agent-framework-core 1.22.0__tar.gz → 1.23.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/PKG-INFO +16 -15
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_agents.py +50 -42
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_feature_stage.py +0 -1
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_filesystem.py +29 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_background_agents.py +10 -5
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_loop.py +4 -3
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_memory.py +9 -19
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_todo.py +7 -12
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_tool_approval.py +2 -3
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_mcp.py +879 -956
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_skills.py +84 -70
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_tools.py +50 -16
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_types.py +77 -25
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_agent_executor.py +59 -8
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_functional.py +10 -3
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_typing_utils.py +15 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/ag_ui/__init__.py +2 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/ag_ui/__init__.pyi +2 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/security.py +7 -9
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/pyproject.toml +16 -15
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/LICENSE +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/README.md +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_agent_hooks.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_clients.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_compaction.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_docstrings.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_evaluation.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_agent.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_agent.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_file_access.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_file_memory.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_mode.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_in_memory.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_middleware.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_serialization.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_sessions.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_settings.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_telemetry.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_vector_filters.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_vectors.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_agent.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_agent_utils.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_checkpoint.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_checkpoint_encoding.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_const.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_conversation_history.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_edge.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_edge_runner.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_events.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_executor.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_function_executor.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_message_utils.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_model_utils.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_request_info_mixin.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_runner.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_runner_context.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_state.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_validation.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_viz.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_workflow.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_workflow_builder.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_workflow_context.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_workflows/_workflow_executor.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/a2a/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/a2a/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/amazon/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/amazon/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/anthropic/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/anthropic/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/azure/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/azure/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/chatkit/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/chatkit/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/declarative/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/declarative/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/devui/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/devui/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/exceptions.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/foundry/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/foundry/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/gemini/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/gemini/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/github/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/github/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/google/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/google/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/hyperlight/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/lab/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/mem0/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/mem0/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/microsoft/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/microsoft/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/mistral/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/mistral/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/monty/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/monty/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/observability.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/ollama/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/ollama/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/openai/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/openai/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/orchestrations/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/orchestrations/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/py.typed +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/redis/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/redis/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/tools/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/tools/__init__.pyi +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agent-framework-core
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.23.0
|
|
4
4
|
Summary: Microsoft Agent Framework for building AI Agents with Python. This is the core package that has all the core abstractions and implementations.
|
|
5
5
|
Author-email: Microsoft <af-support@microsoft.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -24,36 +24,37 @@ Requires-Dist: python-dotenv>=1,<2
|
|
|
24
24
|
Requires-Dist: opentelemetry-api>=1.39.0,<2
|
|
25
25
|
Requires-Dist: pyyaml>=6.0,<7.0
|
|
26
26
|
Requires-Dist: regex>=2024.11.6
|
|
27
|
-
Requires-Dist: mcp>=
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist: agent-framework-
|
|
30
|
-
Requires-Dist: agent-framework-
|
|
27
|
+
Requires-Dist: mcp>=2.2.0,<3 ; extra == "all"
|
|
28
|
+
Requires-Dist: tenacity>=9.1.4,<9.2.0 ; extra == "all"
|
|
29
|
+
Requires-Dist: agent-framework-a2a>=1.0.0b261022,<2 ; extra == "all"
|
|
30
|
+
Requires-Dist: agent-framework-ag-ui>=1.7.0,<2 ; extra == "all"
|
|
31
|
+
Requires-Dist: agent-framework-anthropic>=1.0.0b261022,<2 ; extra == "all"
|
|
31
32
|
Requires-Dist: agent-framework-azure-ai-search>=1.0.0b261015,<2 ; extra == "all"
|
|
32
33
|
Requires-Dist: agent-framework-azure-contentunderstanding>=1.0.0b261015,<2 ; extra == "all"
|
|
33
34
|
Requires-Dist: agent-framework-azure-cosmos>=1.0.0b261015,<2 ; extra == "all"
|
|
34
35
|
Requires-Dist: agent-framework-azurefunctions>=1.0.0b260922,<2 ; extra == "all"
|
|
35
|
-
Requires-Dist: agent-framework-bedrock>=1.0.
|
|
36
|
+
Requires-Dist: agent-framework-bedrock>=1.0.0b261022,<2 ; extra == "all"
|
|
36
37
|
Requires-Dist: agent-framework-chatkit>=1.0.0b261015,<2 ; extra == "all"
|
|
37
38
|
Requires-Dist: agent-framework-claude>=1.0.0b261015,<2 ; extra == "all"
|
|
38
39
|
Requires-Dist: agent-framework-copilotstudio>=1.0.0b261015,<2 ; extra == "all"
|
|
39
|
-
Requires-Dist: agent-framework-declarative>=1.
|
|
40
|
-
Requires-Dist: agent-framework-devui>=1.0.
|
|
40
|
+
Requires-Dist: agent-framework-declarative>=1.4.0,<2 ; extra == "all"
|
|
41
|
+
Requires-Dist: agent-framework-devui>=1.0.0b261022,<2 ; extra == "all"
|
|
41
42
|
Requires-Dist: agent-framework-durabletask>=1.0.0b260922,<2 ; extra == "all"
|
|
42
43
|
Requires-Dist: agent-framework-foundry>=1.15.0,<2 ; extra == "all"
|
|
43
|
-
Requires-Dist: agent-framework-foundry-hosting>=1.0.
|
|
44
|
+
Requires-Dist: agent-framework-foundry-hosting>=1.0.0b261022,<2 ; extra == "all"
|
|
44
45
|
Requires-Dist: agent-framework-foundry-local>=1.0.0b261015,<2 ; extra == "all"
|
|
45
|
-
Requires-Dist: agent-framework-gemini>=1.0.
|
|
46
|
+
Requires-Dist: agent-framework-gemini>=1.0.0b261022,<2 ; extra == "all"
|
|
46
47
|
Requires-Dist: agent-framework-github-copilot>=2.1.0,<3 ; extra == "all" and ( python_version >= '3.11')
|
|
47
|
-
Requires-Dist: agent-framework-hyperlight>=1.0.
|
|
48
|
+
Requires-Dist: agent-framework-hyperlight>=1.0.0b261022,<2 ; extra == "all" and ( (sys_platform == 'linux' and platform_machine == 'x86_64') or (sys_platform == 'win32' and platform_machine == 'AMD64'))
|
|
48
49
|
Requires-Dist: agent-framework-mem0>=1.0.0b261015,<2 ; extra == "all"
|
|
49
50
|
Requires-Dist: agent-framework-mistral>=1.0.0b261015,<2 ; extra == "all"
|
|
50
51
|
Requires-Dist: agent-framework-monty>=1.0.0b261015,<2 ; extra == "all"
|
|
51
|
-
Requires-Dist: agent-framework-ollama>=1.0.
|
|
52
|
+
Requires-Dist: agent-framework-ollama>=1.0.0b261022,<2 ; extra == "all"
|
|
52
53
|
Requires-Dist: agent-framework-openai>=1.17.0,<2 ; extra == "all"
|
|
53
|
-
Requires-Dist: agent-framework-orchestrations>=1.
|
|
54
|
+
Requires-Dist: agent-framework-orchestrations>=1.4.0,<2 ; extra == "all"
|
|
54
55
|
Requires-Dist: agent-framework-purview>=1.0.0b261015,<2 ; extra == "all"
|
|
55
|
-
Requires-Dist: agent-framework-redis>=1.0.
|
|
56
|
-
Requires-Dist: agent-framework-tools>=1.0.
|
|
56
|
+
Requires-Dist: agent-framework-redis>=1.0.0b261022,<2 ; extra == "all" and ( python_version < '3.15')
|
|
57
|
+
Requires-Dist: agent-framework-tools>=1.0.0b261022,<2 ; extra == "all"
|
|
57
58
|
Project-URL: homepage, https://aka.ms/agent-framework
|
|
58
59
|
Project-URL: issues, https://github.com/microsoft/agent-framework/issues
|
|
59
60
|
Project-URL: release_notes, https://github.com/microsoft/agent-framework/releases?q=tag%3Apython-1&expanded=true
|
|
@@ -1881,8 +1881,9 @@ class RawAgent(BaseAgent, Generic[OptionsCoT]):
|
|
|
1881
1881
|
"""
|
|
1882
1882
|
try:
|
|
1883
1883
|
from mcp import types
|
|
1884
|
+
from mcp.server import ServerRequestContext
|
|
1884
1885
|
from mcp.server.lowlevel import Server
|
|
1885
|
-
from mcp.shared.exceptions import
|
|
1886
|
+
from mcp.shared.exceptions import MCPError
|
|
1886
1887
|
except ModuleNotFoundError as exc:
|
|
1887
1888
|
raise ModuleNotFoundError(
|
|
1888
1889
|
"`mcp` is required to use `Agent.as_mcp_server()`. Please install `mcp`."
|
|
@@ -1891,55 +1892,57 @@ class RawAgent(BaseAgent, Generic[OptionsCoT]):
|
|
|
1891
1892
|
|
|
1892
1893
|
server_args: dict[str, Any] = {
|
|
1893
1894
|
"name": server_name,
|
|
1894
|
-
"version": version,
|
|
1895
1895
|
"instructions": instructions,
|
|
1896
1896
|
}
|
|
1897
|
+
|
|
1898
|
+
if version is not None:
|
|
1899
|
+
server_args["version"] = version
|
|
1900
|
+
|
|
1897
1901
|
if lifespan:
|
|
1898
1902
|
server_args["lifespan"] = lifespan
|
|
1899
1903
|
if kwargs:
|
|
1900
1904
|
server_args.update(kwargs)
|
|
1901
1905
|
|
|
1902
|
-
server: Server[Any] = Server(**server_args)
|
|
1903
|
-
|
|
1904
1906
|
agent_tool = self.as_tool(name=self._get_agent_name())
|
|
1905
1907
|
|
|
1906
|
-
async def _log(level: types.LoggingLevel, data: Any) -> None:
|
|
1907
|
-
"""Log
|
|
1908
|
-
# Log to the local logger
|
|
1908
|
+
async def _log(ctx: ServerRequestContext[dict[str, Any]], level: types.LoggingLevel, data: Any) -> None:
|
|
1909
|
+
"""Log locally and forward through the session handling this request."""
|
|
1909
1910
|
logger.log(LOG_LEVEL_MAPPING[level], data)
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1911
|
+
try:
|
|
1912
|
+
await ctx.session.send_log_message( # pyright: ignore[reportDeprecated]
|
|
1913
|
+
level=level,
|
|
1914
|
+
data=data,
|
|
1915
|
+
)
|
|
1916
|
+
except Exception as exc:
|
|
1917
|
+
logger.error("Failed to send log message to MCP client: %s", exc)
|
|
1918
|
+
|
|
1919
|
+
async def _list_tools(
|
|
1920
|
+
ctx: ServerRequestContext[dict[str, Any]], _params: types.PaginatedRequestParams | None
|
|
1921
|
+
) -> types.ListToolsResult:
|
|
1918
1922
|
"""List all tools in the agent."""
|
|
1919
1923
|
schema = agent_tool.parameters()
|
|
1920
1924
|
|
|
1921
1925
|
tool = types.Tool(
|
|
1922
1926
|
name=agent_tool.name,
|
|
1923
1927
|
description=agent_tool.description,
|
|
1924
|
-
|
|
1928
|
+
input_schema=schema,
|
|
1925
1929
|
)
|
|
1926
1930
|
|
|
1927
|
-
await _log(level="debug", data=f"Agent tool: {agent_tool}")
|
|
1928
|
-
return [tool]
|
|
1931
|
+
await _log(ctx, level="debug", data=f"Agent tool: {agent_tool}")
|
|
1932
|
+
return types.ListToolsResult(tools=[tool])
|
|
1929
1933
|
|
|
1930
|
-
@server.call_tool()
|
|
1931
1934
|
async def _call_tool(
|
|
1932
|
-
|
|
1933
|
-
) ->
|
|
1935
|
+
ctx: ServerRequestContext[dict[str, Any]], params: types.CallToolRequestParams
|
|
1936
|
+
) -> types.CallToolResult:
|
|
1934
1937
|
"""Call a tool in the agent."""
|
|
1935
|
-
|
|
1938
|
+
arguments = params.arguments or {}
|
|
1939
|
+
name = params.name
|
|
1940
|
+
await _log(ctx, level="debug", data=f"Calling tool with args: {arguments}")
|
|
1936
1941
|
|
|
1937
1942
|
if name != agent_tool.name:
|
|
1938
|
-
raise
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
message=f"Tool {name} not found",
|
|
1942
|
-
),
|
|
1943
|
+
raise MCPError(
|
|
1944
|
+
code=types.INTERNAL_ERROR,
|
|
1945
|
+
message=f"Tool {name} not found",
|
|
1943
1946
|
)
|
|
1944
1947
|
|
|
1945
1948
|
# Create an instance of the input model with the arguments
|
|
@@ -1949,17 +1952,15 @@ class RawAgent(BaseAgent, Generic[OptionsCoT]):
|
|
|
1949
1952
|
)
|
|
1950
1953
|
result = await agent_tool.invoke(arguments=args_instance)
|
|
1951
1954
|
except Exception as e:
|
|
1952
|
-
raise
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
message=f"Error calling tool {name}: {e}",
|
|
1956
|
-
),
|
|
1955
|
+
raise MCPError(
|
|
1956
|
+
code=types.INTERNAL_ERROR,
|
|
1957
|
+
message=f"Error calling tool {name}: {e}",
|
|
1957
1958
|
) from e
|
|
1958
1959
|
|
|
1959
1960
|
# Convert result to MCP content.
|
|
1960
1961
|
# Currently only text items are forwarded over MCP; rich content
|
|
1961
1962
|
# (images, audio) is not yet supported in the MCP server path.
|
|
1962
|
-
mcp_content: list[types.
|
|
1963
|
+
mcp_content: list[types.ContentBlock] = []
|
|
1963
1964
|
for c in result:
|
|
1964
1965
|
if c.type == "text" and c.text:
|
|
1965
1966
|
mcp_content.append(types.TextContent(type="text", text=c.text))
|
|
@@ -1968,15 +1969,22 @@ class RawAgent(BaseAgent, Generic[OptionsCoT]):
|
|
|
1968
1969
|
"MCP server does not yet forward rich content (images, audio) "
|
|
1969
1970
|
"in tool results. Rich content items will be omitted."
|
|
1970
1971
|
)
|
|
1971
|
-
return
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
await _log(level=level, data=f"Log level set to {level}")
|
|
1979
|
-
|
|
1972
|
+
return types.CallToolResult(content=mcp_content)
|
|
1973
|
+
|
|
1974
|
+
async def _set_logging_level(
|
|
1975
|
+
ctx: ServerRequestContext[dict[str, Any]], params: types.SetLevelRequestParams
|
|
1976
|
+
) -> types.EmptyResult:
|
|
1977
|
+
"""Set the local threshold and confirm it through the requesting MCP session."""
|
|
1978
|
+
logger.setLevel(LOG_LEVEL_MAPPING[params.level])
|
|
1979
|
+
await _log(ctx, level=params.level, data=f"Log level set to {params.level}")
|
|
1980
|
+
return types.EmptyResult()
|
|
1981
|
+
|
|
1982
|
+
server: Server[Any] = Server( # pyright: ignore[reportDeprecated]
|
|
1983
|
+
**server_args,
|
|
1984
|
+
on_list_tools=_list_tools,
|
|
1985
|
+
on_call_tool=_call_tool,
|
|
1986
|
+
on_set_logging_level=_set_logging_level,
|
|
1987
|
+
)
|
|
1980
1988
|
return server
|
|
1981
1989
|
|
|
1982
1990
|
def _get_agent_name(self) -> str:
|
{agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_feature_stage.py
RENAMED
|
@@ -60,7 +60,6 @@ class ExperimentalFeature(str, Enum):
|
|
|
60
60
|
FOUNDRY_PREVIEW_TOOLS = "FOUNDRY_PREVIEW_TOOLS"
|
|
61
61
|
FUNCTIONAL_WORKFLOWS = "FUNCTIONAL_WORKFLOWS"
|
|
62
62
|
HARNESS = "HARNESS"
|
|
63
|
-
MCP_LONG_RUNNING_TASKS = "MCP_LONG_RUNNING_TASKS"
|
|
64
63
|
MCP_SKILLS = "MCP_SKILLS"
|
|
65
64
|
PROGRESSIVE_TOOLS = "PROGRESSIVE_TOOLS"
|
|
66
65
|
SESSION_STORE = "SESSION_STORE"
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
7
|
import hashlib
|
|
8
|
+
import os
|
|
8
9
|
import stat
|
|
10
|
+
import uuid
|
|
9
11
|
from base64 import b32encode
|
|
10
12
|
from pathlib import Path
|
|
11
13
|
|
|
@@ -44,6 +46,33 @@ _MAX_ENCODED_STORAGE_KEY_SEGMENT_LENGTH = 180
|
|
|
44
46
|
_DIGEST_SEGMENT_MARKER = "sha256-"
|
|
45
47
|
|
|
46
48
|
|
|
49
|
+
def _atomic_write_text(path: Path, text: str, *, encoding: str = "utf-8") -> None: # pyright: ignore[reportUnusedFunction]
|
|
50
|
+
"""Atomically write text through a securely created sibling temporary file.
|
|
51
|
+
|
|
52
|
+
Exclusive creation prevents an existing file or symbolic link from redirecting the write.
|
|
53
|
+
"""
|
|
54
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
55
|
+
temp_path = path.with_name(f".maf-state-{uuid.uuid4().hex}.tmp")
|
|
56
|
+
cleanup_path: Path | None = None
|
|
57
|
+
file_descriptor: int | None = None
|
|
58
|
+
try:
|
|
59
|
+
file_descriptor = os.open(temp_path, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o666)
|
|
60
|
+
cleanup_path = temp_path
|
|
61
|
+
file_handle = os.fdopen(file_descriptor, "w", encoding=encoding, closefd=False)
|
|
62
|
+
with file_handle:
|
|
63
|
+
file_handle.write(text)
|
|
64
|
+
descriptor_to_close = file_descriptor
|
|
65
|
+
file_descriptor = None
|
|
66
|
+
os.close(descriptor_to_close)
|
|
67
|
+
os.replace(temp_path, path)
|
|
68
|
+
cleanup_path = None
|
|
69
|
+
finally:
|
|
70
|
+
if file_descriptor is not None:
|
|
71
|
+
os.close(file_descriptor)
|
|
72
|
+
if cleanup_path is not None:
|
|
73
|
+
cleanup_path.unlink(missing_ok=True)
|
|
74
|
+
|
|
75
|
+
|
|
47
76
|
def _is_link_or_reparse_point(path: Path) -> bool: # pyright: ignore[reportUnusedFunction]
|
|
48
77
|
"""Return whether ``path`` is a symbolic link, junction, or other reparse point."""
|
|
49
78
|
path_stat = path.lstat()
|
|
@@ -229,7 +229,9 @@ def _finalize_task(
|
|
|
229
229
|
else:
|
|
230
230
|
task_info.status = BackgroundTaskStatus.COMPLETED
|
|
231
231
|
task_info.result_text = completed_task.result().text
|
|
232
|
-
|
|
232
|
+
# A stale waiter may observe a task ID already reused by a continuation.
|
|
233
|
+
if runtime.in_flight_tasks.get(task_info.id) is completed_task:
|
|
234
|
+
runtime.in_flight_tasks.pop(task_info.id, None)
|
|
233
235
|
|
|
234
236
|
|
|
235
237
|
def _refresh_task_state(
|
|
@@ -559,18 +561,21 @@ class BackgroundAgentsProvider(ContextProvider):
|
|
|
559
561
|
|
|
560
562
|
# Find which ID completed.
|
|
561
563
|
completed_id: int | None = None
|
|
564
|
+
completed_task: asyncio.Task[AgentResponse[Any]] | None = None
|
|
562
565
|
for tid, task in waitable:
|
|
563
566
|
if task in done:
|
|
564
567
|
completed_id = tid
|
|
568
|
+
completed_task = task
|
|
565
569
|
break
|
|
566
570
|
|
|
567
571
|
# Finalize the completed task.
|
|
568
572
|
tasks = _get_tasks(provider_state)
|
|
569
573
|
task_info = next((t for t in tasks if t.id == completed_id), None)
|
|
570
|
-
if task_info is not None and
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
+
if task_info is not None and completed_task is not None:
|
|
575
|
+
# Report the waited-on execution without overwriting a newer one.
|
|
576
|
+
is_current_task = runtime.in_flight_tasks.get(task_info.id) is completed_task
|
|
577
|
+
_finalize_task(task_info, completed_task, runtime)
|
|
578
|
+
if is_current_task:
|
|
574
579
|
_save_tasks(provider_state, tasks)
|
|
575
580
|
_save_provider_state(session, provider_state, source_id=source_id)
|
|
576
581
|
|
{agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_loop.py
RENAMED
|
@@ -654,10 +654,11 @@ class AgentLoopMiddleware(AgentMiddleware):
|
|
|
654
654
|
f"got {type(inner).__name__}."
|
|
655
655
|
)
|
|
656
656
|
|
|
657
|
-
async
|
|
658
|
-
|
|
657
|
+
async with inner:
|
|
658
|
+
async for update in inner:
|
|
659
|
+
yield update
|
|
659
660
|
|
|
660
|
-
|
|
661
|
+
holder["final"] = await inner.get_final_response()
|
|
661
662
|
except MiddlewareTermination:
|
|
662
663
|
# The pipeline's MiddlewareTermination suppression is no longer active once
|
|
663
664
|
# process() has returned (the stream is consumed lazily), so a termination
|
{agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_memory.py
RENAMED
|
@@ -5,7 +5,6 @@ from __future__ import annotations
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import json
|
|
7
7
|
import logging
|
|
8
|
-
import os
|
|
9
8
|
import re
|
|
10
9
|
import threading
|
|
11
10
|
import weakref
|
|
@@ -20,7 +19,10 @@ from typing import Any, ClassVar, Final, cast
|
|
|
20
19
|
from .._clients import SupportsChatGetResponse
|
|
21
20
|
from .._compaction import group_messages
|
|
22
21
|
from .._feature_stage import ExperimentalFeature, experimental
|
|
23
|
-
from .._filesystem import
|
|
22
|
+
from .._filesystem import (
|
|
23
|
+
_atomic_write_text, # pyright: ignore[reportPrivateUsage]
|
|
24
|
+
_storage_key_segment, # pyright: ignore[reportPrivateUsage]
|
|
25
|
+
)
|
|
24
26
|
from .._sessions import AgentSession, FileHistoryProvider, HistoryProvider, JsonDumps, JsonLoads, SessionContext
|
|
25
27
|
from .._telemetry import FeatureIndex, mark_feature_used
|
|
26
28
|
from .._tools import tool
|
|
@@ -122,22 +124,6 @@ def _unescape_markdown_line(line: str) -> str:
|
|
|
122
124
|
return line
|
|
123
125
|
|
|
124
126
|
|
|
125
|
-
def _atomic_write_text(path: Path, text: str, *, encoding: str = "utf-8") -> None:
|
|
126
|
-
"""Write text to ``path`` atomically via a sibling temp file plus :func:`os.replace`.
|
|
127
|
-
|
|
128
|
-
A crash, OOM, or disk-full mid-write leaves the previous file (if any) intact instead of
|
|
129
|
-
producing a truncated file that breaks every subsequent read.
|
|
130
|
-
"""
|
|
131
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
132
|
-
temp_path = path.with_name(f"{path.name}.tmp.{os.getpid()}")
|
|
133
|
-
try:
|
|
134
|
-
temp_path.write_text(text, encoding=encoding)
|
|
135
|
-
os.replace(temp_path, path)
|
|
136
|
-
finally:
|
|
137
|
-
if temp_path.exists():
|
|
138
|
-
temp_path.unlink(missing_ok=True)
|
|
139
|
-
|
|
140
|
-
|
|
141
127
|
def _slugify_topic(topic: str) -> str:
|
|
142
128
|
slug = re.sub(r"[^a-z0-9]+", "-", _normalize_topic(topic).lower()).strip("-")
|
|
143
129
|
return slug or "memory-topic"
|
|
@@ -661,7 +647,11 @@ class MemoryStore(ABC):
|
|
|
661
647
|
|
|
662
648
|
@experimental(feature_id=ExperimentalFeature.HARNESS)
|
|
663
649
|
class MemoryFileStore(MemoryStore):
|
|
664
|
-
"""Store memory files under ``MEMORY.md``, ``topics/``, and ``transcripts/``.
|
|
650
|
+
"""Store memory files under ``MEMORY.md``, ``topics/``, and ``transcripts/``.
|
|
651
|
+
|
|
652
|
+
The storage directory must not be writable by untrusted users, because they could
|
|
653
|
+
replace the final memory files independently of this store's secure temporary writes.
|
|
654
|
+
"""
|
|
665
655
|
|
|
666
656
|
def __init__(
|
|
667
657
|
self,
|
{agent_framework_core-1.22.0 → agent_framework_core-1.23.0}/agent_framework/_harness/_todo.py
RENAMED
|
@@ -4,7 +4,6 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import json
|
|
7
|
-
import os
|
|
8
7
|
import weakref
|
|
9
8
|
from abc import ABC, abstractmethod
|
|
10
9
|
from collections.abc import Mapping, MutableMapping
|
|
@@ -15,6 +14,7 @@ from typing_extensions import NotRequired, TypedDict
|
|
|
15
14
|
|
|
16
15
|
from .._feature_stage import ExperimentalFeature, experimental
|
|
17
16
|
from .._filesystem import (
|
|
17
|
+
_atomic_write_text, # pyright: ignore[reportPrivateUsage]
|
|
18
18
|
_is_literal_storage_key_segment_safe, # pyright: ignore[reportPrivateUsage]
|
|
19
19
|
_storage_key_segment, # pyright: ignore[reportPrivateUsage]
|
|
20
20
|
)
|
|
@@ -289,7 +289,11 @@ class TodoSessionStore(TodoStore):
|
|
|
289
289
|
|
|
290
290
|
@experimental(feature_id=ExperimentalFeature.HARNESS)
|
|
291
291
|
class TodoFileStore(TodoStore):
|
|
292
|
-
"""Store todo state in one JSON file per session and source ID.
|
|
292
|
+
"""Store todo state in one JSON file per session and source ID.
|
|
293
|
+
|
|
294
|
+
The storage directory must not be writable by untrusted users, because they could
|
|
295
|
+
replace the final todo files independently of this store's secure temporary writes.
|
|
296
|
+
"""
|
|
293
297
|
|
|
294
298
|
def __init__(
|
|
295
299
|
self,
|
|
@@ -404,16 +408,7 @@ class TodoFileStore(TodoStore):
|
|
|
404
408
|
@staticmethod
|
|
405
409
|
def _save_state_sync(state_path: Path, payload: str) -> None:
|
|
406
410
|
"""Synchronous helper that atomically writes the JSON state file."""
|
|
407
|
-
state_path
|
|
408
|
-
# Write to a sibling temp file then atomically replace, so a crash mid-write cannot leave
|
|
409
|
-
# a truncated state file that breaks every subsequent tool call.
|
|
410
|
-
temp_path = state_path.with_name(f"{state_path.name}.tmp.{os.getpid()}")
|
|
411
|
-
try:
|
|
412
|
-
temp_path.write_text(payload, encoding="utf-8")
|
|
413
|
-
os.replace(temp_path, state_path)
|
|
414
|
-
finally:
|
|
415
|
-
if temp_path.exists():
|
|
416
|
-
temp_path.unlink(missing_ok=True)
|
|
411
|
+
_atomic_write_text(state_path, payload)
|
|
417
412
|
|
|
418
413
|
|
|
419
414
|
class TodoProvider(ContextProvider):
|
|
@@ -130,10 +130,9 @@ class ToolApprovalRule(SerializationMixin):
|
|
|
130
130
|
server_label: Optional hosted-tool server boundary. Hosted approvals
|
|
131
131
|
only match future approvals from the same server label.
|
|
132
132
|
"""
|
|
133
|
-
|
|
134
|
-
if not normalized_name:
|
|
133
|
+
if not tool_name.strip():
|
|
135
134
|
raise ValueError("Tool approval rule tool_name must be a non-empty string.")
|
|
136
|
-
self.tool_name =
|
|
135
|
+
self.tool_name = tool_name
|
|
137
136
|
self.arguments = dict(arguments) if arguments is not None else None
|
|
138
137
|
self.server_label = server_label
|
|
139
138
|
|