agent-virtualization
v0.1.3
Published
Capability-constrained runtime virtualization for autonomous CLI agents
Maintainers
Readme
Agent Virtualization
一个独立、通用、宿主可控的 CLI Agent 运行时虚拟化包。它保留 Claude Code、Codex 等 CLI Agent 自己的推理和工具循环,同时把可执行动作限制在宿主当前声明的 Action Space 中。
本包不依赖任何特定编排框架。宿主既可以直接使用程序化 API,也可以通过模型提供方协议把本地 CLI Agent 暴露为可选模型,或通过 ACP 把它作为独立 Agent transport 使用。
执行所有权
编排宿主始终拥有外层执行链路:
用户输入 → Inbox → Agent Loop → 动态组装 Context/Tools → LLM
→ Tool Scheduler → Tool Result → 回填 Session → 下一 Step → 直到 Turn 结束选择虚拟化模型时,LLM 这个节点由可暂停、可恢复的 CLI Agent 进程实现:
Host LLM Step
└─ model.run(Context + 当前 Tools + Workspace)
└─ Agent Virtualization
└─ CLI Agent 自有 loop
├─ 普通输出 ────────────────> model.result
└─ 请求工具 ──> tool.call(CLI 暂停)
│
Host <────────── 标准 LLM tool-call ──────────┘
└─ Tool Scheduler 执行并写入 Session
└─ 下一 Step 发送 tool.result
└─ 恢复同一 CLI Agent loop因此 CLI Agent 可以在一次任务内保持自己的规划、上下文和 agent loop,但每个工具调用仍由宿主调度、记录并推进外层 Step。CLI Agent 完成后,其输出作为当前宿主 Turn 的模型结果返回,不形成第二套顶层执行链。
已实现
AgentVirtualization.run(runtime, task, environment)返回可取消的AsyncIterable<AgentEvent>,并提供最终result。agent-virtualization model --config ...提供持久 NDJSON 模型桥;工具调用期间进程保持存活。- 四层控制:Prompt 指令、Tool Exposure、逐次校验的 Tool Gateway、OS Sandbox。
- capability 注册、JSON Schema 参数校验、deny-first 参数级策略、审批与 JSONL 审计。
- 动态 capability 申请;无法热更新工具的 CLI 会以状态摘要重启,工作区状态保持不变。
- Claude Code:原生 CLI + 本地登录凭据 + 严格 MCP 配置 + 鉴权 Unix Socket 代理。
- Codex:原生
app-server --stdio+dynamicTools回调。 - 任意 CLI:最小双向 JSONL adapter。
- macOS Seatbelt、Linux Bubblewrap,以及用于外层已有隔离的显式 No-op provider。
- ACP server 作为通用的可选 client transport,适合需要 child-agent 语义的宿主。
安装与构建
pnpm install
pnpm run check运行独立示例:
pnpm run build
node dist/cli/bin.js run --config examples/generic-jsonl.json --workspace "$PWD" -- "write a proof"发布包的典型用法:
npm install agent-virtualization
agent-virtualization run --config ./agent-virtualization.json -- "完成任务"宿主集成
agent-virtualization model --config <file> 暴露一个稳定的 NDJSON stdio 边界。宿主 adapter 负责把自己的 Context 和精确 Tool catalog 写入 model.run,把 tool.call 转换为宿主原生模型工具调用,再在工具调度与持久化完成后用 tool.result 恢复同一 CLI 进程。完整消息定义见模型提供方协议。
框架专属 adapter 应作为独立包维护;本仓库只拥有通用 runtime、协议和安全边界。
程序化 API
import {
AgentVirtualization,
CapabilityRegistry,
CodexRuntime,
LocalSandboxProvider,
RuntimeRegistry,
} from 'agent-virtualization'
import { nodeCapabilities } from 'agent-virtualization/capabilities/node'
const capabilities = new CapabilityRegistry()
for (const capability of nodeCapabilities) capabilities.register(capability)
const runtimes = new RuntimeRegistry()
runtimes.register(new CodexRuntime({ inheritHostCredentials: true }))
const virtualization = new AgentVirtualization({
capabilities,
runtimes,
sandbox: new LocalSandboxProvider(),
})
const run = virtualization.run('codex', '更新 README', {
capabilities: ['read_file', 'search_files', 'write_file'],
workspace: { root: process.cwd(), writableRoots: [process.cwd()] },
sandbox: { mode: 'workspace-write', network: 'inherit', requireEnforcement: true },
policy: {
rules: [
{ capability: 'read_file', decision: 'allow' },
{ capability: 'search_files', decision: 'allow' },
{
capability: 'write_file',
decision: 'approve',
constraints: [{ kind: 'path', argument: 'path', roots: ['$workspace'] }],
},
],
},
})
for await (const event of run) console.log(event)
const result = await run.result配置与安全边界
可直接使用 Codex 配置、Claude Code 配置 或 通用 JSONL 配置。配置文件可以加载明确声明的 ESM capability module;模块导出 capabilities 数组,或默认导出 (registry) => disposer 注册函数。
配置默认使用本地 OS sandbox。只有外层宿主已经提供等价隔离时,才可显式设置 "sandboxProvider": { "type": "noop", "reason": "..." };空原因会使加载失败,且 environment.sandbox.requireEnforcement: true 仍会拒绝 No-op provider。
Claude Code、Codex 作为模型运行时需要访问各自的模型服务,因此示例使用 network: "inherit"。Claude Code 通过显式的 homeMode: "inherit" 读取本地登录;Codex 使用 inheritHostCredentials: true,只把宿主 auth.json 复制到本轮私有、可写且结束即删除的 CODEX_HOME,不会写入真实 ~/.codex。可见动作继续由宿主注入的 Action Space、Gateway policy 和文件写入沙箱控制。若通过 API key、企业代理或外层策略提供认证与网络,可按部署环境收紧这些选项。
- 未进入当前
environment.capabilities的动作不可见且不可执行。 - 未命中 allow/approve 策略的调用默认拒绝。
- 模型提供方模式以宿主当前传入的 tools 覆盖配置中的可见 Action Space,并默认关闭 capability escalation。
- CLI 环境变量使用白名单继承,不自动传递 API key 或云凭据。
- 内置文件能力拒绝越界路径与符号链接写入;最终隔离仍由 Seatbelt、Bubblewrap 或外层容器承担。
NoopSandboxProvider只用于宿主已经提供隔离的场景;requireEnforcement: true会拒绝它。
详细设计见 架构、安全模型、模型提供方协议 和 Generic JSONL 协议。
本项目目前为 0.1.0,API、协议与 CLI adapter 仍处于早期阶段。
开发与发布
仓库分支与发布流程沿用 hsu-ui 的约定:功能分支合入 develop,仅允许
develop 合入 main;main 发布当前大版本,<major>.x 用于旧大版本维护。
CI 会在 Node.js 22.19 和 24 上执行 pnpm run check。发布前需在 GitHub
Actions 中配置 NPM_TOKEN,版本号对应的 npm 版本和 Git tag 已存在时会安全跳过。
