Write it. Run it. Ship it.
A little natural language. A little Python.
A program that's yours.
uv add kedi

Program with natural language.
Typed by design.
Compose model calls, decisions, and tools as typed programs. Natural language is part of the code, not a string on the side.
# Load the movie lookup tool.> import: tmdb# Let the model use it.> approval: allow> use: movie_details # Find the film by name and capture its details.>> Look up Spirited Away using movie_details. Its director is [director: str], release year [year: int], and runtime [minutes: int] minutes. # Use the result as a program value.= <director>uv add kediThe context, the question, and the shape of the answer.
All in the same line of your program.
>> The next action in is .note: strQA must reproduce the timeout before Mira can fix checkout.
~Action(owner: str, task: str, blocked: bool) [note] = QA must reproduce the timeout before Mira can fix checkout.>> The next action in <note> is [action: Action]. = `action`Use the result in the next statement, pass it to a procedure, or hand it to Python.
Let a model evaluate a claim.
Let your program decide what happens next.
[change] = Rename user_id to account_id in API responses.[track] = standard > if: <change> requires existing integrations to change [track] := migration = <track>Does this API change
need a migration?
Natural-language claims and deterministic Python conditions. Same control flow.
[facts] = CSV export ships Monday. PDF is not available.[draft] = Export any report as CSV or PDF today. > loop: <draft> makes promises not supported by <facts> >> A revision of <draft> supported only by <facts> would read [revision]. [draft] := <revision> = <draft>Does the copy claim more than the facts support?
Remove unsupported formats and launch dates.
Stop when no unsupported promises are found.
The condition is evaluated again before every iteration.
[reports: list[str]] = `["CSV loses the last row.", "Please add a dark theme."]`[bugs: list[str]] = `[]` > loop [report]: `reports`: >> It is [is_bug: bool] that <report> describes a defect. The issue title is [title: str].> map: > if: `is_bug`: `bugs.append(title)` = `bugs`Each incoming report gets its own iteration scope.
The map receives that report's classification and title.
Collect bug titles; leave feature requests out.
Independent continuations can overlap. Kedi waits for the map stage before moving on; completion order may differ.
Templates are the beginning. Compose them with the tools you already use.
[quote] = 12 seats at 19 dollars per month, billed yearly. >> In <quote>, there are [seats: int] seats at [monthly_usd: float] dollars per seat per month. [annual_usd: float] = `seats * monthly_usd * 12`= `annual_usd`A model reads the pricing terms. Python multiplies the typed numbers to get the annual total.
~Brief(problem: str, next_step: str) @handoff(report: str) -> Brief: >> The on-call handoff for <report> is [brief: Brief]. = `brief` [report] = Checkout times out only after a coupon is applied.[brief: Brief] = <handoff(<report>)> = `brief`Turn a report into a reusable, typed on-call handoff: a problem and a concrete next step.
```import jsonfrom pathlib import Path``` @stock(item: str) -> int: = ``` path = Path("inventory.json") return json.loads(path.read_text())[item] ``` > approval: allow> use: stock>> The stock tool reports [remaining: int] units of "field-notebook". It is [can_fulfill: bool] that this can fill an order of 4. = `can_fulfill`The model checks actual stock before answering. A Kedi procedure reads the inventory through Python.
Example inventoryA researcher finds the breaking change. An editor explains the migration. Profiles, tools, subagents, and typed answers, in the same program.
> import: filesystem> model: google/gemini-3-flash-preview > profile: researcher: > instructions: Read CHANGELOG.md. Find required v2.0 migrations. > use: read_text_file > output: list[str] > profile: editor: > subagent: researcher > use: editor>> The v2.0 migration checklist reported by the researcher is [steps: list[str]]. = `steps`Pick a queue. Assess cancellation intent. Let your program decide the priority.
> import: decisions> model: typesafe/jev-latest [ticket] = I was charged twice. Reverse it or I cancel today. >> <ticket> belongs to [queue: Literal["billing", "technical"]]. The probability the customer intends to cancel is [churn: Probability]. = `{"queue": queue, "priority": churn >= 0.80}`Literal limits the answer to your defined options.Try a template. Inspect its values. Keep going in the next cell, with your program's state right where you left it.
kedi notebookOpens your browser at localhost:8788/notebook/. Served locally, on your machine.
From a Kedi source checkout with its submodules initialized, install the notebook dependencies and launch it with:
uv run --extra notebook kedi notebookAfter installation, run kedi notebook with that environment active.
[1] > model: openai/gpt-6-luna >> In Türkiye, [city: str] spans the [strait: str]. [2] > show: <city> spans the <strait>. Istanbul spans the Bosphorus Strait.
Start with browser Python, or select a host interpreter with a reusable notebook virtual environment.
Mix Kedi, Markdown, and terminal cells. Save a .kedinb notebook, with optional execution progress and no Secret Manager values.
Write a template, inspect a capture, and build on it. Variables, procedures, and model settings stay with your session.
kedi --idleSyntax highlighting is on by default. Use --no-color for plain text.
$ kedi --idle +++ > model: openai/gpt-6-luna +++ >> [city] is the city of cats. +++ > show: `city.upper()` ISTANBUL +++ > show: Cats love <city>. Cats love Istanbul. +++
Use :multiline for a longer fragment and :show to inspect a value.
Save your session's source to a .kedi file with :dump.
An agent harness.
With a mind of its own.
Meet the cat taking the keyboard. An agent harness for your projects, with Kedi as its orchestration language. It can write and run Kedi programs to coordinate its own tools, subagents, and next steps.
Follow the work on GitHub

Co-creatorApplied AI Engineer

Co-creatorPhD Student
A little natural language. A little Python.
A program that's yours.
uv add kedi