Annotated Examples
Learning by example is the fastest way to understand task chains.
1. The Default Chain (Tool Use)
This is the chain used for interactive chat when you run contenox chat "hello" (or rely on the configured default chain) without an explicit --chain flag. It defines a loop between the model and the tools. A bare contenox "hello" uses default-run-chain.json via the injected run command instead — see the CLI reference.
{
"id": "default-chain",
"description": "Standard interactive chat loop supporting tool calls.",
"token_limit": 8192,
"tasks": [
{
"id": "chat",
"handler": "chat_completion",
"execute_config": {
"model": "<span v-pre>{{var:model}}</span>",
"provider": "<span v-pre>{{var:provider}}</span>",
"hooks": ["local_shell", "local_fs"]
},
"transition": {
"branches": [
// If the model decides a tool is needed, loop to run_tools
{ "operator": "equals", "when": "tool-call", "goto": "run_tools" },
// Otherwise, end the chain and wait for next user input
{ "operator": "default", "when": "", "goto": "end" }
]
}
},
{
"id": "run_tools",
"handler": "execute_tool_calls",
// input_var ensures it reads the tool calls from the 'chat' task output
"input_var": "chat",
"transition": {
"branches": [
// Once tools finish, loop back to the chat task to feed results in
{ "operator": "default", "when": "", "goto": "chat" }
]
}
}
]
}
2. Remote Hook Example (NWS)
This chain replaces the local shell hooks with a remote API hook (the US National Weather Service). Notice the custom system_instruction providing domain-specific guidance on how to use the NWS tools.
{
"id": "chain-nws",
"description": "Query the US National Weather Service via natural language.",
"token_limit": 32768,
"tasks": [
{
"id": "nws_chat",
"handler": "chat_completion",
"system_instruction": "You are a weather assistant with access to the US National Weather Service API. Use the tools to answer weather questions. Summarise results concisely — do NOT dump raw JSON or lists of hundreds of items. For forecasts you may need two calls: first the 'point' tool with latitude and longitude, then 'gridpoint_forecast' with the returned grid reference. For alerts, use 'alerts_active_area' with the two-letter state code. 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" }
]
}
},
{
"id": "run_tools",
"handler": "execute_tool_calls",
"input_var": "nws_chat",
"transition": {
"branches": [
{ "operator": "default", "when": "", "goto": "nws_chat" }
]
}
}
]
}
3. Retry and Fallback Model
This chain calls an external API via webhook. retry_policy retries up to three times with exponential backoff and swaps to a cheaper model after two consecutive failures. compact_policy summarises older history when the context reaches 80 % of token_limit, keeping the ten most recent messages verbatim — useful for long-running sessions.
{
"id": "resilient-chain",
"description": "Chat loop with retry on transient errors and a fallback model.",
"token_limit": 16384,
"tasks": [
{
"id": "chat",
"handler": "chat_completion",
"execute_config": {
"model": "gpt-4.1",
"provider": "openai",
"hooks": ["webhook"],
"retry_policy": {
"max_attempts": 3,
"initial_backoff": "1s",
"max_backoff": "30s",
"jitter": 0.2,
"fallback_model_id": "gpt-4.1-nano",
"fallback_after": 2
},
"compact_policy": {
"trigger_fraction": 0.80,
"keep_recent": 10
}
},
"transition": {
"branches": [
{ "operator": "equals", "when": "tool-call", "goto": "run_tools" },
{ "operator": "default", "when": "", "goto": "end" }
]
}
},
{
"id": "run_tools",
"handler": "execute_tool_calls",
"input_var": "chat",
"transition": {
"branches": [
{ "operator": "default", "when": "", "goto": "chat" }
]
}
}
]
}
4. Error Handling with on_failure
on_failure routes to a named task whenever the current task raises an uncaught error — before any branch conditions are checked. Here both edit and run_tools point to bail, which calls raise_error to terminate cleanly instead of leaving the run in an undefined state.
{
"id": "safe-chain",
"description": "File-editing chain with explicit error handling.",
"token_limit": 8192,
"tasks": [
{
"id": "edit",
"handler": "chat_completion",
"execute_config": {
"model": "<span v-pre>{{var:model}}</span>",
"provider": "<span v-pre>{{var:provider}}</span>",
"hooks": ["local_fs"]
},
"transition": {
"on_failure": "bail",
"branches": [
{ "operator": "equals", "when": "tool-call", "goto": "run_tools" },
{ "operator": "default", "when": "", "goto": "end" }
]
}
},
{
"id": "run_tools",
"handler": "execute_tool_calls",
"input_var": "edit",
"transition": {
"on_failure": "bail",
"branches": [
{ "operator": "default", "when": "", "goto": "edit" }
]
}
},
{
"id": "bail",
"handler": "raise_error"
}
]
}
5. plan_manager — Autonomous Multi-Step Execution
A three-task planning chain. The planner drives steps using plan_manager tools — creating the plan, then calling run_next_step in a loop. The executor runs the resulting tool calls. Once the planner stops calling tools, it hands off to summariser, which calls plan_summary.persist to write step results to the local database (visible via contenox plan show).
{
"id": "plan-chain",
"description": "Autonomous step-by-step execution with plan tracking.",
"token_limit": 32768,
"tasks": [
{
"id": "planner",
"handler": "chat_completion",
"system_instruction": "You are a task planner. Use plan_manager tools to create a plan, then call run_next_step in a loop until get_plan_status shows all steps complete.",
"execute_config": {
"model": "<span v-pre>{{var:model}}</span>",
"provider": "<span v-pre>{{var:provider}}</span>",
"hooks": ["plan_manager", "local_shell", "local_fs"]
},
"transition": {
"branches": [
{ "operator": "equals", "when": "tool-call", "goto": "executor" },
{ "operator": "default", "when": "", "goto": "summariser" }
]
}
},
{
"id": "executor",
"handler": "execute_tool_calls",
"input_var": "planner",
"transition": {
"branches": [
{ "operator": "default", "when": "", "goto": "planner" }
]
}
},
{
"id": "summariser",
"handler": "chat_completion",
"system_instruction": "Summarise the completed plan results and call plan_summary.persist to store them.",
"execute_config": {
"model": "<span v-pre>{{var:model}}</span>",
"provider": "<span v-pre>{{var:provider}}</span>",
"hooks": ["plan_summary"]
},
"transition": {
"branches": [
{ "operator": "equals", "when": "tool-call", "goto": "persist_tools" },
{ "operator": "default", "when": "", "goto": "end" }
]
}
},
{
"id": "persist_tools",
"handler": "execute_tool_calls",
"input_var": "summariser",
"transition": {
"branches": [
{ "operator": "default", "when": "", "goto": "end" }
]
}
}
]
}