Use this file for human-readable structure and formatting guidance after you know what the agent should do. These patterns shape the JSON that drives the generated CLI tool.
Keep top-level keys in this order:
versioninputs- optional
action_execution - optional
runtime_vars agent_schemaactions
Keep each action in this order:
namelogicrun
Keep each run step in this order:
kind- required kind-specific fields
whenfailure_modeoutput_variablestatus_variableerror_variable
Keep input objects easy to scan:
- named input objects:
name, thentype, then the value field such astext,url, orpath - unnamed literal inputs:
type, then the value field
- Use short, behavior-based action names such as
send_summaryornotify_on_failure. - Use explicit captured-variable names such as
child_statusorreport_error. - Do not overload one variable name for multiple meanings.
Choose one of these intentionally:
- baked inputs
- keep instructions and fixed local paths in the JSON
inputsarray
- keep instructions and fixed local paths in the JSON
- runtime inputs
- let the caller provide values such as
--input-text,--input-file,--input-url, or--input-image
- let the caller provide values such as
Important rule:
- If runtime input flags are used without
--input-mode, they replace the full bakedinputsarray for that run. - Use
--input-mode appendto keep baked inputs first, or--input-mode prependto place runtime inputs first. - If the caller supplies
--input-filein replace mode but the agent also needs instructions, the caller should also supply--input-text.
Use baked file/image paths only when the definition should own a fixed local asset. Use runtime flags when the caller should choose the asset.
Use top-level runtime_vars when the caller should choose action behavior or a step-local setting without editing the JSON:
- gating flags such as
runtime.generate_images - thresholds such as
runtime.score_threshold - step-local image model selection such as
runtime.hero_image_model
Reference them as runtime.<name> and pass them with --run-var name=value.
When a JSON definition becomes complex, recommend a same-name sidecar Markdown file:
my_agent.jsonmy_agent.md
Good sidecar sections:
- goal
- expected inputs
- expected outputs
- action flow
- child-agent relationships
- testing notes
Prefer boxed ASCII diagrams by default because they work in CLI sessions, editors, and diffs.
Example:
+----------------------+
| Parent Agent |
+----------+-----------+
|
v
+----------------------+
| when run_child=true |
| agent: ./child_demo |
+----------+-----------+
|
+-----+-----+
| |
v v
+-----------+ +-----------+
| succeeded | | failed |
+-----+-----+ +-----+-----+
| |
v v
+-----------+ +-----------+
| success | | failure |
| branch | | branch |
+-----------+ +-----------+
If the runtime clearly supports Mermaid rendering, offer Mermaid as an additional option and ask whether the user wants that representation. When support is uncertain, stay with ASCII only.
Default to the most portable shape that satisfies the user's goal.
Prefer these in order:
- plain model output with minimal actions
email_meor child-agent steps when they fit the taskexeconly when the task truly needs a local command
If one Cargo AI agent needs to call another Cargo AI agent:
- prefer a native
kind: "agent"step - do not add Python or shell wrappers just to launch the child agent
- use wrapper programs only when the task truly needs non-Cargo-AI behavior around that call
If the user needs a reusable project-local capability:
- prefer a native
kind: "tool"step over inventing repeatedexecwrappers - when Cargo is available and new executable code is needed, create a Rust tool with
cargo ai add tool <name>instead of ad hoc Python, Node, or shell helper scripts - put custom behavior in
src/tool.rs; leavesrc/lib.rsfocused on Cargo AI protocol adapter code unless the protocol contract itself must change - when adding dependencies, follow the dependency discipline in
tool-hardening.mdinstead of grabbing the first crate that compiles - before completion, perform the hardening review in
tool-hardening.mdand treat the tool as production local executable code - keep the tool contract in the tool crate and keep the agent JSON focused on
name,params, and optional output capture - use
.cargo-ai/guidance/tool-authoring.mdfor the workflow,.cargo-ai/guidance/tool-contract.mdfor the detailed contract, and.cargo-ai/guidance/tool-child-agents.mdwhen the tool needs child agents
When the user wants portability across macOS, Windows, and Linux:
- avoid shell-specific scripts when possible
- avoid OS-specific paths
- keep file paths relative
- isolate any unavoidable platform-specific logic and explain it in the sidecar notes
When the user wants local-machine behavior:
- you may use local commands and conventions
- prefer real executables over shell builtins when possible
- for macOS-only examples, prefer
/bin/echoover bareecho - pair intentionally platform-specific steps with
platform - still keep the JSON as small and explicit as possible
- Draft the JSON.
- If complexity grows, add the sidecar Markdown file.
- Run
cargo ai hatch <agent-name> --config <config.json> --check. - Fix errors before building.