[FEATURE BRANCH]-DNP Start Agent 365 support branch#464
Draft
heyitsaamir wants to merge 7 commits into
Draft
Conversation
Collaborator
Author
|
This change is part of the following stack: Change managed by git-spice. |
This was referenced Jun 11, 2026
Closed
Contributor
There was a problem hiding this comment.
Pull request overview
Introduces a short README notice indicating that “Agent 365 support” work is happening on this integration branch, clarifying branch intent within the Teams SDK for Python repository.
Changes:
- Add an “Agent 365 Support” section near the top of the README to describe the purpose of the integration branch.
Comment on lines
+8
to
+10
| ## Agent 365 Support | ||
|
|
||
| Agent 365 support is being developed on this integration branch. |
This was referenced Jun 13, 2026
7f2794d to
20d15b5
Compare
This was referenced Jun 18, 2026
2958451 to
0addde5
Compare
Adds Agent 365 agent user token support to TokenManager. Why: This lets apps request resource tokens for an agent identity acting through its agent user, including Teams bot API tokens. Interesting bits: - Added generic get_agent_user_token(scope=...) plus get_agent_bot_token() convenience. - Uses MSAL's user FIC support and a client assertion callback for T1 so we don't sit on stale assertions. - Added an agent365 example that reads values from env vars and avoids printing the full token. tiny safety win. Reviewer tips: Start with packages/apps/src/microsoft_teams/apps/token_manager.py, then examples/agent365/src/main.py. Testing: - uv run pytest packages/apps/tests/test_token_manager.py - uv run ruff check packages/apps/src/microsoft_teams/apps/token_manager.py examples/agent365/src/main.py stubs/msal/__init__.pyi - pre-commit hooks on commit: ruff, ruff format, pyright, license header
Adds inbound validation for Agent ID activities using Entra tokens. Why: Agent 365 inbound activities can arrive with *Entra access tokens* whose audience is the agent identity blueprint app ID. Classic Bot Framework validation looks at the wrong JWKS for those tokens, so the request is rejected before handlers run. Interesting bits: - TokenValidator now owns the inbound activity token branching. - We do one untrusted JWT parse up front to choose the validation path. This is only routing info (`iss` / `tid`), not authentication. The token is accepted only after the chosen validator does full signature, issuer, audience, and scope validation. - Entra issuers validate with tenant Entra JWKS and blueprint audience. - Classic Bot Framework tokens keep the existing service token validation path. - The per-tenant Entra validator cache is bounded so random tenant IDs can’t grow it forever. Testing: - uv run pytest packages/apps/tests/test_token_validator.py::TestInboundActivityTokenValidator::test_validate_token_uses_service_validator_for_bot_framework_tokens packages/apps/tests/test_token_validator.py::TestInboundActivityTokenValidator::test_get_entra_validator_caches_by_tenant packages/apps/tests/test_token_validator.py::TestInboundActivityTokenValidator::test_get_entra_validator_cache_is_bounded - uv run ruff check packages/apps/src/microsoft_teams/apps/auth/token_validator.py packages/apps/tests/test_token_validator.py
Adds agentic auth provider plumbing to the API layer. `ApiClient` is powered by `HttpClient` to make requests. Normally, `HttpClient` can take a token directly, but Agent ID calls need the SDK to choose between a regular bot token and an agentic identity token per request. So this PR does the following: 1. Introduces the `AgenticIdentity` model. 2. Introduces an `AuthProvider` concept at the `ApiClient` layer. If provided, auth can happen through `ApiClient` if HttpClient does not have a token revolver. 3. Installs an HTTP interceptor from `ApiClient`. The interceptor skips requests that already have `Authorization`, otherwise it uses the `AuthProvider`. 4. Uses `httpx` request extensions to mark per-request `AgenticIdentity` metadata. This is local-only metadata, not a header, so it does not leak to Teams endpoints. With this, we are basically stamping a request that requires agentic identity. 5. The interceptor reads that extension, picks the bot vs Agent ID scope, and passes the scope + identity to the `AuthProvider`. 6. Updates token-provider typing so custom token providers can receive `AgenticIdentity` when needed. 7. Sovereign cloud Agent ID scopes are TODO-marked until platform values are confirmed. No sneaky magic there.
f39b58f to
6198553
Compare
This PR adds `AgenticIdentity` as a new auth context across the Teams API surface. Why: Agent ID calls need a user-shaped Agent ID token instead of the normal bot token. The API methods now accept `agentic_identity` where needed, and the shared auth interceptor uses local request metadata to pick the right auth path. Interesting bits: - Adds optional `agentic_identity` to conversation create, activity operations, conversation members, reactions, teams, and meetings. - Adds optional `service_url` overrides across the service-url based APIs touched here. - Agentic identity is passed through `httpx` request extensions, not headers. So it stays inside the client pipeline and does not leak to Teams endpoints. - The auth interceptor reads that extension and asks the auth provider for the right token. Reviewer tips: Start with the API method signatures, then the changed call sites in `ConversationActivityClient`, `ConversationMemberClient`, `ReactionClient`, `TeamClient`, and `MeetingClient`. The auth plumbing itself lives one PR down in #485. Testing: - Focused API unit tests for conversation, reaction, bot, user, team, and meeting clients. - Full test suite passed locally. Live smoke tested with Agent ID token: - conversation activity create/update/reply/get_members - conversation members get_all/get/get_paged - reactions add/delete - teams get_by_id/get_conversations - conversations.create - meetings get_by_id/get_participant Known limitation: - targeted activity create/update reached the service but returned 500. Leaving that as not proven until platform behavior is confirmed.
Removes the separate `ActivitySender` class while preserving its send behavior. Why: ActivitySender had become a second send path. With AgenticIdentity support, the API client owns service URL resolution and request auth, so activity sends should route through the same API client path. Interesting bits: - `send_or_update_activity` keeps the old ActivitySender contract without keeping the class. - Preserves create vs update behavior when `activity.id` is set. - Preserves targeted create/update routing through `create_targeted` / `update_targeted`. - Preserves `activity.from_ = ref.bot` and `activity.conversation = ref.conversation` stamping. - Preserves targeted-in-personal-chat validation. - ActivityContext still creates `HttpStream` directly from its scoped API client. Reviewer tips: Start with `activity_send.py`, then check `ActivityContext.send`, `App.send`, and `FunctionContext.send`. Testing: - Focused app send/reply/function/quoted-reply tests covering the old ActivitySender behavior. - Ruff on touched app send files and tests.
Adds app-level reactive and proactive helpers on top of the
AgenticIdentity API surface.
Why:
The lower branches teach the API client how to send with
`agentic_identity`. This branch wires that into the developer-facing app
flows.
Reactive flow:
```python
@app.on_message
async def handle_message(ctx: ActivityContext[MessageActivity]):
await ctx.reply(TypingActivityInput())
if "react" in ctx.activity.text.lower():
await ctx.api.reactions.add(
conversation_id=ctx.activity.conversation.id,
activity_id=ctx.activity.id,
reaction_type="like",
)
await ctx.reply("Added a like reaction to your message.")
return
await ctx.send(f"You said '{ctx.activity.text}'")
```
Proactive app helper:
```python
agentic_identity = app.get_agentic_identity(agentic_app_id, agentic_user_id)
sent = await app.send(
conversation_id,
"Hello from app.send with an AgenticIdentity.",
agentic_identity=agentic_identity,
)
```
Interesting bits:
- Reactive `ctx.api` is scoped with the inbound Agent ID identity when
present.
- Reactive `ctx.send` / `ctx.reply` use the inbound service URL and
identity through the API layer.
- `ActivityProcessor` now receives the app's existing auth provider
instead of rebuilding one without credentials.
- Proactive `app.send(..., agentic_identity=...)` is a convenience over
the same API operation path.
Reviewer tips:
Start with `examples/agent365/src/main.py`, then `ActivityProcessor` and
`ActivityContext.send`.
Testing:
- Focused app helper, reactive context, and app-process auth-provider
tests.
- Ruff on touched app/example files.
Live smoke tested with Agent ID token:
- reactive message send/reply flow
- proactive conversation activity create/update/reply/get_members
- reactions add/delete using canary service URL
- conversation members get_all/get/get_paged
- teams get_by_id/get_conversations
- conversations.create
- meetings get_by_id/get_participant
Known limitation:
- targeted activity create/update reached the service but returned 500.
Leaving that as not proven until platform behavior is confirmed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Starts the Agent 365 support integration branch. Do not push.