A PROGRAMMING LANGUAGE

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.

movie_night.kedi
# 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>
BOUND VALUESIllustrative output
director
str
Hayao Miyazaki
year
int
2001
minutes
int
125
41.0082° N / 28.9784° E
01 / THE LANGUAGE

Templates and typed values

The context, the question, and the shape of the answer.
All in the same line of your program.

>> The next action in is .
INPUT / note: str

The design team will send the event poster to the printer.

next_action.kedi
~Action(owner: str, task: str) [note] = The design team will send the event poster to the printer.>> The next action in <note> is [action: Action]. = `action`

Using captured values

Use the result in the next statement, pass it to a procedure, or hand it to Python.

Explore templates
02 / NATURAL CONTROL FLOW

Conditions and loops

Let a model evaluate a claim and your program decide what happens next.

release_gate.kedi
[change] = The response field user_id is being replaced by account_id.[track] = standard > if: The API change "<change>" breaks compatibility with existing clients  [track] := migration = <track>
BOUND VALUESIllustrative output
track
str
migration

Does this API change
need a migration?

Truemigration
Falsestandard

Natural-language claims and deterministic Python conditions. Same control flow.

Read about conditions, loops, and maps
03 / PYTHON INTEROP

Keep writing your program.

Templates are the beginning. Compose them with the tools you already use.

quote.kedi
[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`
BOUND VALUESIllustrative output
seats
int
12
monthly_usd
float
19.0
annual_usd
float
2736.0

A backtick away
from Python.

A model reads the pricing terms. Python multiplies the typed numbers to get the annual total.

Typed boundariesLexical scopesPython interopPluggable agent adapters
04 / PROFILES AND SUBAGENTS

From building blocks to a working crew.

A researcher finds the breaking change. An editor explains the migration. Profiles, tools, subagents, and typed answers, in the same program.

release_team.kedi
> import: filesystem> model: google/gemini-3-flash-preview > profile: researcher:  > instructions: Read CHANGELOG.md. Quote the v2.0 breaking changes.  > use: read_text_file  > output: list[str] > profile: editor:  > instructions: Turn the researcher's findings into concise migration steps.  > subagent: researcher > use: editor>> Based on the researcher's findings, API clients should follow [steps: list[str]] to migrate to v2.0. = `steps`
BOUND VALUESIllustrative output
steps
list[str]
["Read account_id instead of user_id in API responses"]
Explore subagents
05 / KEDI + JEVJEV BY TYPESAFE

Typed assessments with Jev

Pick a queue. Assess cancellation intent. Let your program decide the priority.

ticket_triage.kedi
> 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 cancellation intent is [cancellation_intent: Annotated[  Probability,  "The customer states an intention to cancel their subscription."]]. = `{"queue": queue, "priority": cancellation_intent >= 0.80}`
BOUND VALUESIllustrative output
queue
Literal
billing
cancellation_intent
Probability
0.93
Choice
A Literal limits the answer to your defined options.
Probability
A value from 0 to 1. Keep the assessment; set your own decision rule.
Explore the Jev integration
06 / INTERACTIVE KEDIA LITTLE ROOM TO EXPERIMENT.

Notebook and REPL

Stateful notebook cells

Try a template. Inspect its values. Keep going in the next cell, with your program's state right where you left it.

kedi notebook

Opens your browser at localhost:8788/notebook/. Served locally, on your machine.

First-time setup

From a Kedi source checkout with its submodules initialized, install the notebook dependencies and launch it with:

uv run --extra notebook kedi notebook

After installation, run kedi notebook with that environment active.

kediNotebookCity notes
[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.
0:09 / 0:09

Your Python, your choice.

Start with browser Python, or select a host interpreter with a reusable notebook virtual environment.

More than a scratchpad.

Mix Kedi, Markdown, and terminal cells. Save a .kedinb notebook, with optional execution progress and no Secret Manager values.

Notebook setup guide
COMING SOON

Kedi Harness

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
The tuxedo cat at a retro computer, with a glass of Turkish tea beside the keyboard
07 / THE TEAM

The people behind Kedi.

  • Front-facing pixel portrait of a white and brown tabby cat

    Mert Sırakaya

    Co-creatorApplied AI Engineer

  • Front-facing pixel portrait of a white Ankara cat with blue eyes

    Doğukan Yiğit Polat

    Co-creatorPhD Student

08 / YOUR FIRST .KEDI FILE

Write it. Run it. Ship it.

A little natural language. A little Python.
A program that's yours.

uv add kedi
KARAKÖY
KADIKÖY
An Istanbul ferry crossing the Bosphorus, with the cat on board