Files
wehub-resource-sync 426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00

5.5 KiB

Inline chat activity pipeline (#13536)

How elizaOS surfaces orchestrator/task/sub-agent/tool/workflow/todo activity inline in the chat thread as it happens — the Codex / Claude-Code / OpenCode turn-pipelining model, mapped onto the event stream elizaOS already emits. This note records the mapping so the next engineer does not reinvent it or add a second mechanism.

How the reference agents pipe a turn

All three interleave one ordered activity stream inside the assistant turn, not a separate rail:

  • Claude Code — the turn is a sequence of text, thinking, and tool_use blocks. Each tool call is a collapsible row that transitions running → result in place; a sub-agent (Task tool) is a nested block with its own indented stream; the todo list (TodoWrite) is a live checklist that mutates in place rather than reprinting.
  • Codex — the same shape over its exec/event protocol: streamed reasoning + message deltas, tool_call items that resolve to tool_result, and a plan/update surface rendered as a checklist.
  • OpenCode — an ordered part stream per message (text, reasoning, tool, step-start/finish), child sessions nested under the parent, and a todowrite/plan tool whose latest snapshot is the checklist.

The common model: one stream, ordered by sequence, grouped into a task → sub-agent → step tree, with a plan/todo snapshot that mutates in place. We mirror it; we do not invent a new one.

The elizaOS mapping

elizaOS already emits the equivalent events — the work was a typed envelope plus an inline renderer, not new plumbing.

Reference concept elizaOS source Inline surface
ordered turn stream SwarmEvent over the pty-session-event WS channel ordered by stamped seq
streamed text / thinking ACP message / reasoning events sub-agent "current line"
tool call running→result ACP tool_running events (SwarmActivityTool) ToolCallEventLog step row
sub-agent / child session a session's sessionId, nested via parentSessionId SubagentBlock (indented)
plan / todo snapshot ACP plan events (SwarmActivityPlanEntry[]) PlanChecklist (mutates in place)
task grouping the owning task thread projected as taskId the [TASK:<id>] card
agent-authored todo list [CHECKLIST] marker in a reply PlanChecklist
agent-authored pipeline [WORKFLOW] marker in a reply WorkflowSteps

The three seams

  1. Wire projection — the client cannot reconstruct order or grouping from a flat, non-order-preserving WS stream, so SwarmCoordinatorService.dispatchSwarmEvent stamps every event with a monotonic seq, the owning taskId (resolved from the task context the service already maintains), and a parentSessionId when the payload names a nesting parent. Assigned once, at dispatch, so every emit site (including escalation/validator dispatches) gets the same projection.

  2. Typed envelopeSwarmEvent.data is unknown because it is assembled from ACP-adapter payloads whose shape varies by backend. toSwarmActivity (packages/core/src/types/swarm-coordinator.ts) is the single boundary that validates one raw event and narrows it to a SwarmActivityEnvelope variant (message | reasoning | plan | tool | lifecycle) or null when nothing is renderable. Every widget reads the typed envelope; none pokes at data. Pure and dependency-free so it runs identically in server tests and the browser.

  3. Stream-driven storetask-activity-store (packages/ui/src/state) subscribes once to pty-session-event, runs each event through toSwarmActivity, and regroups the flat stream into the task → sub-agent → step tree via useSyncExternalStore. A task card selects its own subtree with useTaskActivity(taskId) and re-renders only on its own events. This is what lets the [TASK] card drop its old 5s poll — the one durable hydrate fetch fills header fields that predate the current WS session; everything after arrives on the stream.

One scheduler, not two

The inline pipeline is a read model over the existing orchestrator event stream — the same SwarmEvents the sidebar rail already consumes. It adds no new scheduler, no new poll for data already on the stream, and no second knowledge store. The sidebar rail stays as the flat "all activity" overflow; the thread carries the focused, grouped pipeline. summarizePtyEvent (activity-plaintext.ts) was extended so the previously-dropped message/reasoning/plan/ready/login_required/reconnected events render as useful text in the rail instead of raw event names.

Making the agent-authored widgets reachable

[CHECKLIST] and [WORKFLOW] are taught to the model in the uiWidgets provider (packages/agent/src/providers/ui-catalog.ts) alongside [FOLLOWUPS]/[FORM], so they are reachable end to end (model → marker → parser → widget), not speculative dead widgets. A re-emitted block mutates the list in place — the agent's own turn-to-turn plan/pipeline tracking, distinct from the WS-driven plan inside an orchestrator task card (which the agent must not duplicate).