2525 UserPromptPart ,
2626)
2727from pydantic_ai .providers .openai import OpenAIProvider
28- from typing_extensions import Callable
28+ from typing import Callable , Union
2929
3030logger = logging .getLogger (__name__ )
3131
@@ -34,7 +34,7 @@ class PydanticAgentRolloutProcessor(RolloutProcessor):
3434 """Rollout processor for Pydantic AI agents. Mainly converts
3535 EvaluationRow.messages to and from Pydantic AI ModelMessage format."""
3636
37- def __init__ (self , setup_agent : Callable [..., Agent ], usage_limits : UsageLimits = None ):
37+ def __init__ (self , setup_agent : Union [ Callable [..., Agent ] , Agent ], usage_limits : UsageLimits = None ):
3838 # dummy model used for its helper functions for processing messages
3939 self .util = OpenAIModel ("dummy-model" , provider = OpenAIProvider (api_key = "dummy" ))
4040 self .setup_agent = setup_agent
@@ -58,63 +58,47 @@ def _map_litellm_to_pydantic_ai(
5858 "azure_ai" : "azure" ,
5959 }
6060 provider = model_name .split ("/" )[0 ]
61+ model_name = model_name .removeprefix (f"{ provider } /" )
6162 if provider in mapping :
6263 provider = mapping [provider ]
63- return provider # type: ignore
64+ return provider , model_name
65+
66+ def _map_litellm_to_pydantic_ai_model (self , model_name : str ) -> Union [OpenAIModel , GoogleModel , AnthropicModel ]:
67+ if model_name .startswith ("anthropic/" ):
68+ return AnthropicModel (
69+ model_name .removeprefix ("anthropic/" ),
70+ )
71+ elif model_name .startswith ("google/" ):
72+ return GoogleModel (
73+ model_name .removeprefix ("google/" ),
74+ )
75+ elif model_name .startswith ("gemini/" ):
76+ return GoogleModel (
77+ model_name .removeprefix ("gemini/" ),
78+ )
79+ provider , model_name = self ._map_litellm_to_pydantic_ai (model_name )
80+ return OpenAIModel (
81+ model_name ,
82+ provider = provider ,
83+ )
6484
6585 def __call__ (self , rows : List [EvaluationRow ], config : RolloutProcessorConfig ) -> List [asyncio .Task [EvaluationRow ]]:
6686 """Create agent rollout tasks and return them for external handling."""
6787
6888 max_concurrent = getattr (config , "max_concurrent_rollouts" , 8 ) or 8
6989 semaphore = asyncio .Semaphore (max_concurrent )
7090
71- # validate that the "agent" field is present with a valid Pydantic AI Agent instance in the completion_params dict
72- if "agent" not in config .kwargs :
73- raise ValueError ("kwargs must contain an 'agent' field with a valid Pydantic AI Agent instance" )
74- if not isinstance (config .kwargs ["agent" ], Agent ) and not isinstance (
75- config .kwargs ["agent" ], types .FunctionType
76- ):
77- raise ValueError (
78- "kwargs['agent'] must be a valid Pydantic AI Agent instance or a function that returns an Agent"
79- )
80-
81- if isinstance (config .kwargs ["agent" ], types .FunctionType ):
82- setup_agent = config .kwargs ["agent" ]
83- if not isinstance (config .completion_params ["model" ], dict ):
84- raise ValueError (
85- "completion_params['model'] must be a dict mapping agent argument names to model config dicts (with 'model' and 'provider' keys)"
86- )
91+ if isinstance (self .setup_agent , types .FunctionType ):
8792 kwargs : dict [str , OpenAIModel | GoogleModel | AnthropicModel ] = {}
8893 for agent , model_config in config .completion_params ["model" ].items ():
8994 if "model" not in model_config :
9095 raise ValueError (f"model_config for agent { agent } must contain a 'model' key" )
91- model_name = model_config ["model" ]
92- if model_name .startswith ("anthropic/" ):
93- kwargs [agent ] = AnthropicModel (
94- model_name .removeprefix ("anthropic/" ),
95- )
96- elif model_name .startswith ("google/" ):
97- kwargs [agent ] = GoogleModel (
98- model_name .removeprefix ("google/" ),
99- )
100- elif model_name .startswith ("gemini/" ):
101- kwargs [agent ] = GoogleModel (
102- model_name .removeprefix ("gemini/" ),
103- )
104- else :
105- provider = self ._map_litellm_to_pydantic_ai (model_name )
106- kwargs [agent ] = OpenAIModel (
107- model_name .removeprefix (f"{ provider } /" ),
108- provider = provider ,
109- )
110- agent = setup_agent (** kwargs )
96+ kwargs [agent ] = self ._map_litellm_to_pydantic_ai_model (model_config ["model" ])
97+ agent = self .setup_agent (** kwargs )
11198 model = None
11299 else :
113- agent = config .kwargs ["agent" ]
114- model = OpenAIModel (
115- config .completion_params ["model" ],
116- provider = config .completion_params ["provider" ],
117- )
100+ agent = self .setup_agent
101+ model = self ._map_litellm_to_pydantic_ai_model (config .completion_params ["model" ])
118102
119103 async def process_row (row : EvaluationRow ) -> EvaluationRow :
120104 """Process a single row with agent rollout."""
0 commit comments