Skip to content

Updated quoted replies & new quotes features#321

Merged
corinagum merged 23 commits into
mainfrom
cg/quoted-replies
May 7, 2026
Merged

Updated quoted replies & new quotes features#321
corinagum merged 23 commits into
mainfrom
cg/quoted-replies

Conversation

@corinagum

@corinagum corinagum commented Mar 23, 2026

Copy link
Copy Markdown
Contributor
image
  • Add QuotedReplyEntity Pydantic model with nested QuotedReplyData (message_id required, sender_id/sender_name/preview/time/is_reply_deleted/validated_message_reference optional); register in Entity union
  • Add get_quoted_messages() on MessageActivity to read inbound quoted reply entities
  • Add add_quoted_reply(message_id, response?) builder on MessageActivityInput
  • Update reply() to stamp QuotedReplyEntity + <quoted messageId="..."/> placeholder instead of blockquote HTML; remove reply_to_id assignment
  • Add quote_reply() on ActivityContext
  • Mark all quoted reply types and methods as @experimental
  • Add quoted-replies example exercising all APIs

@corinagum
corinagum marked this pull request as ready for review March 24, 2026 18:19
Copilot AI review requested due to automatic review settings March 24, 2026 18:19

Copilot AI 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.

Pull request overview

This PR updates how “quoted replies” are represented and built in the Microsoft Teams SDK for Python by moving from reply_to_id/blockquote HTML to a dedicated quotedReply entity plus a <quoted messageId="..."/> placeholder, and exposes new helper APIs for creating and reading quoted replies.

Changes:

  • Add QuotedReplyData / QuotedReplyEntity models and register QuotedReplyEntity in the entity union.
  • Update outbound reply building (ActivityContext.reply() / quote_reply(), MessageActivityInput.add_quoted_reply()) and inbound parsing (MessageActivity.get_quoted_messages()).
  • Add unit tests and a new examples/quoted-replies sample app; remove with_reply_to_id().

Reviewed changes

Copilot reviewed 14 out of 16 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
uv.lock Adds the new quoted-replies example as a workspace member/package entry.
packages/apps/tests/test_quoted_reply.py New tests validating quoted reply stamping/placeholder behavior.
packages/apps/tests/test_activity_context.py Updates reply tests to assert quotedReply entity + placeholder; removes one targeted-send inference test.
packages/apps/src/microsoft_teams/apps/routing/activity_context.py Implements quotedReply stamping in reply() and adds quote_reply().
packages/api/tests/unit/test_quoted_reply_entity.py Tests serialization/deserialization for the new quoted reply models.
packages/api/tests/unit/test_quoted_replies_property.py Tests inbound filtering (get_quoted_messages) and outbound builder (add_quoted_reply).
packages/api/tests/unit/test_activity.py Removes usage/assertion for the deleted with_reply_to_id() builder.
packages/api/src/microsoft_teams/api/models/entity/quoted_reply_entity.py Introduces QuotedReplyData and QuotedReplyEntity models (experimental).
packages/api/src/microsoft_teams/api/models/entity/entity.py Registers QuotedReplyEntity in the Entity union.
packages/api/src/microsoft_teams/api/models/entity/init.py Exports QuotedReplyData and QuotedReplyEntity.
packages/api/src/microsoft_teams/api/models/activity.py Removes with_reply_to_id() builder.
packages/api/src/microsoft_teams/api/activities/message/message.py Adds get_quoted_messages() and add_quoted_reply() on message activities.
examples/quoted-replies/src/main.py New example bot demonstrating all quoted-reply APIs.
examples/quoted-replies/pyproject.toml Adds project metadata/deps for the new example.
examples/quoted-replies/README.md Adds run instructions and command list for the example.
.coverage Adds a coverage database artifact to the repo (should not be committed).

Comment thread packages/apps/src/microsoft_teams/apps/routing/activity_context.py Outdated
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 packages/apps/src/microsoft_teams/apps/routing/activity_context.py Outdated
Comment thread packages/api/src/microsoft_teams/api/activities/message/message.py Outdated
Comment thread examples/quoted-replies/src/main.py Outdated
Comment thread packages/apps/tests/test_quoted_reply.py
Comment thread packages/apps/src/microsoft_teams/apps/routing/activity_context.py Outdated
Comment thread packages/api/src/microsoft_teams/api/activities/message/message.py
Comment thread packages/apps/tests/test_activity_context.py
Comment thread examples/quoting/README.md
@corinagum corinagum changed the title Updated quoted replies Updated quoted replies & new quotes features Mar 25, 2026
Comment thread examples/quoting/README.md
Comment thread examples/quoted-replies/src/main.py Outdated
Comment thread examples/quoting/README.md
@corinagum

Copy link
Copy Markdown
Contributor Author

Re: Copilot review comments

  • Missing @experimental decorators: Fixed — added to quote(), get_quoted_messages(), prepend_quote(), add_quote().
  • messageId escaping: messageId is an APX-controlled IC3 ID, not user input. No escaping needed.
  • Non-message activity guard on reply(): Handled in quote() — non-message activities bypass entity stamping.
  • .strip() mutating caller text: Text is only stripped for the empty-check decision in prepend_quote(), not in reply() or quote().
  • test_activity_context removed test: Targeted-send inference is covered elsewhere.
  • "preview" wording: Updated to "coming soon."

Comment thread packages/api/src/microsoft_teams/api/activities/message/message.py
@corinagum
corinagum force-pushed the cg/quoted-replies branch from 4236a21 to d0e3a6f Compare April 7, 2026 19:16
corinagum added a commit that referenced this pull request Apr 13, 2026
- Remove `with_reply_to_id()` method

`reply_to_id` is a field on the activity that is used by the service,
but any changes to it on the bot side are completely ignored. After
thorough testing to confirm, this PR removes the misleading method
`with_reply_to_id`; setting replyToId on outgoing activities is a no-op.

Originally part of #321 but separated out due to timing concerns for GA
@corinagum
corinagum force-pushed the cg/quoted-replies branch 2 times, most recently from 282f981 to 684dc26 Compare April 27, 2026 22:26
Comment thread examples/quoting/src/main.py
Comment thread packages/apps/tests/test_activity_context.py Outdated
@corinagum
corinagum force-pushed the cg/quoted-replies branch from 2a3c7c4 to f70a187 Compare May 7, 2026 17:53
@corinagum
corinagum merged commit 681ddeb into main May 7, 2026
7 checks passed
@corinagum
corinagum deleted the cg/quoted-replies branch May 7, 2026 17:55
corinagum added a commit that referenced this pull request May 14, 2026
## Summary

Brings `main` into `release` for the 2.0.11 release, with quoted-replies
(PR #321) excluded. Also bumps `version.json` from `2.0.0` to `2.0.11`
to align with the teams.ts release cadence.

Single squashed commit.

> **Branch name note**: the branch is `cg/prep-release-2.0.1` (left over
from an earlier draft when alignment hadn't been decided yet). The
actual published version per `version.json` is **2.0.11**.

## What's in this release

- All commits merged to main since 2.0.0 (the previous release),
notably:
  - **Reactions GA** (PR #427) — `@experimental` removed; sample fixed
  - Prompt Preview Support (PR #397)
  - Various dependency bumps and bug fixes

## What's NOT in this release

**Quoted-replies feature (PR #321) is excluded:**
- `prepend_quote()`, `add_quote()` builder methods — absent
- `ctx.quote()` and quote-aware `ctx.reply()` behavior — reverted to
legacy `reply_to_id` + blockquote
- `examples/quoting` — removed
- QR-related tests — removed

**Kept intentionally:**
- `QuotedReplyEntity` and `QuotedReplyData` types stay in the `Entity`
union so inbound activities carrying `quotedReply` entities still parse
- `add_targeted_message_info` runtime strip-QR logic — preserves
prompt-preview cleanup

## Version

`version.json`: `2.0.0` → `2.0.11`

This one-time jump aligns teams.py with teams.ts. Going forward, both
progress on a shared 2.0.x patch cadence.

## Test plan

- [x] `uv run ruff check` — all checks passed
- [x] `uv run pyright` — 0 errors, 0 warnings
- [x] `uv run pytest` — 571/571 tests
- [x] `uv build --all-packages` — wheels produced; consumer install
verified (fresh venv, `pip install --no-index --find-links` succeeds,
`QuotedReplyEntity` importable, `prepend_quote`/`add_quote` absent,
`add_targeted_message_info` present)
- [ ] ADO Public publish pipeline (post-merge)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
corinagum added a commit that referenced this pull request May 27, 2026
## Summary

Brings `origin/main` into `release` for the **2.0.12** release. **No
carve-outs this time** — Quoted Replies (PR #321) is included.

`version.json`: `2.0.11` → `2.0.12`.

Aligns with teams.ts/teams.net cadence.

## What's in this release (delta from 2.0.11)

**Features**
- Quoted Replies & new quotes features (#321) — previously held back
- SuggestedActionSubmitActivity for `suggestedAction/submit` invoke
(#434)
- Default targeted replies for targeted inbound messages (#439)
- Reactions API marked GA (#427) — already shipped in 2.0.11 actually,
ignore if duplicate
- Prompt Preview support (#397)
- Sample: opt targeted-messages into slash commands (#430)
- Sample: a2a-in-teams (#401)
- Sample: proactive message update (#405)
- Allow custom HTTP client via `AppOptions` (#416)

**Security & fixes**
- Lock JsonWebToken trust-boundary contract (#432)
- Bump starlette 1.0.0 -> 1.1.0 for PYSEC-2026-161 / BadHost (#441)
- warn when bot starts without credentials (#435)
- fix(apps): support AAD v1 issuers in Entra token validation (#422)
- fix(apps): log inbound activities at info, warn on missing
Authorization (#425)
- fix(http-stream): wait for in-flight flush before sending final close
(#419)
- Mark reactions API as GA and fix sample remove flow (#427)
- Revert serviceUrl allowlist (ADO 5310460) (#415)
- Route `app.get_app_graph` + `ctx.*_graph` to sovereign endpoints via
`cloud.graph_scope` (#402)

**Deprecations / package changes**
- Remove ai, openai, mcpplugin, a2a, and devtools packages (#413)
- Restore and deprecate devtools package (#410)
- Deprecate ai, openai, mcpplugin, a2a packages (#406)
- Add agent framework example, remove chatprompt/mcp client samples
(#386)

**Dependency bumps**
- urllib3 2.6.3 → 2.7.0 (#426)
- python-multipart 0.0.26 → 0.0.27 (#424)
- microsoft-kiota-http 1.9.7 → 1.9.9 (#423)
- idna 3.11 → 3.15 (#431)
- starlette 1.0.0 → 1.1.0 (#441, security)
- /examples/tab/Web: qs, postcss, uuid, follow-redirects bumps

## Quoted Replies inclusion notes

- Teams client rendering is in-sync with the wire format as of
2026-05-06.
- APX QR rollout completed: Public 2026-04-10, GCCH/DoD/Gallatin
2026-04-14.
- Builder methods (`prepend_quote()`, `add_quote()`), `ctx.quote()`, and
the quote-aware `ctx.reply()` behavior are all present in this release.
- `examples/quoting` is included.

## Conflict resolution

The 2.0.11 release branch had the QR-removed shape for four files; took
`main`'s (QR-included) version for all of them:
- `examples/targeted-messages/src/main.py`
- `packages/api/src/microsoft_teams/api/activities/message/message.py`
- `packages/apps/src/microsoft_teams/apps/routing/activity_context.py`
- `packages/apps/tests/test_activity_context.py`

`version.json` conflict resolved to `2.0.12`.

## Test plan

- [x] `uv sync` clean
- [x] `poe check` (ruff format + lint) — clean
- [x] `poe test` — 609 passed
- [x] `pyright` — 0 errors, 0 warnings
- [ ] Pipeline build + test stages green on `release` after merge
- [ ] Publish pipeline run with **Public** → ESRP approval → PyPI
- [ ] `pip install microsoft-teams-apps==2.0.12` smoke install

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Aamir Jawaid <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: Shanmathi Mayuram Krithivasan <[email protected]>
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