代理中继沙盒路由器
为沙盒工作量提供信用-第一SDK和路由底物.
它在配置的提供者集合中构建和选择,同时授权每次运行时间
运行到 @agent-relay/sandbox。 。 。 .
此寄存器不会分叉,复制或执行提供者运行时间适配器.
V1 边界
路由器拥有 :
- 供应商申报的沙盒能力简介,包括账户范围 最大寿命和正/负要求;
- 稳定的供应商登记册接口;
- 要求排行前过滤;
- 决定性
cost, (中文(简体) ),latency, (中文(简体) ),reliability,以及balanced排名; - 明确分类、证明的有限度的购置时间倒计时 分配前失败(默认三次尝试,最多10次);
- 仅读账户容量测量和明确命令容量外溢;
- 稳定
sbx_…定位码、标签和耐用供应商绘图接合器; - 私人流程识别验证和确定启动/启动计划;
- 已打入、已消毒的路由错误和结构化可观察事件;
- 当获取了沙盒后持久性失败时, 最佳清理.
全权证书仅作为明确的理由提出,而且处于停业状态. 路由器不从环境变量或文件读取提供者密钥. 没错 没有 拥有供应商SDK适配器,秘密存储,计费,计量,REST 处理器、数据库基础设施或云政策. 内存登记册和绘图库是测试/当地参考文献,而不是 生产储存.
过程-显式脚手架也是有意的私人组成逻辑.
它使得有用的节点准备, 安全的历史撕裂, 和证据的闲置
政策明确而不改变公共运行时端口。 见
docs/process-manifest-design.md。 。 。 .
证书-第一入场点支持代托纳,E2B,Vercel,Freestyle,
代理37,并托管Microsandbox通过 @agent-relay/sandbox >=0.1.10。 。 。 .
云已经消耗了路由软件包; 其环境/ 秘密搜索,
快照选择、记录器、安全配置和签名的Microsandbox
桥梁仍然为呼叫者所有.
这是云获取边界的提供者-集合分级器. 这不是一个
机队/节点调度器。 选择请求 fleet,混凝土节点近似,或
没有沙盒被拒绝使用 RoutingNotApplicableError离开工厂
现有车队安放权限和消费者-当地执行未受影响.
控制流量
SandboxRequest
│
├─ validate request and attempt bound
├─ filter provider-declared correctness/trust requirements
├─ resolve request-scoped operational signals for survivors
├─ filter availability and time-to-ready budget
├─ deterministically rank eligible pools
└─ attempt at most N providers
│
├─ SandboxRuntime.launch(...)
├─ allocate sbx_<32 hex>
├─ persist sbx id ↔ labels ↔ provider id ↔ provider sandbox id
└─ return only the Agent Relay id
供应商登记令从不打分;稳定的供应商编号 词典顺序是。 平衡排名将当前符合条件的套件正常化 采用35%的成本、25%的耐久目标、40% 预算范围内的可靠性。 能力从未被探测过 从来没有一个"更多更好"的分数:注册声明,请求 可能要求或禁止,而且路由器相信这些声明.
信誉第一工程
安装 @agent-relay/sandbox-router 财务报告和审定财务报表 @agent-relay/sandbox@^0.1.10附加时
只为你使用的供应商提供SDK. 代顿a的使用 @daytonaio/sdk 内
>=0.180.0 <0.206.0; E2B 用途 e2b 内 >=2.35.0 <3.0.0。沙盒软件包
列出 Vercel、 Freestyle 和 Microsandbox 的可选 SDK 要求.
Agent 37使用其HTTP适配器.
供应商证书准备状态
信任的后端可以提供 provisioning: { hasAvailableCredentials(providerId) }
改为: SandboxRouter 或者说 createSandboxRouter租户/环境范围
端口读取现有的证书准备状态,只返回布尔值。 从来没有
创建账户或返回证书。 账户设置必须在
获取; 省略端口保留了已存在的行为.
两者 provision() 财务报告和审定财务报表 provisionDetached() 排除之前的不可用约束
解决操作信号,排名或读取能力. 抛出错误或
非布尔结果中止以静态获取 ProvisioningAvailabilityError。 。 。 .
准备就绪的全权证书并不意味着具备能力:已启用的能力路径仍然
拒绝未知能力或用尽能力。 准备门新分配;确实
并不妨碍清理已经获得的沙盒.
能力衡量和外溢效应
每个内置注册有一个 CapacityReader.getCapacity() 方法。 打电话
await router.getCapacity() 不创建而读取所有已配置的账户
或启动沙盒。 结果要么是 { status: "known", resources } 或者说
{ status: "unknown", reason }每份资源报告 used, (中文(简体) ), limit, (中文(简体) ), unit, (中文(简体) ),
headroom,以及配置的池中每次发射的分配(required. CPU (中文(简体) )
使用vCPU,内存/磁盘使用MIB,实例配额使用沙盒槽.
启用带有明确命令的许可列表的入境检查 :
const router = createSandboxRouter({
providers: {
daytona: {
apiKey: daytonaKey,
snapshot: snapshotName,
capacity: {
limits: { cpu: 250 }, // This organization's verified cap, not a universal default.
demand: { cpu: 2 }, // Actual allocation of the configured snapshot.
},
},
microsandbox: {
apiKey: microboxKey, image: microboxImage, homeDir: "/root",
capacity: { limits: { sandboxes: verifiedMicroboxSlotLimit } },
},
},
capacity: { providerOrder: ["daytona", "microsandbox"], timeoutMs: 5000 },
});
const measurements = await router.getCapacity(); // Only reads inventory.
路由器应用能力,所需资源,精确 providerId,以及
操作资格,然后使用 providerOrder 取代战略
排行榜. 无法选择未列出的提供者 。 每次发射前都要检查
相对于所配置的分配和请求中较大的新能力
所需经费。 每一个报告的方面都必须适合。 完全,未知,畸形,
失败, 或者超时读取器被跳过, 而无需尝试发射 .
如果没有人有空间, ProviderCapacityExhaustedError 携带代码
PROVIDER_CAPACITY_EXHAUSTED 并进行消毒 UNKNOWN编号 :EXHAUSTED 拒绝.
同样的行为适用于 provisionDetached。确切的提供者制约
永远不要溢出 在提供者之外. acquisitionFallback: "forbidden" 限制
实际发射为1;容量跳过不进行获取.
| 提供者 | 建筑测量 | 需要的呼叫限制 |
|---|---|---|
| 代顿a | 完整的组织清单,汇总于所有州/工作场所 | CPU和/或内存/磁盘,每发射需求匹配;内存/磁盘输入为GiB |
| E2B 软件 | 所提供 API 密钥的分解运行沙盒目录 | 正在运行 sandbox 货币 |
| 微分箱/ 微分箱 | 利用所提供的主机后端,在所有各州编目 | 账户沙盒插槽共计 |
| 特工37号 | 所有各州的账户实例清单 | 账户实例插槽总数 |
| 维塞尔 | 明确 unknown: NOT_SUPPORTED;适配器列表为前缀范围 | 提供自定义的全账户阅读器 |
| 自由风格 | 明确 unknown: NOT_SUPPORTED; 通用计数为占位符 | 提供自定义的全账户阅读器 |
单凭库存不能显示账户配额。 缺少经核实的限制
生产 unknown: LIMIT_NOT_CONFIGURED,决不为零,也不为推算的定价级别
盖. Daytona 在快照需求缺失时也会返回未知. 内容
保守的全态目录和保存了云助语义;
它可能会高估目前保留的计算。 只配置配额尺寸
,因此配置您需要执行的每个限制。 能力是一个
时间点观察,而不是保留:同时呼叫者可以进行比赛,以及
提供者产生失败,保留了现有的认识到结果的回落政策.
读者有5秒的默认截止日期; 读者应取消其
必要时拥有基本信息/操作。 没有共享缓存或证书状态
路由器实例 .
构造器接受自定义 { getCapacity: async () => ... } 在一个
供应商 capacity 用于配额 API 或外置配置的字段
表面 。 自定义阅读器必须报告全账户使用情况和实际启用情况
需求。 关于直接登记建造,请作为附件附上 ProviderDefinition.capacity。 。 。 .
省略路由器级的现有调用器 capacity 保税政策
现有基于战略的路由行为;计量仍然可用.
summarizeDaytonaCapacity 财务报告和审定财务报表 parseDaytonaCapacityLimits 从
云的帮手。 。 。 .
显示摘要保留了警告/临界阈值、组织总数、,
工作空间范围闲置细节、限制出处和 provisioningCheck: "not_covered". 录取使用严格的计量验证,而不是
显示帮助者的数字强制。 另见
代托纳列表 API
财务报告和审定财务报表 E2B 上市合同。 。 。 .
运行 node scripts/verify-capacity-mutations.mjs 证明外溢效应
每个提供者的断言拒绝蓄意的倒退。 跑者用假的
证书和当地定着物,恢复每次变异,并要求
恢复测试通过.
基础建筑
import { createSandboxRouter } from "@agent-relay/sandbox-router";
const router = createSandboxRouter({
providers: {
daytona: {
apiKey: daytonaKey,
createParams: { autoStopInterval: 5, autoDeleteInterval: 0 },
},
e2b: { apiKey: e2bKey },
},
});
const sandbox = await router.provision({
launch: { labels: { requestedBy: "my-application" } },
});
try {
const result = await router.runScript(sandbox.id, { command: "echo hello" });
console.log(result.output);
} finally {
await router.destroy(sandbox.id);
}
createSandboxRouter 是同步的; 提供者适配器和可选 SDKs 负载
第一次行动 返回的路由器扩展 SandboxRouter,与
runScript(id, options) 财务报告和审定财务报表 destroy(id) 通过
存储绘图. destroy 容忍一个已经删除的提供商沙盒.
createProviderRuntime(provider, options) 暴露出同样的证书安全
为保持自己注册的来电者建造运行时间.
| 提供者 | 所需的明确配置 | 意外发生 |
|---|---|---|
| 代顿a | apiKey | API 密码 https://app.daytona.io/api目标 usưμ㼯a /home/daytona |
| E2B 软件 | apiKey | 模板 base |
| 维塞尔 | token, (中文(简体) ), teamId, (中文(简体) ), projectId, (中文(简体) ), defaultHomeDir, (中文(简体) ), namePrefix | 适配器默认值 |
| 自由风格 | apiKey, (中文(简体) ), defaultHomeDir, (中文(简体) ), namePrefix, (中文(简体) ), persistence | 适配器默认值 |
| 特工37号 | apiKey, (中文(简体) ), baseUrl, (中文(简体) ), defaultHomeDir | 适配器默认值 |
| 微软箱 | apiKey, (中文(简体) ), homeDir, (中文(简体) ), image | 主机后端; 可选 url |
在选择自定义快照时, 覆盖代托纳的主目录 。 E2B级
base 模板用于基本工作量;必须为
应用程序特定二进制。 Microsandbox 配置文件和本地执行
而主机-本地快照则不在此证书式第一地表上.
提供者条目也接受 capabilities 财务报告和审定财务报表 signals未明确
元数据,工厂只广告同步执行和文件传输;
资源限制为零,区域/图像/隔离/耐久性索赔为空.
因此,要求拥有这些财产的请求在您宣布之前,将被拒绝
配置了游泳池的信封 。 默认信号是等位占位符,
没有衡量价格、耐久性、可靠性或健康。 供应信号或
resolveRoutingSignals 进行知情的多提供者选择.
映射默认为内存 。 供应 mappings 用于持久、跨进程
身份证明 提供者密钥从不输入映射、可观察事件或
可连续运行的外观。 供应商SDK故障,包括建造,
搜查、执行和销毁 ProviderRuntimeError 仅限
提供者和操作; 原始信件、 堆栈和原因被丢弃 .
此表面的失败分类器接收到已消毒的错误, 所以它必须
而不是从缺失的提供者细节中推断出一个安全重试。 采购失败中止
结果- 默认未知和终端.
原画 new SandboxRouter({ registry, mappings, ... }) 财务报告和审定财务报表
routeProviders(request, providers) 签名保持不变。 明确
运行时路径仍然支持呼叫者拥有的适配器和提供者错误分类器.
登记和供应
import {
InMemoryProviderRegistry,
SandboxRouter,
asProviderId,
} from "@agent-relay/sandbox-router";
const registry = new InMemoryProviderRegistry([
{
id: asProviderId("primary-eu"),
runtime: externallyConstructedRuntime,
capabilities: externallyDeclaredCapabilities,
signals: {
estimatedCost: 0.12,
coldStartLatencyMs: 850,
readyLatencyMs: 12_000,
completionWithinBudgetRate: 0.999,
available: true,
},
},
]);
const router = new SandboxRouter({
registry,
mappings: durableMappingStore,
observer: structuredEventSink,
classifyProviderFailure: (error, provider) => {
if (isProvenPreAllocationCapacityFailure(error, provider)) {
return { code: "PROVIDER_CAPACITY_PRE_ALLOCATION", retryable: true };
}
return { code: "PROVIDER_LAUNCH_OUTCOME_UNKNOWN", retryable: false };
},
});
const sandbox = await router.provision({
resources: { cpu: 4, memoryMb: 8192 },
requires: {
requiredCapabilities: ["pty", "publicPorts"],
forbiddenCapabilities: ["nestedUserNamespaces"],
image: { identity: "agent-v4", requiredBinaries: ["node"] },
timeout: {
semantics: ["command-lifetime"],
maxReadyLatencyMs: 30_000,
requiredSandboxLifetimeMs: 30 * 60_000,
completionBudgetMs: 1_800_000,
},
},
region: { preferred: ["eu-west"], required: true },
routing: {
strategy: "balanced",
latencyObjective: "ready",
acquisitionFallback: "allowed",
maxAcquisitionAttempts: 3,
},
});
运行时间建设是有意的外部. 所配置的运行时间可能持有 其供应商内部授权,但证书从未输入供应商 定义、请求、路由事件、绘图或路由器出错.
最大沙盒寿命是正确性的制约,而不是排名信号.
每个注册人才库可申报 capabilities.timeout.maxSandboxLifetimeMs
在运行时间后面的供应商账户。 有限价值是包容性的
上限; null 明确表示无约束;省略表示账户限额
不详。 当有需要时
requires.timeout.requiredSandboxLifetimeMs,未知且池子不足
以 SANDBOX_LIFETIME 在排名或获取之前。 请求
寿命要求与登记保持后向兼容
略去声明.
这一例子中的分类者代表呼叫者拥有的提供者知识;
isProvenPreAllocationCapacityFailure 只能当提供者返回真实
保证没有进行分配。 监视分类器比较安全:所有
发射失败是默认的终端.
路由-信号接合
ProviderRoutingSignals 是可比较的选择输入,而不是收费或使用
记录. estimatedCost 指相关购置的预期成本,
时 coldStartLatencyMs 财务报告和审定财务报表 readyLatencyMs 故意分离 SDK
根据实际工作量准备情况作出反应. completionWithinBudgetRate 计数
挂起为失败, 而不是只将返回的错误视为不可靠 。 打电话的人可以提供
resolveRoutingSignals(provider, request) 将身体健康或自身健康纳入其中
工作量知识——例如,寒冷获得加破坏乘以
预期的步数。 解决者不计费和计量.
安置、后退和身份护栏
- 后退只存在于内部
provision在任何执行、租赁或状态 操作。 证书- 第一执行路径解决原始提供者 绘制地图,永远不改变居民工作路线。 租赁/居民电话acquisitionFallback: "forbidden"。 。 。 . acquisitionFallback: "allowed"尝试限制不会发射 可重试错误 。 向另一供应商推进还需要 明确调用者分类器返回retryable: true对于一个狭隘的证明 预分配失败, 如创建前拒绝提供者容量 .- 提供者的能力是申报的,而不是从方法的存在中推断出来的。 这个 词汇包括图像/ 二进制身份、 egress 类、超时语义 和颗粒性、提供者-账户寿命、状态耐久性、端口/尾网、, 长期进程/PID/PTY/启动需求、未处理的入学问题 要求的限制.
sbx_…是一个独立提供者的定位器,而不是工作量身份。 它共存 带有标签。 长期国家领导身份,工厂invocationId和 PID 数据 tuple 仍然属于其现有生命周期系统所有,没有被替换.placement.authority: "none" | "fleet"财务报告和审定财务报表nodeAffinity明确绕行 提供者的路由;这个库从未成为第二舰队调度器.
失败的语义
- 要求或可用性故障从不要求提供者.
- 通用或未分类的发射故障是未知结果和最终结果 默认, 因为一个提供者在丢弃前可能已经远程分配 .
- 只有呼叫者提供的分类器才能通过返回来授权回落
retryable: true; 呼叫者必须将其保留在经过严格验证的预分配中 失败。 可重试的失败只会推进到收购尝试被约束. - 分类器只显示消毒代码;终端故障上升
ProviderProvisioningError并释放出一个尝试失败的事件retryable: false。 。 。 . - 原始提供者出错信息不会被发送或复制到已耗尽的数据中.
- 获取后映射存储失败不是提供者失败:路由器 试图摧毁沙盒, 显示清理是否成功, 并停止.
- 观察失败从来不影响选择、获取回落或供给.
公用基数缺口( 未在此复制)
这些属于 @agent-relay/sandbox 或在必要时其提供者适配器:
- 便携式发射要求:
SandboxRuntime.launch仅接受 名称/env/标签/超时,而不是资源、区域或孤立。 因此,V1级 使用 它不注入不支持的字段。 通过 创建供应商过程中的可移植要求需要一项公共港口决定. - 部分分配清理:
SandboxRuntime.launch只返回一个控点 在成功方面。 如果适配器远程分配然后扔出,则路由器有 没有清理手柄。 该案的漏损安全恢复必须受到 适配器或添加到公共端口. 因此,路由器处理a 未分类的发射例外作为终端,而不是风险重复 通过自动后退分配. - 可移植声明的能力词汇 : 公共外部运行时间 描述符包含一些操作方法,而不是图像身份,二进制, egress, 超时语义学, 提供者-账户寿命, 状态耐用性, 信任限制、区域、资源、网络或GPU信封。 商业登记处拥有这些 提供商声明 不得通过探测器加以实施; 目前但不能使用的方法已经证明这种推论不安全.
- 可选对等声明表面 : 公共一揽子声明
参考戴托纳对等类型,即使对于一个没有适配器的纯类型消费者.
此软件包使用
skipLibCheck;公共基础应隔离可选 供应商声明导入.
发展
需要20号或更新的节点.
npm install
npm run build
npm run typecheck
npm test
行为测试被命名为"必须开火/必须开火的对" 所以两个触发器都是 其戒备是明显的。 软件包是私有的,没有出版脚本.
证书式的第一个回归证明可以复制
node scripts/verify-tenant0-mutations.mjs它暂时变异并恢复
源, 声明每个负控失败, 然后运行干净的回归套件 .
在不同时编辑源码的情况下运行它 .
选入现场证明是 npm run build 接下来是
node scripts/prove-tenant0-daytona.mjs它读取代顿纳证书来自
~/Projects/AgentWorkforce/cloud/.env 在使用时,规定
沙盒,验证命令stdout,摧毁它,并审计其独特的标签.
它只写了一张经消毒的笔录 .workflow-artifacts/tenant0-0906/。 。 。 .