Packages

@cloudflare/think

0.21.0 · 20 Oct 2026MIT97k / weekRepositorynpmAtom feed

52 stable releases, newest first, by release line. Notes are quoted as the maintainers published them.

  1. 0.21.x · latest line
  2. 0.21.0

    20 Oct 2026
    • deprecated

      createExecuteTool and createExecuteRuntime are deprecated in favour of exec with a ws:tools module. See Calling the agent's tools from code.

    • deprecated

      Chat recovery now seals a turn after chatRecovery.maxInterruptedAttempts interrupted attempts (default 5), so a turn that exceeds the Durable Object memory limit on every run no longer retries forever; maxOomRetries is deprecated. See Stream Recovery.

    • Think's workspace tools are now @cloudflare/computer's createAITools, and exec offers every backend the Workspace has; createWorkspaceTools, workspaceBash, and @cloudflare/think/tools/workspace are removed. See Built-in workspace tools.

  3. 0.20.x
  4. 0.20.2

    9 Oct 2026
  5. 0.20.1

    7 Oct 2026
    • Fix a chat that could stall when the model chains fast client tool calls across steps.

  6. 0.20.0

    2 Oct 2026
    • breaking

      declared scheduled tasks now run on the root agent only; override getScheduledTasksScope() to return "all" for per-facet scheduling. See Think scheduled tasks.

    • deprecated

      Keep assistant messages and tool outputs attached to the correct turn when a provider reuses a toolCallId; resolveToolMergeId is deprecated in favour of reconcileMessages. See Chat agents.

    • Require ai@^7 and @ai-sdk/react@^4, because Think bundles providers that return AI SDK v7 models. See Think dependencies.

  7. 0.19.x
  8. 0.19.0

    18 Sep 2026
    • Add the Queue Lifecycle capability (agents/queue) for durable background work. Each pushed item is a job in the Lifecycle job queue, due immediately, run from the alarm loop one at a time in push order with Lifecycle's retry, deadman, and memory-limit policy. Callbacks are registered in the constructor and typed at declaration and push; push() accepts a stable id (upsert) and per-item retry.

      Agent.queue() and friends now delegate to the capability. Queued callbacks run from the alarm loop in a fresh invocation, so they no longer see the enqueuing request's connection or request through getCurrentAgent() (the agent itself is still available). The cf_agents_queues table and the in-isolate drain are gone; legacy rows migrate into the job queue on the next start. queue() accepts options.id; dequeue, dequeueAll, dequeueAllByCallback, getQueue, and getQueues are now asynchronous; and QueueItem.created_at is renamed createdAt. LifecycleServices.starting() is replaced by status(), which returns "zero" | "starting" | "started".

      Think's workflow-notification outbox and submission drain now run as queue items; the cf_think_workflow_notifications table migrates and is dropped on start.

      Both one-shot migrations (cf_agents_queues in Queue, cf_think_workflow_notifications in Think) are temporary upgrade paths and will be removed in the next minor release, by which point every started object has migrated. Deployments skipping this release should upgrade through it. Workflow-notification delivery retries with backoff capped at ten minutes (previously five) and gives up after twelve hours of continuous failure (previously never), reporting the failure through onError.

    • Require agents >=0.24.0 for Think's background work, which relies on the Queue capability's stable item IDs and alarm-driven execution.

    • Recover an interrupted Think turn that had opened its stream but persisted no content by re-running its user message instead of trying to continue it. Think opens the resumable stream row before inference, so a Durable Object reset in the window before the first chunk left a turn with a stream id, no partial, and a user message as the latest leaf; recovery classified it as continue, found no assistant message to continue from, and marked the incident skipped. A parent tailing such a child through agent tools then sealed the run as an error. This mirrors AIChatAgent's empty-partial new-turn rule (#1691).

  9. 0.18.x
  10. 0.18.0

    11 Sep 2026
    • Replatform Think conversation storage onto agents/sessions and prompt context onto agents/context.

      Existing subclasses keep compiling and running. configureSession(session) still accepts the withContext() / withCachedPrompt() chain, this.session still carries addContext, getContextBlock, replaceContextBlock, refreshSystemPrompt, freezeSystemPrompt, tools(), and the rest, and appendMessage(message, parentId) / getHistory(leafId) still take their positional arguments. Those context methods are deprecated forwards to the new this.context; new code should declare blocks in configureContext() and read this.context directly. withCachedPrompt() is a no-op because the frozen prompt is always persisted now.

      What you may want to change

      Behaviour changes on upgrade

      Removed

    • Lifecycle owns a durable job queue, driven as an alarm event loop.

      The thing in the queue is a job: a serialisable callback address — the
      owning capability plus a function name — with a due time and a payload.
      Capabilities and the host push jobs through the scoped jobs surface;
      Lifecycle drives due jobs in timestamp order when the alarm fires, owns
      dispatch retries and platform-failure deferral, arms a deadman pre-alarm
      before driving so an isolate death mid-drive still wakes the object, and
      derives the physical alarm purely from queue state (queue mutations re-arm
      automatically; an exclusive job suppresses ordinary candidates).

      class Cleanup extends LifecycleCapability {
        async scheduleSweep(time: number) {
          await this.lifecycle.jobs.push({ id: "sweep", fn: "sweep", time });
        }
        onJob({ job }: LifecycleJobContext) {
          // drive result: nothing = complete, { rescheduleAt } = suspend,
          // "yield" = leave due and wake again immediately
        }
      }

      The pull-based alarm-contribution model is removed: capability
      getNextAlarm()/onAlarm(), host getNextAlarm(),
      LifecycleServices.alarms (rearm/disabled), and AlarmContribution
      are gone. Host onAlarm() remains and runs once per alarm invocation
      after due jobs are driven. Terminal application failures reach the
      owner's onJobError(), whose drive result decides advancement.

      The alarm memory-limit circuit breaker (#1825) moves from Agent.alarm()
      into the Lifecycle event loop, targeting the exact executing job; Agent
      contributes domain policy through the new onAlarmMemoryLimit() host
      hook, and Scheduler's __DO_NOT_USE_WILL_BREAK__handleAlarmMemoryLimit
      escape hatch is gone. After recording a strike the breaker now finishes by
      resetting the isolate with ctx.abort(reason, { retryAlarm: false })
      (retry of the handled alarm suppressed; the backoff alarm owns the next
      wake), and Agent.destroy() uses the same no-retry abort so a completed
      teardown's alarm cannot be retried into a fresh constructor that recreates
      the deleted schema.

      Scheduler keeps its entire public API and loses its storage and due-row
      loop: a schedule is one job whose fn is the callback name, and interval
      schedules are single-flight jobs. Existing cf_agents_schedules rows are
      migrated into the cf_agents_jobs queue on startup and the legacy table
      is dropped. Agent's public scheduling and keepAlive() APIs are
      unchanged; its keep-alive, fiber-recovery/facet housekeeping, and
      deferred-destroy wakes are now host jobs, and Think's
      workflow-notification wake replaces the removed _getExtensionAlarm().

    • Keep media eviction a context-window technique, separate from how Sessions stores a message.

      How Sessions lays a message out in rows is invisible and lossless: a message too large for one row is split across continuation rows and reassembled byte for byte. Media eviction is a decision about the model's context: once media has aged past mediaEviction.keepRecentMessages on the active path, Think removes it from the conversation so the model stops re-reading a large image every turn, and leaves [evicted image/png, 812004 bytes; preserved at /attachments/evicted/<messageId>-<n>.png] in its place. The raw bytes are written to the Workspace at that path with their real mime type, so the workspace read tool puts the actual image back in context when the agent deliberately reads it. The rewritten message no longer carries the payload, so the bytes live in exactly one place.

      mediaEviction: false now means the model keeps seeing aged media. It no longer changes where Sessions keeps the bytes.

      minPartBytes is Think's context threshold and is no longer passed to Sessions as a storage setting. The marker text and the /attachments/evicted/<id>-<n>.<ext> paths are unchanged, so old markers keep resolving.

      MediaEvictionConfig.externalizeToWorkspace is deprecated and ignored: evicted bytes are always preserved. Existing configurations keep compiling.

      WorkspaceLike.writeFileBytes is optional. Eviction and skills projection need it to write raw bytes; a custom workspace without it keeps working and those two features log once and stand down.

  11. 0.17.x
  12. 0.17.0

    27 Aug 2026
    • Make durable chat recovery unconditional for AIChatAgent and Think.

      Every chat turn now runs in a recovery fiber, including WebSocket, programmatic, retry, and continuation paths. chatRecovery accepts true or a configuration object; false is no longer supported. Previously compiled JavaScript that still supplies false safely receives the default recovery configuration.

      To keep durable bookkeeping while preventing automatic inference after an interruption, return { continue: false } from onChatRecovery(). Use durable cancellation, side-effect, or spend state in that hook and tune chatRecovery budgets when retries must be bounded.

    • Preserve orphaned durable execution outcomes as framework-authored notes, then project them to user context for inference so provider transcript validation cannot reject their arbitrary position. Existing outcome notes receive the same projection without rewriting stored history.

    • Add Scheduler, a reusable Lifecycle capability for persistent delayed, dated, cron, and interval callbacks, under agents/schedules. Scheduled callbacks are registered on the Scheduler itself (new Scheduler({ callbacks: { ... } })), and set() / every() type both the callback name and the payload against that registration, so the typed scheduling surface and the runtime dispatch target are the same object. LifecycleCapability supplies every capability with storage, readiness, startup state, alarm coordination, a host invocation boundary, best-effort events, and generic capability routing — Scheduler consumes only that standard surface plus its callbacks and policy options, so any host that installs it configures nothing else. Lifecycle owns the physical Durable Object alarm and routes matching capability messages between Agent facets through one internal transport aperture, preserving existing root-owned facet schedule rows without Scheduler-specific Agent RPC methods or an Agent adapter. Agent uses the same Scheduler behind its existing APIs — name-based this.schedule(60, "methodName") keeps dispatching to Agent methods through a composition-root resolver — and preserves callback context, observability, retries, OOM handling, and alarm behavior. MCP now receives storage from Lifecycle when installed. Explicit destruction disposes live capability resources once, then clears shared Durable Object storage with deleteAll(). Think workflow notifications now contribute their wake time through Lifecycle instead of writing the physical alarm directly. The previous agents/schedule parser entry point remains as a deprecated compatibility alias. Agent exposes the composition root as experimental this.lifecycle and this.scheduler properties. The agents/lifecycle entry point and the capability surfaces built on it (Scheduler, installing MCPClientManager directly as a capability) are experimental and may change between releases; Agent's established APIs are unaffected.

      Compatibility notes: MCPClientManagerOptions.storage is removed — the manager receives storage from the Lifecycle it is installed on, so standalone construction with an explicit DurableObjectStorage is no longer supported. Scheduled callbacks now receive the documented parsed Schedule object as their second argument (previously the raw storage row, whose payload was an unparsed JSON string). The internal _cf_*ForFacet schedule RPC methods are replaced by the generic _cf_routeLifecycle capability aperture; facets always run the same deployed script, so no coordination is required.

  13. 0.16.x
  14. 0.16.0

    18 Aug 2026
    • Remove the convention-driven Think framework, including the Vite plugin, generated Worker entry and virtual modules, CLI, Studio, framework helpers, and server-entry helpers. Remove the separate create-think scaffolder and its starter templates. Think remains available as an explicit runtime for hand-written Worker entries.

      Migration for existing framework users

      If you only use the Think runtime, React integration, messengers, workflows, extensions, or tools, no migration is required.

      Existing useRequired change
      @cloudflare/think/viteUse agents/vite for decorators and agents:skills, alongside @cloudflare/vite-plugin.
      virtual:think/entryAdd a real Worker entry, such as src/server.ts, that explicitly exports each Think class.
      Generated bindings, migrations, and routingDeclare top-level Durable Object bindings and migrations in wrangler.jsonc; route with routeAgentRequest() and, for custom sub-agent routing, routeSubAgentRequest().
      @cloudflare/think/frameworkMove generated configuration and class exports into application code.
      @cloudflare/think/server-entryUse Agents SDK routing helpers and application-owned request handlers.
      think typesUse wrangler types.
      think init or create-thinkUse npx create-cloudflare@latest --template cloudflare/agents-starter, or manually configure a Think Worker.
      think studio, think state, or think inspectNo direct replacement.

      Existing deployments must preserve generated ThinkAgent_* and ThinkSubAgent_* constructor names and existing migration history. Sub-agent registries use Class.name, so export aliases alone do not preserve compatibility. If renaming classes, use a data-preserving Durable Object rename migration.

    • Preserve spacing between streamed text segments separated by tool calls. Think messenger delivery and Voice now share the same boundary-aware text joining logic from agents/chat.

      Existing users must:

    • Emit workspace image reads as image-data model content so AI SDK v6 routes them as images, while preserving file-data output for PDFs.

      Existing consumers that inspect raw workspace tool content must handle image-data for images; PDFs continue to use file-data. Normal tool callers require no change.

  15. 0.15.x
  16. 0.15.1

    28 Jul 2026
    • Fix AI SDK v7 telemetry, which produced spans with no token counts, no finish reason, no tool results and zero durations.

      Spans that must not outlive their invocation now close at the end of it rather than at the first await. Closing at the handoff ended every WebSocket-turn span before its result existed, so every finish-time attribute was dropped. A span still open when its invocation ends is closed and marked cloudflare.agents.span.truncated instead of passing as complete, approval spans decided asynchronously included. A chat turn owns its own boundary rather than its caller's, so a turn that is not awaited — an ack-and-return submit, or an auto-continuation fired from a timer — is no longer cut short by the handler that started it. generateText is bounded on the same terms as streamText, and a turn that fails or is cancelled keeps the usage it already reported.

      chat and execute_tool spans sit under their invoke_agent operation span on v7, where they were previously emitted as unrelated roots, and tool_approval segments sit under execute_tool.

      v7 has no telemetry metadata bag, so identity and turn context arrive through runtimeContext and telemetry.includeRuntimeContext. Reserved keys project onto the attributes v6 already emits, so a query written against v6 traces still matches v7 ones; other included keys pass through as cloudflare.agents.runtime_context.{key}, and context the caller did not mark stays off the span.

  17. 0.15.0

    23 Jul 2026

    Reading the note…

  18. 0.14.x
  19. 0.14.0

    22 Jul 2026

    Reading the note…

  20. 0.13.x
  21. 0.13.0

    13 Jul 2026

    Reading the note…

  22. 0.12.x
  23. 0.12.1

    30 Jun 2026

    Reading the note…

  24. 0.11.x
  25. 0.11.1

    28 Jun 2026

    Reading the note…

  26. 0.11.0

    26 Jun 2026

    Reading the note…

  27. 0.10.x
  28. 0.10.0

    17 Jun 2026

    Reading the note…

  29. 0.9.x
  30. 0.9.1

    16 Jun 2026

    Reading the note…

  31. 0.9.0

    12 Jun 2026

    Reading the note…

  32. 0.8.x
  33. 0.8.8

    8 Jun 2026

    Reading the note…

  34. 0.8.7

    8 Jun 2026

    Reading the note…

  35. 0.8.6

    7 Jun 2026

    Reading the note…

  36. 0.8.5

    7 Jun 2026

    Reading the note…

  37. 0.8.4

    5 Jun 2026

    Reading the note…

  38. 0.8.3

    5 Jun 2026

    Reading the note…

  39. 0.8.2

    3 Jun 2026

    Reading the note…

  40. 0.8.1

    3 Jun 2026

    Reading the note…

  41. 0.8.0

    2 Jun 2026

    Reading the note…

  42. 0.7.x
  43. 0.7.3

    26 May 2026

    Reading the note…

  44. 0.7.2

    21 May 2026

    Reading the note…

  45. 0.7.1

    20 May 2026

    Reading the note…

  46. 0.7.0

    19 May 2026

    Reading the note…

  47. 0.6.x
  48. 0.6.1

    14 May 2026

    Reading the note…

  49. 0.6.0

    13 May 2026

    Reading the note…

  50. 0.5.x
  51. 0.5.3

    2 May 2026

    Reading the note…

  52. 0.5.2

    1 May 2026

    Reading the note…

  53. 0.5.1

    1 May 2026

    Reading the note…

  54. 0.5.0

    30 Apr 2026

    Reading the note…

  55. 0.4.x
  56. 0.4.2

    28 Apr 2026

    Reading the note…

  57. 0.4.1

    27 Apr 2026

    Reading the note…

  58. 0.4.0

    23 Apr 2026

    Reading the note…

  59. 0.3.x
  60. 0.3.0

    18 Apr 2026

    Reading the note…

  61. 0.2.x
  62. 0.2.5

    18 Apr 2026

    Reading the note…

  63. 0.2.4

    15 Apr 2026

    Reading the note…

  64. 0.2.3

    15 Apr 2026

    Reading the note…

  65. 0.2.2

    14 Apr 2026

    Reading the note…

  66. 0.2.1

    11 Apr 2026

    Reading the note…

  67. 0.2.0

    7 Apr 2026

    Reading the note…

  68. 0.1.x
  69. 0.1.2

    1 Apr 2026

    Reading the note…

  70. 0.1.1

    30 Mar 2026

    Reading the note…

  71. 0.1.0

    23 Mar 2026

    Reading the note…