Skip to main content
Prompts are the core of most TOON workflows. The prompt: field on a step defines the text sent to the step’s agent.
Every prompt: step requires an agent: field referencing a declared agent. The examples below omit agents: declarations and agent: fields for brevity — see Nodes for complete examples.

Basic Prompt

steps[1]:
  - id: greet
    prompt: Say hello to {input.name}.
    output:
      message: string

Multi-line Prompts

Multi-line prompts in TOON are written as quoted strings with \n escape sequences for newlines:
steps[1]:
  - id: analyze
    prompt: "You are a senior software engineer.\n\nAnalyze the following bug report and identify:\n1. Root cause\n2. Affected systems\n3. Suggested fix\n\nBug report:\n{input.description}"
    output:
      rootCause: string
      affectedSystems: "string[]"
      suggestedFix: string
The \n sequences are converted to newlines when the prompt is sent to the agent.

Interpolation

Use {expression} to inject values into prompts:

Workflow Input

prompt: "Research the topic: {input.topic}\nPriority: {input.priority}"

Upstream Step Outputs

prompt: "Based on the analysis:\nSummary: {analyze.summary}\nSeverity: {analyze.severity}"

Nested Fields

prompt: "Deploy to {config.deployment.environment}\nRegion: {config.deployment.region}"

Array Values

Arrays are interpolated as comma-separated values by default:
prompt: "The key points are: {research.keyPoints}"
For more control, reference individual items or use them in a list context:
prompt: "Key findings:\n{research.keyPoints}\n\nPlease elaborate on each point above."

Escaping Braces

Use double braces to output a literal brace:
prompt: "Return a JSON object like {{key: value}}.\nThe input topic is {input.topic}."
{{ becomes { and }} becomes } in the final prompt text.

Expressions

Interpolation braces {...} evaluate full JavaScript expressions — ternaries, method calls, and string concatenation all work:
steps[1]:
  - id: fix
    prompt: "Fix the bug described below.\n\n{input.priority == 'high' ? 'URGENT: This is a high-priority fix. Minimize the blast radius.\n' : ''}Description: {input.description}"
    output:
      patch: string

Ternaries

Use ternary expressions for conditional content:
prompt: "{input.tags.length > 0 ? 'Tags: ' + input.tags.join(', ') : 'No tags provided.'}"

Method Calls

Call methods on interpolated values:
prompt: "Keywords: {input.tags.join(', ')}\nTitle: {draft.title.toUpperCase()}"

Referencing Loop State

Inside a loop, reference the current iteration’s data:
steps[1]:
  - kind: loop
    until: "{review.approved}"
    children[1]:
      - id: review
        prompt: "Review this content.\nThis is iteration {loop.iteration}.\n{loop.iteration > 1 ? 'Previous feedback: ' + review.feedback : ''}"
        output:
          approved: boolean
          feedback: string

Component Parameters in Prompts

Inside a component, use {params.fieldName}:
components:
  Reviewer:
    params:
      content: string
      role: string
    steps[1]:
      - id: "{id}-review"
        prompt: "You are {params.role}.\nReview: {params.content}"
        output:
          approved: boolean
          feedback: string

Prompt Best Practices

Keep prompts focused. Each step should have a single clear instruction. Split complex tasks across multiple steps. Keep expressions readable. Ternaries and method calls work inside {}, but if an expression gets complex, use an inline run: block to prepare the data and reference its output in a downstream prompt. Leverage multi-line. Use quoted strings with \n to write clear, well-structured multi-line prompts. Reference specific fields. Instead of passing an entire object, reference the specific fields the model needs:
prompt: "Summary: {analysis.summary}\nSeverity: {analysis.severity}"
Over passing entire objects:
prompt: "Analysis: {analysis}"

Next Steps

  • Inline Code — Use TypeScript when prompts aren’t enough.
  • Schemas — Define the output shapes that prompts produce.
  • Nodes — All node kinds for controlling prompt execution flow.