Add agentic send helpers#632
Conversation
|
This change is part of the following stack: Change managed by git-spice. |
94dbb33 to
089807c
Compare
ad1251d to
f54a6f6
Compare
089807c to
a8f0e2c
Compare
f54a6f6 to
1cf0b6f
Compare
a8f0e2c to
eb8d2e2
Compare
1cf0b6f to
e582bcb
Compare
eb8d2e2 to
c92e38c
Compare
cefad04 to
9088f52
Compare
c92e38c to
b57702e
Compare
9088f52 to
6925d74
Compare
There was a problem hiding this comment.
Pull request overview
This PR wires agentic identity and request-level overrides into the @microsoft/teams.apps send/reply pipeline by threading RequestOptions (serviceUrl + agenticIdentity) through App, ActivityContext, and ActivitySender, and adds a new examples/agent365 sample demonstrating reactive + proactive agentic sends.
Changes:
- Extend app-layer
send()/reply()helpers to acceptRequestOptions, and add anApp.getAgenticIdentity()convenience factory. - Refactor
ActivitySenderto reuse a pre-built Teams APIClientand passRequestOptionsinto conversation activity operations. - Add
examples/agent365workspace showing reactive echo and proactive agentic sends.
Reviewed changes
Copilot reviewed 16 out of 19 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/apps/src/types/plugin/sender.ts | Extends IActivitySender with optional agentic identity + RequestOptions support. |
| packages/apps/src/contexts/activity.ts | Simplifies ActivityContext.send() delegation to activitySender. |
| packages/apps/src/app.ts | Adds RequestOptions plumbing to send/reply and introduces getAgenticIdentity(). |
| packages/apps/src/app.spec.ts | Updates tests to pass valid ActivityLike payloads (explicit type). |
| packages/apps/src/app.process.ts | Creates per-turn ApiClient/ActivitySender with agentic identity from inbound recipient. |
| packages/apps/src/app.process.spec.ts | Adjusts serviceUrl capture tests to hook ActivitySender.send. |
| packages/apps/src/activity-sender.ts | Refactors sender to reuse Client and forward RequestOptions into API calls. |
| packages/apps/src/activity-sender.spec.ts | Reworks sender tests to mock the API client instead of raw HTTP. |
| package-lock.json | Adds workspace entries for the new @examples/agent365 package. |
| examples/agent365/turbo.json | Adds turbo task config for building the new example workspace. |
| examples/agent365/tsconfig.json | TypeScript configuration for the new example. |
| examples/agent365/src/proactive.ts | Proactive messaging sample using AgenticIdentity with both app.send and API client. |
| examples/agent365/src/main.ts | Reactive echo sample demonstrating automatic propagation of inbound agentic identity/serviceUrl. |
| examples/agent365/README.md | Documentation for running reactive and proactive samples. |
| examples/agent365/package.json | Declares the new example workspace and scripts. |
| examples/agent365/eslint.config.js | ESLint config for the new example workspace. |
| examples/agent365/appPackage/manifest.json | Teams app manifest for the example agent package. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
b57702e to
fbf0cbd
Compare
6925d74 to
b8e2b61
Compare
fbf0cbd to
c5dfbda
Compare
b8e2b61 to
80a73f2
Compare
76ad125 to
3cc0104
Compare
51ca77f to
e275cc8
Compare
e275cc8 to
93776bc
Compare
| * @param agenticUserId the agentic user's ID | ||
| * @param opts optional overrides (tenantId defaults to this app's configured tenant) | ||
| */ | ||
| getAgenticIdentity(agenticAppId: string, agenticUserId: string, opts?: { tenantId?: string }): AgenticIdentity { |
There was a problem hiding this comment.
getAgenticIdentity diverges from PY. get_agentic_identity raises if it can't resolve a tenant, and accepts agentic_app_blueprint_id . The TS version returns { tenantId: undefined } silently, and there's no way to set the blueprint id. Worth noting the TS extractor getAgenticIdentity(account) in account.ts does carry agenticAppBlueprintId , so the factory is varied even within TS. Should a tenant guard + a blueprintId option be added to match PY?
There was a problem hiding this comment.
Also: PY resolves tenant from credentials.tenantId vs TS options.tenantId , are those equivalent?)
There was a problem hiding this comment.
Good catch -
- Default agentic_app_blueprint_id to app client id in get_agentic_identity teams.py#494 - updated Py to default with self.id if blueprint id is not provided
- Updated this to accept blueprint id optionally and default to this.id if not provided.
|
|
||
| const client = this.client.clone(); | ||
| const apiClient = new ApiClient(serviceUrl, this.client.clone({ token: () => this.getBotToken() }), this.options.apiClientSettings); | ||
| const agenticIdentity = getAgenticIdentity(activity.recipient); |
There was a problem hiding this comment.
This collides with app.ts, will this cause confusion?
| /** | ||
| * The agentic identity used for outbound requests (if any) | ||
| */ | ||
| readonly agenticIdentity?: AgenticIdentity; |
There was a problem hiding this comment.
Is anything meant to read this? Looks like this is not set anywhere.
There was a problem hiding this comment.
You're right - no longer necessary (and in fact we should just remove this sender concept, it feels legacy)
3cc0104 to
4d38786
Compare
93776bc to
aa66b72
Compare
4d38786 to
6ddcadd
Compare
aa66b72 to
155f87e
Compare
6ddcadd to
711a6ac
Compare
155f87e to
499df33
Compare
711a6ac to
bff3ee5
Compare
cc09eae to
db6a642
Compare
bff3ee5 to
ef6df69
Compare
db6a642 to
2168311
Compare
ef6df69 to
64922a6
Compare
2168311 to
5188887
Compare
64922a6 to
b2a0d57
Compare
5188887 to
51a9bea
Compare
b2a0d57 to
56bb113
Compare
51a9bea to
4cfa97e
Compare
- Add RequestOptions (agenticIdentity, serviceUrl) to app.send() - Add isRequestOptions guard for reply() overload disambiguation - Refactor ActivitySender to accept pre-built API Client - Wire agentic identity from inbound recipient into per-turn sender - Forward serviceUrl from ConversationReference in all API calls - Add getAgenticIdentity() factory on App - Add agenticIdentity to IActivitySender interface - Simplify ActivityContext.send() to delegate to sender directly - Add examples/agent365 reactive + proactive sample Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4cfa97e to
cf3ab03
Compare
Wires agentic identity into the app-layer send/reply helpers (mirrors Python PR #480):
app.send(conversationId, activity, options?)acceptsRequestOptionsapp.reply()supports options viaisRequestOptionstype guardapp.getAgenticIdentity(appId, userId, opts?)factory methodActivitySenderrefactored to accept pre-builtClient; mergesagenticIdentityandserviceUrlinto all API callsActivitySenderin$processwith identity fromactivity.recipientIActivitySenderinterface extended withreadonly agenticIdentity?ActivityContext.send()simplified — delegates to sender directlyexamples/agent365/— reactive echo + proactive send sample