Implement stream cancelation#337
Conversation
|
@microsoft-github-policy-service agree company="Klippa App B.V." |
lilyydu
left a comment
There was a problem hiding this comment.
Thank you for filing this!
|
looks like the build is failing, could you also run |
Yeah I wanted to setup pre-commit, but I couldn't get it to install, had some issues with the |
lilyydu
left a comment
There was a problem hiding this comment.
LGTM! @heyitsaamir do you mind taking a look?
|
I like the approach here. Soemthings I think we should do:
I'm leaning toward throwing on emit. Thoughts? |
What do you mean? It already is.
I'd like the second approach more. Perhaps something using Edit: |
Oops you're right. Ignore 1st. @jerbob92 why do you prefer second? I think your |
Personally I think an event based approach is cleaner, but maybe that would only really make sense if the cancelation may happen without the user doing emits, for that to work the Streamer would either need an endpoint to check for cancelation every x duration or it needs to be an actual HTTP stream. (or maybe I just didn't really get your comment and you're talking about something that's not directly related to the MR) |
+1 with Aamir — throwing on emit seems like the right approach. I think event-based only adds value if cancellation happens between emits |
|
Yeah event emitter is less useful here because it would catch the errors asynchronously (out of band), so coordinating it back with where you're emitting in application code will be difficult. |
…eam-cancelation-332
- Add StreamCancelledError (extends asyncio.CancelledError) for stream-specific cancellation signaling - emit() raises StreamCancelledError when cancelled, breaking the caller's AI generation loop instead of silently dropping chunks - close() returns immediately when stream is cancelled instead of waiting 30s for queue to drain - _flush() signals _state_changed in finally block so close() wakes up on errors - app_process catches StreamCancelledError and returns 200 so Teams does not retry the request - Remove unnecessary bare except/re-raise in _send() - Add LOG_LEVEL env support to ai-test example Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
Updated the PR with some changes:
Tested by:
Then:
|
## Summary - Detect when Teams stops a stream (user presses Stop or 2-min timeout) via 403 response and cancel immediately instead of silently retrying until timeout - Add `StreamCancelledError` class and `canceled` property to `IStreamer` interface - `HttpStream.send()` catches 403, sets `canceled` flag, and throws `StreamCancelledError` - `emit()` and `close()` bail out immediately when canceled - `retry()` skips retries for `StreamCancelledError` (no point retrying a permanent cancellation) - `flush()` suppresses error log for expected cancellation - `app.process` catches `StreamCancelledError` and returns 200 so Teams doesn't retry Ports [teams.py#337](microsoft/teams.py#337) to TypeScript. To test, I ran a streaming bot, press Stop mid-stream — verify no held connection, verify future messages weren't impacted, verified that stream didn't restart b/c of a 500. --------- Co-authored-by: Claude <[email protected]>
Fixes #332