Changelog
Release history of @deuz-sdk/core — what shipped in each version.
ドキュメント本文は英語です。ナビゲーション・検索・UI は選択した言語に従います。
All notable changes to @deuz-sdk/core. The package follows semver: minor versions are additive, the locked 1.0 type surface only changes in a major.
2.0.0
The things you used to build yourself. Eight new subpaths, three new modalities, real databases behind the four storage seams, guardrails and handoffs in the loop, and MCP that connects itself. The 1.9 call surface still compiles and every stored checkpoint still loads. Four loud breaks — NotImplementedError removed, two unions grew a member, compaction.trigger is always present, structured output now refuses mcp / guardrails / doneWhen — plus the two recovering behaviour changes, are on What is new in 2.0.
- Persistent stores (
/stores/sqlite,/stores/redis,/stores/postgres) — one factory per backend returningMemoryStore/ChatStore/SessionStore/RunStoreon one connection. SQLite: FTS5 + vector hybrid overnode:sqlite, zero dependencies. Postgres: pgvector HNSW with anembedding_jsonfallback and a one-statement upgrade. Redis: a structural client seam, no package dependency. → Persistent stores - Guardrails (
/guardrails,guardrailscall option) —onInput/onToolCall/onOutput, each pass / block / rewrite. A blocked tool call joins the existing denial machinery and does not count toward the runaway guard; a blocked input or output is a gracefulstoppedBystop. → Guardrails - Handoffs (
handoff()) — transfer the run to another agent: system prompt, tools and model change, history travels. Deterministic interception,maxHandoffsloop guard,handoffstream part, durable resume. → Handoffs - Zero-config MCP (
mcpcall option) plus OAuth 2.0 (TokenStore,createOAuthProvider,/mcp/nodefile store + loopback listener), sampling, roots,ping()-verified reconnect,status(),keepAliveMs, anddeps.mcpPool. → MCP - Compaction — public
compactMessages(), a rolling summary that folds instead of stacking, automatic recovery from a provider context-overflow rejection (theanthropic,chat_completionsandresponseswires; not Gemininative), andcountTokensfor a real tokenizer. → Compaction - Speech, transcription, video (
/speech,/transcription,/video) — OpenAI + ElevenLabs TTS, OpenAI + Deepgram STT, and async video jobs over the OpenAI Videos shape. - Memory —
recall.scorer/maxChars/expandLinks,writePolicy,sweep: 'on-extract', write-time hash dedup, per-fact importance and links, and the optionalfindByHash/deleteExpiredstore fast paths. → Memory - Eight more providers — Perplexity, Cohere, DeepInfra, NVIDIA NIM, SambaNova, Hyperbolic, plus keyless Ollama and LM Studio;
CompatSettings.capabilitiesandapiKeyOptionalare public. → Local models runtimeContext— an opaque per-call value threaded into tools,prepareStep,verifyStep,doneWhenand every guardrail hook. Never serialized, never checkpointed.- Breaking —
NotImplementedErrorremoved (never thrown).ObservedSubsystemgainedspeech/transcription/video. Compactiontriggergainedmanual/overflowand is always present on the stream part.generateObject/streamObjectrefusemcp,guardrails, anddoneWhen.
1.9.0
Parity, hardening, and no dead API. Three surfaces that shipped as types with no producer now actually produce; the rest is ergonomics and a chat UI layer. → What is new in 1.9
- Producers for declared surface —
warnings(CallWarning[]on every result, pluswarningparts onfullStream),ToolStatePart.denied/deniedReason, andsub-agentframes folded intoturn.subAgents. - Ergonomics —
prompt/instructions, a four-layertimeout: { ttftMs, totalMs, stepMs, toolMs },Tool.timeoutMs, thetool()identity helper,filePart()/imagePart()with PDFs on all four wires,consume(), per-callcapabilities, andcreateOpenAICompatible({ id, baseURL }). createAgent(/agent) — a reusable agent as a frozen value of closures, not a class.- OpenTelemetry bridge (
/otel) —createOtelTracer()/createOtelObserver()over the existingdeps.tracer/deps.observerseams. - Vertex ADC (
/vertex/node) —createAdcKeyProvider(), the Node twin of the edge-safe service-account key provider. - Request validation (
validateChatRequeston/chatand/edge) — gate an attacker-controlled POST body before it reaches the loop. It never repairs; every failure is a rejection withissues. - Two intentional behaviour changes —
generateObject/streamObjectnow reject loop options instead of ignoring them, and a hallucinated tool name self-heals into anis_errorresult instead of ending the run as a client hand-off.
1.8.0
Autonomous Agent Runtime. The primitives to build a Manus-style, fully autonomous system on the edge-safe core — every heavy capability is a seam with a Node-only reference adapter. See Autonomy and the Build your own Manus cookbook.
- Workspace (
@deuz-sdk/core/workspace,/workspace/node) — path-addressed externalized memory (Workspace), in-memory + sandboxed-directory backends, andcreateWorkspaceTools. Persistplan.json, notes, and artifacts across compaction, checkpoints, and restarts. - Compute / CodeAct (
/compute,/compute/node) —ComputeSandbox(runCode/runShell),codeActTool/shellTool, and anode:child_processreference sandbox. Thrown runs self-heal intois_errorresults. Swap the backend for Docker/E2B/Daytona without changing call sites. - Planner → Executor → Verifier (
/autonomy,verifyStep) —planTasks+ pureTaskListreducers;verifyStepon both loops (rejection re-drives with feedback, bounded bymaxVerifyAttempts, recordsproviderMetadata.deuz.verified, streaming emits averifypart); plusbestOfN,selfConsistency, andparallelAgents. - Background runs (
/runtime,/runtime/node) —RunStore/createRunManager,pollStaleRuns, liveplan-update/activitystream parts (UI wire +useChat), andcreateSteeringControllerfor mid-run user messages. - Browser control (
/browser,/browser/node) —BrowserController+createBrowserTools; Playwright reference adapter as an optional peer. - Providers + model router (
/providers) — published OpenAI-compatible factories (Groq, Mistral, DeepSeek, Together, OpenRouter, Cerebras, Fireworks, Moonshot/Kimi, Qwen, GLM, MiniMax) andcreateProviderRegistryfor'groq:…'-style lookup with zero network. - Testing (
/testing) — publishedcreateMockModel,runEval, and golden-replay fixtures for deterministic agent tests. - Azure / Bedrock / Kimi —
@deuz-sdk/core/azure(createAzure),@deuz-sdk/core/bedrock(createBedrockMantle Bearer; no SigV4), andcreateKimialias on/providers. Docs: Azure, Bedrock, compat hosts.
All additive: heavy code stays under */node subpaths; the canonical stream/UI wire gains open-union parts (v1 clients unaffected).
1.7.1
Memory isolation and settlement. Chat-scoped memory queries now match chatId exactly in both the in-memory and Markdown stores, and Markdown records preserve that field through frontmatter round-trips. A buffered run suspended for approval or a client tool now exposes result.memory and settles it to an empty mutation list instead of omitting the field.
Complete resume lifecycle. Settled approval and client-tool paths emit the same v2 tool-state transitions as the initial execution path, including explicit complete and error terminals. Negotiated v1 streams continue to omit v2-only state parts.
Conversation-safe persistence. ChatStore saves the caller's original conversation plus real assistant/tool additions rather than compaction summaries or prepareStep prompt rewrites. Durable resume uses a matching stored chat when available and avoids overwriting a record after a load failure or scope mismatch.
Complete buffered additions. result.response.messages now includes the final text-only assistant turn. Memory extraction consumes that same additions list exactly once. This patch adds no public exports, subpaths, or types.
1.7.0
Persistent, resumable chat. The new @deuz-sdk/core/chat and /chat/node surfaces provide a framework-neutral chat reducer, branching helpers, a scoped ChatStore seam, and a binary-safe JSONL implementation. Durable checkpoints now combine with the resumable v2 UI wire so a client can replay from Last-Event-ID, tail a live producer, or continue a dead run from its last completed boundary.
Built-in cross-session memory. Add memory: { seams, scope } to recall relevant memories before the first model step and run extract/reconcile/apply after completion. The pipeline is best-effort, non-blocking, scoped, and uses the existing in-library memory seams rather than a hosted service.
Richer agent UI and controls. Wire v2 adds monotonic event ids, StreamStateStore, typed data parts with optional validation, tool lifecycle state, RAG citations, live USD cost/cache-savings parts, and typed budget-exceeded events. fallbackModels and withFallback add pre-first-content cross-provider failover backed by the circuit breaker.
React package. @deuz-sdk/react is the thin React home for the core chat engine, with v2 useChat, useObject, reconnect/branching flows, signed approval handling, live cost and budget state, plus headless ToolApprovalCard and CostBadge components. The legacy @deuz-sdk/core/react subpath remains available but frozen.
1.6.1
Redaction final barrier (security fix). The built-in observation redaction profile now also runs after a custom redact hook and after structural truncation — a buggy or malicious redactor can no longer reintroduce a secret into an event, and truncation can never split a secret into a decodable prefix. The JWT pattern additionally catches tokens embedded mid-string.
Per-sink capture projection in composites (security fix). composeObservers children now each receive only what their own capture options allow: disallowed captured* fields are stripped, error.message is gated per child, and a child redact hook applies only to that child's view. Behavior change: a composed observer with no options no longer receives captured content from its siblings' opt-ins — it now matches a standalone observer's privacy defaults.
observation.settled. generateText / streamChat / embed / embedMany results expose an optional observation.settled promise — await it before observer.close() so async cost.calculated enrichments aren't dropped. Nothing about the run itself ever waits on it.
createMemoryObserver({ maxBytes }). A total byte budget alongside maxEvents, evicting by the existing overflow strategy and counting into droppedCount.
deps.tracerMode: 'legacy'. Opt back into the 1.5 flat span topology — one parent-less invoke per model call with deuz.step.count: 1 — for dashboards built against it. The default remains 'hierarchical'.
Notes. eventId is now derived as `${executionId}:${sequence}` (one fewer id draw per event; the format is not part of the contract). The release workflow supports npm trusted publishing (OIDC) alongside NPM_TOKEN and moved to actions/*@v5.
1.6.0
Observable Runtime — the versioned observation event protocol. Every run can emit ObserveEvents (schemaVersion: 1) through the new Dependencies.observer seam: run/model lifecycle with TTFT and per-retry reason + backoff, agent steps with per-step duration and cumulative usage, per-tool timings with real parallel completion order, approval requests and resolutions (server / client-response / default-deny), durable checkpoint saves/loads with resume correlation (one runId across legs, fresh executionId per leg, checkpoint.loaded before run.started { resumed: true }), per-layer compaction events with the summarize side-call visible as a tagged model call, sub-agent trees keyed by agentPath, and sync/async cost via the existing priceProvider. Local-first: no API key, no account, no data leaves the process. See Observability and the event catalog.
Built-in observers — @deuz-sdk/core/observe + /observe/node. createMemoryObserver (capped ring buffer), createCallbackObserver, composeObservers (a throwing child never blocks siblings), filterObserver, and the pure summarizeRun aggregator. Node-side, createJsonlObserver persists one valid JSON line per event through a bounded queue (a slow or failing disk can never affect the run) with binary-safe $deuzBytes round-trips via readJsonlEvents.
Privacy-first by default. Events carry only counts, ids, names, durations and enums; prompt/tool/reasoning/error content is opt-in per field and always passes a [REDACTED] redaction profile (API keys, Bearer/JWT/PEM patterns, secret-looking keys) plus structural limits — regression-tested against planted secrets in every channel. Deterministic per-run sampling (sampleRate) hashes the existing runId, so a run is all-in or all-out and test fixtures stay stable.
Tracer bridge — the span hierarchy, completed. An injected Dependencies.tracer now receives the documented invoke → step → execute_tool hierarchy driven by the same events (1.5 emitted only flat per-model-call invoke spans). Span names and attribute keys are unchanged; a user abort still ends the span without an exception. Agentic loops now produce one invoke with children instead of N flat invokes.
Behavior fix. A tool-call-first response now clears the TTFT timer (previously only text/reasoning deltas did — a tool-first stream could falsely trip the 60-second ttft timeout) and reports contentType: 'tool-call' in model.first-content.
Guarantees. Observers are isolated and never awaited — a throwing, slow, or closed observer cannot affect a run; with no observer the hot path pays a single boolean branch and draws no ids. streamChat stays synchronous and lazy (G2). Exactly one terminal event per execution leg.
1.5.1
Foundation hardening. CI now covers Node 22/24 and Windows/Linux, validates documentation, and re-runs the full release gate before a tag-driven provenance publish. Packed exports are loaded through ESM and CommonJS, browser/edge consumer bundles are compiled, public declarations/subpaths are locked, and raw/gzip bundle budgets catch regressions.
Protocol and provider contracts. The SSE parser covers all legal line endings, BOMs, arbitrary UTF-8 chunk boundaries, multiline data, EOF tails, and early cancellation. Anthropic, both OpenAI wires, and Google native run through one conformance suite for request, text, usage, finish, and typed-error semantics.
Standard errors. OpenAI-compatible errors retain their real provider id; exhausted transport failures become NetworkError; isDeuzError works across package copies/realms; DeuzError.toJSON() emits a stable, secret-safe diagnostic shape.
1.5.0
Durable sessions — session + SessionStore + AgentCheckpoint. Pass session: { store, runId? } on any agentic call and both loops checkpoint at every step boundary into a two-method storage seam — any backend, no vendor runtime. Checkpoints carry the full immutable history, cumulative cross-leg usage, and a running/suspended/completed status; the result carries runId (synchronously on streaming). A throwing store logs and never kills the run. serializeCheckpoint/deserializeCheckpoint round-trip binary parts safely for persistent stores. New subpath @deuz-sdk/core/durable, everything re-exported from /edge. See Durable runtime.
resumeFromCheckpoint / resumeStreamFromCheckpoint. Continue a crashed or suspended run: the stored history becomes the messages, settle-on-resume answers pending approvals from approvalResponses, and step indices + usage continue across legs (identically in both loops, including prepareStep's ctx.stepIndex). Resuming without a verdict denies pending gated calls by default (safe side). A mid-step crash re-runs that step — the honest recovery unit is one step. Unknown runId rejects with CheckpointNotFoundError (buffered) or surfaces as an error part (streaming, sync-return contract preserved).
Client-mode approval inside sub-agents. The 1.4 limitation is gone: with a durable session, a gated call inside an agentTool suspends the child into its own checkpoint and the parent suspends with agentPath-tagged pending approvals; resuming the parent routes verdicts back down the tree at any depth. Without session, the 1.4 is_error contract is unchanged. See Durable runtime.
HMAC-signed approvals — createApprovalSigner. WebCrypto HMAC-SHA256 tokens over the full approval request + optional runId binding + issuedAt; verify returns the payload or null (forged/tampered/expired/malformed — never a throw), with optional maxAgeMs expiry, a strict three-segment token shape, and an injectable clock; large tool inputs sign safely (loop-based base64) and an empty secret throws at construction. Closes the approvalResponses trust boundary documented in Client tools.
1.4.0
Loop hooks — prepareStep + activeTools. prepareStep(ctx) runs before every model step (after automatic compaction) and may return { messages, activeTools, toolChoice, model } — messages rewrites the base history for this and all following steps, the rest apply to that step only. A thrown prepareStep fails the call; it is never swallowed. Static activeTools restricts which tools are sent on every step; prepareStep's return overrides it. Works in both generateText and streamChat whenever tools is present. See Tool loop.
Budget stop conditions — totalTokensExceed / costExceeds. Stop the loop once cumulative real usage or cost (all steps and sub-agents included) crosses a bound. OR-ed into stopWhen like any condition, evaluated at step boundaries. A budget stop never changes finishReason — it sets providerMetadata.deuz.stoppedBy instead. costExceeds requires deps.priceProvider, otherwise it warns once and never fires.
Automatic layered compaction. Opt-in via compaction: 'auto' (or a CompactionPolicy), active inside the agentic loop. Three cheapest-first layers — prune old tool results, prune old reasoning, summarize the oldest unprotected slice — run before a step once estimated context fill crosses a threshold (default 92%). System messages, the first user message, the last message, and recent turns are always protected. Streaming emits a compaction part per layer that ran. See Compaction.
Sub-agents — agentTool. Wraps a { model, tools, system, maxSteps, maxDepth, ... } definition into a Tool that runs a nested agentic loop and returns its final text. When the parent streams, the sub-agent's canonical stream forwards live as agentPath-tagged sub-agent parts. The parent's approveToolCall is inherited at every depth; usage folds into the parent total; maxDepth (default 2) guards runaway nesting. See Sub-agents.
1.3.0
Tool approval flow. needsApproval is wired end to end. Server mode: approveToolCall(call, { messages }) decides inline; denials become an is_error result the model can react to. Client mode: gated calls break the loop — generateText returns pendingApprovals, streaming emits tool-approval-request parts — and the next call's approvalResponses settles them. New UI wire parts: tool-approval-request / tool-approval-response. See Client tools.
streamObject. Streaming structured output with partialObjectStream: AsyncIterable<DeepPartial<T>> plus a validated object promise. Same options as generateObject; synchronous return; zero-dep tolerant partial-JSON parser. No repair retry — usage/finishReason still resolve on validation failure. See streamObject.
React hooks. @deuz-sdk/core/react (React becomes an optional peer ^18 || ^19): useChat — streaming messages over the Deuz wire with automatic client-tool round-trips and tool-approval pauses — and useObject — streaming DeepPartial<T> from the new object-delta part. Plain hooks, no JSX, SSR-safe. See React hooks.
toDeuzObjectStreamResponse. Serialize a streamObject result over the Deuz v1 wire as object-delta parts; failures become redacted error parts.
MCP extensions. Peer @modelcontextprotocol/sdk floor raised to ^1.29.0. listResources / readResource / listPrompts / getPrompt on McpClient (auto-paginated). Tool results with structuredContent now return that object verbatim. Server outputSchema is carried on the new Tool.outputSchema field. onElicitationRequest handles form and url elicitation. See MCP.
1.2.0
providerOptions escape hatch. Per-provider raw request-body fields on every call — { openai: { service_tier: 'flex' } }, { anthropic: { fallbacks: [...] } }, { google: { cachedContent } }. Canonical fields always win; shallow, top-level only.
promptCaching: 'auto' | 'auto-1h'. One flag turns on Anthropic's automatic prompt caching (top-level cache_control). No-op on providers that cache implicitly.
Provider-executed web search on 3 wires. anthropicWebSearch(), openaiWebSearch() (Responses hosted tool), googleSearch() (grounding). Results and citations stream as canonical source parts; usage.serverToolUses counts billed invocations. See Provider-executed tools.
Responses stateless round-trips fixed. With tools + reasoning, the wire now sends include: ["reasoning.encrypted_content"] + store: false and replays encrypted reasoning items verbatim on later steps. ReasoningDeltaPart.encrypted marks opaque encrypted reasoning payloads on fullStream.
1.1.1
Anthropic effort wire fix. On Claude Opus 4.7+, Sonnet 5 and Fable 5, effort now rides output_config.effort — the previous thinking.budget_tokens path returns HTTP 400 on those models. Legacy models keep the budget mapping (plus new xhigh/max → 48k).
effort union widened. New 'xhigh' and 'max' levels. OpenAI clamps max → xhigh; Gemini clamps both to high (level wire) or a 32,768 budget (2.5 wire); the Responses wire sends 'none' verbatim.
samplingRestrictions on Anthropic rows. Opus 4.7/4.8, Sonnet 5 and Fable 5 reject non-default temperature/top_p — the adapter no longer sends them there.
Catalog refresh (2026-07). New registry rows: claude-fable-5, claude-sonnet-5, gpt-5.4-nano, gpt-5.3-codex, gemini-3.1-pro-preview (both wires), gemini-3.1-flash-lite, gemini-embedding-2. Pricing corrections for gpt-5.5, gpt-5.5-pro, grok-4.3, gemini-3.5-flash. Long-context pricing tiers via ModelPrice.over200k. Retired text-embedding-004 and gemini-3-pro-preview removed.
Usage extensions. Anthropic usage.reasoningTokens now populated from output_tokens_details.thinking_tokens; server-side fallback/compaction usage.iterations[] are summed. FinishStreamPart.providerMetadata surfaces Anthropic refusal stop_details.
0.1.0
Initial public release. Pure, web-first, multi-provider AI SDK (Anthropic, OpenAI, xAI Grok, Google Gemini, Vertex, Yunwu) with zero runtime dependencies and an ESM+CJS dual build. Ships a canonical streaming + tool-loop core, structured output, memory, RAG, skills, MCP, media generation, middleware, and a versioned Deuz UI wire.
0.0.0
Scaffolding: tooling (tsup dual ESM/CJS + dts, vitest, ESLint edge-safety, Prettier, changesets), publish hygiene (subpath exports, publint/attw gate, MIT license), and the locked 1.0 public surface. Methods threw NotImplementedError until the first release.