mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-07-12 21:02:17 +02:00
feat(x): teach copilot when to spawn sub-agents; fence shared surfaces
The spawn-agent tool shipped with mechanics but no judgment layer — the only guidance was the tool description. This adds the ambient decision heuristics and closes a child-profile hole. - Copilot system prompt gains a "Sub-Agents (parallel & heavy work)" section (same strong/anti signal structure as Background Tasks): the organizing principle is context hygiene — a sub-agent's reads and fetches never enter the main conversation, only its distilled answer. Research-shaped requests (catch-me-up, dig-into, meeting prep) now route through sub-agents by default, with copilot as synthesizer. Anti-signals: single quick lookups, journeys-as-answer, anything needing mid-task user input, driving shared surfaces. - Background-task agent gets a matching (shorter) note — children have their own model-call budgets, so a bg-task covers more ground per run by fanning out. - The inline default child profile now also excludes app-navigation and browser-control: both drive shared visible surfaces (the UI the user is watching; the single embedded browser pane), which headless or parallel children would corrupt, not just clutter. Still available via explicit tools selection. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
3822bda1f7
commit
f546d1ad59
4 changed files with 37 additions and 1 deletions
|
|
@ -149,6 +149,12 @@ ${codeModeEnabled
|
|||
|
||||
*Medium signals (load the skill, answer the one-off, then offer):* one-off questions about decaying info ("what's the weather?", "top HN stories?"), "what's the latest on X / catch me up on X / any updates on X" about a person, company, project, or topic, recurring artifacts ("morning briefing", "weekly review", "Acme deal dashboard"). **Heuristic:** if you reach for \`web-search\` or a news tool to answer a recurring question, the answer is the kind of thing a bg-task would refresh on a schedule.
|
||||
|
||||
**Sub-Agents (parallel & heavy work):** The \`spawn-agent\` tool runs a sub-agent in its own isolated, headless thread and returns only its final answer — the sub-agent's tool calls, page fetches, and file reads never enter this conversation. Use it to keep this context clean: a sub-agent can read twenty notes or six web pages and hand you back one paragraph. Issue several spawn-agent calls in ONE response to run them in parallel.
|
||||
|
||||
*Strong signals (spawn without asking):* the request decomposes into independent lookups ("prep me on these 3 attendees", "compare these vendors") — one sub-agent each; the task needs reading MANY files, notes, pages, or a long document but the user wants a summary ("what do we know about Acme", "summarize this 40-page PDF"); open-ended web research where you don't know the sources upfront. **Research-shaped requests ("catch me up on X", "dig into Y", meeting prep) should route through sub-agents by default** — you act as the synthesizer, weaving their findings together with what you know from memory.
|
||||
|
||||
*Do NOT spawn for:* single quick lookups (one file read, one search — just do it); tasks where the user wants to see the intermediate detail, not a distillation; anything needing user input mid-way (sub-agents run headless and cannot ask questions); driving the app UI or the embedded browser (those are shared surfaces you control, not sub-agents). Remember each sub-agent starts with ZERO context — its \`task\` must be fully self-contained (names, dates, constraints, expected output format).
|
||||
|
||||
**Rowboat Apps:** When users ask you to build/make/create an *app* or *dashboard* ("build me an app that…", "make a dashboard for…"), load the \`apps\` skill FIRST — it defines the app contract (manifest, dist/, Host API) and the build flow. For ambiguous requests that could be a one-off answer ("show me my open PRs"), the skill's intent gate says to confirm before building. Do not hand-roll app folders without the skill.
|
||||
|
||||
**Live Notes:** If the user explicitly says "live note" or "live-note", load the \`live-note\` skill. Otherwise, do not propose live notes — prefer the \`background-task\` skill for anything recurring.
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ Only available when the run message contains a **"# Coding task"** block (the ta
|
|||
- Group related items, then call \`launch-code-task\` once per group (\`taskSlug\` is your own slug). It runs full-auto in an isolated worktree and **owns the \`## Code Sessions\` section of \`index.md\`** — never edit those rows yourself. Write a complete, self-contained \`prompt\`: the coding agent has no other context and no human to ask.
|
||||
- If nothing is actionable, launch nothing and say so in your summary.
|
||||
|
||||
# Sub-agents
|
||||
|
||||
The \`spawn-agent\` tool runs a sub-agent in its own isolated turn and returns only its final answer — its intermediate reads and fetches never enter your context, and it has its own model-call budget separate from yours. Spawn when your instructions require sweeping many sources (several sites, many notes, a long document) and you only need the conclusions, or when the work splits into independent lookups — issue several spawn-agent calls in ONE message to run them in parallel, then synthesize. Do not spawn for single quick lookups. Each sub-agent starts with zero context: its \`task\` must be fully self-contained.
|
||||
|
||||
# Triggers
|
||||
|
||||
The run message tells you which trigger fired and how to interpret it:
|
||||
|
|
|
|||
|
|
@ -30,6 +30,16 @@ const fakeBuiltins = {
|
|||
inputSchema: z.object({ command: z.string() }),
|
||||
execute: async () => null,
|
||||
},
|
||||
"app-navigation": {
|
||||
description: "Drive the app UI",
|
||||
inputSchema: z.object({}),
|
||||
execute: async () => null,
|
||||
},
|
||||
"browser-control": {
|
||||
description: "Drive the embedded browser",
|
||||
inputSchema: z.object({}),
|
||||
execute: async () => null,
|
||||
},
|
||||
} as unknown as typeof BuiltinTools;
|
||||
|
||||
function makeResolver() {
|
||||
|
|
@ -97,5 +107,16 @@ describe("InlineAgentResolver", () => {
|
|||
// Excluded by policy, not by absence:
|
||||
expect(names).not.toContain("executeCommand");
|
||||
expect(names).not.toContain("spawn-agent");
|
||||
// Shared visible surfaces: a headless child must not drive the UI
|
||||
// the user is watching or the single embedded browser pane.
|
||||
expect(names).not.toContain("app-navigation");
|
||||
expect(names).not.toContain("browser-control");
|
||||
});
|
||||
|
||||
it("shared-surface tools remain available via explicit selection", async () => {
|
||||
const resolved = await makeResolver().resolve({
|
||||
inline: { name: "a", instructions: "x", tools: ["browser-control"] },
|
||||
});
|
||||
expect(resolved.tools.map((t) => t.name)).toEqual(["browser-control"]);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,7 +15,10 @@ import { builtinToolDescriptor } from "./builtin-descriptors.js";
|
|||
// except the ones that make no sense headlessly or in a child. Mirrors the
|
||||
// background-task agent's exclusions (no interactive approval surface) plus
|
||||
// the task/session launchers — an ephemeral child should do its own work,
|
||||
// not schedule more.
|
||||
// not schedule more — and the shared visible surfaces: a headless child
|
||||
// navigating the UI the user is looking at, or parallel children fighting
|
||||
// over the one embedded browser pane, is broken behavior, not just noise.
|
||||
// All remain available via an explicit `tools` selection.
|
||||
const DEFAULT_PROFILE_EXCLUDED = new Set([
|
||||
"executeCommand", // headless: no interactive approval
|
||||
"code_agent_run", // headless: needs interactive permission UI
|
||||
|
|
@ -24,6 +27,8 @@ const DEFAULT_PROFILE_EXCLUDED = new Set([
|
|||
"create-background-task",
|
||||
"patch-background-task",
|
||||
"run-live-note-agent",
|
||||
"app-navigation", // shared surface: drives the UI the user is watching
|
||||
"browser-control", // shared surface: the single embedded browser pane
|
||||
SPAWN_AGENT_TOOL_NAME,
|
||||
]);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue