Skip to content

packages web protocol

Zachary BENSALEM edited this page Aug 15, 2026 · 1 revision

Web protocol

Active contributors: Zachary BENSALEM

Purpose

web/protocol (@prime-agent/web-protocol) is the wire contract package for the Qredence web chat. It is the single source of truth for the shape of every HTTP request and streamed event exchanged between the browser and web/server. The package exports plain TypeScript types (in web/protocol/src/chat-protocol.ts) and zod schemas (in web/protocol/src/chat-protocol.zod.ts and the web/protocol/src/schemas/ fragments) so the server and browser validate against the same contract without either importing the other.

The package is pure TypeScript with no React and no runtime. It is consumed by:

  • web/server (web/server/src/event-mapper.ts, the handlers) which produces ChatStreamEvent frames and validates inbound requests against the schemas;
  • web/app (web/app/src/lib/pi/chat-client.ts) which parses NDJSON responses and validates them through the same schemas;
  • web/design which renders messages and tool parts by dispatching on ChatMessagePart/ChatToolPart shapes.

The package also carries the OpenUI integration: web/protocol/src/openui-prompt.ts builds the system prompt for generative UI rendering from the @openuidev/lang-core component signatures in web/protocol/src/openui-signatures.ts.

Directory layout

web/protocol/
├── package.json              # @prime-agent/web-protocol, private, subpath exports
├── tsconfig.json
└── src/
    ├── index.ts              # re-exports chat-protocol, chat-types,
    │                         #   model-patterns, provider-catalog, openui-prompt
    ├── chat-protocol.ts      # all wire types (ChatStreamEvent, ChatRequest, ...)
    ├── chat-protocol.zod.ts  # re-exports every schema from ./schemas
    ├── chat-types.ts         # ChatMessage, ChatMessagePart, ChatToolPart, ChatStatus
    ├── provider-catalog.ts   # provider catalog, custom-provider id helpers, env scrub list
    ├── model-patterns.ts     # enabled-model glob matching helpers
    ├── openui-prompt.ts      # buildOpenUIPrompt (OpenUI Lang prompt builder)
    ├── openui-signatures.ts  # @generated OpenUI component signatures
    └── schemas/
        ├── z.ts              # patched zod instance (extendZodWithOpenApi)
        ├── shared.ts         # enums (mode, plan action, thinking level, transport),
        │                     #   nonEmptyStringSchema, etc.
        ├── chat.ts           # stream events, message/part schemas, session/request schemas
        ├── catalog.ts        # models, providers, resources, commands, workspace schemas
        ├── settings.ts       # ChatPiSettings schema + update/response
        └── misc.ts           # ErrorResponseSchema, HealthResponseSchema

Key abstractions

Type Full path One-line description
ChatStreamEvent web/protocol/src/chat-protocol.ts Discriminated union of every NDJSON frame: start, delta, tool, thinking, plan, state, queue, compaction, retry, done, error.
ChatRequest web/protocol/src/chat-protocol.ts Body of POST /api/chat: session metadata plus message, model, mode, planAction, and streamingBehavior.
ChatSessionMetadata web/protocol/src/chat-protocol.ts Identifies a session via sessionFile/sessionId/cwd; omitting all three starts a new one.
ChatModelSelection web/protocol/src/chat-protocol.ts Model selector as either a key string or { provider, id, thinkingLevel? }.
ChatPiSettings web/protocol/src/chat-protocol.ts Full editable Pi settings (compaction, models, retry, delivery modes, transport, resources).
ChatPiSettingsUpdate web/protocol/src/chat-protocol.ts Partial update shape; enabledModels and other arrays accept null to clear.
ChatQuestionAnswer web/protocol/src/chat-protocol.ts An answer to a pending dialog: single/multi/text/skip selection.
ChatPlanState web/protocol/src/chat-protocol.ts Structured plan snapshot: mode, executing, pending decision, completed/total, todos.
QueueState web/protocol/src/chat-protocol.ts Steering and follow-up queue lists (Array<string> each).
ChatMode web/protocol/src/chat-protocol.ts `"agent"
ChatTransport web/protocol/src/chat-protocol.ts `"auto"
ChatMessage web/protocol/src/chat-types.ts A transcript message: id, role, parts array, optional createdAt and web-only source: "local".
ChatToolPart web/protocol/src/chat-types.ts Open-ended tool part keyed by type (tool-IPython, tool-Edit, ...) with toolCallId/state/input/output.
ChatStreamEventSchema web/protocol/src/schemas/chat.ts Zod union of every stream-event schema, exported via chat-protocol.zod.ts.
PI_PROVIDER_CATALOG web/protocol/src/provider-catalog.ts User-facing Settings credential catalog (id, name, env var, auth type).
PI_LLM_RUNTIME_PROVIDER_IDS web/protocol/src/provider-catalog.ts Full Pi provider ids that can pick up org env/auth credentials.
buildOpenUIPrompt web/protocol/src/openui-prompt.ts Builds the OpenUI Lang system prompt for a given mode from the component signatures.
openUIPromptSpec web/protocol/src/openui-signatures.ts @generated OpenUI component signature table consumed by generatePrompt.
modelMatchesPattern web/protocol/src/model-patterns.ts Tests whether a model matches an enabled-model glob/exact pattern.

How it works

The contract has one rule: the browser and server never invent shapes. Types are the source for runtime behavior through the zod schemas, and every stream frame and request body maps to one of the exported types.

The stream event union is the heart of the contract. A turn begins with a start frame carrying runId, sessionId, and optional diagnostics; content arrives as delta (text), thinking, and tool frames; lifecycle signals come as plan, state, and queue; progress as compaction/retry; the turn closes with done (which carries the final ChatMessage) or error. chat-protocol.zod.ts re-exports per-domain schemas from web/protocol/src/schemas/, and the patched zod instance in web/protocol/src/schemas/z.ts registers the .openapi() extension (via @asteasolutions/zod-to-openapi) before any other fragment module is evaluated, so the schemas double as OpenAPI documentation.

web/protocol/src/provider-catalog.ts keeps the provider surface and the scrub policy in one place. PI_PROVIDER_CATALOG is the user-facing credential list; INFRA_PROVIDER_IDS marks config/sandbox entries that are not selectable LLMs; custom and OpenAI-compatible instances get prefixed ids (custom+<slug>, openai-chat-completions+<slug>); and PROVIDER_ENV_SCRUB_VAR_NAMES lists every env var scrubbed on Vercel. A provider-catalog integrity test fails if the scrub list diverges from packages/ai/src/env-api-keys.ts.

web/protocol/src/model-patterns.ts implements the enabled-model allowlist. Patterns may be exact ids or globs (*, ?), optionally suffixed with a thinking level (:high), and are matched case-insensitively against the model id, modelId, name, key, and provider/id forms. Compiled glob regexes are cached with a small cap.

OpenUI integration

buildOpenUIPrompt (web/protocol/src/openui-prompt.ts) calls generatePrompt from @openuidev/lang-core with openUIPromptSpec (the generated component signatures), a preamble telling the model it may emit openui-lang blocks, a set of base rules (Root first line, positional arguments, reactive $state, @-prefixed functions, Action([...]) compositions), and mode-specific rules (plan suppresses OpenUI actions). The signature table in web/protocol/src/openui-signatures.ts is @generated, so adding a component updates that file rather than hand-editing it.

graph LR
    R[web/server handlers<br/>event-mapper] -->|writes ChatStreamEvent| S[web/protocol<br/>types + schemas]
    S --> V[web/app chat-client<br/>zod validation]
    S --> D[web/design<br/>renderers dispatch on parts]
    P[provider-catalog.ts] --> C[provider/config surface]
    M[model-patterns.ts] --> E[enabled-model allowlist]
    O[openui-prompt.ts + signatures] --> UI[OpenUI Lang prompt]
Loading

Integration points

  • web/server consumes the types in event-mapper.ts (producing frames) and validates inbound requests against the schemas; see web-server.
  • web/app consumes the types and schemas in web/app/src/lib/pi/chat-client.ts and chat-fetch.ts; see web-app.
  • web/design renders ChatMessagePart/ChatToolPart by dispatching on part.type; see web-design and tool-cards.
  • The HTTP endpoints and their request/response shapes are documented in web-api.
  • Streaming flows over the wire: streaming-chat.
  • The repo-wide contract conventions are summarized in patterns-and-conventions.

Entry points for modification

  • Add a field to an existing type: edit the type in web/protocol/src/chat-protocol.ts and the matching schema in web/protocol/src/schemas/*; the schema must stay in sync because the client validates against it.
  • Add a new stream event variant: extend the ChatStreamEvent union, add a schema, and register it in the ChatStreamEventSchema union in web/protocol/src/schemas/chat.ts.
  • Change the provider surface or scrub policy: edit web/protocol/src/provider-catalog.ts and the matching env var map in packages/ai/src/env-api-keys.ts.
  • Change model allowlist semantics: edit web/protocol/src/model-patterns.ts.
  • Change the generative UI prompt: edit web/protocol/src/openui-prompt.ts rules/examples; regenerate signatures by updating the source that produces web/protocol/src/openui-signatures.ts.
  • Add a public symbol: export it from web/protocol/src/index.ts and add a subpath in web/protocol/package.json if it needs a dedicated entry.

Key source files

File Role
web/protocol/src/chat-protocol.ts All wire types: stream events, requests, responses, settings, plan state, models, providers, resources, workspace, commands.
web/protocol/src/chat-protocol.zod.ts Single re-export surface for every schema, grouped by domain.
web/protocol/src/chat-types.ts ChatMessage, ChatMessagePart, ChatToolPart, ChatStatus, and roles.
web/protocol/src/schemas/chat.ts Stream-event, message/part, session, request, and plan schemas; the ChatStreamEventSchema union.
web/protocol/src/schemas/catalog.ts Model, provider, resource, command, and workspace schemas.
web/protocol/src/schemas/settings.ts ChatPiSettingsSchema and update/response schemas.
web/protocol/src/schemas/z.ts Patched zod instance with the OpenAPI extension registered.
web/protocol/src/provider-catalog.ts Provider catalog, custom/OCC id helpers, and the env scrub list.
web/protocol/src/model-patterns.ts Glob/exact model matching for the enabled-model allowlist.
web/protocol/src/openui-prompt.ts buildOpenUIPrompt: OpenUI Lang prompt builder per mode.
web/protocol/src/openui-signatures.ts @generated OpenUI component signature table.

Clone this wiki locally