Skip to content

Commit 8aec280

Browse files
committed
feat(sdk): chat.agent → Sessions migration (phases B + C + min E)
Rewires chat.agent's internal I/O and TriggerChatTransport's send + subscribe paths onto the Session primitive. Minimum token-scope work included so the transport's session endpoints actually authenticate. Phase B — chat.agent internals (ai.ts) - New ChatInputChunk tagged union (`kind: "message" | "stop"`) — replaces the two-stream split (chat-messages + chat-stop) with a single Session `.in` channel. - New chatSessionHandleKey locals slot populated at run start from `payload.sessionId ?? payload.chatId`. Every module-level helper now resolves to the per-run session handle. - Module-level `chatStream`, `messagesInput`, `stopInput` become thin facades over the session. `chatStream` mirrors `RealtimeDefinedStream<UIMessageChunk>` and delegates to `handle.out`. `messagesInput` / `stopInput` mirror `RealtimeDefinedInputStream<…>` and filter `.in` by kind — the two internal `.on()`/`.waitWithIdleTimeout()` callers and the `chat.messages` / `chat.createStopSignal` public exposures keep their existing shapes. - Every `streams.writer(CHAT_STREAM_KEY, …)` callsite swaps to `chatStream.writer(…)` so all chat output flows through `session.out` → `SessionStreamInstance` → direct-to-S2. - Threaded `sessionId` through `ChatTaskWirePayload` / `ChatTaskPayload` / `ChatTaskRunPayload` so advanced users can `sessions.open(sessionId)` directly from `run()`. Phase C — TriggerChatTransport (chat.ts) - `ChatSessionState` keys durable identity on `sessionId` (friendlyId); `runId` becomes an optional hint about whether a run is live. - `ensureSession(chatId)` lazily upserts the Session via `apiClient.createSession({type: "chat.agent", externalId: chatId})` on the direct `accessToken` path. Idempotent — two tabs on the same chat converge. - `sendMessages`, `sendPendingMessage`, `stopGeneration`, `sendAction` all go through `appendToSessionStream(sessionId, "in", serializeInputChunk({kind: …}))` — one endpoint, one tag per record. - SSE subscribe URL moves from `/realtime/v1/streams/{runId}/chat` to `/realtime/v1/sessions/{sessionId}/out`. The old run-scoped `subscribeToStream` is replaced by `subscribeToSessionStream`. Incoming chunks come back as JSON strings on the session channel (server wraps records as `{data, id}` on S2), so the subscribe loop parses them back into objects to keep the rest of the control flow (turn-complete / upgrade-required / skipToTurnComplete) unchanged. - Upgrade-required re-trigger keeps the same Session and swaps only the runId + token. - `getSession` / `setSession` / `setOnSessionChange` / persistence shape all grow a `sessionId` field (runId now optional). Phase E — minimum token scopes - `chat.createTriggerAction` (server side) now creates the Session before triggering so it can (a) thread `sessionId` into the run payload and (b) mint a token with both run and session scopes. Returns `sessionId` in its result so the transport can skip its own `sessions.create` call on the server-side-trigger path. - `TriggerChatTaskResult` gains optional `sessionId`. - The two in-run PAT refresh sites (preloadAccessToken, turnAccessToken) add `read:sessions:{sessionId}` + `write:sessions:{sessionId}` alongside the existing run scopes. Known follow-ups (deferred to later passes) - Phase D: `AgentChat` / `ChatStream` in chat-client.ts still uses the old `/realtime/v1/streams/{runId}/chat` path. Used by server- side task-to-task compositions, not the browser transport. - Phase F: delete CHAT_STREAM_KEY, CHAT_MESSAGES_STREAM_ID, CHAT_STOP_STREAM_ID from chat-constants.ts + ai-chat smoke verify.
1 parent 1e16248 commit 8aec280

3 files changed

Lines changed: 823 additions & 238 deletions

File tree

0 commit comments

Comments
 (0)