Builtin Library
README.md
service
Public Luau surface over the __service Internal FFI namespace
(crates/zero_scripting/src/ffi/bindings/services.rs) — the credit-metered
seam the service system uses to reach external generation APIs.
A .service names a provider offering and a logical endpoint;
service.invoke POSTs {offering, endpoint, params, headers, body} to
ZeroMind's /v1/services/invoke. ZeroMind resolves the real upstream target,
injects the provider's secret, debits the caller's credits, and forwards. The
platform JWT and the real upstream URL live only in Rust — user-scope Luau
never sees them.
Surface
service.invoke(offering, endpoint, opts?) -> string?— promise handle fortask.await()resolving the InvokeResponse JSON, or nil when the gateway is unconfigured or no caller identity is available.service.invokeStream(offering, endpoint, opts) -> ServiceStream?— the streamedinvoke. ZeroMind relays the upstream's server-sent events as they arrive and ends with azeromind.settledevent ({"charged":N,"balance":M}) or, when the relay stopped early,zeromind.failed({"reason":...}). It returns a stream at once, or nil when the gateway is unconfigured or no caller identity is available.optstakes whatinvoketakes plus a required, per-call-uniqueidempotency_keyand an optionaltimeout_ms(the wait for the response head and for each next chunk; default 120000). The stream'spoll()returns the next event or nil without waiting;read()waits for the next event and returns nil at the end;isEnded()is true once the end was reached;close()drops the connection. An event is{ event = <name or nil>, data = <text>, status = <number, refusals only> }. An answer that is not an event stream arrives as onezeromind.refusedevent carrying the HTTPstatusand the JSON answer asdata; a call that could not be made, or a stream that broke or went quiet, arrives as onezeromind.failedevent. A stream belongs to the VM that opened it: its handle is random, another VM's read or close of it is refused, at most sixteen are open per VM, and a closing VM takes its streams with it. A stream that ended and was not read for thirty seconds is dropped, and one whose queue stayed full for five minutes with nothing reading it is let go with azeromind.failedevent. The queue holds at most 1024 events and 32 MiB.timeout_msis at most 600000 (0 or absent is 120000). The gateway must be https, or the machine's own loopback; any other origin is no gateway.- Every call that carries the caller's bearer (
invoke,invokeStream,submitJob,jobStatus,balance) goes to the configured gateway, which must be https or the machine's own loopback; any other origin counts as no gateway, so those calls return nil andgatewayConfigured()is false. service.balance() -> string?— promise handle resolving the caller's credit balance, or nil when not ready.service.gatewayConfigured() -> boolean/service.authenticated() -> boolean— readiness probes to surface a precise message wheninvokereturns nil.service.configureGateway(baseUrl, tokenIssuer?) -> boolean: trusted only; present only in the trusted VM, which sets the ZeroMind base URL at boot and the issuer its JWTs name asiss(ZeroMind serves/v1/*onhttps://origozero.aiand stamps its JWTs withhttps://api.origozero.ai).
Most handlers use the serviceCall helper (modules/serviceCall), which awaits
the promise, classifies HTTP status into legible errors, and returns
(InvokeResponse, err).