Your First Kedi Program¶
Create a .kedi File¶
Create review.kedi:
~Review(decision: Literal["approve", "revise"], summary: str)
@review_change(title: str, diff_summary: str) -> Review:
>> For change <title> with diff summary <diff_summary>, the review result is [review: Review].
= `review`
= `review_change(args.title, args.diff_summary).model_dump_json()`
Run it:
kedi review.kedi \
--title "Reject unsafe paths" \
--diff-summary "Adds containment checks before file access"
Add Inputs¶
title and diff_summary are typed procedure parameters. The final call uses
a single-backtick Python expression:
[review: Review] = `review_change(args.title, args.diff_summary)`
This passes native strings and preserves the native Review return. An angle
call renders its result to text, so it is appropriate for procedures returning
str, not for carrying a Review object through the dataflow.
Write a Template¶
Continuation rows after >> are joined with newlines and sent as one model
request. This example needs only one row:
>> For change <title> with diff summary <diff_summary>, the review result is [review: Review].
<title> and <diff_summary> are substitutions. They read existing values;
they do not ask the model to generate anything. Use substitutions for runtime
facts, user input, prior procedure results, or deterministic Python values.
Capture a Typed Output¶
[review: Review] is an output capture. The selected adapter receives a schema
derived from the Kedi type and must return a matching object. Capture output
when downstream logic needs typed fields or when the response must be validated.
Kedi also exposes raw capture for deliberately unstructured provider text:
@review_change(title: str, diff_summary: str) -> str:
[review] << Review of <title> with diff summary <diff_summary>:
= <review>
Do not put output fields inside a raw << prompt. Raw captures always produce a
string; types other than str are rejected. Prefer the typed version above for
normal application dataflow, including typed str results.
Return the Result¶
Inside the typed version, = `review` returns the native Review model.
The top-level expression serializes it deliberately:
= `review_change(args.title, args.diff_summary).model_dump_json()`
Use a native return when Python or another Kedi procedure needs the object. Use a rendered return when the program's final output is text.
Pass Command-Line Arguments¶
Application flags belong after the Kedi source:
Dashed names become underscore attributes, so --diff-summary is available as
args.diff_summary. Flags without values become booleans. Kedi's own options,
such as --adapter and --test, are parsed by the CLI rather than exposed as
application arguments.
Parse Before Running¶
Parsing catches malformed syntax, duplicate selective imports, invalid directives, and other structural errors. It cannot prove that provider credentials exist or that a runtime-computed type is valid. Those checks happen during compilation or execution.