diff --git a/src/cai/sdk/agents/function_schema.py b/src/cai/sdk/agents/function_schema.py index 681affce..193c5c6d 100644 --- a/src/cai/sdk/agents/function_schema.py +++ b/src/cai/sdk/agents/function_schema.py @@ -36,7 +36,6 @@ class FuncSchema: strict_json_schema: bool = True """Whether the JSON schema is in strict mode. We **strongly** recommend setting this to True, as it increases the likelihood of correct JSON input.""" - def to_call_args(self, data: BaseModel) -> tuple[list[Any], dict[str, Any]]: """ Converts validated data from the Pydantic model into (args, kwargs), suitable for calling @@ -51,6 +50,10 @@ class FuncSchema: # If the function takes a RunContextWrapper and this is the first parameter, skip it. if self.takes_context and idx == 0: continue + + # Skip parameters named 'ctf' or 'CTF' + if name.lower() == 'ctf': + continue value = getattr(data, name, None) if param.kind == param.VAR_POSITIONAL: diff --git a/src/cai/sdk/agents/model_settings.py b/src/cai/sdk/agents/model_settings.py index 2b0885ab..2d413576 100644 --- a/src/cai/sdk/agents/model_settings.py +++ b/src/cai/sdk/agents/model_settings.py @@ -43,6 +43,10 @@ class ModelSettings: store: bool | None = None """Whether to store the generated model response for later retrieval. Defaults to True if not provided.""" + + agent_model: str | None = None + """The model from the Agent class. If set, this will override the model provided + to the OpenAIChatCompletionsModel during initialization.""" def resolve(self, override: ModelSettings | None) -> ModelSettings: """Produce a new ModelSettings by overlaying any non-None values from the diff --git a/src/cai/sdk/agents/models/openai_chatcompletions.py b/src/cai/sdk/agents/models/openai_chatcompletions.py index a61ab895..2a023b16 100644 --- a/src/cai/sdk/agents/models/openai_chatcompletions.py +++ b/src/cai/sdk/agents/models/openai_chatcompletions.py @@ -1485,9 +1485,16 @@ class OpenAIChatCompletionsModel(Model): # Match the behavior of Responses where store is True when not given store = model_settings.store if model_settings.store is not None else True + # Check if we should use the agent's model instead of self.model + # This prioritizes the model from Agent when available + agent_model = None + if hasattr(model_settings, 'agent_model') and model_settings.agent_model: + agent_model = model_settings.agent_model + logger.debug(f"Using agent model: {agent_model} instead of {self.model}") + # Prepare kwargs for the API call kwargs = { - "model": self.model, + "model": agent_model if agent_model else self.model, "messages": converted_messages, "tools": converted_tools or NOT_GIVEN, "temperature": self._non_null_or_not_given(model_settings.temperature), @@ -1505,7 +1512,7 @@ class OpenAIChatCompletionsModel(Model): } # Determine provider based on model string - model_str = str(self.model).lower() + model_str = str(kwargs["model"]).lower() # Provider-specific adjustments if "/" in model_str: diff --git a/src/cai/sdk/agents/run.py b/src/cai/sdk/agents/run.py index bdfe8721..6089d331 100644 --- a/src/cai/sdk/agents/run.py +++ b/src/cai/sdk/agents/run.py @@ -657,6 +657,13 @@ class Runner: model = cls._get_model(agent, run_config) model_settings = agent.model_settings.resolve(run_config.model_settings) model_settings = RunImpl.maybe_reset_tool_choice(agent, tool_use_tracker, model_settings) + + # Ensure agent model is set in model_settings for streaming mode + if not hasattr(model_settings, 'agent_model') or not model_settings.agent_model: + if isinstance(agent.model, str): + model_settings.agent_model = agent.model + elif isinstance(run_config.model, str): + model_settings.agent_model = run_config.model final_response: ModelResponse | None = None @@ -941,6 +948,13 @@ class Runner: model_settings = agent.model_settings.resolve(run_config.model_settings) model_settings = RunImpl.maybe_reset_tool_choice(agent, tool_use_tracker, model_settings) + # Ensure agent model is set in model_settings + if not hasattr(model_settings, 'agent_model') or not model_settings.agent_model: + if isinstance(agent.model, str): + model_settings.agent_model = agent.model + elif isinstance(run_config.model, str): + model_settings.agent_model = run_config.model + new_response = await model.get_response( system_instructions=system_prompt, input=input, @@ -981,14 +995,21 @@ class Runner: @classmethod def _get_model(cls, agent: Agent[Any], run_config: RunConfig) -> Model: model = None + agent_model = None if isinstance(run_config.model, Model): model = run_config.model elif isinstance(run_config.model, str): model = run_config.model_provider.get_model(run_config.model) + agent_model = run_config.model elif isinstance(agent.model, Model): model = agent.model else: model = run_config.model_provider.get_model(agent.model) + agent_model = agent.model + + # Store the original agent model in model_settings for later use + if agent_model and hasattr(agent, 'model_settings'): + agent.model_settings.agent_model = agent_model # Set agent name if the model supports it (for CLI display) if hasattr(model, 'set_agent_name'):