Umans AI Coding Plan 接入 opencodex:Anthropic 兼容 key-login Provider 的注册、元数据保留与工具名转义全解析

发布时间:2026/9/23 4:52:33

Umans AI Coding Plan 接入 opencodex:Anthropic 兼容 key-login Provider 的注册、元数据保留与工具名转义全解析 【免费下载链接】opencodexUniversal provider proxy for OpenAI Codex Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code项目地址https://gitcode.com/gh_mirrors/ope/opencodex点击查看免费下载导读opencodex 是一个通用的 Provider 代理Universal provider proxy允许 Codex CLI、Codex App、SDK 以及 Claude Code 通过统一入口使用 Claude、Gemini、Grok、DeepSeek 等任意 LLM 服务。本篇以开发日志 devlog/_fin/241_umans-provider-cleanup/00_note.md 为骨架完整还原将 Umans AI Coding Plan 接入为 key-login 型 Anthropic 兼容 Provider这一工作包括 Provider 注册条目、模型种子数据、key-login 保存时的运行时元数据保留、以 Anthropic Messages API 形态校验 API Key以及为网关转义内置工具名cx_前缀并在回传前剥离前缀。读完本文你将掌握在 opencodex 中新增/理解一个 Anthropic 兼容 key-login Provider 所需的全部配置要点与底层实现路径。背景PR #14/#19 合并审计中的工作树清理该开发日志记录了一个典型的工程实践场景在PR #14/#19 本地开发合并停机审计local dev merge stop audit过程中工作树里出现了一个与本次合并无关的Umans provider 半成品WIP。虽然 PR #14/#19 的提交本身已经过验证但脏工作树dirty tree意味着 dev 分支尚未为后续的 main 合并决策做好准备——这正是把 Umans 相关的零散改动整理成一个独立、可验证、可合入单元的直接动因。该工作的范围被明确界定为五件事将Umans AI Coding Plan添加为 key-login 型 Anthropic 兼容 Provider在保存 API-key 登录时保留 Provider 运行时元数据模型列表、上下文窗口、输入模态、推理档位、无视觉模型列表等以Anthropic Messages API 形态而非/models列表探测校验 Anthropic 兼容 API Key对需要该能力的网关转义内置工具名并在将工具调用返回给 Codex 前剥离前缀在 README 与 docs-site 各语言文档页中记录新增的 Provider/配置标志。以下各节将逐一对应源码展开。Provider 注册条目Umans 在目录中的完整声明Umans AI Coding Plan 的注册条目位于 src/providers/registry/entries-core.ts{ id: umans, label: Umans AI Coding Plan, adapter: anthropic, baseUrl: https://api.code.umans.ai, authKind: key, featured: true, dashboardUrl: https://app.umans.ai/billing, defaultModel: umans-coder, models: UMANS_MODELS, modelContextWindows: UMANS_MODEL_CONTEXT_WINDOWS, modelInputModalities: UMANS_MODEL_INPUT_MODALITIES, note: Coding plan via Anthropic Messages, modelReasoningEfforts: { umans-coder: UMANS_REASONING_EFFORTS, umans-kimi-k2.7: UMANS_REASONING_EFFORTS, umans-flash: UMANS_REASONING_EFFORTS, umans-glm-5.3: UMANS_GLM_53_REASONING_EFFORTS, umans-glm-5.3-flash: UMANS_GLM_53_REASONING_EFFORTS, umans-glm-5.2: UMANS_GLM_REASONING_EFFORTS, umans-glm-5.1: UMANS_GLM_REASONING_EFFORTS, umans-qwen3.6-35b-a3b: UMANS_REASONING_EFFORTS, }, noVisionModels: UMANS_TEXT_ONLY_MODELS, escapeBuiltinToolNames: true, },逐字段解读字段值含义adapteranthropic走 Anthropic Messages 适配器上游端点按/v1/messages处理authKindkeykey-login 型 Provider通过粘贴 API Key 登录而非 OAuth 设备码流程featuredtrue在 GUI Add provider 选择器中置顶展示defaultModelumans-coder默认模型同时作为 API Key 校验时探测的模型baseUrlhttps://api.code.umans.aiUmans 网关地址docs-site 的 provider 汇总表也收录了该地址见 docs-site/src/content/docs/guides/providers.mddashboardUrlhttps://app.umans.ai/billing用量/账单控制台escapeBuiltinToolNamestrue触发内置工具名转义逻辑详见下文工具名转义一节注意modelReasoningEfforts是按模型配置的GLM 家族与 Kimi/通用模型使用不同的推理档位集合说明网关对同系列不同模型开放的reasoning effort档位并不一致——注册时不能一刀切。模型种子数据Umans 的完整模型目录Umans 的模型清单与元数据集中在 src/providers/registry/model-seeds.tsexport const UMANS_MODELS [ umans-coder, umans-kimi-k2.7, umans-flash, umans-glm-5.3, umans-glm-5.3-flash, umans-glm-5.2, umans-glm-5.1, umans-qwen3.6-35b-a3b, ]; export const UMANS_REASONING_EFFORTS [low, medium, high, xhigh, max]; export const UMANS_GLM_REASONING_EFFORTS [high, xhigh, max]; // 260814: Z.AI folds GLM-5.3 efforts into low/high/maxlow 是真实档位xhigh 与 max 不区分 export const UMANS_GLM_53_REASONING_EFFORTS [low, high, max]; // umans-glm-5.3-flash 不在此列Z.AI 将其列为 VLM 文档原生支持图像 export const UMANS_TEXT_ONLY_MODELS [umans-glm-5.3, umans-glm-5.2, umans-glm-5.1]; export const UMANS_MODEL_CONTEXT_WINDOWS: Recordstring, number { umans-coder: 262_144, umans-kimi-k2.7: 262_144, umans-flash: 262_144, umans-glm-5.3: 405_504, umans-glm-5.3-flash: 405_504, // 与同系列兄弟模型一致Umans 未单独公布 flash 档位 umans-glm-5.2: 405_504, umans-glm-5.1: 202_752, umans-qwen3.6-35b-a3b: 262_144, }; export const UMANS_MODEL_INPUT_MODALITIES: Recordstring, string[] Object.fromEntries( UMANS_MODELS.map(id [id, UMANS_TEXT_ONLY_MODELS.includes(id) ? [text] : [text, image]]), );几个值得注意的细节源码注释直接印证上下文窗口并非统一GLM-5.x 系列为 405,504 token其中 GLM-5.1 为 202,752其余模型统一 262,144 token。若注册时给所有模型套同一个窗口Codex 侧会按保守的 128k 兜底从而浪费真实可用上下文——这正是该数据被显式声明的意义。umans-glm-5.3-flash不在纯文本列表Z.AI 将 glm-5.3-flash 文档化在 VLM 指南下原生接受图像因此不需要走代理的视觉 sidecar。源码注释还诚实记录了一次seed 分类按家族名误判、后续只修正了部分 Provider的教训。输入模态按模型推导非纯文本模型默认[text, image]纯文本模型为[text]。该推导式Object.fromEntries(...)在测试中同样被断言例如modelInputModalities[umans-glm-5.2]必须等于[text]。key-login 保存运行时元数据如何被完整保留这是本工作的核心工程点通过 CLI 以 API Key 登录并保存 Provider 行时绝不能丢目录中声明的运行时元数据。实现位于 src/oauth/login-cli.ts 的providerConfigFromKeyLoginProviderexport function providerConfigFromKeyLoginProvider(def: KeyLoginProvider, key: string, baseUrlOverride?: string): OcxProviderConfig { return { adapter: def.adapter, baseUrl: baseUrlOverride ?? def.baseUrl, apiKey: key, ...(def.apiKeyTransport ! undefined ? { apiKeyTransport: def.apiKeyTransport } : {}), ...(def.defaultModel ? { defaultModel: def.defaultModel } : {}), ...(def.models ? { models: [...def.models] } : {}), ...(def.contextWindow ! undefined ? { contextWindow: def.contextWindow } : {}), ...(def.modelContextWindows ? { modelContextWindows: { ...def.modelContextWindows } } : {}), ...(def.modelMaxInputTokens ? { modelMaxInputTokens: { ...def.modelMaxInputTokens } } : {}), ...(def.defaultMaxOutputTokens ! undefined ? { defaultMaxOutputTokens: def.defaultMaxOutputTokens } : {}), ...(def.modelMaxOutputTokens ? { modelMaxOutputTokens: { ...def.modelMaxOutputTokens } } : {}), ...(def.modelInputModalities ? { modelInputModalities: cloneRecordOfArrays(def.modelInputModalities) } : {}), ...(def.reasoningEfforts ? { reasoningEfforts: [...def.reasoningEfforts] } : {}), ...(def.modelReasoningEfforts ? { modelReasoningEfforts: cloneRecordOfArrays(def.modelReasoningEfforts) } : {}), ...(def.reasoningEffortMap ? { reasoningEffortMap: { ...def.reasoningEffortMap } } : {}), ...(def.modelReasoningEffortMap ? { modelReasoningEffortMap: cloneNestedRecord(def.modelReasoningEffortMap) } : {}), ...(def.noVisionModels ? { noVisionModels: [...def.noVisionModels] } : {}), ...(def.noReasoningModels ? { noReasoningModels: [...def.noReasoningModels] } : {}), ...(def.noTemperatureModels ? { noTemperatureModels: [...def.noTemperatureModels] } : {}), ...(def.noTopPModels ? { noTopPModels: [...def.noTopPModels] } : {}), ...(def.noPenaltyModels ? { noPenaltyModels: [...def.noPenaltyModels] } : {}), ...(def.autoToolChoiceOnlyModels ? { autoToolChoiceOnlyModels: [...def.autoToolChoiceOnlyModels] } : {}), ...(def.preserveReasoningContentModels ? { preserveReasoningContentModels: [...def.preserveReasoningContentModels] } : {}), ...(def.requiresReasoningPlaceholderModels ? { requiresReasoningPlaceholderModels: [...def.requiresReasoningPlaceholderModels] } : {}), ...(def.escapeBuiltinToolNames ! undefined ? { escapeBuiltinToolNames: def.escapeBuiltinToolNames } : {}), }; }三个值得展开的实现要点① 全程防御性拷贝defensive clone数组字段用[...arr]普通记录用{ ...record }嵌套数组记录用cloneRecordOfArrays深层嵌套用cloneNestedRecord。这是刻意的设计——保存的 Provider 行是独立快照此后修改其models、modelContextWindows等字段不得反向污染目录里的共享常量。测试umans-provider.test.ts中专门验证了这一点对 OpenAI API-key 条目克隆出的modelMaxInputTokens写入新值后源对象source.modelMaxInputTokens[gpt-5.6-sol]仍保持 922_000。② 保留apiKeyTransport某些 Anthropic 兼容网关要求Authorization: Bearer而非x-api-key。字段存在即透传测试CLI key-login save payload preserves apiKeyTransport when configured用{...KEY_LOGIN_PROVIDERS.umans, apiKeyTransport: bearer}验证保存后仍为bearer。③ 保留空数组语义requiresReasoningPlaceholderModels若为显式[]用户主动关闭占位策略展开后仍是[]而不是被undefined吞掉导致回退默认策略。测试用[deepseek-reasoner]与[]两种预设分别断言两者都原样保留。保存时的 operator 字段合并providerConfigFromKeyLoginProvider产出的是预设行而落盘时还需与既有行合并避免把 operator 手动配置的字段覆盖掉。同一文件中的 mergeKeyLoginProviderRow 目前专门保留modelCosts覆盖用户配置的模型成本估算这样轮换 API Key 不会静默把 Logs/Usage 的成本估算回退成目录价格随后 commitKeyLoginProvider 把合并行写盘并推送给运行中的代理保证磁盘配置与运行时代理配置不产生漂移。API Key 校验改用 Anthropic Messages 形态而非/models传统 OpenAI 兼容 Provider 的 Key 校验方式是GET /models探测。但 Anthropic 兼容网关如 Umans用/models往往拿不到有效的鉴权语义因此 src/oauth/key-providers.ts 的validateApiKey对adapter anthropic走专用分支if (provider.adapter anthropic) { const base provider.baseUrl.replace(/\/v1\/?$/, ); const res await fetch(${base}/v1/messages, { method: POST, headers: anthropicKeyValidationHeaders(provider, key), body: JSON.stringify({ model: provider.defaultModel ?? claude-haiku-4-5, max_tokens: 1, messages: [{ role: user, content: ping }], }), redirect: error, signal: AbortSignal.timeout(8000), }); if (res.ok) return true; if (res.status 401 || res.status 403) return false; return unknown; }要点请求形态POST {base}/v1/messagesbody 为最小 Messages 请求——model缺省回退claude-haiku-4-5、max_tokens: 1、单条userping 消息。8 秒超时禁止跟随重定向。三态结果ok → true401/403 → false其他状态码返回unknown保持尽力而为的登录流程可用但不把不确定的结果写成验证通过。无状态语义函数开头的provider.apiKeyValidation unknown早退同样返回unknown——公共模型目录无法证明某个 Key 有效时不产生假阳性。传输方式可切换anthropicKeyValidationHeaders根据apiKeyTransport选择x-api-key: key或Authorization: Bearer key。测试 tests/providers/umans-provider.test.ts 对两种模式均有断言默认模式请求头含x-api-key且无authorizationbearer模式则相反且都携带anthropic-version: 2023-06-01。内置工具名转义cx_前缀的上线与回传剥离这是 Umans 条目escapeBuiltinToolNames: true的底层实现位于 src/adapters/anthropic.ts 与 buildToolNameTransformsconst COMPAT_TOOL_PREFIX cx_; function buildToolNameTransforms(provider: OcxProviderConfig): { toWire: (name: string) string; fromWire: (name: string) string } { if (provider.authMode oauth) { return { toWire: applyClaudeToolPrefix, fromWire: stripClaudeToolPrefix }; } if (provider.escapeBuiltinToolNames true) { return { toWire: (name) name.startsWith(COMPAT_TOOL_PREFIX) ? name : COMPAT_TOOL_PREFIX name, fromWire: (name) name.startsWith(COMPAT_TOOL_PREFIX) ? name.slice(COMPAT_TOOL_PREFIX.length) : name, }; } return { toWire: (name) name, fromWire: (name) name }; }为什么需要转义部分 Anthropic 兼容网关会保留一组同名的内置工具如web_search。如果 opencodex 把 Codex 侧的web_search原样发给该网关网关可能无法区分来自客户端的工具声明与自身内置工具导致冲突或工具调用异常。cx_前缀相当于命名空间隔离上行时给工具名加前缀幂等已带前缀的不重复加下行解析工具调用时再剥掉前缀把干净的web_search交还给 Codex。测试如何验证这条链路tests/providers/umans-provider.test.ts 用 mock fetch/流式响应完整覆盖了该行为请求构造buildRequest后断言req.url https://api.code.umans.ai/v1/messages、POST、x-api-key生效、anthropic-beta缺省请求体中工具名已变为cx_web_searchtool_choice同步为{ type: tool, name: cx_web_search }system 提示中含Valid tool names for this turn are exactly \cx_web_search.。Responses 风格 allowed_tools 过滤两个工具web_search与run_tests仅allowedTools: [web_search]时上行tools只剩cx_web_searchtool_choice归一为{ type: any }。流式回传剥离mock SSE 流中content_block_start携带name: cx_web_search解析出的首个事件必须是{ type: tool_call_start, id: toolu_1, name: web_search }前缀已剥离。非流式回传剥离parseResponse对 JSON 响应中tool_use块做同样处理且最终必须产出done事件。模型成本与推理档位语义的严谨性Umans 条目中还体现了一类证据边界纪律umans-glm-5.3-flash的上下文窗口直接复用同系列兄弟模型的 405,504源码注释明确说明Umans 没有单独公布 flash 档位断言一个不同的数字就是猜测。同理GLM-5.3 的档位按 Z.AI 最新文档折叠为[low, high, max]并注明日期。这类宁可镜像已知事实、不虚构未知数据的处理方式是 Provider 目录维护中值得借鉴的准则。验证命令与文档同步该工作收尾时通过以下命令门禁见 00_note.mdbun run typecheck bun test tests/umans-provider.test.ts tests/provider-registry-parity.test.ts bun test tests bun run build:guitests/umans-provider.test.ts是本次新增的专项测试上文各节引用的断言均出自于此tests/providers/provider-registry-parity.test.ts用于保证目录条目与其他来源如 models.dev 同步数据、上游模型元数据的一致性全量bun test tests与bun run build:gui防止该改动波及 GUI 构建与既有测试。文档同步方面Provider 汇总表已在 docs-site/src/content/docs/guides/providers.md 及各语言页fr/ja/ko/ru/tr/zh-cn/zh-tw 对应文件登记 Umans 的 base URLGUI 侧featured: true让该条目在 Add provider 选择器置顶展示。README 亦同步记录新增 Provider 与escapeBuiltinToolNames配置标志方便新用户直接搜索到。小结从一次合并审计中揪出的无关 WIP到最终落地的完整 Provider 支持241_umans-provider-cleanup展示了 opencodex 接入 Anthropic 兼容 key-login Provider 的标准姿势目录注册entries-core.ts→ 模型种子model-seeds.ts→ key-login 元数据保留login-cli.ts→ Messages 形态 Key 校验key-providers.ts→ 工具名转义anthropic.ts→ 专项测试与文档同步。对想要理解或新增类似 Provider 的读者沿着umans字符串在 src/providers/registry/entries-core.ts、src/providers/registry/model-seeds.ts、src/oauth/login-cli.ts、src/oauth/key-providers.ts 与 src/adapters/anthropic.ts 中的引用链即可复现这条完整的接入路径。赞分享【免费下载链接】opencodexUniversal provider proxy for OpenAI Codex Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code项目地址https://gitcode.com/gh_mirrors/ope/opencodex点击查看免费下载相关推荐DeepSeek Harness Workspace 注册删除深度解析仅删除注册记录、保留数据的安全语义设计DeepSeek Harness Workspace 注册删除深度解析仅删除注册记录、保留数据的安全语义设计 导读 本文聚焦 DeepSeek Harness人工智能AI AgentAgent 框架DeepSeekCargo Login 命令完全指南注册表认证令牌的保存与 Credential Provider 机制Cargo Login 命令完全指南注册表认证令牌的保存与 Credential Provider 机制 cargo login 是 CargoThe Ru开发工具包管理器CLI构建工具OpenSSL EVP_SKEY 元数据机制为 PKCS12 对称密钥保留别名、Local Key ID 与算法标识OpenSSL EVP_SKEY 元数据机制为 PKCS 12 对称密钥保留别名、Local Key ID 与算法标识 OpenSSL 正在将对称密钥纳入 P密码学网络安全通信创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/23 4:47:33

5个坑点:人性的电影环境配置与面试必问注销流程避坑

5个坑点:人性的电影环境配置与面试必问注销流程避坑 配置环境就卡半天,这感觉太熟悉了。你明明照着教程敲了半小时,结果还是报错,头发都抓秃了也没个结果。更扎心的是,当你去搜“人性的电影”相关的项目案例或资源时,发现很多教程里夹带的“注销流程”…

2026/9/23 4:47:33

YOLOv5火灾烟雾检测:注意力机制与TensorRT部署实战

简介:Python毕业设计专用的YOLOv5火灾火焰烟雾检测方案,整合了标注数据集、训练好的模型、完整源码与PyQt交互界面,适合深度学习或计算机视觉方向的毕业生或开发者参考,能够解决火灾检测项目从数据准备到模型部署的完整需求&#…

2026/9/23 6:02:35

IgA肾病精准治疗:基因检测指导激素用药

1. IgA肾病治疗现状与精准用药需求IgA肾病作为全球最常见的原发性肾小球肾炎,约占原发性肾小球疾病的40%。在临床实践中,糖皮质激素一直是治疗中高危IgA肾病的主要药物选择。然而,长期困扰肾内科医生的一个核心问题是:为什么有些患…

2026/9/23 6:02:35

Python封装机制详解与实践指南

1. 为什么我们需要讨论Python封装在Python开发社区里,封装(encapsulation)可能是最常被误解的面向对象特性之一。很多开发者认为Python的封装机制很"弱",因为不像Java那样有严格的private修饰符。但实际情况是,Python提供了一套更灵…

2026/9/23 6:02:35

植物的光合作用源码解析

3行代码看懂植物光合作用的性能优化逻辑 控制台炸出一串红色的 StackTrace,光标在 NullPointerException…

2026/9/23 6:02:35

多无人机协同路径规划:基于Dubins路径的Matlab实现

1. 项目背景与核心挑战在动态对抗环境中,多无人机系统的协同路径规划一直是学术界和工业界关注的焦点问题。传统单机路径规划方法难以应对复杂威胁环境下的实时避障、队形保持和任务分配等多重需求。这个项目针对性地提出了一种基于多段Dubins路径的协同策略&#x…

2026/9/23 5:57:35

《漫长的季节》沈墨角色解析:人性异化与社会隐喻

1. 角色塑造与人性解构的艺术《漫长的季节》中沈墨这一角色的塑造,堪称近年来国产剧集中最令人深思的人物形象之一。这个看似普通的医院护工,在剧中的行为模式和心理变化,实际上完成了一次对人性边界的残酷拷问。沈墨对待他人的方式&#xff…

2026/9/22 10:02:42

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/22 9:07:39

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/23 0:01:54

3个实战技巧搞定形式英语:从看教程到跑通性能优化

3个实战技巧搞定形式英语:从看教程到跑通性能优化 看了一堆教程还是不会写项目?别慌,这种“眼高手低”的困境在开发者圈子里太常见了。很多人以为卡点在语法,其实真正拦路虎是缺乏将知识点串联成完整链路的能力。今天咱们不聊虚的,直接拿【形式英语】这…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码