feat: phase 3-5 — workflow engine, background subagents, multi-modal, cache shape, inline diff
Phase 3: Dynamic Workflow Engine - VM sandbox (node:vm) with agent/parallel/pipeline API, Claude Code compatible - Workflow file discovery (.boocode/workflows/*.js + ~/.boocode/workflows/*.js) - Workflow manager with session/chat creation and inference dispatch - Built-in catalog: deep-research, review-code, find-issues - Resumability cache: SHA-256 hash of agent spec, in-memory Map Phase 4: Background Subagents - background-task.ts service: spawn/poll/cancel lifecycle - spawn_subagent, subagent_status, subagent_result tools in ALL_TOOLS Phase 5: Multi-modal + Cache Shape - Multi-modal stub with type defs and hook point in payload.ts - CacheShapeBadge component in trace viewer (colored bar + %)
This commit is contained in:
@@ -21,10 +21,11 @@ import { registerSkillsRoutes } from './routes/skills.js';
|
||||
import { registerTraceRoutes } from './routes/traces.js';
|
||||
import { registerToolsRoutes } from './routes/tools.js';
|
||||
import { registerAnalyticsRoutes } from './routes/analytics.js';
|
||||
import { registerMemoryRoutes } from './routes/memory.js';
|
||||
|
||||
import { registerInferenceSettingsRoutes } from './routes/inference-settings.js';
|
||||
import { createInferenceRunner } from './services/inference/index.js';
|
||||
import { createInferenceRunner, runInferenceWithModel } from './services/inference/index.js';
|
||||
import { createBroker } from './services/broker.js';
|
||||
import { setBackgroundInferenceEnqueuer } from './services/background-task.js';
|
||||
import { listSkills } from './services/skills.js';
|
||||
import * as compaction from './services/compaction.js';
|
||||
import { configureModelContext } from './services/model-context.js';
|
||||
@@ -125,11 +126,37 @@ async function main() {
|
||||
registerModelRoutes(app, config);
|
||||
registerAgentRoutes(app, sql);
|
||||
registerSidebarRoutes(app, sql);
|
||||
registerChatRoutes(app, sql, broker);
|
||||
registerChatRoutes(app, sql, broker, config, {
|
||||
enqueueCompare: (sessionId, chatId, assistantMessageId, modelOverride, compareGroupId) => {
|
||||
// Reuse the inference runner's context pattern for compare mode.
|
||||
// Each compare run gets its own AbortController; cancellation keyed by
|
||||
// chatId (cancels ALL parallel runs in that compare group).
|
||||
const compareCtx: import('./services/inference/types.js').InferenceContext = {
|
||||
sql,
|
||||
config,
|
||||
log: app.log,
|
||||
publish: (sid, frame) => {
|
||||
broker.publishFrame(sid, frame as unknown as import('@boocode/contracts/ws-frames').WsFrame);
|
||||
},
|
||||
publishUser: (frame) => {
|
||||
broker.publishUserFrame('default', frame as unknown as import('@boocode/contracts/ws-frames').WsFrame);
|
||||
},
|
||||
broker,
|
||||
hooks: hasHooks ? hookRunner : undefined,
|
||||
};
|
||||
compareCtx.publishUser({ type: 'chat_status', chat_id: chatId, status: 'streaming', at: new Date().toISOString() });
|
||||
void runInferenceWithModel(compareCtx, sessionId, chatId, assistantMessageId, modelOverride, compareGroupId).catch(
|
||||
(err: Error) => app.log.error({ err, chatId, modelOverride }, 'compare inference failed'),
|
||||
);
|
||||
},
|
||||
cancelInference: async (_sessionId, chatId) => {
|
||||
return inference.cancel(_sessionId, chatId);
|
||||
},
|
||||
hasActiveInference: (chatId) => inference.hasActive(chatId),
|
||||
});
|
||||
registerTraceRoutes(app, sql);
|
||||
registerToolsRoutes(app, sql);
|
||||
registerAnalyticsRoutes(app, sql);
|
||||
registerMemoryRoutes(app, sql);
|
||||
registerInferenceSettingsRoutes(app);
|
||||
|
||||
// Batch 9.6: warm the skills cache at boot and surface the count. Empty or
|
||||
@@ -167,6 +194,13 @@ async function main() {
|
||||
broker.publishUserFrame(user, frame as unknown as import('@boocode/contracts/ws-frames').WsFrame);
|
||||
}
|
||||
);
|
||||
// v2.x: wire the background subagent task system to the inference runner.
|
||||
// Tools (spawn_subagent) dispatch fire-and-forget inference via this
|
||||
// module-level reference — no import cycle through the tool registry.
|
||||
setBackgroundInferenceEnqueuer((sessionId, chatId, assistantId, user) => {
|
||||
inference.enqueue(sessionId, chatId, assistantId, user);
|
||||
});
|
||||
|
||||
registerMessageRoutes(app, sql, config, broker, {
|
||||
enqueueInference: (sessionId, chatId, assistantId, user) => {
|
||||
inference.enqueue(sessionId, chatId, assistantId, user);
|
||||
|
||||
Reference in New Issue
Block a user