Osy#betaRun it on Osyrin: osyrin.com

Reference / Agent

Osysharp.Llm — every call to a model: which one, what it may cost, what it did cost

`Osysharp.Llm` is the one road every model call in an app takes: the app's router picks the model, room is reserved against every budget the call falls under, the provider is called, the next model is tried when one fails, and every attempt is written on a meter with what it cost.

previewagentsguidekit

Source on GitHub: Osysharp.Llm — github.com/osysharp/llm ↗

You are here: Building with agents › The kits › Llm

Summary#

Osysharp.Llm is the one road every model call in an app takes: the app's router picks the model, room is reserved against every budget the call falls under, the provider is called, the next model is tried when one fails, and every attempt is written on a meter with what it cost.

You list the models your app has keys for. Then Llm.Complete answers text, Llm.Extract<T> reads a typed value out of text, and Llm.Decide<T> makes a typed decision with a confidence. Agents call models through this kit too, so one set of budgets and one meter covers everything.

PackageOsysharp.Llm, version 2.4.0
You add it withuse Osysharp.Llm; in the app's manifest.
Bridges that arrive when it meets another kit[[agent-kit-privacy-llm|Privacy.Llm]]
Its own test appA seed bank that reads the notes sent in with each seed lot — kits/llm/tests

Description#

What do you get without writing anything?#

  • A meter row for every attempt: the model, why that one, the tokens, the cost in millionths of a dollar.
  • Hard limits: for the app, for each person, for a model, for anything you name. A call that would pass one is not sent.
  • Fallback: when a provider fails, the next model the router admits is tried.
  • An answer of the wrong shape is sent back to the model once before your code sees an error.
  • The operator's switch: AI can be turned off while the app runs, with no redeploy.

When do you need it?#

Always: every other kit on this map sits on it. On its own, it is all you need for one answer from a model with no tools — see [[agent-guide-choosing#agent-or-call]].

What does it expose?#

The tables below are generated from the kit itself, not written by hand: osy kits Osysharp.Llm --surface lists each of them with the code of the kit's own test app that uses it, and the tests that show it working.

Settings — one line in the app, each field with a default.

You writeIt says
app.Llm = new LlmSetup { Models, Default, Router, HoldFor }How this app calls models.

Contracts you can implement — a class of yours that the kit then calls.

ContractWhat it is
interface ILlmClient { internal Complete, internal Stream }What a model provider implements.
interface IDecisionModel { internal Decide }What a typed-decision model implements — a model built to return a value of a schema given in advance, with a confidence, rather than text: a classifier, a scorer, an extractor.
interface ILlmRouter { Route }What a model router implements — the ONE place that decides which model serves which call.

Policies you answer — each is a question the kit asks your app: policy Name => …;

PolicyThe questionUntil the app says otherwise
UsesModelsWho may call a model at all.everybody
ReadsModelUsageWho reads the meter — every call's model, tokens and cost.nobody
ReadsModelUsageOfWho reads the calls charged to particular scopes — a call at a time, by what it is charged to (ModelCall.Scopes, one scope a line).nobody
ManagesModelSpendWho sets prices and budgets.nobody

Functions you call, those its own tests show most first.

FunctionWhat it doesTests that show it
CostMicros(LlmPricePoint price, int inputTokens, int outputTokens, int cacheReadTokens, int cacheWriteTokens)What some tokens cost at a price, in millionths of a dollar, rounded UP — a price per million tokens in dollars is a price per token in millionths.63
Served(LlmAdmission admission, int inputTokens, int outputTokens, int cacheReadTokens, int cacheWriteTokens, DateTime started, string? note)The provider answered: settle what was held at what it actually cost, and write the attempt's meter row.63
Failed(LlmWalk walk, LlmAdmission admission, DateTime started, string said)The provider failed: release what was held, write the attempt's meter row, and remember it for the next candidate.62
ScriptedAnswer(string model, LlmRequest request)What the scripted model named model answers to request.62
RequestOf(string prompt, string system = …)A request that is one question from the user, with an optional system prompt.60
ScriptedDecision(string model, LlmDecisionRequest request)What the scripted decision model named model decides for request.60
RemoveBudget(string scope, string subject, LlmBudgetWindow window)Remove a budget, and what was counted against it.59
ForgetModelCallRequester(Guid requester, DateTime? before = …)Take a person off the meter: every row of a call made for requester loses who it was for — the row, the model, the tokens and the cost stay, charged to the same app, model and named scopes as b…59
SetBudget(string scope, string subject, LlmBudgetWindow window, decimal limit, LlmOnLimit onLimit = …, decimal warnAt = …)Set the budget for scope (and subject within it — "" for every subject, each on its own) in window to limit US dollars.57
ModelCallsInFlightFor(Guid requester)Whether a call made for requester is still on its way: room is held for it against a budget of theirs, and it has not reported back.57
ForgetModelCallsBefore(DateTime before)Delete the meter rows of calls made before before.57
GenerationIsOn()Whether the operator allows this app generative AI right now.54
SetModelPrice(string model, decimal input, decimal output, decimal? cacheRead = …, decimal? cacheWrite = …, DateTime? from = …)From from on (now, when null), a million tokens on model cost this many US dollars.49
RunScopes()What a model call is charged to because of where it is made: in a workflow's run, the workflow — workflow:Onboarding — and that run of it — run.Onboarding:8f1c….7
SpentAgainst(string scope, LlmBudgetWindow window = …)What the calls that carried a limit for scope have spent against it this window, in US dollars — settled calls only.5
SpentIn(string scope, string subject, LlmBudgetWindow window)What subject has spent in scope this window, in US dollars — settled calls only.4
SpentOn(string scope)What the calls charged to one scope cost in all, in US dollars — SpentOn("task:" + task.Id), SpentOn("app:").4
RunKind(string workflow)The kind a budget for EACH run of a workflow is set on: run.Onboarding — an empty subject gives every run an allowance of its own; a run's id as the subject sets one run's.3
WorkflowScope(string workflow)The scope every call made for a workflow is charged to, whichever run: workflow:Onboarding.2
RunScope(string workflow, Guid run)The scope the calls of ONE run of a workflow are charged to: run.Onboarding:8f1c….2

Events your app can hear — [On] void Heard(EventName e) { … }

EventWhen
LlmBudgetNearlySpentA budget has passed its warning share for this period.
LlmBudgetSpentA call was refused because a budget had no room for it.

Go deeper#

Related

The map of the kits — which sits on which, and what each one is for

The agents family is 29 kits. Two are under everything: `Osysharp.Llm` for every model call and `Osysharp.Agents` for…

The Llm kit — call a model, and know what each call cost

`Osysharp.Llm` is the road every model call takes, written in Osy#: the operator's AI switch, the app's router, a…

Model spend — budgets, the meter and the price book (Llm kit)

The Llm kit keeps three things about what model calls cost. The METER: one `ModelCall` row for every attempt, with the…

Typed answers from a model — Llm.Extract<T> and Llm.Decide<T> (Llm kit)

Two calls of the Llm kit that answer a VALUE instead of text. `Llm.Extract<T>` reads a `T` out of text: the model is…

Testing model calls without a model — ScriptedModel (Llm kit)

The Llm kit ships a provider whose answers a test writes. Name a `ScriptedModel` where a real provider would go, and…

turning AI off (the runtime switch)

An operator can switch an application's AI off while it runs — no recompile, no redeploy. Text generation and embedding…