Builtin Library
README.md
serviceCall
The user-scope entry point for credit-metered service calls. A .service
handler calls Service.invoke(offering, endpoint, opts) instead of touching
the service primitive directly, getting one (response, err) contract with
the HTTP status already classified.
local Service = require("modules.serviceCall")
local resp, err, _, detail = Service.invoke("origozero/mesh_gen", "create_preview", {
body = { prompt = "a wooden chest" },
})
if not resp then
handle:fail(err, detail) -- "out of credits …", "not signed in …"; detail.code names the platform's refusal
return
end
local refused = Service.refusal(resp)
if refused ~= nil then -- upstream relayed a non-2xx (charged 0)
handle:fail(refused, Service.refusalDetail(resp)) -- reason, field, retryAfterSecs
return
end
local task = resp.body -- the upstream payload
Handing the refusal's detail to handle:fail puts its reason, field and
retryAfterSecs on the run, and keeps a refusal for a cap (quota_exhausted,
throttled, spent credits or budget) where services.caps lists it.
Service.retriable({ status, reason, message }) says whether the same call is
worth sending again, reading reason first.
Service.invoke returns the InvokeResponse { status, headers, body, charged, balance } on a successful round-trip, or (nil, errMsg) when the call could
not be charged or forwarded. Service.balance() returns the caller's integer
credit balance.
Direct calls: an answer, with no run
Service.invoke runs the call as a durable gateway job, which a generation
producing an asset needs: the job keeps a paid result through a crash. A call
whose answer is the point (a language-model reply, a judge's verdict) goes
direct instead: one request on the caller's connection, answered at the
provider's speed, metered like any call, filing nothing.
local Service = require("@builtin::modules.serviceCall")
-- An endpoint that answers in one response.
local resp, err = Service.call("origozero/jev", "decide", { body = { ... } })
-- An endpoint that answers as a stream, such as the language model
-- (`origozero/llm`, `chat`): read to the end, the reply's text assembled.
local answer, why = Service.stream("origozero/llm", "chat", {
body = {
model = "deepseek/deepseek-v4.1-flash-1017",
messages = { { role = "user", content = "Name a fantasy town." } },
stream = true,
stream_options = { include_usage = true },
},
}, function(event) --[[ each piece as it arrives ]] end)
print(answer and answer.text)
call returns the InvokeResponse as invoke does. stream returns { text, events, charged, balance }, or (nil, reason) for a refusal, which names what
the endpoint takes (its models, a field it refuses) and charges nothing.
readStream(stream, onEvent?) reads a stream already opened with
service.invokeStream. A .service operation is called the same way with
asset.resolve("<name>", "service"):call(input).
ZeroMind injects the provider secret and meters credits server-side; the platform JWT and the real upstream URL are never visible to this script.