跳转到内容

Minimal TypeScript orchestrator core — Web UI as plugin

Minimal TypeScript orchestrator core — Web UI as plugin

Section titled “Minimal TypeScript orchestrator core — Web UI as plugin”

Related: Cloud agent orchestrator · 2026-09-28 Pi SDK sessions worktrees and TS coordinator · Lightweight Grokbot Clone


SourceSteal
OpenHands Agent ServerIndependent REST + WebSocket; conversation/workspace/file/command APIs; immutable persisted events with search/replaydocs · events
OpenCode serveStandalone HTTP + OpenAPI + SSE; TUI is just a client of the same serverserver
ContinueTyped ToCore / FromCore protocol; abstract messenger transportprotocol
GooseServer API for agent/session lifecycle; streaming events; reconnect-friendlyAPI
TemporalClient / Server / Worker split; durable event history; workers poll queuesarchitecture
LSPUI starts/connects to a server; JSON-RPC; UI does not own analysis statespec
AiderAnti-pattern for core: CLI-first; UIs wrap process + stream-json — OK as adapter, not as the design

orchestrator-core
CLI
HTTP / JSON-RPC control API
event bus + append-only event store
worker registry + task queue

Minimal capabilities:

interface Orchestrator {
createSession(input: CreateSession): Promise<Session>;
sendMessage(id: SessionId, input: MessageInput): Promise<void>;
cancel(id: SessionId): Promise<void>;
getSnapshot(id: SessionId): Promise<SessionSnapshot>;
readEvents(id: SessionId, cursor?: string): Promise<EventPage>;
subscribe(id: SessionId, listener: EventListener): Unsubscribe;
}

Expose at least: POST /sessions, POST /sessions/:id/messages, POST /sessions/:id/cancel, GET /sessions/:id, GET /sessions/:id/events?cursor=…, GET /health, GET /openapi.json.

SSE first for the Web UI plugin; add WebSocket only when bidirectional streaming or interactive approvals need it. Keep the internal bus transport-neutral.

Persistence: append-only event log (stable ids, timestamps, session id, type, payload, schema version). Snapshots / derived state separate. Replay reconstructs after restart. Cursors + short replay buffer so reconnecting UIs do not lose events. Bootstrap: subscribe before snapshot, buffer, then apply snapshot + buffered events (avoid race).

Workers: separate processes/modules that register capabilities and poll a queue. Core schedules and records; workers run Pi sessions, tools, long jobs. Temporal-shaped without requiring Temporal on day one.


The UI should:

  1. Discover the core (configured URL or local process launcher).
  2. Use a generated OpenAPI client for commands/queries.
  3. Subscribe to SSE before sending prompts.
  4. Rehydrate from snapshot + cursor.
  5. Render sessions, messages, tool calls, approvals, logs, diffs.
  6. Never own orchestration state or worker processes.

Fits Lightweight Grokbot Clone as interface + monitor panel against this core.


Build the core like a small OpenCode server + LSP, use OpenHands-style immutable events, add Temporal-style workers when durability and parallel worktree runs justify it. Pi sessions are workers’ concern; the core owns run lifecycle, events, and the plugin contract.