Prompt Composition
How Weave builds agent prompts from templates, delegation targets, and configuration
Weave composes each agent’s final prompt before execution by combining prompt sources, rendering templates, and injecting delegation routing guidance. This guide explains how prompt composition works, what template features are supported, and how to customize agent prompts safely.
Overview
Section titled “Overview”The Weave engine builds a complete prompt for each agent by:
- Loading the primary prompt source (inline
promptorprompt_file) - Rendering Mustache template tags with context from configuration
- Generating delegation targets from agent triggers
- Appending optional additional instructions (
prompt_appendorprompt_append_file) - Evaluating tool policy into concrete permissions
The output is a normalized agent descriptor containing the final prompt text and all metadata needed by the execution harness.
Prompt Sources
Section titled “Prompt Sources”Primary Prompt
Section titled “Primary Prompt”Every agent must declare exactly one primary prompt source:
prompt: Inline prompt text in the agent configurationprompt_file: Path to a Markdown file containing the prompt
agent reviewer { prompt "Review code changes for quality and security." # OR prompt_file "prompts/reviewer.md"}If neither is declared, composition fails with PromptSourceMissingError.
Prompt Append
Section titled “Prompt Append”Agents can optionally append additional instructions after the primary prompt:
prompt_append: Inline append textprompt_append_file: Path to a Markdown file containing append text
agent reviewer { prompt_file "prompts/reviewer.md" prompt_append "Focus on security vulnerabilities." # OR prompt_append_file "prompts/security-focus.md"}prompt_append and prompt_append_file are mutually exclusive. Only one may be declared per agent.
Template Syntax
Section titled “Template Syntax”All prompt sources (primary and append) are rendered as Mustache templates before execution. Templates can reference bounded context fields to customize prompts based on agent configuration.
Supported Features
Section titled “Supported Features”Weave supports these Mustache features:
- Escaped variables:
{{agent.name}}renders with HTML escaping - Unescaped variables:
{{{delegation.section}}}renders without escaping (use for Markdown content) - Dotted paths:
{{agent.name}},{{toolPolicy.effective.read}} - Sections:
{{#delegation.targets}}...{{/delegation.targets}}for conditionals and iteration - Inverted sections:
{{^delegation.targets}}...{{/delegation.targets}}for negation - Comments:
{{! This is a comment }} - Current item:
{{.}}inside list sections
Unsupported Features
Section titled “Unsupported Features”These features are explicitly rejected and cause composition to fail:
- Partials:
{{> footer}}(cannot load external content) - Delimiter changes:
{{=<% %>=}}(cannot bypass path validation) - Lambdas: No executable behavior, function calls, or dynamic logic
- Filesystem access: Templates cannot read files or environment variables
Literal Tags
Section titled “Literal Tags”Use a backslash to render a literal Mustache tag without template expansion:
To reference an agent, use \{{agent.name}} in your template.This renders as {{agent.name}} in the final prompt.
Template Context
Section titled “Template Context”Templates are rendered against a bounded context containing only safe, public fields from agent configuration. This is a security boundary: templates cannot access raw config, environment variables, or runtime state.
Context Fields
Section titled “Context Fields”| Path | Type | Description |
|---|---|---|
agent.name |
string |
Stable internal agent identifier |
agent.description |
string? |
Optional agent description |
agent.mode |
"primary" | "subagent" | "all" |
Agent mode hint |
agent.skills |
string[] |
Requested skill names |
agent.isCategory |
boolean |
True for category shuttle agents |
category.name |
string? |
Category name (only for category agents) |
category.description |
string? |
Category description (only for category agents) |
toolPolicy.effective.read |
"allow" | "deny" | "ask" |
Resolved read permission |
toolPolicy.effective.write |
"allow" | "deny" | "ask" |
Resolved write permission |
toolPolicy.effective.execute |
"allow" | "deny" | "ask" |
Resolved execute permission |
toolPolicy.effective.delegate |
"allow" | "deny" | "ask" |
Resolved delegation permission |
toolPolicy.effective.network |
"allow" | "deny" | "ask" |
Resolved network permission |
delegation.targets |
array |
List of eligible delegation targets (see below) |
Delegation Target Fields
Section titled “Delegation Target Fields”Each item in delegation.targets has these fields:
| Path | Type | Description |
|---|---|---|
name |
string |
Target agent name |
description |
string? |
Optional target description |
domains |
string[] |
Domains this target handles |
triggers |
array |
List of trigger patterns |
Each trigger in triggers has:
| Path | Type | Description |
|---|---|---|
domain |
string |
Domain this trigger belongs to |
trigger |
string |
Trigger pattern |
routing_hint |
string? |
Optional routing guidance |
Context Stack Semantics
Section titled “Context Stack Semantics”Inside list sections, Mustache context-stack rules apply:
{{#delegation.targets}}- **{{name}}**: {{description}} Domains: {{#domains}}{{.}}{{^last}}, {{/last}}{{/domains}}{{/delegation.targets}}Inside {{#delegation.targets}}, {{name}} resolves to the current target’s name. For scalar lists like domains, use {{.}} to render each item.
Delegation Rendering
Section titled “Delegation Rendering”When an agent has tool_policy.delegate = "allow", Weave generates a list of eligible delegation targets based on other agents’ triggers. Templates can iterate over this list to render routing guidance.
Example: Delegation Section
Section titled “Example: Delegation Section”## Delegation
You can delegate tasks to these specialized agents:
{{#delegation.targets}}### {{name}}
{{#description}}{{description}}{{/description}}
**Domains**: {{#domains}}{{.}}{{^last}}, {{/last}}{{/domains}}
**Triggers**:{{#triggers}}- `{{trigger}}`{{#routing_hint}} - {{routing_hint}}{{/routing_hint}}{{/triggers}}
{{/delegation.targets}}
{{^delegation.targets}}No delegation targets are available.{{/delegation.targets}}This renders a complete delegation section with target names, descriptions, domains, and trigger patterns. If no targets are available, it renders a fallback message.
Delegation Filtering
Section titled “Delegation Filtering”Weave automatically filters delegation targets using these rules:
- Exclude self: An agent cannot delegate to itself
- Exclude disabled agents: Agents in
disabled.agentsare removed - Exclude primary agents: Agents with
mode: "primary"are not delegation targets - Exclude shuttle agents from shuttles: The shared
shuttleagent and category shuttles do not advertise each other
Composition Order
Section titled “Composition Order”Agent Prompts
Section titled “Agent Prompts”Final agent prompt text is assembled in this order:
- Rendered primary prompt source (
promptorprompt_file) - Rendered append source (
prompt_appendorprompt_append_file), if present
Both sources are rendered with the same template context. The two parts are joined with a blank line (\n\n).
Workflow Step Prompts
Section titled “Workflow Step Prompts”Workflow steps can also declare prompts and appends. Step composition follows these precedence rules:
| Step has append? | Workflow has append? | Effective append | Source |
|---|---|---|---|
| yes | any | step’s append | step-local |
| no | yes | workflow’s append | workflow fallback |
| no | no | none | none |
Step-local wins: If a step declares its own prompt_append or prompt_append_file, the workflow-level append is completely suppressed for that step.
Example: Step-local wins
workflow secure-feature { version 1 prompt_append "Always write tests."
step implement { name "Implement" type autonomous agent shuttle prompt "Execute the plan." prompt_append "Focus on security." completion agent_signal }}Composed prompt for implement step:
Execute the plan.
Focus on security.The workflow-level "Always write tests." is suppressed.
Example: Workflow fallback
workflow secure-feature { version 1 prompt_append "Always write tests."
step review { name "Review" type gate agent weft prompt "Review the changes." completion review_verdict on_reject pause }}Composed prompt for review step:
Review the changes.
Always write tests.The workflow-level append is applied because the step has no append of its own.
Trust Boundary
Section titled “Trust Boundary”Template rendering enforces a strict security boundary. Templates can only reference paths in the explicit allowed-path set.
Allowed Paths
Section titled “Allowed Paths”Templates can reference:
{{agent.name}},{{agent.mode}},{{agent.skills}},{{agent.isCategory}}{{category.name}},{{category.description}}{{toolPolicy.effective.read}}(and other capability fields){{#delegation.targets}}iteration and nested fields
Rejected Paths
Section titled “Rejected Paths”These paths are explicitly rejected with UnknownPath errors:
{{artifact.contents}}(artifact data is not in context){{chat.history}}(chat history is not in context){{raw.prompt}}(raw prompt text is not in context)- Any path not in the allowed-path set
Unsafe Paths
Section titled “Unsafe Paths”These paths are rejected with UnsafePath errors:
{{__proto__}},{{constructor}},{{prototype}}(prototype traversal)
Static Text
Section titled “Static Text”Static append text without Mustache tags is always safe and passes through unchanged.
Template Errors
Section titled “Template Errors”Template failures are reported as typed errors with detailed context:
Error Types
Section titled “Error Types”MalformedSyntax: Invalid Mustache syntax (e.g., unclosed tags)UnsupportedTag: Partial or delimiter change detectedUnknownPath: Path not in allowed-path set (e.g.,{{agnt.name}})UnsafePath: Prototype traversal attemptFunctionValue: Template tried to call a functionSectionMismatch: Mismatched section tags (e.g.,{{#foo}}...{{/bar}})UnresolvedTag: Mustache tag remained in rendered output
Error Context
Section titled “Error Context”Template errors include:
- Agent name
- Source kind (
prompt,prompt_file,prompt_append,prompt_append_file) - File path (when source is a file)
- Line and column (when available)
- Offending tag or path
Strict Path Validation
Section titled “Strict Path Validation”Because rendering uses schema-aware strict paths:
{{agent.name}}succeeds{{agnt.name}}fails as unknown path (typo detection){{#category}}...{{/category}}is valid and falsey for non-category agents{{agent.__proto__}}fails as unsafe path
Complete Example
Section titled “Complete Example”Here’s a complete custom prompt with delegation rendering:
# Code Reviewer
You are a specialized code review agent. Your role is to analyze code changes for quality, security, and maintainability.
## Your Capabilities
- **Read**: {{toolPolicy.effective.read}}- **Write**: {{toolPolicy.effective.write}}- **Execute**: {{toolPolicy.effective.execute}}- **Delegate**: {{toolPolicy.effective.delegate}}
## Review Guidelines
1. Check for security vulnerabilities2. Verify test coverage3. Ensure code follows project conventions4. Look for performance issues
{{#delegation.targets}}## Delegation
When you encounter specialized concerns, delegate to these agents:
{{#delegation.targets}}### {{name}}
{{#description}}{{description}}{{/description}}
**Handles**: {{#domains}}{{.}}{{^last}}, {{/last}}{{/domains}}
**Delegate when**:{{#triggers}}- {{trigger}}{{#routing_hint}} ({{routing_hint}}){{/routing_hint}}{{/triggers}}
{{/delegation.targets}}{{/delegation.targets}}
## Output Format
Provide your review as:
- **APPROVE** if changes are acceptable- **BLOCK** if changes require fixes
Include specific feedback for any issues found.This template:
- References tool policy to explain capabilities
- Conditionally renders delegation section only when targets exist
- Iterates over targets with nested field access
- Uses unescaped triple braces for Markdown content
- Provides clear output format guidance
Best Practices
Section titled “Best Practices”Use Templates Sparingly
Section titled “Use Templates Sparingly”Only use template tags where they improve prompt clarity. Don’t add artificial tags just to prove templating works.
Prefer Unescaped for Markdown
Section titled “Prefer Unescaped for Markdown”Use triple braces {{{...}}} for Markdown-rich values to avoid unwanted HTML escaping:
{{#category}}{{{category.description}}}{{/category}}Test Optional Paths
Section titled “Test Optional Paths”Use sections to test for optional fields:
{{#agent.description}}Description: {{agent.description}}{{/agent.description}}Avoid Hardcoded Lists
Section titled “Avoid Hardcoded Lists”Use {{#delegation.targets}} loops instead of hardcoding target lists that could diverge from configuration.
Keep Appends Focused
Section titled “Keep Appends Focused”Use prompt_append for narrow, context-specific guidance. Keep the primary prompt general and reusable.
Related Documentation
Section titled “Related Documentation”- Agents - How to configure agents
- Tool Policy - Understanding tool permissions
- Categories - How delegation routing works
- Workflows - Workflow step composition