data pipeline refactor and fix

This commit is contained in:
2026-04-13 18:30:04 -04:00
parent 6418729b16
commit 326bf80846
96 changed files with 7107 additions and 1763 deletions

View File

@@ -59,6 +59,18 @@ const addToolCallBubble = (label: string) => {
}]
}
const appendToolCallStatus = (status: string) => {
if (!toolCallMessageId) return
const idx = messages.value.findIndex(m => m._id === toolCallMessageId)
if (idx !== -1) {
messages.value[idx] = {
...messages.value[idx],
content: messages.value[idx].content + `\n↳ ${status}`
}
messages.value = [...messages.value]
}
}
const removeToolCallBubble = () => {
if (toolCallMessageId) {
messages.value = messages.value.filter(m => m._id !== toolCallMessageId)
@@ -76,11 +88,47 @@ const streamingImages = ref<any[]>([])
const handleMessage = (data: WebSocketMessage) => {
console.log('[ChatPanel] Received message:', data)
if (data.type === 'conversation_history') {
messages.value = (data.messages as any[]).map((m: any) => {
const ts = new Date(m.timestamp / 1000) // microseconds → ms
const files = (m.files ?? []).map((b: any) => ({
name: `image_${b.id}.png`,
size: 0,
type: b.mimeType.split('/')[1] ?? 'png',
url: `data:${b.mimeType};base64,${b.data}`,
preview: `data:${b.mimeType};base64,${b.data}`,
}))
return {
_id: m.id,
content: m.content,
senderId: m.role === 'user' ? CURRENT_USER_ID : AGENT_ID,
timestamp: ts.toTimeString().split(' ')[0].slice(0, 5),
date: ts.toLocaleDateString(),
saved: true,
distributed: true,
seen: true,
files,
}
})
messagesLoaded.value = true
return
}
if (data.type === 'agent_tool_call') {
addToolCallBubble(data.label ?? data.toolName ?? 'Tool call...')
return
}
if (data.type === 'subagent_tool_call') {
appendToolCallStatus(data.toolName ?? data.label ?? 'tool')
return
}
if (data.type === 'subagent_chunk') {
// Subagent final text — not shown separately; the main agent will incorporate it in its response
return
}
if (data.type === 'image') {
// Handle image message - attach to current streaming message or create standalone
console.log('[ChatPanel] Processing image message')

View File

@@ -3,6 +3,24 @@ import * as jsonpatch from 'fast-json-patch';
import type { BackendMessage, FrontendMessage, HelloMessage, PatchMessage } from '../types/sync';
import { wsManager } from './useWebSocket';
function deepReplace(target: Record<string, any>, source: Record<string, any>) {
for (const key of Object.keys(target)) {
if (!(key in source)) {
delete target[key]
}
}
for (const [key, value] of Object.entries(source)) {
if (
value !== null && typeof value === 'object' && !Array.isArray(value) &&
target[key] !== null && typeof target[key] === 'object' && !Array.isArray(target[key])
) {
deepReplace(target[key], value)
} else {
target[key] = value
}
}
}
export function useStateSync(stores: Record<string, Store>) {
console.log('[StateSync] Initializing with stores:', Object.keys(stores));
@@ -35,7 +53,7 @@ export function useStateSync(stores: Record<string, Store>) {
if (store) {
console.log('[StateSync] Applying snapshot state:', msg.state);
isApplyingBackendPatch[msg.store] = true;
store.$patch(msg.state);
store.$patch((state) => deepReplace(state as Record<string, any>, msg.state as Record<string, any>));
// Update previousState to stay in sync
previousStates[msg.store] = JSON.parse(JSON.stringify(store.$state));
isApplyingBackendPatch[msg.store] = false;
@@ -64,7 +82,7 @@ export function useStateSync(stores: Record<string, Store>) {
const newState = jsonpatch.applyPatch(currentState, msg.patch, false, false).newDocument;
console.log('[StateSync] New state after patch:', newState);
isApplyingBackendPatch[msg.store] = true;
store.$patch(newState);
store.$patch((state) => deepReplace(state as Record<string, any>, newState as Record<string, any>));
// Update previousState to stay in sync
previousStates[msg.store] = JSON.parse(JSON.stringify(store.$state));
isApplyingBackendPatch[msg.store] = false;

View File

@@ -123,8 +123,9 @@ class WebSocketManager {
this.statusMessage.value = ''
console.log('WebSocket disconnected:', event.code, event.reason)
// Attempt to reconnect if we have a token
if (this.token && !event.wasClean) {
// Attempt to reconnect if we have a token and it wasn't an intentional close.
// Check code instead of wasClean: code 1005 has wasClean=true but still needs retry.
if (this.token && event.code !== 1000 && event.code !== 1001) {
this.scheduleReconnect()
}
}