{"id":41801127,"url":"https://github.com/ducks/lok","last_synced_at":"2026-02-08T20:14:54.421Z","repository":{"id":334458237,"uuid":"1141445765","full_name":"ducks/lok","owner":"ducks","description":"Local orchestration layer for coordinating multiple LLM backends through a single control plane. Lok is the brain that controls the arms you already have.","archived":false,"fork":false,"pushed_at":"2026-02-01T04:10:57.000Z","size":409,"stargazers_count":3,"open_issues_count":29,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-01T04:54:14.751Z","etag":null,"topics":["ai","llm","orchestration","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ducks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-24T21:24:48.000Z","updated_at":"2026-02-01T04:10:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ducks/lok","commit_stats":null,"previous_names":["ducks/lok"],"tags_count":50,"template":false,"template_full_name":null,"purl":"pkg:github/ducks/lok","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ducks%2Flok","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ducks%2Flok/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ducks%2Flok/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ducks%2Flok/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ducks","download_url":"https://codeload.github.com/ducks/lok/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ducks%2Flok/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29242003,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-08T19:36:48.828Z","status":"ssl_error","status_checked_at":"2026-02-08T19:27:12.336Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","llm","orchestration","rust"],"created_at":"2026-01-25T06:00:52.853Z","updated_at":"2026-02-08T20:14:54.415Z","avatar_url":"https://github.com/ducks.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lok\n\nDeclarative multi-LLM orchestration. Define workflows in TOML, run them against\nmultiple backends, get synthesized results.\n\n## What It Is\n\n- **Multi-backend queries**: Ask the same question to Claude, Codex, Gemini, and\n  Ollama in parallel, then synthesize or vote on the results\n- **Declarative workflows**: TOML files that define multi-step LLM pipelines with\n  dependencies, retries, and error handling\n- **Backend abstraction**: Swap `backend = \"claude\"` for `backend = \"ollama\"`\n  without changing your workflow logic\n\n## What It's Not\n\n- **Not an agent**: Lok doesn't make decisions or write code. It runs queries and\n  returns results. Use it *with* an agent (Claude Code, Cursor, etc.) that acts\n  on the output.\n- **Not a wrapper for one LLM**: If you only use Claude, you don't need lok. The\n  value is in multi-backend orchestration and consensus.\n\n## Quick Start\n\n```bash\ncargo install lokomotiv      # Package is \"lokomotiv\", binary is \"lok\"\n\nlok doctor                   # Check what backends are available\nlok ask \"Explain this code\"  # Query all available backends\nlok hunt .                   # Find bugs in current directory\n```\n\nExample `lok doctor` output when backends are configured:\n\n```\nChecking backends...\n\n  ✓ codex - ready\n  ✓ gemini - ready\n  ✓ claude - ready\n\n✓ 3 backend(s) ready.\n```\n\n## Prerequisites\n\nLok wraps existing LLM CLI tools. Install the ones you want to use:\n\n| Backend | Install | Notes |\n|---------|---------|-------|\n| Codex | `npm install -g @openai/codex` | Fast code analysis |\n| Gemini | `npm install -g @google/gemini-cli` | Deep security audits |\n| Claude | [claude.ai/download](https://claude.ai/download) | Claude Code CLI |\n| Ollama | [ollama.ai](https://ollama.ai) | Local models, no API keys |\n\nFor issue/PR workflows, you also need:\n\n| Tool | Install | Used by |\n|------|---------|---------|\n| gh | [cli.github.com](https://cli.github.com) | `lok run fix`, `lok run review-pr` |\n\nRun `lok doctor` to see which backends are detected. Core commands (`lok ask`,\n`lok hunt`, `lok audit`) work without `gh`.\n\n## Commands\n\n### Analysis\n\n```bash\nlok ask \"Find N+1 queries\"              # Query all backends\nlok ask -b codex \"Find dead code\"       # Specific backend\nlok hunt .                              # Bug hunt (multiple prompts)\nlok hunt --issues                       # Bug hunt + create GitHub issues\nlok audit .                             # Security audit\nlok explain                             # Explain codebase structure\n```\n\n### Code Review\n\n```bash\nlok diff                                # Review staged changes\nlok diff main..HEAD                     # Review branch vs main\nlok run review-pr 123                   # Multi-backend PR review + comment\n```\n\n### Issue Management\n\n```bash\nlok run fix 123                         # Analyze issue, propose fix, comment\nlok ci 123                              # Analyze CI failures\n```\n\n### Multi-Agent Modes\n\n```bash\nlok debate \"Should we use async here?\"  # Backends argue and refine\nlok spawn \"Build a REST API\"            # Break into parallel subtasks\nlok conduct \"Find and fix perf issues\"  # Fully autonomous\n```\n\n### Workflows\n\n```bash\nlok run workflow-name                   # Run a workflow\nlok workflow list                       # List available workflows\n```\n\n### Utilities\n\n```bash\nlok doctor                              # Check installation\nlok backends                            # List configured backends\nlok suggest \"task\"                      # Suggest best backend for task\nlok init                                # Create config file\n```\n\n## Workflows\n\nWorkflows are TOML files that define multi-step LLM pipelines. Steps can depend\non previous steps and run in parallel when possible.\n\n```toml\n# .lok/workflows/example.toml\nname = \"example\"\n\n[[steps]]\nname = \"scan\"\nbackend = \"codex\"\nprompt = \"Find obvious issues in this codebase\"\n\n[[steps]]\nname = \"deep-dive\"\nbackend = \"gemini\"\ndepends_on = [\"scan\"]\nprompt = \"Investigate these findings: {{ steps.scan.output }}\"\n\n[[steps]]\nname = \"comment\"\ndepends_on = [\"deep-dive\"]\nshell = \"gh issue comment 123 --body '{{ steps.deep-dive.output }}'\"\n```\n\n### Workflow Resolution\n\nLok searches for workflows in this order (first match wins):\n\n1. **Project**: `.lok/workflows/{name}.toml`\n2. **User**: `~/.config/lok/workflows/{name}.toml`\n3. **Embedded**: Built into the lok binary\n\nThis means you can override any built-in workflow by creating your own version\nat the project or user level.\n\n### Built-in Workflows\n\nLok ships with these workflows embedded in the binary:\n\n| Workflow | Description |\n|----------|-------------|\n| `diff` | Review git changes with multiple backends |\n| `explain` | Explain codebase structure and architecture |\n| `audit` | Security audit with multiple backends |\n| `hunt` | Bug hunt with multiple backends |\n\nRun `lok workflow list` to see all available workflows. Built-in workflows show\nas \"(built-in)\", which you can override by creating your own version:\n\n```bash\nlok workflow list              # Shows: diff (built-in)\n# Create override:\nmkdir -p .lok/workflows\nlok run diff \u003e /dev/null       # See what it does, then customize:\ncat \u003e .lok/workflows/diff.toml \u003c\u003c 'EOF'\nname = \"diff\"\ndescription = \"My custom diff review\"\n# ... your custom steps\nEOF\nlok workflow list              # Now shows: diff (local)\n```\n\n### Consensus and Error Handling\n\nFor multi-backend steps, you can require consensus and handle partial failures.\n\n**Workflow-level defaults** apply to all steps (steps can override):\n\n```toml\nname = \"my-workflow\"\ncontinue_on_error = true    # All steps continue on failure by default\ntimeout = 300000            # All steps get 5 minute timeout by default\n\n[[steps]]\nname = \"fast_step\"\nbackend = \"codex\"\ntimeout = 60000             # Override: this step gets 1 minute\nprompt = \"Quick analysis...\"\n\n[[steps]]\nname = \"critical_step\"\nbackend = \"claude\"\ncontinue_on_error = false   # Override: this step must succeed\nprompt = \"Important work...\"\n```\n\n**Step-level consensus** for multi-backend synthesis:\n\n```toml\n[[steps]]\nname = \"propose_claude\"\nbackend = \"claude\"\nprompt = \"Propose a fix...\"\n\n[[steps]]\nname = \"propose_codex\"\nbackend = \"codex\"\nprompt = \"Propose a fix...\"\n\n[[steps]]\nname = \"debate\"\nbackend = \"claude\"\ndepends_on = [\"propose_claude\", \"propose_codex\", \"propose_gemini\"]\nmin_deps_success = 2        # Need at least 2/3 backends to succeed\nprompt = \"Synthesize the proposals: {{ steps.propose_claude.output }}...\"\n```\n\nWhen `min_deps_success` is set:\n- Step runs if at least N dependencies succeeded\n- Failed dependencies with `continue_on_error` pass their error output to the prompt\n- Logs \"consensus reached (2/3 succeeded)\" when threshold is met\n\nThis prevents wasted tokens when one backend times out or hits rate limits.\n\n### Hard vs Soft Failures\n\nSteps fail in two ways:\n\n- **Hard failure**: Step fails and workflow stops. This is the default behavior.\n- **Soft failure**: Step fails but workflow continues. Enabled with `continue_on_error = true`.\n\nWhen a soft failure occurs, the error message is passed to dependent steps instead\nof the normal output. This lets downstream steps handle the failure gracefully:\n\n```toml\n[[steps]]\nname = \"risky_step\"\nbackend = \"gemini\"\ncontinue_on_error = true   # Soft failure - workflow continues\nprompt = \"...\"\n\n[[steps]]\nname = \"handler\"\ndepends_on = [\"risky_step\"]\nprompt = \"\"\"\n{% if \"error\" in steps.risky_step.output %}\nHandle the error: {{ steps.risky_step.output }}\n{% else %}\nProcess result: {{ steps.risky_step.output }}\n{% endif %}\n\"\"\"\n```\n\n### Retries\n\nSteps can retry on transient failures with exponential backoff:\n\n```toml\n[[steps]]\nname = \"flaky_backend\"\nbackend = \"gemini\"\nretries = 3              # Retry up to 3 times (default: 0)\nretry_delay = 2000       # Start with 2 second delay (default: 1000ms)\nprompt = \"...\"\n```\n\nThe delay doubles after each retry: 2s, 4s, 8s. Retries help with rate limits\nand temporary network issues. After all retries are exhausted, the step fails\nnormally (hard or soft depending on `continue_on_error`).\n\n### Agentic Features\n\nWorkflows can apply code edits and verify them:\n\n```toml\n[[steps]]\nname = \"fix\"\nbackend = \"claude\"\napply_edits = true\nverify = \"cargo build\"\nprompt = \"\"\"\nFix this issue. Output JSON:\n{\"edits\": [{\"file\": \"src/main.rs\", \"old\": \"...\", \"new\": \"...\"}]}\n\"\"\"\n```\n\n**How `apply_edits` works:**\n\n1. Parses JSON from LLM output looking for `{\"edits\": [...]}`\n2. For each edit, finds `old` text in `file` and replaces with `new`\n3. If `verify` is set, runs the command after edits\n4. If verification fails, the step fails (edits remain applied)\n\n**Risks and failure modes:**\n\n- **File not found**: Edit fails if the target file doesn't exist\n- **Text not found**: Edit fails if `old` text isn't in the file\n- **Ambiguous match**: Edit fails if `old` text appears multiple times\n- **Partial application**: If edit 3 of 5 fails, edits 1-2 remain applied\n\n**Automatic rollback with git-agent:**\n\nIf [git-agent](https://github.com/ducks/git-agent) is installed and initialized,\nlok automatically creates a checkpoint before applying edits. If edits fail or\nverification fails, lok rolls back to the checkpoint.\n\n```bash\n# Install git-agent\ncargo install --git https://github.com/ducks/git-agent\n\n# Initialize in your project\ngit-agent init\ngit-agent begin \"Working on feature X\"\n\n# Now lok will auto-checkpoint before apply_edits\nlok run my-workflow  # Creates checkpoint, applies edits, rolls back on failure\n```\n\nWhen git-agent is active, you'll see:\n```\n  → Applying edits...\n    ✓ git-agent checkpoint created\n    ✓ Applied 3 edit(s)\n  verify: cargo build\n    ✗ Verification failed: ...\n    ↩ Rolled back via git-agent\n```\n\nWithout git-agent, lok still works but won't auto-rollback.\n\n**Recommendations:**\n\n- Use git-agent for automatic rollback on failures\n- Start with `verify` commands to catch bad edits early\n- Review LLM output before running with `--apply` in production\n- Keep `old` text specific enough to match exactly once\n\n### Structured Output\n\nWorkflows can produce JSON output for programmatic consumption. Use the\n`output_format` field to control how LLM responses are parsed:\n\n```toml\n[[steps]]\nname = \"analyze\"\nbackend = \"codex\"\noutput_format = \"json\"    # Parse output as JSON\nprompt = \"Return findings as JSON array...\"\n```\n\nOutput format options:\n- `text` (default): Raw text output\n- `json`: Parse as JSON object\n- `json_array`: Parse as JSON array\n- `jsonl`: Parse as newline-delimited JSON\n\nDownstream steps can access parsed fields:\n\n```toml\n[[steps]]\nname = \"report\"\ndepends_on = [\"analyze\"]\nprompt = \"Summarize: {{ steps.analyze.output.findings }}\"\n```\n\n## Configuration\n\nWorks without config. For customization, create `lok.toml` or\n`~/.config/lok/lok.toml`:\n\n```toml\n[defaults]\nparallel = true\ntimeout = 300\n# Wrap shell commands for isolated environments (NixOS, Docker)\n# command_wrapper = \"nix-shell --run '{cmd}'\"\n# command_wrapper = \"docker exec dev sh -c '{cmd}'\"\n\n[backends.codex]\nenabled = true\ncommand = \"codex\"\nargs = [\"exec\", \"--json\", \"-s\", \"read-only\"]\n\n[backends.ollama]\nenabled = true\ncommand = \"http://localhost:11434\"\nmodel = \"qwen2.5-coder:7b\"\n\n[cache]\nenabled = true\nttl_hours = 24\n```\n\n### Command Wrapper (NixOS/Docker)\n\nIf you use isolated environments, shell commands in workflows may fail due to\nmissing dependencies. Use `command_wrapper` to wrap all shell commands:\n\n```toml\n[defaults]\n# For NixOS with nix-shell\ncommand_wrapper = \"nix-shell --run '{cmd}'\"\n\n# For Docker\ncommand_wrapper = \"docker exec dev sh -c '{cmd}'\"\n\n# For direnv\ncommand_wrapper = \"direnv exec . {cmd}\"\n```\n\nThe `{cmd}` placeholder is replaced with the actual command.\n\n## Backend Strengths\n\n| Backend | Best For | Speed |\n|---------|----------|-------|\n| Codex | Code patterns, N+1, dead code | Fast |\n| Gemini | Security audits, deep analysis | Slow (thorough) |\n| Claude | Orchestration, reasoning | Medium |\n| Ollama | Local/private, no rate limits | Varies |\n\n## Real World Results\n\nLok found 25 bugs in its own codebase, then found a real bug in Discourse\n(35k stars) that became a merged PR.\n\n```bash\nlok hunt ~/dev/discourse --issues -y    # Found hardlink limit bug\n```\n\n## Why \"Lok\"?\n\nSwedish/German: Short for \"lokomotiv\" (locomotive). The conductor sends trained\nmodels down the tracks.\n\nSanskrit/Hindi: \"lok\" means \"world\" or \"people\", as in \"Lok Sabha\" (People's\nAssembly). Multiple agents working as a collective.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fducks%2Flok","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fducks%2Flok","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fducks%2Flok/lists"}