Skip to content

startAgUiServer

startAgUiServer(config, port, host?, corsOrigin?): Promise<Server<typeof IncomingMessage, typeof ServerResponse>>

Defined in: _worktrees/docs-release/gaunt-sloth/packages/agent/src/modules/apiAgUiModule.ts:479

Start the AG-UI server.

host is the interface to bind, and its precedence is the argument (what the caller’s --host flag said), then commands.api.host, then DEFAULT_AGUI_HOST. It is passed to listen unvalidated, on purpose: there is no silent wrong answer to prevent here the way there is for a port (listen(NaN) binds an arbitrary port, where a host node cannot resolve raises on the error event and is rejected below), and any list of accepted literals would refuse ::, a specific interface address, or a hostname — all legitimate. An empty host is the one value that is rewritten, because listen treats it as falsy and binds the wildcard, which is the opposite of anything an empty value could have meant.

corsOrigin is the browser origin allowed to call this server, and it takes the same shape of precedence: the argument (the caller’s --cors-origin flag), then commands.api.cors.allowOrigin, then the default below. It is resolved here rather than at either CLI door for the reason DEFAULT_AGUI_HOST gives about the host — one definition, reached by both doors and by a programmatic caller alike.

Why an argument at all, when the header value is already a config key: the port and the origin are one decision. Whatever moves the web client — a per-worktree port allocation, a second client on the same machine, a WEB_PORT in a .env — changes its origin at the same moment, and a config file cannot be rewritten by the thing that computed the port. Without the override the client relocates and every request it makes is then refused by a preflight still naming the origin it no longer has (OPS-16).

Singular, matching the config key it overrides rather than the ADK server’s plural --adk.web.cors.origins: that server matches an incoming origin against a list and echoes the one that matched, while this one sets the header verbatim, and Access-Control-Allow-Origin carries exactly one origin. A list here would produce a header no browser accepts.

A blank origin falls through to the config rather than being sent, because an empty Access-Control-Allow-Origin matches nothing and would block every browser client — the opposite of what supplying the flag can have meant. That is the same reasoning as the empty host above and the opposite outcome, since there the empty value had a live meaning to listen worth overriding.

Resolves with the bound http.Server once it is listening: the one handle that says which port a port: 0 request actually got, and the one way to stop the server. The CLI door ignores it.

GthConfig

number

string

string

Promise<Server<typeof IncomingMessage, typeof ServerResponse>>