soev for developers

soev_agents.entrypoints.http

Serve agents over HTTP: the threads API and the OpenAI Responses API, in one FastAPI app.

create_app returns a FastAPI app that runs the on the and keeps each in a store. The API opens, continues, reads, follows, , and deletes . The Responses API serves the same to clients of the OpenAI SDK. The two HTTP APIs are public as specifications: the guide and the OpenAPI document are in the docs/ folder of this package.

The framework has no access-control model. The gives its own rules through hooks: who calls, whether a call is allowed, and which each gets for an HTTP request.

The app

create_app serves over a store. A adds its own routes and middleware to the app. A Mount names the routes of the API that a deployment serves.

create_app

functioncreate_app(store, agents, *, version, hooks=None, resources=no_resources, models=(), default_model=None, shutdown_grace=30.0, lease_ttl=30.0, keepalive=15.0, lifespan=None, observer=None, mount=Mount(thread_parameter='thread_id', capabilities='/v1/capabilities', health='/healthz'), list_threads=None, list_tools=None, list_models=None, complete_task=None, features=(), responses=False) -> FastAPI

Make the FastAPI app that serves agents over store.

The app serves the API at the routes of mount. With the default mount, the API is under /threads, with GET /v1/capabilities and GET /healthz. The hooks apply to the routes of the API, except the health route.

With responses, the app also serves the OpenAI Responses API under /v1/responses, and GET /v1/models. The Responses API is experimental. It calls no hook, so it does not apply the 's access rules. Use it only for a without access rules. resources applies to both APIs.

The four functions list_threads, list_tools, list_models and complete_task serve the optional routes of the public profile (Mount.public()). A route that mount names, but whose function is None, responds with 501. When mount.models is /v1/models, the API serves that route, also with responses.

The app maps the runtime's refusals to status codes, as DefaultHooks.error does. An input that the refuses, or a log outside the , gets 422. A fresh input while a has not ended, a with nothing to , a id in use, or a that another process runs, gets 409.

At shutdown, the app waits for the running turns, then closes the observer, then leaves lifespan. So the 's clients stay open while the finish.

Example

from soev_agents.adapters import InMemoryTraceStore
from soev_agents.entrypoints.http import ListQuery, Mount, RequestContext, ThreadList, create_app
from soev_agents.toolkit import ReActAgent

# config is a ReActConfig of your own.


async def list_threads(ctx: RequestContext, query: ListQuery) -> ThreadList:
    # `index` is the server's own index of threads, which its hooks fill
    return ThreadList(data=await index.threads_of(ctx.identity.subject, limit=query.limit))


app = create_app(
    InMemoryTraceStore(),
    {"assistant": ReActAgent(config)},
    version="1.4.0",
    mount=Mount.public(),
    list_threads=list_threads,
)

Run it with any ASGI , for example uvicorn.

paramstoreTraceStore

The store of the .

paramagentsMapping[str, Agent[Any, Any]]

The , by the name that a client opens a under. With responses, the first runs a Responses conversation whose call names no .

paramversionstr

The of the code that runs the . Each that the app's append records it.

paramhooksHooks | None
= None

The 's hooks for the API. None uses DefaultHooks.

paramresourcesResourcesFor
= no_resources

The function that gives each its for one HTTP request.

parammodelsSequence[str]
= ()

The models that an input can name. An empty sequence accepts each model. The API refuses another model with 422, and the Responses API with 400. With responses, the GET /v1/models route of the Responses API lists these models.

paramdefault_modelstr | None
= None

The model that a fresh input records when it names none, so that each 's model is in the . With None, an input that names no model records none.

paramshutdown_gracefloat
= 30.0

How many seconds the app waits for running turns at shutdown before it them. A cancelled turn keeps its work, and the next process can it.

paramlease_ttlfloat
= 30.0

How many seconds a 's on its stays valid without renewal.

paramkeepalivefloat
= 15.0

How many seconds an event stream can stay idle before the app sends a : keepalive comment.

paramlifespanLifespan[FastAPI] | None
= None

The 's own lifespan, for example to open and close the store's connections.

paramobserverObserver | None
= None

The observer of each HTTP request, run, and call. None observes nothing.

parammountMount
= Mount(thread_parameter='thread_id', capabilities='/v1/capabilities', health='/healthz')

The routes of the API. The health route at mount.health gives the contract version and calls no hook. The default serves the below /threads, with the id in the path parameter thread_id, the capabilities at /v1/capabilities and the health route at /healthz.

paramlist_threadsListFor | None
= None

The function that gives the list of GET <mount.threads>, when mount.list_threads is on. None responds with 501.

paramlist_toolsToolsFor | None
= None

The function that gives the list at mount.tools. None responds with 501.

paramlist_modelsModelsFor | None
= None

The function that gives the model list at mount.models. None responds with 501.

paramcomplete_taskTaskFor | None
= None

The function that gives the completion at mount.tasks. None responds with 501.

paramfeaturesSequence[str]
= ()

The names of the features that GET <mount.capabilities> reports, for the clients of the . The app does not read them.

paramresponsesbool
= False

Whether the app also serves the experimental OpenAI Responses API. It calls no hook.

Returns

FastAPI

The FastAPI app. A can add its own routes and middleware to it.

Raises:

  • ValueError: keepalive is not a positive, finite number.

CONTRACT

constantCONTRACT: Final = '0.3.0'

The of the API contract that this code serves.

GET /healthz reports it, and the OpenAPI document carries it as its . A client reads it to check that it speaks the same contract as the . The contract is at 0.x, so names and shapes can still change.

ResourcesFor

type aliasResourcesFor = Callable[[Request, Agent[Any, Any]], Awaitable[Any]]

An async function that returns the of an for one HTTP request.

The app calls it with the HTTP request and the each time that it builds a , never for a read, a or a . Its result goes to the 's build as resources, in a type that the chooses. Use it to give each the clients of the caller, for example a model client with the caller's credentials. The function gets the HTTP request, not the 's input: the input goes to the only.

no_resources

functionno_resourcesasync (request, agent) -> None

Give no : the default resources of create_app, for that need none.

paramrequestRequest

The HTTP request. It is not read.

paramagentAgent[Any, Any]

The whose the app builds. It is not read.

Mount

dataclassMount(threads='/threads', thread_parameter='id', tools=None, models=None, tasks=None, capabilities=None, health=None, list_threads=False, thread_status=True, force_sse=False, thread_id_header=False)

The routes of the API that a deployment serves, and how they behave.

The defaults serve the below /threads, with the route and without the optional routes. Mount.public() gives the routes of the public profile. The conformance suite reads the same fields to find the routes that it checks.

The app of create_app serves the routes of its mount argument. The default is Mount(thread_parameter="thread_id", capabilities="/v1/capabilities", health="/healthz").

paramthreadsstr
= '/threads'

The path of the . POST on it opens a . The routes of one are below <threads>/<thread id>, and the Location header of open and fork names that path of the new .

paramthread_parameterLiteral['id', 'thread_id']
= 'id'

The name of the path parameter that holds the id: "id" or "thread_id". With "thread_id", each operation id in the OpenAPI document also holds the path and the HTTP method.

paramtoolsstr | None
= None

The path of the list, or None to not serve it.

parammodelsstr | None
= None

The path of the model list, or None to not serve it.

paramtasksstr | None
= None

The path of the completions, or None to not serve them.

paramcapabilitiesstr | None
= None

The path of the contract version and the features, or None to not serve it.

paramhealthstr | None
= None

The path of the health route, which gives the contract version, or None to not serve it.

paramlist_threadsbool
= False

Whether GET <threads> serves the list.

paramthread_statusbool
= True

Whether GET <threads>/{id}/status serves the of a .

paramforce_ssebool
= False

Whether Call.streaming is True for each call, whatever its Accept header. A completion streams only when its body sets stream.

paramthread_id_headerbool
= False

Whether the response of open and fork also gives the id of the new in an X-Soev-Thread-Id header. The conformance suite then lets the deployment choose the id of each new , and checks the header.

methodpublic() -> Mount

Return the routes of the public profile.

Returns

Mount

The below /v1/chat/threads, with the list and without the route. The list is at /v1/chat/tools, the model list at /v1/models, the completions at /v1/completions/task and the capabilities at /v1/capabilities. There is no health route. force_sse and thread_id_header are on.

Hooks

Hooks connect the 's authentication, authorization and error format to each HTTP request.

Hooks

protocolHooks

The 's hooks on each HTTP request of the API: authentication, authorization and errors.

The framework has no access-control model. The hooks give the means, and the gives the rules. The app calls the hooks of one HTTP request in this order:

  1. subject finds the caller.
  2. authorize allows or refuses the call.
  3. extend can change the call.
  4. before_dispatch runs just before the operation.
  5. The operation runs. When it fails, on_failed runs.
  6. on_accepted runs when the operation accepted the call, and on_opened after it for a new . For open, inputs and resume, the has not run yet: it runs while the app sends the response.
  7. For an event stream, on_frame runs for each , and stream_error renders a failure of the .

An error in 1 to 6 goes to error, which renders the HTTP response. A hook refuses a call when it raises, for example fastapi.HTTPException with a status code.

Subclass DefaultHooks and override only the hooks that you need.

Example

from fastapi import HTTPException, Request

from soev_agents.entrypoints.http import DefaultHooks, Identity, create_app

# USERS maps each bearer token to the id of its user. store is a TraceStore, and agents maps each
# agent name to an Agent of your own.


class TokenHooks(DefaultHooks):
    async def subject(self, request: Request) -> Identity:
        token = request.headers.get("authorization", "").removeprefix("Bearer ")
        if token not in USERS:
            raise HTTPException(401, "unknown token")
        return Identity(USERS[token])


app = create_app(store, agents, version="1.4.0", hooks=TokenHooks())
methodsubjectasync (request) -> Identity

Find the caller of an HTTP request.

paramrequestRequest

The HTTP request, before its body is read.

Returns

Identity

The caller. The other hooks receive it in RequestContext.identity.

Raises:

  • Exception: Any error refuses the HTTP request. error renders it, with an anonymous identity.
methodauthorizeasync (ctx, call) -> None

Allow or refuse a call before anything runs.

paramctxRequestContext

The HTTP request and its caller.

paramcallCall[CallBody]

The call, as the client sent it.

Raises:

  • Exception: Any error refuses the call, and error renders it. Nothing runs and nothing is recorded.
methodextendasync (ctx, call) -> Call[CallBody]

Return the call to run, changed or not.

Use it to fill or override fields of the body, for example to choose the id of a new . The app validates the body of the returned call again, as the operation's body. A body that fails this validation is an error of the : DefaultHooks.error does not render it, so the response is 500.

paramctxRequestContext

The HTTP request and its caller.

paramcallCall[CallBody]

The call, after authorize allowed it.

Returns

Call[CallBody]

The call to run.

methodoutbound_headersasync (ctx, call, outbound) -> Mapping[str, str]
paramctxRequestContext
paramcallCall[CallBody]
paramoutbound_OutboundRequest
methodbefore_dispatchasync (ctx, call) -> None

Run the 's work just before the operation, for example to record a new in an index.

paramctxRequestContext

The HTTP request and its caller.

paramcallPreparedCall[CallBody]

The call to run. Its call attribute holds the Call that extend returned.

Raises:

  • Exception: Any error refuses the call, and error renders it. The operation does not run, and on_failed is not called.
methodon_acceptedasync (ctx, call, reply) -> None

Run the 's work after the operation accepted the call, before the app sends the response.

For open, inputs and resume, the runs after this hook. An error of the goes to error, not to on_failed.

paramctxRequestContext

The HTTP request and its caller.

paramcallPreparedCall[CallBody]

The call that ran. Its call attribute holds the Call.

paramreplyBackendReply

The result of the operation. Its status_code is the HTTP status. A new is a reply.status_code of 201 after open or fork.

Raises:

  • Exception: Any error becomes the error response, through error. It does not undo what the operation recorded.
methodon_openedasync (ctx, *, thread_id, agent) -> None

Run the 's work after open made a new , before the response is sent.

The of the new runs after this hook.

paramctxRequestContext

The HTTP request and its caller.

paramthread_idstr

The id of the new .

paramagentstr

The name of the that runs the .

Raises:

  • Exception: Any error becomes the error response, through error. The stays.
methodon_frameasync (ctx, call, frame) -> None

Observe one of an event stream, before the app sends it.

Only event streams call it. A JSON response does not.

paramctxRequestContext

The HTTP request and its caller.

paramcallPreparedCall[CallBody]

The call that streams. Its call attribute holds the Call.

paramframebytes

The bytes of one complete server-sent , as the app sends them, with the blank line that ends it. A : keepalive comment is a too.

Raises:

  • Exception: Any error stops the , and stream_error renders it.
methodon_failedasync (ctx, call, error) -> None

Run the 's work when the operation failed, for example to undo the work of before_dispatch.

error renders the failure after this hook. An error of on_accepted or on_opened does not call it. An error of the of open, inputs or resume does not call it either, because the runs after the operation accepted the call.

paramctxRequestContext

The HTTP request and its caller.

paramcallPreparedCall[CallBody]

The call that failed. Its call attribute holds the Call.

paramerrorException

The error of the operation.

methoderrorasync (ctx, call, error) -> ErrorReply

Render an error of a call as its HTTP response.

paramctxRequestContext

The HTTP request and its caller. The caller is anonymous when subject failed.

paramcallCall[CallBody]

The call, as the client sent it. Its body is None when subject failed.

paramerrorException

The error that a hook or the operation raised.

Returns

ErrorReply

The HTTP response.

Raises:

  • Exception: An error that the hook does not render. It raises it again.
methodstream_errorasync (ctx, call, error) -> StreamError | None

Render a failure of an event stream as its last .

The status code was sent when the started, so the failure can only end the .

paramctxRequestContext

The HTTP request and its caller.

paramcallPreparedCall[CallBody]

The call that streams. Its call attribute holds the Call.

paramerrorException

The error of the , or of on_frame.

Returns

StreamError | None

The last to send, or None to end the without one.

DefaultHooks

classDefaultHooks

The hooks of a without authentication: each caller is anonymous, and each call is allowed.

create_app uses them when it gets no hooks. Subclass them and override only the hooks that you need. Each hook that is not listed below does nothing.

  • subject returns an anonymous identity.
  • extend returns the call unchanged.
  • error renders the errors of the framework and fastapi.HTTPException, and raises each other error again.
  • stream_error raises the error again, so the fails without a last .
methodsubjectasync (request) -> Identity

Return an anonymous identity for each HTTP request.

paramrequestRequest

The HTTP request. It is not read.

Returns

Identity

Identity(None).

methodauthorizeasync (ctx, call) -> None

Allow each call.

paramctxRequestContext

The HTTP request and its caller.

paramcallCall[CallBody]

The call.

methodextendasync (ctx, call) -> Call[CallBody]

Return the call unchanged.

paramctxRequestContext

The HTTP request and its caller.

paramcallCall[CallBody]

The call.

Returns

Call[CallBody]

call.

methodoutbound_headersasync (ctx, call, outbound) -> Mapping[str, str]
paramctxRequestContext
paramcallCall[CallBody]
paramoutbound_OutboundRequest
methodbefore_dispatchasync (ctx, call) -> None

Do nothing.

paramctxRequestContext

The HTTP request and its caller.

paramcallPreparedCall[CallBody]

The call to run.

methodon_acceptedasync (ctx, call, reply) -> None

Do nothing.

paramctxRequestContext

The HTTP request and its caller.

paramcallPreparedCall[CallBody]

The call that ran.

paramreplyBackendReply

The result of the operation.

methodon_openedasync (ctx, *, thread_id, agent) -> None

Do nothing.

paramctxRequestContext

The HTTP request and its caller.

paramthread_idstr

The id of the new .

paramagentstr

The name of the that runs the .

methodon_frameasync (ctx, call, frame) -> None

Do nothing.

paramctxRequestContext

The HTTP request and its caller.

paramcallPreparedCall[CallBody]

The call that streams.

paramframebytes

The bytes of one server-sent .

methodon_failedasync (ctx, call, error) -> None

Do nothing.

paramctxRequestContext

The HTTP request and its caller.

paramcallPreparedCall[CallBody]

The call that failed.

paramerrorException

The error of the operation.

methoderrorasync (ctx, call, error) -> ErrorReply

Render the errors of the framework and fastapi.HTTPException as JSON responses.

Each body is a JSON object with a detail field. An HTTPException keeps its status code, its detail and its headers. The runtime's refusals get these status codes:

  • 422: the refuses the input (InputDeniedError), or a log is outside the (PositionOutOfRangeError).
  • 409: the has nothing to (NothingToCancelError), its has not ended (ThreadActiveError), its id is in use (ThreadExistsError), or another process runs it (LeaseHeldError).
paramctxRequestContext

The HTTP request and its caller.

paramcallCall[CallBody]

The call, as the client sent it.

paramerrorException

The error that a hook or the operation raised.

Returns

ErrorReply

The HTTP response.

Raises:

  • Exception: Each other error, raised again.
methodstream_errorasync (ctx, call, error) -> StreamError | None

Raise the error again, so that the fails without a last .

paramctxRequestContext

The HTTP request and its caller.

paramcallPreparedCall[CallBody]

The call that streams.

paramerrorException

The error of the .

Raises:

  • Exception: error.

Identity

dataclassIdentity(subject, state=None)

Who makes an HTTP request, as Hooks.subject finds it.

paramsubjectstr | None

The id of the caller, or None for an anonymous caller. The framework does not read it. Only the 's own hooks read it.

paramstateobject
= None

Any other value that the keeps about the caller, for its later hooks, for example the caller's roles. The framework does not read it.

RequestContext

dataclassRequestContext(request, identity)

One HTTP request of the API and its caller, as each hook receives them.

paramrequestRequest

The HTTP request.

paramidentityIdentity

The caller, as Hooks.subject returned it.

Call

dataclassCall[T](operation, thread_id, body, streaming=False, after=0, listing=None)

One call of the API: the operation, its and its parsed body.

The hooks receive the call before it runs. Hooks.extend can return a changed copy, for example with dataclasses.replace.

paramoperationOperation

The operation of the call.

paramthread_idstr | None

The from the path of the HTTP request, or None for an operation without a in its path. For open, the body holds the id of the new , when the client chose one.

parambodyT

The parsed body of the HTTP request, or None for an operation without a body. open, inputs, fork and task have a body, and cancel has an optional one. The hooks get it as a CallBody.

paramstreamingbool
= False

Whether the client accepts an event stream (Accept: text/event-stream), or the Mount has force_sse. Then open, inputs and resume respond with a of . events requires it. For task, only the stream field of the body sets it.

paramafterint
= 0

The log after which events starts, from the Last-Event-ID header. 0 for each other operation.

paramlistingListQuery | None
= None

The query of a list, for the list operation only. None for each other operation.

PreparedCall

dataclassPreparedCall[T](call, outbound, headers=dict(), cached_reply=None)

A call that is ready to run, as the hooks after extend receive it.

The app of create_app runs each call in its own process, so only call holds information there. The other fields serve a backend that sends the call to another .

paramcallCall[T]

The call to run, as extend returned it, with its body validated again.

paramoutbound_OutboundRequest | None

The HTTP request that a backend sends to another for the call, or None for a call that runs in this process.

paramheadersMapping[str, str]
= dict()

The headers that Hooks.outbound_headers gave for outbound. Empty for a call that runs in this process.

paramcached_replyBackendReply | None
= None

A reply that a backend kept from an earlier call, to give instead of a new HTTP request, or None.

BackendReply

dataclassBackendReply(status_code, media_type, content, headers=dict(), thread_id=None)

The result of one operation, before the app sends it as the HTTP response.

Hooks.on_accepted receives it. A complete_task function of create_app gives one, inside a ReplyContext.

paramstatus_codeint

The HTTP status code.

parammedia_typestr | None

The value of the Content-Type header, or None for a response without a body.

paramcontentBaseModel | bytes | AsyncIterator[bytes] | None

The body. The app sends a pydantic model as JSON, and bytes as they are. With the media type text/event-stream, the app streams an async iterator of bytes, and Hooks.on_frame sees each complete . With another media type, the app joins the bytes of an iterator before it sends them. None sends an empty body.

paramheadersMapping[str, str]
= dict()

More headers of the response.

paramthread_idstr | None
= None

The id of the of the call, or None. It names a new when open or fork responds with 201: the app then sets the Location header to the path of that .

Operation

type aliasOperation = Literal['open', 'inputs', 'resume', 'cancel', 'events', 'fork', 'read', 'export', 'status', 'delete', 'list', 'tools', 'models', 'task', 'capabilities']

The name of one operation of the API, as a hook receives it in Call.operation.

With the default mount of create_app, the app serves these operations:

  • open: POST /threads
  • inputs: POST /threads/{thread_id}/inputs
  • resume: POST /threads/{thread_id}/resume
  • cancel: POST /threads/{thread_id}/cancel
  • fork: POST /threads/{thread_id}/fork
  • read: GET /threads/{thread_id}
  • export: GET /threads/{thread_id}/export
  • status: GET /threads/{thread_id}/status
  • events: GET /threads/{thread_id}/events
  • delete: DELETE /threads/{thread_id}
  • capabilities: GET /v1/capabilities

list, tools, models and task name the optional routes of a Mount: GET <threads> with list_threads, and the paths tools, models and tasks. Mount.public() serves all four.

ErrorReply

dataclassErrorReply(status_code, media_type, body, headers=dict())

The HTTP response to an error, as Hooks.error renders it.

paramstatus_codeint

The HTTP status code.

parammedia_typestr

The value of the Content-Type header, for example "application/json".

parambodyMapping[str, JsonValue] | bytes

The body of the response. A mapping is sent as JSON, and bytes are sent as they are.

paramheadersMapping[str, str]
= dict()

More headers of the response, for example Retry-After.

StreamError

dataclassStreamError(event, data)

The last of an event stream that failed, as Hooks.stream_error renders it.

The status code is sent when the starts, so a later error cannot change it. The app sends this instead, as event: <event> and data: <JSON of data>, and then ends the .

parameventstr | None

The name of the server-sent , for example "error", or None to send no event: line.

paramdataMapping[str, JsonValue]

The JSON object of the data: line.

Request bodies

A hook finds the body of a call in Call.body, as one of these models. Check its type before you read a field.

CallBody

type aliasCallBody = wire.OpenThread | wire.SendInput | wire.ForkThread | wire.CancelThread | wire.TaskRequest | None

The body of a Call that the hooks get, by operation.

open has an OpenThread, inputs a SendInput, fork a ForkThread, and task a TaskRequest. cancel has a CancelThread, or None when the client sent no body. Each other operation has None. Check the type with isinstance before you read a field.

OpenThread

modelOpenThread

What it takes to open a : the , your first input, and optionally the id you want.

It is the body of POST /threads, and a hook finds it in Call.body for the open operation.

attributeagentstr

The name of the that runs the .

attributeinputJsonValue

The first input, any JSON value that fits the input schema of the .

attributemodelstr | None
= None

The model that the runs on, or None for the default_model of create_app, else the default of the .

attributethread_idstr | None
= None

The id that the new gets, or None for a generated id. One URL-safe path segment of 1 to 128 characters: letters, digits, _, . and -. A hook can set it.

SendInput

modelSendInput

What it takes to continue a : the input, and the request it answers if it answers one.

It is the body of POST /threads/{thread_id}/inputs, and a hook finds it in Call.body for the inputs operation.

attributeinputJsonValue

The input, any JSON value that fits the input schema of the .

attributemodelstr | None
= None

The model that the runs on, or None for the default_model of create_app, else the default of the . An input with answering records None.

attributeansweringstr | None
= None

The id (stream:seq) of the that the input responds to, or None to start a new .

ForkThread

modelForkThread

What it takes to a : the of the last to copy.

It is the body of POST /threads/{thread_id}/fork, and a hook finds it in Call.body for the fork operation.

attributeatint

The log of the last that the new gets.

CancelThread

modelCancelThread

What it takes to the of one input, instead of the current .

It is the optional body of POST /threads/{thread_id}/cancel. A hook finds it in Call.body for the cancel operation, or None when the client sent no body.

attributeinputint | None
= None

The log of the input whose to , or None to the current .

The public profile

Four functions of create_app serve the optional routes of Mount.public(): the , and model lists, and the completions.

ListFor

type aliasListFor = Callable[[RequestContext, ListQuery], Awaitable[wire.ThreadList]]

An async function that gives the list of a caller, the list_threads argument of create_app.

The app calls it for GET <threads> after the hooks allowed the call, with the HTTP request, its caller and the query. The app keeps no list itself: the keeps one, for example in Hooks.on_opened. An error goes to Hooks.error.

ListQuery

dataclassListQuery(agent=None, limit=50, before=None, include=frozenset())

The query of a list, from the query string of GET <threads>.

The app validates the query string before the list function receives it, and refuses an invalid one with 422. The app does not apply the query: the list function does.

paramagentstr | None
= None

The whose the client asks for, or None for the of each . 1 to 64 characters.

paramlimitint
= 50

The maximum number of in the list, from 1 to 100. 50 when the client gives none.

parambeforestr | None
= None

The id of the last of the page before, so that the list continues after it, or None for the first page. 1 to 128 characters.

paramincludefrozenset[str]
= frozenset()

The names in the comma-separated include parameter, for example status. An empty set when the client gives none.

ToolsFor

type aliasToolsFor = Callable[[RequestContext], Awaitable[wire.ToolList]]

An async function that gives the list for a caller, the list_tools argument of create_app.

The app calls it for the route Mount.tools, after the hooks allowed the call. An error goes to Hooks.error.

ModelsFor

type aliasModelsFor = Callable[[RequestContext], Awaitable[wire.ModelList]]

An async function that gives the model list for a caller, the list_models argument of create_app.

The app calls it for the route Mount.models, after the hooks allowed the call. The list does not change which models an input can name: the models argument of create_app does. An error goes to Hooks.error.

TaskFor

type aliasTaskFor = Callable[[RequestContext, wire.TaskRequest], ReplyContext]

A function that runs one completion, the complete_task argument of create_app.

The app calls it for POST <Mount.tasks>, after the hooks allowed the call, with the validated body. A completion is one model call in the format of the OpenAI Chat Completions API, outside any . The app records nothing in a for it. The function returns a ReplyContext. Make its reply with task_completion, or, when the body sets stream, as a text/event-stream of task_chunk .

ReplyContext

type aliasReplyContext = AbstractAsyncContextManager[BackendReply]

An async context manager that gives the BackendReply of one call.

The app enters it and reads the reply. For a JSON reply, the app leaves it after it reads the body, before it sends the response. For a , the app leaves it after the last , also when the client disconnects. So the context manager can close what the reads, for example an HTTP response from a model . An error before the reply goes to Hooks.error.

Lists

The bodies that the three list functions give.

ThreadList

modelThreadList

The body of a list, which a list_threads function of create_app gives.

attributedatalist[ThreadSummary]

The of the list, in the order of the .

ThreadSummary

modelThreadSummary

One in a list: its id, its , when it was opened, and its title.

A list_threads function of create_app gives these in the data of a ThreadList.

attributethread_idstr

The id of the .

attributeagentstr

The name of the that runs the .

attributecreated_atdatetime

When the was opened.

attributetitlestr | None

The title that the opening input named, or None when it named none.

ToolList

modelToolList

The body of the list, which a list_tools function of create_app gives.

attributeobjectLiteral['list']
= 'list'

Always "list".

attributedatalist[ToolView]

The .

ToolView

modelToolView

One in the list: its name, and how a client shows a call of it.

attributenamestr

The name of the , as a model calls it.

attributestatusdict[str, JsonValue]

How a client shows a call of the , as JSON: running while it runs, and done once its tool_output is recorded. Each has a template with {{param}} placeholders, a fallback, and params, which names the source of each value. The app does not check this shape.

ModelList

modelModelList

The body of the model list, which a list_models function of create_app gives.

attributedatalist[ModelView]

The models.

ModelView

modelModelView

One model in the model list: what a client shows to people, and the id that an input names.

attributeidstr

The catalog id of the model, as vendor/model. It is not the id of an endpoint.

attributelabelstr

The name to show, which is id unless the deployment gives another one.

attributedescriptionDisplayDescription | None

The description to show, or None.

attributevendorstr | None

The organization that made the model, or None.

attributeoriginstr | None

The country of the vendor, or None.

attributeopen_weightsbool | None

Whether the weights of the model are open, or None when unknown.

attributelicensestr | None

The license of the model, or None.

attributehostingHosting | None

Where the model runs and who runs it, or None.

attributecapabilitiesModelCapabilities

What the model can do.

attributestructured_outputStructuredOutputStrategy

How the model gives output in a JSON schema.

attributecontext_windowint

The context window of the model, in tokens.

attributemax_output_tokensint | None

The maximum number of output tokens of one model call, or None when unstated.

attributelifecycleLiteral['active', 'superseded', 'deprecated']

active, superseded or deprecated.

attributereplaced_bystr | None

The catalog id of the model that replaces it, or None.

attributedefaultbool

Whether the model is the default model for chat.

ModelCapabilities

classModelCapabilities

What a model can do, each as a CapabilityState.

attributetoolsCapabilityState

Whether the model can call .

attributevisionCapabilityState

Whether the model can read images.

attributeaudioCapabilityState

Whether the model can read audio.

attributereasoningCapabilityState

Whether the model reasons before its output.

CapabilityState

type aliasCapabilityState = Literal['unknown', 'supported', 'unsupported']

Whether a model has a capability: supported, unsupported, or unknown when nobody stated it.

StructuredOutputStrategy

type aliasStructuredOutputStrategy = Literal['unknown', 'native', 'json_mode', 'unsupported']

How a model gives output in a JSON schema.

native: the model takes the schema in the request. json_mode: the model takes a request for JSON, and the instructions name the schema. unsupported: the model gives no structured output. unknown: nobody stated it.

DisplayDescription

modelDisplayDescription

A text that a client shows to people, in Dutch and in English.

attributenlstr

The Dutch text.

attributeenstr

The English text.

Hosting

modelHosting

Where the endpoint of a model runs, who runs it, and how long it keeps the data of a call.

attributehosted_bystr

The name of the organization that runs the endpoint of the model.

attributeregionstr

The region where the endpoint runs.

attributeretentionstr | None
= None

How long the endpoint keeps the data of a call, as its operator states it, or None when the operator states nothing.

Task completions

A completion is one model call in the OpenAI Chat Completions format, outside any . These are its body and the functions that make its response.

TaskRequest

modelTaskRequest

The body of a completion, in the OpenAI Chat Completions format, without a model.

The app validates it and gives it to the complete_task function of create_app. Validation refuses a field that the class does not declare.

attributemessageslist[TaskMessage]

The messages for the model, at least one.

attributestreambool
= False

Whether the client asks for a text/event-stream response. It sets Call.streaming too.

attributetemperaturefloat | None
= None

The sampling temperature, from 0 to 2, or None.

attributemax_tokensint | None
= None

The maximum number of output tokens, more than 0, or None.

attributetop_pfloat | None
= None

The nucleus sampling probability, from 0 to 1, or None.

attributeresponse_formatAnnotated[TextFormat | ObjectFormat | SchemaFormat, Field(discriminator=type)] | None
= None

The format of the output, or None for text.

attributestopstr | list[str] | None
= None

One stop sequence or a list of them, or None.

TaskMessage

modelTaskMessage

One message of a completion, in the OpenAI Chat Completions format.

Validation refuses a message that breaks these rules:

  • The roles system, developer and assistant take text content only.
  • Each message has content, except a message of the role assistant with tool_calls.
  • Only the role assistant has tool_calls.
  • The role tool has a tool_call_id, and only that role has one.
attributeroleLiteral['system', 'developer', 'user', 'assistant', 'tool']

Who wrote the message.

attributecontentContent | None
= None

The content, or None for a message of the role assistant that only calls .

attributetool_call_idstr | None
= None

The id of the whose result a message of the role tool holds, or None.

attributetool_callslist[HistoryToolCall] | None
= None

The of a message of the role assistant, or None.

Content

type aliasContent = str | list[Annotated[TextContent | ImageContent, Field(discriminator=type)]]

The content of a TaskMessage: a text, or a list of text and image parts.

TextContent

modelTextContent

A text part of the content of a TaskMessage.

attributetypeLiteral['text']

Always "text".

attributetextstr

The text.

ImageContent

modelImageContent

An image part of the content of a TaskMessage.

attributetypeLiteral['image_url']

Always "image_url".

attributeimage_urlImageURL

The address of the image.

ImageURL

modelImageURL

The address of an image in an ImageContent.

attributeurlstr

The URL of the image.

HistoryToolCall

modelHistoryToolCall

A of the model, in a TaskMessage of the role assistant or in a TaskAnswer.

attributeidstr

The id of the call. A TaskMessage of the role tool names it in tool_call_id.

attributetypeLiteral['function']

Always "function".

attributefunctionFunctionCall

The and its arguments.

FunctionCall

modelFunctionCall

The function of a HistoryToolCall: the name of the and its arguments.

attributenamestr

The name of the .

attributeargumentsstr

The arguments, as the text of a JSON object.

TextFormat

modelTextFormat

The response_format of a completion that asks for text output.

attributetypeLiteral['text']

Always "text".

ObjectFormat

modelObjectFormat

The response_format of a completion that asks for a JSON object, without a schema.

attributetypeLiteral['json_object']

Always "json_object".

SchemaFormat

modelSchemaFormat

The response_format of a completion that asks for JSON output in a schema.

attributetypeLiteral['json_schema']

Always "json_schema".

attributejson_schemaSchemaDefinition

The schema.

SchemaDefinition

modelSchemaDefinition

The JSON schema of a SchemaFormat.

attributenamestr

The name of the schema.

attributeschema_dict[str, JsonValue]

The JSON schema of the output. On the wire, its field name is schema.

attributestrictbool
= False

Whether the output must follow the schema exactly.

attributedescriptionstr | None
= None

What the output is, for the model, or None.

task_completion

functiontask_completion(answer, *, model, response_id, created, finish='stop', usage=None) -> bytes

Make the JSON body of a completion that does not stream, in the OpenAI Chat Completions format.

The body is a chat.completion object with one choice, at index 0, whose message is answer. The message has the role assistant, and it leaves out reasoning_content when it is None, and tool_calls when it is None or empty. Give the body to the app in a BackendReply with the media type application/json.

paramanswerTaskAnswer

The message of the model.

parammodelstr

The id of the model that made the message.

paramresponse_idstr

The id of the completion.

paramcreatedint

When the completion was made, in seconds since the Unix epoch.

paramfinishstr
= 'stop'

The finish_reason of the choice, for example "stop", "length" or "tool_calls".

paramusageTaskUsage | None
= None

The token counts of the model call, or None to leave out usage.

Returns

bytes

The JSON body, encoded as UTF-8.

task_chunk

functiontask_chunk(model, response_id, created, delta, *, finish=None, usage=None) -> bytes

Make one of a completion that streams, in the OpenAI Chat Completions format.

The is a server-sent without an name: data: <JSON> and a blank line. Its JSON is a chat.completion.chunk object with one choice, at index 0, that holds delta. With usage, the has no choice and gives the token counts only. This function does not make the data: [DONE] that ends an OpenAI stream. Send data: [DONE] yourself as the last .

parammodelstr

The id of the model that makes the message.

paramresponse_idstr

The id of the completion. Use the same id in each of one .

paramcreatedint

When the completion was made, in seconds since the Unix epoch.

paramdeltaMapping[str, JsonValue]

The next part of the message, for example {"content": "Hello"}, or {"role": "assistant"} in the first .

paramfinishstr | None
= None

The finish_reason of the choice in the last of the message, or None before it.

paramusageTaskUsage | None
= None

The token counts of the model call, for a after the message, or None.

Returns

bytes

The , encoded as UTF-8.

TaskAnswer

modelTaskAnswer

The message that the model gave for a completion, as task_completion takes it.

attributeroleLiteral['assistant']
= 'assistant'

Always "assistant".

attributecontentstr

The text of the message.

attributereasoning_contentstr | None
= None

The reasoning of the model, or None.

attributetool_callslist[HistoryToolCall] | None
= None

The of the model, or None.

TaskUsage

modelTaskUsage

The token counts of the model call of a completion.

attributeprompt_tokensint

The number of input tokens.

attributecompletion_tokensint

The number of output tokens.

attributetotal_tokensint

The number of input and output tokens together.

Client models

A body of the API as a pydantic model, for Python clients and that read .

ThreadExport

modelThreadExport

One 's stored , every field, in log order: a file.

It is the body of GET /threads/{id}/export. Unlike a read, it leaves out nothing that only the model sees, such as the images of a result. The app reads it from the store directly, so a whose is gone exports too.

attributeformatLiteral['soev.trace/1']
= …

The format of the document, always "soev.trace/1". Validation refuses a document of another format.

attributethread_idstr

The id of the .

attributeexported_atdatetime

When the was exported, in UTC.

attributeeventslist[LogEntry[StoredEvent]]

The stored of the , each with its log , in log order.

methodof(thread_id, entries) -> ThreadExport

Make the export of a from its stored , exported now.

paramthread_idstr

The id of the .

paramentriesSequence[LogEntry[StoredEvent]]

The stored of the , in log order, as TraceStore.read yields them.

Returns

ThreadExport

The export.

On this page