/add-worker-agent chatmode¶
Partner-facing intro
What it is: Add a new specialist worker agent to an existing scenario by invoking scripts/scaffold-agent.py, then finishing the three manual follow-ups the scaffolder cannot do.
When to load it: In VS Code with GitHub Copilot Chat installed, after cloning this template repo. Type /add-worker-agent in the chat input — Copilot picks up the mode from .github/chatmodes/ automatically. (Other LLM IDEs that read .github/chatmodes/ work the same way.)
What to ask: Open-ended task questions in the area above; the chatmode walks you through the inputs it needs and produces the expected artifacts.
The full system prompt is reproduced below for transparency. You don't need to read it to use the chatmode — Copilot loads it for you when you invoke the command.
System prompt (full text)
/add-worker-agent — scaffold a new worker via scripts/scaffold-agent.py¶
Use this when the brief or a follow-on requirement introduces a capability no current worker covers (e.g., "pricing calc", "risk scoring", "invoice classification").
Do not hand-scaffold. scripts/scaffold-agent.py is the single supported entry point. It edits the declarative WORKERS: dict[str, WorkerSpec] registry in src/scenarios/<scenario>/workflow.py — that dict is the only attachment point the supervisor DAG reads. Hand edits whose shape doesn't match what the scaffolder expects flip the file to "no longer scaffold-managed" and break future automation.
Preconditions¶
- The solution uses the
supervisor-routingpattern (checkaccelerator.yaml.solution.pattern). - The target scenario exists under
src/scenarios/<scenario>/and itsworkflow.pydeclaresWORKERS: dict[str, WorkerSpec] = { ... }in the canonical single-form shape. (The flagshipsales-researchscenario is the reference.) - The new worker has a clear, one-sentence capability. If you can't write that sentence, push back to clarify — don't scaffold fuzziness.
Inputs to gather¶
- Agent id (lowercase_with_underscores, e.g.
pricing_calculator,risk_scoring) - Scenario id (lowercase-with-hyphens — matches
accelerator.yaml.scenario.id, e.g.sales-research) - One-sentence capability (used by the supervisor router; quoted verbatim into the YAML snippet)
- Upstream workers it depends on (comma-separated list of existing worker ids the DAG must schedule first)
- Whether it's optional (the DAG can skip it and still produce a valid answer)
- Foundry agent name — defaults to
accel-<scenario-id>-<agent-id-with-underscores-to-hyphens>(e.g.risk_scoring→accel-sales-research-risk-scoring). Ensure the agent exists in the Foundry portal with system instructions configured there — never in code.
Invoke the scaffolder¶
# <agent_id> e.g., risk_scoring; <scenario-id> e.g., sales-research
python scripts/scaffold-agent.py <agent_id> \
--scenario <scenario-id> \
--capability "<one-sentence capability>" \
--depends-on <upstream_a>,<upstream_b> \
[--optional]
The scaffolder will:
- Create src/scenarios/<scenario>/agents/<agent_id>/{__init__,prompt,transform,validate}.py with working three-layer stubs.
- Patch src/scenarios/<scenario>/agents/__init__.py — add the import and extend __all__.
- Patch src/scenarios/<scenario>/workflow.py — add the import, insert a _build_input_<agent_id> helper immediately above WORKERS, and insert a new "<agent_id>": WorkerSpec(...) entry immediately before the dict's closing }.
- Write a Foundry agent spec stub at docs/agent-specs/<foundry-agent-name>.md.
- Print the YAML snippet you must paste into accelerator.yaml -> scenario.agents[].
The scaffolder is transactional: it snapshots workflow.py and agents/__init__.py before any write and rolls everything back (including deleting newly created files) on any failure, including a post-write ast.parse syntax check. It is also re-run safe: a second run with the same <agent_id> exits non-zero without changing anything.
Three manual follow-ups¶
The scaffolder cannot do these; you must.
- Paste the printed YAML snippet into
accelerator.yaml -> scenario.agents[]. The lint ruleagents_registered_in_manifest_match_codeenforces parity between the manifest and theWORKERSdict. - Add the agent id to at least one golden case's
exercisesarray inevals/quality/golden_cases.jsonl. Example:"exercises": ["account_planner", "<new_agent_id>"]. The blocking lint ruleagent_has_golden_caserejects any registered worker that no golden case exercises. A separate rulegolden_cases_exercises_validchecks the ids resolve. - Tune the
_build_input_<agent_id>stub inworkflow.pyif the default (pass each declared dependency's output plusrequest) isn't the right payload. The TODO comment marks the spot.
Tools¶
If the agent needs a side-effect tool (writes to a system, sends email/webhook, destructive action), run /add-tool for each separately — never mix tool creation with worker scaffolding, and ensure the tool flows through src/accelerator_baseline/hitl.py.
Validate¶
python scripts/accelerator-lint.py # must be 0 blocking / 0 warning
python -c "from src.main import app; print('OK')"
If lint reports agent_has_golden_case or agents_registered_in_manifest_match_code, revisit the two manual follow-ups above. If the scaffolder reports workflow.py is no longer scaffold-managed, someone has hand-edited the from .agents import (...) tuple, the WORKERS dict shape, or the close-brace line; restore the canonical shape (see the flagship sales_research/workflow.py) before retrying.
Verify against acceptance¶
A new worker changes the supervisor's routing surface. Re-run the full acceptance chain against your deployed dev environment to confirm quality and safety still hold:
python evals/quality/run.py --api-url <your-api-url>
python evals/redteam/run.py --api-url <your-api-url>
python scripts/enforce-acceptance.py
enforce-acceptance.py reports pass/fail against every threshold in accelerator.yaml.acceptance. If quality regresses on a worker the new agent shouldn't have touched, the supervisor is mis-routing — tighten the new agent's one-sentence capability or its _build_input_<agent_id> payload. The same chain runs in CI and will block merge.
Guardrails¶
- Never write the Foundry system prompt in code — it lives in the portal.
- Never bypass the scaffolder to "just quickly add" a worker. The declarative
WORKERSregistry is the contract every future tool (scheduler, telemetry, lints, docs) reads. - The supervisor is always-invoked; do not list it in
depends_onor golden-caseexercises.