Handlers

Every task has a handler field that determines what it does. This page documents all available handlers and which fields are valid for each.

Handler types

HandlerWhat it does
chat_completionSend messages to an LLM, receive a text/tool-call reply
execute_tool_callsExecute the tool calls from the previous LLM reply
toolsCall a specific named tools tool directly (no LLM involved)
prompt_to_stringRender a Go template with task variables, output as string
prompt_to_intParse the model's reply as an integer
raise_errorImmediately halt the chain with an error message
noopPass input through unchanged

chat_completion

Sends the current input to the LLM and waits for a reply. If the model calls a tool, the transition evaluates to "tool-call".

Key fields:

FieldRequiredDescription
system_instructionNoSystem prompt (supports macros)
execute_config.modelYesModel name, e.g. qwen2.5:7b
execute_config.providerYesollama, openai, vllm, gemini, vertex-google, vertex-anthropic, vertex-meta, vertex-mistralai
execute_config.toolsNoTools allowlist: []=none, ["*"]=all, ["a","b"]=named, ["*","!x"]=all-except. Absent=all (backward compat).
execute_config.hide_toolsNoTools to suppress from the model
execute_config.temperatureNoSampling temperature (0–1)
execute_config.thinkNoReasoning effort level. "low", "medium", "high", or "false". Supported by Ollama (v0.17.5+), Gemini 2.5+, vLLM, and OpenAI o-series models.
execute_config.max_tokensNoCap on the model's output tokens for this task. When unset, the engine falls back to the chain's token_limit so providers (notably Gemini thinking models) don't burn their entire output budget on hidden reasoning and emit empty content.
execute_config.shiftNoBoolean. If true, slides the context window by dropping old messages instead of erroring on token limits.
execute_config.truncateNoBoolean. If true, truncates the initial prompt instead of sliding the context window (Ollama-specific).
execute_config.modelsNoArray of fallback model IDs tried in order when the primary model is unavailable.
execute_config.providersNoArray of fallback provider types, paired index-for-index with models.

| execute_config.retry_policy | No | LLM-call retry and model-fallback settings — see retry_policy below. |

Transition values:

  • "tool-call" — model issued one or more tool calls
  • "stop" — model replied with text and stopped
  • "length" — reply was truncated at token limit

retry_policy

Controls automatic retries on transient LLM errors and optional model swapping after repeated failures.

FieldTypeDefaultDescription
max_attemptsint1Total attempts including the first (0 or 1 disables retry)
initial_backoffduration"500ms"Wait before the second attempt; doubled each retry
max_backoffdurationCap on exponential backoff
jitterfloat00–1 fraction of backoff added as random noise
rate_limit_min_waitdurationMinimum wait when the provider returns a rate-limit error
fallback_model_idstringAlternate model ID to switch to after fallback_after consecutive failures
fallback_afterintFailure count that triggers the model swap

Example:

{
  "id": "chat",
  "handler": "chat_completion",
  "system_instruction": "You are a helpful assistant. Today is <span v-pre>{{now:2006-01-02}}</span>.",
  "execute_config": {
    "model": "<span v-pre>{{var:model}}</span>",
    "provider": "<span v-pre>{{var:provider}}</span>",
    "tools": ["nws"]
  },
  "transition": {
    "branches": [
      { "operator": "equals", "when": "tool-call", "goto": "run_tools" },
      { "operator": "default", "when": "", "goto": "end" }
    ]
  }
}

execute_tool_calls

Executes the tool calls emitted by the previous chat_completion task, appends the results to the chat history, and loops back.

Key fields:

FieldRequiredDescription
input_varYesID of the chat_completion task whose output to use

Example:

{
  "id": "run_tools",
  "handler": "execute_tool_calls",
  "input_var": "chat",
  "transition": {
    "branches": [
      { "operator": "default", "when": "", "goto": "chat" }
    ]
  }
}

tools

Calls a specific tool on a named tool directly — no LLM involved. Use for deterministic side effects (e.g. writing a file, calling a fixed API endpoint).

Key fields:

FieldRequiredDescription
tools.nameYesRegistered tools name (e.g. local_shell)
tools.tool_nameYesTool/operation to call on that tool
tools.argsNoStatic arguments passed to the tool
output_templateNoGo text/template string rendered against the tools's JSON response. Variables are the response fields (e.g. {{.exit_code}}). Output stored as a string.

Example:

{
  "id": "write_file",
  "handler": "tools",
  "tools": {
    "name": "local_fs",
    "tool_name": "write_file",
    "args": { "path": "/tmp/output.txt" }
  }
}

prompt_to_string

Sends the prompt to the LLM and returns the response as a plain string. Use prompt_template to build the prompt from previous task outputs.

Key fields:

FieldRequiredDescription
prompt_templateNoGo template string assembling input from prior tasks via {{.task_id}}
system_instructionNoSystem prompt for the LLM call
execute_config.model / providerYesModel to use

noop

Passes input through to the next task unchanged. Useful as an explicit routing node.


prompt_to_int

Sends the prompt to the LLM and parses the reply as an integer. The eval string is the decimal representation of the result (e.g. "42"). Use with the in_range or equals operators in branches.

Key fields:

FieldRequiredDescription
system_instructionYesPrompt that instructs the model to reply with a number
execute_config.model / providerYesModel to use

raise_error

Immediately halts the chain with the input string as the error message. Use as a terminal error branch — no transition needed.