Skip to content

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
hookCall a specific named hook tool directly (no LLM involved)
condition_keyBranch based on a keyword the model output
prompt_to_stringRender a Go template with task variables, output as string
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
execute_config.hooksNoList of hook names to expose as tools
execute_config.hide_toolsNoTools to suppress from the model
execute_config.temperatureNoSampling temperature (0–1)

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

Example:

json
{
  "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>",
    "hooks": ["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:

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

hook

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

Key fields:

FieldRequiredDescription
hook.nameYesRegistered hook name (e.g. local_shell)
hook.tool_nameYesTool/operation to call on that hook
hook.argsNoStatic string arguments
output_templateNoGo template to format the hook output

Example:

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

condition_key

Routes based on a keyword in the model's output. Useful for yes/no decisions.

Key fields:

FieldRequiredDescription
system_instructionYesPrompt that asks the model to reply with a keyword
valid_conditionsYesMap of accepted keyword → boolean

Example:

json
{
  "id": "validate",
  "handler": "condition_key",
  "system_instruction": "Does this look like valid JSON? Reply only 'valid' or 'invalid'.",
  "valid_conditions": { "valid": true, "invalid": true },
  "transition": {
    "branches": [
      { "operator": "equals", "when": "valid",   "goto": "process" },
      { "operator": "equals", "when": "invalid",  "goto": "error_handler" }
    ]
  }
}

prompt_to_string

Renders a Go template string using accumulated task output variables. Useful for building prompts that combine outputs from multiple previous tasks.

Key fields:

FieldRequiredDescription
prompt_templateYesGo template string, variables via {{.task_id}}

noop

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

Released under the Apache 2.0 License.