Python: add agent-framework-hosting-activity-protocol channel#5641
Conversation
There was a problem hiding this comment.
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_teamshelper accepts astreamparameter but no test ever passesstream=True, and the_FakeAgentfixture always returns a plain coroutine rather than aResponseStream, meaning streaming cannot be exercised with the current test infrastructure. Therun_hookandstream_transform_hookextensibility 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]: |
There was a problem hiding this comment.
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.
6ace616 to
1a97b16
Compare
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>
1a97b16 to
e8616b7
Compare
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-teamspackage built on themicrosoft-teams-appsSDK for Teams-native affordances (Adaptive Cards, Citations, streaming viactx.stream).Description
Adds
agent-framework-hosting-activity-protocol(python/packages/hosting-activity-protocol/):ActivityProtocolChannel— mountsPOST /activity(configurable), validates Bot Framework JWT, decodes Activity Protocol payloads intoChannelRequest, replies as outbound activities.This is the rename target of the previously-named
hosting-teamspackage — the directory rename freeshosting-teamsfor the Teams-SDK-based channel in PR-5b.TeamsChannel→ActivityProtocolChannel,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
hosting-teamspackage was never released).