Deuz SDK 2.4 출시 — 버전 관리 메모리와 컨텍스트 컴파일러, 목표 감독자와 영속 스케줄러, 로컬 Docker 러너, 영속 채팅 스트림. 2.4의 새로운 점
Deuz SDK

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.4.0

Released 2026-10-16.

What an agent remembers, what it sees on each call, and work that outlives one process. Versioned memory, a context compiler with working memory, transcript search, V3 native runs, a goal supervisor with a durable scheduler and webhooks, a local Docker runner, conditional chats, durable streams and React chat snapshots; nine new subpaths. Every 2.4 feature is off until you configure it, and with none configured, provider requests are byte-identical to 2.3.0's. Upgrade notes, behaviour changes and known limits are on What is new in 2.4. Nothing in this release was run against a model provider: model calls are tested against scripted models, and the new stores and the Docker runner against real SQLite, PostgreSQL, Redis and Docker where the test environment provides them.

  • Versioned memory (/memory/versioned, /sqlite, /postgres) — records with a stable id, revisions, sources and an asserted or inferred origin, operations with receipts and idempotent replay, revise, retract, forget and a resumable re-embed. → Versioned memory
  • Context compiler and working memory (/context) — memory, RAG, past chats and the skill catalog in one token budget, placed append-only, with a manifest of what each step saw, and structured working memory. → Context compiler
  • Transcript search — scope-checked lexical search over conditional chat stores. → Transcript search
  • V3 native runs (checkpointVersion: 3) — checkpoints that carry the context packages, the working memory and durable memory intents, with V3 run stores in memory, SQLite and PostgreSQL. → Native agents
  • Goal runtime (/goal/runtime, /sqlite, /postgres) — a goal supervisor over the native executor, a durable time-zone aware scheduler, a webhook handler that queues into a goal's inbox, and acceptance on evidence with verifyGoalAcceptance and digestWorkspace. → Goal runtime
  • Docker runner (/compute/docker, preview, Node-only) — a sandbox for the compute tools and a process runner that reconnects after a host restart. → Docker runner
  • Chat and stream continuity — compare-and-set chat stores with tombstones, durable persist-before-publish streams (preview, Redis included), the capability handshake, and ChatSnapshotV1 in @deuz-sdk/react. → Chat and stream durability
  • Accounting and retention — embed, RAG, memory and verifier calls on the budget ledger, unaccounted calls refused under unknownPrice: 'reject', and an explicit cleanup call for every new store. → Budgets · Retention and forget
  • Skill proposals (/skills/learning, experimental) — a sourced SKILL.md draft from one verified run. → Skills
  • Examples — three new examples: versioned memory and context in a V3 run (21), a goal supervisor on one SQLite file (22), both keyless, and the Docker runner (23), which needs a local Docker engine.

Fixed: a legacy StreamStateStore that cannot report its last seq, or fails an append, no longer journals over stored frames or loses frames silently; the response warns with stream-store-error. createNodeSandbox confines runShell's cwd to the sandbox root, says when output was truncated, and kills the whole process tree on a timeout or abort. An interrupted native memory extraction completes only when every planned mutation is confirmed. memory_update drops a stale vector, a legacy vector query no longer ranks records of another embedding model or size, and uiFromMessages keeps stored message ids. createOtelObserver keeps a run's span when built-in memory runs inside it, and the SQLite ops store reports the error that failed a transaction.

CallWarning['type'], BudgetLedgerErrorCode, GoalErrorCode, ObservedSubsystem and DeuzUIPart are widened. @deuz-sdk/core/react is deprecated and will be removed in 3.0. The new tables have their own version tables, so a 2.3 process still opens the same databases; it refuses V3 run records.

2.3.0

Released 2026-10-13.

One path for every tool call, the 2.2 deferrals delivered, and a headless preview. Native runs gain memory, a chat projection and model fail-over; usage is billed once; a model without a price runs under a USD budget with a warning; requests follow each model's documented rules; nine new subpaths. Call sites from 2.2 keep working, but some defaults change, and native runs that record the new state need 2.3 to resume. Upgrade notes, behaviour changes and known limits are on What is new in 2.3. Nothing in this release was run against a provider or a third-party service; provider behaviour is verified offline and labelled not live-verified.

  • One path for every tool call — the finish-reason gate, policy, approval, admission, effect receipt, execution, onToolResult and checkpoint, in that order, for local and MCP tools, handoff transfers, blackboard tools, spawned tasks and sub-agents. Refused or cut-off turns dispatch nothing; stopDetails and ToolCallOutcome name how a turn and a call ended; approvals are bound to their call; native runs take MCP tools behind receipts, a native lease that another process can signal to cancel or drain the run, AgentRunStore.list, findStaleAgentRuns, and the opt-in reconciledToolResults and retryFailed resume options. A resume answers a call whose receipt records its outcome from that receipt, without gating it for approval again, saves what its settle answered before its first model call, and keeps the client results it was given across a crash. → Native agents
  • Native memory, chat and fail-over — memory, chat and fallbackModels in runAgent and streamAgent, bound to the checkpoint and the resume binding (envelope version 2), and reconcileAgentRun for what a run left behind. → Native agents
  • Usage, prices and budgets — every token billed once (outputTokens includes reasoning), explicit price lookup with PRICE_ALIASES, Claude 5.5 prices, unpriced models under USD budgets with an unpriced-model warning (unknownPrice: 'reject' is the strict mode), reservations at the output cap the request sends, BudgetStore holds / sweep / prune, and a batch price tier. → Budgets
  • Models and requests — resolveModelProfile, Claude 5.x rows and request rules, research-dated rows for new models, a warning for every value a request changes, OpenAI Responses store: false by default, and structured output that keeps the conversation's tools. → Model profiles
  • Preserved thinking — a byte-stable prefix for Claude 5.x in the agentic loops, block_binding drop as the safety net, one reasoning part per block, and reasoning kept within its provider family. → Preserved thinking
  • MCP 2026-07-28 and an MCP server (/mcp, /mcp/server, /mcp/server/stdio) — a dual-stack client over the v1 and v2 SDKs, and createMcpServer publishing tools, native agent tools and agents over Streamable HTTP and stdio. → MCP server
  • A2A (/a2a) — an edge-safe, dependency-free A2A 1.0.0 client and handler over JSON-RPC and HTTP+JSON, and createA2AAgentExecutor, which serves a native agent run as the handler's executor: answers are checked against the run before anything is written (a signed approval echoes its token), a drained run goes on at the next message, a failed task names only the error's code or name, and a run with output guardrails streams no drafts unless drafts: true. → A2A
  • Realtime voice (/realtime) — OpenAI Realtime and Gemini Live over WebSocket, with Deuz tools, ephemeral browser tokens and per-modality usage. → Realtime voice
  • Batch requests (/batch) — the OpenAI, Anthropic and Gemini batch APIs, priced on the batch tier, with budget holds settled per result and jobs a new process can resume. → Batch requests
  • Redis backends (/ops/redis, /swarm/redis) — leases, native runs, claims, budgets and swarms in atomic Lua scripts, and runs in the Redis store pack. → Operations
  • Goals (/goal) — versioned goal records moved by pure transitions, acceptance on evidence, explicit waiting reasons, and wakeup and event envelopes. → Goals
  • Native agents in a UI — toDeuzAgentStreamResponse and agentStateFromParts on /ui, and useChat (@deuz-sdk/react) driving native agent routes, with verdicts matched to the open gate and replay-safe client tools. → UI streaming
  • Evals (runEvalSuite on /testing) — versioned tasks with per-attempt metrics for success, false completion, cost, rescues, repeated effects and recovery. The baseline runs 22 offline tasks and 33 fault-injection scenarios (22 recovered, 11 contained) on every npm test. → Evals
  • Headless preview (/headless, Node-only) — runHeadless, resumeHeadless, inspectRun, doctor, project instructions and documented exit codes; no binary. A report names both answers to an unknown effect, marks a failure in transit as retryable (retry) and reports a drained run as pending (exit 3), and resumeHeadless takes reconciledToolResults and retryFailed. → Headless
  • Examples — seven new keyless examples (14–20): native memory, chat and fail-over, the native UI bridge, goals and wakeups, realtime and batch on scripted wires, an MCP server, and a native agent served over A2A. → Examples

Fixed: createNodeSandbox no longer takes the host process down when a child stops reading its stdin, and createFileWorkspace accepts names such as ..notes and no longer writes through a dangling link. Handoff transfers work in native runs. MCP listTools() reads every page. A swarm executor whose start-up commit fails releases its lease and heartbeat. The Postgres stores retry serialization failures and deadlocks. streamObject's warnings no longer hangs on a failed call, and agentTool child sessions no longer collide when a provider reuses a call id. Every Gemini finish reason is mapped on purpose (a Gemini filter no longer ends a turn with stop; the stops without a usable answer still end it with stop, and the finish part keeps Gemini's own value as providerMetadata.google.finishReason), an OpenAI Responses turn that its content filter cut off ends with content_filter, and an OpenAI refusal is kept as stopDetails instead of being dropped.

A native run that 2.3 saved with mcp, handoffs, memory, chat or fallbackModels needs 2.3 to resume: its resume binding records them, and memory, a chat projection or fail-over state also make the envelope version 2. So does a run that waits on an approval (2.2 looks a verdict up by the bare tool call ID, so it would answer the approved call as denied), and a run stopped with an open call 2.2 would answer wrongly (a failed or suspended receipt, a client call a resume took up and still waits on, a call the approval gate issued a request for), until a checkpoint answers the call: such an envelope is version 2 as well. OpenAI Responses requests send store: false, and validateChatRequest accepts the tool results useChat posts. CallWarning['type'], BudgetLedgerErrorCode, AgentToolReceipt['stage'] and AgentRunEnvelope.version are widened.

2.2.0

Dynamic swarms, durable operations and evolve. Swarms grow at runtime, share notes and move between processes; budgets outlive a run; seven new subpaths. Call sites from 2.1 keep working, but the SQLite swarm file and version 2 runs and ledger snapshots move forward only. Upgrade notes, widened unions and operational limits are on What is new in 2.2.

  • Scale — BudgetLedger.compact folds finished scopes into ancestor aggregates (ledger snapshot version 2), native runs under a shared child context checkpoint only their ledger slice, event readers poll the optional SwarmStore.head(), and timeout.chunkMs fails a stalled stream with TimeoutError layer 'chunk'. Native tools can declare replay: 'idempotent' and read ctx.modelStep.
  • Dynamic swarms — dynamic limits, context.spawn in reducers and spawn(output) on agent bindings, committed atomically with the parent's terminal state; onFailure compensation tasks and per-task timeoutMs. Dynamic runs are version 2 and need a store with 'spawn'. → Swarm
  • Blackboards, soft dependencies and rounds — task groups with idempotent blackboard_post / blackboard_read tools over durable channels, context.readChannel, after with context.settled, and createRounds for group-parallel rounds with a consolidator.
  • Durability operations (/ops, /ops/sqlite, /ops/postgres, /swarm/postgres) — swarm leases with SwarmLeaseError 'held' / 'lost', handle.drain(), a paging swarm.recover() that returns { handles, failed }, a swarm.requestCancel(key) whose cancel survives a change of executor, expectedRevision / expectedStatus on resume, a revision-gated Postgres swarm store, revision-fenced native agent run stores, and durable schedule claims in the SQLite and Postgres ops stores. → Operations
  • Persistent budgets — admission: { store, scopes, warnAtPercent, onWarning } admits every model call all-or-nothing against shared scopes such as user:42, with rolling windows, for native runs and swarms alike. Memory, SQLite and Postgres budget stores. → Budgets
  • Evolve (/evolve, /evolve/sqlite) — evolutionary program search over evolve blocks with diffs, rewrites and crossovers, an evaluation cascade, islands, a MAP-Elites archive, a UCB1 model bandit, a mandatory budget, zero-call resume and leases. → Evolve
  • Schedules and signals (/schedule) — five-field UTC cron, createScheduler with tick / start, claim-based dedupe and catch-up, and WebCrypto GitHub, Slack and HMAC verifiers behind handleSignal. → Schedules and signals
  • Polish — createCohereReranker and createVoyageReranker, the onToolResult guardrail hook with maxToolResultLength, and MCP fingerprintTools / detectToolDrift.

Fixed: SQLite stores that open a file path load node:sqlite again (the 2.1 build stripped the prefix), and every SQLite store waits for another process's lock while opening and retries a failed open. The 2.0 Postgres store pack serializes its first migration with an advisory lock and retries a lost race.

Back up SQLite swarm files before the first 2.2 open: the in-place upgrade to schema 2 is one-way and 2.1 refuses the upgraded file. Custom BudgetLedger implementations and hand-built reducer contexts need the new required members.

2.1.0

Native agents and durable swarm DAGs. The new engine is opt-in; existing generation and createAgent APIs remain available. Full contracts, upgrade notes and operational limits are on What is new in 2.1.

  • Native agent runs (/agent) — runAgent, streamAgent and their resume functions return explicit completed/suspended/stopped/failed outcomes. Accepted structured output is runtime-validated, with bounded finalization and verified / rejected / inconclusive verification. Native tool context and output validation plus toModelOutput separate raw results from model history. → Native agents
  • Strict native persistence — versioned run envelopes, approval and client-result resume, persisted limits and bindings, and tool receipts that preserve completed effects and require reconciliation for uncertain dispatches. A failed required checkpoint stops execution.
  • Swarm scheduling (/swarm) — fixed DAG validation, bounded agent/reducer concurrency, independent-branch completion, cancellation, scoped approvals and client results, and an ordered cursor journal. Completed tasks are reused on recovery; interrupted work is not blindly replayed. → Swarm
  • Swarm stores — in-memory storage and Node-only /swarm/sqlite, with atomic task/result/event transactions and an independent SQLite schema version.
  • Execution policy and budgets — inherited model/tool restrictions, approval gates, depth/deadline constraints and a shared durable reservation ledger. Unknown amounts remain held across recovery; admission uses estimates rather than promising a hard ceiling on the provider's final bill.
  • Accounting and package boundaries — legacy loops price individual model invocations and retain historical cost on resume. Native request accounting, optional usage pricing and memory pipelines load through separate optional chunks; existing core/edge eager bundle limits are preserved.

The scheduler is single-executor. External effects still need idempotency or reconciliation, and cancellation is cooperative. Native events and stores are separate from the existing UI wire and legacy checkpoint contracts.

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 returning MemoryStore / ChatStore / SessionStore / RunStore on one connection. SQLite: FTS5 + vector hybrid over node:sqlite, zero dependencies. Postgres: pgvector HNSW with an embedding_json fallback and a one-statement upgrade. Redis: a structural client seam, no package dependency. Correction (2.3): the Redis pack had no RunStore until 2.3, where createRedisStores returns runs. → Persistent stores
  • Guardrails (/guardrails, guardrails call 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 graceful stoppedBy stop. → Guardrails
  • Handoffs (handoff()) — transfer the run to another agent: system prompt, tools and model change, history travels. Deterministic interception, maxHandoffs loop guard, handoff stream part, durable resume. → Handoffs
  • Zero-config MCP (mcp call option) plus OAuth 2.0 (TokenStore, createOAuthProvider, /mcp/node file store + loopback listener), sampling, roots, ping()-verified reconnect, status(), keepAliveMs, and deps.mcpPool. → MCP
  • Compaction — public compactMessages(), a rolling summary that folds instead of stacking, automatic recovery from a provider context-overflow rejection (the anthropic, chat_completions and responses wires; not Gemini native), and countTokens for 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 optional findByHash / deleteExpired store fast paths. → Memory
  • Eight more providers — Perplexity, Cohere, DeepInfra, NVIDIA NIM, SambaNova, Hyperbolic, plus keyless Ollama and LM Studio; CompatSettings.capabilities and apiKeyOptional are public. → Local models
  • runtimeContext — an opaque per-call value threaded into tools, prepareStep, verifyStep, doneWhen and every guardrail hook. Never serialized, never checkpointed.
  • Breaking — NotImplementedError removed (never thrown). ObservedSubsystem gained speech / transcription / video. Compaction trigger gained manual / overflow and is always present on the stream part. generateObject / streamObject refuse mcp, guardrails, and doneWhen.

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, plus warning parts on fullStream), ToolStatePart.denied / deniedReason, and sub-agent frames folded into turn.subAgents.
  • Ergonomics — prompt / instructions, a four-layer timeout: { ttftMs, totalMs, stepMs, toolMs }, Tool.timeoutMs, the tool() identity helper, filePart() / imagePart() with PDFs on all four wires, consume(), per-call capabilities, and createOpenAICompatible({ id, baseURL }).
  • createAgent (/agent) — a reusable agent as a frozen value of closures, not a class.
  • OpenTelemetry bridge (/otel) — createOtelTracer() / createOtelObserver() over the existing deps.tracer / deps.observer seams.
  • Vertex ADC (/vertex/node) — createAdcKeyProvider(), the Node twin of the edge-safe service-account key provider.
  • Request validation (validateChatRequest on /chat and /edge) — gate an attacker-controlled POST body before it reaches the loop. It never repairs; every failure is a rejection with issues.
  • Two intentional behaviour changes — generateObject / streamObject now reject loop options instead of ignoring them, and a hallucinated tool name self-heals into an is_error result 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, and createWorkspaceTools. Persist plan.json, notes, and artifacts across compaction, checkpoints, and restarts.
  • Compute / CodeAct (/compute, /compute/node) — ComputeSandbox (runCode / runShell), codeActTool / shellTool, and a node:child_process reference sandbox. Thrown runs self-heal into is_error results. Swap the backend for Docker/E2B/Daytona without changing call sites.
  • Planner → Executor → Verifier (/autonomy, verifyStep) — planTasks + pure TaskList reducers; verifyStep on both loops (rejection re-drives with feedback, bounded by maxVerifyAttempts, records providerMetadata.deuz.verified, streaming emits a verify part); plus bestOfN, selfConsistency, and parallelAgents.
  • Background runs (/runtime, /runtime/node) — RunStore / createRunManager, pollStaleRuns, live plan-update / activity stream parts (UI wire + useChat), and createSteeringController for 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) and createProviderRegistry for 'groq:…'-style lookup with zero network.
  • Testing (/testing) — published createMockModel, runEval, and golden-replay fixtures for deterministic agent tests.
  • Azure / Bedrock / Kimi — @deuz-sdk/core/azure (createAzure), @deuz-sdk/core/bedrock (createBedrock Mantle Bearer; no SigV4), and createKimi alias 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.

이 페이지에서