refactor(desktop): ChatStore structured split + IDB persistence + stream cancel
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Split monolithic chatStore.ts (908 lines) into 4 focused stores: - chatStore.ts: facade layer, owns messages[], backward-compatible selectors - conversationStore.ts: conversation CRUD, agent switching, IndexedDB persistence - streamStore.ts: streaming orchestration, chat mode, suggestions - messageStore.ts: token tracking Key fixes from 3-round deep audit: - C1: Fix Rust serde camelCase vs TS snake_case mismatch (toolStart/toolEnd/iterationStart) - C2: Fix IDB async rehydration race with persist.hasHydrated() subscribe - C3: Add sessionKey to partialize to survive page refresh - H3: Fix IDB migration retry on failure (don't set migrated=true in catch) - M3: Fix ToolCallStep deduplication (toolStart creates, toolEnd updates) - M-NEW-2: Clear sessionKey on cancelStream Also adds: - Rust backend stream cancellation via AtomicBool + cancel_stream command - IndexedDB storage adapter with one-time localStorage migration - HMR cleanup for cross-store subscriptions
This commit is contained in:
@@ -109,7 +109,7 @@ export function installChatMethods(ClientClass: { prototype: KernelClient }): vo
|
||||
}
|
||||
break;
|
||||
|
||||
case 'tool_start':
|
||||
case 'toolStart':
|
||||
log.debug('Tool started:', streamEvent.name, streamEvent.input);
|
||||
if (callbacks.onTool) {
|
||||
callbacks.onTool(
|
||||
@@ -120,7 +120,7 @@ export function installChatMethods(ClientClass: { prototype: KernelClient }): vo
|
||||
}
|
||||
break;
|
||||
|
||||
case 'tool_end':
|
||||
case 'toolEnd':
|
||||
log.debug('Tool ended:', streamEvent.name, streamEvent.output);
|
||||
if (callbacks.onTool) {
|
||||
callbacks.onTool(
|
||||
@@ -145,7 +145,7 @@ export function installChatMethods(ClientClass: { prototype: KernelClient }): vo
|
||||
}
|
||||
break;
|
||||
|
||||
case 'iteration_start':
|
||||
case 'iterationStart':
|
||||
log.debug('Iteration started:', streamEvent.iteration, '/', streamEvent.maxIterations);
|
||||
// Don't need to notify user about iterations
|
||||
break;
|
||||
@@ -201,10 +201,17 @@ export function installChatMethods(ClientClass: { prototype: KernelClient }): vo
|
||||
};
|
||||
|
||||
/**
|
||||
* Cancel a stream (no-op for internal kernel)
|
||||
* Cancel an active stream by session ID.
|
||||
* Invokes the Rust `cancel_stream` command which sets the AtomicBool flag
|
||||
* checked by the spawned streaming task each iteration.
|
||||
*/
|
||||
proto.cancelStream = function (this: KernelClient, _runId: string): void {
|
||||
// No-op: internal kernel doesn't support stream cancellation
|
||||
proto.cancelStream = async function (this: KernelClient, sessionId: string): Promise<void> {
|
||||
try {
|
||||
await invoke('cancel_stream', { sessionId });
|
||||
log.debug('Cancel stream requested for session:', sessionId);
|
||||
} catch (err) {
|
||||
log.warn('Failed to cancel stream:', err);
|
||||
}
|
||||
};
|
||||
|
||||
// ─── Default Agent ───
|
||||
|
||||
Reference in New Issue
Block a user