Skip to content

Commit d8d4e8c

Browse files
authored
fix(web): keep long streams responsive (#1643)
* fix(web): keep long streams responsive * fix(web): drop queued events for archived sessions
1 parent b24a347 commit d8d4e8c

7 files changed

Lines changed: 1197 additions & 148 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@moonshot-ai/kimi-code": patch
3+
---
4+
5+
web: Prevent long streaming responses from stalling after a tab is backgrounded.

apps/kimi-web/src/api/daemon/client.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1434,14 +1434,26 @@ export class DaemonKimiWebApi implements KimiWebApi {
14341434
const { type, seq, session_id: sessionId, payload, offset } = frame;
14351435
const appEvents = projector.project(type, payload, sessionId, { offset });
14361436
for (const appEvent of appEvents) {
1437+
const turnId = (payload as { turnId?: unknown } | null)?.turnId;
1438+
const stream =
1439+
appEvent.type === 'assistantDelta' &&
1440+
typeof turnId === 'number' &&
1441+
typeof offset === 'number' &&
1442+
(type === 'assistant.delta' || type === 'thinking.delta')
1443+
? {
1444+
turnId,
1445+
offset,
1446+
kind: type === 'assistant.delta' ? ('text' as const) : ('thinking' as const),
1447+
}
1448+
: undefined;
14371449
// historyCompacted from the projector is either a compaction signal
14381450
// (reason auto_compact — no reload, the divider marker handles it) or
14391451
// a delta-gap recovery (reason delta_gap — a real resync, routed to
14401452
// onResync with the real frame.seq, mirroring the protocol path).
14411453
if (appEvent.type === 'historyCompacted' && !isCompactionReason(appEvent.reason)) {
14421454
handlers.onResync(sessionId, seq);
14431455
}
1444-
handlers.onEvent(appEvent, { sessionId, seq });
1456+
handlers.onEvent(appEvent, { sessionId, seq, stream });
14451457
}
14461458
},
14471459

apps/kimi-web/src/api/types.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,14 +507,26 @@ export interface AppSessionSnapshot {
507507
}
508508

509509
export interface KimiEventHandlers {
510-
onEvent(event: AppEvent, meta: { sessionId: string; seq: number }): void;
510+
onEvent(event: AppEvent, meta: KimiEventMeta): void;
511511
onResync(sessionId: string, currentSeq: number, epoch?: string): void;
512512
onError(code: number, msg: string, fatal: boolean): void;
513513
onConnectionChange(connected: boolean): void;
514514
onTerminalOutput?(sessionId: string, terminalId: string, data: string, seq: number): void;
515515
onTerminalExit?(sessionId: string, terminalId: string, exitCode: number | null): void;
516516
}
517517

518+
/** Raw stream coordinates are present only for kap-server assistant/thinking
519+
deltas. They let the render queue merge chunks without guessing continuity. */
520+
export interface KimiEventMeta {
521+
sessionId: string;
522+
seq: number;
523+
stream?: {
524+
turnId: number;
525+
offset: number;
526+
kind: 'text' | 'thinking';
527+
};
528+
}
529+
518530
export interface KimiEventConnection {
519531
subscribe(sessionId: string, cursor?: AppSessionCursor): void;
520532
unsubscribe(sessionId: string): void;

0 commit comments

Comments
 (0)