Deuz SDK
A TypeScript runtime for agents that have to survive production
Docs · What's new in 2.0 · Coming from the Vercel AI SDK · Changelog
Calling a model is a solved problem. What is not solved is everything around it: remembering a user across sessions, staying inside a context window on turn forty, asking a human before the irreversible thing, resuming after the process dies mid-run, and connecting a tool server without hand-rolling OAuth.
Most SDKs leave those to you. @deuz-sdk/core ships them — one package, zero runtime dependencies, and nothing ambient: clock, randomness, fetch, keys and logging are all injected, so the same code runs on Node, Bun, Deno and the edge, and tests stay deterministic.
We are not claiming to build ASI. This is meant to be honest infrastructure on that road — a vehicle, not the destination.
import { streamChat } from '@deuz-sdk/core';
import { createAnthropic } from '@deuz-sdk/core/anthropic';
const anthropic = createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
// Returns synchronously and never throws. Failures arrive as typed stream parts.
const res = streamChat({
model: anthropic('claude-opus-4-8'),
instructions: 'You are terse.',
prompt: 'Hello!',
});
for await (const chunk of res.textStream) process.stdout.write(chunk);
const usage = await res.usage;
The two things nobody else ships
Every SDK gives you generateText. These are the ones you would otherwise build yourself, badly, twice.
Memory that outlives the session. Not a message array — a pipeline that extracts durable facts from a conversation, reconciles them against what it already knows (add / update / delete, never blind appends), scores them for importance, expires them, and pulls the relevant ones back on the next call. It runs on a vector store, a Postgres table, or an Obsidian vault.
await generateText({
model, messages,
memory: {
seams: { store, embedder, llm: model },
scope: { userId },
recall: { topK: 6, maxChars: 2000, expandLinks: 1 },
writePolicy: 'each-turn',
},
});
Compaction that keeps a long run alive. When the window fills, it prunes stale tool output, drops old reasoning, and folds the earliest turns into a single running summary — one block that gets updated, not a stack that grows. And when a provider rejects a request as too long anyway, the loop force-compacts and retries that step instead of failing the run.
await generateText({ model, messages, maxSteps: 30, compaction: 'auto' });
What else is in the box
| You need | It ships as |
|---|---|
| Tool loops that hold up | Parallel calls, self-healing errors, runaway guards, cost and token budgets, sub-agents |
| A human in the loop | needsApproval at any depth, HMAC-signed expiring tokens, a missing verdict denies |
| Runs that survive a crash | Step checkpoints in your database, resumeFromCheckpoint later — no workflow vendor |
| Rules the run must obey | Guardrails on input, each tool call and the final answer: pass / block / rewrite |
| Agents that hand off | handoff() moves the conversation — history, tools and model — to another agent |
| Tool servers, connected | MCP with OAuth 2.0, reconnect, sampling and roots; mcp: [{ url }] does the rest |
| Plan → act → verify | planTasks, CodeAct sandboxes, verifyStep, workspaces, browser control, background runs |
| State in your database | SQLite, Redis and Postgres packs behind the memory, chat, session and run seams |
| Many models, one call | 28 chat providers across four wires, plus embeddings, images, speech, transcription and video |
| A reusable agent | createAgent — a frozen value, not a class. No new, no second runtime |
| Traces without an account | Versioned events, a JSONL observer, a standalone HTML run report, an OpenTelemetry bridge |
| Resumable UI | A refresh, a network blip and a server crash all look the same to the client |
import { generateText, handoff } from '@deuz-sdk/core';
import { promptInjectionGuardrail, maxOutputLength } from '@deuz-sdk/core/guardrails';
import { createPostgresStores } from '@deuz-sdk/core/stores/postgres';
const stores = createPostgresStores({ connectionString: process.env.DATABASE_URL });
await generateText({
model: triage,
messages,
maxSteps: 8,
tools: { ...handoff({ billing, support }), search },
guardrails: { onInput: promptInjectionGuardrail(), onOutput: maxOutputLength(4000) },
mcp: [{ url: 'https://mcp.example.com/mcp' }], // connected, namespaced and closed for you
chat: { store: stores.chats, chatId, scope: { userId } },
session: { store: stores.sessions, runId }, // transcript and checkpoints, one connection
runtimeContext: { tenantId, db }, // travels with the call, not a per-request closure
});
Install
npm install @deuz-sdk/core # the runtime
npm install @deuz-sdk/react # optional: useChat, useObject, headless UI
Node ≥ 22, or any edge runtime with fetch. Optional peers only when you use them: zod (or any Standard Schema library), @modelcontextprotocol/sdk, react, pg / redis, unpdf / mammoth / xlsx, playwright, @opentelemetry/api.
Teach your coding agent
npx skills add Deuz-AI/Deuz-SDK
Two Agent Skills, for Claude Code and any other agent that reads the format.
deuz-sdk is a build guide over the whole surface — the mental model and its invariants, a task-to-file router, and thirteen reference files the agent loads only when the task needs them, covering every one of the 53 subpaths. migrate-from-ai-sdk is the verified name-by-name port from ai and @ai-sdk/*.
They are gated, not just written. Every @deuz-sdk symbol in them is resolved against the real export table on every commit, every code example is compiled against the built package, and a freshness check fails the moment the version or the locked API contract moves — so an agent reading them cannot confidently invent a function that does not exist. Written test-first: nine build tasks were given to agents without the skill first, which produced 19 imaginary imports across 8 of 9 answers.
How it is built
One design rule explains most of the code: normalize provider bytes to a canonical delta stream first. Retry, failover, resume, budgets, sub-agents and typed UI events then share one language, and no code path streams a provider's raw SSE to a caller.
The rest follows from it:
- Zero runtime dependencies. Ours to test, version and secure.
- No ambient state. One
Dependenciesseam for clock, randomness,fetch, logging and keys — lint bansDate.now()andMath.random()in core, which is also why tests are deterministic. - Your infrastructure. Checkpoints and journals live in your process and your database.
- Privacy by default. Content capture is opt-in and always redacted; API keys never reach a log, error or span.
- The gate is the contract.
npm run checkruns formatting, lint, types, 1,892 tests, a dual build,publint+ Are-the-Types-Wrong, an edge bundle with no Node leaks, byte budgets, and a locked list of 242 public exports across 54 subpaths. A removed export fails the release, not your build.
Most tests replay recorded provider bytes, which proves the SDK builds the request it means to but never that a provider accepts it. So a separate live suite calls the real endpoints. It has already earned its keep: it confirmed that Gemini answers a tool request with finishReason: STOP — the exact shape that makes a naive loop hang up holding a tool call instead of an answer — and that a thinking model can spend 112 reasoning tokens against 1 answer token, which an SDK that misreads the usage envelope would under-report by an order of magnitude.
What this is not
Need the largest ecosystem today? Use the Vercel AI SDK. Years of production hours, hundreds of contributors, integrations everywhere. That gap is real and it is not closing this year, and no feature list here changes it.
Our bet is smaller: a runtime you can hold in your head. Durability without a workflow vendor. Autonomy without an Agent god-class. Observability without an account. Nothing phones home.
So the limitations sit next to the features rather than in an issue tracker. Overflow recovery does not reach the Gemini native wire. generateObject cannot coerce a DeepSeek V4 model — it refuses both strategies, and the page says why. The Redis pack has no MULTI. Token counting is a calibrated heuristic unless you supply a tokenizer. rerank is still the identity reranker, MCP has no WebSocket transport, and the Part union has no AudioPart. Speech, transcription and video are covered by mocked tests but have not yet been run against a live endpoint. The full list.
The map
@deuz-sdk/core streamChat · generateText · generateObject · streamObject · embed
tool · filePart · imagePart · agentTool · handoff · compactMessages
createAgent · getModelCapabilities
providers /anthropic /openai /azure /bedrock /google /google/extras /xai /voyage
/vertex /vertex/node (service-account JWT on the edge; ADC on Node)
/providers (Mistral, DeepSeek, Qwen, Kimi, Groq, Perplexity, Cohere, DeepInfra,
NVIDIA, SambaNova, Hyperbolic, keyless Ollama / LM Studio,
createOpenAICompatible, createProviderRegistry)
agents /agent /guardrails /autonomy /runtime /runtime/node
memory & context /memory /memory/markdown /rag /rag/node /skills /skills/node
state & storage /stores/sqlite /stores/redis /stores/postgres /durable
chat & wire /chat /chat/node /ui
work & tools /workspace /workspace/node /compute /compute/node /browser /browser/node
connect & media /mcp /mcp/stdio /mcp/node
/image /midjourney /speech /transcription /video /yunwu
ops /observe /observe/node /otel /middleware /pricing /testing /edge
@deuz-sdk/react useChat · useObject · ToolApprovalCard · CostBadge
Docs & contributing
docs/ — start with autonomy, the durable runtime, or the unbreakable chatbot. Coming from the Vercel AI SDK? The verified mapping lists what has an equivalent — and what does not.
git clone https://github.com/Deuz-AI/Deuz-SDK.git && cd Deuz-SDK
npm install
npm run check
Built by Umutcan Edizaslan — X @UEdizaslan · GitHub @U-C4N
With help from Claude Opus 4.8 and Claude Opus 5.
MIT © 2026
No comments yet
Be the first to share your take.