Skip to main content

Workflow orchestrator using LangGraph with Claude, DeepSeek, and script execution backends

Project description

sqrlly

A workflow orchestrator that compiles a YAML file into a runnable LangGraph. Each step runs an LLM prompt, a script, a binary, or a nested workflow; quality gates retry failing steps with feedback; routing and fan-out handle branching and parallelism.

What it is

sqrlly turns a declarative YAML workflow into a compiled LangGraph StateGraph and runs it. A workflow is a list of nodes — each node executes one thing: a prompt against an LLM, an interpreted script (.py / .js / .ts / .sh), a binary, or a recursive subgraph (another sqrlly workflow). Quality gates wrap any node — a gate scores the node's output and retries it with feedback until it passes. Routing sends flow to the next node conditionally; fan-out spawns a parallel branch per item in a manifest. State checkpoints to SQLite, so --resume picks up where a stopped run left off.

Install

pip install sqrlly                      # core
pip install "sqrlly[anthropic,openai]"  # + API backends

Backend extras:

  • anthropic — Claude via the Anthropic API.
  • openai — OpenAI, DeepSeek, and any OpenAI-compatible endpoint.
  • acp — Claude via the local claude-code-acp adapter (also needs npm i -g @zed-industries/claude-code-acp).

Requires Python 3.11+. From source: git clone then uv sync (add --extra openai --extra anthropic for backends).

Quickstart

A two-node workflow — generate jokes, gate them, pick the best (examples/jokes/):

name: "Joke Generator"
version: "0.1.0"

nodes:
  - id: generate
    name: "Generate Jokes"
    execute:
      url: "examples/jokes/generate.md"
    evaluation:
      validator: "examples/jokes/gates/validate_jokes.py"
      threshold: 1.0
      blocking: true
      max_retries: 2

  - id: select
    name: "Select Best Joke"
    depends_on: ["generate"]
    execute:
      url: "examples/jokes/select.md"

settings:
  presets:
    default:
      transport: acp
      provider: anthropic
      model: sonnet
      default: true
sqrlly validate examples/jokes/workflow.yaml
sqrlly run examples/jokes/workflow.yaml --log run.jsonl

validate compiles the graph and reports the node count. run executes it and writes a JSONL event log you can inspect for workflow_start, node_completed, gate_evaluated, node_retried, and workflow_end events.

How it works

A node's execute.url is dispatched by extension: .md / .txt / .prompt → LLM prompt, .py / .js / .ts / .sh → script, .yaml → subgraph, anything else → binary. Prompt files are Jinja2 templates — {{generate}} interpolates the output of an upstream node named generate.

  • Gates & retries — an evaluation: block runs a script or LLM scorer over a node's output. Below threshold, the node re-runs with the gate's feedback injected ({{_retry_reason}}), up to max_retries.
  • Routing — a route: block declares where flow goes next: goto: for unconditional dispatch, or a cases: / else: predicate ladder for conditional branching.
  • Fan-out — a fan_out: block spawns one parallel branch per item in a JSON manifest, optionally backed by a per-item subgraph.
  • Subgraphs — a node whose execute.url is a .yaml runs another workflow, recursively. The same file is runnable standalone or as a subgraph reference.
  • Foreman — when run inside a git repository, each node executes in its own git worktree, reused across retries so prompt nodes can iterate on prior files.
  • Resume — state checkpoints to <workdir>/.sqrlly-checkpoint.db; --resume restarts from the last checkpoint.

Backends and presets

LLM and script execution is configured by presets under settings.presets — named bundles referenced by a node's params.preset. Exactly one LLM preset is marked default: true:

settings:
  presets:
    default:
      transport: api        # api | acp
      provider: anthropic   # anthropic | openai | deepseek | custom
      model: sonnet
      default: true

If settings.presets is omitted entirely, sqrlly auto-detects a backend from environment keys, in order: ANTHROPIC_API_KEYDEEPSEEK_API_KEYnpx on PATH (ACP). API keys load from the environment or a project-local .env file (copy .env.example):

ANTHROPIC_API_KEY=sk-ant-...
DEEPSEEK_API_KEY=sk-...
OPENAI_API_KEY=sk-...                          # reserved for real openai.com
CUSTOM_API_KEY=...                             # any OpenAI-compatible endpoint
CUSTOM_API_BASE_URL=https://openrouter.ai/api/v1

The full preset and settings reference — including CommandPreset for custom script interpreters — is in docs/schema-reference.md.

CLI

Command Purpose
sqrlly validate <config> Compile the workflow; report node count and lint warnings.
sqrlly run <config> Execute the workflow.
sqrlly graph <config> Print the topology as a Mermaid diagram.
sqrlly view <config> Render a self-contained interactive HTML viewer.

run flags: --workdir/-w <dir>, --dry-run, --preset/-p <name> (force a named preset as default), --resume, --log <path>.

Examples

Each example directory ships a checked-in view.html (authoring view) and, where the run is deterministic, a view-debug.html from a captured log.

Workflow What it shows
examples/jokes/ Minimal: prompt + script gate + select. Start here.
examples/route_classify/ Inline route: case ladder over structured state.
examples/pipeline_style/ route: { goto: <next> } forward-edge authoring; a linear pipeline.
examples/absurd-paper/ 13-node multi-stage pipeline with subgraphs and per-item subgraph fan-out.
examples/wave_planner/ Wave-driven dynamic-task pattern — goto: loop-back to a fan-out parent.

Documentation

  • docs/schema-reference.md — every Settings / Node / Execute / preset / route / evaluation field, the URL dispatch table, and the route-predicate namespace.
  • TECHNICAL.md — three-layer architecture, pipeline flow, state model, key invariants.
  • SKILLS.md — agent skill doc: instructions for an AI coding agent authoring and running sqrlly workflows.

Contributing

The codebase is a three-layer split — schema/ (Pydantic models) → compile/ (YAML → LangGraph) → runtime/ (executors, backends) — enforced at CI time by an AST import check. Tests use real subprocesses, real git worktree, and real backends (no mocks of external systems). See TECHNICAL.md for architecture and contributor reading order.

uv run pytest tests/ --ignore=tests/acp     # ~840 tests
uv run pytest tests/acp                     # ACP integration (needs the npm adapter)

License

Apache-2.0 — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sqrlly-0.1.0.tar.gz (467.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sqrlly-0.1.0-py3-none-any.whl (109.9 kB view details)

Uploaded Python 3

File details

Details for the file sqrlly-0.1.0.tar.gz.

File metadata

  • Download URL: sqrlly-0.1.0.tar.gz
  • Upload date:
  • Size: 467.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for sqrlly-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0f87c1c87a3b26981c99369c715435aa525ba0853f98cea3a534167d60594983
MD5 ae2f7145b526ab683954f312d65361c3
BLAKE2b-256 82b6cee479a0465d723415f0011fd96b940252d22c77b08d225cdee1b3c4edcf

See more details on using hashes here.

File details

Details for the file sqrlly-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: sqrlly-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 109.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for sqrlly-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ed255b2d143f1ff3bb347fbb813b762d41faba317b2853b1f274d2fc3fb13637
MD5 3c70fb2b7a198c03dd855738f46b9739
BLAKE2b-256 18e78c8cf4c0426c6923f8102e25d4462a4e272e1d0e9750fffff66586ddf684

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page