07 · Studio: live agent feed — chat, todos, prompt insertion #8
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
cmoriarty/trog#8
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The feed becomes a first-class coding-agent chat — the OpenCode/Claude-Code experience, but rendering trog's own LangGraph runs. The #7 shell already streams tokens via
useStream; this ticket makes the stream legible.Core
ideation,gate_fun,assets…)trog-mcp·websearch· seat calls), so you can see what the agent is reaching for at a glancetodosstate key the nodes maintain; renders from the same values stream+/-countsreasoning_contentthrough llama.cpp's reasoning-format flag)More OpenCode features worth stealing
ideation 34s · preprod 1m12s · …) — doubles as a cost/latency profilejoinStreamfor live ones)Plumbing notes
messages-tuple(tokens +tool_call_chunks),values(todos, phase),updates(node boundaries → provenance + timeline),custom(seat/MCP progress events if graphs emit them)v2 note (unchanged): judging is scoped out to v2 — prompt insertion here is steering, not gate judgment. Build the interrupt path so v2's gate-judgment UI drops in without rework.
Studio: live agent feed — chat, todos, prompt insertionto 07 · Studio: live agent feed — chat, todos, prompt insertionCore implemented (deployed to :2027)
All verified live against a phasewalk run in the browser:
[node]narration prefix)trog-mcp/websearch mcp/seat), args summary, beat-locked spinner while pending, expandable args/result; calls paired toToolMessages bytool_call_idstate.todos = [{text, status: pending|in_progress|done}]; collapsible strip with count + current item. phasewalk maintains it across the walkupdatesevents — the fun-gate bounce is visible in the chips), token meter (latest turn usage when the model reports it), quote-into-prompt, autoscrollalpha, the follow-up walk kept checkpointed state (fun gate passed first try — the bounce disappeared)phasewalk exercises all of it GPU-free: todos, gates emitting real
check_phasetool_calls + results, markdown narration. Structural test asserts both contracts.Remaining (next passes)
joinStreamfor live runs)langgraph_node) instead of the narration prefix — needed for graphs that don't prefixtodosstate key, and interrupt-node steering (current steering is stop-and-fold; graph-levelinterrupt()gives mid-node folding)reasoning_contentpassthrough — verify the brain's llama.cpp reasoning-format flag surfaces thinking deltasSwappable brains shipped (feed's timeline strip replaced by the brain selector)
Design: llama-swap was exactly the right tool.
brain/buildstrog-brain: the same pinned llama.cpp engine digest (the surprise-engine-swap lesson survives) fronted by llama-swap v242. One endpoint on :8090, the request'smodelfield picks the brain, one model at a time, requests queued during loads.BRAIN_URL/BRAIN_MODELcontracts untouched; orchestrator brain bracketing untouched (stopping the container still frees GPUs);brain_idlegrew a llama-swap-aware fallback (/running+/upstream/{m}/slots).Roster (brain/llama-swap.yaml, all off the RAID):
qwen3.6-27b(default — flags verbatim from the static brain, preloaded on startup) ·qwen3.6-27b-q6·qwen3.6-35b-a3b·qwen3-coder-next·qwen3-vl-8b·gemma-4-26b-a4b·gemma-4-31b.Graphs:
configurable.modeloverrides the default in hello + production (module llm stays default so the FakeLLM tests keep working). Studio submit rides it.Studio: brain dropdown above the prompt — roster from
/brain/v1/models,· loadedmarker from/running, honest "swaps in on next send (~a minute to load)" hint when picking a cold one. Third same-origin proxy/brain.Verified live end to end: default 27B answered through the proxy →
model: qwen3-vl-8bswapped brains in 48s and answered → studio dropdown + hello graph swapped back to 27B (STUDIO BRAIN SWAP OK). Suite 118 passed.Watch item: the llama-swap-aware
brain_idlefallback hasn't seen a real seat cycle yet — firsttrog image …or drain after this deploy is the live test.Roster audit (4× Quadro RTX 5000, 64GB total) — deployed, every brain verified live
qwen3.6-27b(default)qwen3.6-35b-a3bqwen3-coder-nextgemma-4-31bCut:
qwen3-vl-8b,gemma-4-26b-a4b(not brain-grade),qwen3.6-27b-q6. The llama-swap config is the roster — the studio selector shows exactly these four; nothing else can be requested.Bug found during verify: gemma-4's CLIP rejects
--image-min-tokens 1024(itsimage_max_pixelscap is below what 1024 min tokens implies) and llama-server exits at load. The flag is qwen-vision calibration; removed from the gemma entry, noted in the config.Default restored and resident (
qwen3.6-27b · ready).tok/s in the brain bar (deployed): output tokens per generation second for the last run, measured client-side from first streamed chunk to run end (excludes queueing and model-load, counts thinking tokens — honest across every roster brain). Verified live:
15.8 tok/son the 27B default. Found and fixed en route:usage_metadatanever reached the client — langchain-openai streams withoutinclude_usageby default, so the token meter had been silently dead;stream_usage=Trueon every brain client in hello + production feeds both readouts now (21↑ 661↓alive).Brain-swap status shipped (deployed): llama-swap /running state feeds both readouts — topbar activity shows
swapping brain · <model>first while any model is non-ready, feed working line saysswapping brainduring the load,· loadedmarker only counts ready models, roster poll tightens to 3s mid-run. Captured live through a 27B→gemma swap:swapping brain · qwen3.6-27b(unload) →swapping brain · gemma-4-31b · run · call_brain(load) →run · call_brain→idle.Final #8 round (deployed) — games, sessions, provenance, live reasoning
scratchis the ungrouped default;+ new game…creates a stub inline (real wizard = #25). Threadmetadata.gameis the source of truth; stubs live in localStorage until their first session exists.langgraph_nodefrom the stream itself (getMessagesMetadata().streamMetadata), so unprefixed graphs get chips too; verifiedcall_brainon hello.reasoning_content, which base ChatOpenAI silently drops — root cause of the foldout never firing). The brain's thinking now streams into the feed foldout in real time while it works, and never pollutes content/docs. Verified mid-run at 15s into a think.That empties the ticket as scoped + reviewed.
Closing summary
The feed went from token stream to a coding-agent-grade window into the studio, plus infrastructure it pulled in along the way. All deployed to :2027; running containers verified equal to latest images; suite 118 passed.
Chat/feed: streaming markdown + syntax highlighting · tool-call cards with MCP attribution and live spinners · the graph's todo list (
state.todoscontract) · node-provenance chips from stream metadata · live-streaming reasoning foldout (ChatDeepSeek brain client — base ChatOpenAI dropsreasoning_content) · steering mid-run (stop-and-fold, checkpointed state proven to survive) · token meter + tok/s.Games + brain sessions: top-bar game selector (thread
metadata.game= truth,scratchfor the unstamped, inline stub creation until #25's wizard) · per-game session picker with full history load on switch · birth + post-run stamping (aegra metadata-clobber race caught live).Swappable brains (grew out of this ticket):
brain/= llama-swap v242 fronting the pinned llama.cpp engine · curated 4-model roster audited for the 4× RTX 5000 (27B default @262k, 35B-A3B UD-Q8_K_XL, Coder-Next at the VRAM ceiling, gemma-4-31B QAT) · every brain verified on the metal · graphs honorconfigurable.model· brain bar: selector, loaded marker, swap progress, tok/s · topbar showsswapping brain · <model>through loads.Cut/moved: notifications (review call) · quote buttons (review call) · timeline strip (superseded by brain bar) · production-graph todos + interrupt steering → #11.
Contracts this ticket established:
state.todos,configurable.model,metadata.game, the[node]-or-metadata provenance rule,stream_usage=Trueon every brain client. phasewalk exercises all of it GPU-free.Watch item that remains: seats brain_idle's llama-swap fallback still wants a real seat cycle.