Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit3bb1da2647

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 for task.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 streamed invoke. ZeroMind relays the upstream's server-sent events as they arrive and ends with a zeromind.settled event ({"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. opts takes what invoke takes plus a required, per-call-unique idempotency_key and an optional timeout_ms (the wait for the response head and for each next chunk; default 120000). The stream's poll() 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 one zeromind.refused event carrying the HTTP status and the JSON answer as data; a call that could not be made, or a stream that broke or went quiet, arrives as one zeromind.failed event. 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 a zeromind.failed event. The queue holds at most 1024 events and 32 MiB. timeout_ms is 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 and gatewayConfigured() 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 when invoke returns 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 as iss (ZeroMind serves /v1/* on https://origozero.ai and stamps its JWTs with https://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).