Skip to contents

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 approve rule 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).

Value

ai_service(): a service; ai_serve(): the server, invisibly.

Details

routeanswer
GET /interfacethe program, described ({"functai_interface": 1, ...})
GET /openapi.jsonthe same, as OpenAPI 3.1; GET /: a form
POST /call {"inputs": ...}{"call", "outputs", "value"}; a refused input 422
POST /streamServer-Sent Events of the outside view
POST /conversations/<id>/turnsa 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.