@cloudflare/computer
持久对象的持久 SQLite 支持的虚拟文件系统, 包含可插接的命令和代码执行。 用于需要 小型、便携式工作目录和读取、写取和运行的工具 里面的东西.
[大 只有预言. 此软件包作为反馈的预览 只有这个 API不稳定,设计有变化. 适当 实验、探索和原型 这不适合 此时生产用途.
你得到的东西
- 您持久对象中的文件系统 .
workspace.fs看起来像node:fs/promises—— 说readFile, (中文(简体) ),writeFile, (中文(简体) ),mkdir, (中文(简体) ),readdir, (中文(简体) ),rm, (中文(简体) ),grep——在DO重启中具有耐用性,辅以DO的 拥有 SQLite 存储器. - 一个行刑表面,几个后端.
workspace.runtime.exec()运行 shell 命令或 ECMAScript 模块。 选择一个完整的Linux容器,一个快速的工人外壳,或者一个 孤立的 JavaScript 运行时间, 全部对应相同的文件 . - 特工用的电池. 现成 AI SDK 软件
工具 (单位:千美元)
read, (中文(简体) ),ls, (中文(简体) ),find, (中文(简体) ),grep, (中文(简体) ),write, (中文(简体) ),edit, (中文(简体) ),delete选择exec),一个 git 客户端, R2 支持的只读挂载, 以及用于出版的助手 文档.
工作空间也可以运行, 完全没有执行后端, 给您 只有文件系统.
限制
- ~10 GB 每个工作空间(它与DO共享存储).
- 容器侧文件系统为内存所持有. 代理级目标 工作空间,不完全单调.
- 集装箱通过FUSE,如此重的I/O(大型)
node_modules安装,取出大焦油球)比出土盘慢. 见docs/19_performance.md。 。 。 .
安装
npm install @cloudflare/computer
您的员工需要 nodejs_compat 相容性旗. 这个
工壳和工页纸的后端 还需要
experimental 旗和工人装入器绑定。 每个后端都有它
本身的约束性要求——见 选择后端。 。 。 .
可选对等者依赖关系, 仅在使用匹配时安装
特性 : ai 财务报告和审定财务报表 zod (计: @cloudflare/computer/tools, (中文(简体) ),
@platformatic/vfs (为节点侧VFS供应商提供).
快开始
最小的有用是没有执行后端的文件系统. 添加
withWorkspace 到持久对象时,您有持久文件 :
import { withWorkspace, getWorkspace } from "@cloudflare/computer";
import { DurableObject } from "cloudflare:workers";
export class Agent extends withWorkspace(
class extends DurableObject<Env> {},
(self) => ({ storage: self.ctx.storage }),
) {}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const id = env.Agent.idFromName("user-123");
using ws = await getWorkspace(env.Agent.get(id));
await ws.fs.writeFile("/notes.md", "- [ ] ship it\n");
const notes = await ws.fs.readFile("/notes.md", "utf8");
return new Response(notes);
},
} satisfies ExportedHandler<Env>;
wrangler.jsonc数字 :
{
"compatibility_flags": ["nodejs_compat"],
"durable_objects": {
"bindings": [{ "name": "Agent", "class_name": "Agent" }]
},
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["Agent"] }
]
}
要运行针对这些文件的命令,请添加执行后端. 这个
工壳后端不需要容器和多克,所以是
程е快猭 exec 工作时间:
import { withWorkspace, getWorkspace } from "@cloudflare/computer";
import { WorkerShellBackend } from "@cloudflare/computer/backends/worker-shell";
import curlModules from "@cloudflare/computer/shell/curl";
import { DurableObject } from "cloudflare:workers";
export class Agent extends withWorkspace(
class extends DurableObject<Env> {},
(self) => ({
storage: self.ctx.storage,
backends: [
new WorkerShellBackend({
loader: self.env.LOADER,
workspace: { binding: "Agent", id: self.ctx.id.toString() },
ctx: self.ctx,
commands: [curlModules],
}),
],
}),
) {}
添加装入器绑定 experimental 旗为 wrangler.jsonc数字 :
{
"compatibility_flags": ["nodejs_compat", "experimental"],
"worker_loaders": [{ "binding": "LOADER" }]
}
工人外壳船作为特色组: 恒心外加
每个命令一个可选组
@cloudflare/computer/shell/<feature>组合
把它们交给 WorkerShellBackend是因为 commands 选项; 组合
在您的捆绑和捆绑中永远不能导入
这个 可选团体是: curl, (中文(简体) ), html-to-markdown, (中文(简体) ), python, (中文(简体) ),
sqlite, (中文(简体) ), js-exec, (中文(简体) ), yq, (中文(简体) ), file, (中文(简体) ), xan,以及 jq。 。 。 . curl 运行
隔离的全局性 fetch (无) undici 在捆绑中
继续由动态工人管理 globalOutbound。 。 。 .
现在 exec 运行与您相同的文件 fs 电话写道:
using ws = await getWorkspace(env.Agent.get(id));
await ws.fs.writeFile("/hello.txt", "world");
using run = await ws.runtime.exec("cat /hello.txt");
const { stdout, exitCode } = await run.result();
完整、可操作的版本请见
examples/worker-shell。 。 。 .
文件系统
workspace.fs 使用绝对路径, 并具有耐用性
重启 。 字符串默认为 UTF-8; 通过 a Uint8Array 或一个
ReadableStream 二进制内容.
// Write a string, bytes, or a stream straight to disk.
await ws.fs.writeFile("/notes/todo.md", "- [ ] ship it\n");
await ws.fs.writeFile("/data/blob.bin", new Uint8Array([1, 2, 3]));
await ws.fs.writeFile("/uploads/big.csv", request.body!);
// Read back as a string or as a stream.
const todo = await ws.fs.readFile("/notes/todo.md", "utf8");
const stream = await ws.fs.readFile("/uploads/big.csv");
return new Response(stream);
// Directories.
await ws.fs.mkdir("/notes/daily", { recursive: true });
for (const entry of await ws.fs.readdir("/notes")) {
console.log(entry.isDirectory ? `d ${entry.name}` : `f ${entry.name}`);
}
// Remove and search.
await ws.fs.rm("/notes/daily", { recursive: true });
const hits = await ws.fs.grep("TODO", "/", { ignoreCase: true });
见 docs/04_filesystem_interface.md
为整个地表.
只读挂载
从一出R2桶中预填出部分树. 挂载点下的文件
只读; 写入拒绝 EROFS。 。 。 .
import { R2Bucket } from "@cloudflare/computer";
new Workspace({
storage: ctx.storage,
mounts: { "/workspace/r2": R2Bucket(env.Bucket) },
});
运行命令和代码
workspace.runtime.exec(source, options) 是单个执行条目
点。 什麽 source 表示取决于后端: shell 命令用于
容器和工人壳后端,用于
工人 - 贾瓦斯图的后端.
using run = await ws.runtime.exec("ls -la /workspace", { encoding: "utf8" });
const { stdout, stderr, exitCode } = await run.result();
手柄也是个 ReadableStream 现场活动,你可以前进
输出, 以 Server- Sent Evolution 为例:
async fetch(request: Request) {
const run = await ws.runtime.exec("npm test", { encoding: "utf8" });
const sse = run.pipeThrough(
new TransformStream({
transform(event, controller) {
const frame = `event: ${event.name}\ndata: ${JSON.stringify(event.value)}\n\n`;
controller.enqueue(new TextEncoder().encode(frame));
},
}),
);
return new Response(sse, {
headers: { "content-type": "text/event-stream", "cache-control": "no-cache" },
});
}
边上 exec,运行时间曝光 getExec, (中文(简体) ), killExec,以及
disposeExec。见
docs/05_runtime_interface.md。 。 。 .
选择后端
| 后端 | 导入 | 运行 | 需求 |
|---|---|---|---|
| 集装箱 | @cloudflare/computer/backends/container | Shell 命令完全 Linux 用户区域( 真实的 二进制, npm, (中文(简体) ), node,网络) | 正在运行 Cloudflare 容器 computerd |
| 工人壳 | @cloudflare/computer/backends/worker-shell | 通过 shell 命令 刚刚巴什 在动态工作者中 | 装入工人的装入器; experimental 旗帜 |
| 工人 Java 脚本 | @cloudflare/computer/backends/worker-javascript | 新的动态工作者中的ECMAScript模块 | 装入工人的装入器; experimental 旗帜 |
- 集装箱 冷启动比较慢,但会给你真正的Linux
环境。 容器拥有自己的SQLite后卫VFS和这个
软件包将两个商店同步到一个capnweb WebSocket。 见
docs/07_injected_service.md页:1 容器图像,以及examples/container。 。 。 . - 工人壳 速度快,不需要集装箱。 每个文件系统
操作返回到同一个持久对象,所以没有
第二家商店,没有同步往返。 见
docs/12_worker_backend.md财务报告和审定财务报表examples/worker-shell。 。 。 . - 工人 Java 脚本 评估结构化模块
输入/结果、持久的相对进口、配置库、,
工作空间支持
node:fs/promises,并值得信赖ws:git编号 :ws:artifacts模块。 紧接着跑runtime.exec()返回; 图标 运行在它的活动流被消耗时保持活性。 见docs/17_isolate_javascript.md财务报告和审定财务报表examples/worker-javascript。 。 。 .
您可以在一个工作区注册数个后端, 并且每个呼叫都会路由 给一个名字的,看 多个后端。 。 。 .
代理工具
@cloudflare/computer/tools 环绕工作空间的AI SDK工具
表面,准备交接 generateText, (中文(简体) ), streamText,或代理人
框架 getTools()。默认设定是 read, (中文(简体) ), ls, (中文(简体) ), find, (中文(简体) ),
grep, (中文(简体) ), write, (中文(简体) ), edit,以及 delete· ; exec 财务报告和审定财务报表 publish 添加
当你配置它们。 只读模式保存 read, (中文(简体) ), ls, (中文(简体) ), find,以及
grep。 。 。 .
import { createAITools } from "@cloudflare/computer/tools";
const tools = createAITools({
workspace,
read: { maxBytes: 32 * 1024, maxLines: 800 },
shell: {
defaultBackend: "shell",
backends: {
shell: { description: "Fast Worker shell with built-in text commands." },
container: { description: "Full Linux userland in a Cloudflare Container." },
},
},
});
模型读每个后端的 description 当决定在哪里
命令应该运行,所以用简单的语言写。 短句文本
模型输出同时保持行和字节续作; 传到
下一个调用,以避免再次传输相同的字节。 合格形象
PDF 字节在被绑定的工具执行中抓取一次并返回
作为 AI SDK file 不重读文件的模型输出 。 SVG 来源
语句. ls, (中文(简体) ), find,以及 grep 将 pagination 传递到存储层
返回时 nextOffset 当有更多结果时 文件突变共享
锁定相同工作空间的工具集,并递归删除
排除整个亚树突变。 见
docs/09_tool_interface.md。 。 。 .
图形
workspace.git 是选择输入的 git 客户端, 由
isomorphic-git, (中文(简体) ),
直接在本地 SQLite VFS 上操作 — 没有后端或外壳
所需经费。 以通过方式启用 createGitClient() 从
@cloudflare/computer/git数字 :
import { Workspace } from "@cloudflare/computer";
import { createGitClient } from "@cloudflare/computer/git";
const ws = new Workspace({
storage: ctx.storage,
git: createGitClient(),
defaultGitIdentity: { name: "Agent", email: "[email protected]" },
});
await ws.git.clone({ url: "https://github.com/example/repo.git" });
await ws.fs.writeFile("/notes.md", "hello");
await ws.git.add({ paths: ["notes.md"] });
await ws.git.commit({ message: "add notes" });
Git 子路径捆绑 isomorphic-git 懒惰地交换 pako
对工人的依赖 node:zlib 执行,所以默认
包式图保持无基特. 还有一个转子入口
(单位:千美元)workspace.git.cli({ argv })),当 git 配置时
工壳后端显示内置 git 命令。 见
docs/13_git_interface.md。 。 。 .
共享文件
两种方法,从工作空间得到文件并进入世界:
- 资产 (单位:千美元)
@cloudflare/computer/assets:createAssets(...).share将工作空间文件上传到 R2 并返回一个预先签名的 URL 。 随附 结束WorkspaceOptions.assets以曝光内壳assets publish <path> [<expiry>]命令。 见docs/14_assets_interface.md。 。 。 . - 艺术品 (单位:千美元)
@cloudflare/computer/artifacts:createArtifact(binding, sessionId)是一个会话范围外观 页:1 云花艺术 装订。 每个寄存器名称都暗含着会话的前缀 id,所以一个命名空间会主持许多孤立的会话.
import { createArtifact } from "@cloudflare/computer/artifacts";
const artifacts = createArtifact(env.ARTIFACTS, agentId);
const repo = await artifacts.create("build-cache", { description: "CI artifacts" });
const token = await artifacts.createToken("build-cache", "read", 3600);
const mine = await artifacts.list(); // only this session's repos
工艺品还提供一种rgv CLI(artifacts.cli({ argv })),以及何时
Workspace 配置为装订工人壳的艺术
后端曝光一个 artifacts 命令。 见
docs/15_artifacts_interface.md。 。 。 .
跨越工人 – DO 边界
持久对象拥有工作空间;一个工人通过
ub. withWorkspace 安装管道,和 getWorkspace(stub)
返回客户端 :
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const id = env.Agent.idFromName("user-123");
using ws = await getWorkspace(env.Agent.get(id));
await ws.fs.writeFile("/notes.md", "hello");
using run = await ws.runtime.exec("ls /workspace");
const { exitCode, stdout } = await run.result();
return new Response(stdout, { status: exitCode === 0 ? 200 : 500 });
},
} satisfies ExportedHandler<Env>;
放下你的根茎
一个值得内化:RPC层不 收集垃圾的远程根 在长寿的会话中,没有被处理的根茎 累积到会话结束。 规则很短:
using从getWorkspace(...)。 。 。 .using手柄从ws.runtime.exec(...)。 。 。 .- 别担心
ws.fs, (中文(简体) ),ws.runtime,或ws.git- 他们骑着 父母亲. - 纯值回报( E)
readFile作为一个弦,stat, (中文(简体) ),readdir, (中文(简体) ),git.cli({...}))无根;无可处理.
短命的一发子弹 工人们按要求拆了会话,
所以这对长生不老的隔离物来说 最重要
棍子或忙着 exec 工作量。 合同满了
docs/11_lifecycle.md。 。 。 .
猎取出泄密物 CAPNWEB_TRACK_STUBS=1 读取 stubSnapshot()
从 @cloudflare/computer-rpc/debug,或击中 GET /__computerd/stubs
在电脑上.
软件包入口
| 入境点 | 目的 |
|---|---|
@cloudflare/computer | 这个 Workspace 伪装, workspace.runtime, stub 类型, R2 挂载, 和代理类. |
@cloudflare/computer/backends/container | CloudflareContainerBackend 财务报告和审定财务报表 withWorkspaceContainer在电脑上拉出/capnweb同步管道. |
@cloudflare/computer/backends/worker-shell | WorkerShellBackend 和捆绑的短跑时间. |
@cloudflare/computer/backends/worker-javascript | WorkerJavaScriptBackend,配置库,持久导入, node:fs/promises,并值得信赖 ws:git 编号 : ws:artifacts。 。 。 . |
@cloudflare/computer/tools | 用于代理的AI SDK工具: read, (中文(简体) ), ls, (中文(简体) ), find, (中文(简体) ), grep, (中文(简体) ), write, (中文(简体) ), edit, (中文(简体) ), delete选择 exec 财务报告和审定财务报表 publish。 。 。 . |
@cloudflare/computer/git | 选入 isomorphic-git 工作空间内检查的胶水 . |
@cloudflare/computer/assets | createAssets ——将一个工作空间文件共享到R2,作为预先签名的URL. |
@cloudflare/computer/artifacts | createArtifact 和它的CLI, 一个会话范围外观 在Cloudflare 艺术约束. |
@cloudflare/computer/observe/cloudflare | 云花-跑步时间适配器为可观察钩. |
只使用容器后端的消费者从不进口工人
子路径,所以未使用的后端有效载荷树摇走。 共享电线类型
集装箱服务在兄弟会的包里
@cloudflare/computer-rpc。 。 。 .
高级
多个后端
工作空间可携带一个以上的后端,每个后端在 a 下注册
稳定选择器 id (违约) "worker-shell", (中文(简体) ),
"container-shell",或 "worker-javascript") (中文(简体) ). runtime.exec 使用该
第一个后端, 除非呼叫者给它取了一个名字 :
const ws = new Workspace({
storage: ctx.storage,
backends: [
new WorkerShellBackend({ id: "shell", loader: env.LOADER, /* ... */ }),
new CloudflareContainerBackend({ id: "sandbox", container: () => this, /* ... */ }),
],
});
const grep = await ws.runtime.exec("grep -r TODO /workspace"); // default: "shell"
const build = await ws.runtime.exec("npm test", { backend: "sandbox" });
后端连接懒惰——第一个 exec, (中文(简体) ), push, (中文(简体) ), pull,或
ready(id) 为了一个id拨打它. ready({ all: true }) 温暖前
后端,它从代理的方便 onStart后端同步
光标是独立的,所以一个上的活动从来不会扰动另一个上的活动.
接受结构化的后端 input 返回结构化
value 声明 callable: true (工人-javascript后端确实如此).
通过 input 对不可调用的后端是一个明显的错误而不是一个
静地滴出.
没有混音的构造
withWorkspace 是快捷键。 您也可以构建一个 Workspace
直接通过一根接地来揭露:
const ws = new Workspace({ storage: ctx.storage, backends: [/* ... */] });
await ws.ready();
const stub = ws.stub(); // crosses the Workers-RPC boundary
当给智商分配工作空间时 workspace,通过
useThink: true 因此,思考的相容性方法被添加在一起
workspace.fs 财务报告和审定财务报表 workspace.runtime。 。 。 .
持久未决同步重试
一个命令可以更改后端文件, 然后有它的后命令拉
失败;结果曝光 sync: { status: "pending", ... }配置 a
SyncRetryScheduler 打开 Workspace 每一次连续重试一次
后端,然后调用 workspace.retryPendingSync(backend) 从你的Do's
警报 返回时使用受限指数回转 "exhausted"
在配置的最大值之后。 更换容器返回 "lost"
并清除无法恢复的意图,所以新工作不会被阻断。 图书馆
并不拥有您指定的警告。 见 SyncRetryScheduler, (中文(简体) ), SyncRetryIntent, (中文(简体) ),
财务报告和审定财务报表 SyncRetryOptions 在套件导出中.
观察性
通过一个 observer 页:1 Workspace 接收一个跨度的构造器
每一次有文件记录的行动(workspace.connect, (中文(简体) ), workspace.sync.push, (中文(简体) ),
workspace.sync.pull, (中文(简体) ), workspace.runtime.exec.spawn, (中文(简体) ),
workspace.fs.<op>) (中文(简体) ). 这个 span(name, attributes, run) 形状符合
云浮跑步时间 ctx.tracing,开口遥测,或测试记录器;
属性值仅限于 boolean | number | string编辑
默认是一个零成本的不操作,所以没有间接费用 除非你选择加入.
Cloudflare 运行时间的适配器住在
@cloudflare/computer/observe/cloudflare。 。 。 .
实例
examples/worker-shell- 那个 工人壳后端awrite编号 :read编号 :execHTTP表面. 没有集装箱.examples/worker-javascript- 那个 相同形状,运行ECMAScript模块而不是 shell 命令.examples/container- 集装箱 后端运行computerd。 。 。 .examples/think- 一个聊天代理,使用 工作空间作为其工作目录.examples/tutorial——分步建设: 在主机上写下标记卡, 并用pandoc内 集装箱.
文档
设计规格如下: docs/。 。 。 .
开始 01. VFS, (中文(简体) ),
04. 文件系统接口,以及
05. 运行时界面这是
前瞻性——读取意向,而不是描述代码
今时.
许可证
麻省理工学院. 见 LICENSE。 。 。 .