# TypeAgent Studio — `studio` Agent Plan

> **Status:** Draft. Proposes a new first-party TypeAgent agent (`studio`) that
> exposes the Studio authoring/tuning/validation loop as dispatchable actions,
> making it drivable by an AI orchestrator (and conversationally) — not only by
> the VS Code extension UI.
>
> **Reads with:** [`USER-STORY.md`](./USER-STORY.md) (interaction modes),
> [`STATUS.md`](./STATUS.md) (what's built; agent-drivability direction),
> [`DESIGN.md`](./DESIGN.md) (architecture).

## 1. Why a `studio` agent

The Studio capabilities (sandbox lifecycle, health, collision scan, corpus
federation, replay) already exist as **VS Code-free typed primitives** in
`@typeagent/core` and the runtime that wraps them. Today they're consumed only
**in-process by the extension host** — a human-driven surface.

A TypeAgent agent is the natural, low-cost way to add the **agent-driven** and
**hybrid** surfaces (USER-STORY §5):

- TypeAgent agents are **automatically exposed over MCP** and via
  `list_commands` (per the onboarding agent's `AGENTS.md`), so an AI
  orchestrator (Claude, Copilot, or a TypeAgent agent) can discover and call
  Studio actions with no new transport code.
- It is **conversational** through the dispatcher (`@studio scan player for
collisions`), reusing the platform's existing routing.
- It reuses the exact same core primitives, so the extension UI and the agent
  stay two **thin presenters over one engine** — the design principle in
  STATUS.

The `onboarding` agent already proves this shape end-to-end (it is "itself a
TypeAgent agent, so its actions are available to AI orchestrators"). `studio`
is the analogous agent for the **tune → validate** half of the loop, where
`onboarding` owns the **author** half.

## 2. How it fits the existing pieces

```
          authoring loop (USER-STORY §1)
  ┌────────────┬─────────────────────────┬──────────────┐
  │  author    │  tune schema / grammar  │  validate    │
  └────────────┴─────────────────────────┴──────────────┘
        │                  │                     │
   onboarding agent   studio agent + extension   studio agent + extension
   (exists)           (new)        (exists)      (new)        (exists)

         ┌───────────────────────────────────────────┐
         │            @typeagent/core (engine)        │
         │  sandbox · health · corpus · collisions ·  │
         │  events · feedback · replay · onboarding   │
         └───────────────────────────────────────────┘
              ▲                                  ▲
   thin presenter (human)              thin presenter (agent/MCP)
   typeagent-studio (VS Code)          studio agent (dispatchable actions)
```

- **`onboarding` agent** — owns J1 (stand up a new agent). Unchanged.
- **`typeagent-studio` extension** — the human UI. Unchanged in principle; it
  keeps consuming the core runtime directly.
- **`studio` agent (new)** — exposes the same core primitives as typed actions
  for agent/MCP/conversational consumption.

## 3. Action surface — the full vision

The agent surface is **layered by abstraction**, not a flat list of command
wrappers. Three tiers:

- **Tier 1 — Primitives:** 1:1 with a core function; deterministic or
  command-shaped; typed result is the agent's data.
- **Tier 2 — Composites:** a few primitives sequenced into a useful unit
  (e.g. "load → run an utterance → return the resolved action + trace").
- **Tier 3 — Goal-oriented:** an LLM-planned loop that pursues an objective
  ("make these utterances map without regressing the 👍 set"), emitting
  structured progress events and pausing at approval checkpoints.

Tier 1 is what makes the loop _scriptable_; Tier 3 is what makes it
_agent-driven_. The extension UI mostly needs Tier 1; an autonomous or hybrid
agent lives in Tiers 2–3.

Every action returns a **typed, documented result** and — for any mutation —
supports a **`dryRun`** that returns the proposed diff/plan without applying it.
Agents and rules are addressed by **stable ids** (agent name, action type name,
grammar rule id) so calls are idempotent and composable.

### A. Inspect (read; autonomous-safe)

| Action                     | Returns                                                                                              | Building block                                  |
| -------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `ListAgents`               | name, emoji, loaded state, health badge, schema/grammar hashes                                       | `listAvailableAgents` + health                  |
| `DescribeAgent`            | full picture: actions, grammar rule count, corpus size, recent feedback, health findings, collisions | composite                                       |
| `GetSchema` / `GetGrammar` | the artifact text + parsed structure (actions / rules)                                               | `actionSchema`, `grammarTools/core.loadGrammar` |
| `ListActions`              | the typed action surface of an agent (names, params, descriptions)                                   | `actionSchema` parser                           |
| `GetCoverage`              | per-utterance: matched action vs unmatched, grouped                                                  | `grammarTools/core.computeCoverage`             |
| `SearchCorpus`             | corpus entries filtered by source / rating / category / text                                         | `CorpusService.list`                            |
| `ListCollisions`           | cross-schema overlaps with participants + grammar source locations                                   | collision scanner                               |
| `GetTrace`                 | full dispatch tree for a `requestId` (grammar match → cache → translate → action → result)           | structured event stream (J5)                    |
| `QueryEvents`              | filtered slice of the structured event stream                                                        | `events`                                        |

### B. Author / edit (mutating; approval or `dryRun`)

| Action                                      | Returns / effect                                            | Building block                                      |
| ------------------------------------------- | ----------------------------------------------------------- | --------------------------------------------------- |
| `ProposeActionsFromUtterances`              | suggested action shapes for un-typeable utterances (J2)     | `schemaAuthor`                                      |
| `AddAction` / `EditAction` / `RemoveAction` | schema edit (file diff)                                     | `actionSchema` + edit                               |
| `ProposeGrammarVariations`                  | candidate phrasings for an intent/action (J3)               | `schemaAuthor`, `examples/schemaStudio @variations` |
| `AddGrammarRule` / `EditGrammarRule`        | `.agr` edit (file diff)                                     | `.agr` edit                                         |
| `GenerateGrammarFromSchema`                 | a `.agr` draft from the schema + phrases                    | `SchemaToGrammarGenerator`, `@fromSchema`           |
| `BuildAgent` / `CompileGrammar`             | `asc`/`agc` build result (+ errors)                         | build tasks                                         |
| `ScaffoldAgent`                             | delegate to the **`onboarding`** agent (don't duplicate J1) | `onboarding`                                        |

### C. Corpus management (mutating; approval for writes)

| Action                          | Effect                                                        | Building block                    |
| ------------------------------- | ------------------------------------------------------------- | --------------------------------- |
| `SeedInRepoCorpus`              | create `corpus/<agent>.utterances.jsonl`                      | `CorpusService.seedInRepoCorpus`  |
| `AddExternalCorpus`             | register a JSONL source in `.typeagent/studio.json`           | `CorpusService.addExternalSource` |
| `CaptureSession`                | turn a sandbox session's utterances into capture entries      | `CorpusService.append`            |
| `PromoteCaptures`               | move captures → in-repo seed                                  | `CorpusService.promote`           |
| `ImportCorpus` / `ExportCorpus` | JSONL interchange (`@feedback export` format)                 | `CorpusService` + feedback        |
| `ProposeFeedbackLabels`         | suggest 👍/👎 + category (human confirms — labels stay human) | feedback (assistive only)         |

### D. Run / try (sandbox execution; the "does it work?" loop)

| Action                                            | Returns                                                                  | Building block        |
| ------------------------------------------------- | ------------------------------------------------------------------------ | --------------------- |
| `StartSandbox` / `StopSandbox` / `RestartSandbox` | `SandboxStatus`                                                          | `SandboxManager`      |
| `LoadAgent` / `UnloadAgent`                       | `SandboxStatus`                                                          | `SandboxManager`      |
| `RunUtterance`                                    | resolved action + cache hit/miss + result + `requestId` (for `GetTrace`) | dispatcher in sandbox |
| `RunUtterances`                                   | batch of the above (drives quick coverage probes)                        | dispatcher in sandbox |

### E. Validate / regress (the headline; read-only analysis)

| Action              | Returns                                                                              | Building block                           |
| ------------------- | ------------------------------------------------------------------------------------ | ---------------------------------------- |
| `ReplayCorpus`      | `ActionDelta[]` + summary (vA vs vB over the federated corpus)                       | `replayCorpus`                           |
| `DetectRegressions` | red/green verdict per delta by policy (changed action where prior 👍, or current 👎) | composite over `ReplayCorpus` + feedback |
| `DiffGrammars`      | structural grammar diff                                                              | `grammarTools/core.diffGrammars`         |
| `CoverageDelta`     | coverage before/after                                                                | `computeCoverage`                        |
| `CollisionsDelta`   | collisions introduced/removed by a change                                            | collision scanner                        |
| `HealthGate`        | pass/fail + findings (the ship gate)                                                 | `FileHealthService`                      |
| `ScanCollisions`    | full cross-agent overlap report                                                      | collision scanner                        |

### F. Orchestrate (Tier 3; goal-oriented, LLM-planned, checkpointed)

These are the actions that make the agent _autonomous_; each is a loop over A–E
that emits structured progress and stops at an approval boundary.

| Action                               | Goal                                                                                                    |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------- |
| `ImproveCoverage(agent, utterances)` | add grammar/schema until the target utterances map; re-validate; report what changed                    |
| `FixRegression(agent, deltaId)`      | propose + apply a schema/grammar fix for one red replay row; re-replay; report                          |
| `TuneAgent(agent, goal)`             | a guided improve→validate loop toward a stated objective, surfacing each proposed change for approval   |
| `ValidateChange(agent, vA, vB)`      | run all of tier E and return a single Impact-Report-shaped verdict (the same shape the webview renders) |
| `ReviewAgent(agent)`                 | one-shot audit: health + collisions + coverage gaps + un-typeable utterances, as an actionable report   |

### Mapping to journeys & modes

- **J1 (author)** → delegate to `onboarding`; `studio` picks up at install.
- **J2 (schema)** → B (`ProposeActionsFromUtterances`, `AddAction`) + A (`GetCoverage`).
- **J3 (grammar)** → B (`ProposeGrammarVariations`, `AddGrammarRule`) + D (`RunUtterances`).
- **J4 (regression, headline)** → E (`ReplayCorpus`, `DetectRegressions`, `ValidateChange`).
- **J5 (trace)** → A (`GetTrace`).
- **J6 (observe)** → A (`QueryEvents`).
- **Mode A (human)** uses Tiers 1–2 via the UI. **Mode B (agent)** uses Tier 3
  end-to-end. **Mode C (hybrid)** runs Tier 3 with `dryRun` + approval
  checkpoints so the human confirms each mutation.

### Build ordering (kept honest)

Ship **A (Inspect)** first — fully agent-drivable today, zero mutation risk.
Then **D (Run/try)** and **C (Corpus)**, then **E (Validate)** once real
two-version replay lands, then **B (Author/edit)** and finally **F
(Orchestrate)**, which composes everything. The phasing in §7 reflects this.

## 4. Architecture

- **Reuse `@typeagent/core` directly.** The agent's handler constructs the core
  services (`InMemorySandboxManager` + `createRepoAgentLoader`,
  `FileHealthService`, `FileCorpusService`, `InProcessCollisionService`,
  `createRepoGrammarScanner`, `replayCorpus`) — exactly what the extension's
  runtime does, minus the VS Code context.
- **Factor a headless runtime.** The extension's `studioRuntimeCore` already
  contains this orchestration but is shaped around a VS Code-ish context
  (`workspaceState`, `globalStorageFsPath`). Extract the engine wiring into a
  context-agnostic core runtime that **both** the extension and the `studio`
  agent consume. (This is the "split `studioRuntimeCore`" item in STATUS,
  now with a second consumer justifying it.)
- **Repo root / search paths.** The agent resolves its repo root the same way
  the extension does (`resolveRepoRoot` + the planned `agentSearchPaths`), so
  both surfaces see the same agents.
- **State / profile.** Follow the onboarding agent's convention
  (`~/.typeagent/studio/...`) for any persisted state (e.g. replay run history),
  via an `AGENTS.md`-style `workspace.ts`.

## 5. Human-in-the-loop / approval boundary (hybrid mode)

Mirror onboarding's `pending → in-progress → approved` checkpoint model for any
**mutating** or **judgment** step:

- **Autonomous-safe** (no approval): all of group **A (Inspect)**, group **E
  (Validate)** read-only analysis (`ReplayCorpus`, `ScanCollisions`,
  `HealthGate`), and `RunUtterance` (executes in the throwaway sandbox only).
- **Needs approval / `dryRun` first**: group **C** writes (`SeedInRepoCorpus`,
  `AddExternalCorpus`, `PromoteCaptures` — already guarded in the extension by a
  confirmation) and all of group **B (Author/edit)** (schema/grammar edits),
  plus anything that commits. The agent proposes a diff; a human (or an
  allow-listed policy) approves.
- **Tier 3 orchestration** runs the whole loop but pauses at each group-B/C
  mutation for the same checkpoint, so `TuneAgent` is safe to invoke
  autonomously — it can't write without sign-off unless explicitly allow-listed.
- **Feedback labels stay human.** The agent may _propose_ labels
  (`ProposeFeedbackLabels`) and a regression verdict from `ReplayCorpus` deltas,
  but authentic 👍/👎 is the human anchor.

## 6. Agent structure (follows the onboarding template)

```
packages/agents/studio/src/
  studioManifest.json        ← manifest; emoji 🔌; declares sub-action groups
  studioSchema.ts            ← top-level coordination actions
  studioSchema.agr           ← grammar for top-level actions
  studioActionHandler.ts     ← instantiate(); routes by actionName
  lib/
    runtime.ts               ← constructs the headless core runtime
    workspace.ts             ← persisted state under ~/.typeagent/studio/
  sandbox/  health/  collisions/  corpus/  replay/   ← per-group schema/grammar/handler
```

Registration: add `"studio": { "name": "studio-agent" }` to
`packages/defaultAgentProvider/data/config.json`. Package declares the standard
`./agent/manifest` + `./agent/handlers` exports. MCP exposure is then automatic.

## 7. Phasing

Ordered to ship the most agent-drivable, lowest-risk surface first; each phase
maps to the §3 capability groups.

- **S0 — headless runtime extraction.** Lift the engine wiring out of the
  extension's `studioRuntimeCore` into a context-agnostic runtime in
  `@typeagent/core` (or a small shared package); the extension switches to it.
  No behavior change; unblocks a second consumer.
- **S1 — Inspect (group A).** `ListAgents`, `DescribeAgent`, `GetSchema`/
  `GetGrammar`, `ListActions`, `GetCoverage`, `SearchCorpus`, `ListCollisions`,
  `QueryEvents`. Read-only; proves MCP/conversational drivability with zero
  mutation risk. **This is the fast proof-of-concept for modes B/C.**
- **S2 — Run/try + Corpus (groups D, C).** Sandbox lifecycle, `RunUtterance(s)`,
  corpus seed/add/capture/promote (writes behind the approval checkpoint).
- **S3 — Validate (group E).** `ScanCollisions`, `HealthGate`, `DiffGrammars`,
  `CoverageDelta`; then `ReplayCorpus` / `DetectRegressions` / `ValidateChange`
  once the real two-version replay lands — the headline agent actions and the
  shared `ActionDelta[]` contract the Impact Report webview also renders.
- **S4 — Author/edit (group B).** `Propose*`, `Add/Edit*`, `GenerateGrammarFromSchema`,
  build actions — the mutating authoring surface, always `dryRun`-able.
- **S5 — Orchestrate (group F).** `ImproveCoverage`, `FixRegression`,
  `TuneAgent`, `ValidateChange`, `ReviewAgent` — the goal-oriented loops that
  compose S1–S4 and turn the agent from scriptable into autonomous.

## 8. Open questions

- **One agent or two?** Fold tune+validate into a single `studio` agent (simpler
  discovery) vs. separate `studio-tune` / `studio-validate` agents (smaller
  surfaces). Leaning single agent with sub-action groups, like onboarding.
- **Sandbox sharing.** Should the `studio` agent and the extension share one
  sandbox set, or run isolated ones? Sharing enables true hybrid (human watches
  in the UI what the agent does); isolation is simpler. Likely: shared, keyed by
  repo root + sandbox id.
- **Where the driving orchestrator runs** (in-editor Copilot, external MCP
  client, CI) — affects auth and which actions are allow-listed autonomous.
- **Relationship to a possible "Studio as MCP host"** (STATUS open decision):
  the `studio` agent makes Studio an MCP _provider_ via the dispatcher already;
  a dedicated MCP host is only needed if we want to bypass the dispatcher.

## 9. Why this is low-risk, high-leverage

- It adds **no new transport** — rides the dispatcher + existing MCP exposure.
- It reuses **already-tested** core primitives; the new code is thin action
  routing plus schema/grammar.
- It makes the **agent-driven and hybrid interaction modes real** without
  blocking on the Impact Report webview — the read-only actions (S1) are
  shippable immediately and are the most naturally agent-drivable surface.
