TanStack
OSS
ai
Sign in / Sign up
Open main menu
ai
GitHub
Overview
Runs
Analytics
Loading workspace stats
Loading workspace insights...
Statistics interval
7 days
30 days
Latest CI Pipeline Executions
Status
Fix filter
Filter
Fuzzy
Filter range
Sort by
Sort by
Start time
Sort ascending
Sort descending
Succeeded
add-claude-sonnet-4-6
e41edc17 feat(ai, ai-client): add SessionAdapter for durable session support. (#286) * feat(ai): align start event types with AG-UI Widen TextMessageStartEvent.role to accept all message roles and add optional parentMessageId to ToolCallStartEvent. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(ai): add MessageStreamState type for per-message stream tracking Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(ai): refactor StreamProcessor to per-message state Replace single-message instance variables with a Map<string, MessageStreamState> keyed by messageId. Add explicit handlers for TEXT_MESSAGE_START, TEXT_MESSAGE_END, and STATE_SNAPSHOT events. Route tool calls via toolCallToMessage mapping. Maintains backward compat: startAssistantMessage() sets pendingManualMessageId which TEXT_MESSAGE_START associates with. ensureAssistantMessage() auto-creates state for streams without TEXT_MESSAGE_START. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(ai): replace STATE_SNAPSHOT with MESSAGES_SNAPSHOT event Add MessagesSnapshotEvent as a first-class AG-UI event type for conversation hydration. Replace the previous STATE_SNAPSHOT handler (which extracted messages from arbitrary state) with a dedicated MESSAGES_SNAPSHOT handler that accepts a typed messages array. - Add MessagesSnapshotEvent type to AGUIEventType and AGUIEvent unions - Add MESSAGES_SNAPSHOT case in StreamProcessor.processChunk() - Remove STATE_SNAPSHOT handler (falls through to default no-op) - Fix onStreamEnd to fire per-message (not only when no active messages remain) - Fix getActiveAssistantMessageId to return on first reverse match - Fix ensureAssistantMessage to emit onStreamStart and onMessagesChange - Add proposal docs for resumeable session support Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(ai-client): add SessionAdapter interface and createDefaultSession Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(ai-client): refactor ChatClient to use SessionAdapter subscription model Replace direct ConnectionAdapter usage in ChatClient with a SessionAdapter-based subscription loop. When only a ConnectionAdapter is provided, it is wrapped in a DefaultSessionAdapter internally. This enables persistent session support while preserving existing timing semantics and backwards compatibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ai-preact): thread option through. * fix(ai): finalizeStream when RUN_FINISHED. * fix(ai-client): handle reload during active stream with generation counter reload() now cancels the active stream (abort controllers, subscription, processing promise) before starting a new one. A stream generation counter prevents a superseded stream's async cleanup from clobbering the new stream's state (abortController, isLoading, processor). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: remove proposal docs. * fix(ai, ai-client): address stream lifecycle edge cases from PR review - Guard against double onStreamEnd when RUN_FINISHED arrives before TEXT_MESSAGE_END - Clear dead waiters on subscribe exit to prevent chunk loss on reconnection - Reset transient processor state (messageStates, activeMessageIds, etc.) on MESSAGES_SNAPSHOT - Remove optimistic startAssistantMessage() from streamResponse(); let stream events create the message naturally via TEXT_MESSAGE_START or ensureAssistantMessage() - Clean up abort listeners on normal waiter resolution to prevent listener accumulation - Make handleStepFinishedEvent use ensureAssistantMessage() for backward compat with streams that lack TEXT_MESSAGE_START Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ai-client): fix reload failures from stale stream state and waiter race Reset processor stream state (prepareAssistantMessage) in streamResponse() before the subscription loop, preventing stale messageStates from blocking new assistant message creation on reload. Rewrite createDefaultSession with per-subscribe queue isolation: each subscribe() synchronously installs fresh buffer/waiters, drains pre-buffered chunks via splice(0), and removes async cleanup that raced with new subscription cycles. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * ci: apply automated fixes * fix(ai): resolve eslint errors in stream processor Remove unnecessary `chunk.delta !== undefined` condition (delta is always a string on TextMessageContentEvent) and remove redundant `!` non-null assertion inside an already-narrowed `if` block. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ai-client): resolve eslint errors in chat-client and session-adapter Fix import ordering: move value import `createDefaultSession` above type-only imports. Convert shorthand method signatures to function property style in the SessionAdapter interface. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ai-client): propagate send() errors to subscribe() consumers Wrap createDefaultSession's send() in try/catch and push a RUN_ERROR AG-UI event to the queue before re-throwing, so subscribe() consumers learn about connection failures through the standard protocol. Also resolve processingResolve on RUN_ERROR in consumeSubscription (same as RUN_FINISHED) to prevent hangs. Tests updated: error assertions now check message content rather than referential identity, since errors flowing through RUN_ERROR create new Error instances from the message string. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ai): map 'tool' role to 'assistant' in message state to fix lookups The stream processor mapped 'tool' to 'assistant' for UIMessage but stored the raw 'tool' role in MessageStreamState. This caused getActiveAssistantMessageId() and getCurrentAssistantMessageId() to miss tool-role messages, so subsequent stream events couldn't attach to the existing message. Now the uiRole mapping is applied consistently across all three cases in handleTextMessageStartEvent. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ai): normalize chunk.delta to avoid "undefined" string concatenation When chunk.delta was undefined, the check `chunk.delta !== ''` evaluated to true, causing "undefined" to be concatenated into nextText. Use `chunk.delta ?? ''` to normalize before comparison, matching the safe pattern already used in handleToolCallArgsEvent. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ai): use || instead of ?? for chunk.delta fallback to satisfy eslint The no-unnecessary-condition rule flags ?? since TypeScript types delta as string. Using || preserves runtime safety and matches existing patterns. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ai): reset stream flags on MESSAGES_SNAPSHOT to avoid stale state handleMessagesSnapshotEvent was clearing maps but not resetting isDone, hasError, and finishReason. Use resetStreamState() which handles all of these, ensuring finalizeStream() sees fresh state after a snapshot. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(ai-client): finalize connection adapter unification Squash all post-groundwork changes into a single commit that completes the connection adapter unification, stream lifecycle hardening, and restoration of ai stream snapshot/state behavior. Co-authored-by: Cursor <cursoragent@cursor.com> * ci: apply automated fixes * fix: return booleans from chat client streamResponse Keep early stream exits aligned with the Promise<boolean> contract so repo-wide type checks pass after the merge from main. Made-with: Cursor * chore: add changeset for durable chat updates Document the patch releases for the durable subscribe/send chat transport, generation client wrappers, and core stream processing changes included on this branch. Made-with: Cursor * fix: resolve tool call approval after RUN_FINISHED using toolCallToMessage fallback After RUN_FINISHED, activeMessageIds is cleared so tool call approval couldn't find the parent message. Fall back to the toolCallToMessage map which is populated during TOOL_CALL_START and preserved across finalize. Also adds missing role field to mock chat scenarios. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Sam Willis <sam.willis@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Jack Herrington <jherr@pobox.com>
12 hours ago
by James Arthur
J
Previous page
Previous
Next
Next page