Handle stream cancellation and sanitize tool call parsing#22
Handle stream cancellation and sanitize tool call parsing#22christopherkarani wants to merge 2 commits intomainfrom
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@claude Review |
PR ReviewOverall this is a solid set of improvements — replacing crash-on-invalid-input with graceful sanitization, propagating cancellation correctly, and fixing the CRLF boundary edge case are all good defensive changes. A few issues worth addressing before merge: Issues1. Stale doc comment on
|
|
@claude review and fix all identified issues |
|
Claude finished @christopherkarani's task in 2m 13s —— View job Review Issues FixedAll three issues from the previous review have been addressed in commit
Changes Made1. Stale doc comment — Replaced the -/// The index must be in the range `0...100` (see ``maxToolCallIndex``).
+/// The index is clamped to `0...maxToolCallIndex` (see ``maxToolCallIndex``).
...
-/// - Precondition: Must be in range `0...maxToolCallIndex` (0...100).
+/// - Note: Values outside `0...maxToolCallIndex` are clamped rather than rejected.2. Duplicate Replaced the two separate // Before: two separate if-case checks around a guard
if case .cancelled = termination { task.cancel() }
guard let strongSelf = self else { return }
if case .cancelled = termination { Task { await strongSelf.provider.cancelGeneration() } }
strongSelf.withLock { strongSelf.generationTask = nil }
// After: single guard-case, cancellation effects grouped
guard case .cancelled = termination else {
self?.withLock { self?.generationTask = nil }
return
}
task.cancel()
guard let strongSelf = self else { return }
strongSelf.withLock { strongSelf.generationTask = nil }
Task { await strongSelf.provider.cancelGeneration() }3. Test race condition — Added consumer.cancel()
_ = await consumer.result
// Yield to the cooperative scheduler so the fire-and-forget
// cancelGeneration() Task has a chance to run before we assert.
await Task.yield()
let cancelCount = await provider.cancelCallCount
#expect(cancelCount >= 1)| Branch |
- Update PartialToolCall.index doc to reflect clamping rather than precondition - Deduplicate duplicate `if case .cancelled` checks in ChatSession.onTermination into a single guard-case, grouping both cancellation side-effects together - Add Task.yield() after awaiting consumer.result in streamCancellationPropagates test to give the fire-and-forget cancelGeneration() Task a chance to execute before asserting on cancelCallCount Co-authored-by: Christopher Karani <christopherkarani@users.noreply.github.com>
Summary
cancelGeneration()is invoked when the session is cancelledPartialToolCalldata and add tests for sanitization and stream cancellation behaviormaxToolCallIndexand track skipped accumulators while parsingTesting