v0.1.0 · Rust · MIT · Claude Code & Codex skill

Keep talking while it thinks.

Delphin wraps your AI agent's CLI and runs it in a PTY, mirroring every line so the session looks untouched. The difference is underneath: you can keep typing while the agent works, and a supervisor decides what each new line deserves — forwarded the moment the agent is free, or held back until it is.

$ cargo run --release -- -- claude See how it works →
queue, don't discard interrupt on urgency local SQLite memory

Fifteen minutes in, it was building the wrong thing.

You hand the agent a task and step away. It works — quietly, confidently, for the better part of fifteen minutes — and when you look back it has built something you never asked for. The misunderstanding isn't the problem; those happen with any collaborator. The problem is that there's no way to say “wait, that's not what I meant” without killing the session and discarding everything it has done. It never paused to ask the one clarifying question a person would have asked first.

The bottleneck isn't the model's reasoning. It's the interface around it — turn-based and half-duplex: while you type it waits, while it generates it stops listening. Thinking Machines Lab made the same case in Interaction Models (Mira Murati, May 2026). Delphin removes the turn-taking. You keep adding context while the agent works, nothing in flight gets thrown away, and a long session starts to feel less like submitting jobs and more like talking to someone.

Half-duplex · today

you …you wait… agent

Duplex · with Delphin

you keep typing queue
agent works mirrored output

A supervisor sits between you and the agent.

Delphin spawns your agent inside a pseudo-terminal and watches its output go quiet — that silence is how it knows the agent is idle. Every line you type goes to an arbiter, which returns one of three verdicts. Every turn lands in memory.

you type stdin, while busy Supervisor PTY spawn · idle detection mirrors agent output back to you busy? output ↑ mirrored Arbiter verdict per prompt send enqueue interrupt Queue drained one prompt per idle every turn → SQLite agent_turns · on your machine

Three verdicts. A pluggable rule.

The arbiter decides what each new prompt deserves the moment you press enter. The default heuristic protects a half-finished thought; switch to --arbiter question and questions barge in too — a question usually needs answering before the current work is even useful. The rule is a trait, so you can swap in your own.

send now send

The agent is idle, so your prompt is forwarded immediately. No waiting, no ceremony.

enqueue enqueue

The agent is busy and your prompt can wait. It joins the queue and is released one at a time as the agent finishes. The default — a half-finished thought is worth protecting.

interrupt interrupt

The agent is busy, but you signalled urgency — so the prompt barges in and stops the current task.

triggers on stop · wait · no · actually

It remembers — on your machine.

  • Every prompt, the arbiter's verdict, and the agent's reply are written to a local SQLite file.
  • Your conversation history lives in agent_turns — nowhere else, under your control.
  • Search it from the terminal — no SQL needed — with delphin recall <query>.
  • Point it at another database to accompany another system's memory. Companionship by choice, not dependency.
  • Or turn it off entirely with --no-log.
inspect your history
sqlite3 ~/Library/Application\ Support/Delphin/delphin.sqlite3 \
  "SELECT direction, verdict, substr(text,1,60)
   FROM agent_turns ORDER BY id DESC LIMIT 20;"
recall — search without SQL
delphin recall postgres
delphin recall --limit 50 auth
point at another database
cargo run -- --db /path/to/other.sqlite3 -- claude

Try it — no real model needed.

Build it, then watch the mock agent “think” in dots. Type while it does.

Prefer a binary? Grab one from the v0.1.0 release (macOS arm64) — chmod +x and run. Or build from source below.

run the mock
cargo build
cargo run -- --interrupt ctrl-c -- bash examples/mock-agent.sh
while it's “thinking”…
# queues, sent when the mock finishes
also add logging
# interrupts and sends your line
stop wrong thing

Use it with a real agent.

Claude Code
cargo run --release -- -- claude
Codex
cargo run --release -- --interrupt esc -- codex

ESC stops Claude Code; many CLIs use Ctrl-C. Set --interrupt to match your agent — or none for queue-only mode.

Options

--idle-ms NSilence in ms before the agent is considered idle. [800]
--tick-ms NIdle-detector tick interval in ms. [150]
--submit-newlineSubmit prompts with \n instead of \r.
--interrupt KINDesc · double-esc · ctrl-c · none · <literal>. [esc]
--arbiter KINDheuristic · question. [heuristic]
--ready MARKERoutput ending with MARKER means the agent is idle (repeatable).
--db PATHRemember into this SQLite file instead of the default.
--no-logDo not remember the conversation.

A skill for Claude Code & Codex.

Reach Delphin from inside your assistant — pull up a past session or dig through its memory without leaving the chat. “Recall my last Delphin session.” “Search Delphin memory for the migration.”

claude code · plugin

Install from the marketplace

This repo is a Claude Code marketplace, so the skill installs directly — then it triggers automatically, or invoke it with /delphin.

recommended
/plugin marketplace add wuisabel-gif/Delphin
/plugin install delphin@delphin
codex · prompt

Copy the prompt in

Drop the prompt into your Codex prompts directory, then run /delphin — for example /delphin recall migration.

~/.codex/prompts/
cp .codex/prompts/delphin.md ~/.codex/prompts/

Honest caveats v1

It's early. Here's exactly where the edges are.

idle
Idle is inferred.

By default “is the agent thinking?” is read from output silence (--idle-ms). If your agent prints a prompt while waiting, --ready makes detection instant; otherwise it needs per-agent tuning.

intr
Interrupting is agent-specific.

ESC stops Claude Code; many CLIs use Ctrl-C. Set --interrupt accordingly — none gives queue-only mode.

line
Line-oriented input.

Delphin reads whole lines; rich TUIs may render imperfectly. Line-based agents work cleanly.

Source layout

src/main.rsCLI parsing, wiring
src/supervisor.rsPTY spawn, idle detection, event loop
src/arbiter.rsArbiter trait + heuristic & question policies (+ tests)
src/config.rsOptional .delphin.toml config (+ tests)
src/queue.rsPrompt FIFO (+ tests)
src/memory.rsSQLite log + recall search (+ tests)
examples/mock-agent.shFake thinking agent for testing
tests/e2e.rsEnd-to-end test against the mock agent