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.
Files changed (112) hide show
  1. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/PKG-INFO +45 -35
  2. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/README.md +15 -5
  3. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/__init__.py +10 -1
  4. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/__init__.pyi +10 -1
  5. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_agent_hooks.py +273 -19
  6. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_agents.py +50 -42
  7. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_clients.py +67 -0
  8. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_compaction.py +557 -3
  9. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_feature_stage.py +1 -1
  10. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_filesystem.py +29 -0
  11. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_background_agents.py +10 -5
  12. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_file_access.py +233 -22
  13. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_loop.py +4 -3
  14. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_memory.py +9 -19
  15. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_todo.py +7 -12
  16. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_tool_approval.py +2 -3
  17. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_in_memory.py +278 -5
  18. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_mcp.py +988 -981
  19. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_sessions.py +28 -4
  20. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_skills.py +126 -76
  21. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_tools.py +56 -23
  22. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_types.py +129 -29
  23. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_agent.py +119 -19
  24. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_agent_executor.py +59 -8
  25. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_checkpoint.py +55 -16
  26. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_checkpoint_encoding.py +98 -7
  27. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_edge.py +32 -12
  28. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_edge_runner.py +10 -5
  29. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_functional.py +120 -14
  30. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_typing_utils.py +15 -0
  31. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_workflow_builder.py +2 -2
  32. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/ag_ui/__init__.py +2 -0
  33. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/ag_ui/__init__.pyi +2 -0
  34. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/observability.py +5 -1
  35. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/security.py +33 -24
  36. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/pyproject.toml +37 -30
  37. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/LICENSE +0 -0
  38. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_docstrings.py +0 -0
  39. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_evaluation.py +0 -0
  40. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/__init__.py +0 -0
  41. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_agent.py +0 -0
  42. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_agent.pyi +0 -0
  43. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_file_memory.py +0 -0
  44. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_harness/_mode.py +0 -0
  45. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_middleware.py +0 -0
  46. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_serialization.py +0 -0
  47. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_settings.py +0 -0
  48. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_telemetry.py +0 -0
  49. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_vector_filters.py +0 -0
  50. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_vectors.py +0 -0
  51. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/__init__.py +0 -0
  52. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_agent_utils.py +0 -0
  53. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_const.py +0 -0
  54. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_conversation_history.py +0 -0
  55. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_events.py +0 -0
  56. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_executor.py +0 -0
  57. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_function_executor.py +0 -0
  58. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_message_utils.py +0 -0
  59. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_model_utils.py +0 -0
  60. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_request_info_mixin.py +0 -0
  61. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_runner.py +0 -0
  62. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_runner_context.py +0 -0
  63. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_state.py +0 -0
  64. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_validation.py +0 -0
  65. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_viz.py +0 -0
  66. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_workflow.py +0 -0
  67. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_workflow_context.py +0 -0
  68. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/_workflows/_workflow_executor.py +0 -0
  69. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/a2a/__init__.py +0 -0
  70. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/a2a/__init__.pyi +0 -0
  71. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/amazon/__init__.py +0 -0
  72. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/amazon/__init__.pyi +0 -0
  73. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/anthropic/__init__.py +0 -0
  74. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/anthropic/__init__.pyi +0 -0
  75. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/azure/__init__.py +0 -0
  76. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/azure/__init__.pyi +0 -0
  77. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/chatkit/__init__.py +0 -0
  78. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/chatkit/__init__.pyi +0 -0
  79. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/declarative/__init__.py +0 -0
  80. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/declarative/__init__.pyi +0 -0
  81. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/devui/__init__.py +0 -0
  82. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/devui/__init__.pyi +0 -0
  83. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/exceptions.py +0 -0
  84. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/foundry/__init__.py +0 -0
  85. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/foundry/__init__.pyi +0 -0
  86. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/gemini/__init__.py +0 -0
  87. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/gemini/__init__.pyi +0 -0
  88. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/github/__init__.py +0 -0
  89. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/github/__init__.pyi +0 -0
  90. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/google/__init__.py +0 -0
  91. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/google/__init__.pyi +0 -0
  92. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/hyperlight/__init__.py +0 -0
  93. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/lab/__init__.py +0 -0
  94. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/mem0/__init__.py +0 -0
  95. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/mem0/__init__.pyi +0 -0
  96. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/microsoft/__init__.py +0 -0
  97. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/microsoft/__init__.pyi +0 -0
  98. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/mistral/__init__.py +0 -0
  99. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/mistral/__init__.pyi +0 -0
  100. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/monty/__init__.py +0 -0
  101. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/monty/__init__.pyi +0 -0
  102. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/ollama/__init__.py +0 -0
  103. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/ollama/__init__.pyi +0 -0
  104. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/openai/__init__.py +0 -0
  105. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/openai/__init__.pyi +0 -0
  106. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/orchestrations/__init__.py +0 -0
  107. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/orchestrations/__init__.pyi +0 -0
  108. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/py.typed +0 -0
  109. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/redis/__init__.py +0 -0
  110. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/redis/__init__.pyi +0 -0
  111. {agent_framework_core-1.22.0 → agent_framework_core-1.24.0}/agent_framework/tools/__init__.py +0 -0
  112. {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.22.0
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>=1.24.0,<2 ; extra == "all"
28
- Requires-Dist: agent-framework-a2a>=1.0.0b261015,<2 ; extra == "all"
29
- Requires-Dist: agent-framework-ag-ui>=1.6.0,<2 ; extra == "all"
30
- Requires-Dist: agent-framework-anthropic>=1.0.0b261015,<2 ; extra == "all"
31
- Requires-Dist: agent-framework-azure-ai-search>=1.0.0b261015,<2 ; extra == "all"
32
- Requires-Dist: agent-framework-azure-contentunderstanding>=1.0.0b261015,<2 ; extra == "all"
33
- Requires-Dist: agent-framework-azure-cosmos>=1.0.0b261015,<2 ; extra == "all"
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.0b261015,<2 ; extra == "all"
36
- Requires-Dist: agent-framework-chatkit>=1.0.0b261015,<2 ; extra == "all"
37
- Requires-Dist: agent-framework-claude>=1.0.0b261015,<2 ; extra == "all"
38
- Requires-Dist: agent-framework-copilotstudio>=1.0.0b261015,<2 ; extra == "all"
39
- Requires-Dist: agent-framework-declarative>=1.3.0,<2 ; extra == "all"
40
- Requires-Dist: agent-framework-devui>=1.0.0b261015,<2 ; extra == "all"
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.15.0,<2 ; extra == "all"
43
- Requires-Dist: agent-framework-foundry-hosting>=1.0.0b261015,<2 ; extra == "all"
44
- Requires-Dist: agent-framework-foundry-local>=1.0.0b261015,<2 ; extra == "all"
45
- Requires-Dist: agent-framework-gemini>=1.0.0b261015,<2 ; extra == "all"
46
- 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.0b261015,<2 ; extra == "all" and ( python_version < '3.15' 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.0b261015,<2 ; extra == "all"
49
- Requires-Dist: agent-framework-mistral>=1.0.0b261015,<2 ; extra == "all"
50
- Requires-Dist: agent-framework-monty>=1.0.0b261015,<2 ; extra == "all"
51
- Requires-Dist: agent-framework-ollama>=1.0.0b261015,<2 ; extra == "all"
52
- Requires-Dist: agent-framework-openai>=1.17.0,<2 ; extra == "all"
53
- Requires-Dist: agent-framework-orchestrations>=1.3.2,<2 ; extra == "all"
54
- Requires-Dist: agent-framework-purview>=1.0.0b261015,<2 ; extra == "all"
55
- Requires-Dist: agent-framework-redis>=1.0.0b261015,<2 ; extra == "all" and ( python_version < '3.15')
56
- Requires-Dist: agent-framework-tools>=1.0.0b261015,<2 ; extra == "all"
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.10–3.15
88
+ - Python: 3.11–3.15
89
89
  - OS: Windows, macOS, Linux
90
90
 
91
- Python 3.10 remains supported and tested for this release, but it is deprecated
92
- because upstream Python 3.10 has reached end of life. New environments should
93
- use Python 3.11 or later. Removing Python 3.10 support will be handled in a
94
- future release rather than by this compatibility update.
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.10–3.15
25
+ - Python: 3.11–3.15
26
26
  - OS: Windows, macOS, Linux
27
27
 
28
- Python 3.10 remains supported and tested for this release, but it is deprecated
29
- because upstream Python 3.10 has reached end of life. New environments should
30
- use Python 3.11 or later. Removing Python 3.10 support will be handled in a
31
- future release rather than by this compatibility update.
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": ("create_agent_hooks_middleware", "create_agent_hooks_middleware_from_emitter"),
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 create_agent_hooks_middleware, create_agent_hooks_middleware_from_emitter
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) and :func:`create_agent_hooks_middleware_from_emitter` (host-owned
14
- session). Both return a :class:`~agent_framework.MiddlewareBundle`: the three middleware
15
- implementations are deliberately private and travel as one indivisible unit, because
16
- installing only part of them would enforce only part of the control contract. Install
17
- exactly one bundle per agent, placed first in the middleware list: middleware listed
18
- before the bundle runs outside the enforcement boundary (outer position is outer trust)
19
- — e.g. a function middleware placed before the bundle can substitute a tool result that
20
- the tool seam never brackets; the final ``output`` point still guards whatever egresses.
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
- kwargs: dict[str, Any] = {
1040
- "resolver": config.resolver,
1041
- "timeout": config.timeout,
1042
- "composition": config.composition,
1043
- "identity_provider": config.identity_provider,
1044
- }
1045
- if config.mode is not None:
1046
- kwargs["mode"] = config.mode
1047
- emitter = InterceptionEmitter(**kwargs)
1048
- for name, interceptor in config.interceptors:
1049
- emitter.register(interceptor, name)
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([