mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Fix declarative package powerfx import crash and response_format kwarg error (#3841)
* Fix declarative package powerfx import crash and response_format kwarg error * Address PR feedback. Propagate kwargs for declarative workflows * move tests * Fix options merge logic
This commit is contained in:
committed by
GitHub
Unverified
parent
692fcd1888
commit
ff91473912
@@ -1,8 +1,10 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import builtins
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
@@ -905,3 +907,105 @@ tools:
|
||||
|
||||
# Verify project_connection_id is set from connection name
|
||||
assert mcp_tool.get("project_connection_id") == "my-oauth-connection"
|
||||
|
||||
|
||||
class TestProviderResponseFormat:
|
||||
"""response_format from outputSchema must be passed inside default_options."""
|
||||
|
||||
@staticmethod
|
||||
def _make_mock_prompt_agent(*, with_output_schema: bool = False) -> MagicMock:
|
||||
"""Create a mock PromptAgent to avoid serialization complexity."""
|
||||
mock_model = MagicMock()
|
||||
mock_model.id = "gpt-4"
|
||||
mock_model.connection = None
|
||||
|
||||
agent = MagicMock()
|
||||
agent.name = "test-agent"
|
||||
agent.description = "test"
|
||||
agent.instructions = "be helpful"
|
||||
agent.model = mock_model
|
||||
agent.tools = None
|
||||
|
||||
if with_output_schema:
|
||||
mock_schema = MagicMock()
|
||||
mock_schema.to_json_schema.return_value = {
|
||||
"type": "object",
|
||||
"properties": {"answer": {"type": "string"}},
|
||||
}
|
||||
agent.outputSchema = mock_schema
|
||||
else:
|
||||
agent.outputSchema = None
|
||||
|
||||
return agent
|
||||
|
||||
@staticmethod
|
||||
def _make_mock_provider() -> tuple[MagicMock, AsyncMock]:
|
||||
"""Create a mock provider class and its instance."""
|
||||
mock_agent = MagicMock()
|
||||
mock_provider_instance = AsyncMock()
|
||||
mock_provider_instance.create_agent = AsyncMock(return_value=mock_agent)
|
||||
mock_provider_class = MagicMock(return_value=mock_provider_instance)
|
||||
return mock_provider_class, mock_provider_instance
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_response_format_in_default_options(self):
|
||||
"""Provider.create_agent() should receive response_format inside default_options."""
|
||||
from agent_framework_declarative._loader import AgentFactory
|
||||
|
||||
prompt_agent = self._make_mock_prompt_agent(with_output_schema=True)
|
||||
mock_provider_class, mock_provider_instance = self._make_mock_provider()
|
||||
|
||||
mapping = {"package": "some_module", "name": "SomeProvider"}
|
||||
factory = AgentFactory()
|
||||
|
||||
original_import = builtins.__import__
|
||||
|
||||
def mock_import(name, *args, **kwargs):
|
||||
if name == "some_module":
|
||||
mod = MagicMock()
|
||||
mod.SomeProvider = mock_provider_class
|
||||
return mod
|
||||
return original_import(name, *args, **kwargs)
|
||||
|
||||
with (
|
||||
patch.object(builtins, "__import__", side_effect=mock_import),
|
||||
patch.object(factory, "_parse_tools", return_value=None),
|
||||
):
|
||||
await factory._create_agent_with_provider(prompt_agent, mapping)
|
||||
|
||||
mock_provider_instance.create_agent.assert_called_once()
|
||||
call_kwargs = mock_provider_instance.create_agent.call_args.kwargs
|
||||
|
||||
assert "response_format" not in call_kwargs
|
||||
default_options = call_kwargs.get("default_options")
|
||||
assert default_options is not None
|
||||
assert "response_format" in default_options
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_no_default_options_without_output_schema(self):
|
||||
"""When there's no outputSchema, default_options should be None."""
|
||||
from agent_framework_declarative._loader import AgentFactory
|
||||
|
||||
prompt_agent = self._make_mock_prompt_agent(with_output_schema=False)
|
||||
mock_provider_class, mock_provider_instance = self._make_mock_provider()
|
||||
|
||||
mapping = {"package": "some_module", "name": "SomeProvider"}
|
||||
factory = AgentFactory()
|
||||
|
||||
original_import = builtins.__import__
|
||||
|
||||
def mock_import(name, *args, **kwargs):
|
||||
if name == "some_module":
|
||||
mod = MagicMock()
|
||||
mod.SomeProvider = mock_provider_class
|
||||
return mod
|
||||
return original_import(name, *args, **kwargs)
|
||||
|
||||
with (
|
||||
patch.object(builtins, "__import__", side_effect=mock_import),
|
||||
patch.object(factory, "_parse_tools", return_value=None),
|
||||
):
|
||||
await factory._create_agent_with_provider(prompt_agent, mapping)
|
||||
|
||||
call_kwargs = mock_provider_instance.create_agent.call_args.kwargs
|
||||
assert call_kwargs.get("default_options") is None
|
||||
|
||||
Reference in New Issue
Block a user