sammy-sdk
v0.4.1
Published
Auto-configuring AI agent framework that learns your codebase and builds itself
Maintainers
Readme
sammy-sdk
Auto-configuring AI agent framework that learns your codebase and builds itself.
sammy-sdk is the official TypeScript SDK and CLI for Sammy. It scans your Next.js (or any TypeScript) project, builds typed agent tools from your real server actions and route handlers, and gives you a chat-style runtime that calls them safely.
Install
npm install sammy-sdksammy-sdk itself ships no transitive npm audit advisories. If you see audit warnings after this install, they refer to your project's existing dependencies (e.g. Next.js / Vite / vitest transitives), not to anything Sammy adds.
Get an API key from the Sammy dashboard, then add it to your project's .env.local:
- Sign up (free, no card required): https://sammy-web-pearl.vercel.app/signup
- Create a key at Dashboard → API Keys: https://sammy-web-pearl.vercel.app/dashboard/api-keys
- Paste it into
.env.local:
SAMMY_API_KEY=sk_sammy_...The dashboard currently lives on the Vercel deployment above. The custom domain
sammy.devhosts the marketing site only — it does not yet have signup/login. Once DNS is moved, this URL will redirect.
The SDK defaults to the public Sammy Cloud API at https://sammyapi-production.up.railway.app. To point at a self-hosted instance or a preview deployment, set:
SAMMY_API_URL=https://your-sammy-api.example.comCLI
The sammy binary ships with the package, so once sammy-sdk is installed you can run:
# 1. Scan your codebase and write sammy.config.json
npx sammy init
# 2. Generate typed tool wrappers around the things Sammy found
npx sammy generate
# 3. Scaffold Next.js wiring (API routes, server, chat page)
npx sammy scaffold next
# 4. Boot the local dev chat UI
npx sammy devsammy scaffold next
scaffold next writes the Next.js App Router wiring so you don't have to copy it by hand:
lib/sammy-server.ts— sharedSammyinstance +resolveUserFromSession(auth-provider aware: NextAuth, Clerk, or a compile-safe TODO stub)app/api/chat/route.ts,app/api/chat/conversations/route.ts,app/api/chat/conversations/[id]/route.tsapp/chat/page.tsxusingSammyChatApp
It also patches, never clobbers:
- adds
serverExternalPackages: ["sammy-sdk", "tsx"]to yournext.config(creates one if absent) - allowlists
/chatand/api/chatin an existingPUBLIC_PATHS-style middleware array - appends a
SAMMY_DEV_USER_ID=placeholder to.env.local
It detects your src/ layout and TS path alias (@/), never overwrites existing files, and prints copy-paste guidance whenever a file can't be edited safely. Preview everything with --dry-run:
npx sammy scaffold next --dry-runsammy generate is non-destructive — files you've edited under .sammy/ are preserved across runs. Pass --force to overwrite local edits and regenerate from scratch.
There's also npx sammy eval for running deterministic evals against your agent.
Programmatic usage
Sammy reads its API key from SAMMY_API_KEY (or .env.local) and its tool/agent topology from sammy.config.json. Models are configured per-agent in that file — there's no global tier to set in code.
import { Sammy } from "sammy-sdk";
const sammy = new Sammy();
const reply = await sammy.chat({
message: "Create a new deal for Acme Corp at $50k.",
user: { id: "user_123" },
});
console.log(reply.message);
console.log("tools used:", reply.toolsUsed.map((t) => t.name));SammyOptions covers systemPrompt, hooks, resolvePermissions, middleware, onError, and configPath for advanced use.
Next.js route handler
createSammyRouteHandler(sammy, options?) returns a Next.js App Router POST handler. It handles both one-shot JSON requests and SSE streaming (the sammy-sdk-client / sammy-sdk-react / sammy-sdk-ui packages send stream: true), validates the request body, returns clean error JSON, and supports a resolveUser callback for auth.
// app/api/chat/route.ts
import { Sammy, createSammyRouteHandler } from "sammy-sdk";
import { auth } from "@/lib/auth";
const sammy = new Sammy();
export const POST = createSammyRouteHandler(sammy, {
resolveUser: async () => {
const session = await auth();
if (!session) return undefined;
return {
id: session.user.id,
email: session.user.email ?? undefined,
roles: session.user.roles,
};
},
});If you don't need auth, the whole route is one line: export const POST = createSammyRouteHandler(sammy);.
Streaming (SSE) wire format
sammy.chatStream(request) (and createSammyRouteHandler when called with stream: true) emits SSE events using the shared StreamChunk shape — each frame is a JSON object { type, data }. data is an object (not a stringified JSON) so consumers can read it directly.
| type | data shape |
|---|---|
| text | string chunk to append to the assistant message |
| tool_call | { id, name, params } |
| tool_result | { id, name, result: { success, data?, error? } } |
| agent_handoff | { fromAgent, targetAgent, reason } (multi-agent only) |
| done | the full ChatResponse |
| error | { message } |
The sammy-sdk-client package consumes this format directly — see sammy-sdk-client, sammy-sdk-react, and sammy-sdk-ui.
Sub-paths
import { Sammy, loadRuntimeConfig } from "sammy-sdk/runtime";
import { SammyCloudClient } from "sammy-sdk/cloud";Environment variables
| Var | Purpose | Default |
|---|---|---|
| SAMMY_API_KEY | Your Sammy Cloud API key | (required) |
| SAMMY_API_URL | Override the Cloud API base URL | https://sammyapi-production.up.railway.app |
License
MIT
