-
Notifications
You must be signed in to change notification settings - Fork 0
api web api
The web HTTP API is the browser-facing wire surface for the Qredence web chat UI. Routes live under web/app/src/routes/api/ as thin TanStack Start wrappers that delegate to handler functions in web/server/src/handlers/. The browser talks HTTP only: NDJSON over POST /api/chat for streaming a turn, and Server-Sent Events over GET /api/chat/events for out-of-turn pushes. The contract is defined in web/protocol/src/chat-protocol.ts, validated by zod schemas in web/protocol/src/chat-protocol.zod.ts.
The server binds to 127.0.0.1 with no tokens, so there is no multi-user authentication on this surface. All handlers are process-agnostic Request -> Response functions coordinated by a single PrimeBridge per Node process (web/server/src/prime-bridge.ts).
Routes are declared under web/app/src/routes/api/. Each row lists the route file, the method and path, the underlying handler, and its purpose. The route wrappers are one-line delegations to @prime-agent/web-server.
| Method | Path | Route file | Handler | Purpose |
|---|---|---|---|---|
| POST | /api/chat | web/app/src/routes/api/chat.ts |
handleChatPost |
Run a turn; returns NDJSON ChatStreamEvent frames |
| POST | /api/chat/abort | web/app/src/routes/api/chat/abort.ts |
handleChatAbortPost |
Abort the active turn and cancel pending dialogs |
| POST | /api/chat/question | web/app/src/routes/api/chat/question.ts |
handleChatQuestionPost |
Answer a pending tool question |
| POST | /api/chat/new | web/app/src/routes/api/chat/new.ts |
handleChatNewPost |
Create a session ({cwd, model?, thinkingLevel?}) |
| POST | /api/chat/resume | web/app/src/routes/api/chat/resume.ts |
handleChatResumePost |
Resume by sessionId or sessionFile
|
| POST | /api/chat/model | web/app/src/routes/api/chat/model.ts |
handleChatModelPost |
session.setModel({provider, id}) |
| GET | /api/chat/session | web/app/src/routes/api/chat/session.ts |
handleChatSessionGet |
One session plus its messages |
| GET | /api/chat/sessions | web/app/src/routes/api/chat/sessions.ts |
handleChatSessionsGet |
Session picker list (?cwd= optional) |
| GET | /api/chat/models | web/app/src/routes/api/chat/models.ts |
handleChatModelsGet |
Model registry (`?scope=enabled |
| POST | /api/chat/models/discover | web/app/src/routes/api/chat/models/discover.ts |
handleChatModelsDiscoverPost |
Probe an OpenAI-compatible base URL /v1/models
|
| GET | /api/chat/settings | web/app/src/routes/api/chat/settings.ts |
handleChatSettingsGet |
Resolved settings |
| PATCH | /api/chat/settings | web/app/src/routes/api/chat/settings.ts |
handleChatSettingsPatch |
Persist settings via SettingsManager
|
| GET | /api/chat/providers | web/app/src/routes/api/chat/providers.ts |
handleChatProvidersGet |
Provider catalog plus credentials |
| POST | /api/chat/providers | web/app/src/routes/api/chat/providers.ts |
handleChatProvidersPost |
Store a provider API key |
| DELETE | /api/chat/providers | web/app/src/routes/api/chat/providers.ts |
handleChatProvidersDelete |
Remove a provider credential |
| POST | /api/chat/providers/oauth | web/app/src/routes/api/chat/providers/oauth.ts |
handleChatProvidersOAuth |
Start/poll/continue/cancel an interactive OAuth login |
| GET | /api/chat/resources | web/app/src/routes/api/chat/resources.ts |
handleChatResourcesGet |
Skills, prompts, extensions, themes |
| GET | /api/chat/commands | web/app/src/routes/api/chat/commands.ts |
handleChatCommandsGet |
Slash command autocomplete |
| POST | /api/chat/command | web/app/src/routes/api/chat/command.ts |
handleChatCommandPost |
Run a slash command on a session |
| GET | /api/chat/events | web/app/src/routes/api/chat/events.ts |
handleChatEventsGet |
SSE stream with ring-buffer replay |
| GET | /api/workspace/tree | web/app/src/routes/api/workspace/tree.ts |
handleWorkspaceTreeGet |
Workspace file tree |
| GET | /api/workspace/file | web/app/src/routes/api/workspace/file.ts |
handleWorkspaceFileGet |
File preview |
| GET | /api/workspace/browse | web/app/src/routes/api/workspace/browse.ts |
handleWorkspaceBrowseGet |
Directory picker |
| POST | /api/workspace/root | web/app/src/routes/api/workspace/root.ts |
handleWorkspaceRootPost |
Rebind the default cwd |
| GET | /api/health | web/app/src/routes/api/health.ts |
handleHealthGet |
Liveness plus kernel readiness |
The wire types are defined in web/protocol/src/chat-protocol.ts and validated by zod in web/protocol/src/chat-protocol.zod.ts (ChatRequestSchema, ChatStreamEventSchema, ChatQuestionAnswerRequestSchema, the workspace schemas, and so on).
Body of POST /api/chat. It extends ChatSessionMetadata (one of sessionId/sessionFile, plus optional cwd). Optional fields: message, model (ChatModelSelection, either a string key or {provider, id, thinkingLevel?}), mode, planAction, streamingBehavior, userId, and userEmail.
userId and userEmail may appear on the wire for OpenAPI documentation, but client-supplied values are stripped after validation; the server sets them only from the authenticated session (see the post-chat handler). Do not treat them as client-controllable identity.
A single NDJSON frame on the turn stream, discriminated by type. A turn begins with start, then a mix of delta/tool/thinking content and plan/state/queue lifecycle signals, optional compaction/retry progress, and ends with done (success) or error. Validated by ChatStreamEventSchema.
| Frame type | Shape |
|---|---|
start |
{type, id, runId, sessionId, sessionFile?, sessionReset?, diagnostics?} |
delta |
{type, text, messageId?} |
tool |
{type, part, messageId?} (a ChatToolPart) |
thinking |
{type, text, messageId?} |
plan |
{type, mode, executing, completed, total, state, message?} |
state |
{type, state} (a ChatStateEvent, e.g. agent_start/agent_end) |
queue |
{type, steering, followUp} |
compaction |
`{type, phase: "start" |
retry |
`{type, phase: "start" |
done |
{type, runId, message, sessionId, sessionFile?, sessionReset?} |
error |
{type, message, runId?} |
Identifies the target session. At least one of sessionFile/sessionId is typically provided to continue an existing session; omitting both starts a new one. Includes an optional cwd.
GET /api/health returns { ok: true, kernel, uptimeMs }, where kernel is { ok: boolean, reason?: string } from PrimeBridge.kernelReadyState(). The client hook web/app/src/lib/pi/use-kernel-health.ts polls this endpoint (default 15 s) to drive the kernel status chip.
handleChatPost (web/server/src/handlers/chat.ts) validates the body with ChatRequestSchema, resolves the session, then returns a ReadableStream with Content-Type: application/x-ndjson; charset=utf-8. Each frame is a single JSON object followed by a newline:
- The handler writes a leading
startframe, then subscribes to the bridge and forwards every matching session frame. - The stream closes after a
doneorerrorframe. - The response headers disable caching (
Cache-Control: no-cache, no-store) and setX-Accel-Buffering: no.
handleChatEventsGet (web/server/src/handlers/chat-events.ts) returns a text/event-stream response for out-of-turn pushes for a session. The client passes the session in ?sessionId= and an optional Last-Event-ID header (or ?lastEventId=) to resume replay.
- On connect the server writes a synthetic
{ type: "connected", sessionId }frame. - Events carry an
idequal to the ring-buffer sequence number; the frame isevent: messagewith theChatStreamEventasdata. - Ring-buffer replay: with a nonzero
Last-Event-ID,RingBuffer.replaySincereturns every retained frame with a higher sequence. If the client is behind the oldest retained frame, the buffer reports overflow and the server emits astateframe withname: "agent_settled"andmessage: "resync-required", telling the UI to fall back toGET /api/chat/session. - For first-time clients (
Last-Event-IDabsent), only still-pending tool-question frames are replayed (web/server/src/sse-replay.ts). - A heartbeat comment is sent every 15 s to keep the connection alive.
- Headers:
Content-Type: text/event-stream; charset=utf-8,Cache-Control: no-cache, no-store,Connection: keep-alive,X-Accel-Buffering: no.
The turn stream (POST /api/chat) remains authoritative during an active turn; the SSE handler skips frames while the session is streaming/submitted. Out-of-turn pushes such as tool-Question requests, state frames for notify/setStatus, and agent messages are applied through the same reducer.
All request bodies pass through zod schemas in web/protocol/src/chat-protocol.zod.ts before handlers act on them. Schemas are organized per-domain under web/protocol/src/schemas/ (chat, catalog, settings, shared, misc) and registered with zod-to-openapi for documentation. userId/userEmail are server-set only; they are stripped from client input after validation.
- API index, the three wire surfaces
- Handlers and PrimeBridge, the HTTP adapter
- Route layer, the TanStack Start route wrappers
- Streaming chat, NDJSON + SSE flows
- System overview
- Security, trust model, local-only binding, validation