Skip to content

fix: return stream ID when closing streamed activity - #593

Open
Alex Bitar (AlxBit) wants to merge 2 commits into
microsoft:mainfrom
AlxBit:alexbitar/fix-stream-set-activity-id
Open

fix: return stream ID when closing streamed activity#593
Alex Bitar (AlxBit) wants to merge 2 commits into
microsoft:mainfrom
AlxBit:alexbitar/fix-stream-set-activity-id

Conversation

@AlxBit

Copy link
Copy Markdown

Fixes #592

Summary

ctx.stream.close() now returns the original stream activity ID instead of
DO_NOT_USE_PLACEHOLDER_ID when Teams returns an empty response for the final
streaming request.

The stream already retains the ID returned by the initial streaming request.
This change uses that retained ID for the final SentActivity, including the
value emitted to on_close handlers and cached for repeated close() calls.

Tests

  • Added regression coverage for a final streaming response with no ID.

  • Verified that close() and the close event handler both receive the original
    stream ID.

  • Run:

    uv run --python python3 pytest -q packages/apps/tests/test_http_stream.py

Copilot AI lite review requested due to automatic review settings September 10, 2026 16:54
@AlxBit

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

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.

🟡 Changes recommended

The new assert self._id is not None is unsafe for library runtime behavior (can be stripped with -O and lead to invalid id updates), and should be replaced with an explicit guard.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR fixes HttpStream.close() to return the original streamed activity ID when the final streaming request gets an empty/placeholder response from Teams, aligning the SDK behavior with Teams’ streaming contract.

Changes:

  • Overwrites the final SentActivity.id with the stream’s retained _id before emitting the close event and caching the result.
  • Adds a regression test to ensure close() (and on_close handlers) receive the original stream ID when the final response has the placeholder ID.
  • Strengthens an existing close/flush synchronization test to assert the returned SentActivity.id is the retained activity id.
File summaries
File Description
packages/apps/src/microsoft_teams/apps/http_stream.py Ensures close() returns a stable stream activity ID even when the final API response is represented with a placeholder ID.
packages/apps/tests/test_http_stream.py Adds/updates tests to validate close() retains the initial stream ID and propagates it to close handlers.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/apps/src/microsoft_teams/apps/http_stream.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

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.

🟡 Changes recommended

The new close() logic currently overwrites the returned activity ID unconditionally when _id is set, which can clobber a real final-response ID and should be gated to placeholder-only responses.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment on lines +251 to +256
# Teams only returns the stream id on the first streaming request. Subsequent
# responses, including the final streamed message, are empty and the API client
# represents those with a placeholder id. The stream id captured from the first
# chunk is the stable id for the finalized activity.
if self._id is not None:
res = res.model_copy(update={"id": self._id})
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.

[Bug]: ctx.stream.close() returns placeholder activity ID

2 participants