0032 — Studio AI assistant (conversational, context-aware, action-taking)¶
Status: DRAFT — vision + architecture carve-out; not a full design. This reserves the
space and the seams for a large, phased feature; each phase gets its detailed design as it's
built.
Date: 2026-07-12
Source: ideation 2026-07-12 — a chat interface in the studio where the user talks to their
configured provider's AI, and it assists on each section — generating images, scripts,
text, and copy as part of the process. Matt: "this should probably be its own spec with how
complex it could get, but I want to carve out space for it now."
Depends on: the existing chat (internal/chatgen, pkg/studio/chat.go, Chat.svelte), the
generation cores (gencmd, internal/takes, social compose), the provider config
(providers.chat.provider), GTB pkg/chat (tool-calling capable). Relates: the IA in 0029
§8 (the Chat drawer is this assistant's home), the decomposition 0028 (chat gets a
chat.svelte.js session), MCP (0001/0002 §5 — the same command cores exposed as tools).
1. Goal & scope¶
A conversational assistant embedded in the studio that (a) is context-aware of the
current phase and selection, and (b) can both converse and act — draft/critique scripts
and text, generate card/cover images, suggest or trigger VO/music, draft per-platform social
copy — through the user's configured chat provider (claude | gemini | openai). It is the
in-UI counterpart to keryx's external MCP assistant, working the same command cores.
This spec's job is to carve out space, not to finish the design: state the vision, record the honest baseline, fix the architecture and seams so the feature can grow safely, phase it, and enumerate the (many) open questions. Detailed per-phase design follows.
Out of scope (here): the final tool set, the exact agency model, autonomous posting (never — §7), and provider-by-provider tool-calling parity (a Phase-gating question, §8).
2. Baseline — what exists today (honest)¶
internal/chatgenwires GTB's provider-abstracted chat client (chat.ChatClient; provider fromproviders.chat.provider= claude|gemini|openai, or inferred from the one present API key). GTB's client supports tool-calling (SetTools,tool_use) and streaming (StreamChat).pkg/studio/chat.goexposes a narrowChatterseam:Propose(ctx, system, user, onToken) → (reel.Storyboard, summary, error). The studio chat endpoint (handlers_chat.go, R-UI-5) takes a message + the current board + source and proposes a new storyboard (structured), streamed. System prompt: "keryx's authoring assistant for short vertical reels."Chat.svelterenders that single flow.
So today the assistant does exactly one thing — draft a storyboard in the Author phase. It can't assist per-section, can't take actions (generate media, edit a single card, draft copy), and isn't a general multi-turn conversation with tools. Everything below generalises this one seam.
3. Vision¶
The Chat drawer (0029 §8) becomes a phase-aware assistant:
- Author: draft/refine the storyboard and per-card narration; critique pacing; suggest an accent word; "make card 3 punchier."
- Produce: "generate an image for card 2 in the theme", "re-roll the VO for line 4", "the music's too busy — regenerate a calmer bed" — proposing/triggering the existing generation cores.
- Publish: "draft an Instagram caption from this reel", "tighten the LinkedIn copy", "what hashtags fit?" — drafting per-platform copy.
It converses (answers, critiques, suggests) and acts (produces artefacts through keryx's own cores), with the current phase + selection as context, and every paid/side-effecting action gated by explicit user confirmation (§7).
4. Architecture — the seams to reserve now¶
Five seams. Reserving them now (even before the later phases build out) is the point of this spec.
- Provider — reuse as-is. The config-driven GTB chat client (
providers.chat.provider). No change; the assistant is provider-neutral by construction. - Assistant seam (generalise
Chatter). Replace the board-onlyProposewith a generalAssistant: multi-turnConverse(ctx, turn, context, onEvent)that streams text and tool-call events. The current storyboard proposer becomes one tool (propose_ storyboard) within it — Phase 0 preserved, not discarded. - Action-tool registry. Define studio tools as GTB
chat.Tools whose handlers call keryx's existing cores —gencmd.GenerateInto(card/cover/VO/music),takes.Select*, storyboard edits, social compose. These are the same cores keryx's MCP wraps, so the in-UI assistant and the external MCP assistant stay consistent (and post/approve/auth stay excluded — §7). One registry, resolved per phase (Author tools ≠ Publish tools). - Context provider. A seam that assembles the per-turn context — current phase, selected card/line, the board, the source post, the theme, asset/selection state, and quota/cost — injected as system/context so the model answers about this reel, not in the abstract.
- Action gating + confirmation. Any paid (generation spend) or side-effecting
action is a proposal the user confirms in the UI before keryx executes; cost is
disclosed first (reuse the
0016estimate +QuotaReporter). Posting is never autonomous (§7). Read/draft actions (suggest copy, critique) need no gate.
UI (the 0029 §8 drawer, phase-aware): messages interleave the model's text with action
proposals (a confirm button + cost) and results (an image thumbnail, an audio take, a
board/copy diff). Tool-call progress surfaces inline ("generating card 2 image…").
5. Phasing (deliberately incremental — this can get complex)¶
- Phase 0 (exists): storyboard proposer (Author). Fold into the new
Assistantseam as a tool; no regression. - Phase 1 — conversational assist (no actions): per-phase, context-aware text answers/critique/suggestions on the current card/copy. Streamed. Lowest risk; immediately useful; establishes the context seam.
- Phase 2 — proposed + confirmed single actions: the assistant proposes one concrete action (generate this image / re-roll this VO / draft this caption) as a confirmable button; on confirm, keryx runs the existing core and the result lands in the flow. Establishes the tool registry + gating.
- Phase 3 — tool-calling (light agency): the model chains a few tools to satisfy a
multi-step ask ("make card 3 punchier and regenerate its image"), with per-action
confirmation for spend/side-effects. Uses GTB's
tool_useloop. - Phase 4+ — richer: multimodal input (attach a reference image), provider failover, conversation memory/history persistence, "explain what you changed" diffs.
6. Reserve-now (what lands even before Phases 2+)¶
To avoid a rewrite later, the early work should already: generalise Chatter → Assistant
(multi-turn + event stream), stand up the context provider seam, and define the
action-tool registry interface (even if Phase 1 registers zero acting tools). The
storyboard proposer keeps working throughout. The 0028 decomposition should give chat its
own chat.svelte.js session hosting this.
7. Safety, cost, and agency¶
- Never autonomous posting. The assistant may draft copy and propose a post, but
post/approve/authare never executable tools — mirroring the MCP exclusion (R-MCP-2). Publishing stays a human action on the CLI/Publish surface. - Spend is always confirmed + disclosed. No generation runs without the user OK-ing the
estimated cost (reuse
0016cost +QuotaReporter). Optional per-session spend cap. - Actions are reversible / take-based. Generation lands as a candidate take (the existing model), never overwriting a selection without a pick — so an assistant action is as safe as a manual one.
- Provider keys use the existing config/keychain path; no new secret surface.
8. Open questions (many — reflects the complexity)¶
- Q1 — provider tool-calling parity. GTB's Claude client supports tools; verify/gate on
Gemini + OpenAI coverage in GTB
pkg/chat. Phase 3 may be Claude-first, others text-only until parity. - Q2 — agency model. Propose-only (user clicks every action) vs light autonomous chains with per-action confirm. Lean: propose-only through Phase 2, light chains in Phase 3.
- Q3 — reuse MCP tool definitions directly, or a parallel studio registry? Same cores either way; decide whether the assistant literally consumes the MCP tool manifest or a hand-picked studio subset.
- Q4 — context/token budget. How much board/source to inject per turn; summarise vs full; cost of a long conversation.
- Q5 — confirmation UX + streaming tool-calls. How proposals/results render inline; how a mid-stream tool call is surfaced and cancelled.
- Q6 — per-phase tool sets + when the assistant switches context (follows the active tab? explicit?).
- Q7 — history/memory. Persist a conversation per reel (stateless-tool tension — 0001 §3.2), or ephemeral per session?
- Q8 — cost caps + abuse. Per-session/most-per-day spend guard for an over-eager loop.
- Q9 — how much is keryx-specific vs a GTB primitive? A generalised "studio assistant over tool-wrapped cores" could be a GTB pattern (krites would want it too) — decide the keryx/GTB split, like the local-CA feature.
9. Testing / DoD (per phase)¶
Failing test → code → green just ci. Fakes for the chat client (no LLM/network) and each
tool handler (no spend); assert: context assembly per phase, the Assistant streams
text+tool events, confirmation gating blocks unconfirmed paid/side-effecting actions, posting
tools are absent, the storyboard-proposer parity holds. A godog scenario per phase (assist →
propose → confirm → result via fakes; the real provider path stays INT_TEST=1-gated).
Frontend: @testing-library/svelte over the drawer + the 0028 Playwright harness for the
assist→confirm→result flow (mocked API). Docs: a studio "AI assistant" concepts/how-to
page per phase.