Microsoft Teams plugin packaging and Python version issues

NousResearch/hermes-agent · cluster 22015 · docs

Data as of

Nothing open on GitHub. Fix merged in #46764. Check it covers your case.

The short answer

0open issues
0open PRs
6items grouped
Known?
Yes. 6 related items grouped here, 2 issues already closed.
Fix event
A fix was merged to main in PR #46764. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this unresolved. That is separate from the fix event.
Still open
Nothing open on GitHub.

These issues and PRs concern the Microsoft Teams platform plugin failing to load due to Python version constraints and packaging problems. Work focuses on making the Teams SDK an installable extra, documenting local installation, and adding clear error messaging for version incompatibilities.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #46764 fix(teams): package Microsoft Teams SDK as an installable extra (salvage #43945)

    merged to main

    files: plugins/platforms/teams/adapter.py, pyproject.toml, scripts/release.py, tests/gateway/test_teams.py, tools/lazy_deps.py, website/docs/user-guide/messaging/teams.md

    Show the diff
    • plugins/platforms/teams/adapter.py
      @@ -617,7 +617,74 @@ async def _standalone_send(
       
       
       # Keep the old name as an alias so existing test imports don't break.
      -check_teams_requirements = check_requirements
      +# NOTE: ``check_requirements`` is the PASSIVE probe (used as the registry
      +# ``check_fn`` and by ``gateway status``) — it must never trigger a pip
      +# install. ``check_teams_requirements`` is the ACTIVE lazy-installer called
      +# from ``connect()``; it installs ``platform.teams`` on demand and rebinds the
      +# SDK globals, mirroring ``check_slack_requirements`` in gateway/platforms/slack.py.
      +def check_teams_requirements() -> bool:
      +    """Ensure the Teams SDK is importable, lazy-installing it on first use.
      +
      +    Lazy-installs ``microsoft-teams-apps`` via
      +    ``tools.lazy_deps.ensure("platform.teams")`` if not present, then rebinds
      +    all module-level SDK globals on success. Returns True once the SDK (and
      +    aiohttp) are importable, False if they couldn't be installed/imported.
      +    """
      +    if TEAMS_SDK_AVAILABLE and AIOHTTP_AVAILABLE:
      +        return True
      +
      +    def _import() -> dict:
      +        from aiohttp import web as _web
      +        from microsoft_teams.apps import App, ActivityContext
      +        from microsoft_teams.common.http.client import ClientOptions
      +        from microsoft_teams.api import MessageActivity, ConversationReference
      +        from microsoft_teams.api.activities.typing import TypingActivityInput
      +        from microsoft_teams.api.activities.invoke.adaptive_card import (
      +            AdaptiveCardInvokeActivity,
      +        )
      +        from microsoft_teams.api.models.adaptive_card import (
      +            AdaptiveCardActionCardResponse,
      +            AdaptiveCardActionMessageResponse,
      +        )
      +        from microsoft_teams.api.models.invoke_response import (
      +            InvokeResponse,
      +            AdaptiveCardInvokeResponse,
      +        )
      +        from microsoft_teams.apps.http.adapter import (
      +            HttpMethod,
      +            HttpRequest,
      +            HttpResponse,
      +            HttpRouteHandler,
      +        )
      +        from microsoft_teams.cards import AdaptiveCard, ExecuteAction, TextBlock
      +
      +        return {
      +            "web": _web,
      +            "AIOHTTP_AVAILABLE": True,
      +            "App": App,
      +            "ActivityContext": ActivityContext,
      +            "ClientOptions": ClientOptions,
      +            "MessageActivity": MessageActivity,
      +            "ConversationReference": ConversationReference,
      +            "TypingActivityInput": TypingActivityInput,
      +            "AdaptiveCardInvokeActivity": AdaptiveCardInvokeActivity,
      +            "AdaptiveCardActionCardResponse": AdaptiveCardActionCardResponse,
      +            "AdaptiveCardActionMessageResponse": AdaptiveCardActionMessageResponse,
      +            "InvokeResponse": InvokeResponse,
      +            "AdaptiveCardInvokeResponse": AdaptiveCardInvokeResponse,
      +            "HttpMethod": HttpMethod,
      +            "HttpRequest": HttpRequest,
      +            "HttpResponse": HttpResponse,
      +            "HttpRouteHandler": HttpRouteHandler,
      +            "AdaptiveCard": AdaptiveCard,
      +            "ExecuteAction": ExecuteAction,
      +            "TextBlock": TextBlock,
      +            "TEAMS_SDK_AVAILABLE": True,
      +        }
      +
      +    from tools.lazy_deps import ensure_and_bind
      +
      +    return ensure_and_bind("platform.teams", _import, globals(), prompt=False)
       
       
       class TeamsAdapter(BasePlatformAdapter):
      @@ -642,10 +709,13 @@ def __init__(self, config: PlatformConfig):
               self._conv_refs: Dict[str, Any] = {}
       
           async def connect(self) -> bool:
      +        # Lazy-install the Teams SDK on demand (parity with Slack/Discord/etc.),
      +        # then re-check the module globals it rebinds.
      +        check_teams_requirements()
               if not TEAMS_SDK_AVAILABLE:
                   self._set_fatal_error(
                       "MISSING_SDK",
      -                "microsoft-teams-apps not installed. Run: pip install microsoft-teams-apps",
      +                "microsoft-teams-apps could not be installed. Run: pip install microsoft-teams-apps",
                       retryable=False,
                   )
                   return False
    • pyproject.toml
      @@ -179,6 +179,7 @@ mcp = ["mcp==1.26.0", "starlette==1.0.1"]  # starlette: CVE-2026-48710
       nemo-relay = ["nemo-relay==0.3"]
       homeassistant = ["aiohttp==3.13.4"]
       sms = ["aiohttp==3.13.4"]
      +teams = ["microsoft-teams-apps==2.0.13.4", "aiohttp==3.13.4"]
       # Computer use — macOS background desktop control via cua-driver (MCP stdio).
       # The cua-driver binary itself is installed via `hermes tools` post-setup
       # (curl install script); this extra just pins the MCP client used to talk
    • scripts/release.py
      @@ -45,6 +45,7 @@
       
       # Auto-extracted from noreply emails + manual overrides
       AUTHOR_MAP = {
      +    "[redacted:email]": "rio-jeong",
           "[redacted:email]": "ArcanePivot",
           "[redacted:email]": "benegessarit",
           "[redacted:email]": "Kenmege",
    • tests/gateway/test_teams.py
      @@ -211,10 +211,39 @@ def test_returns_true_when_deps_available(self, monkeypatch):
               monkeypatch.setattr(_teams_mod, "AIOHTTP_AVAILABLE", True)
               assert check_requirements() is True
       
      -    def test_alias_matches(self, monkeypatch):
      +    def test_check_teams_requirements_shortcircuits_when_present(self, monkeypatch):
      +        # When the SDK + aiohttp are already importable, the active lazy-
      +        # installer returns True immediately without attempting an install.
               monkeypatch.setattr(_teams_mod, "TEAMS_SDK_AVAILABLE", True)
               monkeypatch.setattr(_teams_mod, "AIOHTTP_AVAILABLE", True)
      +        called = {"ensure_and_bind": 0}
      +
      +        def _fake_ensure_and_bind(*_args, **_kwargs):
      +            called["ensure_and_bind"] += 1
      +            return True
      +
      +        monkeypatch.setattr(
      +            "tools.lazy_deps.ensure_and_bind", _fake_ensure_and_bind
      +        )
      +        assert check_teams_requirements() is True
      +        assert called["ensure_and_bind"] == 0
      +
      +    def test_check_teams_requirements_lazy_installs_when_missing(self, monkeypatch):
      +        # When deps are missing, the active installer delegates to
      +        # ensure_and_bind("platform.teams", ...) — parity with Slack/Discord.
      +        monkeypatch.setattr(_teams_mod, "TEAMS_SDK_AVAILABLE", False)
      +        monkeypatch.setattr(_teams_mod, "AIOHTTP_AVAILABLE", False)
      +        seen = {}
      +
      +        def _fake_ensure_and_bind(feature, importer, target_globals, **kwargs):
      +            seen["feature"] = feature
      +            return True
      +
      +        monkeypatch.setattr(
      +            "tools.lazy_deps.ensure_and_bind", _fake_ensure_and_bind
      +        )
               assert check_teams_requirements() is True
      +        assert seen["feature"] == "platform.teams"
       
           def test_validate_config_with_env(self, monkeypatch):
               monkeypatch.setenv("TEAMS_CLIENT_ID", "test-id")
      @@ -371,6 +400,13 @@ class TestTeamsConnect:
           @pytest.mark.anyio
           async def test_connect_fails_without_sdk(self, monkeypatch):
               monkeypatch.setattr(_teams_mod, "TEAMS_SDK_AVAILABLE", False)
      +        # Simulate the SDK being unavailable AND not installable (offline /
      +        # locked-down env): the lazy-installer can't rebind the globals, so
      +        # TEAMS_SDK_AVAILABLE stays False and connect() must fail.
      +        monkeypatch.setattr(
      +            "tools.lazy_deps.ensure_and_bind",
      +            lambda *_a, **_k: False,
      +        )
               adapter = TeamsAdapter(_make_config(
                   client_id="id", client_secret="[redacted:secret-assignment]", tenant_id="tenant",
               ))
    • tools/lazy_deps.py
      @@ -152,6 +152,11 @@
           # defusedxml only; aiohttp/httpx are core dependencies of every messaging
           # adapter and ship via `platform.discord` / `platform.slack` / etc.
           "platform.wecom_callback": ("defusedxml==0.7.1",),
      +    # Microsoft Teams adapter — microsoft-teams-apps pulls a heavy tree
      +    # (microsoft-teams-api/cards/common, dependency-injector, msal). Lazy-
      +    # installed on demand like every other messaging platform; also exposed
      +    # as the `teams` extra in pyproject for packagers / explicit installs.
      +    "platform.teams": ("microsoft-teams-apps==2.0.13.4", "aiohttp==3.13.4"),
       
           # ─── Terminal backends ─────────────────────────────────────────────────
           "terminal.modal": ("modal==1.3.4",),
    • uv.lock
      @@ -960,6 +960,28 @@ wheels = [
           { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" },
       ]
       
      +[[package]]
      +name = "dependency-injector"
      +version = "4.49.0"
      +source = { registry = "https://pypi.org/simple" }
      +dependencies = [
      +    { name = "typing-extensions", marker = "python_full_version < '3.13'" },
      +]
      +sdist = { url = "https://files.pythonhosted.org/packages/f3/be/26bb530d06618fb0bb34244d46b0d0ccc53d0974e680d8653f1b1b313a0e/dependency_injector-4.49.0.tar.gz", hash = "sha256:17a04dbfaa8159f1dc068fc26bc2fa0af9774cdd87f99e3b61bd74c9e7171589", size = 1168930, upload-time = "2026-03-22T21:20:05.524Z" }
      +wheels = [
      +    { url = "https://files.pythonhosted.org/packages/5c/5d/cc49fb34e0c03aa56d7583de00e2f8f5aa1b8a878b695e970dcdb751a477/dependency_injector-4.49.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:9690192fd5aed07f21dfdfae07696fef12c68bf98e4c0e1af8f8128b255a74a7", size = 1769395, upload-time = "2026-03-22T21:19:14.163Z" },
      +    { url = "https://files.pythonhosted.org/packages/7f/97/b3b144c96e1f7fff0a7e2e83eb0767bd23b6bacffd0ac8cff397d350e94d/dependency_injector-4.49.0-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f91f2a191bdb17bd3068f32fe65f04128bc162c6237ea554c117b303c22aaabb", size = 1852089, upload-time = "2026-03-22T21:19:16.354Z" },
      +    { url = "https://files.pythonhosted.org/packages/4c/e7/33061f427bcb56c8936d5db464d757d926bf752a874683fb64b2ee225463/dependency_injector-4.49.0-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:733c0d88b26be17a48e5741cc3e3956080112e40c07a38ff38e99dfa772f9772", size = 1765608, upload-time = "2026-03-22T21:19:19.217Z" },
      +    { url = "https://files.pythonhosted.org/packages/1e/4d/2751a6c055de4a200d65af297ecd926d6b6107f66f3849e8122928abf461/dependency_injector-4.49.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:45720b30a2a3df6e5e2320e242f6dd94540ba27c3da57cafdc37fdeec59d5ce3", size = 1746555, upload-time = "2026-03-22T21:19:21.231Z" },
      +    { url = "https://files.pythonhosted.org/packages/02/6f/f74fee9629528f0879295b9f89a5c751d3ad931eca0c78407f715e5472a6/dependency_injector-4.49.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b5d2f1be2dc971db47b1305a83b5a8c24d0eba7fb4cea7845679f9c9f24a0a9", size = 1843223, upload-time = "2026-03-22T21:19:23.356Z" },
      +    { url = "https://files.pythonhosted.org/packages/c5/f0/45948c7c933f063039a44afb4bd61747a7bafd50693e6ccdc972fac0839c/dependency_injector-4.49.0-cp310-abi3-win32.whl", hash = "sha256:0593c8aaade651a5a88ff8ba1271a8364773e76d3aa2efbeacc3be4969cafd1c", size = 1546172, upload-time = "2026-03-22T21:19:25.392Z" },
      +    { url = "https://files.pythonhosted.org/packages/e2/b5/1d8e5627137cb9a6812ecaa468eaf39154f6605c5088da4749e5a8579483/dependency_injector-4.49.0-cp310-abi3-win_amd64.whl", hash = "sha256:fa4b587158b0d65a1f9681ca648da3f9bf90f312f68c2f2e73cc58296ec2bf45", size = 1674743, upload-time = "2026-03-22T21:19:27.018Z" },
      +    { url = "https://files.pythonhosted.org/packages/92/35/ca21ab897fc193dcdbad1f856361e7614b8e2b69f9f9351e9a87a3c58e51/dependency_injector-4.49.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:6c4b49df30f13f5e4361719b21c79445db11869a7a00d80a0486c03fd764ba8f", size = 1744444, upload-time = "2026-03-22T21:19:57.332Z" },
      +    { url = "https://files.pythonhosted.org/packages/25/44/d108aeee8f2edd3e725ac0e32d16e4339a034a07da9ddaf07f772f425140/dependency_injector-4.49.0-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4b0c637ba230e390631da13bb80c955a9f85487f78c9772c0f6a3b50bfbff3a6", size = 1822320, upload-time = "2026-03-22T21:19:59.334Z" },
      +    { url = "https://files.pythonhosted.org/packages/35/32/6243ef32c384dda156b053c3df5c8b6c3ac42250ec089a09915f015d38a1/dependency_injector-4.49.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a5857b2672512654110dd0371fa965b98255e2f0507dd4732a066767b72e23c4", size = 1741215, upload-time = "2026-03-22T21:20:01.523Z" },
      +    { url = "https://files.pythonhosted.org/packages/b9/52/a1957d4ef87a52c13f2b790c1cc5fae17eb385fbe2e978c7fd8c1ebb4ea9/dependency_injector-4.49.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8ffa2ac9297446f73bd28ada81aadf4494a52d869159d58923435bcd88b5ef60", size = 1652017, upload-time = "2026-03-22T21:20:03.653Z" },
      +]
      +
       [[package]]
       name = "deprecated"
       version = "1.3.1"
      @@ -1542,6 +1564,10 @@ slack = [
       sms = [
           { name = "aiohttp" },
       ]
      +teams = [
      +    { name = "aiohttp" },
      +    { name = "microsoft-teams-apps" },
      +]
       termux = [
           { name = "agent-client-protocol" },
           { name = "honcho-ai" },
      @@ -1591,6 +1617,7 @@ requires-dist = [
           { name = "aiohttp", marker = "extra == 'messaging'", specifier = "==3.13.4" },
           { name = "aiohttp", marker = "extra == 'slack'", specifier = "==3.13.4" },
           { name = "aiohttp", marker = "extra == 'sms'", specifier = "==3.13.4" },
      +    { name = "aiohttp", marker = "extra == 'teams'", specifier = "==3.13.4" },
           { name = "aiohttp-socks", marker = "extra == 'matrix'", specifier = "==0.11.0" },
           { name = "aiosqlite", marker = "extra == 'matrix'", specifier = "==0.22.1" },
           { name = "alibabacloud-dingtalk", marker = "extra == 'dingtalk'", specifier = "==2.2.42" },
      @@ -1649,6 +1676,7 @@ requires-dist = [
           { name = "mcp", marker = "extra == 'computer-use'", specifier = "==1.26.0" },
           { name = "mcp", marker = "extra == 'dev'", specifier = "==1.26.0" },
           { name = "mcp", marker = "extra == 'mcp'", specifier = "==1.26.0" },
      +    { name = "microsoft-teams-apps", marker = "extra == 'teams'", specifier = "==2.0.13.4" },
           { name = "mistralai", marker = "extra == 'mistral'", specifier = "==2.4.8" },
           { name = "modal", marker = "extra == 'modal'", specifier = "==1.3.4" },
           { name = "nemo-relay", marker = "extra == 'nemo-relay'", specifier = "==0.3" },
      @@ -1697,7 +1725,7 @@ requires-dist = [
           { name = "websockets", specifier = "==15.0.1" },
           { name = "youtube-transcript-api", marker = "extra == 'youtube'", specifier = "==1.2.4" },
       ]
      -provides-extras = ["anthropic", "exa", "firecrawl", "parallel-web", "fal", "edge-tts", "modal", "daytona", "hindsight", "dev", "messaging", "cron", "slack", "matrix", "wecom", "cli", "tts-premium", "voice", "pty", "honcho", "vision", "mcp", "nemo-relay", "homeassistant", "sms", "computer-use", "acp", "mistral", "bedrock", "azure-identity", "termux", "termux-all", "dingtalk", "feishu", "google", "youtube", "web", "all"]
      +provides-extras = ["anthropic", "exa", "firecrawl", "parallel-web", "fal", "edge-tts", "modal", "daytona", "hindsight", "dev", "messaging", "cron", "slack", "matrix", "wecom", "cli", "tts-premium", "voice", "pty", "honcho", "vision", "mcp", "nemo-relay", "homeassistant", "sms", "teams", "computer-use", "acp", "mistral", "bedrock", "azure-identity", "termux", "termux-all", "dingtalk", "feishu", "google", "youtube", "web", "all"]
       
       [[package]]
       name = "hf-xet"
      @@ -2176,6 +2204,63 @@ wheels = [
           { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
       ]
       
      +[[package]]
      +name = "microsoft-teams-api"
      +version = "2.0.13.4"
      +source = { registry = "https://pypi.org/simple" }
      +dependencies = [
      +    { name = "microsoft-teams-cards" },
      +    { name = "microsoft-teams-common" },
      +    { name = "pydantic" },
      +    { name = "pyjwt", extra = ["crypto"] },
      +]
      +sdist = { url = "https://files.pythonhosted.org/packages/e1/7f/dc1995f72a8d23e723b168db20bac67b819ef2fa734bc23f63bc8086c41b/microsoft_teams_api-2.0.13.4.tar.gz", hash = "sha256:d16f88ae90f65bcce83ede9ecc57773f7b1a19cbecde63be624b586b59e34fc9", size = 51779, upload-time = "2026-06-08T19:24:02.661Z" }
      +wheels = [
      +    { url = "https://files.pythonhosted.org/packages/27/15/e1a1369a22c265b52da3ac4b3ee67b5c02911300db045894868bd7be932f/microsoft_teams_api-2.0.13.4-py3-none-any.whl", hash = "sha256:be52ef7765ea5851e0982de1ff6b1192869c85fc74e890ae20029bd99064b532", size = 149825, upload-time = "2026-06-08T19:24:13.202Z" },
      +]
      +
      +[[package]]
      +name = "microsoft-teams-apps"
      +version = "2.0.13.4"
      +source = { registry = "https://pypi.org/simple" }
      +dependencies = [
      +    { name = "cryptography" },
      +    { name = "dependency-injector" },
      +    { name = "fastapi" },
      +    { name = "microsoft-teams-api" },
      +    { name = "microsoft-teams-common" },
      +    { name = "msal" },
      +    { name = "pydantic-settings" },
      +    { name = "pyjwt", extra = ["crypto"] },
      +    { name = "python-dotenv" },
      +    { name = "uvicorn" },
      +]
      +sdist = { url = "https://files.pythonhosted.org/packages/61/0a/733f05f8decee2da6e53ee38757e742520ae56363bc2d006b309cdbf9cfe/microsoft_teams_apps-2.0.13.4.tar.gz", hash = "sha256:d0b12e5e82024cffd3739b329b098b98a08803753eb5484bf96dbb6ce1237e04", size = 91366, upload-time = "2026-06-08T19:24:04.591Z" }
      +wheels = [
      +    { url = "https://files.pythonhosted.org/packages/3a/d4/3c4205258642035d160c09f598a302260776dcb6d5bdf659eea7c6066d5e/microsoft_teams_apps-2.0.13.4-py3-none-any.whl", hash = "sha256:db16f714ec658b592929c6386a29792e90bb73840732f8ae65a198cda1fea96c", size = 71406, upload-time = "2026-06-08T19:24:15.034Z" },
      +]
      +
      +[[package]]
      +name = "microsoft-teams-cards"
      +version = "2.0.13.4"
      +source = { registry = "https://pypi.org/simple" }
      +sdist = { url = "https://files.pythonhosted.org/packages/ef/7f/cce9633f635d9e1b2318ce2146a804a14a46c9e34e855c3784beb8ab39b3/microsoft_teams_cards-2.0.13.4.tar.gz", hash = "sha256:de54956a2afbbcf187f2531459967515b4f4743fa784bd0f454eaff1ac675c90", size = 28108, upload-time = "2026-06-08T19:24:07.841Z" }
      +wheels = [
      +    { url = "https://files.pythonhosted.org/packages/20/09/95cad44d4417e33df11a15c82ca1bde442c1f1f77396f936f18896f116c1/microsoft_teams_cards-2.0.13.4-py3-none-any.whl", hash = "sha256:b8b887466c8144675ff5704064daf05ec3ebdf4d322658ab9a25bfc1373d7909", size = 29617, upload-time = "2026-06-08T19:24:17.373Z" },
      +]
      +
      +[[package]]
      +name = "microsoft-teams-common"
      +version = "2.0.13.4"
      +source = { registry = "https://pypi.org/simple" }
      +dependencies = [
      +    { name = "httpx" },
      +]
      +sdist = { url = "https://files.pythonhosted.org/packages/6c/f1/a32821cfdde6c0d33a1e4022492a2211af670a81ec1fab727c49cddd4f7a/microsoft_teams_common-2.0.13.4.tar.gz", hash = "sha256:ed3175316f77f083a500da0a84ddf53ac31c6de008a252f0cfd86bdb70120bf3", size = 11122, upload-time = "2026-06-08T19:24:09.694Z" }
      +wheels = [
      +    { url = "https://files.pythonhosted.org/packages/cb/04/859b3d7fadd1d61ab581f79afb6125c16c60cecf2a2e6bbb2ebbcfd34f80/microsoft_teams_common-2.0.13.4-py3-none-any.whl", hash = "sha256:19524ec75587d797d07c5a78e9b72921b6d58f33d39512ca2d33468160fd0d82", size = 16588, upload-time = "2026-06-08T19:24:18.325Z" },
      +]
      +
       [[package]]
       name = "mistralai"
       version = "2.4.8"
    • website/docs/user-guide/messaging/teams.md
      @@ -24,6 +24,15 @@ Teams delivers @mentions as regular messages with `<at>BotName</at>` tags, which
       
       ---
       
      +For source or local installs, include the Teams extra so the bundled adapter can
      +import the Microsoft Teams SDK:
      +
      +```bash
      +uv sync --extra teams
      +# or, for editable installs:
      +uv pip install -e ".[teams]"
      +```
      +
       ## Step 1: Install the Teams CLI
       
       The `@microsoft/teams.cli` automates bot registration — no Azure portal needed.

3 PRs closed without merging

From the close comments: done elsewhere 1 · merged via another change 1 · other 1

  • #22229 fix: document local Microsoft Teams gateway install · done elsewhere → 5f6be7f
  • #26094 fix(teams): add Python version check and clear error message for Teams plugin · other
  • #43945 fix(teams): package Microsoft Teams SDK as an installable extra · merged via another change → 5f6be7f, #46764
Closed issues · 2
  • Closed#22015[Bug]: microsoft-teams-apps Python package only available in Nous Docker image
  • Closed#26083Microsoft Teams platform plugin fails to load on bundled Python 3.11 — microsoft-teams-apps requires Python ≥ 3.12
How this cluster was grouped
  • Link evidence (partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text.
  • Members outside that structural core may belong to a different underlying problem.
  • Pairwise link density 0.29: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
docs
Merged PRs
#46764
Closed issues
2
Attempts
3 PRs closed without merging
Fix link checked
15 Jun 2026

For your agent

The same facts, typed.