Threads AI

host

Bind agents to a store, channels and schedules.

Starts nothing until ready(). Its HTTP API also serves web UIs: the AI SDK UI message stream (useChat) at /v1/ui/ai-sdk/{agent} and AG-UI at /v1/ui/ag-ui/{agent}, with frames derived from the log; a browser chat key is scoped to the signed-in principal.

Import from @threads/host (TypeScript) or threads.host (Python).

function host(options: {
  store: Store;
  agents: Record<string, Agent<unknown, unknown>>;
  channels?: Record<string, ChannelAdapter>;
  ceiling?: Partial<Policy.permissions>;
  telemetry?: Exporter;
  schedules?: readonly Schedule[];
  authenticate?: (request: Request) => Promise<Principal | null>;
  messagePolicy?: readonly MessagePolicyRule[];
}): Host

Parameters

storeStorerequired

The store every bound agent's threads, runs and host records live in. See Store.

agentsRecord<string, Agent<unknown, unknown>>required

Keyed by the name channels, schedules and the HTTP API use.

channelsRecord<string, ChannelAdapter>default {}

A channel thread's replies are derived from its log, whatever ran it: each end_turn reply and each open approval card is a host-issued channel_send, issued after every run of the thread and, for a crash in between, again after ready(). A send with a result or a parked effect is never issued twice.

ceilingPartial<Policy.permissions>

The host ceiling every run this host starts or resumes is also decided under (Agent.run ceiling). Omitted: no ceiling.

telemetryExporter

An exporter, such as otel(), that the host syncs every second and once more on stop() (bounded by 5 s). A failing collector is retried with back-off (1 s doubling to 60 s) and logged once per streak; runs never wait on it. Omitted: no telemetry. See Exporter.

schedulesreadonly Schedule[]default []

The schedules the host fires once ready() has run. Default [] fires none.

authenticate(request: Request) => Promise<Principal | null>

Maps an HTTP API request to a principal, or null for 401. Omitted: every /v1 route answers 401; channel webhooks still work.

authenticate(request)Requestrequired

The incoming HTTP request, to read its headers or cookies: a fetch Request in TypeScript, a Starlette Request in Python.

messagePolicy / message_policyreadonly MessagePolicyRule[]default []

Rules that let one host agent start, send to, ask, monitor or cancel another beyond what a team grants (wait is decided as monitor). They decide after a team's grant and before default deny, for every op of every sender, and only add. Each (from, to) pair appears once (a repeat is refused at setup with duplicate_name), so a logged decision names its rule by from and to. A from or to that names no host agent is refused at setup (invalid_config); so is an empty allow, a rule to a host member that allows start, monitor or cancel, and a rule between host members that allows anything but send or ask (invalid_config, naming the rule). An agent gets the team tools only for the ops some rule with it as from allows. A rule that allows start makes its from a lead; one whose rules target only host members makes it a caller, in no team. Default []: everything else is denied. Every decision is logged as message_policy_decided.

Returns

Host

Edit on GitHub

On this page