From 796808830b6b742ea9376b94e122b91d12647d98 Mon Sep 17 00:00:00 2001 From: Wey Gu Date: Fri, 29 May 2026 16:53:14 +0800 Subject: [PATCH 1/3] chore: relax openai and fastmcp pins --- CHANGELOG.md | 2 + packages/kosong/CHANGELOG.md | 2 + packages/kosong/pyproject.toml | 2 +- pyproject.toml | 2 +- uv.lock | 80 +++++++++++++++++++++++++--------- 5 files changed, 66 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5bb391b8..8687cfeb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ Only write entries that are worth mentioning to users. ## Unreleased +- MCP: Bump FastMCP to 3.3.1, keeping OAuth MCP support on the current upstream client/server stack + ## 1.46.0 (2026-05-28) - Shell: Support styled text in welcome tips diff --git a/packages/kosong/CHANGELOG.md b/packages/kosong/CHANGELOG.md index a010d2e59..ad2802671 100644 --- a/packages/kosong/CHANGELOG.md +++ b/packages/kosong/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- OpenAI: Relax the OpenAI SDK dependency to allow current 2.x releases, so downstream apps can keep their provider stack up to date without conflicting with Kosong + ## 0.53.0 (2026-04-28) - Kimi: Fix stale API key after OAuth token refresh — `on_retryable_error` now reads the current `api_key` from the live client instead of the cached `_api_key`, so that OAuth token refreshes applied via `client.api_key` are preserved when the client is rebuilt after a retryable error diff --git a/packages/kosong/pyproject.toml b/packages/kosong/pyproject.toml index 945d80fe6..8be0bedc5 100644 --- a/packages/kosong/pyproject.toml +++ b/packages/kosong/pyproject.toml @@ -9,7 +9,7 @@ dependencies = [ "google-genai>=1.56.0", "jsonschema>=4.25.1", "loguru>=0.6.0,<0.8", - "openai>=2.14.0,<2.15.0", + "openai>=2.14.0,<3.0.0", "pydantic>=2.12.5", "python-dotenv>=1.2.1", "typing-extensions>=4.15.0", diff --git a/pyproject.toml b/pyproject.toml index d6ffbe818..3d9e9995b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ dependencies = [ # lxml is used by trafilatura/htmldate/justext; keep pinned for binary wheels. "lxml==6.0.2", "tenacity==9.1.2", - "fastmcp==3.2.4", + "fastmcp==3.3.1", "pydantic==2.12.5", "httpx[socks]==0.28.1", "pykaos==0.9.0", diff --git a/uv.lock b/uv.lock index e5a4d81f6..4d033921a 100644 --- a/uv.lock +++ b/uv.lock @@ -261,14 +261,15 @@ wheels = [ [[package]] name = "authlib" -version = "1.6.5" +version = "1.7.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, + { name = "joserfc" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cd/3f/1d3bbd0bf23bdd99276d4def22f29c27a914067b4cf66f753ff9b8bbd0f3/authlib-1.6.5.tar.gz", hash = "sha256:6aaf9c79b7cc96c900f0b284061691c5d4e61221640a948fe690b556a6d6d10b", size = 164553, upload-time = "2025-10-02T13:36:09.489Z" } +sdist = { url = "https://files.pythonhosted.org/packages/36/98/7d93f30d029643c0275dbc0bd6d5a6f670661ee6c9a94d93af7ab4887600/authlib-1.7.2.tar.gz", hash = "sha256:2cea25fefcd4e7173bdf1372c0afc265c8034b23a8cd5dcb6a9164b826c64231", size = 176511, upload-time = "2026-05-06T08:10:23.116Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/aa/5082412d1ee302e9e7d80b6949bc4d2a8fa1149aaab610c5fc24709605d6/authlib-1.6.5-py2.py3-none-any.whl", hash = "sha256:3e0e0507807f842b02175507bdee8957a1d5707fd4afb17c32fb43fee90b6e3a", size = 243608, upload-time = "2025-10-02T13:36:07.637Z" }, + { url = "https://files.pythonhosted.org/packages/fb/95/adcb68e20c34162e9135f370d6e31737719c2b6f94bc953fe7ed1f10fe21/authlib-1.7.2-py2.py3-none-any.whl", hash = "sha256:3e1faedc9d87e7d56a164eca3ccb6ace0d61b94abe83e92242f8dc8bba9b4a9f", size = 259548, upload-time = "2026-05-06T08:10:21.436Z" }, ] [[package]] @@ -698,9 +699,43 @@ wheels = [ [[package]] name = "fastmcp" -version = "3.2.4" +version = "3.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "fastmcp-slim", extra = ["client", "server"] }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3b/a9/5c5a01b6abd5346bf60b97cfd29e4a86661940c27dd562bfcda07fd03519/fastmcp-3.3.1.tar.gz", hash = "sha256:979362ea557de42a5f40342563c7e4b236bcc8e7cd192715f50030695d1a71cd", size = 28681699, upload-time = "2026-05-15T15:50:39.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/11/6b1bdada6ccfe647d615ae63f9106f8136aec17971e9361546af01c7d38e/fastmcp-3.3.1-py3-none-any.whl", hash = "sha256:862440c5c4d281363a5995eee59d77f0f7cac1f18869038729cecf03b02fc522", size = 7903, upload-time = "2026-05-15T15:50:36.424Z" }, +] + +[[package]] +name = "fastmcp-slim" +version = "3.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "pydantic", extra = ["email"] }, + { name = "pydantic-settings" }, + { name = "python-dotenv" }, + { name = "rich" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d1/a0/627103e517e1d0d6f1eec633d5662d13e776f01b45ad188e4f5f7478b438/fastmcp_slim-3.3.1.tar.gz", hash = "sha256:0957835fc59452e143ab2f4b7836d2d2df9b2d9958408edc79ba8b56232b2a88", size = 567007, upload-time = "2026-05-15T15:50:10.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/ee/97047f4cc2d7b1d46670d08d8ad01a96e7a748cc01c0b4b351ad8eddbc7a/fastmcp_slim-3.3.1-py3-none-any.whl", hash = "sha256:6cf1c2d77e3adb0d409d6825ed6b0b2a999062973e00b8eea03bd48bf9b4c043", size = 738644, upload-time = "2026-05-15T15:50:08.336Z" }, +] + +[package.optional-dependencies] +client = [ + { name = "authlib" }, + { name = "exceptiongroup" }, + { name = "httpx" }, + { name = "mcp" }, + { name = "opentelemetry-api" }, + { name = "py-key-value-aio", extra = ["filetree", "keyring", "memory"] }, +] +server = [ { name = "authlib" }, { name = "cyclopts" }, { name = "exceptiongroup" }, @@ -712,22 +747,15 @@ dependencies = [ { name = "openapi-pydantic" }, { name = "opentelemetry-api" }, { name = "packaging" }, - { name = "platformdirs" }, { name = "py-key-value-aio", extra = ["filetree", "keyring", "memory"] }, - { name = "pydantic", extra = ["email"] }, { name = "pyperclip" }, - { name = "python-dotenv" }, + { name = "python-multipart" }, { name = "pyyaml" }, - { name = "rich" }, { name = "uncalled-for" }, { name = "uvicorn" }, { name = "watchfiles" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9c/13/29544fbc6dfe45ea38046af0067311e0bad7acc7d1f2ad38bb08f2409fe2/fastmcp-3.2.4.tar.gz", hash = "sha256:083ecb75b44a4169e7fc0f632f94b781bdb0ff877c6b35b9877cbb566fd4d4d1", size = 28746127, upload-time = "2026-04-14T01:42:24.174Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/76/b310d52fa0e30d39bd937eb58ec2c1f1ea1b5f519f0575e9dd9612f01deb/fastmcp-3.2.4-py3-none-any.whl", hash = "sha256:e6c9c429171041455e47ab94bb3f83c4657622a0ec28922f6940053959bd58a9", size = 728599, upload-time = "2026-04-14T01:42:26.85Z" }, -] [[package]] name = "frozenlist" @@ -1200,6 +1228,18 @@ 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, upload-time = "2025-10-17T11:31:13.773Z" }, ] +[[package]] +name = "joserfc" +version = "1.6.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5d/ac/d4fd5b30f82900eac60d765f179f0ba005825ac462cc8ced6e13ec685ab3/joserfc-1.6.8.tar.gz", hash = "sha256:878620c553a6ebdd76ccdc356782fee3f735f21a356d079a546b42a4670ace5f", size = 232930, upload-time = "2026-05-27T03:22:37.819Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/8c/5cdce2cf3ce8155849baf9a5e2ce77e89dc87ec3bdb38259e5d85fbc45bd/joserfc-1.6.8-py3-none-any.whl", hash = "sha256:22fb31a69094a5e6f44632002a9df2c30c941fc6c8ce1b037e92c03de954cf9f", size = 70927, upload-time = "2026-05-27T03:22:35.796Z" }, +] + [[package]] name = "jsonref" version = "1.1.0" @@ -1335,7 +1375,7 @@ requires-dist = [ { name = "aiohttp", specifier = "==3.13.3" }, { name = "batrachian-toad", marker = "python_full_version >= '3.14'", specifier = "==0.5.23" }, { name = "fastapi", specifier = ">=0.115.0" }, - { name = "fastmcp", specifier = "==3.2.4" }, + { name = "fastmcp", specifier = "==3.3.1" }, { name = "httpx", extras = ["socks"], specifier = "==0.28.1" }, { name = "jinja2", specifier = "==3.1.6" }, { name = "keyring", specifier = ">=25.7.0" }, @@ -1462,7 +1502,7 @@ requires-dist = [ { name = "jsonschema", specifier = ">=4.25.1" }, { name = "loguru", specifier = ">=0.6.0,<0.8" }, { name = "mcp", specifier = ">=1,<2" }, - { name = "openai", specifier = ">=2.14.0,<2.15.0" }, + { name = "openai", specifier = ">=2.14.0,<3.0.0" }, { name = "pydantic", specifier = ">=2.12.5" }, { name = "python-dotenv", specifier = ">=1.2.1" }, { name = "typing-extensions", specifier = ">=4.15.0" }, @@ -1910,7 +1950,7 @@ wheels = [ [[package]] name = "openai" -version = "2.14.0" +version = "2.38.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1922,9 +1962,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/b1/12fe1c196bea326261718eb037307c1c1fe1dedc2d2d4de777df822e6238/openai-2.14.0.tar.gz", hash = "sha256:419357bedde9402d23bf8f2ee372fca1985a73348debba94bddff06f19459952", size = 626938, upload-time = "2025-12-19T03:28:45.742Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8f/12/cfa322c5f5dd8fa21aab9a7a8e979e7a11123800f86ca8d82eb68a83d213/openai-2.38.0.tar.gz", hash = "sha256:798694c6cf74145541fda94325b6f8f72d8e1fd0262cc137c8d728177a6a4ce3", size = 772764, upload-time = "2026-05-21T21:23:42.105Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/4b/7c1a00c2c3fbd004253937f7520f692a9650767aa73894d7a34f0d65d3f4/openai-2.14.0-py3-none-any.whl", hash = "sha256:7ea40aca4ffc4c4a776e77679021b47eec1160e341f42ae086ba949c9dcc9183", size = 1067558, upload-time = "2025-12-19T03:28:43.727Z" }, + { url = "https://files.pythonhosted.org/packages/0a/bf/ccff9be562e24207716d04ef9dc931c76aff0c89a7265da43e2104d7fe06/openai-2.38.0-py3-none-any.whl", hash = "sha256:ec6661c57b2dcc47414a767e6e3335c7ed3d19c9696999283a3c82e95c756a3c", size = 1344910, upload-time = "2026-05-21T21:23:39.636Z" }, ] [[package]] @@ -2548,11 +2588,11 @@ wheels = [ [[package]] name = "python-multipart" -version = "0.0.20" +version = "0.0.29" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/fe/70bd71a6738b09a0bdf6480ca6436b167469ca4578b2a0efbe390b4b0e70/python_multipart-0.0.29.tar.gz", hash = "sha256:643e93849196645e2dbdd81a0f8829a23123ad7f797a84a364c6fb3563f18904", size = 45678, upload-time = "2026-05-17T17:29:47.654Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" }, + { url = "https://files.pythonhosted.org/packages/8f/cb/769cfc37177252872a45a71f3fbdde9d51b471a3f3c14bfe95dde3407386/python_multipart-0.0.29-py3-none-any.whl", hash = "sha256:2ddcc971cef266225f54f552d8fa10bcfbb1f14446caec199060daac59ff2d69", size = 29640, upload-time = "2026-05-17T17:29:45.69Z" }, ] [[package]] From b5b14fe107e15ae0636250d2a65ed2a39fec03ef Mon Sep 17 00:00:00 2001 From: Wey Gu Date: Fri, 29 May 2026 17:00:02 +0800 Subject: [PATCH 2/3] chore: tighten openai sdk upper bound --- packages/kosong/CHANGELOG.md | 2 +- packages/kosong/pyproject.toml | 2 +- uv.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/kosong/CHANGELOG.md b/packages/kosong/CHANGELOG.md index ad2802671..28869f573 100644 --- a/packages/kosong/CHANGELOG.md +++ b/packages/kosong/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -- OpenAI: Relax the OpenAI SDK dependency to allow current 2.x releases, so downstream apps can keep their provider stack up to date without conflicting with Kosong +- OpenAI: Relax the OpenAI SDK dependency to allow recent tested 2.x releases, so downstream apps can keep their provider stack up to date without conflicting with Kosong ## 0.53.0 (2026-04-28) diff --git a/packages/kosong/pyproject.toml b/packages/kosong/pyproject.toml index 8be0bedc5..110ddbeed 100644 --- a/packages/kosong/pyproject.toml +++ b/packages/kosong/pyproject.toml @@ -9,7 +9,7 @@ dependencies = [ "google-genai>=1.56.0", "jsonschema>=4.25.1", "loguru>=0.6.0,<0.8", - "openai>=2.14.0,<3.0.0", + "openai>=2.14.0,<2.38.0", "pydantic>=2.12.5", "python-dotenv>=1.2.1", "typing-extensions>=4.15.0", diff --git a/uv.lock b/uv.lock index 4d033921a..86ce6a119 100644 --- a/uv.lock +++ b/uv.lock @@ -1502,7 +1502,7 @@ requires-dist = [ { name = "jsonschema", specifier = ">=4.25.1" }, { name = "loguru", specifier = ">=0.6.0,<0.8" }, { name = "mcp", specifier = ">=1,<2" }, - { name = "openai", specifier = ">=2.14.0,<3.0.0" }, + { name = "openai", specifier = ">=2.14.0,<2.38.0" }, { name = "pydantic", specifier = ">=2.12.5" }, { name = "python-dotenv", specifier = ">=1.2.1" }, { name = "typing-extensions", specifier = ">=4.15.0" }, @@ -1950,7 +1950,7 @@ wheels = [ [[package]] name = "openai" -version = "2.38.0" +version = "2.37.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1962,9 +1962,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8f/12/cfa322c5f5dd8fa21aab9a7a8e979e7a11123800f86ca8d82eb68a83d213/openai-2.38.0.tar.gz", hash = "sha256:798694c6cf74145541fda94325b6f8f72d8e1fd0262cc137c8d728177a6a4ce3", size = 772764, upload-time = "2026-05-21T21:23:42.105Z" } +sdist = { url = "https://files.pythonhosted.org/packages/32/50/5901f01ef14e6c27788beb91e54fef5d6204fb5fb9e97402fc8a14de2e32/openai-2.37.0.tar.gz", hash = "sha256:f4bc562cc5f3a43d40d678105572d9d44765f6e0f50c125f63055419b72f4bd9", size = 754706, upload-time = "2026-05-15T22:30:35.428Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/bf/ccff9be562e24207716d04ef9dc931c76aff0c89a7265da43e2104d7fe06/openai-2.38.0-py3-none-any.whl", hash = "sha256:ec6661c57b2dcc47414a767e6e3335c7ed3d19c9696999283a3c82e95c756a3c", size = 1344910, upload-time = "2026-05-21T21:23:39.636Z" }, + { url = "https://files.pythonhosted.org/packages/ed/4c/bce61680d0699a78a405fd9a67989b175ba020590428831aab2ab1d2be7c/openai-2.37.0-py3-none-any.whl", hash = "sha256:814633888b8f3b1ffd6615697c6e4ef93632d08b7c2e28c8c5ef3556e5a10107", size = 1303238, upload-time = "2026-05-15T22:30:32.767Z" }, ] [[package]] From e1a89f2979f291e70e7438c3cb09a2cfcde25f4f Mon Sep 17 00:00:00 2001 From: Wey Gu Date: Fri, 29 May 2026 17:05:16 +0800 Subject: [PATCH 3/3] test: avoid hard-coded fastmcp metadata version --- tests/utils/test_pyinstaller_utils.py | 41 +++++++++------------------ 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/tests/utils/test_pyinstaller_utils.py b/tests/utils/test_pyinstaller_utils.py index 2f754720f..dbf14c4ed 100644 --- a/tests/utils/test_pyinstaller_utils.py +++ b/tests/utils/test_pyinstaller_utils.py @@ -2,6 +2,7 @@ import platform import sys +from importlib.metadata import distribution from pathlib import Path from inline_snapshot import snapshot @@ -13,6 +14,8 @@ def test_pyinstaller_datas(): project_root = Path(__file__).parent.parent.parent python_version = f"{sys.version_info.major}.{sys.version_info.minor}" site_packages = f".venv/lib/python{python_version}/site-packages" + fastmcp_distribution = distribution("fastmcp") + fastmcp_dist_info = f"fastmcp-{fastmcp_distribution.version}.dist-info" rg_binary = "rg.exe" if platform.system() == "Windows" else "rg" has_rg_binary = (project_root / "src/kimi_cli/deps/bin" / rg_binary).exists() datas = [ @@ -28,39 +31,21 @@ def test_pyinstaller_datas(): datas = [(p, d) for p, d in datas if "web/static" not in d and "vis/static" not in d] + fastmcp_dist_info_datas = [ + ( + f"{site_packages}/fastmcp/../{file_path}", + f"fastmcp/../{Path(file_path).parent.as_posix()}", + ) + for file_path in sorted(str(file) for file in fastmcp_distribution.files or []) + if file_path.startswith(f"{fastmcp_dist_info}/") + ] + expected_datas = [ ( f"{site_packages}/dateparser/data/dateparser_tz_cache.pkl", "dateparser/data", ), - ( - f"{site_packages}/fastmcp/../fastmcp-3.2.4.dist-info/INSTALLER", - "fastmcp/../fastmcp-3.2.4.dist-info", - ), - ( - f"{site_packages}/fastmcp/../fastmcp-3.2.4.dist-info/METADATA", - "fastmcp/../fastmcp-3.2.4.dist-info", - ), - ( - f"{site_packages}/fastmcp/../fastmcp-3.2.4.dist-info/RECORD", - "fastmcp/../fastmcp-3.2.4.dist-info", - ), - ( - f"{site_packages}/fastmcp/../fastmcp-3.2.4.dist-info/REQUESTED", - "fastmcp/../fastmcp-3.2.4.dist-info", - ), - ( - f"{site_packages}/fastmcp/../fastmcp-3.2.4.dist-info/WHEEL", - "fastmcp/../fastmcp-3.2.4.dist-info", - ), - ( - f"{site_packages}/fastmcp/../fastmcp-3.2.4.dist-info/entry_points.txt", - "fastmcp/../fastmcp-3.2.4.dist-info", - ), - ( - f"{site_packages}/fastmcp/../fastmcp-3.2.4.dist-info/licenses/LICENSE", - "fastmcp/../fastmcp-3.2.4.dist-info/licenses", - ), + *fastmcp_dist_info_datas, ( "src/kimi_cli/CHANGELOG.md", "kimi_cli",