Skip to content

Add app-level agentic send helpers#480

Merged
heyitsaamir merged 7 commits into
feature_agent365_supportfrom
add_app_agentic_send_helpers
Jun 24, 2026
Merged

Add app-level agentic send helpers#480
heyitsaamir merged 7 commits into
feature_agent365_supportfrom
add_app_agentic_send_helpers

Conversation

@heyitsaamir

@heyitsaamir heyitsaamir commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

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:

@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:

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.

@heyitsaamir

heyitsaamir commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator Author

This change is part of the following stack:

Change managed by git-spice.

@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from fd83c83 to d1219ac Compare June 17, 2026 22:26
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 60f8575 to c6f3c86 Compare June 17, 2026 22:26
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from d1219ac to 123df7d Compare June 17, 2026 22:57
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from c6f3c86 to 19d2ace Compare June 17, 2026 22:57
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from 123df7d to fe6b8c5 Compare June 17, 2026 23:01
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 19d2ace to 96d043f Compare June 17, 2026 23:02
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from fe6b8c5 to 1b0b92d Compare June 18, 2026 00:01
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 96d043f to 615be85 Compare June 18, 2026 00:01
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from 1b0b92d to d9fb845 Compare June 18, 2026 18:28
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from f2998f1 to 8b70f4c Compare June 18, 2026 18:28
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from d9fb845 to 28b42b4 Compare June 18, 2026 20:41
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 8b70f4c to 08aff1c Compare June 18, 2026 20:41
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from 28b42b4 to 9a47d7b Compare June 18, 2026 23:39
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 08aff1c to 0aad1e2 Compare June 18, 2026 23:39
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from 9a47d7b to bd67034 Compare June 18, 2026 23:52
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 0aad1e2 to 81ee3d1 Compare June 18, 2026 23:52
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from bd67034 to 703a53d Compare June 19, 2026 00:22
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 81ee3d1 to 787b1c2 Compare June 19, 2026 00:22
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from 703a53d to dd092e4 Compare June 19, 2026 00:52
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 787b1c2 to 3832165 Compare June 19, 2026 00:52
self.api = ApiClient(
service_url,
self.http_client.clone(ClientOptions(token=self._get_bot_token)),
self.http_client,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This removes the bot token from the HTTP client.  _get_agentic_token  returns None when there's no agentic identity, and nothing else provides a default token, so all non-agentic outbound API calls will be unauthenticated. Was this intentional?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The auth provider should call get_app_token if agentic_identity is none:

return await self._token_manager.get_app_token(scope, tenant_id=tenant_id, caller_name="token")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The problem is auth_provider.token is never called for non-agentic requests.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Ah shit. You're right. That's bad. Nice catch!

self.http_client,
self.api_client_settings,
auth_provider=self.auth_provider,
agentic_identity=activity.recipient.agentic_identity,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

recipient is Optional[Account] & this will crash with AttributeError for any inbound activity without a recipient. Since _build_context runs for every activity, this could break the full flow.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Hmm recipient is actually Account on ActivityBase so it should be okay.

self.default_connection_name = default_connection_name
self.http_client = http_client
self.token_manager = token_manager
self.auth_provider = AppAuthProvider(token_manager)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This omits credentials, as opposed to App._init_. tenant_id fallback in AppAuthProvider.token() won't work in reactive flows.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

token_manager, uses the tenant id from the credentials if not passed in. is that what you meant?

But maybe herer we can just pass app authprovider instead of reconstructing it with tokemanager.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Makes sense to me

@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from dd092e4 to f305e45 Compare June 19, 2026 20:21
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 3832165 to 1996701 Compare June 19, 2026 20:22
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from 6088587 to 54dc844 Compare June 22, 2026 22:39
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from a665861 to 37ab4be Compare June 22, 2026 22:39
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from 54dc844 to a9ef9ab Compare June 22, 2026 23:14
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 37ab4be to 87f196e Compare June 22, 2026 23:14
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from a9ef9ab to cbadaff Compare June 23, 2026 04:07
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 87f196e to e1308b3 Compare June 23, 2026 04:07
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from cbadaff to f7b9a58 Compare June 23, 2026 04:11
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from e1308b3 to f207765 Compare June 23, 2026 04:11

@lilyydu lilyydu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice!

@corinagum corinagum left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, thanks for addressing the feedback for all the Agentic Identity PRs

@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from f7b9a58 to e874de7 Compare June 24, 2026 00:35
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from f207765 to 867eea1 Compare June 24, 2026 00:35
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from e874de7 to e4f974b Compare June 24, 2026 00:43
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 867eea1 to 978dfa9 Compare June 24, 2026 00:43
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from e4f974b to fd063c1 Compare June 24, 2026 05:31
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 978dfa9 to ad51a6e Compare June 24, 2026 05:31
@heyitsaamir heyitsaamir force-pushed the remove_activity_sender branch from fd063c1 to 408095b Compare June 24, 2026 05:55
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch 2 times, most recently from 1797e5b to 6851e6b Compare June 24, 2026 06:05
Base automatically changed from remove_activity_sender to feature_agent365_support June 24, 2026 17:02
@heyitsaamir heyitsaamir force-pushed the add_app_agentic_send_helpers branch from 6851e6b to 49b98f7 Compare June 24, 2026 17:06
@heyitsaamir heyitsaamir merged commit b65a997 into feature_agent365_support Jun 24, 2026
9 checks passed
@heyitsaamir heyitsaamir deleted the add_app_agentic_send_helpers branch June 24, 2026 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants