These libraries are experimental. APIs may change without notice. Generated from source with koruc 0.1.7 on 8/19/2026.

AI

@korulang/ai@0.0.1

First-class Koru edition of LLM text generation (Anthropic, OpenAI) over @korulang/curl, with request + response resources tracked as phantom obligations

ai/index.kz · 5 tors

@koru/ai - AI SDK for Koru · 29 more lines
@koru/ai - AI SDK for Koru A first-class Koru edition of LLM text generation over the Anthropic and OpenAI HTTP APIs. Built on @koru/curl — dogfooding our own lifted HTTP client. The lift is entirely in the type system: a request-in-flight carries a `built!` free-obligation and the HTTP response carries curl's `open!` close-obligation, so the compiler will not let a caller leak the request scratch OR forget to close the connection. Two obligations, both enforced, discharged in the caller's flow. Non-streaming: one request, one reply. ── Shape & history (why it looks like this) ───────────────────────────────── The pre-current-language edition of this file (a) declared bare `~proc`s (KORU110: bare procs are unresolvable in the current language) and (b) called curl through an INVENTED Zig escape hatch — `@import("root").koru_libs.curl.post_with_headers_event.call(.{...})` — a symbol attested by no passing test. This edition removes both. Composition with curl now uses the sanctioned koru-level, cross-module event form (`koru/curl:post.with-headers(...)`, `koru/curl:close(...)`) in flow position, grounded in tests/regression/100_MODULE_SYSTEM/110_IMPORTS/ 110_020_cross_module_literal_arg and koru-by-example's subflow section. The API is a set of building-block events the caller wires in a top-level flow (see examples/ and README.md), NOT a single `generate(...)` convenience event. That is a deliberate, forced choice: a single all-in-one event would have to be a subflow that borrow-parses the response, discharges it, and produces a value — and that exact shape is blocked by three current compiler gaps (see LIFT_NOTES.md "Toolchain findings"). The building-block flow sits entirely in top-level flow position, which the compiler handles cleanly and which — bonus — makes BOTH obligations visible at the call site.

Phantom lifecycles

Derived from the phantom labels in the declarations below — state! issues an obligation the compiler will chase, !state discharges it, a bare state holds it without moving it. Nothing here is hand-drawn.

Request 1 state built!

Response is borrowed: this module holds <koru/curl:open> without issuing or discharging it — the obligation belongs to koru/curl.

request.anthropic

<built!> index.kz:74

request.openai

<built!> index.kz:102

free.request

<!built> index.kz:133

parse.anthropic

<koru/curl:open> index.kz:152

parse.openai

<koru/curl:open> index.kz:188