-
#1557
447013dThanks @mattzcarey! - Add MCP SDK v2 client and server support.MCPClientConnectionnow uses the exact-pinned@modelcontextprotocol/client@2.0.0-beta.5. It probes for stateless MCP withserver/discover, then falls back to the legacyinitializehandshake on the same connection when needed. The SDK auto-fulfills stateless elicitationinput_requiredresults through the existing form and URL elicitation handlers whilecallTool,getPrompt, andreadResourceremain pending. OAuth reauthorization discards redirect-scoped discovery after token issuance and preserves discovery-triggered authentication, allowing a changed authorization server to be rediscovered and registered without reusing the prior issuer's credentials. Legacy pushed elicitation, Streamable HTTP, SSE, RPC, OAuth, and hibernation recovery remain supported. Codemode's MCP connector now uses an SDK-neutral structural boundary compatible with both MCP client generations.Add MCP SDK v2 support to
createMcpHandler. Pass a factory returningMcpServerorServerfrom the exact-pinned@modelcontextprotocol/server@2.0.0-beta.5peer dependency to serve stateless MCP with legacy compatibility by default. The newagents/mcp/serverentry exports the stateless Agents handler without retainingMcpAgent,WorkerTransport, MCP client transports, PartyServer, or SDK v1 modules. The returned handler remains callable for Worker dispatch and exposes the lower-level SDKfetch(request, options?)method plus typednotifymethods; upstreamcloseand event-bus internals are not part of the Agents surface. The retained v1 server APIs use the exact-pinned@modelcontextprotocol/sdk@1.29.0peer dependency.The legacy compatibility fallback now uses SDK v2's web-standard transport, including fail-fast handling for unsupported server-to-client requests, active-request teardown, and the same 25-second Cloudflare SSE keepalive previously supplied by
WorkerTransport. It returns405for session-only GET and DELETE requests without constructing an application server.createLegacyMcpHandlerremains an explicit public API for SDK v1 servers and complete WorkerTransport options.The MCP client storage codec now preserves stateless discovery data with resumed HTTP sessions and preserves the binding name and props required to restore RPC servers. Stored HTTP session IDs from older Agents versions have no associated protocol version. The upgraded client discards those IDs and reconnects instead of sending an unsafe resumed request, so in-flight work tied to an old remote session does not resume.
The v2 callable handler maps verified provider-issued metadata from compatible
@cloudflare/workers-oauth-providerreleases to standard MCPAuthInfowhile preservinggetMcpAuthContext().props.The Workers handler rejects malformed, opaque, and non-HTTP browser Origins. Its default allowlist includes localhost-class Origins, the endpoint's
workers.devhostname, and a concretecorsOptions.originhostname. It applies matching Host checks to localhost andworkers.devendpoints. Custom-domain deployments with wildcard CORS can setallowedHostnamesandallowedOriginHostnamesexplicitly, or setallowedOriginHostnames: "*"when trusted upstream middleware already enforces the required Origin policy. Requests without Origin remain valid for non-browser MCP clients. Default CORS preflights allow the statelessMcp-MethodandMcp-Namerequest headers.@cloudflare/codemodeis now an optional peer. Applications that importagents/skillsoragents/browserinstall Codemode explicitly; MCP-only applications no longer install it transitively.Deprecations in this release:
McpAgentis deprecated and feature-frozen as a stateful SDK v1 path. New servers should use an SDK v2 factory withcreateMcpHandlerfromagents/mcp/server.- Passing an SDK v1 server to the overloaded
createMcpHandleris deprecated for removal in the next major release. Move the server to an SDK v2 factory. UsecreateLegacyMcpHandleronly to temporarily retain sessionful SDK v1 behavior while migrating. - The explicit result-schema overloads
MCPClientManager.callTool(params, resultSchema, options)andwithX402Client(...).callTool(confirm, params, resultSchema, options)are deprecated. UsecallTool(params, options)orcallTool(confirm, params, options)instead.
experimental_createMcpHandlerwas already deprecated and remains scheduled for removal in the next major release. Its warning now directs users to an SDK v2 factory first and namescreateLegacyMcpHandleronly as a temporary bridge for sessionful SDK v1 behavior.
-
#1922
cb4c1c7Thanks @cjol! - Support both AI SDK v6 and v7.The
aipeer range isai@^6 || ^7(and@ai-sdk/reactis@^3 || ^4) acrossagents,@cloudflare/ai-chat,@cloudflare/codemode, and@cloudflare/think. Consumers can adopt AI SDK v7 or stay on v6 — no forced AI SDK upgrade when bumping these packages.Only the current implementations are covered. New optimisations and APIs made available by AI SDK v7 (broader result-shape audits, stream helper migrations, etc.) are intentionally out of scope.
How dual-version support works —
@cloudflare/thinkcalls the AI SDK through the option names present in both majors (v7 keeps the v6 names as aliases), and normalizes the genuine divergences at the boundary:- Uses
stepCountIs,system,experimental_telemetry,onStepFinish, andexperimental_onToolCallFinish(in v7 this alias resolves toonToolExecutionEndand fires once). - The tool-execution-finished event is normalized across majors: v6's
{ success, output, error, durationMs, stepNumber }and v7's{ toolOutput, toolExecutionMs }collapse to oneToolCallResultContext.stepNumberisundefinedunder v7 (the v7 event no longer provides it). - The UI message stream is built via the result's
toUIMessageStream()method (present in both majors); the standalonetoUIMessageStream({ stream })helper andresult.streamare v7-only. - The workspace read tool emits
{ type: "file-data", data, mediaType, filename }model output, accepted by both majors (v7's newer{ type: "file", data: { type: "data", data } }shape does not exist in v6).
Public API notes:
@cloudflare/thinkkeepssystem,onStepFinish, andexperimental_telemetrywhere callers already use them, and also acceptsTurnConfig.telemetry(forwarded ahead ofexperimental_telemetrywhen present).@cloudflare/ai-chatupdates theAIChatAgent.onChatMessagecallback type fromStreamTextOnFinishCallbacktoGenerateTextOnFinishCallback.
Verified against both
ai@6andai@7:@cloudflare/thinktype-checks with zero errors and its full workers test suite passes under each major.Known limitations:
workers-ai-provider(Think's default model provider) is fixed at v4 for AI SDK v7. Consumers onai@6who rely on Think's built-in default model may hit a provider-version mismatch; passing their ownLanguageModelavoids this.chat@4.31.0currently declares anai@^6peer and does not yet advertise v7 support; tracked separately.- CI should exercise both an
ai@6and anai@7resolution to guard the matrix.
- Uses
- #1969
80ad8deThanks @mattzcarey! - Add framework-neutralexecute,search, anddescribemethods to the durable Code Mode runtime handle so MCP servers and other non-AI-SDK hosts can invoke execution and discovery directly. Search and describe results now identify methods that require approval.
- #1904
88f7f69Thanks @mattzcarey! - Echo the durable tool-call log on the proxy tool output.ProxyToolOutputnow carries an optionalcallsfield (the execution'sToolLogEntry[]) on completed, paused and error outcomes, so UIs can render an audit trail of every connector call and step — name, args, result, approval requirement and state — without a separateexecutions()round trip.
-
#1807
7eea2fbThanks @mattzcarey! - Cleanup connector imports so connector modules are imported normally and the Vite plugin only auto-exports the CodemodeRuntime facet class. Codemode now fails loudly when the runtime facet class is not exported from the Worker entry. -
#1814
a79144dThanks @threepointone! - Dispose the dynamically-loaded Worker and its RPC entrypoint stub after eachDynamicWorkerExecutor.execute()run.Each execution spins up a child Worker via
loader.load()and obtains an RPCFetcherstub viagetEntrypoint(). These own native handles, and the code previously left them for the garbage collector. When such a handle is finalized late — for example during isolate shutdown under@cloudflare/vitest-pool-workers— workerd raises a fatal assertion ("tried to defer destruction during isolate shutdown") that kills the worker, surfacing as a flaky "Worker exited unexpectedly" with no failing assertion. The milder manifestation is workerd's "An RPC result was not disposed properly" warning.The executor now disposes the entrypoint stub and the loaded worker in
finallyblocks (best-effort, viaSymbol.dispose), releasing the handles while the isolate is still alive. No behavior or API change for callers. -
#1793
247ebebThanks @mattzcarey! - Pass the outer MCP tool-call context toopenApiMcpServerrequest callbacks so server-to-client requests and notifications can be associated with the originating response stream. -
#1791
9c85369Thanks @mattzcarey! - Remove the root entry's runtime dependency on the optionalaiandzodpeers. Executor and runtime imports now bundle without either framework package installed. -
#1772
d4f27feThanks @mattzcarey! - Include each package's documentation in its published package. -
#1806
43f663dThanks @mattzcarey! - Increase the default DynamicWorkerExecutor timeout from 30 seconds to 60 seconds to better support longer-running codemode executions.
- #1760
6769830Thanks @cjol! - Fix the runtime tool description to say "Execute JavaScript" instead of "Execute TypeScript". The codemode sandbox executes JavaScript only; TypeScript types are generated for LLM context but are not executed.
-
#1581
b2b6762Thanks @mattzcarey! - Add the connector model and a durable runtime for codemode.Connectors — class-based integrations that bridge external services into the sandbox. A connector is three things:
name(), optionalinstructions(), andtools()— one record, one entry per tool, with each tool carrying its own description, schema,requiresApproval,execute, and optionalrevert:CodemodeConnector— abstract base; authortools()directly (AI SDK toolsets are shape-compatible and can be returned as-is). Its constructor accepts aDurableObjectStateor anExecutionContext, so you passthis.ctxfrom inside an Agent/DO with no cast.McpConnector— derivestools()from an MCP connection (createConnection()); decorate derived tools via thetool(name, t)hook- Per-execution resources — a tool's
execute(args, ctx)/revert(args, result, ctx)now receive the run'sexecutionId(stable across pause/resume), and connectors can overridedisposeExecution(executionId, status)to tear down a resource scoped to one run (a browser/CDP session, a transaction). It fires on each terminal transition (completed/error/rejected/rolled_back) and never on pause, so a resource survives an approval pause and is released when the run truly ends. Must be idempotent (a completed-then-rolled-back run disposes twice). A stale/no-oprejectno longer triggers teardown, so a still-resumable run keeps its resources OpenApiConnector— derives one typed tool per operation from the spec (host-side, zero prompt tokens), so the model callsapi.get_repository({ owner, repo })directly;request()remains as a low-level escape hatch. Derivation resolves local$refs (includingallOf/oneOf/anyOf) and is memoized by spec identity, so a static spec is parsed once even though connectors are reconstructed per message; operations whose names collide (or hit the reservedrequest/spec) are skipped with a warning
Runtime —
CodemodeRuntime, a DurableObject facet that wraps anExecutorand makes execution durable via abort-and-replay:- Every tool call and
codemode.step(name, fn)is recorded in a durable log - Reads and steps execute and record their result
- Approval-required actions pause the run (abort)
- The facet is stateless across calls — execution id + a host-allocated sequence + the approval requirement are threaded into every call, so runs are safe across hibernation and can run concurrently without clobbering one another
- Once a run pauses or terminates, the facet refuses further progress: every subsequent call/step gets a pause decision and records nothing, so model code that catches the pause sentinel and keeps going can't drive extra side effects
- A decided-but-not-yet-recorded call is logged as
executing(notapplied), so a crash between deciding and recording the result re-executes on replay instead of replayingundefined - Replay divergence (a call's connector/method or its arguments differ from the recorded run, e.g. nondeterminism not wrapped in
codemode.step) is detected and recorded as a failed execution - Execution outcomes are returned, not thrown: the tool yields
{ status: "completed" | "paused" | "error" }so a sandbox error or divergence is an observable tool result rather than an exception that breaks the agent loop - Lifecycle calls target an explicit
executionId— there is no implicit "current run" (a single shared pointer would be racy with concurrent runs). Every tool outcome (completed/paused/error) carriesexecutionId, andpending()/executions()surface ids for approval UIs runtime.pending()lists actions awaiting approval, for approval UIs — with noexecutionIdit aggregates across all paused runs (not just the most recent);runtime.executions()lists all runs (the audit trail)runtime.approve({ executionId })replays the log and runs the approved action; it only resumes a paused run — approving a run that already completed, was rejected, or rolled back (a stale/racing approval UI) is a safe no-op that revives nothing (returning an error outcome) rather than re-offering a rejected action or re-applying rolled-back effects.runtime.reject({ seq, executionId })ends the execution with a first-classrejectedstatus (it does not auto-undo already-applied actions — callrollback()for that)runtime.rollback({ executionId })reverts all applied, reversible actions (any tool with arevert, not just approval-gated ones) in reverse order, marking only those actually reverted; it attempts every revert even if one fails (surfacing the failures afterward) and marks the executionrolled_back- Retention — terminal executions are auto-pruned to
maxExecutions(default 50) as new runs begin;runtime.deleteExecution(id)andruntime.pruneExecutions(keep)are explicit controls. Running/paused executions are never pruned. codemode.step(name, fn)is the explicit side-effect boundary — wrap any nondeterministic or side-effectful work so it runs once and replays thereafter- The runtime facet's identity is derived from the connector set — changing connectors yields a fresh runtime, so stored snippets and paused executions are always bound to the connectors that can run them
Snippets — durable, addressable saved scripts that replace the old static skills. The model writes and runs scripts; the developer promotes the good ones with
runtime.saveSnippet(name, { executionId?, description })and the model re-runs them withcodemode.run(name, input). Snippets live on the runtime, surface incodemode.search/describe, and are structurally bound to the connector set (no per-snippet dependency tracking).Runtime-facing tool —
createCodemodeRuntime({ ctx, executor, connectors }).tool()returns one{ code }tool. Inside the sandbox:codemode.search/describe/step/runplus<connector>.<method>(...)globals — a deliberately minimal surface: discover, learn, do-once, reuse.Result shaping —
createCodemodeRuntimeaccepts an optionaltransformResultthat reshapes the model-facing result of a completed run (initial run and resume), after the raw value is recorded — so the audit trail keeps the full result while the model sees the shaped one. ExportedtruncateResult/truncateResponse(with{ maxChars?, maxTokens? }) are the default building blocks: structured results pass through unchanged until oversized, then serialize to a bounded, marked string.ResolvedProvidergains an optionalprelude— sandbox-side JS that can define real in-sandbox functions on a namespace (used to implementcodemode.step, which wraps a local closure that can't cross the RPC boundary). New exported typesToolExecuteContextandExecutionEndStatusdescribe the per-execution resource contract.Vite plugin —
@cloudflare/codemode/vitediscovers*.codemode.tsfiles and auto-exports connector classes forctx.exportsaccess.Executor-style ranked search with normalized tokenization and scoring.
-
#1656
4c2d1a7Thanks @cjol! - Codemode runtime refinements (pre-release):- SQL storage. The
CodemodeRuntimefacet now stores executions, the tool-call log, and snippets in SQLite tables (one row per log entry) instead of single key-value blobs — appends no longer rewrite the whole execution, and pruning/expiry/listing are indexed. Args/results are serialized with a binary- and bigint-safe codec. - Size guards. Any single recorded value (call args, a recorded result, the final result) is capped at 1 MB serialized (
MAX_DURABLE_VALUE_BYTES). Oversized args or call results fail the run with a model-actionable error; an oversized final result completes normally with a placeholder in the audit trail. - Replay policy. Connector tools can declare
replay: "reexecute": the call is logged for sequencing/divergence but its result is never stored — replays re-execute it. For idempotent reads with large results. Incompatible withrequiresApproval. onPassEndhook. Connectors getonPassEnd(executionId, status)at the end of every execution pass — including pauses, wheredisposeExecutiondeliberately does not fire — to release per-pass resources (sockets, leases).- Explicit runtime identity. The runtime facet is keyed by an explicit
name(default"default") instead of a fingerprint of the connector set, so executions and snippets survive connector changes. Each execution/snippet records the connector names it needs; resume andcodemode.runverify them and fail with a clear error when one is missing. expirePaused.runtime.expirePaused({ maxAgeMs })(default 24h) expires stale non-terminal runs and firesdisposeExecution, reclaiming their resources — for use from a recurring alarm/scheduled task. Paused (awaiting-approval) runs are marked rejected; runs stuckrunningafter a host crash are marked errored (they could never be resumed or pruned otherwise).- Lifecycle hardening.
runtime.reject()returns whether it actually terminated the run (falsefor a stale/duplicate reject — e.g. the action was approved from another tab) so callers never report a run as rejected when its gated action actually executed.deleteExecutionon a non-terminal run also disposes its per-execution connector resources. Oversized execution code is rejected up front with a model-actionable error, and snippet schemas are size-checked on save.createCodemodeRuntimerejects duplicate connector names (they would silently shadow each other in the sandbox). - Reserved-name hardening. The executor rejects provider/connector names that would shadow harness globals (
Promise,setTimeout,Error,console, …). - Anti-hallucination tool description. The default execute tool description now states explicitly that the connector namespaces plus
codemodeare the only sandbox globals (nohost,fs,require,process), and tells the model to discover method names viacodemode.searchinstead of guessing.tool({ connectorHints })renders a one-line usage hint next to each connector in the description. A sandboxReferenceError(x is not defined) now gets the list of available globals appended, so the model's retry is informed.
- SQL storage. The
-
#1656
4c2d1a7Thanks @cjol! - AddToolSetConnector— adapt an AI SDKToolSetinto a codemode connector.toolSetConnector(ctx, { tools })(default nametools) turns existing AI SDK tools into connector tools for the durable runtime, converting their input schemas to JSON Schema for the sandbox type declarations. Tools withneedsApproval: trueare mapped torequiresApproval: trueon the connector tool — calling one pauses the execution durably for human approval instead of the tool being unavailable. Tools without anexecutefunction (client-side / provider-executed) are excluded from both the bindings and the generated types, with a one-time warning — the sandbox can't call them. The runtime tool's description now also instructs the model to stop and wait when an execution returnsstatus: "paused".
- #1555
2d45abdThanks @mattzcarey! - DefaultopenApiMcpServerto the MCP SDK's Workers-safe JSON schema validator so elicitation response validation does not rely on runtime code generation.
- #1547
f739ec9Thanks @mattzcarey! - Dispatch all codemode tool calls positionally and remove provider-levelpositionalArgsconfiguration.
-
#1521
2911baeThanks @mattzcarey! - Preserve binary values across codemode tool calls soUint8Arrayarguments and results survive the sandbox boundary. This fixesstate.writeFileBytes()from codemode with byte arrays and keepsreadFileBytes()results asUint8Arrayvalues. -
#1523
5f1376fThanks @mattzcarey! - Remove the echoed sourcecodefield from codemode tool results. Successful sandbox executions now return only the executionresultand any capturedlogs.
-
#1468
186a2a4Thanks @mattzcarey! - Add a browser-safe codemode export with an iframe sandbox executor and browser tool helper. Harden iframe message handling with nonce-scoped messages, reject sanitized tool name collisions, and keep tools withneedsApproval: false. -
#1470
1033fa2Thanks @mattzcarey! - Resolve OpenAPI specs inside the codemode sandbox to avoid Worker Loader RPC size limits for heavily-referenced specs. -
#1508
13acffeThanks @threepointone! - fix(codemode): harden OpenAPI sandbox ref handling
-
#1266
d5dbf45Thanks @threepointone! - Add optionaldescriptiontocodeMcpServer, matching the existing option oncreateCodeTool. Supports{{types}}and{{example}}placeholders; falls back to the built-in default when omitted. -
c5ca556Thanks @threepointone! - Fix@tanstack/aipeer dependency range from^0.8.0to>=0.8.0 <1.0.0. The caret range for pre-1.0 packages only allows>=0.8.0 <0.9.0, which excluded the current 0.10.0 release.
- #1248
c74b615Thanks @threepointone! - Update dependencies
- #1204
39d8d62Thanks @threepointone! - Unwrap MCP content wrappers incodeMcpServerso sandbox code sees plain values instead of raw{ content: [{ type: "text", text }] }objects. Error responses (isError) now throw proper exceptions catchable via try/catch, andstructuredContentis returned directly when present.
- #1181
e9bace9Thanks @threepointone! - FixcreateCodeTooldroppingpositionalArgsfrom providers, causing multi-argument tool calls (e.g.stateTools) to silently lose arguments after the first.
- #1138
36e2020Thanks @threepointone! - Drop Zod v3 from peer dependency range — now requireszod ^4.0.0. Replace dynamicimport("ai")withz.fromJSONSchema()from Zod 4 for MCP tool schema conversion, removing theairuntime dependency from the agents core. RemoveensureJsonSchema().
-
#1149
47ce125Thanks @threepointone! - feat: add TanStack AI integration (@cloudflare/codemode/tanstack-ai)New entry point for using codemode with TanStack AI's
chat()instead of the Vercel AI SDK'sstreamText().import { createCodeTool, tanstackTools } from "@cloudflare/codemode/tanstack-ai"; import { chat } from "@tanstack/ai"; const codeTool = createCodeTool({ tools: [tanstackTools(myServerTools)], executor }); const stream = chat({ adapter, tools: [codeTool], messages });
Exports:
createCodeTool— returns a TanStack AIServerTool(viatoolDefinition().server())tanstackTools— converts aTanStackTool[]into aToolProviderwith pre-generated typesgenerateTypes— generates TypeScript type definitions from TanStack AI toolsresolveProvider— re-exported framework-agnostic provider resolver
Internal cleanup: extracted
resolveProviderinto a framework-agnosticresolve.tsmodule so the main entry (@cloudflare/codemode) no longer pulls in theaipackage at runtime. Shared constants and helpers moved toshared.tsto avoid duplication between the AI SDK and TanStack AI entry points.
- #1122
a16e74dThanks @threepointone! - AddToolProviderinterface for composing tools from multiple sources into a single codemode sandbox.createCodeToolnow accepts aToolProvider[]alongside raw tool sets. Each provider contributes tools under a named namespace (e.g.state.*,mcp.*) with the default beingcodemode.*. Providers withpositionalArgs: trueuse natural function signatures (state.readFile("/path")) instead of single-object args. The oldexecutor.execute(code, fns)signature is deprecated but still works with a warning.
-
#1114
5d88b81Thanks @mattzcarey! - Add@cloudflare/codemode/mcpbarrel export with two functions:codeMcpServer({ server, executor })— wraps an MCP server with a singlecodetool where each upstream tool becomes a typedcodemode.*methodopenApiMcpServer({ spec, executor, request })— createssearch+executeMCP tools from an OpenAPI spec with host-side request proxying and automatic$refresolution
-
#1113
1264372Thanks @mattzcarey! - Add optionalmodulesoption toDynamicWorkerExecutorOptionsto allow injecting custom ES modules into the sandbox -
#1117
9837adcThanks @mattzcarey! - DynamicWorkerExecutor now normalizes code and sanitizes tool names internally. Users no longer need to callnormalizeCode()orsanitizeToolName()before passing code/fns toexecute().
-
#1102
f07ef51Thanks @mattzcarey! - BREAKING:generateTypesandToolDescriptor/ToolDescriptorstypes are no longer exported from the main entry point. Import them from@cloudflare/codemode/aiinstead:// Before import { generateTypes } from "@cloudflare/codemode"; // After import { generateTypes } from "@cloudflare/codemode/ai";
The main entry point (
@cloudflare/codemode) no longer requires theaiorzodpeer dependencies. It now exports:sanitizeToolName— sanitize tool names into valid JS identifiersnormalizeCode— normalize LLM-generated code into async arrow functionsgenerateTypesFromJsonSchema— generate TypeScript type definitions from plain JSON Schema (no AI SDK needed)jsonSchemaToType— convert a JSON Schema to a TypeScript type declaration stringDynamicWorkerExecutor,ToolDispatcher— sandboxed code executionJsonSchemaToolDescriptor/JsonSchemaToolDescriptors— types for the JSON Schema API
The
aiandzodpeer dependencies are now optional — only required when importing from@cloudflare/codemode/ai.
-
#1092
c2df742Thanks @mattzcarey! - ExportnormalizeCodeutility function for use by consumers that need to normalize user-provided code to async arrow function format before sandbox execution. -
#1074
33b92d5Thanks @mattzcarey! - Removezod-to-tsdependency to reduce bundle size. Zod schemas are now converted to TypeScript strings via JSON Schema using the existingjsonSchemaToTypeString()function and AI SDK'sasSchema().
- #1020
70ebb05Thanks @threepointone! - udpate dependencies
-
#962
ef46d68Thanks @tumberger! - Validate tool arguments against Zod schema before execution in codemode sandbox -
#973
969fbffThanks @threepointone! - Update dependencies -
#960
179b8cbThanks @mattzcarey! - Harden JSON Schema to TypeScript converter for production use- Add depth and circular reference guards to prevent stack overflows on recursive or deeply nested schemas
- Add
$refresolution for internal JSON Pointers (#/definitions/...,#/$defs/...,#) - Add tuple support (
prefixItemsfor JSON Schema 2020-12, arrayitemsfor draft-07) - Add OpenAPI 3.0
nullable: truesupport across all schema branches - Fix string escaping in enum/const values, property names (control chars, U+2028/U+2029), and JSDoc comments (
*/) - Add per-tool error isolation in
generateTypes()so one malformed schema cannot crash the pipeline - Guard missing
inputSchemaingetAITools()with a fallback to{ type: "object" } - Add per-tool error isolation in
getAITools()so one bad MCP tool does not break the entire tool set
-
#961
f6aa79fThanks @mattzcarey! - Updated default tool prompt to explicitly request JavaScript code from LLMs, preventing TypeScript syntax errors in the Dynamic Worker executor.
-
#879
90e54daThanks @mattzcarey! - Remove experimental_codemode() and CodeModeProxy. Replace with createCodeTool() from @cloudflare/codemode/ai which returns a standard AI SDK Tool. The package no longer owns an LLM call or model choice. Users call streamText/generateText with their own model and pass the codemode tool.The AI-dependent export (createCodeTool) is now at @cloudflare/codemode/ai. The root export (@cloudflare/codemode) contains the executor, type generation, and utilities which do not require the ai peer dependency.
ToolDispatcher (extends RpcTarget) replaces CodeModeProxy (extends WorkerEntrypoint) for dispatching tool calls from the sandbox back to the host. It is passed as a parameter to the dynamic worker's evaluate() method instead of being injected as an env binding, removing the need for CodeModeProxy and globalOutbound service bindings. Only a WorkerLoader binding is required now. globalOutbound on DynamicWorkerExecutor defaults to null which blocks fetch/connect at the runtime level. New Executor interface (execute(code, fns) => ExecuteResult) allows custom sandbox implementations. DynamicWorkerExecutor is the Cloudflare Workers implementation. Console output captured in ExecuteResult.logs. Configurable execution timeout.
AST-based code normalization via acorn replaces regex. sanitizeToolName() exported for converting MCP-style tool names to valid JS identifiers.
- #954
943c407Thanks @threepointone! - update dependencies
- #916
24e16e0Thanks @threepointone! - Widen peer dependency ranges across packages to prevent cascading major bumps during 0.x minor releases. Mark@cloudflare/ai-chatand@cloudflare/codemodeas optional peer dependencies ofagentsto fix unmet peer dependency warnings during installation.
-
#849
21a7977Thanks @Muhammad-Bin-Ali! - Allow configurable model inexperimental_codemodeinstead of hardcodedgpt-4.1 -
#859
3de98a3Thanks @threepointone! - broaden peer deps -
#865
c3211d0Thanks @threepointone! - update dependencies
-
#813
7aebab3Thanks @threepointone! - update dependencies -
#800
a54edf5Thanks @threepointone! - Update dependencies -
#818
7c74336Thanks @threepointone! - update dependencies -
Updated dependencies [
0c3c9bb,0c3c9bb,d1a0c2b,6218541,6218541,6218541,6218541,fd79481,6218541,0c3c9bb,6218541,6218541,e20da53,f604008,7aebab3,a54edf5,7c74336,6218541,ded8d3e]:- agents@0.3.7
-
#776
93c613eThanks @ShoeBoom! - prepend custom prompt to default assistant text -
Updated dependencies [
395f461,f27e62c]:- agents@0.3.6
-
#771
87dc96dThanks @threepointone! - update dependencies -
Updated dependencies [
cf8a1e7,87dc96d]:- agents@0.3.4
-
a5d0137Thanks @threepointone! - trigger a new release -
Updated dependencies [
a5d0137]:- agents@0.3.3
-
#756
0c4275fThanks @threepointone! - feat: split ai-chat and codemode into separate packagesExtract @cloudflare/ai-chat and @cloudflare/codemode into their own packages with comprehensive READMEs. Update agents README to remove chat-specific content and point to new packages. Fix documentation imports to reflect new package structure.
Maintains backward compatibility, no breaking changes.
-
Updated dependencies [
0c4275f,f12553f]:- agents@0.3.2