NemoClaw 的 OpenShell 只读导出适配层:配置导出读取与沙箱文件传输的完整实现解析
【免费下载链接】NemoClawRun agents like Hermes, LangChain Deep Agents, and OpenClaw more securely inside NVIDIA OpenShell with managed inference项目地址https://gitcode.com/gh_mirrors/ne/NemoClaw点击查看免费下载导读NemoClaw 在运行 Hermes、LangChain Deep Agents、OpenClaw 等 Agent 时需要安全地读取 OpenShell 网关中的 Provider、沙箱、配置与推理路由等只读状态用于配置导出、健康检查与生命周期管理。本文基于 src/lib/adapters/openshell/README.md 及其配套源码系统拆解这套只读导出适配层的读取矩阵、SDK 连接与校验契约、Provider/策略的资格认定逻辑以及用户文件传输的中断语义帮助读者理解 NemoClaw 如何在不暴露凭据、不引入第二套凭据加载器的前提下从 OpenShell 网关安全导出配置。适配层定位基于能力边界的只读导出OpenShell 导出适配层位于 src/lib/adapters/openshell/它是一组只读的配置导出能力配置导出使用 #9802 中定义的能力边界其只读新增部分归属 issue #10938 与 PR #11065这些能力并不完成该 epic 中的全部能力迁移capability migrations。也就是说这层适配器只负责读路由变更、回滚等写操作明确留在观察者之外。这种边界设计保证了配置导出永远不触发网关状态变更符合read-only的一贯约束仓库中另有 read-only-config.mts 与 read-only-fixer.py 等配套检查。读取矩阵五类只读能力与归属README 用一张表格明确了五种读取能力各自的所有者Owner、传输方式与理由这是理解适配层的关键索引原样继承如下读取内容所属模块传输方式与理由Provider 端点与身份endpoint and identityproviders.ts使用 SDKraw.getProvider以及raw.getProviderProfile用于无覆盖的原生 NVIDIA 推理、以及被请求的 managed Brave/OpenAI 契约锁定版本的 SDK 没有经过整理的网关 Provider 读取能力。复用provider-adapter.ts#9806、#9825中的元数据字段。沙箱身份、镜像与附件identity, image, attachmentssandboxes.ts使用 SDKraw.getSandbox经过整理的sandbox.get会遗漏 workspace、镜像与生效策略版本。配置身份与生效策略configuration identity and effective policysandbox-config.ts使用 SDKraw.getSandboxConfig通过已验证的 ID 一次响应同时返回两者经过整理的sandbox.getConfig会做一次新的名称查找且遗漏 workspace。面向其他消费方的策略读取仍归属 #9805 与 #9826。推理路由inference routeinference-route-cli.ts通过 #9809 的类型化观察契约typed observation contract进行 CLI 读取要求显式网关。生成的推理客户端generated inference client仍归属 #9828。托管工作负载与网关归属managed workload and gateway ownershipNemoClaw 注册表与网关状态这是 NemoClaw 自身的 provenance溯源信息不属于 OpenShell 资源字段。选择原则很明确当一个经过整理的 SDK 方法能够保留其消费方所需的全部字段与作用域时就优先使用它否则回退到 raw 客户端。而 raw 客户端与生成消息的生产访问必须始终留在本目录内。SDK 连接与预检sdk.ts 的安全建立SDK 连接在 sdk.ts 中建立与沙箱执行共享同一连接sdk.ts并保留三项既有约束受管状态根目录检查连接前通过resolveGatewayStateDirForPort解析网关状态目录并调用managedGatewayStateRootOwnershipFailure校验目录归属默认端口根目录沿用旧版权威边界owner-only 目录检查 本地 mTLS 身份显式覆盖NEMOCLAW_OPENSHELL_GATEWAY_STATE_DIR则必须携带显式 marker否则直接抛错。显式 loopback 网关gatewayPort()要求目标必须是命名网关namednemoclaw使用默认端口nemoclaw-port形式支持显式端口1–65535且不允许等于默认端口SDK 连接字符串固定为https://127.0.0.1:port。有界的本地 mTLS 文件读取从状态目录的tls/下读取ca.crt、client/tls.crt、client/tls.key每个 PEM 文件最大读取 1 MiBMAX_PEM_BYTES 1024 * 1024并通过openRegularFileNoFollow以不跟随符号链接的方式打开防止路径逃逸。因此不需要第二个凭据加载器——凭据就是网关状态目录中的本地 mTLS 材料连接目标始终是显式命名的本机网关。ESM 导入边界sdk-import.mtssrc/lib/adapters/openshell/sdk-import.mts 解决了一个构建层面的实际问题当 CLI 编译为 CommonJS 时nvidia/openshell-sdk只暴露 import-only 的包条件package conditions因此必须把 SDK 的公开入口放在原生 ESM 导入之后。关键实现细节连接importOpenShellSdk与策略序列化importOpenShellRawSdk用于SandboxPolicySchema都走这个惰性边界该桥接模块没有顶层 await因此受支持的 Node 运行时可以在 CommonJS 中加载其产出的.mjs编译后的包测试用 import-only SDK fixture 覆盖这两个消费方SDK 安装与网关资格认定gateway qualification保持独立。统一读取契约sdk-read.ts 的调用约定与错误分类src/lib/adapters/openshell/sdk-read.ts 定义了所有 SDK 读取的公共约束必须显式提供网关目标named、workspace、abort signal三者缺一不可ReadRequest只有确认的 not-found 才返回nullisNotFound通过错误码code 5判定其他失败一律走既有沙箱错误分类authentication/timeout/transport/schema并返回固定消息SDK 失败后没有 CLI 回退错误分类映射code 7/16/permission_denied/unauthenticated→ authenticationcode 4/deadline_exceeded→ timeout其余 → transport资源版本保持十进制字符串metadata()使用String(meta.resourceVersion)输出避免 uint64 精度丢失超时与中断readOpenShell用Promise.race把操作与 abort 死线竞争abort 到达统一返回 timeout 错误且不暴露传输细节或响应数据。TypeBox 模式校验sdk-read-schema.tssrc/lib/adapters/openshell/sdk-read-schema.ts 定义了被消费响应字段的 TypeBox 模式遵循四条规则先校验再投影validate before projectionreadValue()先跑Check(schema, value)不通过即抛OpenShellReadError(schema)凭据值保持不透明OpaqueMapSchema只校验值是普通对象原型为Object.prototype或null不深入校验内部字段Provider 的credentials、credentialHandles、config都走该模式响应身份必须与请求比对metadata()校验响应的name、workspace与请求一致否则判为 schema 错误模式失败使用固定消息不含被拒绝的值OpenShellReadError的消息为OpenShell read failed (kind).不会把原始响应带出。版本字段VersionSchema接受 BigInt 或十进制字符串值域为0..18446744073709551615uint64 全量。ReadTextSchema还保持 SDK reader 的 UTF-16 限制最大 4096 字符按 grapheme 计。Provider 读取与托管 Profile 资格认定providers.tsproviders.ts 实现了 Provider 读取。由于锁定版本的 SDK 没有经过整理的网关 Provider 读取方法这里直接使用raw.getProvider返回的 Provider 包含id、name、workspace、resourceVersion、type、凭据键名来自credentials与credentialHandles的并集排序去重、config 键与请求的非机密配置值。Provider 读取不会返回凭据值——只返回凭据名称与请求的非机密配置值。这保证了导出内容可安全落盘。原生 NVIDIA 托管推理的内建 Profile 派生当 Provider 类型为nvidia、profileWorkspace为空且没有任何配置覆盖时导出会额外读取raw.getProviderProfile要求内建nvidiaprofile静态作用域scope 为空字符串资源版本为 0BigInt(resourceVersion) 0n具备推理能力inferenceCapable: true唯一端点integrate.api.nvidia.com:443。锁定版本的 OpenShell 原生解析器在该主机上使用/v1导出把内建 profile 记录为端点证据BUILD_ENDPOINT_URL。自定义 profile、profile 作用域变更以及 Provider 配置覆盖都不能使用这种派生。Brave / OpenAI 托管 Profile 契约消费方可通过profileContract: brave或openai请求托管 Profile 资格认定读取器在 Provider 的profileWorkspace上通过同一网关解析raw.getProviderProfileBrave onboarding 在defaultworkspace 导入其检入的 profile用户 profile 必须非零资源版本且作用域与其绑定匹配内建 profile 必须全局绑定、空作用域、版本 0——仅名字匹配是不够的validateManagedProfileResponse会比对[scope, workspace, version0]三元组。资格认定的硬性要求包括检入的凭据声明、端点规则、二进制白名单与推理能力Brave允许其单个 header 凭据x-subscription-token来自BRAVE_API_KEY与搜索端点api.search.brave.com:443二进制白名单仅含node与curlOpenAI要求无端点的推理契约inferenceCapable: truecredentials/endpoints/binaries 均为空。凭据刷新、token grant、发现discovery、变更的重写规则以及 profile 语义消息中的未知 protobuf 字段都会导致资格认定失败。Provider 凭据值与句柄保持不透明。读取器返回 profile 身份、来源、作用域、资源版本与绑定纳入完整导出观测绑定或 profile 版本一旦变化观测不一致就会阻止发布。未请求该资格认定的托管消费方保留原有端点语义。OpenAI 无 Profile 场景固定版本的 OpenAI Provider 类型也可以不存在 profile在其全局或同 workspace 绑定处读到确认的 not-found 时返回managedProfile: null。Ollama 导出接受该证据而 managed vLLM 仍要求合格 profile其他读取失败保持终止性terminal。Sandbox 与配置身份读取sandboxes.tssandboxes.ts 使用raw.getSandbox因为经过整理的sandbox.get()会遗漏 workspace、模板镜像与生效策略版本。返回的 Sandbox 包含id、name、workspace、resourceVersion、status.currentPolicyVersion、spec.template.image与排序后的spec.providers。沙箱读取不返回环境变量值。sandbox-config.tssandbox-config.ts 使用raw.getSandboxConfig({ sandboxId })一次响应同时返回配置身份与生效策略校验响应中的workspace与请求一致否则判 schema 错误返回revision配置版本、policyHash、configRevision、providerEnvRevision、policySource1 sandbox2 global与globalPolicyVersion生效策略版本appliedRevision当policySource 2且globalPolicyVersion 0时取全局策略版本否则取沙箱配置版本。配置读取返回修订元数据与不含凭据的生效策略文档且不返回 settings 值。策略导出与转换serializeSdkPolicy配置读取中的策略序列化由 sandbox-config.ts 的serializeSdkPolicy完成其流程严格按顺序执行检查取消信号signal.throwIfAborted()惰性加载nvidia/openshell-sdk/raw的SandboxPolicySchema与bufbuild/protobufisMessage(policy, SandboxPolicySchema)校验消息类型toBinary序列化后检查大小超过 1 MiB 拒绝MAX_POLICY_BYTESrejectUnknownWireFields递归拒绝$unknown非空的消息——未知 protobuf 字段被拒绝而非忽略toJsonuseProtoFieldName: true转 JSON 后经sdkPolicyDocument转换为文档形态sortCanonicalMappings规范化键序YAML.stringify输出再次检查序列化文档大小与无凭据isSandboxPolicyCredentialFree任一不满足即抛 schema 错误。策略转换遵循已审阅的 OpenShell 发布语义filesystem 默认值filesystem_policy显式补上include_workdir: false默认值紧凑端口单端口ports收敛为port多端口保留portsquery/params 匹配器把扁平键还原为嵌套树nestedParamsMCP 场景下name参数映射为tooltools/call与allow_all_known_mcp_methods组合时省略methodMCP 选择器mcp协议的端点把json_rpc_max_body_bytes映射为mcp.max_body_bytes非 MCP 端点映射为json_rpc.max_body_bytesProvider 组合规则rules/deny_rules经convertMatcher转换binaries收敛为{ path }。全局策略修订的优先级与policy get --full一致但导出仍然要求全局修订与观测到的沙箱与配置修订一致见下节双观测一致性。另外注意OpenShell SDK 0.0.116 不暴露传输接收大小选项transport receive-size option因此策略大小只能靠导出侧 1 MiB 上限约束该上限同时适用于 SDK 消息与序列化后的 YAML。推理路由观察inference-route.ts 与 CLI 适配inference-route.ts 定义了两种观测形态configured携带provider与model的路由provider 最长 128 字符、匹配^[A-Za-z0-9._:-]$model 最长 512 字符且通过isSafeModelIdunconfigured未配置路由。错误被分为四类、每类带具体 reasonkindreasonauthentication/timeout/validation—消息直接给出schemamalformed_output/partial_route/protocol_mismatchtransportidentity_mismatch/process_start/unreachablecommandfailed/indeterminate/invalid_requestinference-route-cli.ts 是 CLI 适配器职责包括参数构造与网关作用域校验scopeGatewayOpenshellArgs禁止网关端点覆盖ANSI 与控制序列剥离cleanTerminalText依次移除 OSC、字符串转义、CSI 与 C0/C1 控制字符解析与超时默认DEFAULT_TIMEOUT_MS 15_000捕获上限 1 MiB命令错误映射ENOENT/EACCES →process_startETIMEDOUT → timeoutinvalid wire type|proto…→protocol_mismatch认证关键字authentication failed、missing gateway auth token、device identity required等→ authenticationhandshake verification failed→ transport 类命名网关读取保持作用域化当 OpenShell 拒绝该作用域时观察者返回错误不重试未授权的作用域读取。推理路由的变更与回滚明确留在该观察者之外。双观测一致性导出必须两侧一致配置导出会比较两次完整的观测two complete observations并且当状态变化时可以把同一对观测重复一次repeat that pair onceProvider 读取保留完整的 config 键清单以便导出拒绝不受支持的配置导出要求观测到的沙箱修订、配置修订与全局策略修订三方一致绑定binding或 profile 修订一旦变化观测不一致即阻止发布。这套机制保证了导出物来自同一时间点的一致状态避免读到跨修订的混杂视图。managed-provider-adapter.ts 的边界受管重建恢复、快照克隆的 Provider 检查、Profile 导入与创建使用 managed-provider-adapter.ts它把类型化 CLI 适配器绑定到所选网关。而 Provider 解绑detachment、删除、替换清理等生命周期操作保留既有适配器直到 #9806 剩余的迁移切片落地这不宣称这些操作已获得 SDK 资格认定。用户文件传输sandbox-transfer.ts 与 CLI 适配README 的第二部分描述了用户文件传输契约对应 #9810 的公共命令契约定义sandbox-transfer.tssrc/lib/adapters/openshell/sandbox-transfer.ts 定义异步上传/下载契约type OpenShellSandboxTransferRequest Readonly{ direction: upload | download; sandboxName: string; target: OpenShellGatewayTarget; // 显式命名网关 source: string; destination: string; output?: inherit | suppress; // 默认继承传输输出凭据读取可抑制 };结果分类OpenShellSandboxTransferOutcomecompleted携带退出码failedreason 为invalid_request/unavailable/invocation/interrupted/indeterminate之一。完成对象OpenShellSandboxTransferCompletion包含outcome、wasInterrupted()与release()其中命令完成并不验证产物或发布下载——验证与发布是动作action层的职责传输完成等待子进程关闭child close命令退出码非零也算完成而退出码为零也不证明下载产物存在。CLI 适配与中断语义sandbox-transfer-cli.tssandbox-transfer-cli.ts 负责 CLI 参数、网关目标、环境过滤与进程监督保留继承的 stdin/stdout/stderr包括既有的机器输出重定向类型化结果不包含原始子进程错误或输出继承的 OpenShell 诊断信息保持不变该适配器不做过滤动作action保留既有的源校验 → 私有暂存staging→ 产物校验 → 发布 → 清理 完整链路传输没有固定超时源探测source probes保留其既有超时通过带缓冲的命令执行器buffered command executor执行。中断处理铁律调用方必须遵循以下时序否则可能发布不完整产物持有完成对象直到暂存清理与外部生命周期锁outer lifecycle lock稳定在finally中调用release()在发布之前与返回成功之前都要检查wasInterrupted()——因为中断可能在传输后校验或锁释放期间到达不要重试已中断或状态不确定indeterminate的传输。总结NemoClaw 的 OpenShell 只读导出适配层是一套以安全、只读、可验证为原则的网关读取体系读取矩阵清晰Provider / Sandbox / Config / Inference Route / Managed Ownership 五类读取各有明确归属与传输方式连接安全闭环显式命名网关 本地 mTLS 有界 PEM 读取 状态目录归属检查不引入第二套凭据加载器校验贯穿始终TypeBox 先校验再投影、凭据不透明、身份比对、未知 protobuf 字段拒绝、1 MiB 策略上限资格认定严格内建 NVIDIA profile 派生、Brave/OpenAI 托管 Profile 契约都有硬性字段约束导出一致性保障双观测一致 单次重试配对 三方修订一致传输中断安全wasInterrupted()检查、release()时序与不重试不确定传输的纪律。需要深入阅读实现细节的读者可以从 sdk.ts、sdk-read.ts、sdk-read-schema.ts、providers.ts、sandbox-config.ts 与 sandbox-transfer.ts 入手再结合同目录下各*.test.ts如 providers.test.ts、sandbox-transfer-cli.test.ts、provider-profile.test.ts对照验证行为边界。赞分享【免费下载链接】NemoClawRun agents like Hermes, LangChain Deep Agents, and OpenClaw more securely inside NVIDIA OpenShell with managed inference项目地址https://gitcode.com/gh_mirrors/ne/NemoClaw点击查看免费下载相关推荐NemoClaw PR Review Advisor 技术指南在 OpenShell 沙箱中构建 SDK 驱动的只读 PR 审查流水线NemoClaw PR Review Advisor 技术指南在 OpenShell 沙箱中构建 SDK 驱动的只读 PR 审查流水线 本文深入解析 NemoNemoClaw 适配器层Adapters深度解析如何隔离进程、文件系统与 OpenShell 主机边界NemoClaw 适配器层Adapters深度解析如何隔离进程、文件系统与 OpenShell 主机边界 导读 本文围绕 NemoClaw 开源仓库中 sNocoBase 导出操作详解从界面配置到 xlsx 流式导出的完整实现NocoBase 导出操作详解从界面配置到 xlsx 流式导出的完整实现 本篇围绕 NocoBase 界面搭建中的「导出操作」 nocobase/plug低代码后端前端人工智能AI 应用工作流自动化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考