feat(compound-engineering): live agent output, steering, and a real Q&A surface

Users can now watch everything the agent does while a CE stage works, steer
it mid-stage, and read the whole conversation as a proper chat surface.

Live output:
- New host capability: CreateInteractiveAiSessionOptions.onProgress — the
  engine adapter streams thinking/text deltas + tool start/end markers from
  the pi agent hooks (any plugin can use this).
- Orchestrator buffers per-session live activity (merged deltas, discrete
  tool lines, capped), emits throttled progress events over SSE, and
  GET /sessions/:id attaches it as liveActivity for the polling fallback.
- Routes detach turn execution: start/answer/resume return immediately
  (status active) and clients converge via push/poll — the turn is watchable
  instead of hidden inside a blocking POST.
- Turn timeout is now INACTIVITY-based: an actively-working long turn is
  never killed; a quiet one interrupts with its working trace preserved.
- On settle the trace persists into history as a condensed record.

Steering:
- Stage protocol: responses may be a direct answer, {value, comment}
  (answer + guidance), or {feedback} (guidance without answering); the
  system prompt instructs agents to treat steering as first-class input.
- CeFlow: guidance textarea alongside selectable questions — attach to the
  clicked answer, or "Send guidance" on its own.

Q&A UI:
- Transcript no longer hides control records: past questions/answers render
  as chat bubbles (option ids → labels), steering turns marked, working
  traces as collapsible "Agent work" blocks, completion marker.
- Live working pane (pulse + streaming thinking/tool lines) while a turn runs.

Tests: 130 plugin tests green (14 new: live buffer/flush ordering, inactivity
watchdog survives active work, detached convergence, steering payload shapes,
transcript rendering, live pane). Engine seam tests green; plugin/core/
engine/dashboard tsc clean. Core full suite OOMs locally (known orchestrator-
shell issue) — covered by CI shards.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-06-03 14:17:40 -07:00
parent cff0dee87c
commit 0106eee4ff
13 changed files with 1135 additions and 97 deletions

View File

@@ -161,6 +161,34 @@ const _createInteractiveAiSessionAdapter: CreateInteractiveAiSessionFactory = (
// discovery dirs make those skills actually visible to the loader.
...(opts.requestedSkillNames?.length ? { skills: opts.requestedSkillNames } : {}),
...(opts.additionalSkillPaths?.length ? { additionalSkillPaths: opts.additionalSkillPaths } : {}),
// Live mid-turn visibility: stream thinking/text deltas and tool
// start/end markers to the caller's onProgress while the pull-based
// nextEvent() is still pending. Callback errors must never break the
// agent turn.
...(opts.onProgress
? {
onThinking: (delta: string) => {
try {
opts.onProgress!({ type: "thinking", delta });
} catch { /* consumer error must not break the turn */ }
},
onText: (delta: string) => {
try {
opts.onProgress!({ type: "text", delta });
} catch { /* consumer error must not break the turn */ }
},
onToolStart: (name: string) => {
try {
opts.onProgress!({ type: "tool", name, phase: "start" });
} catch { /* consumer error must not break the turn */ }
},
onToolEnd: (name: string, isError: boolean) => {
try {
opts.onProgress!({ type: "tool", name, phase: "end", isError });
} catch { /* consumer error must not break the turn */ }
},
}
: {}),
}),
options,
);