agent-framework 1.23.0__tar.gz → 1.25.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.
@@ -1,15 +1,14 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agent-framework
3
- Version: 1.23.0
3
+ Version: 1.25.0
4
4
  Summary: Microsoft Agent Framework for building AI Agents with Python. This package contains core and a curated set of optional integrations.
5
5
  Author-email: Microsoft <af-support@microsoft.com>
6
- Requires-Python: >=3.10
6
+ Requires-Python: >=3.11
7
7
  Description-Content-Type: text/markdown
8
8
  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
@@ -17,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.14
17
16
  Classifier: Programming Language :: Python :: 3.15
18
17
  Classifier: Typing :: Typed
19
18
  License-File: LICENSE
20
- Requires-Dist: agent-framework-core[all]==1.23.0
19
+ Requires-Dist: agent-framework-core[all]==1.25.0
21
20
  Project-URL: homepage, https://aka.ms/agent-framework
22
21
  Project-URL: issues, https://github.com/microsoft/agent-framework/issues
23
22
  Project-URL: release_notes, https://github.com/microsoft/agent-framework/releases?q=tag%3Apython-1&expanded=true
@@ -65,14 +64,11 @@ This selective approach is useful when you know which integrations you need, and
65
64
 
66
65
  Supported Platforms:
67
66
 
68
- - Python: 3.10–3.15
67
+ - Python: 3.11–3.15
69
68
  - OS: Windows, macOS, Linux
70
69
 
71
- Python 3.10 remains supported and tested for this release, but it is deprecated
72
- because upstream Python 3.10 has reached end of life. New environments should
73
- use Python 3.11 or later. A future Agent Framework release will raise the
74
- minimum version separately; this release does not remove Python 3.10 from
75
- package metadata or CI.
70
+ Python 3.11 or later is required. Supported environments are subject to the
71
+ integration-specific limits below.
76
72
 
77
73
  ### Python 3.15 limitations
78
74
 
@@ -82,7 +78,6 @@ not provide exactly the same feature set as Python 3.14:
82
78
  | Area | Python 3.15 impact |
83
79
  | --- | --- |
84
80
  | Declarative Power Fx | `agent-framework-declarative` is installed, but its `powerfx` dependency is not. YAML values beginning with `=` produce a warning and remain unchanged instead of being evaluated. Declarative agents or workflows that rely on expressions may therefore use invalid literal values or fail later. |
85
- | Redis | `agent-framework-redis` is omitted from the standard install because RedisVL declares `Requires-Python <3.15`. Redis imports and Redis-backed history, context, and vector storage are unavailable. |
86
81
 
87
82
  ## 1. Setup API Keys
88
83
 
@@ -184,6 +179,46 @@ async def main():
184
179
  asyncio.run(main())
185
180
  ```
186
181
 
182
+ ### Connection and credential lifetimes
183
+
184
+ Chat clients support async context managers for deterministic cleanup:
185
+
186
+ ```python
187
+ from agent_framework import Agent, Message
188
+ from agent_framework.openai import OpenAIChatClient
189
+
190
+ async with OpenAIChatClient() as client:
191
+ response = await client.get_response([Message("user", ["Hello!"])])
192
+
193
+ # Alternatively, let the agent enter and exit its chat client's context.
194
+ async with Agent(client=OpenAIChatClient(), instructions="Be helpful.") as agent:
195
+ response = await agent.run("Hello!")
196
+ ```
197
+
198
+ Calling clients without a context manager remains supported; use `await client.close()` when finished.
199
+ Context exit releases connections created by the connector, including on exceptions. Caller-supplied SDK clients,
200
+ HTTP transports, and credentials remain caller-owned. In particular, closing an Azure SDK connection does not
201
+ close the credential supplied to it. Scope credentials outside the agent or client that uses them:
202
+
203
+ ```python
204
+ from azure.identity.aio import AzureCliCredential
205
+
206
+ async with AzureCliCredential() as credential:
207
+ async with OpenAIChatClient(
208
+ azure_endpoint="https://YOUR-RESOURCE.openai.azure.com",
209
+ model="YOUR-DEPLOYMENT",
210
+ credential=credential,
211
+ ) as client:
212
+ response = await client.get_response([Message("user", ["Hello!"])])
213
+ ```
214
+
215
+ Treat closing a resource-owning client as the end of its lifetime; reopening is SDK-dependent. Avoid overlapping
216
+ agent contexts sharing a connector-owned connection, since exiting either agent closes that connection. To share
217
+ an SDK client across agents, inject it into their chat clients and manage its lifetime outside those agent contexts.
218
+ `BaseChatClient` provides default context methods and a no-op `close()`, so custom subclasses do not need to
219
+ implement lifecycle methods unless they own resources. Protocol-only chat clients do not need context methods.
220
+ Inherited context exit also supports existing subclasses whose `close()` is synchronous.
221
+
187
222
  ## 4. Build an Agent with Tools and Functions
188
223
 
189
224
  Enhance your agent with custom tools and function calling:
@@ -39,14 +39,11 @@ This selective approach is useful when you know which integrations you need, and
39
39
 
40
40
  Supported Platforms:
41
41
 
42
- - Python: 3.10–3.15
42
+ - Python: 3.11–3.15
43
43
  - OS: Windows, macOS, Linux
44
44
 
45
- Python 3.10 remains supported and tested for this release, but it is deprecated
46
- because upstream Python 3.10 has reached end of life. New environments should
47
- use Python 3.11 or later. A future Agent Framework release will raise the
48
- minimum version separately; this release does not remove Python 3.10 from
49
- package metadata or CI.
45
+ Python 3.11 or later is required. Supported environments are subject to the
46
+ integration-specific limits below.
50
47
 
51
48
  ### Python 3.15 limitations
52
49
 
@@ -56,7 +53,6 @@ not provide exactly the same feature set as Python 3.14:
56
53
  | Area | Python 3.15 impact |
57
54
  | --- | --- |
58
55
  | Declarative Power Fx | `agent-framework-declarative` is installed, but its `powerfx` dependency is not. YAML values beginning with `=` produce a warning and remain unchanged instead of being evaluated. Declarative agents or workflows that rely on expressions may therefore use invalid literal values or fail later. |
59
- | Redis | `agent-framework-redis` is omitted from the standard install because RedisVL declares `Requires-Python <3.15`. Redis imports and Redis-backed history, context, and vector storage are unavailable. |
60
56
 
61
57
  ## 1. Setup API Keys
62
58
 
@@ -158,6 +154,46 @@ async def main():
158
154
  asyncio.run(main())
159
155
  ```
160
156
 
157
+ ### Connection and credential lifetimes
158
+
159
+ Chat clients support async context managers for deterministic cleanup:
160
+
161
+ ```python
162
+ from agent_framework import Agent, Message
163
+ from agent_framework.openai import OpenAIChatClient
164
+
165
+ async with OpenAIChatClient() as client:
166
+ response = await client.get_response([Message("user", ["Hello!"])])
167
+
168
+ # Alternatively, let the agent enter and exit its chat client's context.
169
+ async with Agent(client=OpenAIChatClient(), instructions="Be helpful.") as agent:
170
+ response = await agent.run("Hello!")
171
+ ```
172
+
173
+ Calling clients without a context manager remains supported; use `await client.close()` when finished.
174
+ Context exit releases connections created by the connector, including on exceptions. Caller-supplied SDK clients,
175
+ HTTP transports, and credentials remain caller-owned. In particular, closing an Azure SDK connection does not
176
+ close the credential supplied to it. Scope credentials outside the agent or client that uses them:
177
+
178
+ ```python
179
+ from azure.identity.aio import AzureCliCredential
180
+
181
+ async with AzureCliCredential() as credential:
182
+ async with OpenAIChatClient(
183
+ azure_endpoint="https://YOUR-RESOURCE.openai.azure.com",
184
+ model="YOUR-DEPLOYMENT",
185
+ credential=credential,
186
+ ) as client:
187
+ response = await client.get_response([Message("user", ["Hello!"])])
188
+ ```
189
+
190
+ Treat closing a resource-owning client as the end of its lifetime; reopening is SDK-dependent. Avoid overlapping
191
+ agent contexts sharing a connector-owned connection, since exiting either agent closes that connection. To share
192
+ an SDK client across agents, inject it into their chat clients and manage its lifetime outside those agent contexts.
193
+ `BaseChatClient` provides default context methods and a no-op `close()`, so custom subclasses do not need to
194
+ implement lifecycle methods unless they own resources. Protocol-only chat clients do not need context methods.
195
+ Inherited context exit also supports existing subclasses whose `close()` is synchronous.
196
+
161
197
  ## 4. Build an Agent with Tools and Functions
162
198
 
163
199
  Enhance your agent with custom tools and function calling:
@@ -1,18 +1,16 @@
1
1
  # Copyright (c) Microsoft. All rights reserved.
2
2
 
3
+ from __future__ import annotations
4
+
5
+ import tomllib as _toml
3
6
  from importlib import metadata as _metadata
4
7
  from pathlib import Path as _Path
5
8
  from typing import Any, cast
6
9
 
7
- try:
8
- import tomllib as _toml # type: ignore # Python 3.11+
9
- except ModuleNotFoundError: # Python 3.10
10
- import tomli as _toml # type: ignore
11
-
12
10
 
13
11
  def _load_pyproject() -> dict[str, Any]:
14
12
  pyproject = (_Path(__file__).resolve().parents[1] / "pyproject.toml").read_text("utf-8")
15
- return cast(dict[str, Any], _toml.loads(pyproject)) # type: ignore
13
+ return _toml.loads(pyproject)
16
14
 
17
15
 
18
16
  def _version() -> str:
@@ -3,8 +3,8 @@ name = "agent-framework"
3
3
  description = "Microsoft Agent Framework for building AI Agents with Python. This package contains core and a curated set of optional integrations."
4
4
  authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
5
5
  readme = "README.md"
6
- requires-python = ">=3.10"
7
- version = "1.23.0"
6
+ requires-python = ">=3.11"
7
+ version = "1.25.0"
8
8
  license-files = ["LICENSE"]
9
9
  urls.homepage = "https://aka.ms/agent-framework"
10
10
  urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
@@ -15,7 +15,6 @@ classifiers = [
15
15
  "Development Status :: 5 - Production/Stable",
16
16
  "Intended Audience :: Developers",
17
17
  "Programming Language :: Python :: 3",
18
- "Programming Language :: Python :: 3.10",
19
18
  "Programming Language :: Python :: 3.11",
20
19
  "Programming Language :: Python :: 3.12",
21
20
  "Programming Language :: Python :: 3.13",
@@ -24,14 +23,14 @@ classifiers = [
24
23
  "Typing :: Typed",
25
24
  ]
26
25
  dependencies = [
27
- "agent-framework-core[all]==1.23.0",
26
+ "agent-framework-core[all]==1.25.0",
28
27
  ]
29
28
 
30
29
  [dependency-groups]
31
30
  dev = [
32
31
  "uv==0.13.5",
33
- "pytest==9.1.1",
34
- "pytest-asyncio==1.4.0",
32
+ "pytest==9.2.0",
33
+ "pytest-asyncio==1.4.1",
35
34
  "pytest-cov==7.1.0",
36
35
  "pytest-xdist[psutil]==3.8.0",
37
36
  "pytest-timeout==2.4.0",
@@ -39,7 +38,7 @@ dev = [
39
38
  "azure-monitor-opentelemetry>=1.8.10,<2",
40
39
  "mcp",
41
40
  # Optional SDK used by the agent-hooks tests and isolated source checks.
42
- "agent-hooks-sdk>=0.1.0a4,<0.2",
41
+ "agent-hooks-sdk>=0.1.0b2,<0.2",
43
42
  "opentelemetry-sdk",
44
43
  # Task runtime used by every supported Python version.
45
44
  "poethepoet==0.49.0",
@@ -47,7 +46,6 @@ dev = [
47
46
  tool-runtime = [
48
47
  "packaging==26.3",
49
48
  "rich>=13.7.1,<16.0.0",
50
- 'tomli==2.5.0; python_version < "3.11"',
51
49
  ]
52
50
  tool-hooks = [
53
51
  "prek==0.5.7",
@@ -108,6 +106,7 @@ agent-framework-mem0 = { workspace = true }
108
106
  agent-framework-mistral = { workspace = true }
109
107
  agent-framework-mongodb = { workspace = true }
110
108
  agent-framework-monty = { workspace = true }
109
+ agent-framework-nvidia = { workspace = true }
111
110
  agent-framework-ollama = { workspace = true }
112
111
  agent-framework-openai = { workspace = true }
113
112
  agent-framework-oracle = { workspace = true }
@@ -123,7 +122,7 @@ agent-framework-typesafe = { workspace = true }
123
122
 
124
123
  [tool.ruff]
125
124
  line-length = 120
126
- target-version = "py310"
125
+ target-version = "py311"
127
126
  fix = true
128
127
  include = ["*.py", "*.pyi", "**/pyproject.toml", "*.ipynb"]
129
128
  exclude = ["scripts"]
@@ -159,6 +158,7 @@ select = [
159
158
  "W", # pycodestyle warning checks
160
159
  ]
161
160
  ignore = [
161
+ "ASYNC109", # timeout parameters are intentional API contracts
162
162
  "D100", # allow missing docstring in public module
163
163
  "D104", # allow missing docstring in public package
164
164
  "D421", # allow property docstrings that start with a verb
@@ -228,7 +228,7 @@ reportUnnecessaryTypeIgnoreComment = "error"
228
228
  # annotating every function. See docs/skills/python-code-quality.
229
229
  [tool.mypy]
230
230
  plugins = ['pydantic.mypy']
231
- python_version = "3.10"
231
+ python_version = "3.11"
232
232
  ignore_missing_imports = true
233
233
  check_untyped_defs = true
234
234
  disallow_untyped_defs = false
@@ -240,7 +240,7 @@ warn_unused_ignores = false
240
240
  show_error_codes = true
241
241
 
242
242
  # NumPy 2.5 stubs use Python 3.12 type-statement syntax while mypy intentionally
243
- # targets Python 3.10 for test typing; skip parsing NumPy internals.
243
+ # targets Python 3.11 for test typing; skip parsing NumPy internals.
244
244
  [[tool.mypy.overrides]]
245
245
  module = ["numpy", "numpy.*"]
246
246
  follow_imports = "skip"
@@ -354,10 +354,6 @@ sequence = [
354
354
  ]
355
355
  args = [{ name = "project", default = "*", options = ["-P", "--package"] }]
356
356
 
357
- [tool.poe.tasks.publish]
358
- help = "Publish built distributions with uv."
359
- cmd = "uv publish"
360
-
361
357
  # Dependency maintenance
362
358
  [tool.poe.tasks.upgrade-dev-dependency-pins]
363
359
  help = "Repin exact workspace development dependencies and on-demand tool requirements."
@@ -389,6 +385,14 @@ help = "Run the exhaustive workspace dependency-bound test+typing matrix, option
389
385
  shell = "python -m scripts.dependencies.validate_dependency_bounds --mode test --package \"$project\""
390
386
  args = [{ name = "project", default = "*", options = ["-P", "--package"] }]
391
387
 
388
+ [tool.poe.tasks.prepare-python-release]
389
+ help = "Generate .github/release-<fulltag>.json from version changes against the same base as release validation."
390
+ cmd = "python -m scripts.prepare_release --base-ref ${base_ref} --tag ${tag}"
391
+ args = [
392
+ { name = "base_ref", options = ["-B", "--base-ref"] },
393
+ { name = "tag", options = ["--tag"] },
394
+ ]
395
+
392
396
  [tool.poe.tasks.validate-python-release]
393
397
  help = "Refresh uv.lock, then run lower/upper import probes for changed package metadata on each package closure's minimum Python."
394
398
  executor = "simple"