feat: make Kafka projector the Workbench realtime authority

This commit is contained in:
root
2026-07-10 05:23:03 +02:00
parent a685be0b78
commit ce83ffdf49
74 changed files with 7746 additions and 9863 deletions
+4 -4
View File
@@ -98,7 +98,7 @@ const workbenchHealthRuntimeSource = readWeb("src/utils/workbench-health.ts");
const traceTimelineSource = readWeb("src/components/agent/TraceTimeline.vue");
const messageTraceDebugSource = readWeb("src/components/workbench/MessageTraceDebugPanel.vue");
const conversationPanelSource = readWeb("src/components/workbench/ConversationPanel.vue");
const serverWorkbenchHttpSource = fs.readFileSync(path.resolve(rootDir, "..", "..", "internal/cloud/server-workbench-http.ts"), "utf8");
const serverWorkbenchRealtimeHttpSource = fs.readFileSync(path.resolve(rootDir, "..", "..", "internal/cloud/server-workbench-realtime-http.ts"), "utf8");
assert.match(html, /<div id="app"><\/div>/u, "index.html must expose Vue mount root");
assert.match(html, /src="\/src\/main\.ts"/u, "index.html must load Vue TS entry");
@@ -208,9 +208,9 @@ assert.doesNotMatch(workbenchStoreSource, /refreshActiveTraceFromRest[\s\S]{0,12
assert.doesNotMatch(workbenchStoreSource, /refreshTerminalTraceFromRest[\s\S]{0,1200}refreshSessions\([^;]+force:\s*true/u, "Terminal trace REST refresh must not force-refresh the full session list");
assert.doesNotMatch(workbenchStoreSource, /message\.runnerTrace(?:\?\.|\.)status/u, "Workbench message lifecycle must not be inferred from runnerTrace.status");
assert.doesNotMatch(conversationPanelSource, /message\.runnerTrace(?:\?\.|\.)status/u, "ConversationPanel must not override message completion from runnerTrace.status");
assert.doesNotMatch(serverWorkbenchHttpSource, /return\s+turnSnapshot\(context\)|\.\.\.turnSnapshot\(context\)|blockedTraceEventProjection\(context\.projection/u, "Realtime turn snapshots must not fall back to legacy trace/result projection");
assertIncludes(serverWorkbenchHttpSource, "blockedRealtimeTurnSnapshot", "Realtime read-model gaps must produce blocked diagnostic turn snapshots");
assertIncludes(serverWorkbenchHttpSource, "workbench_facts_session_missing", "Realtime read-model gaps must expose a facts-missing blocker");
assert.doesNotMatch(serverWorkbenchRealtimeHttpSource, /return\s+turnSnapshot\(context\)|\.\.\.turnSnapshot\(context\)|blockedTraceEventProjection\(context\.projection/u, "Realtime turn snapshots must not fall back to legacy trace/result projection");
assertIncludes(serverWorkbenchRealtimeHttpSource, "blockedRealtimeTurnSnapshot", "Realtime read-model gaps must produce blocked diagnostic turn snapshots");
assertIncludes(serverWorkbenchRealtimeHttpSource, "workbench_facts_session_missing", "Realtime read-model gaps must expose a facts-missing blocker");
assertIncludes(appSource, "/v1/workbench/events", "Workbench realtime client must use the RESTful same-origin events endpoint");
assertIncludes(appSource, "/v1/workbench/traces/", "trace detail read must use Workbench read-model trace API");
assert.doesNotMatch(appSource, /\/v1\/agent\/(?:turns|traces|chat\/result)\//u, "Cloud Web must not call legacy Code Agent read-through turn/trace/result APIs");