@plumbus/chat
v0.1.7
Published
Plumbus chat primitive — policy, context sources, guards, budgets, evals.
Readme
@plumbus/chat
Policy-first conversation runtime for Plumbus apps. Declare a chat, plug in context sources, set guards — get a fully-governed AI conversation with cited sources, budgets, refusals, and an event-streamed UI.
What is this?
Plumbus is an AI-native, contract-driven TypeScript application framework. You declare capabilities, entities, events, flows, prompts, and translations through define*() functions; the framework generates routes, validation, audit, security, and types.
@plumbus/chat adds a conversation primitive on top of that contract — one defineChat({...}) declaration becomes a complete chat surface with:
- Audience-scoped retrieval grounding (RAG, capability-backed lookups, translation-backed surfaces, static facts)
- Seven built-in policy guards (audience, locale, scope, privacy, provenance, action, behavioral)
- Per-turn / per-session / per-user / per-tenant budgets, with cost recording
- Action-confirmation flow with schema-hash re-validation
- A streamed
ChatEventprotocol consumed by<ChatPanel />in@plumbus/chat-ui
If you're not using Plumbus, this package won't make sense in isolation — defineChat composes on the framework's ExecutionContext, capability registry, prompt registry, and audit pipeline.
When to use this vs alternatives
| You want | Reach for |
|---|---|
| A single capability call with no conversational state | defineCapability in @plumbus/core |
| A long-running multi-step workflow | defineFlow in @plumbus/core |
| One-shot RAG-grounded answer with no chat surface | ctx.ai.retrieve + a normal capability |
| Multi-turn user conversation with scope, budgets, citations, and an event stream | @plumbus/chat (this package) |
| Just expose a capability to an AI agent | @plumbus/mcp |
| React UI for your defineChat chat | @plumbus/chat-ui |
Status
Peer-locked to @plumbus/core ^0.5.0 <0.6.0. The surface is implemented end-to-end: the defineChat declaration, policy DSL, context-source contract, streamed event protocol, mockChatRuntime testing helper, the deterministic evaluation harness (defineChatEvaluation / runChatEvaluation / TraceRecorder), and the runtime's domain events.
Install
pnpm add @plumbus/chatRequired peer: @plumbus/core ^0.5.0 <0.6.0. The framework provides Zod, Vitest, Playwright, and Drizzle transitively — do not add them to your own package.json.
For the React UI, also install @plumbus/chat-ui. For registry-backed knowledge sources, @plumbus/knowledge-base.
Quick start
import { defineChat, knowledgeContext, registerChatRoutes } from '@plumbus/chat';
import { onRoutesRegistered } from '@plumbus/core';
export const helpChat = defineChat({
name: 'help',
access: { roles: ['user'] },
context: [
knowledgeContext({
corpus: 'product-docs',
query: (turnCtx) => turnCtx.userMessage,
filter: (turnCtx) => ({ audience: turnCtx.audience, locale: turnCtx.locale }),
}),
],
policy: {
audience: { roles: ['user', 'admin'], mode: 'strict' },
reply: { locale: 'auto' },
scope: { description: 'Help with ProductX only.' },
behavioral: { cooldowns: [{ trigger: 'refusal', count: 3, durationSeconds: 30, scope: 'session' }] },
},
budget: { perSession: { userMessages: 35 }, perTurn: { tokens: 6000 } },
exposeAs: 'sse',
});
// Register the chat entities so migrations pick them up:
import { chatSessionEntity, chatTurnEntity, chatPendingActionEntity } from '@plumbus/chat';
export const entities = [/* your entities */, chatSessionEntity, chatTurnEntity, chatPendingActionEntity];
// Mount the HTTP route (POST /chat/help/turn — SSE by default):
onRoutesRegistered((app, routeConfig) => {
registerChatRoutes(app, routeConfig, [helpChat]);
});That's a fully-governed chat: roles enforced, retrieval cached and cited, off-scope messages refused, budget exhaustion guarded, refusal cooldowns tracked. Pair with <ChatPanel chatName="help" ... /> from @plumbus/chat-ui on the client.
What's included
| Surface | What it does |
|---|---|
| defineChat({...}) | The declarative entrypoint. Validated with Zod, deep-frozen. |
| runChatTurn(ctx, args) | Streaming runtime — yields ChatEvents. Composable in custom transports. |
| registerChatRoutes(app, routeConfig, chats, opts?) | Mount one SSE/JSON route per chat. Opts: authCookieNames, audienceTenantOverride, beforeTurn, afterTurn. |
| knowledgeContext, capabilityContext, staticContext, staticContextFromTranslations | Built-in context sources. |
| chatSessionEntity, chatTurnEntity, chatPendingActionEntity | Entities — register in the app entity list. |
| chatTurnPrompt, chatSummarizeHistoryPrompt, buildSystemPrompt, renderContext | Prompt building blocks. Override per-chat via definePrompt. |
| compilePolicy(policy) | Returns the ordered guard list — for advanced custom runtimes. |
| chatConfirmAction, chatListTurns, createChatTurnCapability | Auto-routed capabilities. |
| validateCitations, stripInvalidFromAnswer | Provenance helpers. |
| mockChatRuntime (from @plumbus/chat/testing) | Drop-in test harness — runs the full pipeline with a mocked AI. |
| defineChatEvaluation, runChatEvaluation, TraceRecorder | Deterministic eval harness — script a model, run scenarios, assert on the event stream and trace. See docs/chat/evaluations.md. |
Key gotchas
- Register the three chat entities. Without
chatSessionEntity,chatTurnEntity,chatPendingActionEntityin your app entity list, migrations won't create the underlying tables and the runtime will fail at first turn. exposeAsdefaults to'sse'— the SSE route is the only one mounted. SetexposeAs: 'capability'for server-to-server clients that can't consume an event stream, or'both'to mount both (rare).persistence.saveToDb: falserequiresmessageContent: 'client'. And it rejectspolicy.action.allowedCapabilities— ephemeral chats can't survive the action-confirmation round-trip.defineChatvalidates this at startup.policy.scope.classifier: 'inline'— the model classifies and answers in one call (Decision 0001). Refusal turns spend generation tokens; empirically cheaper than a preflight LLM call.useChat.confirm()in@plumbus/chat-uionly clears local state. The server-sidechatConfirmActioncapability does the real schema-hash re-validation; clients must call it directly. See chat-ui docs anddocs/chat/policies.md.
Documentation
- Concept docs (in the monorepo):
docs/chat/README.md— when to use, architecture, package layoutdefining-chats.md— fulldefineChatconfig +registerChatRoutesoptspolicies.md— the seven built-in guardscontext-sources.md— context-source contract + every built-intesting.md—mockChatRuntime+ helpersevaluations.md— eval scenarios withdefineChatEvaluation/runChatEvaluationdesign/— 10 design decisions explaining the framework's shape
- Agent recipes (ship in this package, readable from
node_modules/@plumbus/chat/instructions/):instructions/framework.md— file map, package conventions, critical rulesinstructions/defining-chats.md— recipe for adding a chatinstructions/policies.md— guard configuration recipesinstructions/context-sources.md— picker + per-helper recipesinstructions/testing.md— test patternsinstructions/extending.md— custom prompts, context sources, guards
The Plumbus ecosystem
| Package | Purpose | When to install |
|---|---|---|
| @plumbus/core | Foundation — capabilities, entities, events, flows, prompts, translations, runtime, CLI, audit, governance. | Always (required). |
| @plumbus/ui | Next.js/React UI — typed API clients, auth helpers, form metadata, scaffolds. | When building a Plumbus web UI. |
| @plumbus/api | Partner external API — manifest, OpenAPI, docs, compatibility diff, test intent. | Optional peer 0.1.x — when publishing a documented partner-facing HTTP API. |
| @plumbus/mcp | MCP runtime — serve capabilities to AI agents (tools/*, tasks/*, transports). | Optional peer 0.5.x — when exposing capabilities to MCP clients. |
| @plumbus/chat | You are here. Conversational runtime — defineChat, policy guards, context sources, streamed events. | Optional peer 0.1.x — when adding a chat surface. |
| @plumbus/chat-ui | React chat UI — hooks and <ChatPanel /> for the @plumbus/chat turn protocol. | Peer of @plumbus/chat — when adding a browser chat client. |
| @plumbus/knowledge-base | Knowledge providers — scoped sources, registry, chat knowledgeContext integration. | Optional peer of @plumbus/chat 0.1.x — when sharing named knowledge across features. |
| @plumbus/browser-extension | Extension scaffolder — WXT Chrome/Firefox project wired to your capabilities. | With @plumbus/ui (0.1.x) — when shipping a browser extension UI. |
Links
- Plumbus framework — github.com/plumbus-framework/plumbus
- Full documentation — docs/ in the monorepo
- Top-level README —
../../README.md - Issues — github.com/plumbus-framework/plumbus/issues
Testing
pnpm testFor consumer-app tests, import mockChatRuntime from @plumbus/chat/testing with createTestContext and mockAI from @plumbus/core/testing. See docs/chat/testing.md.
License
MIT
