Kodiqa
The AI coding agent that runs anywhere — free locally with Ollama, or supercharged by 8 cloud APIs. One agent, every model, zero limits.
88 slash commands • 34 tools • lazy MCP tools • RAG search • custom personas • plugins • sub-agents • LSP • 5 themes
How Kodiqa Compares
Every cell below was checked against each vendor's own documentation in September 2026. Where a vendor doesn't publish something, the cell says "Not documented" instead of guessing.
| Feature | Kodiqa | Claude Code | Aider | Gemini CLI | OpenCode |
|---|---|---|---|---|---|
| Open source | Yes (AGPL-3.0) | No — proprietary | Yes (Apache-2.0) | Yes (Apache-2.0) | Yes (MIT) |
| Language | Python | TypeScript | Python | TypeScript | TypeScript |
| Install | pip install kodiqa |
install script, Homebrew, WinGet | pip install aider-install |
npm i -g @google/gemini-cli |
install script, npm, Homebrew |
| Price | Free with Ollama, or pay-per-token | $20/mo Pro, from $100/mo Max, or API pay-per-token | Pay-per-token, bring your own key | Free tier: 60 req/min, 1,000 req/day | Pay-per-token, or sign in with an existing ChatGPT Plus/Pro or GitHub Copilot plan |
| Runs fully offline | Yes — Ollama, with managed start/stop | No | Yes — Ollama, LM Studio | No | Yes — Ollama |
| Model providers | 9 — 8 cloud plus local Ollama | Anthropic, plus Bedrock, Vertex and third-party | "Almost any LLM" — 18+ named | Google Gemini | 75+ via Models.dev |
| Built-in tools | 34 | 45+ | Not tool-based — uses edit formats | 8 | 13 |
| MCP | Yes — local, remote, OAuth; and as a server (--mcp-server) |
Yes | Not documented | Yes | Yes |
| On-demand tool loading | Yes — lazy MCP, ~94% fewer schema tokens | Yes — deferred tools via ToolSearch |
No | No | No |
| OpenAPI / GraphQL endpoints as tools | Yes | Not documented | Not documented | Not documented | Not documented |
| Multi-model consensus | Yes | No | No | No | No |
| Cross-provider failover | Yes (/failover) |
No | No | No | No |
| Sub-agents | Yes — research, plus writers that work in a git worktree and hand back a diff; your own in .kodiqa/agents/ |
Yes | No | Not documented | Yes — 3 built-in plus custom |
| Plan mode | Yes | Yes | Architect mode | Not documented | Yes |
| Permissions | 3 modes, plus allow/ask/deny rules per tool and pattern | allow/ask/deny rules plus permission modes | Confirms each edit | Yes, plus sandbox | allow/ask/deny, per tool and per glob |
| Undo | 10 levels per file, plus /rewind |
/rewind and checkpoints |
/undo, git-based |
Checkpointing | /undo and /redo |
| Auto git commit | Yes (/autocommit) |
On request | Yes, on by default | No | Not documented |
| Auto-lint after edits | Yes (/lint) |
Via hooks | Yes, built-in | No | Not documented |
| Web search | Yes — 3 engines | Yes | No | Yes — Google grounding | Yes |
| Persistent memory | Yes — SQLite | Yes — CLAUDE.md plus auto memory | Conventions file | Yes — GEMINI.md plus save_memory |
AGENTS.md |
| RAG over your codebase | Yes (/embed, /rag) |
No | No | No | No |
| Conversation branching | Yes (/branch) |
No | No | No | No |
| Per-session budget cap | Yes (/budget) |
No | No | No | Workspace and monthly limits in Zen |
| Batch edit review | Yes — accept/reject per file | No | No | No | No |
| Auto model discovery | Yes — live from provider APIs | No | No | No | Via Models.dev |
| CI bot (GitHub / GitLab) | Yes — GitHub (/kq in comments) |
Yes | No | Yes — GitHub | Yes |
| Desktop app / IDE | Editor bridge (--serve) |
VS Code, JetBrains, desktop, web, mobile | Browser UI | No | Desktop app plus IDE extension |
| Shareable session link | No | No | No | No | Yes (/share) |
Where Kodiqa stands alone. Multi-model consensus, cross-provider failover, OpenAPI and GraphQL endpoints as callable tools, conversation branching, a per-session spend cap, batch edit review, and RAG over your own codebase. No other agent in this table ships all of them, and most ship none of them.
Where Kodiqa is behind. There is no desktop app and no shareable session links, and the CI bot covers GitHub only. Those are roadmap items, not shipped features.
Install
pip install kodiqa
kodiqa
Requires Python 3.11 or newer. python -m kodiqa works too.
Features
- Claude Code-style UI —
❯prompt with separator line (prompt_toolkit), arrow-key navigation for all prompts - 34 tools — file ops, git, search, web, memory, clipboard, multi-edit, Jupyter notebook cells, undo, diff apply, live task list, background commands, skills,
exploreto delegate research anddelegateto hand a change to a sub-agent in an isolated worktree - 9 API providers — Ollama (local/free), Claude, OpenAI, DeepSeek, Groq, Mistral, Qwen, OpenRouter, Venice (hundreds of models)
- Editor/IDE bridge —
kodiqa --serveexposes a local HTTP API (/ask,/diagnostics) for VS Code/Zed/Neovim extensions - Cross-provider failover — if a provider is down/rate-limited, the turn auto-retries on the next configured provider and continues (
/failover) - TOON output —
/toonre-encodes JSON tool results into a compact tabular form (~60% fewer tokens on large arrays) - Custom commands — drop
.kodiqa/commands/<name>.mdand run it as/<name>(with$ARGUMENTS/$1substitution);/commandslists them - Skills —
.kodiqa/skills/<name>/SKILL.mdinstructions the model loads by itself when a task matches their description;/skillslists them - MCP server support — connect external tool servers via Model Context Protocol
- Lazy MCP tools — large MCP servers are discovered on demand (
mcp_search/mcp_call) instead of injecting every tool schema each turn — ~94% fewer tool-schema tokens (/mcp lazy) - Auto model discovery — new Claude/Qwen models appear automatically from APIs
- Interactive pickers —
/modeland/keyshow numbered menus, navigate with arrows - Tab autocomplete — slash commands, model names, file paths (prompt_toolkit)
- Compact streaming — hides code output, shows progress instead (toggle with
/verbose) - Stream interrupt — press Esc or Ctrl+C to stop any response instantly
- Stream stall indicator — animated spinner when response pauses (so you know it's still working)
- Thinking display — shows spinner for
<think>reasoning blocks, line count summary - Multi-model consensus — query all models, merge best answers
- 3 permission modes — default (confirm all), relaxed (auto file ops), auto (no confirms)
- Plan mode — AI explores + plans, you approve, then it implements
- Batch edit review — queue edits, accept/reject per file with arrow keys
- Context window management — warns at 70%, auto-compacts at 85%, visual progress bar
- Conversation branching — save/switch between conversation states
- Token tracking — cost per response, session totals, tok/s speed
- Prompt caching — Claude API cache for faster + cheaper responses
- Auto-retry — exponential backoff on API errors (429, 5xx, timeouts)
- Undo / redo / rewind — per-file undo (up to 10 levels) with
/redo, plus/rewindto revert ALL file changes from the last turn(s) - Checkpoints — save/restore conversation state
- Session export — export conversation to markdown
- Git-aware context — auto-detects git repo, includes diff stats
- Project indexing — symbol extraction (def/class/function), cached
- Shell env detection — auto-detects OS, shell, dev tools
- Diff preview — colored diff before every file write/edit
- Parallel tools — read-only operations run concurrently
- Session summary — auto-saves context summary on quit, loaded on next start
- Conversation recovery — auto-saved sessions, resume on crash or with
kodiqa -c/--resume - Workspace boundary — asks permission before accessing files outside working directory
- Smart Ollama lifecycle — starts on launch, stops when switching to cloud, restarts on local switch
- Dynamic model library — scrapes ollama.com/library on every launch (never a baked-in list) with pull counts, download sizes, and whether the model fits your RAM
- Unlimited iterations — no artificial cap, AI keeps working until the task is done
- Live API model routing — auto-discovered models from Claude/Qwen APIs routed to correct provider
- Auto git commit — toggle with
/autocommit, auto-commits after AI edits with descriptive message .kodiqaignore— per-project exclusion for scans and searches: file names (secrets.txt,.env), globs (creds_*.json), extensions (*.log) and directories (node_modules/)- Budget limit —
/budget 5sets $5 session limit, warns at 80%, blocks at 100% - Auto-lint —
/lint ruff check --fixruns linter after edits, feeds errors back to AI - Custom personas —
/personaswitches AI expertise (security-expert, code-reviewer, teacher, architect, debugger) - RAG search —
/embedindexes codebase,/ragsearches with AI-enhanced context - Test generation —
/test <file>auto-generates unit tests - Git diff review —
/review-localAI reviews staged changes - Interactive debugger —
/debug <script>runs, catches errors, debugs with AI - Diagram generation —
/diagramgenerates Mermaid diagrams via AI - File watcher —
/watch <path>monitors for changes - Config profiles —
/profile save/loadmanages settings presets - Multi-file refactoring —
/refactor rename/extractacross project - Session history —
/historybrowses and resumes past sessions - Clipboard patches —
/patchapplies diffs from clipboard - Changelog —
/changelogshows version history - Session stats —
/statsshows metrics (files, tools, time, cost) - 1556 tests — pytest test suite, all passing
Arrow-Key UI
All interactive prompts use arrow keys — no typing letters:
Allow: Write file: ~/project/app.py
❯ Yes
Yes, don't ask again — for this action type
No
Navigate with ↑↓ arrows or j/k, press Enter to select, or 1/2/3 to jump.
Prompt uses a separator line (like Claude Code), with a status line under it:
────────────────────────────────────────
❯ your prompt here
deepseek-chat · default · ⎇ feature/login · ctx 25% · $0.12
The status line shows the model, the permission mode (or plan), the git branch, how
full the context is and what the session has cost ($0.00+ when some spend has no
known price). /config set status_line off hides it. Set it to a command and Kodiqa
runs that instead — the session arrives as JSON on stdin (model, cwd, git_branch,
permission_mode, plan_mode, context_tokens, context_limit, context_percent,
cost, cost_complete, tokens_in, tokens_out, version) and the first line it prints,
colours included, is shown:
#!/bin/sh
# ~/.kodiqa/status.sh (chmod +x)
jq -r '"\(.model) · \(.git_branch) · \(.context_percent)% ctx"'
/config set status_line ~/.kodiqa/status.sh
A command that takes more than 2 seconds or fails says so in the line; the prompt never waits on it.
Slash Commands
| Command | What it does |
|---|---|
/model <name> |
Switch model (interactive picker if no arg) |
/models |
List all available models (with live API discovery) |
/multi <models> |
Multi-model consensus mode |
/single |
Back to single model |
/scan [path] |
Scan project into context (with symbol extraction) |
/clear |
Clear conversation history |
/compact |
Summarize conversation to save context |
/memories |
Show stored memories |
/forget <id> |
Delete a memory |
/context |
Show project context file |
/key [provider] |
Add/update API key (interactive picker if no arg) |
/tokens |
Session token usage, cost, context bar |
/config |
Show config / /config reload to reload |
/export |
Export session to markdown file |
/checkpoint [n] |
Save conversation checkpoint |
/restore [n] |
Restore checkpoint (no arg = list all) |
/env |
Show detected shell environment |
/verbose |
Toggle compact/verbose streaming |
/mode [mode] |
Set permission mode (default/relaxed/auto) |
/permissions |
Allow/ask/deny rules: list, add, remove, and check <tool> <arg> to see how a call is decided |
/plan |
Toggle plan mode (explore → approve → implement) |
/accept |
Toggle batch edit review |
/search <engine> |
Switch search engine (duckduckgo/google/api) |
/cd <path> |
Change working directory |
/branch |
Save/switch/list conversation branches |
/mcp |
Manage MCP tool servers (add/remove/list) |
/autocommit |
Toggle auto git commit after AI edits |
/budget <amount> |
Set session budget limit (warns 80%, blocks 100%) |
/undo [path] |
Undo last edit / list undo history |
/redo [path] |
Re-apply an undone edit / list redo history |
/rewind [n] |
Revert all file changes from the last n turns (default 1) |
/diff [args] |
Show git diff (supports --staged etc.) |
/lint <cmd> |
Auto-lint after edits (/lint off to disable) |
/toon [on|off] |
Compact JSON tool results into TOON (saves tokens) |
/pin <path> |
Pin file to always include in context |
/unpin <path> |
Remove pinned file |
/alias <name> <cmd> |
Create command alias |
/commands |
List custom prompt-template commands (.kodiqa/commands/*.md) |
/skills [name] |
List skills the model can load on demand, or show one |
/jobs |
List background commands; /jobs log <id>, /jobs stop <id>, /jobs stop all |
/unalias <name> |
Remove command alias |
/notify |
Toggle desktop notifications for long tasks |
/optimizer |
Toggle cost optimizer tips |
/theme <name> |
Switch UI theme (dark/light/dracula/monokai/nord) |
/share |
Export session as styled HTML (tool output is left out) |
/pr [title] |
Create GitHub PR via gh CLI |
/review [number] |
Review PR diff via gh CLI |
/issue [number] |
View GitHub issue via gh CLI |
/init [template] |
Scaffold project from template (existing files are kept) |
/plugins |
List/reload custom tool plugins |
/agent [@name] <task> |
Spawn a read-only research sub-agent, or one of your own from .kodiqa/agents/ |
/delegate [@name] <task> |
A sub-agent makes a change in an isolated git worktree; you review the diff before anything is written |
/agents |
List your sub-agent definitions (and why a broken one is refused), then running/completed ones |
/lsp [start|stop] |
Start/stop Language Server Protocol |
/voice |
Voice input via sox + Whisper |
/changelog |
Show version history |
/stats |
Session metrics (files, tools, time, cost) |
/review-local |
AI review of staged git changes |
/test <file> |
Generate unit tests for a file |
/persona <name> |
Switch AI persona (security-expert, code-reviewer, etc.) |
/patch |
Apply diff/patch from clipboard |
/profile |
Save/load config profiles |
/refactor |
Multi-file refactoring (rename, extract) |
/history |
Browse and resume past sessions |
/watch <path> |
Watch files for changes |
/embed [path] |
Index files for RAG search |
/rag <query> |
RAG search + AI answer |
/debug <script> |
Run script, catch errors, debug with AI |
/diagram <desc> |
Generate Mermaid diagram |
/help |
Show help |
/quit |
Exit |
Permission Modes
| Mode | Behavior |
|---|---|
default |
Arrow-key confirm for all writes/commands (Yes / Don't ask again / No) |
relaxed |
Auto-approve file operations, only confirm commands + deletes |
auto |
No confirmations — everything auto-approved |
Switch with /mode relaxed or /mode auto. Default is default.
Permission Rules
Say exactly what may run without asking, what must always ask, and what must never happen — per tool and per argument. In ~/.kodiqa/config.json, or with /permissions allow|ask|deny <rule>:
"permissions": {
"allow": ["run_command(npm test*)", "run_command(git status)", "edit(docs/**)"],
"ask": ["run_command(git push*)", "edit(migrations/**)"],
"deny": ["read(.env*)", "read(~/.ssh/*)", "web_fetch(domain:internal.example.com)"]
}
- A rule is
toolortool(pattern).readcovers every file-reading tool (read_file, grep, glob, tree, …),editevery file-writing one, andmcp_github_*a whole MCP server. deny › ask › allow › your mode.denyrefuses in every mode, for sub-agents too.askalways asks, even in auto mode and after "don't ask again", and a headless run refuses it.allowskips the prompt even in default mode.- Hard to get around. A command is allowed only when every part of it matches, so
npm test*does not allownpm test && curl … | sh. Anything the rule matcher does not fully understand —$(…), backticks, redirections, backslash escapes, comments,$'…'quoting, subshells or groups, or an unclosed quote — is never auto-allowed. Paths are resolved first, so./x/../.envand a symlink to.envare still.env. On macOS and Windows,.ENVcounts as.env. A rule naming a directory covers everything inside it. A symlink cannot borrow anallowfrom the name it is reached through. Areadrule also hides the file from grep and fromgit_diff, which refuses--no-index,--outputand external diff drivers. Aweb_fetchrule is checked on every redirect, with hosts normalised (case, trailing dot, default port). Direct and lazy MCP calls are both checked under the real tool's name. - Projects can tighten, never loosen.
.kodiqa/permissions.jsonin a project may addaskanddenyrules. Anallowthere is ignored with a warning, because a cloned repository must not grant itself permission to run commands. - Nothing is dropped silently. A malformed rule, an unknown tool or a pattern on a tool that takes none is reported at startup and in
/permissions./permissions check run_command "npm test && rm -rf x"shows how a call would be decided, part by part. - Limits: a shell command can read any file, and a determined command can be disguised (
command rm,eval, a script file) past adeny run_command(rm *)rule. Commanddeny/askrules catch honest mistakes; for a guarantee, deny or askrun_commandas a whole.
Hooks
Run your own command before or after any tool, in ~/.kodiqa/config.json:
"hooks": {
"pre_run_command": "./scripts/allow-command.sh {command}",
"post_write_file": "ruff check {path}"
}
Keys are pre_<tool> / post_<tool>; {param} is replaced by that tool parameter, shell-quoted.
- A pre-hook is a gate. The tool runs only if the hook exits 0. A non-zero exit, a timeout (30s) or a hook that cannot start all block it, and the model is told why, including the hook's output.
- A post-hook reports. The action has already happened, so it cannot be blocked; if the hook fails, its output is added to the tool result so the model can fix what it flagged.
- With batch edit review, a file's post-hook runs when you accept the edit and it is written, not when it is queued.
- For a background command,
post_run_commandruns once the command has started, not when it ends. - A hook that needs longer than 30 seconds can be an object:
{"command": "npm test", "timeout": 300}(up to an hour). - A key that would never fire, such as
on_stop,post_writeorpre_explore, is reported at startup instead of being silently ignored.
Session events
Four more hooks run at points in the session rather than around a tool. Each gets the event as JSON on stdin; nothing is substituted into the command line, so the prompt cannot inject anything.
| Hook | When | Exit 0 | Non-zero exit |
|---|---|---|---|
user_prompt_submit |
before your message goes to the model | its output is added to the message as context | the message is not sent (also on a timeout) |
stop |
when the model finishes its turn | done | its output goes back to the model to fix, up to 3 times |
session_start |
when a session (or a headless run) starts | its output is context for the whole session | reported |
pre_compact |
before /compact or auto-compaction |
its output is extra instructions for the summary | reported; compaction goes ahead |
"hooks": {
"session_start": "cat docs/SPRINT.md",
"stop": {"command": "python -m pytest -q -x", "timeout": 300}
}
With a stop hook that runs the tests, the model does not finish until they pass, or until three attempts are used up. A stop hook that times out or cannot start is reported to you, not handed to the model, since the model cannot fix a broken hook. It does not run in plan mode, in multi-model mode, after an interrupt, or once the budget is spent.
Skills
A skill is a set of instructions the model loads on its own when a task calls for it: how this project cuts a release, writes migrations, or formats a changelog entry. Only each skill's name and one-line description sit in the prompt, so a project can carry many of them for a few dozen tokens each. When a task matches a description, the model calls the skill tool and gets the full instructions.
.kodiqa/skills/changelog-entry/SKILL.md (project; ~/.kodiqa/skills/ for global)
---
description: How this project writes changelog entries. Use whenever asked to
write or add a changelog or release-notes entry.
---
1. The first line is exactly: `### Entry`
2. One bullet per change, each starting with a past-tense verb.
3. End with the ticket id from templates/ticket.txt.
- The directory name is the skill's name. A project skill wins over a global one with the same name.
- A skill can carry files. The model is told the skill's directory, so
templates/ticket.txtabove is read from there. - A broken skill is reported.
/skillslists every skill; one with nodescription, or with unclosed frontmatter, is shown with the reason instead of silently doing nothing./skills <name>prints one. - Skill or custom command? A custom command (
.kodiqa/commands/) runs when you type it. A skill is picked up by the model when the task matches, even if you never mention it.
Background Commands
A dev server, a file watcher or a long test run no longer blocks the turn — or gets killed at the 120-second command timeout. The model starts it with run_command and background: true, gets a job id at once, and keeps working:
run_command npm run dev (background) → Started job_1 (pid 48211)
job_output job_1 until "ready|listening" → waits until the server is up (max 60s)
run_command curl -s localhost:5173/api/health
job_output job_1 → only the lines printed since the last read
job_stop job_1 → stops npm and everything it started
- Same protections as any command — the confirmation prompt (relaxed mode still asks), the blocklist,
/sandboxandpre_run_commandhooks all apply. - Never hangs on its own output — output goes to a log file, so a chatty process can't fill a pipe and freeze; each read returns only new output, capped to the last 20 KB.
- Stops cleanly — each job runs in its own process group, so stopping it stops its children too. Quitting Kodiqa (or a crash, or the end of a headless run) stops every job, so no server is left holding a port.
/jobslists what's running;/jobs log <id>shows the recent output without taking it from the model;/jobs stop <id>or/jobs stop all.
Plan Mode
Activate with /plan. The AI will:
- Explore — read files, search, analyze (no writes allowed)
- Present plan — show what it intends to do
- You decide — approve, revise, or reject (arrow keys)
- Implement — on approval, AI executes the plan
Batch Edit Review
When enabled (default ON, toggle with /accept), file edits are queued and presented for review:
? (1/3) app.py — write +15 -3 lines
❯ Accept
Reject
Show diff
Accept all — remaining 3 edits
Reject all
Navigate with arrow keys, view diffs, accept/reject individually or in bulk.
MCP Server Support
Connect external tool servers via the Model Context Protocol — local or remote:
# Local (stdio) server — a command Kodiqa runs
/mcp add fs npx -y @modelcontextprotocol/server-filesystem ~/projects
# Remote (HTTP) server — a hosted URL, with optional auth
/mcp add linear https://mcp.linear.app/mcp --bearer env:LINEAR_TOKEN
/mcp add api https://example.com/mcp --header "X-Api-Key:abc123"
# Remote with OAuth login (opens your browser)
/mcp add linear https://mcp.linear.app/mcp --oauth
# …or machine-to-machine (no browser)
/mcp add api https://example.com/mcp --oauth-client-id env:CID --oauth-client-secret env:CSEC
# Any REST API via its OpenAPI spec — each operation becomes a tool (no codegen)
/mcp add petstore --spec https://petstore3.swagger.io/api/v3/openapi.json
# Any GraphQL endpoint — each query/mutation becomes a tool
/mcp add gql --graphql https://api.example.com/graphql --bearer env:TOKEN
/mcp list # show servers + kind ([stdio]/[http]/[openapi]/[graphql]) + lazy mode
/mcp remove mytools # disconnect
/mcp lazy [on|off] # toggle lazy tool loading (default: on)
Remote servers use the Streamable HTTP transport. Auth values support env:VAR and
file:PATH so tokens aren't typed inline. OAuth (--oauth) handles discovery, dynamic
client registration, the PKCE browser login, and automatic token refresh — tokens are cached
under ~/.kodiqa/oauth/ and reused across sessions.
MCP tools are automatically available to the AI alongside built-in tools, and work with lazy mode (discovered on demand).
⚡ Lazy MCP tools — save up to 94% of tool-schema tokens
Most agents paste every MCP tool's JSON schema into every request, so a big MCP server quietly taxes every turn. Kodiqa doesn't. When servers are connected, it exposes 3 fixed meta-tools and lets the model discover tools on demand:
| Per-turn tool-schema cost (50-tool server) | |
|---|---|
| Inject all schemas (typical agents) | ~5,300 tokens |
| Kodiqa lazy mode | ~310 tokens (~94% less) |
mcp_search— find tools by keyword, ranked by how often you've used themmcp_tool_schema— fetch one tool's full schema only when neededmcp_call— run a tool by name
It's on by default, fully automatic (the model drives it), and the cost stays
flat no matter how many MCP tools you connect. Toggle with /mcp lazy off, or set
mcp_lazy: false in settings to always inject every schema.
Kodiqa as an MCP server
The other direction: kodiqa --mcp-server lets Claude Desktop, Cursor, Claude Code or any
MCP client hand work to Kodiqa's sub-agents, with whatever model Kodiqa is set to — a cheap
DeepSeek or a local Ollama model doing the legwork for a pricier assistant.
| Tool | What it does |
|---|---|
explore |
A read-only sub-agent investigates the project and returns a report. |
delegate |
A writing sub-agent makes the change in a throwaway git worktree and returns its report and the diff. Your files are written only when the client calls it with apply: true, so the diff can be shown first. |
ask |
One question to Kodiqa's model, no tools. |
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"kodiqa": {
"command": "kodiqa",
"args": ["--mcp-server", "--model", "deepseek-chat", "--cwd", "/path/to/project"],
"env": { "DEEPSEEK_API_KEY": "sk-..." }
}
}
}
Claude Code: claude mcp add kodiqa -- kodiqa --mcp-server --model deepseek-chat
Everything the REPL enforces still holds: your permission rules, the sandbox for delegate's
commands (delegate_commands), and your agents in .kodiqa/agents (pass agent). Calls run
concurrently, and stdout carries nothing but the protocol.
Model Shortcuts
Local Models (free, unlimited, requires Ollama)
| Shortcut | Full Model | Best For |
|---|---|---|
/model fast |
qwen3:30b-a3b | Fast answers, 30B brain at 3B speed (MoE) |
/model qwen |
qwen3:14b | General purpose, smart, thinking mode |
/model coder |
qwen3-coder | Coding agent (default without API key) |
/model reason |
phi4-reasoning | Deep reasoning, math, logic |
/model gpt-local |
gpt-oss | OpenAI's open model, reasoning + agentic |
Claude API Models (paid, requires API key)
| Shortcut | Full Model | Price (in/out per MTok) |
|---|---|---|
/model claude / sonnet |
claude-sonnet-4-6 | $3/$15 |
/model opus |
claude-opus-4-6 | $5/$25 |
/model haiku |
claude-haiku-4-5 | $1/$5 |
/model sonnet-4.5 |
claude-sonnet-4-5 | $3/$15 |
/model opus-4.5 |
claude-opus-4-5 | $5/$25 |
/model opus-4.1 |
claude-opus-4-1 | $15/$75 |
/model sonnet-4 / opus-4 |
Legacy Claude 4 | varies |
Qwen API Models (paid, Alibaba Cloud DashScope)
| Shortcut | Full Model | Best For |
|---|---|---|
/model qwen3.5 / qwen-plus |
qwen3.5-plus | Newest flagship |
/model qwen-max / qwen3-max |
qwen3-max | Most powerful |
/model qwen-coder / qwen3-coder |
qwen3-coder-plus | Coding |
/model qwen-coder-next |
qwen3-coder-next | Newest coder |
/model qwq |
qwq-plus | Deep reasoning |
/model qwen-flash |
qwen3.5-flash | Fast |
/model qwen-turbo |
qwen-turbo | Cheapest/fastest |
/model qwen-math |
qwen-math-plus | Math |
/model glm-5 |
glm-5 | Third-party (Coding Plan) |
/model kimi |
kimi-k2.5 | Third-party (Coding Plan) |
Qwen Coding Plan: If you have a Coding Plan subscription (sk-sp- key), /key qwen auto-detects it and configures the dedicated endpoint. Supports $3/mo Lite and $15/mo Pro tiers.
OpenAI API Models (paid, requires API key)
| Shortcut | Full Model | Best For |
|---|---|---|
/model gpt |
gpt-4o | General purpose flagship |
/model gpt-mini |
gpt-4o-mini | Fast and cheap |
/model o3 |
o3 | Deep reasoning |
/model o3-mini |
o3-mini | Fast reasoning |
/model o4-mini |
o4-mini | Latest reasoning |
DeepSeek API Models (paid, requires API key)
| Shortcut | Full Model | Best For |
|---|---|---|
/model deepseek |
deepseek-chat | V3 general purpose |
/model deepseek-r1 |
deepseek-reasoner | R1 deep reasoning |
Groq API Models (free tier available)
| Shortcut | Full Model | Best For |
|---|---|---|
/model llama |
llama-3.3-70b-versatile | Best open model |
/model llama-small |
llama-3.1-8b-instant | Ultra fast |
/model gemma |
gemma2-9b-it | Google's open model |
/model mixtral |
mixtral-8x7b-32768 | MoE, 32K context |
Mistral API Models (paid, requires API key)
| Shortcut | Full Model | Best For |
|---|---|---|
/model mistral |
mistral-large-latest | Flagship |
/model mistral-small |
mistral-small-latest | Fast and cheap |
/model codestral |
codestral-latest | Code generation |
New models are auto-discovered from the APIs — they appear in /model and /models automatically.
You can also use full model names: /model qwen3:14b or /model claude-opus-4-6
Editor / IDE bridge
Run Kodiqa as a small local HTTP server that your editor (VS Code, Zed, Neovim, …) can call:
kodiqa --serve # prints the URL + an auth token
# or, inside a session: /serve
It binds to 127.0.0.1 only and requires the printed bearer token. Set a stable
token (handy for editor config) with KODIQA_BRIDGE_TOKEN=…, and a fixed port with
--port. Protocol:
| Endpoint | ||
|---|---|---|
GET /health |
no auth | {status, model, version} |
POST /ask |
{prompt, context?} |
{response} — one-shot model answer (no history, no file edits) |
GET /diagnostics?file=PATH |
{file, diagnostics} from the LSP (start one with /lsp) |
curl -s localhost:PORT/ask -H "Authorization: Bearer TOKEN" \
-d '{"prompt":"explain this","context":"def f(): return 1"}'
/ask is a safe, non-streaming Q&A call — ideal for "ask Kodiqa about the selection."
A minimal reference client is in examples/bridge_client.py; editor
extensions are thin clients over this API.
GitHub bot
Mention /kodiqa or /kq in an issue or pull-request comment and Kodiqa does the
work in your own Actions runner, replies in the thread, and opens a pull
request when it changed something.
/kq the parser drops the last token when the input ends in a comma — fix it
Copy examples/workflows/kodiqa.yml to
.github/workflows/kodiqa.yml, add your provider key under Settings → Secrets
and variables → Actions, and turn on Settings → Actions → General → Allow GitHub
Actions to create and approve pull requests (off by default; in an organization it
must be allowed there first). Without it the change is pushed to a branch and the
comment links to it, but no pull request is opened. That is the whole setup:
- uses: Kodiqa-Solutions/Kodiqa-agent/github@v3.41.0
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
with:
model: claude-sonnet-4-6
Currently internal. The source repository is private, and GitHub only lets a private repository's action be used inside its own organization — and only once the repository allows it (Settings → Actions → General → Access: accessible from repositories in the organization). Until it is public, this
uses:line resolves for Kodiqa-Solutions repositories only.
Any provider works — set DEEPSEEK_API_KEY, GROQ_API_KEY, OPENROUTER_API_KEY
and so on, and name a model that provider serves. Keys are read from the
environment, so nothing is written to disk in the runner.
Only maintainers can command it
A workflow that runs an agent hands your API key and your runner to whoever can
make the job start. Kodiqa only acts on comments from an OWNER, MEMBER or
COLLABORATOR — GitHub decides that, not the commenter — and, on issues or
pull_request events, only on issues and PRs they opened. Anyone else is logged and
ignored before any model call, so a drive-by comment on a public repository costs
nothing.
What the agent reads from other people (the thread, an issue body) is marked in its
prompt as untrusted information, not instructions. The agent never gets the job's GitHub
token: it is removed from its environment, and the credential actions/checkout keeps
in .git/config is taken out while the agent runs and used only for the bot's own push.
Set require-trusted: false to lift that, and only on a private repository.
What else it can do
| Event | What happens |
|---|---|
issue_comment on an issue |
Reads the thread, makes the change, opens a PR |
issue_comment on a PR |
Commits to that PR's own branch (not pushed when the PR comes from a fork) |
pull_request_review_comment |
Gets the exact file, line and hunk you commented on |
pull_request |
Reviews the diff automatically — see kodiqa-review.yml |
schedule / workflow_dispatch |
Runs the workflow's prompt — see kodiqa-scheduled.yml |
| Input | Default | |
|---|---|---|
model |
— | Required. Any model Kodiqa can reach |
prompt |
"" |
The task, for events with no comment to read |
mentions |
/kodiqa,/kq |
Trigger phrases, case-insensitive |
require-trusted |
true |
Ignore comments from non-maintainers |
kodiqa-version |
latest | Pin a version |
python-version |
3.12 |
Python used in the runner |
github-token |
github.token |
Token for reading, commenting and pushing |
A review job only needs contents: read and pull-requests: write; a job that
should open PRs needs contents: write too. Grant the smaller set where you can —
a job that cannot write cannot be talked into writing.
Sub-agents
/agent hands a question to a research sub-agent that runs its own tool loop in
the background — reading files, grepping, listing directories — and reports back,
while you keep working:
❯ /agent where is the retry logic for provider requests, and what does it retry on?
● Spawned agent_1: where is the retry logic... (read-only; /agents to check)
❯ /agents
● agent_1 done — where is the retry logic...
╭─ agent_1 ─────────────────────────────────────────────────────╮
│ _retry_api_call in kodiqa/agent.py retries on 429 and 5xx... │
It has its own context: the research never lands in your conversation, only the
report does. It is read-only — read_file, grep, glob, tree, list_dir,
git_status, git_diff, read_pdf, read_image, web_search, web_fetch,
memory_search — so it never needs to ask you anything and can safely run in the
background. Paths outside your project are refused rather than prompted for.
/team <task> splits a task into up to four subtasks, runs a sub-agent on each in
parallel, and merges what they found.
The model can delegate by itself
You do not have to type /agent. The explore tool lets the model hand an
open-ended question to a sub-agent on its own — "where is retry handled", "which
callers pass a timeout" — and continue with only the report. Several explore calls in
one turn run in parallel. The investigation never lands in your conversation, so a
search that needed twenty reads costs your context one reply.
Sub-agent spending is booked against the session, so /budget covers it, and a
sub-agent stops before its next request once the budget is spent.
Works with Claude, every OpenAI-compatible provider, and local Ollama models that support tool calling.
Your own sub-agents
Define a specialised sub-agent in .kodiqa/agents/<name>.md (or ~/.kodiqa/agents/ for every project):
---
description: Reviews code for real bugs. Use whenever asked to review or check code.
tools: read_file, grep, glob, git_diff # optional — narrows the default read-only set
model: deepseek-chat # optional — an alias or full id; default: your model
max_steps: 20 # optional — 1 to 50, default 15
---
You are a strict code reviewer. For each real defect give file:line, what goes
wrong, and one input that triggers it. Do not report style issues.
- The model picks it by itself. It sees each agent's name and description and delegates with
exploreandagent: "reviewer"when a task matches. You can call one directly with/agent @reviewer <task>. - Its own model. A cheap, fast model can do the searching while your main model does the thinking. Its spend is booked at that model's price and counts toward
/budget. - Read-only unless it is a writer. A definition whose
toolsinclude a file-writing tool (edit_file,write_file, …) is a writing agent, and runs only throughdelegate(below). No sub-agent can run commands, so a definition asking forrun_commandis not loaded./agentslists every definition and says why a broken one was refused.
Sub-agents that make changes: delegate
The model can hand a whole change to a sub-agent — "add input validation to every handler in api/" — and keep its own context for the rest of the task. You can too: /delegate [@agent] <task>.
● Delegate add input validation to every handler in api/
Sub-agent changes (4 file(s), +38 -6)
diff --git a/api/users.py b/api/users.py
...
Allow: Apply sub-agent changes: 4 file(s), +38 -6
-
It works on a copy, never on your files. A throwaway
git worktreeoutside your project, holding your working tree as it is right now, including uncommitted changes and new untracked files. -
You see one diff and decide. Accept applies it to your files, with
/undoper file. Reject writes nothing, and the patch is kept in~/.kodiqa/patches/. The prompt follows your permission mode, as any file write does (autoandrelaxedapply without asking). -
All or nothing. If your files changed meanwhile and the diff no longer applies, nothing is written and the patch is saved. Several
delegatecalls in one turn run in parallel, each in its own worktree, and are reviewed in order. -
Confined. Every path is resolved inside the worktree. Anything outside it, and anything under
.git, is refused. Your extra allowed directories do not apply to it. -
It can run the tests, sandboxed. Opt in with
/config set delegate_commands on, or listrun_commandin a writing agent'stools. Its commands then run in an OS sandbox (sandbox-execon macOS,bwrapon Linux):- they write only inside its copy and a private temp dir, never your project,
/tmpor another sub-agent's worktree; - no outbound network, and no unix sockets (so no
docker, which could otherwise write anywhere); - no background jobs, and nothing a command starts outlives it;
- no new symlinks on macOS;
- your permission rules still apply.
Files the test run leaves behind (
__pycache__/,.pytest_cache/,node_modules/,*.pyc…) are left out of the diff.It is told where your git-ignored
venv/ornode_modules/are, to run the tests with them. Without an OS sandbox it gets no commands at all, and the result says so. - they write only inside its copy and a private temp dir, never your project,
-
Leaves nothing behind. No branch, no directory in your project, no git hooks run. The worktree is removed even if the sub-agent fails or you interrupt it.
-
Needs a git repository with at least one commit.
Scripting and CI
Run a task without the UI and get the answer back:
kodiqa --headless "add error handling to the retry loop in client.py"
With --format json, stdout carries one object and nothing else — every panel,
spinner and diff moves to stderr — so it pipes straight into jq:
kodiqa --headless "audit the dependencies" --format json | jq
cat long-task.md | kodiqa --headless - --format json # "-" reads the task from stdin
{
"ok": true,
"task": "audit the dependencies",
"model": "claude-sonnet-4-6",
"result": "Two packages are a major version behind …",
"error": "",
"files_changed": ["requirements.txt"],
"tools_used": {"read_file": 6, "edit_file": 1, "run_command": 2},
"counts": {"messages": 1, "files_read": 6, "files_edited": 1, "commands_run": 2, "searches": 0},
"tokens": {"input": 84210, "output": 6120, "cache_read": 71000, "cache_creation": 0},
"cost": 0.3271,
"elapsed_s": 128.4
}
Which makes the usual CI things one-liners:
# fail the job if a task costs more than a dollar
COST=$(kodiqa --headless "$TASK" --format json | jq '.cost')
awk "BEGIN{exit !($COST > 1.0)}" && echo "too expensive" && exit 1
# did it actually change anything?
kodiqa --headless "$TASK" --format json | jq -e '.files_changed | length > 0'
To follow a run as it happens, --format stream-json prints one JSON event per line
instead — each tool call before it runs, its result when it finishes — and ends with
that same object as "type": "result":
kodiqa --headless "why do the tests fail?" --format stream-json
{"type": "init", "model": "deepseek-chat", "cwd": "/work/app", "version": "3.40.0", "permission_mode": "auto"}
{"type": "user", "text": "why do the tests fail?"}
{"type": "tool_use", "id": "call_0", "name": "run_command", "input": {"command": "python3 -m unittest -q"}}
{"type": "tool_result", "id": "call_0", "content": "FAIL: test_add (test_calc.T) …"}
{"type": "assistant", "text": "Both tests fail: add() subtracts, and clamp() uses low twice."}
{"type": "result", "ok": true, "result": "Both tests fail: …", "files_changed": [], "cost": 0.0021, …}
The events read the same whichever provider ran the task. A compact event marks an
automatic compaction; nothing before it is repeated after it.
Scheduled runs. A headless run needs no terminal, and --cwd points it at a project
without a cd, so cron or launchd can run Kodiqa on a timetable:
# crontab -e — every weekday at 07:00, append the result as JSON lines
0 7 * * 1-5 DEEPSEEK_API_KEY=sk-... kodiqa --headless "review yesterday's commits for bugs" --cwd ~/code/app --model deepseek-chat --format json >> ~/kodiqa-daily.jsonl 2>/dev/null
With no one to ask, a headless run refuses anything that would need approval (a path outside
the project, an ask permission rule) instead of waiting. For a schedule on GitHub instead
of your machine, see examples/workflows/kodiqa-scheduled.yml.
Exit codes. 0 when the run produced an answer or changed a file, 1 when it
raised — and 1 when it finished having produced nothing at all. That last case is
what an unreachable provider or an uninstalled local model looks like: Kodiqa prints
a hint and returns normally, which would otherwise report success for a run that
never happened.
--result FILE writes just the final answer, and --output FILE the full
transcript, if a file suits you better than stdout.
Compact Streaming Mode
By default, Kodiqa hides code blocks during streaming and shows progress instead:
Kodiqa I'll create the project structure...
⠋ Writing code (javascript)... 45 lines, 1,890 chars
╰─ code block: javascript 45 lines, 1,890 chars
Now the package.json:
⠋ Writing code (json)... 12 lines, 340 chars
╰─ code block: json 12 lines, 340 chars
1,204 in / 847 out | 42.3 tok/s | ($0.0061 / session: $0.0183)
Use /verbose to toggle full output (see all code as it streams).
API Setup
Use /key to add API keys interactively (shows all 8 providers), or specify directly:
| Provider | Command | Get Key |
|---|---|---|
| Claude | /key claude |
https://console.anthropic.com/settings/keys |
| OpenAI | /key openai |
https://platform.openai.com/api-keys |
| DeepSeek | /key deepseek |
https://platform.deepseek.com/api_keys |
| Groq | /key groq |
https://console.groq.com/keys |
| Mistral | /key mistral |
https://console.mistral.ai/api-keys |
| Qwen | /key qwen |
https://bailian.console.alibabacloud.com/?apiKey=1 |
| Venice | /key venice |
https://venice.ai/settings/api |
Then switch: /model claude, /model gpt, /model deepseek, /model llama, /model mistral, /model qwen3.5
Keys from the environment
Every provider also reads its key from the environment, which takes precedence
over settings.json. This is what makes CI, devcontainers and direnv work
without a settings file — and it lets you override a stored key for one shell.
| Provider | Environment variable |
|---|---|
| Claude | ANTHROPIC_API_KEY |
| OpenAI | OPENAI_API_KEY |
| DeepSeek | DEEPSEEK_API_KEY |
| Groq | GROQ_API_KEY |
| Mistral | MISTRAL_API_KEY |
| Qwen | QWEN_API_KEY or DASHSCOPE_API_KEY |
| Venice | VENICE_API_KEY |
| OpenRouter | OPENROUTER_API_KEY |
If one of those names is already taken by something else, KODIQA_<PROVIDER>_API_KEY
wins over it. A key found in the environment is never written to settings.json —
the environment owns that value. /help marks such providers as connected, from env.
What You Can Ask
File Operations
read the file ~/.zshrc
create a file called hello.py with a hello world program
edit main.py and change the function name from foo to bar
move config.json to config.backup.json
delete the temp file at ~/scratch.txt
Multi-Edit & Undo
rename all occurrences of "oldName" to "newName" in utils.py
undo the last edit to main.py
Search
find all .py files in ~/projects
search for "TODO" in my project
Commands & Git
run npm install
show me the git status
commit these changes with message "fix login bug"
Web Search
search the web for kotlin coroutines tutorial
fetch the content from https://some-docs-page.com
Memory
remember that I prefer Kotlin for Android development
what do you remember about my preferences?
Images & PDFs
look at this screenshot ~/Desktop/screenshot.png
read the PDF ~/Documents/report.pdf
Clipboard
paste what's on my clipboard
copy this code to clipboard
Project Analysis
/scan ~/myapp
now explain what this project does
find any bugs in this code
Safety
- Auto-approved: reading files, listing dirs, searching, web, memory, clipboard read, undo
- Asks permission: writing/editing files, running commands, git commits, delete, move, clipboard write, patches
- Workspace boundary: asks before accessing files outside current working directory (Allow once / Allow directory / Deny)
- Blocked:
rm -rf /,sudo rm,mkfs,dd, fork bombs, etc. - Permission modes:
/mode default(confirm all) →/mode relaxed(auto file ops) →/mode auto(no confirms)
34 Tools
| Category | Tools |
|---|---|
| File ops | read_file, write_file, edit_file, multi_edit, search_replace_all, create_directory, move_file, delete_file, undo_edit |
| Notebooks | notebook_edit (replace, insert or delete one .ipynb cell; read_file shows a notebook as cells) |
| Search | glob, grep, list_dir, tree |
| Commands | run_command (foreground or background), job_output, job_stop |
| Git | git_status, git_diff, git_commit |
| Web | web_search, web_fetch |
| Media | read_image, read_pdf |
| Memory | memory_store, memory_search |
| Clipboard | clipboard_read, clipboard_write |
| Patch | diff_apply |
| Tasks | todo_write |
| Delegation | explore (read-only research), delegate (a change in an isolated worktree, reviewed as a diff) |
| Skills | skill (loads a SKILL.md on demand) |
| UX | ask_user |
Files
~/LLMS/kodiqa/
kodiqa/ # the package (everything imports as kodiqa.<module>)
agent.py # Main agent (7558 lines)
actions.py # Action handlers (1287 lines)
tools.py # Tool schemas (497 lines)
config.py # Config, themes, provider registry (1046 lines)
web.py # Web search + page fetch (241 lines)
memory.py # SQLite persistent memory (94 lines)
mcp.py # MCP client (444 lines)
templates.py # 5 project templates (61 lines)
lsp.py # LSP client (272 lines)
embeddings.py # RAG vector store (92 lines)
repomap.py # Tree-sitter/regex repo map (163 lines)
github/ # the GitHub action (not part of the pip package)
examples/ # bridge client + workflow templates
bin/kodiqa # Global install script
tests/ # 1556 tests (pytest)
pyproject.toml # Package config (pip install .)
requirements.txt # Dependencies
~/.kodiqa/
config.json # User-editable config (overrides defaults)
settings.json # API keys, default model
memory.db # Persistent memories
session.json # Auto-saved conversation
input_history # prompt_toolkit FileHistory
error.log # Error log (capped 1MB)
KODIQA.md # Global context (always in system prompt)
projects/ # Per-project context files
checkpoints/ # Conversation checkpoints
exports/ # Exported session markdown files
Tips
- All prompts use arrow keys — no typing letters, just navigate and press Enter
- Default is compact mode — code hidden during streaming, progress shown instead
- Use
/verbosewhen you want to see code as it streams - Use
/mode relaxedto skip file edit confirmations - Use
/planfor complex tasks — review the plan before implementation - Use
/acceptto toggle batch edit review on/off - Use
/branch savebefore experimenting — switch back if it goes wrong - Use
/mcp addto connect external tool servers - Use
/checkpointbefore risky operations,/restoreto roll back - Use
/exportto save a conversation for later reference - Use
/tokensto monitor API costs and context usage - Use
/modelwith no arg for interactive picker - Use
/keywith no arg to choose provider - Tab complete works for commands, models, and file paths
- New API models appear automatically — no code updates needed
- Memories persist forever across sessions
- Arrow keys work: up/down for history, left/right to edit
- Sessions auto-save — restart if anything goes wrong
- Session summary auto-saved on quit — next start has full context
- Type
quitorexit(no slash needed) to exit - Ollama starts/stops automatically — stops on cloud switch, restarts on local switch
Testing
pytest -v # 1556 tests, all passing
Requirements
- Python 3.11+
- Ollama installed (
/Applications/Ollama.appon macOS) — or just use API models - Models pulled automatically on first run, or
ollama pull qwen3-coder - (Optional) Claude API key for Claude models
- (Optional) DashScope API key for Qwen API models
License
Kodiqa is open source under the AGPL-3.0 License.
For commercial use without AGPL obligations, see Commercial License or contact eniz@kodiqa.com.
Release files for kodiqa 3.41.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| kodiqa-3.41.0.tar.gz | 514.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kodiqa-3.41.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 825.5 kB
Release files / kodiqa-3.41.0.tar.gz
| Download URL | kodiqa-3.41.0.tar.gz |
|---|---|
| Size | 514.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
249b460030381734267fb44b97460b908c36d352146c0679ae1ed3284ea5e954
|
|
BLAKE2b-256 checksum How to use checksums |
8bfb87ab9916058a2019ad46570a15d79b281347c000b84e335693ab2a303398
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / kodiqa-3.41.0-py3-none-any.whl
| Download URL | kodiqa-3.41.0-py3-none-any.whl |
|---|---|
| Size | 311.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
09ba50fba3044f6fce5c2054047e07405672038476ba729fd0737f6c810f514f
|
|
BLAKE2b-256 checksum How to use checksums |
626f514cbc9c5926b9e56b61cba1301a489183e83d59dcb07e0fff2fbfdcba09
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|