A program as an HTTP service (contract/serving.md), to callers who see
only its boundary: its interface, calls, streams and conversations.
ai_service() makes the service (serve_request(service, method, path, headers, body) answers one request, for testing or another server);
ai_serve() runs it on httpuv.
Usage
ai_service(
program,
keys = NULL,
store = NULL,
lm = NULL,
approvals = c("owner", "caller")
)
ai_serve(
program,
host = "127.0.0.1",
port = 8080L,
keys = NULL,
store = NULL,
lm = NULL,
approvals = c("owner", "caller"),
block = TRUE
)
serve_request(service, method, path, headers = list(), body = raw())Arguments
- program
An AI function, a program, or a saved folder.
- keys
Bearer keys a caller must send: a vector, or a file of one per line.
- store
Where conversations are kept (as
ai_conversation()'s).- lm
The model every call uses.
- approvals
Who answers a tool call the program's
approverule asks about:"owner"(in their own session; the caller sees the turn waiting), or"caller", through the approvals route.- host, port
Where it listens.
- block
Whether to serve until interrupted (
FALSE: returns the server; httpuv answers whenever R is idle;httpuv::stopServer()stops it).- service
A service.
- method, path
The request's method and path.
- headers
Its headers, a named list (lower-case names).
- body
Its body (raw or text).
Details
| route | answer |
GET /interface | the program, described ({"functai_interface": 1, ...}) |
GET /openapi.json | the same, as OpenAPI 3.1; GET /: a form |
POST /call {"inputs": ...} | {"call", "outputs", "value"}; a refused input 422 |
POST /stream | Server-Sent Events of the outside view |
POST /conversations/<id>/turns | a turn, saved before it runs (after, request_id, wait) |
GET /conversations/<id>/turns[/<turn>[/events]] | the branch's turns, one turn, its events (Last-Event-ID resumes) |
POST .../turns/<turn>/stop, .../approvals/<invocation> | stop it; answer an approval (approvals = "caller") |
Without keys it listens only on this machine (serve-keys otherwise).
A caller that is a functai call sends FunctAI-Parent: the served call
names it as its parent, so the two logs make one call tree.
R answers one request at a time, as R runs one thing at a time: a long call holds the others until it ends, and a stream's events are sent together when its call ends (httpuv cannot send a response piece by piece). A served program that must stream live, or take many callers at once, is served by Python's or Julia's functai from the same saved folder.