Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -740,10 +740,11 @@ def _parse_chat_options(self, model: Model | None) -> dict[str, Any]:
chat_options["stop"] = options.stopSequences
if options.allowMultipleToolCalls is not None:
chat_options["allow_multiple_tool_calls"] = options.allowMultipleToolCalls
if (chat_tool_mode := options.additionalProperties.pop("chatToolMode", None)) is not None:
additional_properties = options.additionalProperties.copy()
if (chat_tool_mode := additional_properties.pop("chatToolMode", None)) is not None:
chat_options["tool_choice"] = chat_tool_mode
if options.additionalProperties:
chat_options["additional_chat_options"] = options.additionalProperties
if additional_properties:
chat_options["additional_chat_options"] = additional_properties
return chat_options

def _parse_tools(self, tools: list[Tool] | None) -> list[AFFunctionTool | dict[str, Any]] | None:
Expand Down
33 changes: 33 additions & 0 deletions python/packages/declarative/tests/test_declarative_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import builtins
import sys
import threading
from copy import deepcopy
from pathlib import Path
from typing import Any
from unittest.mock import AsyncMock, MagicMock, patch
Expand Down Expand Up @@ -643,6 +644,38 @@ def test_create_agent_from_dict_chat_options_in_default_options(self):
assert agent.default_options.get("temperature") == 0.7
assert agent.default_options.get("top_p") == 0.9

@pytest.mark.parametrize("use_async", [False, True])
@pytest.mark.parametrize("tool_choice", ["auto", "required", "none", None])
async def test_create_agent_from_dict_preserves_reused_model_options(
self, tool_choice: str | None, use_async: bool
) -> None:
"""Reusing a definition preserves caller options and each agent's tool choice."""
from agent_framework_declarative import AgentFactory

additional_properties: dict[str, Any] = {"custom_option": {"nested": ["value"]}}
if tool_choice is not None:
additional_properties["chatToolMode"] = tool_choice
agent_def: dict[str, Any] = {
"kind": "Prompt",
"name": "ReusableAgent",
"model": {"options": {"additionalProperties": additional_properties}},
}
original = deepcopy(agent_def)
mock_client = MagicMock()
mock_client.model = "test-model"
factory = AgentFactory(client=mock_client)

for _ in range(2):
if use_async:
agent = await factory.create_agent_from_dict_async(agent_def)
else:
agent = factory.create_agent_from_dict(agent_def)

assert agent.default_options["tool_choice"] == (tool_choice or "auto")
assert agent.default_options["additional_chat_options"] == {"custom_option": {"nested": ["value"]}}

assert agent_def == original


class TestAgentFactorySafeMode:
"""Tests for AgentFactory safe_mode parameter."""
Expand Down
Loading