Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/codemode-module-prefix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cloudflare/computer": minor
---

Host and source modules for `WorkerJavaScriptBackend` that used `ws:*` names now use the `codemode:` prefix instead of `ws:`.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ SQLite and exposes one pluggable execution surface through
- **Isolate JavaScript** runs an ECMAScript module in a fresh Dynamic
Worker with structured input/results, durable relative imports,
configured libraries, Workspace-backed `node:fs/promises`, and host modules such as
`ws:git`, `ws:artifacts`, and `ws:container`.
`codemode:git`, `codemode:artifacts`, and `codemode:container`.

A Workspace may register multiple backends under stable IDs.
`workspace.runtime.exec(source, { backend })` is the single execution
Expand Down
4 changes: 2 additions & 2 deletions docs/09_tool_interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ createPiTools({ workspace, constrainedSampling: "require" });

pi tool results carry text and images. An image from `read` comes back as an `image` block; a PDF comes back as text saying it cannot be attached. `exec` returns its final snapshot.

`forAISDKTools()` does the same for an AI SDK tool set, such as an agent's own. See [`ws:tools`](17_isolate_javascript.md#wstools).
`forAISDKTools()` does the same for an AI SDK tool set, such as an agent's own. See [`codemode:tools`](17_isolate_javascript.md#codemodetools).

`forPiTools()` serves pi tools to isolate JavaScript as `ws:tools`, through `createToolBindings()`. It takes the result of `createPiTools()` or executable pi tools of your own. See [`ws:tools`](17_isolate_javascript.md#wstools).
`forPiTools()` serves pi tools to isolate JavaScript as `codemode:tools`, through `createToolBindings()`. It takes the result of `createPiTools()` or executable pi tools of your own. See [`codemode:tools`](17_isolate_javascript.md#codemodetools).

## TanStack AI

Expand Down
86 changes: 43 additions & 43 deletions docs/17_isolate_javascript.md

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ It provides:
- Read-only mounts for pre-filling the workspace tree from an R2 bucket or from files shipped with the Worker.
- Durability over DO restarts for all file operations.
- Pluggable execution backends selected through `workspace.runtime`: a Cloudflare Container shell, a just-bash Dynamic Worker, or an isolated ECMAScript-module Dynamic Worker.
- Isolated JavaScript with structured input/results, durable relative imports, configured libraries, durable `node:fs/promises`, host modules such as `ws:git`, `ws:container`, `ws:assets` and `ws:tools`, and managed execution records.
- Isolated JavaScript with structured input/results, durable relative imports, configured libraries, durable `node:fs/promises`, host modules such as `codemode:git`, `codemode:container`, `codemode:assets` and `codemode:tools`, and managed execution records.
- Workspace constructable without a backend, for filesystem-only use cases.
- Out-of-the-box agent tools for the AI SDK (`createAITools()` in `@cloudflare/computer/tools/ai-sdk`), pi (`createPiTools()` in `@cloudflare/computer/tools/pi-ai`), and TanStack AI (`createTanStackTools()` in `@cloudflare/computer/tools/tanstack-ai`).

Expand Down Expand Up @@ -48,11 +48,11 @@ The package ships several entrypoints:
| `@cloudflare/computer/backends/worker-javascript` | `WorkerJavaScriptBackend`, configured libraries, durable relative imports, `node:fs/promises`, and host modules. |
| `@cloudflare/computer/git` | Opt-in isomorphic-git glue for working with checkouts inside the workspace. Bundled lazily, with `pako` replaced by Workers `node:zlib`, and kept out of the default `@cloudflare/computer` graph. |
| `@cloudflare/computer/artifacts` | `createArtifact`, an optionally session-scoped wrapper over the Cloudflare Artifacts Workers binding, plus its argv CLI. |
| `@cloudflare/computer/modules/container` | `createContainerModule()` for `ws:container`: run container commands from isolate JavaScript. |
| `@cloudflare/computer/modules/git` | `createGitModule()` for `ws:git`: confined Git from isolate JavaScript. |
| `@cloudflare/computer/modules/artifacts` | `createArtifactsModule()` for `ws:artifacts`: Artifacts and git tokens from isolate JavaScript. |
| `@cloudflare/computer/modules/assets` | `createAssetsModule()` for `ws:assets`: publish a Workspace file from isolate JavaScript. |
| `@cloudflare/computer/modules/tools` | `createToolBindings()` for `ws:tools`: an agent's own tools, callable from isolate JavaScript. |
| `@cloudflare/computer/modules/container` | `createContainerModule()` for `codemode:container`: run container commands from isolate JavaScript. |
| `@cloudflare/computer/modules/git` | `createGitModule()` for `codemode:git`: confined Git from isolate JavaScript. |
| `@cloudflare/computer/modules/artifacts` | `createArtifactsModule()` for `codemode:artifacts`: Artifacts and git tokens from isolate JavaScript. |
| `@cloudflare/computer/modules/assets` | `createAssetsModule()` for `codemode:assets`: publish a Workspace file from isolate JavaScript. |
| `@cloudflare/computer/modules/tools` | `createToolBindings()` for `codemode:tools`: an agent's own tools, callable from isolate JavaScript. |
| `@cloudflare/computer/tools` | AI SDK tools for agents: read, write, edit, ls, optional exec, and optional publish. |
| `@cloudflare/computer/tools/core` | `defineExec()`: the `exec` tool's description, schema, and executor, with no agent library. |
| `@cloudflare/computer/tools/ai-sdk` | `createAITools()`: the AI SDK tool set for a Workspace. |
Expand Down Expand Up @@ -264,7 +264,7 @@ rather than an API.
| [14. Assets interface](./14_assets_interface.md) | Stable | `share` a workspace file to R2 and get back a presigned URL. |
| [15. Artifacts interface](./15_artifacts_interface.md) | Stable | `createArtifact` and the `artifacts` CLI, an optionally session-scoped wrapper over the Cloudflare Artifacts binding. |
| [16. Execution runtime architecture](./16_code_execution.md) | Stable | One runtime entry point over command and module backends. |
| [17. Isolate JavaScript runtime](./17_isolate_javascript.md) | Stable, except `ws:container` | ECMAScript modules, durable imports, configured libraries, durable `node:fs/promises`, host modules, and managed lifecycle. |
| [17. Isolate JavaScript runtime](./17_isolate_javascript.md) | Stable, except `codemode:container` | ECMAScript modules, durable imports, configured libraries, durable `node:fs/promises`, host modules, and managed lifecycle. |
| [18. Runtime migration](./18_runtime_migration.md) | Reference | Breaking preview-API mappings from public shell and script-execution surfaces to `workspace.runtime`. |
| [19. Performance](./19_performance.md) | Reference | Filesystem benchmarks: `fs-bench` numbers, an `npm install` comparison, and how to reproduce them. |

Expand Down
16 changes: 8 additions & 8 deletions examples/rlm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The browser runs the same long-context task three ways so you can see what the R
|---|---|
| Direct context | One model call with the complete corpus in its prompt |
| JavaScript only | A Workspace and generated JavaScript |
| Structured RLM | A Workspace, generated JavaScript, and bounded model calls through `ws:model` |
| Structured RLM | A Workspace, generated JavaScript, and bounded model calls through `codemode:model` |

## Why use this pattern?

Expand All @@ -47,7 +47,7 @@ This pattern is less useful when the context already fits comfortably in one pro
2. The parent model receives the question, file paths, and the available Computer tool. It does not receive the complete corpus.
3. The parent writes a complete ECMAScript module for the Worker JavaScript backend.
4. That module reads record-aligned partitions from the Workspace.
5. The module calls `ws:model` with a bounded batch of classification or extraction requests.
5. The module calls `codemode:model` with a bounded batch of classification or extraction requests.
6. The module validates the returned JSON and reduces it to one answer with JavaScript.
7. The UI shows the generated module, map calls, token use, duration, and official Oolong score.

Expand All @@ -67,7 +67,7 @@ const backend = new WorkerJavaScriptBackend({
access: "read",
egress: { mode: "none" },
modules: {
"ws:model": modelCapability,
"codemode:model": modelCapability,
},
});

Expand All @@ -77,13 +77,13 @@ const workspace = new Workspace({
});
```

The important line is `modules`. Generated code cannot read model credentials or call the network directly. It can only use the host-owned `ws:model` interface.
The important line is `modules`. Generated code cannot read model credentials or call the network directly. It can only use the host-owned `codemode:model` interface.

A generated module follows this shape:

```js
import fs from "node:fs/promises";
import { batch } from "ws:model";
import { batch } from "codemode:model";

export default async function () {
const manifest = JSON.parse(
Expand Down Expand Up @@ -149,8 +149,8 @@ The reducer is exact relative to its inputs. Model classifications can still be

The shortest path through the example is:

1. [`worker/rlm-agent.ts`](worker/rlm-agent.ts) wires together the model, Workspace, Worker JavaScript backend, executor tool, and `ws:model`.
2. [`worker/capability.ts`](worker/capability.ts) implements the bounded `batch(requests)` function behind `ws:model`.
1. [`worker/rlm-agent.ts`](worker/rlm-agent.ts) wires together the model, Workspace, Worker JavaScript backend, executor tool, and `codemode:model`.
2. [`worker/capability.ts`](worker/capability.ts) implements the bounded `batch(requests)` function behind `codemode:model`.
3. [`worker/structured-rlm.ts`](worker/structured-rlm.ts) describes the map result and JavaScript reduction for each task family.
4. [`worker/agent-common.ts`](worker/agent-common.ts) writes the same corpus into each Computer Workspace.
5. [`worker/executor-tool.ts`](worker/executor-tool.ts) creates the native Computer executor tool and keeps its browser-facing result small.
Expand All @@ -160,7 +160,7 @@ The two baselines live in [`worker/direct-agent.ts`](worker/direct-agent.ts) and

## Bounds used by the example

`ws:model` is deliberately small and predictable:
`codemode:model` is deliberately small and predictable:

- Up to 24 model requests in one run.
- Up to four model calls at a time.
Expand Down
6 changes: 3 additions & 3 deletions examples/rlm/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ function Experiment({ sessionId }: { sessionId: string }) {
<span>
{sample === "synth-frequency"
? "2,433 records → 22 bounded model maps → one JavaScript reduce"
: "Direct context · Computer Workspace · Computer + ws:model"}
: "Direct context · Computer Workspace · Computer + codemode:model"}
</span>
<small
className={orchestrationError ? "bad" : undefined}
Expand Down Expand Up @@ -416,7 +416,7 @@ function Lane({
icon: <Code weight="duotone" />,
},
rlm: {
kicker: "Computer + ws:model",
kicker: "Computer + codemode:model",
title: "Structured RLM",
description:
"Generated code asks model workers to interpret partitions, then combines their JSON.",
Expand Down Expand Up @@ -580,7 +580,7 @@ function Lane({
<strong>JavaScript completed, but its output does not fit this task.</strong>
<p>
The records need semantic labels before code can count them. This lane has no model
capability; Structured RLM adds bounded <code>ws:model</code> map calls.
capability; Structured RLM adds bounded <code>codemode:model</code> map calls.
</p>
</section>
) : null}
Expand Down
2 changes: 1 addition & 1 deletion examples/rlm/src/layout.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ describe("RLM trace layout", () => {
expect(appSource).toContain("JavaScript execution output");
expect(appSource).toContain("Capability mismatch");
expect(appSource).toContain("JavaScript completed, but its output does not fit this task.");
expect(appSource).toContain("bounded <code>ws:model</code> map calls");
expect(appSource).toContain("bounded <code>codemode:model</code> map calls");
});
});
2 changes: 1 addition & 1 deletion examples/rlm/worker/capability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ interface ChildHooks {
failed(metadata: FailedMetadata): void;
}

/** The `ws:model` trusted module: one `batch` function over bounded child requests. */
/** The `codemode:model` trusted module: one `batch` function over bounded child requests. */
export type ModelCapability = {
/** Run up to 24 child model requests and return one result per request. */
readonly batch: WorkspaceModuleFunction;
Expand Down
2 changes: 1 addition & 1 deletion examples/rlm/worker/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The executor command must be a complete ES module with export default async func

export const RLM_SYSTEM_PROMPT = `Solve the Oolong benchmark with one comprehensive recursive Computer execution, then answer briefly.

The executor command must be a complete ES module with export default async function. Use import fs from "node:fs/promises" and import { batch } from "ws:model". Read /workspace/oolong-real/manifest.json. Its contextChunks contain the long corpus.
The executor command must be a complete ES module with export default async function. Use import fs from "node:fs/promises" and import { batch } from "codemode:model". Read /workspace/oolong-real/manifest.json. Its contextChunks contain the long corpus.

Use Computer as an RLM. Do not make manifest-inspection, schema-discovery, or diagnostic-only calls:
1. Read the bounded corpus chunks.
Expand Down
6 changes: 3 additions & 3 deletions examples/rlm/worker/rlm-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ export class RlmAgent extends AIChatAgent<ModelEnv, BenchmarkAgentState> {
root: WORKSPACE_ROOT,
access: "read",
egress: { mode: "none" },
modules: { "ws:model": modelCapability },
modules: { "codemode:model": modelCapability },
maxConcurrentCapabilityCalls: 4,
// One manifest read + 24 chunk reads + one bounded ws:model batch.
// One manifest read + 24 chunk reads + one bounded codemode:model batch.
maxCapabilityCalls: 26,
maxCapabilityBytes: 4 * 1024 * 1024,
maxHostCallMs: 300_000,
Expand Down Expand Up @@ -239,7 +239,7 @@ export class RlmAgent extends AIChatAgent<ModelEnv, BenchmarkAgentState> {
? "The model did not return a successful execution result."
: completedMap
? null
: "The generated module did not use its ws:model map capability.",
: "The generated module did not use its codemode:model map capability.",
finishedAt: new Date().toISOString(),
run: this.#activeRun,
children: this.#children,
Expand Down
2 changes: 1 addition & 1 deletion examples/rlm/worker/rlm-interfaces.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Module interface:
import fs from "node:fs/promises";
import { batch } from "ws:model";
import { batch } from "codemode:model";
export default async function () {
// Put every file read, batch call, reduction, and return statement inside this function.
}
Expand Down
2 changes: 1 addition & 1 deletion examples/rlm/worker/step-settings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe("required Computer steps", () => {
it("retries recursive inference when the first execution produced no child evidence", () => {
expect(requiredRlmStep(1, "system", [], false)).toMatchObject({
instructions: expect.stringContaining("did not use recursive inference"),
messages: [{ role: "user", content: expect.stringContaining("ws:model") }],
messages: [{ role: "user", content: expect.stringContaining("codemode:model") }],
toolChoice: { type: "tool", toolName: "executor" },
});
});
Expand Down
4 changes: 2 additions & 2 deletions examples/rlm/worker/step-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import type { ModelMessage } from "ai";
export const COMPUTER_FINALIZATION_STEP = 1;

const FINALIZATION_INSTRUCTION =
'Return the benchmark answer now. The next executor module must return a typed { answer } object using evidence already seen. Do not inspect more data, return diagnostics, or call ws:model again. The final module must contain no imports or file I/O. Use exactly this shape: export default async function () { return { answer: "derived answer" }; }';
'Return the benchmark answer now. The next executor module must return a typed { answer } object using evidence already seen. Do not inspect more data, return diagnostics, or call codemode:model again. The final module must contain no imports or file I/O. Use exactly this shape: export default async function () { return { answer: "derived answer" }; }';
const RECURSION_RETRY_INSTRUCTION =
"The previous execution did not use recursive inference. Call batch(requests) from ws:model now with question-specific requests over the Workspace chunks, then return the child findings.";
"The previous execution did not use recursive inference. Call batch(requests) from codemode:model now with question-specific requests over the Workspace chunks, then return the child findings.";

export function requiredComputerStep(
stepNumber: number,
Expand Down
Loading
Loading