Skip to content

Prompt Preview Support#397

Open
ShanmathiMayuramKrithivasan wants to merge 4 commits intomicrosoft:mainfrom
ShanmathiMayuramKrithivasan:shmayura/prompt-preview
Open

Prompt Preview Support#397
ShanmathiMayuramKrithivasan wants to merge 4 commits intomicrosoft:mainfrom
ShanmathiMayuramKrithivasan:shmayura/prompt-preview

Conversation

@ShanmathiMayuramKrithivasan
Copy link
Copy Markdown
Contributor

Prompt preview allows a bot to reference the original targeted message in its reply, so Teams can render a collapsible preview of the user's prompt.

When a bot replies to a targeted message (reactive scenarios), the SDK now passes the original message's messageId via a targetedMessageInfo entity in the activity's entities array.

For proactive replies, developers can attach the entity themselves with the messageId of the targeted message.

Copilot AI review requested due to automatic review settings April 21, 2026 12:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds “prompt preview” support so bots can reference an original targeted message by attaching a targetedMessageInfo entity (with the original message ID) to outgoing activities, enabling Teams to render a collapsible prompt preview.

Changes:

  • Introduces TargetedMessageInfoEntity to the API models and exports it via the entity model surface.
  • Auto-attaches TargetedMessageInfoEntity(message_id=<incoming.id>) in ActivityContext.send() when handling an inbound targeted message (unless already provided by the developer).
  • Adds unit tests and extends the targeted-messages example to demonstrate reactive and proactive usage.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/apps/src/microsoft_teams/apps/routing/activity_context.py Auto-adds targetedMessageInfo entity during send for targeted inbound activities.
packages/apps/tests/test_activity_context.py Adds tests validating auto-population, non-targeted behavior, and no-duplication.
packages/api/src/microsoft_teams/api/models/entity/targeted_message_info_entity.py Defines the new entity model with type and message_id.
packages/api/src/microsoft_teams/api/models/entity/entity.py Extends the Entity union to include TargetedMessageInfoEntity.
packages/api/src/microsoft_teams/api/models/entity/init.py Exports TargetedMessageInfoEntity from the entity package.
packages/api/tests/unit/test_targeted_message_info_entity.py Adds unit tests for default type, field behavior, and camelCase serialization.
examples/targeted-messages/src/main.py Adds example commands demonstrating prompt preview usage (reactive/proactive).

Comment thread packages/apps/src/microsoft_teams/apps/routing/activity_context.py
Comment thread packages/apps/src/microsoft_teams/apps/routing/activity_context.py Outdated
Comment thread examples/targeted-messages/src/main.py Outdated
@pytest.mark.asyncio
async def test_send_does_not_add_entity_for_non_message_activity(self) -> None:
"""Non-message activities (e.g. typing) should not get targetedMessageInfo attached."""
from microsoft_teams.api.activities.typing import TypingActivityInput
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.

nit: can we move all these nested imports to top level?

else:
activity = message

self._auto_add_targeted_message_info(activity)
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.

can we add a check here if its a targeted msg first, otherwise all activities will be routed

and attaches the entity automatically so the developer doesn't need to.
Skips if the developer already attached a targetedMessageInfo entity.
"""
incoming = self.activity
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.

nits:
rename method to add_targeted_message_info_entity

instead of incoming, rename to activity (and change method param to activity_params) or something similiar

rename already_has to targeted_msg_info_entities or something alike

@lilyydu
Copy link
Copy Markdown
Collaborator

lilyydu commented Apr 21, 2026

also curious, what does the UI look like for this?

Comment on lines +237 to +254
def _auto_add_targeted_message_info(self, activity: ActivityParams) -> None:
"""Auto-populate targetedMessageInfo entity when replying to a targeted message.

In the reactive flow, the SDK reads the incoming targeted message ID
and attaches the entity automatically so the developer doesn't need to.
Skips if the developer already attached a targetedMessageInfo entity.
"""
incoming = self.activity
if not (hasattr(incoming, "recipient") and hasattr(incoming.recipient, "is_targeted")):
return
if incoming.recipient.is_targeted is not True:
return
if not isinstance(activity, MessageActivityInput):
return

already_has = any(isinstance(e, TargetedMessageInfoEntity) for e in (activity.entities or []))
if not already_has:
activity.add_entity(TargetedMessageInfoEntity(message_id=incoming.id))
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.

Also scan activity.entities for any entity with type == "quotedReply" targeting incoming.id, and scan activity.text for a matching <quoted messageId="<tm-id>"/> placeholder. If either is found, strip both and log. Per §6.1 of the prompt preview design, PP owns the preview surface for targeted message flows and qtdMsgs must not be set. Using the string "quotedReply" avoids taking a dependency on the quoted replies PR, which has not landed on main.

from ..custom_base_model import CustomBaseModel


class TargetedMessageInfoEntity(CustomBaseModel):
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.

No preview marker on this class. For parity with Account.is_targeted (field-level .. warning:: Preview docstring at account.py:36-40) and the SDK's @experimental("ExperimentalTeamsTargeted") decorator at packages/common/src/microsoft_teams/common/experimental.py:23-76, one of these should be added since the surface depends on the still-preview targeted messages feature.

from ..custom_base_model import CustomBaseModel


class TargetedMessageInfoEntity(CustomBaseModel):
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.

A parallel add_targeted_message_info(message_id: str) on MessageActivity would match the other add_* helpers and the TS addTargetedMessageInfo already in this PR. Gives a single home for the §1 P0 "one PP per message" dedup plus the usage docstring.

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.

4 participants