JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 215
  • Score
    100M100P100Q93976F
  • License MIT

Reusable, standards-first agent-chat module — a thin wiring layer over the Vercel AI SDK and MCP for building app-scoped LLM copilots.

Package Exports

  • @coston/agent/mcp
  • @coston/agent/persistence
  • @coston/agent/react
  • @coston/agent/server

Readme

@coston/agent

npm Release

Reusable, standards-first agent-chat for app-scoped LLM copilots. A thin wiring layer over the Vercel AI SDK and MCP — not a framework. Each app keeps its own agent, scoped to its own API; this package removes the copy-paste.

Why

Apps that embed an LLM copilot keep re-growing the same chat plumbing: the streamText → toUIMessageStreamResponse → useChat route, provider resolution + API-key encryption, conversation persistence, the chat panel, and an MCP server. This package is that shared core; each app injects what's app-specific — tools, system prompt, auth, and persistence.

Subpath exports

Import What it gives you
@coston/agent/server createChatRoute, createProviderResolver/buildModel, secret crypto, the model registry, defineAgent
@coston/agent/react ChatPanel/ChatSession/MessageBubble, ProviderForm, createLocalTransport
@coston/agent/persistence PersistenceAdapter + createPrismaPersistence
@coston/agent/mcp createMcpRoute, createScopedHelper, mcpText

Server, persistence, and mcp are server-only; only react ships to the browser.

The model registry and provider-label helpers (MODELS_BY_PROVIDER, DEFAULT_MODEL, providerNeedsKey, providerDisplayName, shortModelName, …) are re-exported from both /server and /react for building settings UIs; the exported types are the reference.

Adopting in a new app? See USAGE.md — a complete, generic recipe (prerequisites, the required data model, and wiring all four subpaths).

Install

npm install @coston/agent

Requires Node >=20. Peer deps resolve from the consuming app, and most are optional — pulled only by the subpath that uses them. Always required: ai, @ai-sdk/anthropic, @ai-sdk/openai. Optional, by subpath: @ai-sdk/react, react, react-dom, @coston/ui (>=0.3.0 <0.5.0), lucide-react, streamdown for /react; mcp-handler, @modelcontextprotocol/sdk for /mcp; @ai-sdk/openai-compatible for the browser local transport. See USAGE.md §1 for the exact set.

Releases

Automated by semantic-release. On push to main, the GitHub Actions workflow type-checks, tests, builds, bumps the SemVer version from the Conventional-Commit history, publishes to npm, tags vX.Y.Z, and cuts a GitHub Release. Use fix: / feat: / feat!: commit prefixes to drive patch / minor / major bumps. (dist/ is a build artifact — rebuilt in CI and shipped in the npm tarball, not committed to git.)

The GitHub Releases page is the changelog — each release lists the changes generated from the commit history.

@coston/agent/server — chat route

// app/api/chat/route.ts
import { createChatRoute, createProviderResolver, decryptSecret } from '@coston/agent/server';

const { resolveUserModel } = createProviderResolver({
  loadSetting: userId => db.aiProviderSetting.findUnique({ where: { userId } }),
  decrypt: decryptSecret,
});

export const { POST } = createChatRoute({
  authorize: async (req, body) => {
    /* app owns ALL auth — return { userId, scope, context } or { error, status } */
  },
  resolveModel: resolveUserModel,
  buildTools: ({ context }) => buildAppTools(context), // standard AI SDK ToolSet
  buildSystemPrompt: ({ context, body }) => buildPrompt(context, body),
  persistence, // or: saveMessages: ({ conversationId, scope, messages }) => …
  conversationIdFrom: body => body.conversationId,
  maxSteps: 12,
});

The same ToolSet works for both actuation styles: tools with execute run server-side; tools without execute are surfaced to the browser via useChat's onToolCall. The package never names a tool.

Agent definition (defineAgent)

Define an agent from Markdown instructions, a tool set, and Skills — Markdown playbooks pulled on demand via an auto-injected load_skill tool (progressive disclosure):

import { defineAgent } from '@coston/agent/server';
import instructions from './agent/instructions.md'; // app loads the markdown

const agent = defineAgent({
  instructions, // Markdown
  tools: ctx => buildAppTools(ctx), // standard AI SDK ToolSet (or a plain ToolSet)
  skills: [{ name: 'example', description: 'When this applies', content: exampleMd }],
  approvals: ['delete_item'], // → AI SDK needsApproval; UI renders Approve/Deny
  context: ctx => snapshot(ctx),
});

// in createChatRoute:
buildTools: ({ context }) => agent.tools(context),
buildSystemPrompt: ({ context }) => agent.systemPrompt(context),

Skills add only name/description to the prompt; the body loads on demand.

Develop

npm install
npm run build      # tsdown → dist/ (ESM, externalized peers, stable d.ts names)
npm test           # vitest
npm run type-check
npm run lint

License

MIT