agent-framework-core 1.22.0__tar.gz → 1.24.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.24.0}/PKG-INFO +45 -35
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/README.md +15 -5
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/__init__.py +10 -1
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/__init__.pyi +10 -1
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_agent_hooks.py +273 -19
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_agents.py +50 -42
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_clients.py +67 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_compaction.py +557 -3
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_feature_stage.py +1 -1
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_filesystem.py +29 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_background_agents.py +10 -5
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_file_access.py +233 -22
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_loop.py +4 -3
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_memory.py +9 -19
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_todo.py +7 -12
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_tool_approval.py +2 -3
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_in_memory.py +278 -5
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_mcp.py +988 -981
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_sessions.py +28 -4
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_skills.py +126 -76
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_tools.py +56 -23
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_types.py +129 -29
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_agent.py +119 -19
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_agent_executor.py +59 -8
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_checkpoint.py +55 -16
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_checkpoint_encoding.py +98 -7
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_edge.py +32 -12
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_edge_runner.py +10 -5
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_functional.py +120 -14
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_typing_utils.py +15 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_workflow_builder.py +2 -2
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/ag_ui/__init__.py +2 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/ag_ui/__init__.pyi +2 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/observability.py +5 -1
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/security.py +33 -24
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/pyproject.toml +37 -30
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/LICENSE +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_docstrings.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_evaluation.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_agent.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_agent.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_file_memory.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_mode.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_middleware.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_serialization.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_settings.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_telemetry.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_vector_filters.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_vectors.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_agent_utils.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_const.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_conversation_history.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_events.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_executor.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_function_executor.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_message_utils.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_model_utils.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_request_info_mixin.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_runner.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_runner_context.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_state.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_validation.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_viz.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_workflow.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_workflow_context.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_workflow_executor.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/a2a/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/a2a/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/amazon/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/amazon/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/anthropic/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/anthropic/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/azure/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/azure/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/chatkit/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/chatkit/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/declarative/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/declarative/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/devui/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/devui/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/exceptions.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/foundry/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/foundry/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/gemini/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/gemini/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/github/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/github/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/google/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/google/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/hyperlight/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/lab/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/mem0/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/mem0/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/microsoft/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/microsoft/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/mistral/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/mistral/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/monty/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/monty/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/ollama/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/ollama/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/openai/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/openai/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/orchestrations/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/orchestrations/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/py.typed +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/redis/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/redis/__init__.pyi +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/tools/__init__.py +0 -0
- {agent_framework_core-1.22.0 → agent_framework_core-1.24.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.24.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
|
|
@@ -9,7 +9,6 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
9
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
13
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
@@ -24,36 +23,37 @@ Requires-Dist: python-dotenv>=1,<2
|
|
|
24
23
|
Requires-Dist: opentelemetry-api>=1.39.0,<2
|
|
25
24
|
Requires-Dist: pyyaml>=6.0,<7.0
|
|
26
25
|
Requires-Dist: regex>=2024.11.6
|
|
27
|
-
Requires-Dist: mcp>=
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist: agent-framework-
|
|
30
|
-
Requires-Dist: agent-framework-
|
|
31
|
-
Requires-Dist: agent-framework-
|
|
32
|
-
Requires-Dist: agent-framework-azure-
|
|
33
|
-
Requires-Dist: agent-framework-azure-
|
|
26
|
+
Requires-Dist: mcp>=2.2.0,<3 ; extra == "all"
|
|
27
|
+
Requires-Dist: tenacity>=9.1.4,<9.2.0 ; extra == "all"
|
|
28
|
+
Requires-Dist: agent-framework-a2a>=1.0.0b261030,<2 ; extra == "all"
|
|
29
|
+
Requires-Dist: agent-framework-ag-ui>=1.7.1,<2 ; extra == "all"
|
|
30
|
+
Requires-Dist: agent-framework-anthropic>=1.0.0b261030,<2 ; extra == "all"
|
|
31
|
+
Requires-Dist: agent-framework-azure-ai-search>=1.0.0b261030,<2 ; extra == "all"
|
|
32
|
+
Requires-Dist: agent-framework-azure-contentunderstanding>=1.0.0b261030,<2 ; extra == "all"
|
|
33
|
+
Requires-Dist: agent-framework-azure-cosmos>=1.0.0b261030,<2 ; extra == "all"
|
|
34
34
|
Requires-Dist: agent-framework-azurefunctions>=1.0.0b260922,<2 ; extra == "all"
|
|
35
|
-
Requires-Dist: agent-framework-bedrock>=1.0.
|
|
36
|
-
Requires-Dist: agent-framework-chatkit>=1.0.
|
|
37
|
-
Requires-Dist: agent-framework-claude>=1.0.
|
|
38
|
-
Requires-Dist: agent-framework-copilotstudio>=1.0.
|
|
39
|
-
Requires-Dist: agent-framework-declarative>=1.
|
|
40
|
-
Requires-Dist: agent-framework-devui>=1.0.
|
|
35
|
+
Requires-Dist: agent-framework-bedrock>=1.0.0b261030,<2 ; extra == "all"
|
|
36
|
+
Requires-Dist: agent-framework-chatkit>=1.0.0b261030,<2 ; extra == "all"
|
|
37
|
+
Requires-Dist: agent-framework-claude>=1.0.0b261030,<2 ; extra == "all"
|
|
38
|
+
Requires-Dist: agent-framework-copilotstudio>=1.0.0b261030,<2 ; extra == "all"
|
|
39
|
+
Requires-Dist: agent-framework-declarative>=1.4.1,<2 ; extra == "all"
|
|
40
|
+
Requires-Dist: agent-framework-devui>=1.0.0b261030,<2 ; extra == "all"
|
|
41
41
|
Requires-Dist: agent-framework-durabletask>=1.0.0b260922,<2 ; extra == "all"
|
|
42
|
-
Requires-Dist: agent-framework-foundry>=1.
|
|
43
|
-
Requires-Dist: agent-framework-foundry-hosting>=1.0.
|
|
44
|
-
Requires-Dist: agent-framework-foundry-local>=1.0.
|
|
45
|
-
Requires-Dist: agent-framework-gemini>=1.0.
|
|
46
|
-
Requires-Dist: agent-framework-github-copilot>=2.1.
|
|
47
|
-
Requires-Dist: agent-framework-hyperlight>=1.0.
|
|
48
|
-
Requires-Dist: agent-framework-mem0>=1.0.
|
|
49
|
-
Requires-Dist: agent-framework-mistral>=1.0.
|
|
50
|
-
Requires-Dist: agent-framework-monty>=1.0.
|
|
51
|
-
Requires-Dist: agent-framework-ollama>=1.0.
|
|
52
|
-
Requires-Dist: agent-framework-openai>=1.
|
|
53
|
-
Requires-Dist: agent-framework-orchestrations>=1.
|
|
54
|
-
Requires-Dist: agent-framework-purview>=1.0.
|
|
55
|
-
Requires-Dist: agent-framework-redis>=1.0.
|
|
56
|
-
Requires-Dist: agent-framework-tools>=1.0.
|
|
42
|
+
Requires-Dist: agent-framework-foundry>=1.16.0,<2 ; extra == "all"
|
|
43
|
+
Requires-Dist: agent-framework-foundry-hosting>=1.0.0b261030,<2 ; extra == "all"
|
|
44
|
+
Requires-Dist: agent-framework-foundry-local>=1.0.0b261030,<2 ; extra == "all"
|
|
45
|
+
Requires-Dist: agent-framework-gemini>=1.0.0b261030,<2 ; extra == "all"
|
|
46
|
+
Requires-Dist: agent-framework-github-copilot>=2.1.1,<3 ; extra == "all" and ( python_version >= '3.11')
|
|
47
|
+
Requires-Dist: agent-framework-hyperlight>=1.0.0b261030,<2 ; extra == "all" and ( (sys_platform == 'linux' and platform_machine == 'x86_64') or (sys_platform == 'win32' and platform_machine == 'AMD64'))
|
|
48
|
+
Requires-Dist: agent-framework-mem0>=1.0.0b261030,<2 ; extra == "all"
|
|
49
|
+
Requires-Dist: agent-framework-mistral>=1.0.0b261030,<2 ; extra == "all"
|
|
50
|
+
Requires-Dist: agent-framework-monty>=1.0.0b261030,<2 ; extra == "all"
|
|
51
|
+
Requires-Dist: agent-framework-ollama>=1.0.0b261030,<2 ; extra == "all"
|
|
52
|
+
Requires-Dist: agent-framework-openai>=1.18.0,<2 ; extra == "all"
|
|
53
|
+
Requires-Dist: agent-framework-orchestrations>=1.4.1,<2 ; extra == "all"
|
|
54
|
+
Requires-Dist: agent-framework-purview>=1.0.0b261030,<2 ; extra == "all"
|
|
55
|
+
Requires-Dist: agent-framework-redis>=1.0.0b261030,<2 ; extra == "all" and ( python_version < '3.15')
|
|
56
|
+
Requires-Dist: agent-framework-tools>=1.0.0b261030,<2 ; extra == "all"
|
|
57
57
|
Project-URL: homepage, https://aka.ms/agent-framework
|
|
58
58
|
Project-URL: issues, https://github.com/microsoft/agent-framework/issues
|
|
59
59
|
Project-URL: release_notes, https://github.com/microsoft/agent-framework/releases?q=tag%3Apython-1&expanded=true
|
|
@@ -85,13 +85,15 @@ pip install agent-framework-openai
|
|
|
85
85
|
|
|
86
86
|
Supported Platforms:
|
|
87
87
|
|
|
88
|
-
- Python: 3.
|
|
88
|
+
- Python: 3.11–3.15
|
|
89
89
|
- OS: Windows, macOS, Linux
|
|
90
90
|
|
|
91
|
-
Python 3.10
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
Python 3.10 is no longer supported because it has reached upstream end of life.
|
|
92
|
+
Package metadata still permits Python 3.10 installation, but CI no longer runs
|
|
93
|
+
unit or integration tests on it and compatibility is not guaranteed. Use
|
|
94
|
+
Python 3.11–3.15 for supported environments, subject to
|
|
95
|
+
[integration-specific limits](../../README.md#python-315-limitations). Raising
|
|
96
|
+
the installation minimum will be handled separately.
|
|
95
97
|
|
|
96
98
|
## 1. Setup API Keys
|
|
97
99
|
|
|
@@ -132,6 +134,14 @@ carry a documented feature-usage token.
|
|
|
132
134
|
- `AGENT_FRAMEWORK_USER_AGENT_DISABLED=true` disables the entire Agent Framework
|
|
133
135
|
User-Agent contribution, including the feature token.
|
|
134
136
|
|
|
137
|
+
OpenTelemetry providers configured through `configure_otel_providers()` share a
|
|
138
|
+
resource containing `"microsoft.agent-framework": "True"` (a string) by default. This
|
|
139
|
+
resource attribute applies to logs, traces, and metrics, including other
|
|
140
|
+
instrumentation using those providers. Existing environment and explicit resource
|
|
141
|
+
attribute overrides retain their precedence. If you configure providers yourself,
|
|
142
|
+
use `agent_framework.observability.create_resource()` for each provider or add the
|
|
143
|
+
attribute to your own shared resource.
|
|
144
|
+
|
|
135
145
|
See the following [getting started samples](https://github.com/microsoft/agent-framework/tree/main/python/samples/01-get-started) for more information.
|
|
136
146
|
|
|
137
147
|
## 2. Create a Simple Agent
|
|
@@ -22,13 +22,15 @@ pip install agent-framework-openai
|
|
|
22
22
|
|
|
23
23
|
Supported Platforms:
|
|
24
24
|
|
|
25
|
-
- Python: 3.
|
|
25
|
+
- Python: 3.11–3.15
|
|
26
26
|
- OS: Windows, macOS, Linux
|
|
27
27
|
|
|
28
|
-
Python 3.10
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
Python 3.10 is no longer supported because it has reached upstream end of life.
|
|
29
|
+
Package metadata still permits Python 3.10 installation, but CI no longer runs
|
|
30
|
+
unit or integration tests on it and compatibility is not guaranteed. Use
|
|
31
|
+
Python 3.11–3.15 for supported environments, subject to
|
|
32
|
+
[integration-specific limits](../../README.md#python-315-limitations). Raising
|
|
33
|
+
the installation minimum will be handled separately.
|
|
32
34
|
|
|
33
35
|
## 1. Setup API Keys
|
|
34
36
|
|
|
@@ -69,6 +71,14 @@ carry a documented feature-usage token.
|
|
|
69
71
|
- `AGENT_FRAMEWORK_USER_AGENT_DISABLED=true` disables the entire Agent Framework
|
|
70
72
|
User-Agent contribution, including the feature token.
|
|
71
73
|
|
|
74
|
+
OpenTelemetry providers configured through `configure_otel_providers()` share a
|
|
75
|
+
resource containing `"microsoft.agent-framework": "True"` (a string) by default. This
|
|
76
|
+
resource attribute applies to logs, traces, and metrics, including other
|
|
77
|
+
instrumentation using those providers. Existing environment and explicit resource
|
|
78
|
+
attribute overrides retain their precedence. If you configure providers yourself,
|
|
79
|
+
use `agent_framework.observability.create_resource()` for each provider or add the
|
|
80
|
+
attribute to your own shared resource.
|
|
81
|
+
|
|
72
82
|
See the following [getting started samples](https://github.com/microsoft/agent-framework/tree/main/python/samples/01-get-started) for more information.
|
|
73
83
|
|
|
74
84
|
## 2. Create a Simple Agent
|
|
@@ -42,7 +42,11 @@ from .exceptions import (
|
|
|
42
42
|
)
|
|
43
43
|
|
|
44
44
|
_LAZY_MODULE_EXPORTS: Final[Mapping[str, tuple[str, ...]]] = {
|
|
45
|
-
"._agent_hooks": (
|
|
45
|
+
"._agent_hooks": (
|
|
46
|
+
"create_agent_hooks_middleware",
|
|
47
|
+
"create_agent_hooks_middleware_from_declaration",
|
|
48
|
+
"create_agent_hooks_middleware_from_emitter",
|
|
49
|
+
),
|
|
46
50
|
"._agents": ("Agent", "BaseAgent", "RawAgent", "SupportsAgentRun"),
|
|
47
51
|
"._clients": (
|
|
48
52
|
"BaseChatClient",
|
|
@@ -69,6 +73,7 @@ _LAZY_MODULE_EXPORTS: Final[Mapping[str, tuple[str, ...]]] = {
|
|
|
69
73
|
"SUMMARIZED_BY_SUMMARY_ID_KEY",
|
|
70
74
|
"SUMMARY_OF_GROUP_IDS_KEY",
|
|
71
75
|
"SUMMARY_OF_MESSAGE_IDS_KEY",
|
|
76
|
+
"AgentTriggeredCompactionStrategy",
|
|
72
77
|
"CharacterEstimatorTokenizer",
|
|
73
78
|
"CompactionProvider",
|
|
74
79
|
"CompactionStrategy",
|
|
@@ -80,6 +85,7 @@ _LAZY_MODULE_EXPORTS: Final[Mapping[str, tuple[str, ...]]] = {
|
|
|
80
85
|
"TokenizerProtocol",
|
|
81
86
|
"ToolResultCompactionStrategy",
|
|
82
87
|
"TruncationStrategy",
|
|
88
|
+
"UnloadSkillsCompactionStrategy",
|
|
83
89
|
"annotate_message_groups",
|
|
84
90
|
"apply_compaction",
|
|
85
91
|
"included_messages",
|
|
@@ -452,6 +458,7 @@ __all__ = [
|
|
|
452
458
|
"AgentResponseUpdate",
|
|
453
459
|
"AgentRunInputs",
|
|
454
460
|
"AgentSession",
|
|
461
|
+
"AgentTriggeredCompactionStrategy",
|
|
455
462
|
"AggregatingSkillsSource",
|
|
456
463
|
"Annotation",
|
|
457
464
|
"BackgroundAgentsProvider",
|
|
@@ -645,6 +652,7 @@ __all__ = [
|
|
|
645
652
|
"ToolTypes",
|
|
646
653
|
"TruncationStrategy",
|
|
647
654
|
"TypeCompatibilityError",
|
|
655
|
+
"UnloadSkillsCompactionStrategy",
|
|
648
656
|
"UpdateT",
|
|
649
657
|
"UsageDetails",
|
|
650
658
|
"UserInputRequiredException",
|
|
@@ -682,6 +690,7 @@ __all__ = [
|
|
|
682
690
|
"background_tasks_running_message",
|
|
683
691
|
"chat_middleware",
|
|
684
692
|
"create_agent_hooks_middleware",
|
|
693
|
+
"create_agent_hooks_middleware_from_declaration",
|
|
685
694
|
"create_agent_hooks_middleware_from_emitter",
|
|
686
695
|
"create_always_approve_tool_response",
|
|
687
696
|
"create_always_approve_tool_with_arguments_response",
|
|
@@ -4,7 +4,11 @@ from typing import Final
|
|
|
4
4
|
|
|
5
5
|
__version__: Final[str]
|
|
6
6
|
|
|
7
|
-
from ._agent_hooks import
|
|
7
|
+
from ._agent_hooks import (
|
|
8
|
+
create_agent_hooks_middleware,
|
|
9
|
+
create_agent_hooks_middleware_from_declaration,
|
|
10
|
+
create_agent_hooks_middleware_from_emitter,
|
|
11
|
+
)
|
|
8
12
|
from ._agents import Agent, BaseAgent, RawAgent, SupportsAgentRun
|
|
9
13
|
from ._clients import (
|
|
10
14
|
BaseChatClient,
|
|
@@ -31,6 +35,7 @@ from ._compaction import (
|
|
|
31
35
|
SUMMARIZED_BY_SUMMARY_ID_KEY,
|
|
32
36
|
SUMMARY_OF_GROUP_IDS_KEY,
|
|
33
37
|
SUMMARY_OF_MESSAGE_IDS_KEY,
|
|
38
|
+
AgentTriggeredCompactionStrategy,
|
|
34
39
|
CharacterEstimatorTokenizer,
|
|
35
40
|
CompactionProvider,
|
|
36
41
|
CompactionStrategy,
|
|
@@ -42,6 +47,7 @@ from ._compaction import (
|
|
|
42
47
|
TokenizerProtocol,
|
|
43
48
|
ToolResultCompactionStrategy,
|
|
44
49
|
TruncationStrategy,
|
|
50
|
+
UnloadSkillsCompactionStrategy,
|
|
45
51
|
annotate_message_groups,
|
|
46
52
|
apply_compaction,
|
|
47
53
|
included_messages,
|
|
@@ -407,6 +413,7 @@ __all__ = [
|
|
|
407
413
|
"AgentResponseUpdate",
|
|
408
414
|
"AgentRunInputs",
|
|
409
415
|
"AgentSession",
|
|
416
|
+
"AgentTriggeredCompactionStrategy",
|
|
410
417
|
"AggregatingSkillsSource",
|
|
411
418
|
"Annotation",
|
|
412
419
|
"BackgroundAgentsProvider",
|
|
@@ -600,6 +607,7 @@ __all__ = [
|
|
|
600
607
|
"ToolTypes",
|
|
601
608
|
"TruncationStrategy",
|
|
602
609
|
"TypeCompatibilityError",
|
|
610
|
+
"UnloadSkillsCompactionStrategy",
|
|
603
611
|
"UpdateT",
|
|
604
612
|
"UsageDetails",
|
|
605
613
|
"UserInputRequiredException",
|
|
@@ -637,6 +645,7 @@ __all__ = [
|
|
|
637
645
|
"background_tasks_running_message",
|
|
638
646
|
"chat_middleware",
|
|
639
647
|
"create_agent_hooks_middleware",
|
|
648
|
+
"create_agent_hooks_middleware_from_declaration",
|
|
640
649
|
"create_agent_hooks_middleware_from_emitter",
|
|
641
650
|
"create_always_approve_tool_response",
|
|
642
651
|
"create_always_approve_tool_with_arguments_response",
|
|
@@ -10,14 +10,17 @@ control contract as one coherent feature on the framework's native middleware se
|
|
|
10
10
|
- ``pre_tool_call`` / ``post_tool_call`` ride the function seam.
|
|
11
11
|
|
|
12
12
|
The public entry points are :func:`create_agent_hooks_middleware` (one agent-hooks
|
|
13
|
-
session per run)
|
|
14
|
-
session)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
session per run), :func:`create_agent_hooks_middleware_from_emitter` (host-owned
|
|
14
|
+
session) and :func:`create_agent_hooks_middleware_from_declaration` (one session per
|
|
15
|
+
run, with the configuration and the interceptor bindings read from a host declaration
|
|
16
|
+
document, spec section 7.7). All return a :class:`~agent_framework.MiddlewareBundle`: the
|
|
17
|
+
three middleware implementations are deliberately private and travel as one indivisible
|
|
18
|
+
unit, because installing only part of them would enforce only part of the control
|
|
19
|
+
contract. Install exactly one bundle per agent, placed first in the middleware list:
|
|
20
|
+
middleware listed before the bundle runs outside the enforcement boundary (outer position
|
|
21
|
+
is outer trust) — e.g. a function middleware placed before the bundle can substitute a
|
|
22
|
+
tool result that the tool seam never brackets; the final ``output`` point still guards
|
|
23
|
+
whatever egresses.
|
|
21
24
|
|
|
22
25
|
Enforcement semantics (``mode="enforce"``):
|
|
23
26
|
|
|
@@ -101,6 +104,7 @@ import asyncio
|
|
|
101
104
|
import contextlib
|
|
102
105
|
import json
|
|
103
106
|
import logging
|
|
107
|
+
import os
|
|
104
108
|
import uuid
|
|
105
109
|
from collections.abc import AsyncGenerator, Awaitable, Callable, Mapping, Sequence
|
|
106
110
|
from contextvars import ContextVar
|
|
@@ -142,9 +146,13 @@ if TYPE_CHECKING:
|
|
|
142
146
|
from agent_hooks import (
|
|
143
147
|
AgentContextBuilder,
|
|
144
148
|
ApprovalResolver,
|
|
149
|
+
BindingContext,
|
|
145
150
|
CompositionConfig,
|
|
146
151
|
EmitOutcome,
|
|
147
152
|
EnforcementMode,
|
|
153
|
+
HostDeclaration,
|
|
154
|
+
HostRegistry,
|
|
155
|
+
HostSurface,
|
|
148
156
|
IdentityProvider,
|
|
149
157
|
InterceptionBlocked,
|
|
150
158
|
InterceptionEmitter,
|
|
@@ -164,6 +172,22 @@ _SDK_MISSING_MESSAGE = (
|
|
|
164
172
|
"Please install it with `pip install agent-hooks-sdk`."
|
|
165
173
|
)
|
|
166
174
|
|
|
175
|
+
_DECLARATION_SDK_MISSING_MESSAGE = (
|
|
176
|
+
"Loading a host declaration requires `agent-hooks-sdk` 0.1.0b2 or later (the first release "
|
|
177
|
+
"that accepts the agent-hooks-declaration/1.0 document). Please upgrade it with "
|
|
178
|
+
"`pip install --upgrade agent-hooks-sdk`."
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# The binding kind this framework registers when a factory receives ``interceptors``:
|
|
182
|
+
# ``{"id": "egress", "kind": "agent_framework.interceptor", "config": {"name": "egress"}}``
|
|
183
|
+
# binds the interceptor supplied under that name (``name`` defaults to the binding id).
|
|
184
|
+
_DECLARATION_KIND = "agent_framework.interceptor"
|
|
185
|
+
# The code surface a declaration is resolved against (spec section 7.7.4): every point, the
|
|
186
|
+
# capabilities the conformance claim lists, and the ``terminate`` posture this module
|
|
187
|
+
# implements at the tool seam.
|
|
188
|
+
_DECLARATION_CAPABILITIES = ("model_calls", "tool_calls", "int64_json", "bigint_json", "host_declaration")
|
|
189
|
+
_DECLARATION_POSTURE = "terminate"
|
|
190
|
+
|
|
167
191
|
_TRIO_REQUIRED_MESSAGE = (
|
|
168
192
|
"agent-hooks {seam} middleware was invoked without an active agent-hooks run. "
|
|
169
193
|
"The middleware bundle returned by create_agent_hooks_middleware() must be installed "
|
|
@@ -211,6 +235,21 @@ def _require_sdk() -> None:
|
|
|
211
235
|
del AgentContextBuilder, EnforcementMode, InterceptionBlocked, InterceptionEmitter
|
|
212
236
|
|
|
213
237
|
|
|
238
|
+
def _require_declaration_sdk() -> None:
|
|
239
|
+
"""Like :func:`_require_sdk`, for the host-declaration loader (``agent-hooks-sdk`` 0.1.0b2+).
|
|
240
|
+
|
|
241
|
+
An installed SDK that predates the loader raises ``ImportError`` on these names; that case
|
|
242
|
+
gets an upgrade hint instead of a bare "cannot import name" message.
|
|
243
|
+
"""
|
|
244
|
+
_require_sdk()
|
|
245
|
+
try:
|
|
246
|
+
from agent_hooks import HostDeclaration, HostRegistry, HostSurface
|
|
247
|
+
except ImportError as exc:
|
|
248
|
+
raise ImportError(_DECLARATION_SDK_MISSING_MESSAGE) from exc
|
|
249
|
+
else:
|
|
250
|
+
del HostDeclaration, HostRegistry, HostSurface
|
|
251
|
+
|
|
252
|
+
|
|
214
253
|
# region Run state
|
|
215
254
|
|
|
216
255
|
|
|
@@ -227,6 +266,9 @@ class _AgentHooksConfig:
|
|
|
227
266
|
record_sink: Callable[[InterceptionRecord], None] | None
|
|
228
267
|
emitter: InterceptionEmitter | None
|
|
229
268
|
builder: AgentContextBuilder | None
|
|
269
|
+
# Set by the host-declaration factory: every run loads a fresh emitter from this pair.
|
|
270
|
+
declaration: HostDeclaration | None = None
|
|
271
|
+
registry: HostRegistry | None = None
|
|
230
272
|
|
|
231
273
|
|
|
232
274
|
@dataclass
|
|
@@ -1036,17 +1078,23 @@ class _AgentHooksAgentMiddleware(_AgentHooksMiddlewareBase, AgentMiddleware):
|
|
|
1036
1078
|
session_id=uuid.uuid4().hex,
|
|
1037
1079
|
agent_name=str(agent_name) if agent_name else None,
|
|
1038
1080
|
)
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1081
|
+
if config.declaration is not None and config.registry is not None:
|
|
1082
|
+
# One session per run, configured by the declaration: the loader rebuilds the
|
|
1083
|
+
# sealed emitter from the same document and registry the factory validated, so
|
|
1084
|
+
# every run gets the same resolved declaration and a fresh session (spec 7.7.7).
|
|
1085
|
+
emitter = InterceptionEmitter.from_declaration(config.declaration, config.registry)
|
|
1086
|
+
else:
|
|
1087
|
+
kwargs: dict[str, Any] = {
|
|
1088
|
+
"resolver": config.resolver,
|
|
1089
|
+
"timeout": config.timeout,
|
|
1090
|
+
"composition": config.composition,
|
|
1091
|
+
"identity_provider": config.identity_provider,
|
|
1092
|
+
}
|
|
1093
|
+
if config.mode is not None:
|
|
1094
|
+
kwargs["mode"] = config.mode
|
|
1095
|
+
emitter = InterceptionEmitter(**kwargs)
|
|
1096
|
+
for name, interceptor in config.interceptors:
|
|
1097
|
+
emitter.register(interceptor, name)
|
|
1050
1098
|
if config.record_sink is not None:
|
|
1051
1099
|
emitter.set_record_sink(config.record_sink)
|
|
1052
1100
|
return _RunState(emitter=emitter, builder=builder, session_scoped=False, config=config)
|
|
@@ -1698,6 +1746,212 @@ def create_agent_hooks_middleware_from_emitter(
|
|
|
1698
1746
|
return _build_bundle(config)
|
|
1699
1747
|
|
|
1700
1748
|
|
|
1749
|
+
def _host_surface() -> HostSurface:
|
|
1750
|
+
from agent_hooks import HostSurface
|
|
1751
|
+
|
|
1752
|
+
return HostSurface.from_capabilities(_DECLARATION_CAPABILITIES, tool_seam_host_error=_DECLARATION_POSTURE)
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
def _host_registry() -> HostRegistry:
|
|
1756
|
+
"""A fresh registry over this framework's surface (the declaration factory builds one per call)."""
|
|
1757
|
+
from agent_hooks import HostRegistry
|
|
1758
|
+
|
|
1759
|
+
return HostRegistry(_host_surface())
|
|
1760
|
+
|
|
1761
|
+
|
|
1762
|
+
def _interceptor_kind_resolver(interceptors: Mapping[str, Interceptor]) -> Callable[[Any, BindingContext], Interceptor]:
|
|
1763
|
+
"""The resolver behind the ``agent_framework.interceptor`` kind.
|
|
1764
|
+
|
|
1765
|
+
``config`` is ``{}`` or ``{"name": "<key>"}``; the key defaults to the binding id. Anything
|
|
1766
|
+
else refuses the binding (``declaration_error:binding_rejected``). Messages name the binding
|
|
1767
|
+
id (the loader prints ids itself) but never echo the config, as spec section 7.7.5 requires.
|
|
1768
|
+
"""
|
|
1769
|
+
|
|
1770
|
+
def resolve(config: Any, binding: BindingContext) -> Interceptor:
|
|
1771
|
+
if not isinstance(config, Mapping):
|
|
1772
|
+
raise ValueError(f"binding {binding.id!r}: config must be an object with an optional 'name' member")
|
|
1773
|
+
members = cast("Mapping[str, Any]", config) # a JSON object: string keys
|
|
1774
|
+
if set(members) - {"name"}:
|
|
1775
|
+
raise ValueError(f"binding {binding.id!r}: config accepts only the 'name' member")
|
|
1776
|
+
name: Any = members.get("name", binding.id)
|
|
1777
|
+
if not isinstance(name, str):
|
|
1778
|
+
raise ValueError(f"binding {binding.id!r}: config.name must be a string")
|
|
1779
|
+
try:
|
|
1780
|
+
return interceptors[name]
|
|
1781
|
+
except KeyError:
|
|
1782
|
+
raise ValueError(f"binding {binding.id!r}: no interceptor was supplied under the name it binds") from None
|
|
1783
|
+
|
|
1784
|
+
return resolve
|
|
1785
|
+
|
|
1786
|
+
|
|
1787
|
+
@experimental(feature_id=ExperimentalFeature.AGENT_HOOKS)
|
|
1788
|
+
def create_agent_hooks_middleware_from_declaration(
|
|
1789
|
+
declaration: HostDeclaration | Mapping[str, Any] | str | os.PathLike[str],
|
|
1790
|
+
*,
|
|
1791
|
+
interceptors: Mapping[str, Interceptor] | None = None,
|
|
1792
|
+
configure_registry: Callable[[HostRegistry], object] | None = None,
|
|
1793
|
+
record_sink: Callable[[InterceptionRecord], None] | None = None,
|
|
1794
|
+
) -> MiddlewareBundle:
|
|
1795
|
+
"""Build the agent-hooks middleware bundle from a host declaration.
|
|
1796
|
+
|
|
1797
|
+
A host declaration (spec section 7.7) is one JSON document that fixes the enforcement
|
|
1798
|
+
configuration (mode, composition, identity provider, approval resolver and redactor,
|
|
1799
|
+
timeouts, record bound), the declared surface and the interceptor bindings. The loader
|
|
1800
|
+
validates it against this framework's code surface and the names registered in code, and
|
|
1801
|
+
refuses anything the framework cannot honour before any emission. Enforcement semantics,
|
|
1802
|
+
the one-session-per-run model and the composition-order requirements are those of
|
|
1803
|
+
:func:`create_agent_hooks_middleware`; every record additionally carries the contract
|
|
1804
|
+
version the emitter was built from (``declaration: "agent-hooks-declaration/1.0"``).
|
|
1805
|
+
|
|
1806
|
+
Bindings name a kind the host registered in code; a kind is a lookup key, never a module
|
|
1807
|
+
or class the loader imports. Passing ``interceptors`` registers the framework's own kind,
|
|
1808
|
+
``agent_framework.interceptor``: a binding ``{"id": "egress", "kind":
|
|
1809
|
+
"agent_framework.interceptor"}`` runs the interceptor supplied as ``interceptors["egress"]``
|
|
1810
|
+
(``config: {"name": ...}`` picks a different key). Other kinds, custom identity providers,
|
|
1811
|
+
approval resolvers and approval redactors are registered through ``configure_registry``.
|
|
1812
|
+
Every call builds a fresh ``agent_hooks.HostRegistry`` over the surface this middleware
|
|
1813
|
+
implements (all eight points; ``model_calls``, ``tool_calls``, ``int64_json``,
|
|
1814
|
+
``bigint_json`` and ``host_declaration``; posture ``tool_seam_host_error: terminate``;
|
|
1815
|
+
buffered streaming), registers ``agent_framework.interceptor`` when ``interceptors`` is
|
|
1816
|
+
given, hands the registry to ``configure_registry``, then validates the document against
|
|
1817
|
+
it. The registry never leaves the factory and nothing caller-owned is touched, so a
|
|
1818
|
+
refused document or a raising callback leaves nothing behind for the next call.
|
|
1819
|
+
|
|
1820
|
+
The emitter the loader builds is sealed, so each run loads a fresh one from the same
|
|
1821
|
+
document and registry (kind resolvers run once at construction and once per run); the
|
|
1822
|
+
interceptors bound through ``agent_framework.interceptor`` are the supplied instances and
|
|
1823
|
+
stay shared across runs, exactly as with :func:`create_agent_hooks_middleware`. To scope
|
|
1824
|
+
one declaration-built session across several runs instead, build the emitter yourself
|
|
1825
|
+
with ``agent_hooks.InterceptionEmitter.from_declaration_path`` (or ``_json`` / ``_value``)
|
|
1826
|
+
and pass it to :func:`create_agent_hooks_middleware_from_emitter`.
|
|
1827
|
+
|
|
1828
|
+
Note:
|
|
1829
|
+
A document's ``configuration.posture.tool_seam_host_error`` must equal the posture the
|
|
1830
|
+
code implements, and the spec default is ``continue``, so every document for this
|
|
1831
|
+
framework has to write ``"posture": {"tool_seam_host_error": "terminate"}`` or the
|
|
1832
|
+
loader refuses it with ``declaration_error:surface_unsupported``.
|
|
1833
|
+
|
|
1834
|
+
Args:
|
|
1835
|
+
declaration: The document, in one of three forms. An ``agent_hooks.HostDeclaration``
|
|
1836
|
+
(for example from ``agent_hooks.DeclarationBuilder``, or
|
|
1837
|
+
``agent_hooks.HostDeclaration.from_json(text)`` for JSON text you already hold) is
|
|
1838
|
+
used as is. A mapping (any ``Mapping``; it is copied into a ``dict`` for the SDK and
|
|
1839
|
+
its members must be JSON values) is the document as a value. A ``str`` or
|
|
1840
|
+
``os.PathLike`` is the path of the document file, read once through
|
|
1841
|
+
``agent_hooks.HostDeclaration.from_path`` (a regular UTF-8 file of at most 1 MiB; an
|
|
1842
|
+
unreadable file is ``agent_hooks.DeclarationError`` with class ``unreadable``).
|
|
1843
|
+
JSON text is not accepted directly: a string is always a path.
|
|
1844
|
+
|
|
1845
|
+
Keyword Args:
|
|
1846
|
+
interceptors: Interceptors by name for the ``agent_framework.interceptor`` kind.
|
|
1847
|
+
``None`` leaves the kind unregistered, so a document that uses it is refused.
|
|
1848
|
+
configure_registry: Called at most once, with the fresh ``agent_hooks.HostRegistry``
|
|
1849
|
+
built for this call, to register the host's own binding kinds, identity providers,
|
|
1850
|
+
approval resolvers and approval redactors (``registry.kind(...)``,
|
|
1851
|
+
``registry.identity_provider(...)``, ``registry.approval_resolver(...)``,
|
|
1852
|
+
``registry.approval_redactor(...)``) before the document is validated. A file that
|
|
1853
|
+
cannot be read (class ``unreadable``) or a value that cannot be serialized (class
|
|
1854
|
+
``malformed``) is refused before the callback runs. ``None`` registers nothing of
|
|
1855
|
+
the host's own. A callback that raises propagates as is; nothing is cached, so the
|
|
1856
|
+
next call starts from a fresh registry.
|
|
1857
|
+
record_sink: Optional callable receiving every interception record.
|
|
1858
|
+
|
|
1859
|
+
Returns:
|
|
1860
|
+
The middleware bundle to pass (as one element) to ``Agent(middleware=...)``.
|
|
1861
|
+
|
|
1862
|
+
Raises:
|
|
1863
|
+
ModuleNotFoundError: If the optional ``agent-hooks-sdk`` package is not installed.
|
|
1864
|
+
ImportError: If the installed ``agent-hooks-sdk`` predates the host-declaration loader.
|
|
1865
|
+
agent_hooks.DeclarationError: If the loader refuses the document (an unreadable file,
|
|
1866
|
+
unsupported version, unknown member, a posture or surface the framework does not
|
|
1867
|
+
implement, an unregistered name or kind, a binding its kind resolver rejects, and
|
|
1868
|
+
so on).
|
|
1869
|
+
ValueError: If ``configure_registry`` registers ``agent_framework.interceptor`` while
|
|
1870
|
+
``interceptors`` is also given, or registers any other name twice or under the
|
|
1871
|
+
wrong grammar (the SDK's own registry checks, raised as they are); or if the
|
|
1872
|
+
document declares no bindings, since an emitter with zero interceptors fails closed
|
|
1873
|
+
on every emission (the same rule as :func:`create_agent_hooks_middleware`).
|
|
1874
|
+
|
|
1875
|
+
Examples:
|
|
1876
|
+
.. code-block:: python
|
|
1877
|
+
|
|
1878
|
+
from agent_framework import Agent, create_agent_hooks_middleware_from_declaration
|
|
1879
|
+
|
|
1880
|
+
declaration = {
|
|
1881
|
+
"declaration": "agent-hooks-declaration/1.0",
|
|
1882
|
+
"configuration": {"posture": {"tool_seam_host_error": "terminate"}},
|
|
1883
|
+
"bindings": [{"id": "egress", "kind": "agent_framework.interceptor"}],
|
|
1884
|
+
}
|
|
1885
|
+
agent = Agent(
|
|
1886
|
+
client=client,
|
|
1887
|
+
name="assistant",
|
|
1888
|
+
middleware=[
|
|
1889
|
+
create_agent_hooks_middleware_from_declaration(declaration, interceptors={"egress": EgressGuard()})
|
|
1890
|
+
],
|
|
1891
|
+
)
|
|
1892
|
+
|
|
1893
|
+
A host kind registered through ``configure_registry``: the document is read once from
|
|
1894
|
+
the file and binds ``{"id": "guard", "kind": "acme.guard", "config": {...}}``. The
|
|
1895
|
+
callback's return value is ignored, so a one-line lambda over the chaining registry
|
|
1896
|
+
methods works:
|
|
1897
|
+
|
|
1898
|
+
.. code-block:: python
|
|
1899
|
+
|
|
1900
|
+
bundle = create_agent_hooks_middleware_from_declaration(
|
|
1901
|
+
"policy/declaration.json",
|
|
1902
|
+
configure_registry=lambda registry: registry.kind("acme.guard", acme_guard),
|
|
1903
|
+
)
|
|
1904
|
+
"""
|
|
1905
|
+
_require_declaration_sdk()
|
|
1906
|
+
from agent_hooks import HostDeclaration, InterceptionEmitter
|
|
1907
|
+
|
|
1908
|
+
if isinstance(declaration, HostDeclaration):
|
|
1909
|
+
document = declaration
|
|
1910
|
+
elif isinstance(declaration, (str, os.PathLike)):
|
|
1911
|
+
# A string is a path, never JSON text (``HostDeclaration.from_json`` is the text path).
|
|
1912
|
+
document = HostDeclaration.from_path(declaration)
|
|
1913
|
+
else:
|
|
1914
|
+
# ``HostDeclaration.from_value`` serializes with ``json.dumps``, which takes a ``dict`` but no
|
|
1915
|
+
# other ``Mapping`` (``MappingProxyType``, ``UserDict``). Anything that is not a mapping goes
|
|
1916
|
+
# through as given, so the SDK's own refusal applies (``malformed``: the root is not an object).
|
|
1917
|
+
value: Any = declaration
|
|
1918
|
+
if isinstance(value, Mapping):
|
|
1919
|
+
value = dict(cast("Mapping[str, Any]", value))
|
|
1920
|
+
document = HostDeclaration.from_value(value)
|
|
1921
|
+
|
|
1922
|
+
# A registry for this call only: it is never handed back, so a refused document or a raising
|
|
1923
|
+
# callback cannot poison a later call, and nothing caller-owned is mutated.
|
|
1924
|
+
registry = _host_registry()
|
|
1925
|
+
if interceptors is not None:
|
|
1926
|
+
registry.kind(_DECLARATION_KIND, _interceptor_kind_resolver(dict(interceptors)))
|
|
1927
|
+
if configure_registry is not None:
|
|
1928
|
+
configure_registry(registry)
|
|
1929
|
+
# Load once here so a refused document (every class of spec section 7.7.6, kind resolvers
|
|
1930
|
+
# included) raises ``agent_hooks.DeclarationError`` at construction, before any run.
|
|
1931
|
+
resolved = InterceptionEmitter.from_declaration(document, registry).declaration
|
|
1932
|
+
if resolved is None or not resolved.bindings:
|
|
1933
|
+
# The spec allows an empty-deny host that is written down; for an agent it means every
|
|
1934
|
+
# run is denied at ``input``, so refuse it here like ``create_agent_hooks_middleware``.
|
|
1935
|
+
raise ValueError(
|
|
1936
|
+
"create_agent_hooks_middleware_from_declaration requires at least one binding in the "
|
|
1937
|
+
"declaration (an emitter with zero interceptors fails closed on every emission)."
|
|
1938
|
+
)
|
|
1939
|
+
config = _AgentHooksConfig(
|
|
1940
|
+
interceptors=(),
|
|
1941
|
+
resolver=None,
|
|
1942
|
+
mode=None,
|
|
1943
|
+
composition=None,
|
|
1944
|
+
identity_provider=None,
|
|
1945
|
+
timeout=None,
|
|
1946
|
+
record_sink=record_sink,
|
|
1947
|
+
emitter=None,
|
|
1948
|
+
builder=None,
|
|
1949
|
+
declaration=document,
|
|
1950
|
+
registry=registry,
|
|
1951
|
+
)
|
|
1952
|
+
return _build_bundle(config)
|
|
1953
|
+
|
|
1954
|
+
|
|
1701
1955
|
def _build_bundle(config: _AgentHooksConfig) -> MiddlewareBundle:
|
|
1702
1956
|
mark_feature_used(FeatureIndex.CORE_AGENT_HOOKS)
|
|
1703
1957
|
return MiddlewareBundle([
|