Generating, its fake and the local driver
The full rules for ai:, ai.generate and the built-in
Driver.openai_compatible, and for how the fake stands in for them in
tests. The common case is under The ai capability
and Typed output.
-
ai:takesconnection:,models:,embedding_dimensions:,limits:,personal_data:andprices:. Any other key, a connection that answers no model, a model that isn't aModelIdsetting, andmodels:withoutdefaultareai.settings_invalid. An action that asks a model whenapp.jadpohas noai:isai.connection_required, as sending email with no email connection isemail.connection_required. A package's connection fillsaitoo (A package fillingai). AModelIdsetting is read from its text, so a setting may hold one (What a setting can hold). -
Driver.openai_compatibletakesurl:alone, as aUrlsetting or an address written out, with plain HTTP only to this machine (connection.key_missing,connection.key_invalid,connection.value_invalid). It sends no credential. Each call is OpenAI's Chat Completions request to<url>/chat/completions, with:- the model's
ModelIdas written, such asmeta-llama/Llama-3.1-8B-Instruct, since vLLM and LM Studio name a model by its repository; - the messages
prompts.rendergives; max_output:asmax_tokens, which every server named on this page reads;- its structured mode,
response_format: { type: "json_schema", json_schema: { name: <prompt>, strict: true, schema } }, so its mode isstrict_subset.
For a package whose mode is
json_onlyornone, the schema goes in the instructions instead, under# Answer format, asking for one JSON document alone. - the model's
-
Reading an answer. The text is
choices.0.message.content. Arefusalor acontent_filterstop isrefused, and alengthstop isover_budget. The built-in driver declares no context window to check before sending, sotoo_longis a400whoseerror.codeiscontext_length_exceeded, as OpenAI answers one. Any other4xx, a redirect, a401or a403ismisconfigured. A server that can't be reached, a429(after itsRetry-After) or a5xxis sent again, at most 3 times in all withintimeout:, then isunavailable. No whole answer withintimeout:istimed_outat once, since that attempt had all the time left. An answer that isn't a chat completion is a fault naming the connection and the prompt, never its text. A JSON answer in a Markdown code fence is read without the fence. -
The schema is OpenAPI's whole schema for
T(OpenAPI): its objects and enums as$defs, and each field's///description on its property. The strict mode is sent it cut to types, properties, required fields, enums,const,anyOf(foroneOf) and nesting. Every property is required, one that may be left out becomes one that may benull, andadditionalPropertiesisfalse. ATwhose JSON isn't an object (an enum, a list, a number) is asked for as the membervalueof an object, since the mode wants an object at its root, and read from it. ATbuilt onTextasks for plain text, held toT's rules as it comes. -
A repair adds the answer as the model's turn and a fixed correction as the user's: "In your answer,
<path>breaks the rule<rule>. Answer again with one JSON document alone that matches the schema." For text that isn't JSON, the correction is "Your answer wasn't one JSON document.", and itsDecodeProblemis its root's,malformed. -
The options are written out:
model:is a bare nameai: { models: }gives (semantic.unknown_nameotherwise);max_output:is 1 to 1,000,000,timeout:is1sto10m, andattempts:is 1 to 3 (type.invalid_literalotherwise);- there are no others (
type.named_argument_unknown).
-
Mapping the failures. Each of the five conditions needs an arm naming a failure of kind
unavailable, as a store'sstorage_fulldoes (failure.rule_unmapped,failure.mapping_kind), andinvalid:covers none of them. The failuremalformed:names receives the lastDecodeProblemin aproblem: DecodeProblemfield, asjson.read'smismatchdoes. -
The route's deadline must leave room for the call. The call's
timeout:times itsattempts:, added to the route's other outside calls on the longest way through its action, must fit the route'sdeadline:. Otherwise it isroute.calls_past_deadline(Calling). -
A
ModelIdwritten in code, in a function, an action, a constant or a test's statements, issemantic.ai_model_literal. A setting'sdefault:andtest:, and a test'sconfig:, give a setting its value, so they may write one. A test that reaches a call reads its model's setting, so a setting with neithertest:nordefault:isconfiguration.test_value_missingthere. -
as:refuses a reference, aFile,BytesandPresentationTextanywhere inT, naming the field (semantic.ai_output_type). It refuses a secret value (configuration.secret_flow) and anything elsejson.readcan't read (type.mismatch). -
Answers reused on a rerun. Each call takes the invocation's next outside-call step. Its answer, or the condition it ended in, is kept with a digest of the request it sent. When an action runs again after a concurrent change (All-or-nothing actions and concurrent changes), it takes the same steps, and is given the answer for the same request without asking again, logged as replayed. A request that changed is asked anew. After an action's first changing call, a call is a step of its record, its answer sealed as a provider's is (Several changing calls in one action), so a redelivery replays it too. Before the first, nothing is recorded, as for a provider's read.
-
The fake. Every
aicall injadpo testandjadpo callanswers through one fake in theai:connection's place, whatever its driver. It answers in the built-in driver's own form, so the real reading, decoding and repair run. Each scripted answer is one attempt, and is one of:- a value of the call's
as:type (a prompt asked for as two types takes onlyraw(...)and failures); raw("...")text;- a condition.
malformedis an answer with no text, which no type decodes.
An attempt past the end of the script gets a generated value of
Tand fails the test astest.fake_exhausted. Answers left over fail it astest.fake_unused. Each namesai.<prompt>.ai.<prompt>.requestslists each call's prompt value once, however many attempts it took, and only a test may read it (semantic.not_callable).recorded(...)is under Embeddings and recordings. - a value of the call's
-
jadpo devsends every call of the model connection to its server. The call log keeps each attempt with its request and answer in full (sourcelive); production keeps neither. How a package'saiis faked injadpo dev,development: { sandbox: [<prompt>] }andjadpo calls scriptfor a prompt are under A package fillingai. -
The network report lists the model connection, for
ai, by the domains whose actions ask it (The network report).
keep_content: on ai: isn't built yet: it is toolchain.not_built_yet.
Markdown for agents: /docs/generating-its-fake-and-the-local-driver.md.Built from Jadpo main at a707efb.