Shared packages
The runtime-neutral contracts that let the frontend and backend agree without depending on each other's internals.
The shared packages define the public thread-event and canonical-engine schemas. The backend event log and each live provider stay authoritative for persisted and native state; the packages are the contract layer on top.
The packages
| Package | What it owns |
|---|---|
@useagent/agent-client |
The browser-side client: reconnect to SSE, reduce events into thread state, and expose selectors to the UI, plus typed API helpers. |
@useagent/agent-harness |
Provider-neutral canonical event, capability, session, and ProviderDriver lifecycle types (the engine control contract), plus the protocol-boundary OpenCode frame parsers exported under ./opencode and ./t3-tool, the one place vendor names are permitted. |
@useagent/artifact-formats |
Native DOCX, XLSX, PPTX, and PDF renderers, plus bounded Office text extraction. |
@useagent/artifact-workspace |
Provider-neutral workpiece kinds, actions, and the native export capability matrix shared by backend and frontend. |
@useagent/conformance |
Deterministic, framework-free contract tests for the client and harness packages. It does not run live providers. |
Both apps consume the packages as plain file:../packages/... dependencies in
backend/package.json and frontend/package.json. There is no workspace or
turbo root: each app installs with bun on its own, and the package exports point
straight at TypeScript source, so both sides type-check the contract at build
time.
Why the contract lives in packages
One schema, two consumers
The frontend and backend both depend on the same event and capability types, so a change to the contract is a change both sides see at build time.
Engine neutrality
agent-harness is where “any engine renders through one UI” is actually
enforced. Adapters implement its ProviderDriver lifecycle.
The conformance suite
packages/conformance holds deterministic tests for the public contracts:
reducer behavior, replay, and capability gating. It runs without a live provider,
so it is fast and stable in CI. Live provider parity is a separate,
environment-gated proof covered under Verification.