Skip to content

Python: add agent-framework-hosting-activity-protocol channel#5641

Open
eavanvalkenburg wants to merge 2 commits intomicrosoft:feature/python-hostingfrom
eavanvalkenburg:feat/hosting-channel-activity-protocol
Open

Python: add agent-framework-hosting-activity-protocol channel#5641
eavanvalkenburg wants to merge 2 commits intomicrosoft:feature/python-hostingfrom
eavanvalkenburg:feat/hosting-channel-activity-protocol

Conversation

@eavanvalkenburg
Copy link
Copy Markdown
Member

Motivation and Context

Implements the Activity Protocol channel described in SPEC-002 §7 (merged via #5549). This is the lower-level Bot Service / Activity Protocol surface — it covers any Activity-Protocol-speaking client (Teams, Direct Line, Web Chat, Slack via Bot Service, etc.).

A separate PR-5b adds a higher-level agent-framework-hosting-teams package built on the microsoft-teams-apps SDK for Teams-native affordances (Adaptive Cards, Citations, streaming via ctx.stream).

Description

Adds agent-framework-hosting-activity-protocol (python/packages/hosting-activity-protocol/):

  • ActivityProtocolChannel — mounts POST /activity (configurable), validates Bot Framework JWT, decodes Activity Protocol payloads into ChannelRequest, replies as outbound activities.
  • Token validation + identity derivation from the Activity sender.
  • Tests for channel wiring, JWT path, and request/response shaping.

This is the rename target of the previously-named hosting-teams package — the directory rename frees hosting-teams for the Teams-SDK-based channel in PR-5b. TeamsChannelActivityProtocolChannel, name="teams""activity", default mount /teams/activity.

Stack

PR-5a of 9. Depends on #PR-2 (feat/hosting-core). Independent of PR-5b — the two Teams-related packages are intentionally separate (different audiences, see PR-5b for the comparison table).

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? No — new package (the previous hosting-teams package was never released).

@moonbox3 moonbox3 added documentation Improvements or additions to documentation python labels May 5, 2026
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review

Reviewers: 2 | Confidence: 77%

✓ Test Coverage

The activity-protocol channel's most complex code path — _stream_to_conversation (~60 lines of concurrent async task logic with rate-limited edits) — has zero test coverage. The _make_teams helper accepts a stream parameter but no test ever passes stream=True, and the _FakeAgent fixture always returns a plain coroutine rather than a ResponseStream, meaning streaming cannot be exercised with the current test infrastructure. The run_hook and stream_transform_hook extensibility points are also untested. Non-streaming paths have reasonable coverage with meaningful assertions.

✓ Design Approach

No actionable issues found in this dimension.


Automated review by eavanvalkenburg's agents

return _coro()


def _make_teams(stream: bool = False) -> tuple[ActivityProtocolChannel, _FakeAgent]:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stream parameter is accepted but never exercised with True in any test. The streaming path (_stream_to_conversation) involves concurrent asyncio.Task coordination, rate-limited edits, and timing thresholds — it's the most complex code in the channel and has zero coverage. Enabling streaming tests also requires updating _FakeAgent.run (line 74) to return a ResponseStream-like async iterable when stream=True.

@eavanvalkenburg eavanvalkenburg force-pushed the feat/hosting-channel-activity-protocol branch from 6ace616 to 1a97b16 Compare May 5, 2026 09:00
eavanvalkenburg and others added 2 commits May 5, 2026 11:08
New ``agent-framework-hosting`` package implementing ADR 0026 / SPEC-002:
the channel-neutral host that lets a single ``Agent`` (or ``Workflow``)
fan out across multiple wire protocols ("channels") behind one Starlette
ASGI app.

Surface (re-exported from ``agent_framework_hosting``):

- ``AgentFrameworkHost`` — wraps a hostable target, mounts channels onto
  an ASGI app, owns per-isolation-key ``AgentSession`` reuse, threads
  request context (``response_id`` / ``previous_response_id``) into
  context providers via an ``ExitStack`` of ``bind_request_context``
  calls, and exposes an opt-in Hypercorn ``serve()`` helper (extra
  ``[serve]``).
- ``Channel`` protocol + ``ChannelContribution`` — the surface a channel
  package implements (routes, lifespans, identity hooks, …).
- ``ChannelRequest`` / ``ChannelSession`` / ``ChannelIdentity`` /
  ``ChannelPush`` / ``ChannelCommand[Context]`` / ``ChannelRunHook`` /
  ``ChannelStreamTransformHook`` / ``DeliveryReport`` /
  ``HostedRunResult`` / ``ResponseTarget`` / ``ResponseTargetKind`` /
  ``apply_run_hook`` — channel-side dataclasses + helpers.
- ``IsolationKeys`` + ``ISOLATION_HEADER_USER`` / ``..._CHAT`` +
  ``get/set/reset_current_isolation_keys`` — the host's ASGI middleware
  reads the ``x-agent-{user,chat}-isolation-key`` headers off each
  inbound request and exposes them to the agent stack via a
  ``ContextVar`` so storage-side providers (e.g.
  ``FoundryHostedAgentHistoryProvider``) can apply per-tenant
  partitioning without channels having to forward anything.

Includes 45 unit tests covering the host, channel contributions,
isolation contextvar, and shared types. Registers the package in
``python/pyproject.toml`` ``[tool.uv.sources]`` and adds the matching
pyright ``executionEnvironments`` entry for tests.

Hypercorn is an optional dependency (``[serve]`` extra); the soft import
in ``serve()`` is annotated for pyright since it isn't on the default
install.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…vityProtocolChannel

The existing Bot-Framework-via-Azure-Bot-Service channel was previously
shipped under the name ``hosting-teams`` / ``TeamsChannel``. That name
is misleading for what the channel actually does -- it speaks the Bot
Framework Activity Protocol against Azure Bot Service, which fans out
across MS Teams, Slack, Webex, Telegram-via-Bot-Service, etc., and does
not provide any Teams-specific affordances.

This PR renames the package atomically and frees the ``hosting-teams``
name for a future Teams-native channel built on
``microsoft-teams-apps`` (PR-5b, spec req microsoft#28).

Renames (all in one commit):

- Package: ``agent-framework-hosting-teams`` ->
  ``agent-framework-hosting-activity-protocol``
- Module: ``agent_framework_hosting_teams`` ->
  ``agent_framework_hosting_activity_protocol``
- Channel class: ``TeamsChannel`` -> ``ActivityProtocolChannel``
- Helper: ``teams_isolation_key`` -> ``activity_protocol_isolation_key``
  (isolation key prefix ``teams:`` -> ``activity:``)
- Channel name: ``"teams"`` -> ``"activity"``; default mount path
  ``/teams`` -> ``/activity``
- Internal helper: ``_parse_teams_activity`` -> ``_parse_activity``
- Worker task name + a couple of error strings updated for consistency

Updates README.md and the module docstring to call out:

- this is the channel-neutral Activity Protocol channel,
- it surfaces what every Bot-Service-connected channel has in common
  (text in / text out),
- a forthcoming ``agent-framework-hosting-teams`` package will layer
  Teams-specific affordances (adaptive cards, message extensions,
  dialogs, SSO, ...) on the same Bot Service transport.

Workspace: registers ``agent-framework-hosting-activity-protocol`` in
``python/pyproject.toml`` and adds the matching pyright
``executionEnvironments`` entry.

Behavior is unchanged. Pyright + mypy clean, 11 tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@eavanvalkenburg eavanvalkenburg force-pushed the feat/hosting-channel-activity-protocol branch from 1a97b16 to e8616b7 Compare May 5, 2026 09:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants