From 340c6c98ab2739834befefe48333ac2598ea901d Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Tue, 20 Jan 2026 10:46:41 -0800 Subject: [PATCH 1/5] Upgrade to FastMCP 3.0, update get/set state --- pyproject.toml | 2 +- servers/auth_entra_mcp.py | 8 +- servers/auth_keycloak_mcp.py | 8 +- uv.lock | 159 ++++------------------------------- 4 files changed, 26 insertions(+), 151 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 104c67c..51e41df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ description = "Demonstration of Python FastMCP servers" readme = "README.md" requires-python = "==3.13.*" dependencies = [ - "fastmcp>=2.14.2", + "fastmcp==3.0.0b1", "debugpy>=1.8.0", "langchain-core>=0.3.0", "mcp>=1.3.0", diff --git a/servers/auth_entra_mcp.py b/servers/auth_entra_mcp.py index 715ec12..dbf189e 100644 --- a/servers/auth_entra_mcp.py +++ b/servers/auth_entra_mcp.py @@ -144,13 +144,13 @@ def _get_user_id(self): async def on_call_tool(self, context: MiddlewareContext, call_next): user_id = self._get_user_id() if context.fastmcp_context is not None: - context.fastmcp_context.set_state("user_id", user_id) + await context.fastmcp_context.set_state("user_id", user_id) return await call_next(context) async def on_read_resource(self, context: MiddlewareContext, call_next): user_id = self._get_user_id() if context.fastmcp_context is not None: - context.fastmcp_context.set_state("user_id", user_id) + await context.fastmcp_context.set_state("user_id", user_id) return await call_next(context) @@ -191,7 +191,7 @@ async def add_user_expense( try: # Read user_id stored by middleware - user_id = ctx.get_state("user_id") + user_id = await ctx.get_state("user_id") if not user_id: return "Error: Authentication required (no user_id present)" expense_id = str(uuid.uuid4()) @@ -217,7 +217,7 @@ async def get_user_expenses(ctx: Context): """Get the authenticated user's expense data from Cosmos DB.""" try: - user_id = ctx.get_state("user_id") + user_id = await ctx.get_state("user_id") if not user_id: return "Error: Authentication required (no user_id present)" query = "SELECT * FROM c WHERE c.user_id = @uid ORDER BY c.date DESC" diff --git a/servers/auth_keycloak_mcp.py b/servers/auth_keycloak_mcp.py index bd871e5..cd38e43 100644 --- a/servers/auth_keycloak_mcp.py +++ b/servers/auth_keycloak_mcp.py @@ -108,13 +108,13 @@ def _get_user_id(self): async def on_call_tool(self, context: MiddlewareContext, call_next): user_id = self._get_user_id() if context.fastmcp_context is not None: - context.fastmcp_context.set_state("user_id", user_id) + await context.fastmcp_context.set_state("user_id", user_id) return await call_next(context) async def on_read_resource(self, context: MiddlewareContext, call_next): user_id = self._get_user_id() if context.fastmcp_context is not None: - context.fastmcp_context.set_state("user_id", user_id) + await context.fastmcp_context.set_state("user_id", user_id) return await call_next(context) @@ -155,7 +155,7 @@ async def add_user_expense( try: # Read user_id stored by middleware - user_id = ctx.get_state("user_id") + user_id = await ctx.get_state("user_id") if not user_id: return "Error: Authentication required (no user_id present)" expense_id = str(uuid.uuid4()) @@ -181,7 +181,7 @@ async def get_user_expenses(ctx: Context): """Get the authenticated user's expense data from Cosmos DB.""" try: - user_id = ctx.get_state("user_id") + user_id = await ctx.get_state("user_id") if not user_id: return "Error: Authentication required (no user_id present)" query = "SELECT * FROM c WHERE c.user_id = @uid ORDER BY c.date DESC" diff --git a/uv.lock b/uv.lock index abdb12d..025a2b7 100644 --- a/uv.lock +++ b/uv.lock @@ -519,15 +519,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295 }, ] -[[package]] -name = "cloudpickle" -version = "3.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/27/fb/576f067976d320f5f0114a8d9fa1215425441bb35627b1993e5afd8111e5/cloudpickle-3.1.2.tar.gz", hash = "sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414", size = 22330 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl", hash = "sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a", size = 22228 }, -] - [[package]] name = "colorama" version = "0.4.6" @@ -703,24 +694,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317 }, ] -[[package]] -name = "fakeredis" -version = "2.33.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "redis" }, - { name = "sortedcontainers" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5f/f9/57464119936414d60697fcbd32f38909bb5688b616ae13de6e98384433e0/fakeredis-2.33.0.tar.gz", hash = "sha256:d7bc9a69d21df108a6451bbffee23b3eba432c21a654afc7ff2d295428ec5770", size = 175187 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6e/78/a850fed8aeef96d4a99043c90b818b2ed5419cd5b24a4049fd7cfb9f1471/fakeredis-2.33.0-py3-none-any.whl", hash = "sha256:de535f3f9ccde1c56672ab2fdd6a8efbc4f2619fc2f1acc87b8737177d71c965", size = 119605 }, -] - -[package.optional-dependencies] -lua = [ - { name = "lupa" }, -] - [[package]] name = "fastapi" version = "0.119.1" @@ -737,29 +710,32 @@ wheels = [ [[package]] name = "fastmcp" -version = "2.14.2" +version = "3.0.0b1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "authlib" }, { name = "cyclopts" }, { name = "exceptiongroup" }, { name = "httpx" }, + { name = "jsonref" }, { name = "jsonschema-path" }, { name = "mcp" }, { name = "openapi-pydantic" }, + { name = "opentelemetry-api" }, + { name = "packaging" }, { name = "platformdirs" }, { name = "py-key-value-aio", extra = ["disk", "keyring", "memory"] }, { name = "pydantic", extra = ["email"] }, - { name = "pydocket" }, { name = "pyperclip" }, { name = "python-dotenv" }, { name = "rich" }, { name = "uvicorn" }, + { name = "watchfiles" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d1/1e/e3528227688c248283f6d86869b1e900563ffc223eff00f4f923d2750365/fastmcp-2.14.2.tar.gz", hash = "sha256:bd23d1b808b6f446444f10114dac468b11bfb9153ed78628f5619763d0cf573e", size = 8272966 } +sdist = { url = "https://files.pythonhosted.org/packages/b6/b4/8b44030f3697ed1d106c79eedcf640451b8060cb52cc4f079d8ad3a2ef76/fastmcp-3.0.0b1.tar.gz", hash = "sha256:adeda5562a23cde8b3607b73ebccfe27efa3c2955eb2c03b0cdd551128b7eaaf", size = 11817449 } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/67/8456d39484fcb7afd0defed21918e773ed59a98b39e5b633328527c88367/fastmcp-2.14.2-py3-none-any.whl", hash = "sha256:e33cd622e1ebd5110af6a981804525b6cd41072e3c7d68268ed69ef3be651aca", size = 413279 }, + { url = "https://files.pythonhosted.org/packages/f2/23/9836025d2b8070cae295c805f51d9fd9da9228584c85290d8fef44d1cb34/fastmcp-3.0.0b1-py3-none-any.whl", hash = "sha256:e64dd54e94411ccc6ff63459eace8e55c79d15647917bc0c178414a642089750", size = 533457 }, ] [[package]] @@ -1139,6 +1115,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595 }, ] +[[package]] +name = "jsonref" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/0d/c1f3277e90ccdb50d33ed5ba1ec5b3f0a242ed8c1b1a85d3afeb68464dca/jsonref-1.1.0.tar.gz", hash = "sha256:32fe8e1d85af0fdefbebce950af85590b22b60f9e95443176adbde4e1ecea552", size = 8814 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/ec/e1db9922bceb168197a558a2b8c03a7963f1afe93517ddd3cf99f202f996/jsonref-1.1.0-py3-none-any.whl", hash = "sha256:590dc7773df6c21cbf948b5dac07a72a251db28b0238ceecce0a2abfa8ec30a9", size = 9425 }, +] + [[package]] name = "jsonschema" version = "4.25.1" @@ -1363,25 +1348,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/39/68/c49baec77c56dcf5698daaa66a097523063d55b2feaecc968000518521a1/logfire-4.17.0-py3-none-any.whl", hash = "sha256:1ed1064a4126f48503f7832ce6039425dff70128d145552d7981ac9ce2151b17", size = 232456 }, ] -[[package]] -name = "lupa" -version = "2.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b8/1c/191c3e6ec6502e3dbe25a53e27f69a5daeac3e56de1f73c0138224171ead/lupa-2.6.tar.gz", hash = "sha256:9a770a6e89576be3447668d7ced312cd6fd41d3c13c2462c9dc2c2ab570e45d9", size = 7240282 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/28/1d/21176b682ca5469001199d8b95fa1737e29957a3d185186e7a8b55345f2e/lupa-2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:663a6e58a0f60e7d212017d6678639ac8df0119bc13c2145029dcba084391310", size = 947232 }, - { url = "https://files.pythonhosted.org/packages/ce/4c/d327befb684660ca13cf79cd1f1d604331808f9f1b6fb6bf57832f8edf80/lupa-2.6-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:d1f5afda5c20b1f3217a80e9bc1b77037f8a6eb11612fd3ada19065303c8f380", size = 1908625 }, - { url = "https://files.pythonhosted.org/packages/66/8e/ad22b0a19454dfd08662237a84c792d6d420d36b061f239e084f29d1a4f3/lupa-2.6-cp313-cp313-macosx_11_0_x86_64.whl", hash = "sha256:26f2b3c085fe76e9119e48c1013c1cccdc1f51585d456858290475aa38e7089e", size = 981057 }, - { url = "https://files.pythonhosted.org/packages/5c/48/74859073ab276bd0566c719f9ca0108b0cfc1956ca0d68678d117d47d155/lupa-2.6-cp313-cp313-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:60d2f902c7b96fb8ab98493dcff315e7bb4d0b44dc9dd76eb37de575025d5685", size = 1156227 }, - { url = "https://files.pythonhosted.org/packages/09/6c/0e9ded061916877253c2266074060eb71ed99fb21d73c8c114a76725bce2/lupa-2.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a02d25dee3a3250967c36590128d9220ae02f2eda166a24279da0b481519cbff", size = 1035752 }, - { url = "https://files.pythonhosted.org/packages/dd/ef/f8c32e454ef9f3fe909f6c7d57a39f950996c37a3deb7b391fec7903dab7/lupa-2.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6eae1ee16b886b8914ff292dbefbf2f48abfbdee94b33a88d1d5475e02423203", size = 2069009 }, - { url = "https://files.pythonhosted.org/packages/53/dc/15b80c226a5225815a890ee1c11f07968e0aba7a852df41e8ae6fe285063/lupa-2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0edd5073a4ee74ab36f74fe61450148e6044f3952b8d21248581f3c5d1a58be", size = 1056301 }, - { url = "https://files.pythonhosted.org/packages/31/14/2086c1425c985acfb30997a67e90c39457122df41324d3c179d6ee2292c6/lupa-2.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0c53ee9f22a8a17e7d4266ad48e86f43771951797042dd51d1494aaa4f5f3f0a", size = 1170673 }, - { url = "https://files.pythonhosted.org/packages/10/e5/b216c054cf86576c0191bf9a9f05de6f7e8e07164897d95eea0078dca9b2/lupa-2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:de7c0f157a9064a400d828789191a96da7f4ce889969a588b87ec80de9b14772", size = 2162227 }, - { url = "https://files.pythonhosted.org/packages/59/2f/33ecb5bedf4f3bc297ceacb7f016ff951331d352f58e7e791589609ea306/lupa-2.6-cp313-cp313-win32.whl", hash = "sha256:ee9523941ae0a87b5b703417720c5d78f72d2f5bc23883a2ea80a949a3ed9e75", size = 1419558 }, - { url = "https://files.pythonhosted.org/packages/f9/b4/55e885834c847ea610e111d87b9ed4768f0afdaeebc00cd46810f25029f6/lupa-2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b1335a5835b0a25ebdbc75cf0bda195e54d133e4d994877ef025e218c2e59db9", size = 1683424 }, -] - [[package]] name = "markdown-it-py" version = "4.0.0" @@ -1871,20 +1837,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bc/46/e4a102e17205bb05a50dbf24ef0e92b66b648cd67db9a68865af06a242fd/opentelemetry_exporter_otlp_proto_http-1.39.0-py3-none-any.whl", hash = "sha256:5789cb1375a8b82653328c0ce13a054d285f774099faf9d068032a49de4c7862", size = 19639 }, ] -[[package]] -name = "opentelemetry-exporter-prometheus" -version = "0.60b0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "opentelemetry-api" }, - { name = "opentelemetry-sdk" }, - { name = "prometheus-client" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/93/da/8b81ff9d045fae7cac1e8bbf7ad59bf113d1008e483fc03e2cd3a0e620a3/opentelemetry_exporter_prometheus-0.60b0.tar.gz", hash = "sha256:c6ae33e52cdd1dbfed1f7436935df94eb03c725b57322026d04e6fbc37108e6e", size = 14975 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/18/18b662a6ecb8252db9e7457fd3c836729bf28b055b60505cbd4763ea9300/opentelemetry_exporter_prometheus-0.60b0-py3-none-any.whl", hash = "sha256:4f616397040257fae4c5e5272b57b47c13372e3b7f0f2db2427fd4dbe69c60b5", size = 13017 }, -] - [[package]] name = "opentelemetry-instrumentation" version = "0.60b0" @@ -2270,15 +2222,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/c4/b2d28e9d2edf4f1713eb3c29307f1a63f3d67cf09bdda29715a36a68921a/pre_commit-4.5.0-py2.py3-none-any.whl", hash = "sha256:25e2ce09595174d9c97860a95609f9f852c0614ba602de3561e267547f2335e1", size = 226429 }, ] -[[package]] -name = "prometheus-client" -version = "0.23.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/23/53/3edb5d68ecf6b38fcbcc1ad28391117d2a322d9a1a3eff04bfdb184d8c3b/prometheus_client-0.23.1.tar.gz", hash = "sha256:6ae8f9081eaaaf153a2e959d2e6c4f4fb57b12ef76c8c7980202f1e57b48b2ce", size = 80481 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.1-py3-none-any.whl", hash = "sha256:dd1913e6e76b59cfe44e7a4b83e01afc9873c1bdfd2ed8739f1e76aeca115f99", size = 61145 }, -] - [[package]] name = "propcache" version = "0.4.1" @@ -2384,9 +2327,6 @@ keyring = [ memory = [ { name = "cachetools" }, ] -redis = [ - { name = "redis" }, -] [[package]] name = "py-key-value-shared" @@ -2503,29 +2443,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/83/d6/887a1ff844e64aa823fb4905978d882a633cfe295c32eacad582b78a7d8b/pydantic_settings-2.11.0-py3-none-any.whl", hash = "sha256:fe2cea3413b9530d10f3a5875adffb17ada5c1e1bab0b2885546d7310415207c", size = 48608 }, ] -[[package]] -name = "pydocket" -version = "0.16.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cloudpickle" }, - { name = "fakeredis", extra = ["lua"] }, - { name = "opentelemetry-api" }, - { name = "opentelemetry-exporter-prometheus" }, - { name = "opentelemetry-instrumentation" }, - { name = "prometheus-client" }, - { name = "py-key-value-aio", extra = ["memory", "redis"] }, - { name = "python-json-logger" }, - { name = "redis" }, - { name = "rich" }, - { name = "typer" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e0/c5/61dcfce4d50b66a3f09743294d37fab598b81bb0975054b7f732da9243ec/pydocket-0.16.3.tar.gz", hash = "sha256:78e9da576de09e9f3f410d2471ef1c679b7741ddd21b586c97a13872b69bd265", size = 297080 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/94/93b7f5981aa04f922e0d9ce7326a4587866ec7e39f7c180ffcf408e66ee8/pydocket-0.16.3-py3-none-any.whl", hash = "sha256:e2b50925356e7cd535286255195458ac7bba15f25293356651b36d223db5dd7c", size = 67087 }, -] - [[package]] name = "pygments" version = "2.19.2" @@ -2579,15 +2496,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556 }, ] -[[package]] -name = "python-json-logger" -version = "4.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/29/bf/eca6a3d43db1dae7070f70e160ab20b807627ba953663ba07928cdd3dc58/python_json_logger-4.0.0.tar.gz", hash = "sha256:f58e68eb46e1faed27e0f574a55a0455eecd7b8a5b88b85a784519ba3cff047f", size = 17683 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl", hash = "sha256:af09c9daf6a813aa4cc7180395f50f2a9e5fa056034c9953aec92e381c5ba1e2", size = 15548 }, -] - [[package]] name = "python-mcp-demos" version = "0.1.0" @@ -2629,7 +2537,7 @@ requires-dist = [ { name = "azure-monitor-opentelemetry", specifier = ">=1.8.3" }, { name = "debugpy", specifier = ">=1.8.0" }, { name = "dotenv-azd", specifier = ">=0.1.0" }, - { name = "fastmcp", specifier = ">=2.14.2" }, + { name = "fastmcp", specifier = "==3.0.0b1" }, { name = "langchain", specifier = "==1.0.0a5" }, { name = "langchain-core", specifier = ">=0.3.0" }, { name = "langchain-mcp-adapters", specifier = ">=0.1.11" }, @@ -2960,15 +2868,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl", hash = "sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137", size = 15554 }, ] -[[package]] -name = "shellingham" -version = "1.5.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, -] - [[package]] name = "six" version = "1.17.0" @@ -2987,15 +2886,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] -[[package]] -name = "sortedcontainers" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575 }, -] - [[package]] name = "sqlalchemy" version = "2.0.44" @@ -3097,21 +2987,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 }, ] -[[package]] -name = "typer" -version = "0.21.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "rich" }, - { name = "shellingham" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/36/bf/8825b5929afd84d0dabd606c67cd57b8388cb3ec385f7ef19c5cc2202069/typer-0.21.1.tar.gz", hash = "sha256:ea835607cd752343b6b2b7ce676893e5a0324082268b48f27aa058bdb7d2145d", size = 110371 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl", hash = "sha256:7985e89081c636b88d172c2ee0cfe33c253160994d47bdfdc302defd7d1f1d01", size = 47381 }, -] - [[package]] name = "typing-extensions" version = "4.15.0" From 295594e03aa7f8148f23f435acdea947d4a8f291 Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Fri, 23 Jan 2026 12:11:59 -0800 Subject: [PATCH 2/5] Ignore logging warnings --- servers/auth_keycloak_mcp.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/servers/auth_keycloak_mcp.py b/servers/auth_keycloak_mcp.py index cd38e43..e68ec48 100644 --- a/servers/auth_keycloak_mcp.py +++ b/servers/auth_keycloak_mcp.py @@ -7,6 +7,7 @@ import logging import os import uuid +import warnings from datetime import date from enum import Enum from typing import Annotated @@ -35,7 +36,7 @@ logging.basicConfig( level=logging.WARNING, - format="%(message)s", + format="%(name)s: %(message)s", handlers=[ RichHandler( console=Console(stderr=True), @@ -45,6 +46,9 @@ ) ], ) +# Suppress OTEL 1.39 deprecation warnings and noisy logs +warnings.filterwarnings("ignore", category=DeprecationWarning, message=r".*Deprecated since version 1\.39\.0.*") +logging.getLogger("azure.monitor.opentelemetry.exporter._performance_counters._manager").setLevel(logging.ERROR) logger = logging.getLogger("ExpensesMCP") logger.setLevel(logging.INFO) From d3bee3b9040a48c64bfc91e2ac4b1867acf9d665 Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Tue, 24 Mar 2026 07:20:17 -0700 Subject: [PATCH 3/5] Upgrade MAF to latest --- agents/agentframework_http.py | 35 +- agents/agentframework_learn.py | 36 +- agents/agentframework_tavily.py | 43 ++- agents/langchainv1_tavily.py | 7 +- pyproject.toml | 2 +- uv.lock | 655 ++++++++++++++++++++++++++++++-- 6 files changed, 685 insertions(+), 93 deletions(-) diff --git a/agents/agentframework_http.py b/agents/agentframework_http.py index ba36463..717bb7f 100644 --- a/agents/agentframework_http.py +++ b/agents/agentframework_http.py @@ -3,10 +3,9 @@ import os from datetime import datetime -from agent_framework import ChatAgent, MCPStreamableHTTPTool -from agent_framework.azure import AzureOpenAIChatClient +from agent_framework import Agent, MCPStreamableHTTPTool from agent_framework.openai import OpenAIChatClient -from azure.identity import DefaultAzureCredential +from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider from dotenv import load_dotenv from rich import print from rich.logging import RichHandler @@ -26,19 +25,21 @@ # Configure chat client based on API_HOST API_HOST = os.getenv("API_HOST", "github") +async_credential = None if API_HOST == "azure": - client = AzureOpenAIChatClient( - credential=DefaultAzureCredential(), - deployment_name=os.environ.get("AZURE_OPENAI_CHAT_DEPLOYMENT"), - endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"), - api_version=os.environ.get("AZURE_OPENAI_VERSION"), + async_credential = DefaultAzureCredential() + token_provider = get_bearer_token_provider(async_credential, "https://cognitiveservices.azure.com/.default") + client = OpenAIChatClient( + base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT']}/openai/v1/", + api_key=token_provider, + model_id=os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"], ) elif API_HOST == "github": client = OpenAIChatClient( base_url="https://models.github.ai/inference", api_key=os.environ["GITHUB_TOKEN"], - model_id=os.getenv("GITHUB_MODEL", "openai/gpt-4o"), + model_id=os.getenv("GITHUB_MODEL", "openai/gpt-4.1-mini"), ) elif API_HOST == "ollama": client = OpenAIChatClient( @@ -48,29 +49,35 @@ ) else: client = OpenAIChatClient( - api_key=os.environ.get("OPENAI_API_KEY"), model_id=os.environ.get("OPENAI_MODEL", "gpt-4o") + api_key=os.environ.get("OPENAI_API_KEY"), model_id=os.environ.get("OPENAI_MODEL", "gpt-4.1-mini") ) # --- Main Agent Logic --- async def http_mcp_example() -> None: + """Run an agent connected to the local expenses MCP server.""" + async with ( MCPStreamableHTTPTool(name="Expenses MCP Server", url=MCP_SERVER_URL) as mcp_server, - ChatAgent( - chat_client=client, + Agent( + client=client, name="Expenses Agent", instructions=f"You help users to log expenses. Today's date is {datetime.now().strftime('%Y-%m-%d')}.", + tools=[mcp_server], ) as agent, ): user_query = "yesterday I bought a laptop for $1200 using my visa." - result = await agent.run(user_query, tools=mcp_server) - print(result) + result = await agent.run(user_query) + print(result.text) # Keep the worker alive in production while RUNNING_IN_PRODUCTION: await asyncio.sleep(60) logger.info("Worker still running...") + if async_credential: + await async_credential.close() + if __name__ == "__main__": asyncio.run(http_mcp_example()) diff --git a/agents/agentframework_learn.py b/agents/agentframework_learn.py index 7eb3b03..304b2b5 100644 --- a/agents/agentframework_learn.py +++ b/agents/agentframework_learn.py @@ -2,10 +2,9 @@ import logging import os -from agent_framework import ChatAgent, MCPStreamableHTTPTool -from agent_framework.azure import AzureOpenAIChatClient +from agent_framework import Agent, MCPStreamableHTTPTool from agent_framework.openai import OpenAIChatClient -from azure.identity import DefaultAzureCredential +from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider from dotenv import load_dotenv from rich import print from rich.logging import RichHandler @@ -20,18 +19,20 @@ # Configure chat client based on API_HOST API_HOST = os.getenv("API_HOST", "github") +async_credential = None if API_HOST == "azure": - client = AzureOpenAIChatClient( - credential=DefaultAzureCredential(), - deployment_name=os.environ.get("AZURE_OPENAI_CHAT_DEPLOYMENT"), - endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"), - api_version=os.environ.get("AZURE_OPENAI_VERSION"), + async_credential = DefaultAzureCredential() + token_provider = get_bearer_token_provider(async_credential, "https://cognitiveservices.azure.com/.default") + client = OpenAIChatClient( + base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT']}/openai/v1/", + api_key=token_provider, + model_id=os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"], ) elif API_HOST == "github": client = OpenAIChatClient( base_url="https://models.github.ai/inference", api_key=os.environ["GITHUB_TOKEN"], - model_id=os.getenv("GITHUB_MODEL", "openai/gpt-4o"), + model_id=os.getenv("GITHUB_MODEL", "openai/gpt-4.1-mini"), ) elif API_HOST == "ollama": client = OpenAIChatClient( @@ -41,26 +42,31 @@ ) else: client = OpenAIChatClient( - api_key=os.environ.get("OPENAI_API_KEY"), model_id=os.environ.get("OPENAI_MODEL", "gpt-4o") + api_key=os.environ.get("OPENAI_API_KEY"), model_id=os.environ.get("OPENAI_MODEL", "gpt-4.1-mini") ) -async def http_mcp_example(): +async def http_mcp_example() -> None: """ Creates an agent that can answer questions about Microsoft documentation using the Microsoft Learn MCP server. """ + async with ( MCPStreamableHTTPTool(name="Microsoft Learn MCP", url="https://learn.microsoft.com/api/mcp") as mcp_server, - ChatAgent( - chat_client=client, + Agent( + client=client, name="DocsAgent", instructions="You help with Microsoft documentation questions.", + tools=[mcp_server], ) as agent, ): query = "How to create an Azure storage account using az cli?" - result = await agent.run(query, tools=mcp_server) - print(result) + result = await agent.run(query) + print(result.text) + + if async_credential: + await async_credential.close() if __name__ == "__main__": diff --git a/agents/agentframework_tavily.py b/agents/agentframework_tavily.py index 0c8104e..543a9f2 100644 --- a/agents/agentframework_tavily.py +++ b/agents/agentframework_tavily.py @@ -1,11 +1,11 @@ import asyncio import logging import os +from urllib.parse import urlencode -from agent_framework import ChatAgent, MCPStreamableHTTPTool -from agent_framework.azure import AzureOpenAIChatClient +from agent_framework import Agent, MCPStreamableHTTPTool from agent_framework.openai import OpenAIChatClient -from azure.identity import DefaultAzureCredential +from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider from dotenv import load_dotenv from rich import print from rich.logging import RichHandler @@ -20,18 +20,20 @@ # Configure chat client based on API_HOST API_HOST = os.getenv("API_HOST", "github") +async_credential = None if API_HOST == "azure": - client = AzureOpenAIChatClient( - credential=DefaultAzureCredential(), - deployment_name=os.environ.get("AZURE_OPENAI_CHAT_DEPLOYMENT"), - endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"), - api_version=os.environ.get("AZURE_OPENAI_VERSION"), + async_credential = DefaultAzureCredential() + token_provider = get_bearer_token_provider(async_credential, "https://cognitiveservices.azure.com/.default") + client = OpenAIChatClient( + base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT']}/openai/v1/", + api_key=token_provider, + model_id=os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"], ) elif API_HOST == "github": client = OpenAIChatClient( base_url="https://models.github.ai/inference", api_key=os.environ["GITHUB_TOKEN"], - model_id=os.getenv("GITHUB_MODEL", "openai/gpt-4o"), + model_id=os.getenv("GITHUB_MODEL", "openai/gpt-4.1-mini"), ) elif API_HOST == "ollama": client = OpenAIChatClient( @@ -41,28 +43,33 @@ ) else: client = OpenAIChatClient( - api_key=os.environ.get("OPENAI_API_KEY"), model_id=os.environ.get("OPENAI_MODEL", "gpt-4o") + api_key=os.environ.get("OPENAI_API_KEY"), model_id=os.environ.get("OPENAI_MODEL", "gpt-4.1-mini") ) -async def http_mcp_example(): +async def http_mcp_example() -> None: """ Creates an agent that can search the web using the Tavily MCP server. """ - tavily_key = os.environ["TAVILY_API_KEY"] - headers = {"Authorization": f"Bearer {tavily_key}"} + tavily_key = os.environ["TAVILY_API_KEY"].strip() + tavily_url = f"https://mcp.tavily.com/mcp/?{urlencode({'tavilyApiKey': tavily_key})}" + async with ( - MCPStreamableHTTPTool(name="Tavily MCP", url="https://mcp.tavily.com/mcp/", headers=headers) as mcp_server, - ChatAgent( - chat_client=client, + MCPStreamableHTTPTool(name="Tavily MCP", url=tavily_url) as mcp_server, + Agent( + client=client, name="WebSearchAgent", instructions="You search the web with Tavily and provide concise answers with links.", + tools=[mcp_server], ) as agent, ): query = "What's new in Python 3.14? Include relevant links." - result = await agent.run(query, tools=mcp_server) - print(result) + result = await agent.run(query) + print(result.text) + + if async_credential: + await async_credential.close() if __name__ == "__main__": diff --git a/agents/langchainv1_tavily.py b/agents/langchainv1_tavily.py index e27ea73..7e78fc4 100644 --- a/agents/langchainv1_tavily.py +++ b/agents/langchainv1_tavily.py @@ -7,6 +7,7 @@ import asyncio import logging import os +from urllib.parse import urlencode import azure.identity from dotenv import load_dotenv @@ -54,13 +55,13 @@ async def run_agent() -> None: """Run a Tavily-backed research agent via MCP tools.""" - tavily_key = os.environ["TAVILY_API_KEY"] + tavily_key = os.environ["TAVILY_API_KEY"].strip() + tavily_url = f"https://mcp.tavily.com/mcp/?{urlencode({'tavilyApiKey': tavily_key})}" client = MultiServerMCPClient( { "tavily": { - "url": "https://mcp.tavily.com/mcp/", + "url": tavily_url, "transport": "streamable_http", - "headers": {"Authorization": f"Bearer {tavily_key}"}, } } ) diff --git a/pyproject.toml b/pyproject.toml index 51e41df..0325110 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ dependencies = [ "langchain-openai>=1.0.1", "langchain-mcp-adapters>=0.1.11", "azure-ai-agents>=1.1.0", - "agent-framework>=1.0.0b251016", + "agent-framework>=1.0.0rc5", "azure-cosmos>=4.9.0", "azure-monitor-opentelemetry>=1.8.3", "opentelemetry-instrumentation-starlette>=0.60b0", diff --git a/uv.lock b/uv.lock index 025a2b7..34f10ae 100644 --- a/uv.lock +++ b/uv.lock @@ -17,23 +17,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ba/9b/82df9530ed77d30831c49ffffc827222961422d444c0d684101e945ee214/a2a_sdk-0.3.10-py3-none-any.whl", hash = "sha256:b216ccc5ccfd00dcfa42f0f2dc709bc7ba057550717a34b0b1b34a99a76749cf", size = 140291 }, ] +[[package]] +name = "ag-ui-protocol" +version = "0.1.13" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/b5/fc0b65b561d00d88811c8a7d98ee735833f81554be244340950e7b65820c/ag_ui_protocol-0.1.13.tar.gz", hash = "sha256:811d7d7dcce4783dec252918f40b717ebfa559399bf6b071c4ba47c0c1e21bcb", size = 5671 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/9f/b833c1ab1999da35ebad54841ae85d2c2764c931da9a6f52d8541b6901b2/ag_ui_protocol-0.1.13-py3-none-any.whl", hash = "sha256:1393fa894c1e8416efe184168a50689e760d05b32f4646eebb8ff423dddf8e8f", size = 8053 }, +] + [[package]] name = "agent-framework" -version = "1.0.0b251016" +version = "1.0.0rc5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "agent-framework-a2a" }, - { name = "agent-framework-azure-ai" }, - { name = "agent-framework-copilotstudio" }, - { name = "agent-framework-core" }, - { name = "agent-framework-devui" }, - { name = "agent-framework-mem0" }, - { name = "agent-framework-purview" }, - { name = "agent-framework-redis" }, + { name = "agent-framework-core", extra = ["all"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/38/c565d6fb914d0504465543e81fad6351a0192b936613449f4bcad7158a48/agent_framework-1.0.0b251016.tar.gz", hash = "sha256:84fc34d10358b5b74cfbfd62bd6a0109073a4204dc5509cfffd2ad74db1f1eb2", size = 2073274 } +sdist = { url = "https://files.pythonhosted.org/packages/0a/bf/64bc9231cef4f23a61c6d6a71f2c9bdc81f1e750418ea884d38abd12ce0f/agent_framework-1.0.0rc5.tar.gz", hash = "sha256:d03a5013f13f3d1c3fa2ed7b5b1806816637e1278884633916a63090490fcf8e", size = 4054945 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/ac/1da507f4a4ec70dc30345ddfb1e0421b33e91397ce2c15c74105d75204a4/agent_framework-1.0.0b251016-py3-none-any.whl", hash = "sha256:d92d5765dc55f820c9136ba423a56055863b5e4ef464db7eafcf9896f3f81359", size = 5557 }, + { url = "https://files.pythonhosted.org/packages/f1/88/032e11af66329c5569b6bd9809c88107ed20e3469a0cc4bc2ee648510930/agent_framework-1.0.0rc5-py3-none-any.whl", hash = "sha256:dc11cbc1034b3ce610cb35e8642994b863e8f006b3ee90718b709a30abf383f4", size = 5500 }, ] [[package]] @@ -49,6 +54,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/79/aca9da8f2c4628266737cfc7190f17814d55a4f315afd77ca86927e8db02/agent_framework_a2a-1.0.0b251016-py3-none-any.whl", hash = "sha256:7ac984c36903eb898c2abbb0473745c6b657cec2ec2911087f5740f90986c399", size = 6866 }, ] +[[package]] +name = "agent-framework-ag-ui" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ag-ui-protocol" }, + { name = "agent-framework-core" }, + { name = "fastapi" }, + { name = "uvicorn", extra = ["standard"] }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8e/b5/c067ba0839028c285c3d3265f001eafb11d8450ec67811a60cb5b21f942b/agent_framework_ag_ui-1.0.0b260319.tar.gz", hash = "sha256:d44d75dcc762235527980e1e0347891312e140350da614679e79ffa05ebd7f06", size = 167847 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/33/05e90a4fa7ca8581b04bd34b7dcc22b75774a063a8b98362a9c415799599/agent_framework_ag_ui-1.0.0b260319-py3-none-any.whl", hash = "sha256:dba1ba58037e4b997ee4c919086e7077f8a59ea720dba667fc9e99757ad70d7c", size = 90535 }, +] + +[[package]] +name = "agent-framework-anthropic" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, + { name = "anthropic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/5b/1454151a0acf590ade8b8e5d6685aa73ac6de1b6b17dce38ba07e6c40f68/agent_framework_anthropic-1.0.0b260319.tar.gz", hash = "sha256:ed88adfe9629a4751593aa4ef1e1a4d3af2cbf3ceac031d2cc00cce974912c29", size = 15696 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/99/edd1f84e738fba41294600ba67d39ba79aba08c8f2ebd309151771451983/agent_framework_anthropic-1.0.0b260319-py3-none-any.whl", hash = "sha256:31f2a531ca4a9ae083e81422db4469545c6c647e76fea7734df252fb8aac10bb", size = 15663 }, +] + [[package]] name = "agent-framework-azure-ai" version = "1.0.0b251016" @@ -64,6 +97,70 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e1/96/e8db5ee8d5a33429a91061e3c6085d0ce9af01fa7984129997967231d5fa/agent_framework_azure_ai-1.0.0b251016-py3-none-any.whl", hash = "sha256:b6b1f004256bfc015c0b7ffdf75a817a1f0caed49300b99215b91c883d87ce03", size = 13907 }, ] +[[package]] +name = "agent-framework-azure-ai-search" +version = "0.0.0a1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/58/b9c706e03b3407be3c70777124136cf428f7879664f9032e606d23024208/agent_framework_azure_ai_search-0.0.0a1.tar.gz", hash = "sha256:ca60fa77a8c3a55eb954c03de4b74ecf890566220854acaad4e07d56f86f43be", size = 1658 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/c0/bd014d57a6718272a10955e679a7e08307cabd9557925350ca6e5f94eae9/agent_framework_azure_ai_search-0.0.0a1-py3-none-any.whl", hash = "sha256:b913cb4640a6a2539b1a008462f6dbdca64b14ad9c2bd68a99fa396b5312e876", size = 2373 }, +] + +[[package]] +name = "agent-framework-azurefunctions" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, + { name = "agent-framework-durabletask" }, + { name = "azure-functions" }, + { name = "azure-functions-durable" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/93/71/be902fe2ed5e0e9376860ce1bcf482e36bd842e69467576476d2682ed0b8/agent_framework_azurefunctions-1.0.0b260319.tar.gz", hash = "sha256:b83464e94581902ace0ba3e0c4f075ecad81b7faec8c861a906c7904cdc8623e", size = 32287 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/c4/35f0353983e45545fa67f3e3de0148d0aaad40b02c9c5915bfae76a9ec10/agent_framework_azurefunctions-1.0.0b260319-py3-none-any.whl", hash = "sha256:74ef42e71368ba8b785361e291be98bc5b6fecba8eff109135a60aa1d5dcc5f9", size = 35472 }, +] + +[[package]] +name = "agent-framework-bedrock" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, + { name = "boto3" }, + { name = "botocore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3b/f8/304e1cf65d708b82bb676fbcbd8b55b61be6dbd82f64fd7e7df4e948b07a/agent_framework_bedrock-1.0.0b260319.tar.gz", hash = "sha256:16a733fb4ce92ed976e6cd9e7e88a598948cc47b27bff5cc0460be2fb4d40633", size = 16984 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2b/20/5af0b2e2821a0bd990fb3ef2cc0f46f45fa3ac62c3944c02a42e4d3b0295/agent_framework_bedrock-1.0.0b260319-py3-none-any.whl", hash = "sha256:96dff6248c8ba2d7137bc95a0159552d078352b7ff0830f64a3880c29c7465d6", size = 13851 }, +] + +[[package]] +name = "agent-framework-chatkit" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, + { name = "openai-chatkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5d/71/47256547da76acd4c215c2542c19aeccac6082d67c1d642a4b642ea2ab41/agent_framework_chatkit-1.0.0b260319.tar.gz", hash = "sha256:df9c69029ecbfe3d446dd669be5b1e96b0b2f841dee5bdcc0f6678c1f7451680", size = 12482 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/b5/28484620509b6f11566a2407aac0aa54c70d6eaaedcc14faa1dd7586d40d/agent_framework_chatkit-1.0.0b260319-py3-none-any.whl", hash = "sha256:61f5747bdf25f0612bb1f3a0b7c08d1e11cc8ad3d623cb709c661c60a7cad311", size = 11708 }, +] + +[[package]] +name = "agent-framework-claude" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, + { name = "claude-agent-sdk" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/32/775928504e636cf30bdbb5a616979047d8516994b233c8c611e882f977ea/agent_framework_claude-1.0.0b260319.tar.gz", hash = "sha256:d86630de6c916c773ddc9ba8b50b2cbadbc8efd24646b60da1f8285c2fb53843", size = 10047 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/cf/d6fa317852f0f0cc5b4355f9c317332547432e39e22f92333a23df24f0ea/agent_framework_claude-1.0.0b260319-py3-none-any.whl", hash = "sha256:b1ea84bdb5e6c059c183ba0c5a2c15b88ce9b6550b72a90b9698ac477d57f291", size = 10138 }, +] + [[package]] name = "agent-framework-copilotstudio" version = "1.0.0b251016" @@ -79,26 +176,63 @@ wheels = [ [[package]] name = "agent-framework-core" -version = "1.0.0b251016" +version = "1.0.0rc5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "aiofiles" }, + { name = "azure-ai-projects" }, { name = "azure-identity" }, - { name = "azure-monitor-opentelemetry" }, - { name = "azure-monitor-opentelemetry-exporter" }, { name = "mcp", extra = ["ws"] }, { name = "openai" }, { name = "opentelemetry-api" }, - { name = "opentelemetry-exporter-otlp-proto-grpc" }, { name = "opentelemetry-sdk" }, { name = "opentelemetry-semantic-conventions-ai" }, + { name = "packaging" }, { name = "pydantic" }, - { name = "pydantic-settings" }, + { name = "python-dotenv" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c1/96/af67b9ece8273834cd23fa6c497e346e12055d05674a8baca1b36341dd1a/agent_framework_core-1.0.0b251016.tar.gz", hash = "sha256:67378bb8017b16ddf843a30d45380e3387102b93d92474296d2bc5f67a8a0e5f", size = 394296 } +sdist = { url = "https://files.pythonhosted.org/packages/d3/96/0a75aace08755d6d299de1ce0bf9f042ab309b870c7a40fb60a5a74a626c/agent_framework_core-1.0.0rc5.tar.gz", hash = "sha256:156bed9154a3be5c35000f240c0bef0cf9c4a39b65b9c5c139af5c4a10871f1a", size = 312046 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/22/b203b06a23636771bff66e5f2185afcb4a5fe8bf76f58c32dd164c670523/agent_framework_core-1.0.0rc5-py3-none-any.whl", hash = "sha256:c906c6edac1f7db97e047e0958e77819b43406fb4cb4efcffb3fe042b69029c8", size = 359665 }, +] + +[package.optional-dependencies] +all = [ + { name = "agent-framework-a2a" }, + { name = "agent-framework-ag-ui" }, + { name = "agent-framework-anthropic" }, + { name = "agent-framework-azure-ai" }, + { name = "agent-framework-azure-ai-search" }, + { name = "agent-framework-azurefunctions" }, + { name = "agent-framework-bedrock" }, + { name = "agent-framework-chatkit" }, + { name = "agent-framework-claude" }, + { name = "agent-framework-copilotstudio" }, + { name = "agent-framework-declarative" }, + { name = "agent-framework-devui" }, + { name = "agent-framework-durabletask" }, + { name = "agent-framework-foundry-local" }, + { name = "agent-framework-github-copilot" }, + { name = "agent-framework-lab" }, + { name = "agent-framework-mem0" }, + { name = "agent-framework-ollama" }, + { name = "agent-framework-orchestrations" }, + { name = "agent-framework-purview" }, + { name = "agent-framework-redis" }, +] + +[[package]] +name = "agent-framework-declarative" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, + { name = "powerfx" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/35/61/a45c61aed819dcb11cc28e9fec50400de11c4751e123a3cfd010db2f07fd/agent_framework_declarative-1.0.0b260319.tar.gz", hash = "sha256:801562cf243353bd3d567d2544ecc1cd0d9a538ab1d39f8bd0ef15f8d67c1269", size = 69843 } wheels = [ - { url = "https://files.pythonhosted.org/packages/da/de/72d60f3db12dd84bf6a77fd6ce6cefdea4cfef9f2411335edf465ec3e02d/agent_framework_core-1.0.0b251016-py3-none-any.whl", hash = "sha256:033f36055bd154bd6b526ad9c260924877f37c978cee47d3a3a0b2c97ed72168", size = 268395 }, + { url = "https://files.pythonhosted.org/packages/65/18/aab2a21a784e169fb36b4532932e36d41be7c10aff8aa0039dec40d4a576/agent_framework_declarative-1.0.0b260319-py3-none-any.whl", hash = "sha256:02abad1fe095cfa5a59cc148acfa86f10584d93107fcf9f24c2a2c17c00209bd", size = 78013 }, ] [[package]] @@ -116,6 +250,59 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/46/c3/87071084f817b21c3aecf80ee56d41df98ed64081a35ce8d03fd4e7ce803/agent_framework_devui-1.0.0b251016-py3-none-any.whl", hash = "sha256:eb4cdcbfce99ed950de2a6d1937ccf1b3751478a88f5657c1b54e93bec22249a", size = 287972 }, ] +[[package]] +name = "agent-framework-durabletask" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, + { name = "durabletask" }, + { name = "durabletask-azuremanaged" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/e2/807ac1f93491c0221ad1a1e1284d5e43b14be3560374f993e4a1d7ca93e7/agent_framework_durabletask-1.0.0b260319.tar.gz", hash = "sha256:dd931fb0fbc3e672f75fcf4fc7efd147ac20c1c63660040a4cc01b46031f5467", size = 30365 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/5e/72660dcc141cca8e7dc8a29296bd0f712f4454aa2d1716750fff350f2a7e/agent_framework_durabletask-1.0.0b260319-py3-none-any.whl", hash = "sha256:434d851b02ec1c6ada85ba7de2fba4dd6fe0099f3f04194ef1186af415132a7b", size = 36528 }, +] + +[[package]] +name = "agent-framework-foundry-local" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, + { name = "foundry-local-sdk" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/a7/e2bced9c1d348cf6c12a524f6ca88fd07e24284821fb799e7d3e5a087e70/agent_framework_foundry_local-1.0.0b260319.tar.gz", hash = "sha256:a3f543e50e3628197d49b8d9c8b2a746173f00f7c650585d6e4d0cbd79947d0e", size = 6151 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/ca/9a4534ef2b197423f9ad84b48f694f2a4f98b6a3a113dad569182e34336f/agent_framework_foundry_local-1.0.0b260319-py3-none-any.whl", hash = "sha256:7617cb0dad95df606a1c0f8911ed7536fac21a227d02a50189b7e87b906c6fca", size = 6744 }, +] + +[[package]] +name = "agent-framework-github-copilot" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, + { name = "github-copilot-sdk" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/88/f0027c97fa3976ea310c1239a245fb257ef891a90e9162f177513b0f59f1/agent_framework_github_copilot-1.0.0b260319.tar.gz", hash = "sha256:dda04e7ccfaff22b519617d5cf0722b754112c926ebbed2ae348ce6c2c40916e", size = 9020 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2f/62/ee6af735c9156b54c4b21872d32d70953d3935de38c9394c16f552b48f89/agent_framework_github_copilot-1.0.0b260319-py3-none-any.whl", hash = "sha256:f931ec76e59a129115e567ef95fa77248e0b806fe82ab20cf6c0bce34e54381d", size = 9133 }, +] + +[[package]] +name = "agent-framework-lab" +version = "1.0.0b251024" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/c5/be86273cb3545651d0c8112ff9f38ae8fe13b740ce9b65b9be83ff2d70ee/agent_framework_lab-1.0.0b251024.tar.gz", hash = "sha256:4261cb595b6edfd4f30db613c1885c71b3dcfa2088cf29224d4f17b3ff956b2a", size = 23397 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/0f/3974b2b1f6bf523ee3ced0886b6afd5ca8bbebd24aa5278ef77db0d3d765/agent_framework_lab-1.0.0b251024-py3-none-any.whl", hash = "sha256:1596408991a92fcacef4bb939305d2b59159517b707f48114105fc0dd46bfee7", size = 26589 }, +] + [[package]] name = "agent-framework-mem0" version = "1.0.0b251016" @@ -129,6 +316,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b5/e0/125eae97a3b764239a2ab6301bf91f016286eccdc191e77e80b8d3495582/agent_framework_mem0-1.0.0b251016-py3-none-any.whl", hash = "sha256:c27d04fc298f6ad9a0c7dd5984bb5968fa5f73b84353a929d0b0659598a048de", size = 5297 }, ] +[[package]] +name = "agent-framework-ollama" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, + { name = "ollama" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/aa/fa/25701317e5129425032d7827dfbfc0a3f08a5ee96e238401a5624160deec/agent_framework_ollama-1.0.0b260319.tar.gz", hash = "sha256:50a562e331dec52863d9a87a33f5b253436e11b2146f68b49d15f9279514bf88", size = 10218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/3b/ea4120df4021b7748b7fcec38ebaf22c4fdd1c0d752fa72916d79d984f43/agent_framework_ollama-1.0.0b260319-py3-none-any.whl", hash = "sha256:5c1537a56585467be67c6cd6171f71fd4569c2a88388f1bd84fe1426fe8585d6", size = 12029 }, +] + +[[package]] +name = "agent-framework-orchestrations" +version = "1.0.0b260319" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "agent-framework-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/c4/1497d877d175437f09eec7ce5873128f468838d0c252a874d519c573bcdc/agent_framework_orchestrations-1.0.0b260319.tar.gz", hash = "sha256:0c951e530a27fad6dc30323f8c769aaebe8fd6869af871d50d7dc87ddc285d80", size = 54996 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/fc/29bc291598d84c0dd37e1018d7f96f8d3e94aa6b194d191168d8900b58ce/agent_framework_orchestrations-1.0.0b260319-py3-none-any.whl", hash = "sha256:f3e22d1ae37f099abd839fb05a73cc1017f951c63a3976977f5fa4bf13093044", size = 61073 }, +] + [[package]] name = "agent-framework-purview" version = "1.0.0b251016" @@ -158,15 +370,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dc/09/061e6aacb88ade83186a99546b6d2c907c5cee0b791ecbc6b619cd5f7f13/agent_framework_redis-1.0.0b251016-py3-none-any.whl", hash = "sha256:e39f0bbf59680bfb047fb2548ccca3c83648f036be455531a1689bdba071b44d", size = 15559 }, ] -[[package]] -name = "aiofiles" -version = "25.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/41/c3/534eac40372d8ee36ef40df62ec129bee4fdb5ad9706e58a29be53b2c970/aiofiles-25.1.0.tar.gz", hash = "sha256:a8d728f0a29de45dc521f18f07297428d56992a742f0cd2701ba86e44d23d5b2", size = 46354 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/8a/340a1555ae33d7354dbca4faa54948d76d89a27ceef032c8c3bc661d003e/aiofiles-25.1.0-py3-none-any.whl", hash = "sha256:abe311e527c862958650f9438e859c1fa7568a141b22abcd015e120e86a85695", size = 14668 }, -] - [[package]] name = "aiohappyeyeballs" version = "2.6.1" @@ -231,6 +434,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, ] +[[package]] +name = "anthropic" +version = "0.80.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "distro" }, + { name = "docstring-parser" }, + { name = "httpx" }, + { name = "jiter" }, + { name = "pydantic" }, + { name = "sniffio" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7f/63/791e14ef5a8ecb485cef5b5d058c7ca3ad6c50a2f94cf4cea5231c6b7c16/anthropic-0.80.0.tar.gz", hash = "sha256:ef042586673fdcab2a6ffd381aa5f9a1bcce38ffe73c07fe70bd56d12b8124ba", size = 533291 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/4b/665f29338f51d0c2f9e04b276ea54cc1e957ae5c521a0ad868aa80abc608/anthropic-0.80.0-py3-none-any.whl", hash = "sha256:dad0e40ec371ee686e9ffb2e0cb461a0ed51447fa100927fb5d39b174c286d6f", size = 453667 }, +] + [[package]] name = "anyio" version = "4.11.0" @@ -253,6 +475,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/17/9c/fc2331f538fbf7eedba64b2052e99ccf9ba9d6888e2f41441ee28847004b/asgiref-3.10.0-py3-none-any.whl", hash = "sha256:aef8a81283a34d0ab31630c9b7dfe70c812c95eba78171367ca8745e88124734", size = 24050 }, ] +[[package]] +name = "asyncio" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/71/ea/26c489a11f7ca862d5705db67683a7361ce11c23a7b98fc6c2deaeccede2/asyncio-4.0.0.tar.gz", hash = "sha256:570cd9e50db83bc1629152d4d0b7558d6451bb1bfd5dfc2e935d96fc2f40329b", size = 5371 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/64/eff2564783bd650ca25e15938d1c5b459cda997574a510f7de69688cb0b4/asyncio-4.0.0-py3-none-any.whl", hash = "sha256:c1eddb0659231837046809e68103969b2bef8b0400d59cfa6363f6b5ed8cc88b", size = 5555 }, +] + [[package]] name = "attrs" version = "25.4.0" @@ -290,31 +521,32 @@ wheels = [ [[package]] name = "azure-ai-projects" -version = "1.1.0b4" +version = "2.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "azure-ai-agents" }, { name = "azure-core" }, + { name = "azure-identity" }, { name = "azure-storage-blob" }, { name = "isodate" }, + { name = "openai" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bc/16/7a7c978a79f545d62ab4327cd704c22b5d7ade8dcfb58ea193257aebabf9/azure_ai_projects-1.1.0b4.tar.gz", hash = "sha256:39e2f1396270b375069c2d9c82ccfe91c11384eca9f61d59adbc12fb6d6a32ca", size = 147568 } +sdist = { url = "https://files.pythonhosted.org/packages/86/f9/a15c8a16e35e6d620faebabc6cc4f9e2f4b7f1d962cc6f58931c46947e24/azure_ai_projects-2.0.1.tar.gz", hash = "sha256:c8c64870aa6b89903af69a4ff28b4eff3df9744f14615ea572cae87394946a0c", size = 491774 } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/10/8b7bd070e3cc804343dab124ce66a3b7999a72d5be0e49232cbcd1d36e18/azure_ai_projects-1.1.0b4-py3-none-any.whl", hash = "sha256:d8aab84fd7cd7c5937e78141e37ca4473dc5ed6cce2c0490c634418abe14afea", size = 126670 }, + { url = "https://files.pythonhosted.org/packages/8d/f7/290ca39501c06c6e23b46ba9f7f3dfb05ecc928cde105fed85d6845060dd/azure_ai_projects-2.0.1-py3-none-any.whl", hash = "sha256:dfda540d256e67a52bf81c75418b6bf92b811b96693fe45787e154a888ad2396", size = 236560 }, ] [[package]] name = "azure-core" -version = "1.36.0" +version = "1.39.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0a/c4/d4ff3bc3ddf155156460bff340bbe9533f99fac54ddea165f35a8619f162/azure_core-1.36.0.tar.gz", hash = "sha256:22e5605e6d0bf1d229726af56d9e92bc37b6e726b141a18be0b4d424131741b7", size = 351139 } +sdist = { url = "https://files.pythonhosted.org/packages/34/83/bbde3faa84ddcb8eb0eca4b3ffb3221252281db4ce351300fe248c5c70b1/azure_core-1.39.0.tar.gz", hash = "sha256:8a90a562998dd44ce84597590fff6249701b98c0e8797c95fcdd695b54c35d74", size = 367531 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/3c/b90d5afc2e47c4a45f4bba00f9c3193b0417fad5ad3bb07869f9d12832aa/azure_core-1.36.0-py3-none-any.whl", hash = "sha256:fee9923a3a753e94a259563429f3644aaf05c486d45b1215d098115102d91d3b", size = 213302 }, + { url = "https://files.pythonhosted.org/packages/7e/d6/8ebcd05b01a580f086ac9a97fb9fac65c09a4b012161cc97c21a336e880b/azure_core-1.39.0-py3-none-any.whl", hash = "sha256:4ac7b70fab5438c3f68770649a78daf97833caa83827f91df9c14e0e0ea7d34f", size = 218318 }, ] [[package]] @@ -343,6 +575,36 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/48/f3/d7c938771c8dc1ad7ae44370694ebacb06d9b37f70be846033395af2c56b/azure_cosmos-4.14.2-py3-none-any.whl", hash = "sha256:f0783a9b1c13f8dbd62bdbf8456f927125d77d5267e5ff6b37193bcd4554fd2c", size = 388602 }, ] +[[package]] +name = "azure-functions" +version = "1.24.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "werkzeug" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1d/be/5535830e0658e9668093941b3c33b0ea03eceadbf6bd6b7870aa37ef071a/azure_functions-1.24.0.tar.gz", hash = "sha256:18ea1607c7a7268b7a1e1bd0cc28c5cc57a9db6baaacddb39ba0e9f865728187", size = 134495 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/76/e6c5809ee0295e882b6c9ad595896748e33989d353b67316a854f65fb754/azure_functions-1.24.0-py3-none-any.whl", hash = "sha256:32b12c2a219824525849dd92036488edeb70d306d164efd9e941f10f9ac0a91c", size = 108341 }, +] + +[[package]] +name = "azure-functions-durable" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "azure-functions" }, + { name = "furl" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-sdk" }, + { name = "python-dateutil" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/51/3a/f168b434fa69eaaf5d14b54d88239b851eceb7e10f666b55289dd0933ccb/azure-functions-durable-1.4.0.tar.gz", hash = "sha256:945488ef28917dae4295a4dd6e6f6601ffabe32e3fbb94ceb261c9b65b6e6c0f", size = 176584 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/74/01/7f03229fa5c05a5cc7e41172aef80c5242d28aeea0825f592f93141a4b91/azure_functions_durable-1.4.0-py3-none-any.whl", hash = "sha256:0efe919cdda96924791feabe192a37c7d872414b4c6ce348417a02ee53d8cc31", size = 143159 }, +] + [[package]] name = "azure-identity" version = "1.25.1" @@ -432,6 +694,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/14/2a/fbcbf5a025d3e71ddafad7efd43e34ec4362f4d523c3c471b457148fb211/beartype-0.22.8-py3-none-any.whl", hash = "sha256:b832882d04e41a4097bab9f63e6992bc6de58c414ee84cba9b45b67314f5ab2e", size = 1331895 }, ] +[[package]] +name = "boto3" +version = "1.42.74" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, + { name = "jmespath" }, + { name = "s3transfer" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/16/a264b4da2af99f4a12609b93fea941cce5ec41da14b33ed3fef77a910f0c/boto3-1.42.74-py3-none-any.whl", hash = "sha256:4bf89c044d618fe4435af854ab820f09dd43569c0df15d7beb0398f50b9aa970", size = 140557 }, +] + +[[package]] +name = "botocore" +version = "1.42.74" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jmespath" }, + { name = "python-dateutil" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/c7/cab8a14f0b69944bd0dd1fd58559163455b347eeda00bf836e93ce2684e4/botocore-1.42.74.tar.gz", hash = "sha256:9cf5cdffc6c90ed87b0fe184676806182588be0d0df9b363e9fe3e2923ac8e80", size = 15014379 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/65/75852e04de5423c9b0c5b88241d0bdea33e6c6f454c88b71377d230216f2/botocore-1.42.74-py3-none-any.whl", hash = "sha256:3a76a8af08b5de82e51a0ae132394e226e15dbf21c8146ac3f7c1f881517a7a7", size = 14688218 }, +] + [[package]] name = "cachetools" version = "6.2.1" @@ -507,6 +796,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402 }, ] +[[package]] +name = "claude-agent-sdk" +version = "0.1.48" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "mcp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6c/dd/2818538efd18ed4ef72d4775efa75bb36cbea0fa418eda51df85ee9c2424/claude_agent_sdk-0.1.48.tar.gz", hash = "sha256:ee294d3f02936c0b826119ffbefcf88c67731cf8c2d2cb7111ccc97f76344272", size = 87375 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/cf/bbbdee52ee0c63c8709b0ac03ce3c1da5bdc37def5da0eca63363448744f/claude_agent_sdk-0.1.48-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5761ff1d362e0f17c2b1bfd890d1c897f0aa81091e37bbd15b7d06f05ced552d", size = 57559306 }, + { url = "https://files.pythonhosted.org/packages/57/d1/2179154b88d4cf6ba1cf6a15066ee8e96257aaeb1330e625e809ba2f28eb/claude_agent_sdk-0.1.48-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:39c1307daa17e42fa8a71180bb20af8a789d72d3891fc93519ff15540badcb83", size = 73980309 }, + { url = "https://files.pythonhosted.org/packages/dc/99/55b0cd3bf54a7449e744d23cf50be104e9445cf623e1ed75722112aa6264/claude_agent_sdk-0.1.48-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:543d70acba468eccfff836965a14b8ac88cf90809aeeb88431dfcea3ee9a2fa9", size = 74583686 }, + { url = "https://files.pythonhosted.org/packages/c8/f6/4851bd9a238b7aadba7639eb906aca7da32a51f01563fa4488469c608b3a/claude_agent_sdk-0.1.48-py3-none-win_amd64.whl", hash = "sha256:0d37e60bd2b17efc3f927dccef080f14897ab62cd1d0d67a4abc8a0e2d4f1006", size = 74956045 }, +] + [[package]] name = "click" version = "8.3.0" @@ -519,6 +824,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295 }, ] +[[package]] +name = "clr-loader" +version = "0.2.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/24/c12faf3f61614b3131b5c98d3bf0d376b49c7feaa73edca559aeb2aee080/clr_loader-0.2.10.tar.gz", hash = "sha256:81f114afbc5005bafc5efe5af1341d400e22137e275b042a8979f3feb9fc9446", size = 83605 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/61/cf819f8e8bb4d4c74661acf2498ba8d4a296714be3478d21eaabf64f5b9b/clr_loader-0.2.10-py3-none-any.whl", hash = "sha256:ebbbf9d511a7fe95fa28a95a4e04cd195b097881dfe66158dc2c281d3536f282", size = 56483 }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -663,6 +980,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c1/f6/35a119a3dcfc8995542fee35c83e800a144890337c9a8377d22a2052fa1d/dotenv_azd-0.3.0-py3-none-any.whl", hash = "sha256:db57c4cba883662f23a64d86bc3dd1bdf91bcbf13f6452d3db4c156c203657a4", size = 4528 }, ] +[[package]] +name = "durabletask" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asyncio" }, + { name = "grpcio" }, + { name = "packaging" }, + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/27/3d021e6b36fc1aab6099fafc56dfc8059b4e8968615a26c1a0418601e50a/durabletask-1.3.0.tar.gz", hash = "sha256:11e38dda6df4737fadca0c71fc0a0f769955877c8a8bdb25ccbf90cf45afbf63", size = 57830 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/87/31ea460dbfaf50d9877f143e2ce9829cac2fb106747d9900cc353356ea77/durabletask-1.3.0-py3-none-any.whl", hash = "sha256:411f23e13391b8845edca010873dd7a87ee7cfc1fe05753ab28a7cd7c3c1bd77", size = 64112 }, +] + +[[package]] +name = "durabletask-azuremanaged" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "azure-identity" }, + { name = "durabletask" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/29/29/6bb0b5fe51aa92e117adcdc93efe97cf5476d86c1496e5c5ab35d99a8d07/durabletask_azuremanaged-1.3.0.tar.gz", hash = "sha256:55172588e075afa80d46dcc2e5ddbd84be0a20cc78c74f687040c3720677d34c", size = 4343 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/11/4d34fec302c4813e626080f1532d189767eb31d6d80e8f3698c230512f14/durabletask_azuremanaged-1.3.0-py3-none-any.whl", hash = "sha256:9da914f569da1597c858d494a95eda37e4372726c0ee65f30080dcafab262d60", size = 6366 }, +] + [[package]] name = "email-validator" version = "2.3.0" @@ -747,6 +1092,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054 }, ] +[[package]] +name = "foundry-local-sdk" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "pydantic" }, + { name = "tqdm" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/6b/76a7fe8f9f4c52cc84eaa1cd1b66acddf993496d55d6ea587bf0d0854d1c/foundry_local_sdk-0.5.1-py3-none-any.whl", hash = "sha256:f3639a3666bc3a94410004a91671338910ac2e1b8094b1587cc4db0f4a7df07e", size = 14003 }, +] + [[package]] name = "frozenlist" version = "1.8.0" @@ -788,6 +1146,36 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409 }, ] +[[package]] +name = "furl" +version = "2.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "orderedmultidict" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/53/e4/203a76fa2ef46cdb0a618295cc115220cbb874229d4d8721068335eb87f0/furl-2.1.4.tar.gz", hash = "sha256:877657501266c929269739fb5f5980534a41abd6bbabcb367c136d1d3b2a6015", size = 57526 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/8c/dce3b1b7593858eba995b2dfdb833f872c7f863e3da92aab7128a6b11af4/furl-2.1.4-py2.py3-none-any.whl", hash = "sha256:da34d0b34e53ffe2d2e6851a7085a05d96922b5b578620a37377ff1dbeeb11c8", size = 27550 }, +] + +[[package]] +name = "github-copilot-sdk" +version = "0.1.32" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dateutil" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/67/ebd002c14fe7d2640d0fff47a0b29fdb21ed239b597afa2d2c6f6cfebb0b/github_copilot_sdk-0.1.32-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:d97bc39fbd4b51e0aea3405299da1e643838ddbf6bff284f688a2d8c20d82ff8", size = 58576987 }, + { url = "https://files.pythonhosted.org/packages/a5/50/add440f61e19f5b7e6989c89c5cefcb14c23f06627621e7c3a15a1f75e5d/github_copilot_sdk-0.1.32-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8098592f34e7ee7decbcbb7615c7eb924471e65a3e4d0d93bc49b0d112f8ec51", size = 55328145 }, + { url = "https://files.pythonhosted.org/packages/f9/b8/c3ca0678b21d8a0dd8fe3aa8fad4b7ec5f22cbe9d5fb3a11f82df4f40578/github_copilot_sdk-0.1.32-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:c20cae4bec3584ce007a65a363216a1f98a71428a3ca3b76622f9e556307eed2", size = 61456678 }, + { url = "https://files.pythonhosted.org/packages/21/5c/bdfe177353f88d44da9600c3ec478e2b0df7a838901947b168e869ba5ad7/github_copilot_sdk-0.1.32-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:0941fd445e97a9b13fb713086c4a8c09c20ec8c7ab854cf009bd7cc213488999", size = 59641536 }, + { url = "https://files.pythonhosted.org/packages/1e/d0/2f3a07c74ecd24587b8f7d26729738f73e63f3341bf4bdc9eb2bb73ddaaf/github_copilot_sdk-0.1.32-py3-none-win_amd64.whl", hash = "sha256:37a82ff0908e01512052b69df4aa498332fa5769999635425015ed43cd850622", size = 54077464 }, + { url = "https://files.pythonhosted.org/packages/1c/76/292088d6ccf2daf8bcb8a94b22b4f16005a6772087896f1b43c4f0d5edaa/github_copilot_sdk-0.1.32-py3-none-win_arm64.whl", hash = "sha256:3199c99604e8d393b1d60905be80b84da44e70d16d30b92e2ae9b92814cdc4ae", size = 52083845 }, +] + [[package]] name = "google-api-core" version = "2.26.0" @@ -849,6 +1237,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685 }, ] +[[package]] +name = "griffe" +version = "1.15.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0d/0c/3a471b6e31951dce2360477420d0a8d1e00dea6cf33b70f3e8c3ab6e28e1/griffe-1.15.0.tar.gz", hash = "sha256:7726e3afd6f298fbc3696e67958803e7ac843c1cfe59734b6251a40cdbfb5eea", size = 424112 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/83/3b1d03d36f224edded98e9affd0467630fc09d766c0e56fb1498cbb04a9b/griffe-1.15.0-py3-none-any.whl", hash = "sha256:6f6762661949411031f5fcda9593f586e6ce8340f0ba88921a0f2ef7a81eb9a3", size = 150705 }, +] + [[package]] name = "grpcio" version = "1.76.0" @@ -1048,6 +1448,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683", size = 49010 }, ] +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, +] + [[package]] name = "jiter" version = "0.11.1" @@ -1082,6 +1494,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d9/71/71408b02c6133153336d29fa3ba53000f1e1a3f78bb2fc2d1a1865d2e743/jiter-0.11.1-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18c77aaa9117510d5bdc6a946baf21b1f0cfa58ef04d31c8d016f206f2118960", size = 343697 }, ] +[[package]] +name = "jmespath" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/59/322338183ecda247fb5d1763a6cbe46eff7222eaeebafd9fa65d4bf5cb11/jmespath-1.1.0.tar.gz", hash = "sha256:472c87d80f36026ae83c6ddd0f1d05d4e510134ed462851fd5f754c8c3cbb88d", size = 27377 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl", hash = "sha256:a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64", size = 20419 }, +] + [[package]] name = "jsonpatch" version = "1.33" @@ -1360,6 +1781,36 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321 }, ] +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622 }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029 }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374 }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980 }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990 }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784 }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588 }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041 }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543 }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113 }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911 }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658 }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066 }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639 }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569 }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284 }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801 }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769 }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642 }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612 }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200 }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973 }, +] + [[package]] name = "mcp" version = "1.25.0" @@ -1745,9 +2196,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/be/9c/92789c596b8df838baa98fa71844d84283302f7604ed565dafe5a6b5041a/oauthlib-3.3.1-py3-none-any.whl", hash = "sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1", size = 160065 }, ] +[[package]] +name = "ollama" +version = "0.5.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/91/6d/ae96027416dcc2e98c944c050c492789502d7d7c0b95a740f0bb39268632/ollama-0.5.3.tar.gz", hash = "sha256:40b6dff729df3b24e56d4042fd9d37e231cee8e528677e0d085413a1d6692394", size = 43331 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/f6/2091e50b8b6c3e6901f6eab283d5efd66fb71c86ddb1b4d68766c3eeba0f/ollama-0.5.3-py3-none-any.whl", hash = "sha256:a8303b413d99a9043dbf77ebf11ced672396b59bec27e6d5db67c88f01b279d2", size = 13490 }, +] + [[package]] name = "openai" -version = "1.109.1" +version = "2.29.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1759,9 +2223,43 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/a1/a303104dc55fc546a3f6914c842d3da471c64eec92043aef8f652eb6c524/openai-1.109.1.tar.gz", hash = "sha256:d173ed8dbca665892a6db099b4a2dfac624f94d20a93f46eb0b56aae940ed869", size = 564133 } +sdist = { url = "https://files.pythonhosted.org/packages/b4/15/203d537e58986b5673e7f232453a2a2f110f22757b15921cbdeea392e520/openai-2.29.0.tar.gz", hash = "sha256:32d09eb2f661b38d3edd7d7e1a2943d1633f572596febe64c0cd370c86d52bec", size = 671128 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/b1/35b6f9c8cf9318e3dbb7146cc82dab4cf61182a8d5406fc9b50864362895/openai-2.29.0-py3-none-any.whl", hash = "sha256:b7c5de513c3286d17c5e29b92c4c98ceaf0d775244ac8159aeb1bddf840eb42a", size = 1141533 }, +] + +[[package]] +name = "openai-agents" +version = "0.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "griffe" }, + { name = "mcp" }, + { name = "openai" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "types-requests" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/df/68927da38588f7b9c418754f2a0c30c9cda1d8621b035906faf85767dda5/openai_agents-0.13.0.tar.gz", hash = "sha256:90ac13697dec3c110c3ed9893629e01b6fc178ae410a7f0e39f387be408e8715", size = 2660070 } wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/2a/7dd3d207ec669cacc1f186fd856a0f61dbc255d24f6fdc1a6715d6051b0f/openai-1.109.1-py3-none-any.whl", hash = "sha256:6bcaf57086cf59159b8e27447e4e7dd019db5d29a438072fbd49c290c7e65315", size = 948627 }, + { url = "https://files.pythonhosted.org/packages/e0/8d/62cf7374a2050daa6b7605c12a9085fa528d493f9cf076826c0c78ac16f7/openai_agents-0.13.0-py3-none-any.whl", hash = "sha256:d1077e71e9c7461f9098922bbc63a1f2a1244c93fd3dc24249882b3130eccd55", size = 454617 }, +] + +[[package]] +name = "openai-chatkit" +version = "1.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "openai" }, + { name = "openai-agents" }, + { name = "pydantic" }, + { name = "uvicorn" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/46/b15fd77f7df12a2cabd8475de6226ce04d1cec7b283b21e8f0f52edc63a7/openai_chatkit-1.6.3.tar.gz", hash = "sha256:f16e347f39c376a78dddb5ceaf5398a4bb700c0145bfa7cb899d65135972956e", size = 61822 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/5e/e06a4bec431083c282dea5729b0947b940900a4014216835182048078877/openai_chatkit-1.6.3-py3-none-any.whl", hash = "sha256:642ecdf810eda3619964f316e393f252741130a5500dc3a357d501f8657b3941", size = 42578 }, ] [[package]] @@ -2092,6 +2590,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/53/5d/a448862f6d10c95685ed0e703596b6bd1784074e7ad90bffdc550abb7b68/opentelemetry_util_http-0.60b0-py3-none-any.whl", hash = "sha256:4f366f1a48adb74ffa6f80aee26f96882e767e01b03cd1cfb948b6e1020341fe", size = 8742 }, ] +[[package]] +name = "orderedmultidict" +version = "1.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5c/62/61ad51f6c19d495970230a7747147ce7ed3c3a63c2af4ebfdb1f6d738703/orderedmultidict-1.0.2.tar.gz", hash = "sha256:16a7ae8432e02cc987d2d6d5af2df5938258f87c870675c73ee77a0920e6f4a6", size = 13973 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/6c/d8a02ffb24876b5f51fbd781f479fc6525a518553a4196bd0433dae9ff8e/orderedmultidict-1.0.2-py2.py3-none-any.whl", hash = "sha256:ab5044c1dca4226ae4c28524cfc5cc4c939f0b49e978efa46a6ad6468049f79b", size = 11897 }, +] + [[package]] name = "orjson" version = "3.11.3" @@ -2134,11 +2644,11 @@ wheels = [ [[package]] name = "packaging" -version = "25.0" +version = "24.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727 } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469 }, + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, ] [[package]] @@ -2206,6 +2716,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1e/ce/5e5ede2f0b24db113544f9f7ce08d395a4107cbc66d77b8d05d9eaeaeada/posthog-6.7.8-py3-none-any.whl", hash = "sha256:842ccb518f925425f714bae29e4ac36a059a8948c45f6ed155543ca7386d554b", size = 137299 }, ] +[[package]] +name = "powerfx" +version = "0.0.34" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, + { name = "pythonnet" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9f/fb/6c4bf87e0c74ca1c563921ce89ca1c5785b7576bca932f7255cdf81082a7/powerfx-0.0.34.tar.gz", hash = "sha256:956992e7afd272657ed16d80f4cad24ec95d9e4a79fb9dfa4a068a09e136af32", size = 3237555 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/96/0f8a1f86485b3ec0315e3e8403326884a0334b3dcd699df2482669cca4be/powerfx-0.0.34-py3-none-any.whl", hash = "sha256:f2dc1c42ba8bfa4c72a7fcff2a00755b95394547388ca0b3e36579c49ee7ed75", size = 3483089 }, +] + [[package]] name = "pre-commit" version = "4.5.0" @@ -2529,7 +3052,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "agent-framework", specifier = ">=1.0.0b251016" }, + { name = "agent-framework", specifier = ">=1.0.0rc5" }, { name = "azure-ai-agents", specifier = ">=1.1.0" }, { name = "azure-core-tracing-opentelemetry", specifier = ">=1.0.0b12" }, { name = "azure-cosmos", specifier = ">=4.9.0" }, @@ -2573,6 +3096,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6c/a0/4ed6632b70a52de845df056654162acdebaf97c20e3212c559ac43e7216e/python_ulid-3.1.0-py3-none-any.whl", hash = "sha256:e2cdc979c8c877029b4b7a38a6fba3bc4578e4f109a308419ff4d3ccf0a46619", size = 11577 }, ] +[[package]] +name = "pythonnet" +version = "3.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "clr-loader" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/d6/1afd75edd932306ae9bd2c2d961d603dc2b52fcec51b04afea464f1f6646/pythonnet-3.0.5.tar.gz", hash = "sha256:48e43ca463941b3608b32b4e236db92d8d40db4c58a75ace902985f76dac21cf", size = 239212 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/f1/bfb6811df4745f92f14c47a29e50e89a36b1533130fcc56452d4660bd2d6/pythonnet-3.0.5-py3-none-any.whl", hash = "sha256:f6702d694d5d5b163c9f3f5cc34e0bed8d6857150237fae411fefb883a656d20", size = 297506 }, +] + [[package]] name = "pytz" version = "2025.2" @@ -2855,6 +3390,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1d/d2/1637f4360ada6a368d3265bf39f2cf737a0aaab15ab520fc005903e883f8/ruff-0.14.7-py3-none-win_arm64.whl", hash = "sha256:be4d653d3bea1b19742fcc6502354e32f65cd61ff2fbdb365803ef2c2aec6228", size = 13609215 }, ] +[[package]] +name = "s3transfer" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/04/74127fc843314818edfa81b5540e26dd537353b123a4edc563109d8f17dd/s3transfer-0.16.0.tar.gz", hash = "sha256:8e990f13268025792229cd52fa10cb7163744bf56e719e0b9cb925ab79abf920", size = 153827 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl", hash = "sha256:18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe", size = 86830 }, +] + [[package]] name = "secretstorage" version = "3.5.0" @@ -2987,6 +3534,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 }, ] +[[package]] +name = "types-requests" +version = "2.32.4.20260324" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6c/b1/66bafdc85965e5aa3db42e1b9128bf8abe252edd7556d00a07ef437a3e0e/types_requests-2.32.4.20260324.tar.gz", hash = "sha256:33a2a9ccb1de7d4e4da36e347622c35418f6761269014cc32857acabd5df739e", size = 23765 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/5a/ce5999f9bd72c7fac681d26cd0a5782b379053bfc2214e2a3fbe30852c9e/types_requests-2.32.4.20260324-py3-none-any.whl", hash = "sha256:f83ef2deb284fe99a249b8b0b0a3e4b9809e01ff456063c4df0aac7670c07ab9", size = 20735 }, +] + [[package]] name = "typing-extensions" version = "4.15.0" @@ -3123,6 +3682,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743 }, ] +[[package]] +name = "werkzeug" +version = "3.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b5/43/76ded108b296a49f52de6bac5192ca1c4be84e886f9b5c9ba8427d9694fd/werkzeug-3.1.7.tar.gz", hash = "sha256:fb8c01fe6ab13b9b7cdb46892b99b1d66754e1d7ab8e542e865ec13f526b5351", size = 875700 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/b2/0bba9bbb4596d2d2f285a16c2ab04118f6b957d8441566e1abb892e6a6b2/werkzeug-3.1.7-py3-none-any.whl", hash = "sha256:4b314d81163a3e1a169b6a0be2a000a0e204e8873c5de6586f453c55688d422f", size = 226295 }, +] + [[package]] name = "wrapt" version = "1.17.3" From c83e2345c94f437e569b126ae299c289567a4ffe Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Tue, 24 Mar 2026 07:39:52 -0700 Subject: [PATCH 4/5] RM tavily files, update MAF one --- README.md | 6 +-- agents/agentframework_http.py | 40 ++++++++-------- agents/agentframework_tavily.py | 76 ----------------------------- agents/langchainv1_tavily.py | 85 --------------------------------- 4 files changed, 23 insertions(+), 184 deletions(-) delete mode 100644 agents/agentframework_tavily.py delete mode 100644 agents/langchainv1_tavily.py diff --git a/README.md b/README.md index f4833b9..2e789ca 100644 --- a/README.md +++ b/README.md @@ -202,10 +202,10 @@ This project includes example agents in the [`agents/`](agents/) directory that | File | Description | | ---- | ----------- | -| [agents/agentframework_learn.py](agents/agentframework_learn.py) | Microsoft Agent Framework integration with MCP | | [agents/agentframework_http.py](agents/agentframework_http.py) | Microsoft Agent Framework integration with local Expenses MCP server | -| [agents/langchainv1_http.py](agents/langchainv1_http.py) | LangChain agent with MCP integration | -| [agents/langchainv1_github.py](agents/langchainv1_github.py) | LangChain tool filtering demo with GitHub MCP (requires `GITHUB_TOKEN`) | +| [agents/agentframework_learn.py](agents/agentframework_learn.py) | Microsoft Agent Framework integration with remote Learn MCP server | +| [agents/langchainv1_http.py](agents/langchainv1_http.py) | LangChain agent with local Expenses MCP server | +| [agents/langchainv1_github.py](agents/langchainv1_github.py) | LangChain tool-filtering agent with remote GitHub MCP (requires `GITHUB_TOKEN`) | **To run an agent:** diff --git a/agents/agentframework_http.py b/agents/agentframework_http.py index 717bb7f..33c3dd8 100644 --- a/agents/agentframework_http.py +++ b/agents/agentframework_http.py @@ -56,27 +56,27 @@ # --- Main Agent Logic --- async def http_mcp_example() -> None: """Run an agent connected to the local expenses MCP server.""" + try: + async with ( + MCPStreamableHTTPTool(name="Expenses MCP Server", url=MCP_SERVER_URL) as mcp_server, + Agent( + client=client, + name="Expenses Agent", + instructions=f"You help users to log expenses. Today's date is {datetime.now().strftime('%Y-%m-%d')}.", + tools=[mcp_server], + ) as agent, + ): + user_query = "yesterday I bought a laptop for $1200 using my visa." + result = await agent.run(user_query) + print(result.text) - async with ( - MCPStreamableHTTPTool(name="Expenses MCP Server", url=MCP_SERVER_URL) as mcp_server, - Agent( - client=client, - name="Expenses Agent", - instructions=f"You help users to log expenses. Today's date is {datetime.now().strftime('%Y-%m-%d')}.", - tools=[mcp_server], - ) as agent, - ): - user_query = "yesterday I bought a laptop for $1200 using my visa." - result = await agent.run(user_query) - print(result.text) - - # Keep the worker alive in production - while RUNNING_IN_PRODUCTION: - await asyncio.sleep(60) - logger.info("Worker still running...") - - if async_credential: - await async_credential.close() + # Keep the worker alive in production + while RUNNING_IN_PRODUCTION: + await asyncio.sleep(60) + logger.info("Worker still running...") + finally: + if async_credential: + await async_credential.close() if __name__ == "__main__": diff --git a/agents/agentframework_tavily.py b/agents/agentframework_tavily.py deleted file mode 100644 index 543a9f2..0000000 --- a/agents/agentframework_tavily.py +++ /dev/null @@ -1,76 +0,0 @@ -import asyncio -import logging -import os -from urllib.parse import urlencode - -from agent_framework import Agent, MCPStreamableHTTPTool -from agent_framework.openai import OpenAIChatClient -from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider -from dotenv import load_dotenv -from rich import print -from rich.logging import RichHandler - -# Configure logging -logging.basicConfig(level=logging.WARNING, format="%(message)s", datefmt="[%X]", handlers=[RichHandler()]) -logger = logging.getLogger("agentframework_tavily") -logger.setLevel(logging.INFO) - -# Load environment variables -load_dotenv(override=True) - -# Configure chat client based on API_HOST -API_HOST = os.getenv("API_HOST", "github") -async_credential = None -if API_HOST == "azure": - async_credential = DefaultAzureCredential() - token_provider = get_bearer_token_provider(async_credential, "https://cognitiveservices.azure.com/.default") - client = OpenAIChatClient( - base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT']}/openai/v1/", - api_key=token_provider, - model_id=os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"], - ) -elif API_HOST == "github": - client = OpenAIChatClient( - base_url="https://models.github.ai/inference", - api_key=os.environ["GITHUB_TOKEN"], - model_id=os.getenv("GITHUB_MODEL", "openai/gpt-4.1-mini"), - ) -elif API_HOST == "ollama": - client = OpenAIChatClient( - base_url=os.environ.get("OLLAMA_ENDPOINT", "http://localhost:11434/v1"), - api_key="none", - model_id=os.environ.get("OLLAMA_MODEL", "llama3.1:latest"), - ) -else: - client = OpenAIChatClient( - api_key=os.environ.get("OPENAI_API_KEY"), model_id=os.environ.get("OPENAI_MODEL", "gpt-4.1-mini") - ) - - -async def http_mcp_example() -> None: - """ - Creates an agent that can search the web using the Tavily MCP server. - """ - - tavily_key = os.environ["TAVILY_API_KEY"].strip() - tavily_url = f"https://mcp.tavily.com/mcp/?{urlencode({'tavilyApiKey': tavily_key})}" - - async with ( - MCPStreamableHTTPTool(name="Tavily MCP", url=tavily_url) as mcp_server, - Agent( - client=client, - name="WebSearchAgent", - instructions="You search the web with Tavily and provide concise answers with links.", - tools=[mcp_server], - ) as agent, - ): - query = "What's new in Python 3.14? Include relevant links." - result = await agent.run(query) - print(result.text) - - if async_credential: - await async_credential.close() - - -if __name__ == "__main__": - asyncio.run(http_mcp_example()) diff --git a/agents/langchainv1_tavily.py b/agents/langchainv1_tavily.py deleted file mode 100644 index 7e78fc4..0000000 --- a/agents/langchainv1_tavily.py +++ /dev/null @@ -1,85 +0,0 @@ -"""LangChain + Tavily MCP Example - -Creates a simple research agent that uses the Tavily MCP server -to search the web and answer questions with relevant links. -""" - -import asyncio -import logging -import os -from urllib.parse import urlencode - -import azure.identity -from dotenv import load_dotenv -from langchain.agents import create_agent -from langchain_core.messages import HumanMessage -from langchain_mcp_adapters.client import MultiServerMCPClient -from langchain_openai import ChatOpenAI -from pydantic import SecretStr -from rich.logging import RichHandler - -# Configure logging -logging.basicConfig(level=logging.WARNING, format="%(message)s", datefmt="[%X]", handlers=[RichHandler()]) -logger = logging.getLogger("langchainv1_tavily") -logger.setLevel(logging.INFO) - -# Load environment variables -load_dotenv(override=True) - -api_host = os.getenv("API_HOST", "github") - -if api_host == "azure": - token_provider = azure.identity.get_bearer_token_provider( - azure.identity.DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default" - ) - model = ChatOpenAI( - model=os.environ.get("AZURE_OPENAI_CHAT_DEPLOYMENT"), - base_url=os.environ["AZURE_OPENAI_ENDPOINT"] + "/openai/v1/", - api_key=token_provider, - ) -elif api_host == "github": - model = ChatOpenAI( - model=os.getenv("GITHUB_MODEL", "gpt-4o"), - base_url="https://models.inference.ai.azure.com", - api_key=SecretStr(os.environ["GITHUB_TOKEN"]), - ) -elif api_host == "ollama": - model = ChatOpenAI( - model=os.environ.get("OLLAMA_MODEL", "llama3.1"), - base_url=os.environ.get("OLLAMA_ENDPOINT", "http://localhost:11434/v1"), - api_key=SecretStr(os.environ.get("OLLAMA_API_KEY", "none")), - ) -else: - model = ChatOpenAI(model=os.getenv("OPENAI_MODEL", "gpt-4o-mini")) - - -async def run_agent() -> None: - """Run a Tavily-backed research agent via MCP tools.""" - tavily_key = os.environ["TAVILY_API_KEY"].strip() - tavily_url = f"https://mcp.tavily.com/mcp/?{urlencode({'tavilyApiKey': tavily_key})}" - client = MultiServerMCPClient( - { - "tavily": { - "url": tavily_url, - "transport": "streamable_http", - } - } - ) - - # Fetch available tools and create the agent - tools = await client.get_tools() - agent = create_agent(model, tools, prompt="You search the web and include relevant links in answers.") - - query = "What's new in Python 3.14? Include relevant links." - response = await agent.ainvoke({"messages": [HumanMessage(content=query)]}) - - final_response = response["messages"][-1].content - print(final_response) - - -def main() -> None: - asyncio.run(run_agent()) - - -if __name__ == "__main__": - main() From 0715ff26bd02fbf8b9d5e46eabcb5a85a4b8df5f Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Tue, 24 Mar 2026 07:42:03 -0700 Subject: [PATCH 5/5] Use try/finally --- agents/agentframework_learn.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/agents/agentframework_learn.py b/agents/agentframework_learn.py index 304b2b5..8e9677f 100644 --- a/agents/agentframework_learn.py +++ b/agents/agentframework_learn.py @@ -52,21 +52,23 @@ async def http_mcp_example() -> None: using the Microsoft Learn MCP server. """ - async with ( - MCPStreamableHTTPTool(name="Microsoft Learn MCP", url="https://learn.microsoft.com/api/mcp") as mcp_server, - Agent( - client=client, - name="DocsAgent", - instructions="You help with Microsoft documentation questions.", - tools=[mcp_server], - ) as agent, - ): - query = "How to create an Azure storage account using az cli?" - result = await agent.run(query) - print(result.text) + try: + async with ( + MCPStreamableHTTPTool(name="Microsoft Learn MCP", url="https://learn.microsoft.com/api/mcp") as mcp_server, + Agent( + client=client, + name="DocsAgent", + instructions="You help with Microsoft documentation questions.", + tools=[mcp_server], + ) as agent, + ): + query = "How to create an Azure storage account using az cli?" + result = await agent.run(query) + print(result.text) - if async_credential: - await async_credential.close() + finally: + if async_credential: + await async_credential.close() if __name__ == "__main__":