Maestro

Agents

An agent in Maestro is a reusable LLM-node configuration: system prompt, model, allowed-tool list. Every LLM node in every score references exactly one agent. The agent is the unit of “this is how the model thinks here.”

The dashboard’s /agents page lists every workspace agent. Clicking through to /agents/$agentId opens the editable detail page.

Why agents are first-class

Pre-Phase-5d Maestro embedded the system prompt + model + tools directly on the LLM-node row. Two LLM nodes with similar prompts duplicated the prompt verbatim. Editing the prompt meant clicking into each node individually.

Promoting agents to a workspace-level table changed three things:

  1. One agent, many nodes. A “draft cold opener” agent can power LLM nodes in five different scores. Edit the agent once; all five pick up the new prompt on their next runs.
  2. Versioning per agent, not per score. The agent has its own version integer. Bumping it doesn’t bump the score’s version — useful when tuning prompts without rewriting the graph.
  3. Edit-impact visibility. The agent detail page lists every score that references it, with node counts. Operators see the blast radius before saving.

Agents are also the cleanest answer to the question “what’s the actual unit of intelligence in Maestro?” The score is the workflow. The agent is the reasoning step. The skill is the deterministic capability.

Agent fields

FieldEditableNotes
nameyesDisplay name. Shown on the canvas card and the agents list.
slugyesURL-safe identifier. Auto-generated from name on creation; editable later. Unique per workspace.
descriptionyesFree-text “what this agent does” — surfaced on the detail page and in catalog rows.
modelyesAnthropic model id (claude-sonnet-4-6, claude-haiku-4-5-..., claude-opus-4-7). Empty = workspace default.
systemPromptyesWhat the LLM session sees before its first user message. Required (non-null).
allowedToolsyesArray of skill names the LLM may invoke as tools during reasoning. Empty / null = pure reasoning, no tool calls.
isTemplatedisplayTrue for seeded agents (the three extracted from hero-score LLM nodes during the v0.1.31 migration). The bootstrap re-seed policy respects this.
sourceAgentIddisplayWhen this agent was cloned from another, the original’s id. NULL for hand-built agents and seed templates.
versionautoBumps by exactly one on every successful save.

Where agents come from

Three creation paths:

  1. Seeded — the bootstrap script extracts every LLM node in the seeded hero scores into an agent row, deterministically named ag_<node_id>. Three agents ship: Shortlist, Draft opener, Classify intent. Seeded agents have is_template: true so the bootstrap re-seed policy can wipe + recreate them on a release that updates the seed prompts (operator edits to seeded agents are detected via updated_at > created_at and skipped — see issue #5 for the safety upgrade).

  2. Inline from the Composer — clicking ”+ New agent” in the LLM-node side panel’s agent picker creates a fresh agent row with placeholder name + prompt. Operator renames + tunes on the agent detail page after.

  3. From the Agents page/agents ”+ New agent” button opens a creation modal (name + system prompt; everything else tunable on the detail page).

Cloned scores always clone their referenced agents too, so the clone is self-contained. The original agents stay reusable.

Agent detail page

Lives at /agents/$agentId.

Form for the editable fields above. Dirty-state badge in the header; Save / Discard / ”+ delete” buttons.

“Used by” panel lists every score with at least one LLM node referencing this agent. Per-score: score name, count of llm nodes referencing the agent, click-through to the score’s canvas.

When you save an agent that has usedByScoreCount > 0, a warning appears: “Used by N scores. Saving will apply to every score’s next run.” Lets the operator confirm before propagating.

Delete is in a “Danger zone” section at the bottom. Server-side: DELETE /api/composer/agents/:id returns 409 with a structured payload listing the referencing scores when the agent is still in use. The operator detaches LLM nodes (or deletes the scores) first.

Tools the agent can call

allowedTools is an array of skill names. When an LLM node fires:

  1. The orchestrator looks up the agent referenced by score_nodes.agent_id.
  2. For each skill in allowedTools, every operation in that skill becomes available as an Anthropic tool the model can call.
  3. Tool calls dispatch through the same Registry.dispatch() path as deterministic nodes — same secret resolution, same cost capture.
  4. The model loops on tool calls until it emits an end_turn or hits the per-node max_inner_steps cap.

Empty / null allowedTools means pure reasoning — the model sees no tools, can only respond. Used by the seeded Shortlist and Classify intent agents (filter / classify based on input alone).

Cost surface

Each LLM node run captures tokens against the agent’s referenced model. The dashboard’s run detail shows tokens per step + USD computed via model_pricing lookup.

Switching an agent’s model from Sonnet to Haiku is the cheapest knob to pull when costs run high. The Composer’s “wired to” link in the side panel makes the experiment trivial — duplicate the agent (or just edit it), run, watch the cost drop.

  • Scores — graphs of nodes, where LLM nodes reference agents.
  • Composer — how the Composer’s LLM-node side panel surfaces agent picking.
  • Skills and tools — what “tools the agent can call” actually points at.
  • Orchestras — distinct concept: orchestras play scores; agents are inside scores.