Key Concepts
Runsight has five core primitives: workflows, blocks, souls, tools, and dispatch. Everything is defined in YAML files on your filesystem. Git is the version control layer.
Workflows
Section titled “Workflows”A workflow is a YAML file in custom/workflows/ that defines a directed graph of blocks. The engine discovers workflow files automatically.
version: "1.0"blocks: research: type: linear soul_ref: researcher summarize: type: linear soul_ref: writer depends: researchworkflow: name: Research Pipeline entry: researchA workflow file has these top-level sections:
| Section | Default | Purpose |
|---|---|---|
version | "1.0" | Schema version |
blocks | {} | Block definitions keyed by block ID |
workflow | required | Graph metadata — name, entry block, and transitions |
souls | {} | Inline soul definitions (optional shorthand) |
tools | [] | Tool IDs available to this workflow |
limits | none | Budget constraints (cost caps, timeouts) |
eval | none | Test cases for offline evaluation |
enabled | false | Whether the workflow is active |
interface | none | Public input/output contract for callable sub-workflows |
config | {} | Arbitrary workflow configuration |
Only workflow is required — all other sections have defaults.
Workflows are nestable — a workflow block can execute another workflow file as a child, with parent-child run linkage and independent error handling.
Blocks
Section titled “Blocks”Blocks are the execution units inside a workflow. Each block has a type that determines its behavior. Runsight ships with six block types:
| Type | What it does |
|---|---|
linear | Single LLM call through a soul. The most common block type. |
gate | LLM quality gate — evaluates another block’s output and routes on pass/fail. |
code | Runs Python code. Define a def main(data) function in the code field. |
loop | Iterates inner blocks for up to max_rounds rounds with optional break conditions. |
workflow | Executes a child workflow via workflow_ref. Parent-child run linkage, on_error modes. |
dispatch | Parallel branching — each exit port gets its own soul and task instruction. All branches execute concurrently. |
All blocks share a unified execution lifecycle via execute_block():
- Observer notified (
on_block_start) - Block-scoped budget session created (if
limitsdefined) - Retry wrapper applied (if
retry_configdefined) - Timeout enforced via
asyncio.wait_for - Block executes
- Exit conditions evaluated — sets the
exit_handlefor downstream routing - Observer notified (
on_block_complete)
Blocks can define assertions for quality evaluation, exits for multi-path routing, depends for dependency ordering, and error_route for error-specific branching.
A soul is an agent identity — it defines who an LLM is and how it behaves. Souls are YAML files in custom/souls/:
id: researcher_v1role: Senior Researchersystem_prompt: > You are an expert researcher. Given a topic, provide a concise, well-structured summary of key findings, trends, and insights.provider: openaimodel_name: gpt-4.1-minitemperature: 0.7max_tokens: 2048Soul fields:
| Field | Required | Purpose |
|---|---|---|
id | Yes | Unique identifier |
role | Yes | Agent role label |
system_prompt | Yes | LLM system instructions |
provider | No | LLM provider (e.g., openai, anthropic) |
model_name | No | Model name (e.g., gpt-4.1-mini). Falls back to runner default if omitted. |
temperature | No | Sampling temperature |
max_tokens | No | Output token limit |
tools | No | Tool names this soul can use |
avatar_color | No | UI display color |
max_tool_iterations | No | Max tool-use loops per execution (default: 5) |
Blocks reference souls via soul_ref:
blocks: research: type: linear soul_ref: researcher # resolves to custom/souls/researcher.yamlSouls can also be defined inline in the workflow YAML as optional shorthand — see Inline Souls.
One soul per step. Each block references at most one soul. The exception is dispatch, where each exit port has its own soul.
Tools are capabilities that souls can use during execution. They come in three types:
- Built-in tools: Ship with Runsight —
delegate(exit port routing),http(outbound requests),file_io(file operations) - Custom tools: YAML files in
custom/tools/with a Python or HTTP executor - HTTP tools: Declarative HTTP request definitions
Custom tool example:
version: "1.0"type: customexecutor: pythonname: Slack Payload Builderdescription: Builds a Slack message payload from plain text.parameters: type: object properties: text: type: string required: [text]code: | import json def main(args): return {"payload_json": json.dumps({"text": args["text"]})}Tools are identified by their filename stem — a file at custom/tools/slack_payload_builder.yaml has tool ID slack_payload_builder. Built-in tools use reserved IDs: delegate, http, file_io.
Tools are discovered automatically from custom/tools/.
Tool governance is enforced at the workflow level: a soul only gets access to tools that the workflow explicitly lists in its tools section. Both the workflow and the soul must declare the tool for it to be available during execution.
Dispatch
Section titled “Dispatch”Dispatch is the branching mechanism. There are two ways to branch in Runsight:
Exit ports on any block
Section titled “Exit ports on any block”Any block can define exits. When a soul lists delegate in its tools and the workflow enables it, the soul can call delegate(port="...", task="...") to pick which exit port to route to — making the LLM the decision-maker.
blocks: triage: type: linear soul_ref: triager exits: - id: urgent label: Urgent — needs immediate attention - id: normal label: Normal — standard processing handle_urgent: type: linear soul_ref: responder depends: triage handle_normal: type: linear soul_ref: processor depends: triageThe delegate tool requires two parameters: port (constrained to the declared exit IDs) and task (instruction for the downstream block). The soul must list delegate in its tools array, and the workflow must include delegate in its top-level tools list.
Dispatch block (parallel branching)
Section titled “Dispatch block (parallel branching)”The dispatch block type runs all branches concurrently — each exit port gets its own soul and task instruction. Unlike exit ports on a linear block (where the LLM picks one), dispatch executes every branch.
See Dispatch & Delegate for details.
YAML-First, Git-Native
Section titled “YAML-First, Git-Native”Everything in Runsight is a file:
| Primitive | Location | Format |
|---|---|---|
| Workflows | custom/workflows/*.yaml | YAML |
| Souls | custom/souls/*.yaml | YAML |
| Tools | custom/tools/*.yaml | YAML |
Git is the version control layer:
- Save writes the workflow YAML to disk and commits to the
mainbranch - Dirty runs (unsaved changes) automatically create simulation branches (
sim/{workflow-slug}/{YYYYMMDD}/{short-id}) - Every run records the commit SHA of the workflow that executed
- Fork recovery lets you branch from a failed run to iterate without losing history
- The run detail view shows the historical YAML snapshot — the exact file content that ran, not the current version
There is no database for workflow definitions. Your repo is the database. Diff your workflows, review them in PRs, roll back with git.