diff --git a/src/content/changelog/agents/2026-10-14-think-computer-workspace.mdx b/src/content/changelog/agents/2026-10-14-think-computer-workspace.mdx
new file mode 100644
index 00000000000..6c5c88fd2d5
--- /dev/null
+++ b/src/content/changelog/agents/2026-10-14-think-computer-workspace.mdx
@@ -0,0 +1,39 @@
+---
+title: Think agents now use a @cloudflare/computer Workspace
+description: Think and Agent Skills now work in a Workspace from @cloudflare/computer. @cloudflare/shell is deprecated.
+products:
+ - agents
+ - workers
+date: 2026-10-14
+---
+
+import { TypeScriptExample } from "~/components";
+
+[Think](/agents/harnesses/think/) and [Agent Skills](/agents/runtime/execution/agent-skills/) now work in a `Workspace` from [`@cloudflare/computer`](https://github.com/cloudflare/computer). Think's built-in workspace tools are now Computer's tools. Add an execution backend to the Workspace and the model gets an `exec` tool.
+
+`@cloudflare/shell` is deprecated, and so is Think's `createExecuteTool`.
+
+
+
+```ts
+import { Think } from "@cloudflare/think";
+import { Workspace } from "@cloudflare/computer";
+import { WorkerJavaScriptBackend } from "@cloudflare/computer/backends/worker-javascript";
+
+export class MyAgent extends Think {
+ override workspace = new Workspace({
+ storage: this.ctx.storage,
+ backends: [
+ new WorkerJavaScriptBackend({ id: "js", loader: this.env.LOADER }),
+ ],
+ });
+}
+```
+
+
+
+## Migrate your workspace data
+
+This is a breaking change. Computer stores files in different tables from Shell, and there is no automatic data migration between workspace formats. To keep an existing workspace, copy its files with the script in [Migrating from `@cloudflare/shell` to `@cloudflare/computer`](https://github.com/cloudflare/agents/blob/main/docs/shell/migrating-to-computer.md). If you do not, your agent starts with an empty workspace.
+
+For more information, refer to [Think tools](/agents/harnesses/think/tools/#built-in-workspace-tools).
diff --git a/src/content/docs/agents/harnesses/think/configuration.mdx b/src/content/docs/agents/harnesses/think/configuration.mdx
index 70ffc0fe9f6..8a31ca3f254 100644
--- a/src/content/docs/agents/harnesses/think/configuration.mdx
+++ b/src/content/docs/agents/harnesses/think/configuration.mdx
@@ -27,12 +27,11 @@ Think is configured by overriding methods and properties on your `Think` subclas
| `configureSession()` | identity | Add context blocks, compaction, search, skills — refer to [Sessions](/agents/runtime/lifecycle/sessions/) |
| `getSkills()` | `[]` | Return Agent Skills sources for on-demand skill activation — refer to [Agent Skills](/agents/runtime/execution/agent-skills/) |
| `getSkillScriptRunner()` | `null` | Enable the optional `run_skill_script` tool |
-| `workspaceBash` | `true` | Include or configure the default workspace `bash` tool — refer to [Tools](/agents/harnesses/think/tools/) |
| `messageConcurrency` | `"queue"` | How overlapping submits behave — refer to [Client tools](/agents/harnesses/think/client-tools/#message-concurrency) |
-| `includeMcpTools` | `true` | Convert connected MCP tools to AI SDK tools and add them to model turns. Refer to [MCP tools](/agents/harnesses/think/tools/#mcp-tools) |
+| `includeMcpTools` | `true` | Convert connected MCP tools to AI SDK tools and add them to model turns. Refer to [MCP tools](/agents/harnesses/think/tools/#mcp-tools) |
| `waitForMcpConnections` | `false` | Wait for MCP servers before inference |
-| `chatRecovery` | Always on | Durable recovery configuration. Refer to [Durable recovery](/agents/harnesses/think/recovery/) for all options and defaults |
-| `chatStreamStallTimeoutMs` | `0` (off) | Opt-in inactivity watchdog: abort a turn whose model stream produces no chunk for this long (measures the gap between chunks, including tool execution). A stall routes into bounded recovery |
+| `chatRecovery` | Always on | Durable recovery configuration. Refer to [Durable recovery](/agents/harnesses/think/recovery/) for all options and defaults |
+| `chatStreamStallTimeoutMs` | `0` (off) | Opt-in inactivity watchdog: abort a turn whose model stream produces no chunk for this long (measures the gap between chunks, including tool execution). A stall routes into bounded recovery |
| `contextOverflow` | `undefined` | Opt-in mid-turn context-overflow handling with `reactive`, `maxRetries`, and `proactive` options. Requires `classifyChatError` plus a session compaction function — refer to [Context-window overflow recovery](/agents/harnesses/think/recovery/#context-window-overflow-recovery) |
For `chatRecovery` and `chatStreamStallTimeoutMs` behavior, refer to [Durable recovery](/agents/harnesses/think/recovery/).
@@ -122,17 +121,16 @@ For the full Session API — context blocks, compaction, search, skills, and mul
## Package exports
-| Export | Description |
-| --------------------------------------- | ------------------------------------------------------------- |
-| `@cloudflare/think` | `Think`, `Session`, `Workspace`, `skills` namespace |
-| `@cloudflare/think/messengers` | Messenger contracts, Chat SDK bridge, state agent, delivery |
-| `@cloudflare/think/messengers/telegram` | Telegram messenger provider and delivery helpers |
-| `@cloudflare/think/workflows` | `ThinkWorkflow`, `step.prompt()` — Workflow prompts |
-| `@cloudflare/think/tools/workspace` | `createWorkspaceTools()` — for custom storage backends |
-| `@cloudflare/think/tools/execute` | `createExecuteTool()` — sandboxed code execution via Code Mode |
-| `@cloudflare/think/tools/browser` | `createBrowserTools()` — Chrome DevTools Protocol tools |
-| `@cloudflare/think/tools/extensions` | `createExtensionTools()` — LLM-driven extension loading |
-| `@cloudflare/think/extensions` | `ExtensionManager`, `HostBridgeLoopback` — extension runtime |
+| Export | Description |
+| --------------------------------------- | ------------------------------------------------------------ |
+| `@cloudflare/think` | `Think`, `Session`, `lazyWorkspace`, `skills` namespace |
+| `@cloudflare/think/messengers` | Messenger contracts, Chat SDK bridge, state agent, delivery |
+| `@cloudflare/think/messengers/telegram` | Telegram messenger provider and delivery helpers |
+| `@cloudflare/think/workflows` | `ThinkWorkflow`, `step.prompt()` — Workflow prompts |
+| `@cloudflare/think/tools/execute` | `createExecuteTool()` — deprecated Code Mode execution tool |
+| `@cloudflare/think/tools/browser` | `createBrowserTools()` — Chrome DevTools Protocol tools |
+| `@cloudflare/think/tools/extensions` | `createExtensionTools()` — LLM-driven extension loading |
+| `@cloudflare/think/extensions` | `ExtensionManager`, `HostBridgeLoopback` — extension runtime |
## Dependencies
@@ -143,14 +141,13 @@ Peer dependencies you provide:
| `agents` | yes | Cloudflare Agents SDK |
| `ai` | yes | AI SDK v6 |
| `zod` | yes | Schema validation (v4) |
+| `@cloudflare/computer` | yes | Workspace and workspace tools |
| `@chat-adapter/telegram` | optional | Required for Telegram messengers |
Bundled with `@cloudflare/think`:
-| Package | Notes |
-| ---------------------- | ----------------------------------------------------- |
-| `@cloudflare/shell` | `Workspace` filesystem |
-| `@cloudflare/codemode` | Code execution for `createExecuteTool()` |
-| `just-bash` | Sandboxed shell for the default workspace `bash` tool |
+| Package | Notes |
+| ---------------------- | ---------------------------------------- |
+| `@cloudflare/codemode` | Code execution for `createExecuteTool()` |
The Agent Skills engine and its script runner live in [`agents/skills`](/agents/runtime/execution/agent-skills/), so skill scripts pull `@cloudflare/worker-bundler` and `just-bash` through `agents`, not Think.
diff --git a/src/content/docs/agents/harnesses/think/getting-started.mdx b/src/content/docs/agents/harnesses/think/getting-started.mdx
index 74b36c7dc6b..428046a1c87 100644
--- a/src/content/docs/agents/harnesses/think/getting-started.mdx
+++ b/src/content/docs/agents/harnesses/think/getting-started.mdx
@@ -18,7 +18,7 @@ By the end of this tutorial you will have a Think agent that:
- Streams responses to a React chat UI
- Has persistent memory the model can read and write
-- Includes workspace file tools (read, write, edit, find, grep, delete)
+- Includes workspace file tools (read, ls, find, grep, write, edit, delete) from @cloudflare/computer
- Supports custom server-side tools
## Prerequisites
@@ -37,7 +37,7 @@ npm init -y
Install dependencies:
```sh
-npm install @cloudflare/think @cloudflare/ai-chat agents ai @cloudflare/shell zod workers-ai-provider react react-dom
+npm install @cloudflare/think @cloudflare/computer @cloudflare/ai-chat agents ai zod workers-ai-provider react react-dom
npm install -D wrangler @cloudflare/vite-plugin @cloudflare/workers-types @vitejs/plugin-react @tailwindcss/vite tailwindcss typescript vite
```
@@ -133,7 +133,7 @@ This is a working agent. Think automatically provides:
- WebSocket chat protocol (compatible with `useAgentChat`)
- Message persistence in SQLite
- Resumable streaming (page refresh replays buffered chunks)
-- Workspace file tools (read, write, edit, list, find, grep, delete)
+- Workspace file tools (read, ls, find, grep, write, edit, delete)
- Abort/cancel support
- Error handling with partial message persistence
@@ -297,7 +297,7 @@ export class MyAgent extends Think {
Think merges tools from multiple sources automatically. On every turn, the model has access to:
-1. **Workspace tools** — read, write, edit, list, find, grep, delete, bash (built-in)
+1. **Workspace tools** — read, ls, find, grep, write, edit, delete, plus exec when the Workspace has a backend (built-in)
2. **Your tools** — from `getTools()`
3. **Extension tools** — from loaded extensions
4. **Session tools** — set_context, load_context, search_context (from `configureSession`)
diff --git a/src/content/docs/agents/harnesses/think/index.mdx b/src/content/docs/agents/harnesses/think/index.mdx
index 429d443b4bf..e11a8dbfe35 100644
--- a/src/content/docs/agents/harnesses/think/index.mdx
+++ b/src/content/docs/agents/harnesses/think/index.mdx
@@ -32,7 +32,7 @@ If this is your first agent, start with the [Getting started tutorial](/agents/h
### Install
-
+
Think supports AI SDK v6 and v7. Use `ai@^6` with `@ai-sdk/react@^3`, or use `ai@^7` with `@ai-sdk/react@^4`. Keep the AI SDK packages on matching major versions throughout your project.
diff --git a/src/content/docs/agents/harnesses/think/tools.mdx b/src/content/docs/agents/harnesses/think/tools.mdx
index dea6092a761..b22e9354da5 100644
--- a/src/content/docs/agents/harnesses/think/tools.mdx
+++ b/src/content/docs/agents/harnesses/think/tools.mdx
@@ -1,7 +1,7 @@
---
title: Tools
pcx_content_type: reference
-description: Built-in workspace tools (including bash), custom tools, approvals, MCP tools, code execution, browser tools, and extensions for Think agents.
+description: Built-in workspace tools, custom tools, approvals, MCP tools, code execution, browser tools, and extensions for Think agents.
sidebar:
order: 4
products:
@@ -16,7 +16,7 @@ Think provides built-in workspace file tools on every turn, plus integration poi
On every turn, Think merges tools from multiple sources. Later sources override earlier ones if names collide:
-1. **Workspace tools** — `read`, `write`, `edit`, `list`, `find`, `grep`, `delete`, `bash` (built-in)
+1. **Workspace tools** — `read`, `ls`, `find`, `grep`, `write`, `edit`, `delete`, plus `exec` and `publish` when configured (built-in)
2. **`getTools()`** — your custom server-side tools
3. **Extension tools** — tools from loaded extensions (prefixed by extension name)
4. **Session tools** — `set_context`, `load_context`, `search_context` (from `configureSession`)
@@ -28,30 +28,54 @@ Tools belong to the agent running the turn. For parent-child orchestration, use
## Built-in workspace tools
-Every Think agent gets `this.workspace` — a virtual filesystem backed by Durable Object SQLite. Workspace tools are automatically available to the model with no configuration.
+Every Think agent gets `this.workspace`, a `Workspace` from [`@cloudflare/computer`](https://github.com/cloudflare/computer) stored in the Durable Object's SQLite. Think adds Computer's AI SDK tools to every turn with no configuration.
-| Tool | Description |
-| -------- | --------------------------------------------------------------------------- |
-| `read` | Read text with line numbers; pass images and PDFs to multimodal models |
-| `write` | Write content to a file (creates parent directories) |
-| `edit` | Apply a find-and-replace edit to an existing file (supports fuzzy matching) |
-| `list` | List files and directories in a path |
-| `find` | Find files matching a glob pattern |
-| `grep` | Search file contents by regex or fixed string |
-| `delete` | Delete a file or directory |
-| `bash` | Run a sandboxed Bash script against workspace files |
+| Tool | Description |
+| --------- | ----------------------------------------------------------------------------------- |
+| `read` | Read text with line and byte paging; pass images and PDFs to multimodal models |
+| `ls` | List files and directories in a path, with pagination |
+| `find` | Find files matching a glob pattern |
+| `grep` | Search file contents by regex or fixed string |
+| `write` | Write content to a file (creates parent directories) |
+| `edit` | Apply exact text replacements to a file, falling back to whitespace-tolerant search |
+| `delete` | Delete a file or directory |
+| `exec` | Run a command or module on one of the Workspace's execution backends |
+| `publish` | Share a workspace file through a presigned URL, when the Workspace has assets |
-The `bash` tool is enabled by default. It mounts workspace files into a `just-bash` virtual filesystem, runs with network access disabled, and writes created, updated, and deleted files and empty directories back to the workspace. Use it for shell-style workflows that combine multiple file operations; use the narrower tools for simple reads, writes, and edits.
+Paths are absolute. Computer's tools and backends treat `/workspace` as the working root, and Think writes its own files there too.
-To keep tool calls bounded, the Bash tool snapshots up to 1,000 workspace files by default and skips files larger than 1 MB. Skipped files are reported in the tool result and are treated as protected during write-back so the script cannot accidentally overwrite or delete content that was not mounted. You can tune `maxWorkspaceFiles`, `maxWorkspaceFileBytes`, `maxOutputBytes`, `timeout`, and `network` through `workspaceBash`.
+`@cloudflare/computer` is a peer dependency of Think:
-Disable the default Bash tool for conservative deployments:
+```sh
+npm install @cloudflare/computer
+```
+
+### Run code with `exec`
+
+The default Workspace has no execution backends, so there is no `exec` tool until you add one. Configure the backends, and the modules they offer, on the Workspace:
```ts
+import { Think } from "@cloudflare/think";
+import { Workspace } from "@cloudflare/computer";
+import { WorkerJavaScriptBackend } from "@cloudflare/computer/backends/worker-javascript";
+import { createGitClient } from "@cloudflare/computer/git";
+import { createGitModule } from "@cloudflare/computer/modules/git";
+
export class MyAgent extends Think {
- workspaceBash = false;
+ override workspace = new Workspace({
+ storage: this.ctx.storage,
+ git: createGitClient(),
+ backends: [
+ new WorkerJavaScriptBackend({
+ id: "js",
+ loader: this.env.LOADER,
+ access: "read-write",
+ modules: { "ws:git": createGitModule() },
+ }),
+ ],
+ });
getModel() {
/* ... */
@@ -61,42 +85,92 @@ export class MyAgent extends Think {
-### R2 spillover
+The JavaScript backend runs code in a [Dynamic Worker](/dynamic-workers/), so it needs a Worker Loader binding:
+
+
+
+```toml
+[[worker_loaders]]
+binding = "LOADER"
+```
+
+
+
+Computer also ships a `just-bash` shell backend that runs in Dynamic Workers, and a container backend with a full Linux userland. Refer to the [Computer README](https://github.com/cloudflare/computer/tree/main/packages/computer#choosing-a-backend) for each backend's bindings.
+
+### Call the agent's tools from code
-By default, the workspace stores everything in SQLite. For large files, override `workspace` to add R2 spillover:
+Give a JavaScript backend a `ws:tools` module, and code the model runs with `exec` can import the agent's tools. Code reads files through `node:fs/promises`, so serve `getTools()` rather than the workspace tools:
```ts
-import { Think } from "@cloudflare/think";
-import { Workspace } from "@cloudflare/shell";
+import { createToolBindings } from "@cloudflare/computer/modules/tools";
+import { forAISDKTools } from "@cloudflare/computer/tools/ai-sdk";
-export class MyAgent extends Think {
- override workspace = new Workspace({
- sql: this.ctx.storage.sql,
- r2: this.env.R2,
- name: () => this.name,
- });
+new WorkerJavaScriptBackend({
+ id: "js",
+ loader: this.env.LOADER,
+ modules: {
+ "ws:tools": createToolBindings(forAISDKTools(() => this.getTools())),
+ },
+});
+```
- getModel() {
- /* ... */
- }
+
+
+Code the model runs with `exec`:
+
+```js
+import { readFile } from "node:fs/promises";
+import { getWeather } from "ws:tools";
+
+export default async function () {
+ const cities = JSON.parse(await readFile("/workspace/cities.json", "utf8"));
+ const reports = [];
+ for (const city of cities) reports.push((await getWeather({ city })).text);
+ return reports;
}
```
-
+`ws:tools` does not export tools that need approval or tools that run in the browser, because nothing can approve or run them from code. Calls from code do not go through `beforeToolCall`. Refer to [`ws:tools`](https://github.com/cloudflare/computer/blob/main/docs/17_isolate_javascript.md#wstools) for how calls and results work.
-This requires an R2 bucket binding:
+### Change the tools
-
+`exec` offers every backend the Workspace has, and each backend describes itself to the model. To change a built-in tool, return a tool with the same name from `getTools()`. It replaces the built-in. To hide tools for a turn, return `activeTools` from `beforeTurn`.
-```toml
-[[r2_buckets]]
-binding = "R2"
-bucket_name = "agent-files"
+### Share a workspace
+
+To work in a Workspace another Durable Object owns, wrap `getWorkspace` in `lazyWorkspace`. Think contacts the owner only when a turn first touches a file:
+
+
+
+```ts
+import { getWorkspace } from "@cloudflare/computer";
+import { Think, lazyWorkspace } from "@cloudflare/think";
+
+export class Chat extends Think {
+ override workspace = lazyWorkspace(async () =>
+ getWorkspace(await this.parentAgent(Directory)),
+ );
+}
```
-
+
+
+Every Think agent can hand out its Workspace this way. `getWorkspace(stub)` calls the agent's `__getWorkspaceStub()` method over RPC. A lazy Workspace gets the file tools but no `exec`.
+
+### Upgrade from `@cloudflare/shell`
+
+Earlier versions of Think used a `Workspace` from `@cloudflare/shell`, which is now deprecated. Computer stores files in different tables, and Think does not move your data. To keep an existing workspace, copy its files with the script in [Migrating from `@cloudflare/shell` to `@cloudflare/computer`](https://github.com/cloudflare/agents/blob/main/docs/shell/migrating-to-computer.md).
+
+The upgrade also changes the tools:
+
+- `list` is now `ls`.
+- The in-process `bash` tool is gone. Add a backend to the Workspace to get `exec`.
+- `workspaceBash`, `createWorkspaceTools`, and `@cloudflare/think/tools/workspace` are removed, with no replacement. To change a built-in tool, return a tool with the same name from `getTools()`. To hide tools for a turn, return `activeTools` from `beforeTurn`.
+
+Refer to [Upgrading to a Computer workspace](https://github.com/cloudflare/agents/blob/main/docs/think/index.md#upgrading-to-a-computer-workspace) for the full list.
## Custom tools
@@ -150,7 +224,7 @@ getTools(): ToolSet {
inputSchema: z.object({ path: z.string() }),
needsApproval: async ({ path }) => path.startsWith("/important/"),
execute: async ({ path }) => {
- await this.workspace.rm(path);
+ await this.workspace.fs.rm(path);
return { deleted: path };
},
}),
@@ -249,18 +323,23 @@ export class MyAgent extends Think {
## Code execution tool
+:::caution[Deprecated]
+`createExecuteTool` and `createExecuteRuntime` are deprecated. Use `exec` on a JavaScript backend with a `ws:tools` module instead. Refer to [Call the agent's tools from code](#call-the-agents-tools-from-code). The execute tool keeps working until it is removed along with `@cloudflare/codemode`.
+:::
+
Let the LLM write and run JavaScript in a sandboxed Worker, recorded on a durable Code Mode runtime (abort-and-replay, human approvals, audit trail, reusable snippets). Requires `@cloudflare/codemode` and a `worker_loaders` binding.
```sh
npm install @cloudflare/codemode
```
-The one-liner infers everything from the agent — `state.*` from `this.workspace`, the executor from `env.LOADER`, and a live browser (`cdp.*`) from `env.BROWSER` if bound:
+The one-liner infers the executor from `env.LOADER` and a live browser (`cdp.*`) from `env.BROWSER` if bound. Pass tools for `tools.*`, including the workspace tools if the sandbox should reach the workspace:
```ts
import { Think } from "@cloudflare/think";
+import { createAITools } from "@cloudflare/computer/tools/ai-sdk";
import { createExecuteTool } from "@cloudflare/think/tools/execute";
export class MyAgent extends Think {
@@ -270,7 +349,9 @@ export class MyAgent extends Think {
getTools() {
return {
- execute: createExecuteTool(this),
+ execute: createExecuteTool(this, {
+ tools: createAITools({ workspace: this.workspace }),
+ }),
};
}
}
@@ -308,31 +389,17 @@ Each missing piece fails with an error naming the step.
Inside the sandbox the model sees typed namespaces plus the platform SDK:
- `tools.*` — your AI SDK tools (object args, validated against their schemas). Only tools with an `execute` function are exposed — client-side tools cannot run in the sandbox.
-- `state.*` — the workspace filesystem (`state.readFile({ path })`, `state.glob({ pattern })`, `state.planEdits(...)`, and so on).
- `cdp.*` — the browser, when a Browser Run binding is configured. The execute tool defaults to `session: { mode: "dynamic" }`: sessions are per-execution unless the model promotes one with `cdp.startSession()`.
- `codemode.search` / `codemode.describe` / `codemode.step` / `codemode.run` — discovery, side-effect boundaries, and saved snippets.
-Pass overrides for anything beyond the defaults — for example, custom `tools.*` alongside the agent-derived state:
-
-
-
-```ts
-execute: createExecuteTool(this, { tools: myDomainTools });
-```
-
-
-
-Or fully explicit options (no agent inference):
+Or pass fully explicit options (no agent inference):
```ts
-import { createWorkspaceStateBackend } from "@cloudflare/shell";
-
createExecuteTool({
ctx: this.ctx,
tools: myDomainTools,
- state: createWorkspaceStateBackend(this.workspace),
browser: this.env.BROWSER,
loader: this.env.LOADER,
});
@@ -429,7 +496,7 @@ The tool is backed by a Code Mode runtime with the `cdp` connector: the model wr
By default each execution gets a fresh browser session (`one-shot`), torn down when the run ends. Pass `session: { mode: "dynamic" }` to let the model promote a session with `cdp.startSession()` so later executions continue in the same browser, or `session: { mode: "reuse", key }` for a named long-lived session. Stale sessions are reclaimed by the connector's `sweep()` — call it from a scheduled task.
:::note
-The simplest setup is the unified execute tool in [Code execution tool](#code-execution-tool): `createExecuteTool(this)` already includes `cdp.*` alongside `state.*` and `tools.*` when `env.BROWSER` is bound — one tool, one durable history. Use `createBrowserTools` when you want a separate, browser-only tool.
+The simplest setup is the unified execute tool in [Code execution tool](#code-execution-tool): `createExecuteTool(this)` already includes `cdp.*` alongside `tools.*` when `env.BROWSER` is bound — one tool, one durable history. Use `createBrowserTools` when you want a separate, browser-only tool.
:::
For a custom Chrome endpoint, pass `cdpUrl` instead of `browser`:
@@ -564,56 +631,3 @@ getExtensions() {
```
The context block is registered as `notes_scratchpad` (namespaced by extension name).
-
-## Custom workspace backends
-
-The individual tool factories are exported for use with custom storage backends:
-
-
-
-```ts
-import {
- createReadTool,
- createWriteTool,
- createEditTool,
- createListTool,
- createFindTool,
- createGrepTool,
- createDeleteTool,
- createWorkspaceTools,
-} from "@cloudflare/think/tools/workspace";
-```
-
-
-
-Implement the operations interface for your storage backend:
-
-
-
-```ts
-import type { ReadOperations } from "@cloudflare/think/tools/workspace";
-
-const myReadOps: ReadOperations = {
- readFile: async (path) => fetchFromMyStorage(path),
- stat: async (path) => getFileInfo(path),
-};
-
-const readTool = createReadTool({ ops: myReadOps });
-```
-
-
-
-Or create the full set from a `Workspace`, optionally disabling the Bash tool:
-
-
-
-```ts
-import { createWorkspaceTools } from "@cloudflare/think/tools/workspace";
-
-const tools = createWorkspaceTools(myCustomWorkspace);
-const toolsWithoutBash = createWorkspaceTools(myCustomWorkspace, {
- bash: false,
-});
-```
-
-
diff --git a/src/content/docs/agents/runtime/execution/agent-skills.mdx b/src/content/docs/agents/runtime/execution/agent-skills.mdx
index 133da646ae1..580acff3445 100644
--- a/src/content/docs/agents/runtime/execution/agent-skills.mdx
+++ b/src/content/docs/agents/runtime/execution/agent-skills.mdx
@@ -113,6 +113,8 @@ export default async function run(input: unknown, ctx: SkillRunContext) {
`ctx` is `{ skill, files, workspace, tools, output }`. `ctx.files` holds bundled text resources by relative path, `ctx.workspace` is gated by the workspace permission, `ctx.tools` only exposes tools the runner was given, and `ctx.output.writeFile(name, content)` returns scratch artifacts to the model (it does not mutate the workspace). Python and Bash use the path-based contract instead: `/input.json`, `/context.json`, bundled resources under `/skill`, and `/output` for artifacts.
+`workspaceInstance` must be a `Workspace` from [`@cloudflare/computer`](https://github.com/cloudflare/computer). In Think, `this.workspace` already is one. Relative paths in skill scripts resolve against `/workspace`.
+
Passing `workspaceInstance` gives scripts read-only workspace access by default. Network access, tools, and workspace writes are opt-in. The default timeout is 30 seconds.
## Example
diff --git a/src/content/docs/agents/tools/browser.mdx b/src/content/docs/agents/tools/browser.mdx
index a1d70c1e4ff..8bc6f0d7305 100644
--- a/src/content/docs/agents/tools/browser.mdx
+++ b/src/content/docs/agents/tools/browser.mdx
@@ -579,10 +579,6 @@ The browser agent example uses the legacy tools. It covers Browser Run setup, to
description="Build an agent that can browse the web, inspect pages, capture screenshots, and debug frontend issues."
/>
-### Think execute tool
-
-Think's unified execute tool, `createExecuteTool(this)`, includes `cdp.*` alongside `state.*` and `tools.*` when `env.BROWSER` is bound. It uses the legacy browser connector. Refer to [Think tools](/agents/harnesses/think/tools/).
-
## Related resources
+
@@ -135,16 +135,22 @@ Use `aiTools()` when combining AI SDK tools with providers from other packages.
import { AIChatAgent } from "@cloudflare/ai-chat";
import { DynamicWorkerExecutor } from "@cloudflare/codemode";
import { aiTools, createCodeTool } from "@cloudflare/codemode/ai";
-import { Workspace } from "@cloudflare/shell";
-import { stateTools } from "@cloudflare/shell/workers";
+import { Workspace } from "@cloudflare/computer";
+import { createAITools } from "@cloudflare/computer/tools/ai-sdk";
import { weatherTools } from "./tools";
export class Chat extends AIChatAgent {
- workspace = new Workspace({ sql: this.ctx.storage.sql });
+ workspace = new Workspace({ storage: this.ctx.storage });
codemodeTool() {
return createCodeTool({
- tools: [aiTools(weatherTools), stateTools(this.workspace)],
+ tools: [
+ aiTools(weatherTools),
+ {
+ name: "workspace",
+ tools: createAITools({ workspace: this.workspace }),
+ },
+ ],
executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),
});
}
@@ -153,7 +159,7 @@ export class Chat extends AIChatAgent {
-This example exposes AI SDK tools as `codemode.*` and workspace tools as `state.*`.
+This example exposes AI SDK tools as `codemode.*` and workspace tools as `workspace.*`, for example `workspace.read({ path })`.
To assign custom namespaces, pass provider objects instead: