opencodex 斜杠模型 ID 编解码:Codex 单斜杠 Slug 契约的完整实现与路由解析

发布时间:2026/9/25 14:43:12

opencodex 斜杠模型 ID 编解码:Codex 单斜杠 Slug 契约的完整实现与路由解析 【免费下载链接】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点击查看免费下载本指南基于devlog/_fin/260718_slash_model_id_codec/记录深入讲解 opencodex 如何为原生 model id 含/的提供商zenmuxmoonshotai/kimi-k3-free、openrouteranthropic/...、nvidiamoonshotai/...等生成 Codex 端单斜杠 slug并在代理层做精确双射解码。读完你将掌握为什么 Codex 的「单斜杠标签查找」会丢失元数据、src/providers/slug-codec.ts的核心契约别名分隔符、解码优先级、冲突处理、路由器与目录的接入点以及如何在ocx sync后验证冷缓存解码与原始全斜杠选择器的兼容性。背景Codex 的单斜杠标签查找Tagging约束opencodex 作为通用提供商代理会把原生 model id 以provider/model-id的「路由 slug」形式写入 Codex 目录catalog使 Codex 模型选择器picker能显示第三方模型。但 Codex 自身对模型元数据推理努力阶梯、上下文窗口、能力标签的解析有严格的单斜杠规则codex-rs 的models-manager中find_model_by_namespaced_suffix对应 模型目录元数据文档对modelId执行split_once(/)若剩余部分仍包含/则直接拒绝本次元数据查找。对于原生 id 自带命名空间的提供商——zenmuxmoonshotai/kimi-k3-free、openrouteranthropic/claude-sonnet-5、nvidiamoonshotai/kimi-k2.6——若原样透传就会生成zenmux/moonshotai/kimi-k3-free这样的双斜杠 slug。Codex 因无法通过标签查找解析它会静默回退到默认元数据努力阶梯、上下文窗口、能力标签全部丢失。该问题在真实缓存中得到了验证~/.codex/opencodex-catalog.json中唯一的双斜杠 slug 就是zenmux/moonshotai/kimi-k3-free。于是产生了一个明确的需求把内层斜杠在 Codex 面对面上改写为别名分隔符同时在代理层无歧义地还原为原生 id。设计决策别名分隔符与单向契约围绕上述约束opencodex 采用了「Codex 兼容性别名仅此而已」的定位并形成四条硬性规则别名分隔符是-连字符由 slug-codec.ts 的SLUG_ALIAS_SEPARATOR -定义。原生 id 往往已含大量下划线连字符在 Codex 应用展示中更易读因此用户方向上从_修订为-。绝不盲目解码-→/解码必须是针对提供商「已知原生 id 集合」的精确双射查找。未知 id 原样透传由上游给出诚实的报错绝不猜测。原生 id 永远是内部规范形式上游请求、日志、用量统计、jawcode 元数据、combo 键、禁用列表全部使用原生 id只有 Codex 面对面的界面目录条目、picker 列表、Codex 侧配置选择才使用编码 slug。向后兼容原始全斜杠选择器用户在配置或请求里直接写zenmux/moonshotai/kimi-k3-free依然有效——精确原生匹配优先于编码匹配。核心编解码函数逐一解析slug-codec.ts 是本次实现的叶子模块只导入类型、不引入循环依赖其导出函数构成了完整的编解码契约1. 编码encodeRoutedModelId与routedSlug/** 原生 model id - Codex 面对面的别名 id。对不含 / 的 id 是 no-op。 */ export function encodeRoutedModelId(id: string): string { return id.includes(/) ? id.replaceAll(/, SLUG_ALIAS_SEPARATOR) : id; } /** Codex 面对面的路由 slug恰好一个 / —— provider/encoded id。 */ export function routedSlug(provider: string, id: string): string { return ${provider}/${encodeRoutedModelId(id)}; }encodeRoutedModelId(moonshotai/kimi-k3-free)→moonshotai-kimi-k3-freeroutedSlug(zenmux, moonshotai/kimi-k3-free)→zenmux/moonshotai-kimi-k3-free恰好一个/配套的encodedModelIdCollides(modelId, knownIds)用于在目录构建期检测两个原生 id 编码后是否撞车例如openai/gpt-5.5与openai-gpt-5.5从而让provider/openai-gpt-5.5能被解码回原生openai-gpt-5.5同时自定义openai/gpt-5.5行仍然可见。2. 解码decodeRoutedModelId的三段优先级export function decodeRoutedModelId(requested: string, knownIds: Iterablestring): string { let aliasMatch: string | undefined; for (const id of knownIds) { if (id requested) return requested; // ① 原生精确匹配原始选择器向后兼容 if (id.includes(/) encodeRoutedModelId(id) requested) { if (aliasMatch ! undefined aliasMatch ! id) return requested; // ② 别名歧义拒绝猜测 aliasMatch id; // ③ 唯一别名匹配 } } return aliasMatch ?? requested; // ③ 未知 id 原样透传 }三段查找按顺序执行原生精确匹配requested本身就是已知原生 id如a/b、a-b→ 原样返回这是原始全斜杠选择器向后兼容的根基唯一别名匹配恰好一个已知原生 id 编码后等于requested→ 返回该原生 id透传既不是原生 id、也没有唯一别名 → 原样返回requested交由上游给出诚实错误。歧义绝不猜测当同一提供商同时存在a/b与a-b且没有原生a-b时decodeRoutedModelId(a-b, ...)保持a-b不变——因为x/y/z与x/y-z会编码成同一个x-y-z盲目替换会把请求路由到错误模型。另有严格变体decodeRoutedModelIdOrThrow它收集所有匹配原生或编码等价到集合中若匹配数 1 直接抛出ambiguous model id ...异常。src/router.ts显式提供商命名空间分支正使用该变体用以在运行期捕获「写入期检查无法覆盖的后来实时缓存冲突」。3. 配置比较的宽容等价slugEquals/slugEquivalenceKey/slugsEquivalentexport function slugEquals(stored: string, provider: string, id: string): boolean { return stored ${provider}/${id} || stored routedSlug(provider, id); } export function slugEquivalenceKey(slug: string): string { const slash slug.indexOf(/); return slash 0 ? JSON.stringify([exact, slug]) : JSON.stringify([routed, slug.slice(0, slash), encodeRoutedModelId(slug.slice(slash 1))]); } export function slugsEquivalent(a: string, b: string): boolean { return a b || slugEquivalenceKey(a) slugEquivalenceKey(b); }slugEquals(zenmux/moonshotai-kimi-k3-free, zenmux, moonshotai/kimi-k3-free)→trueslugEquals(zenmux/moonshotai/kimi-k3-free, zenmux, moonshotai/kimi-k3)→falseid 不同slugsEquivalent(zenmux/moonshotai/kimi-k3-free, zenmux/moonshotai/kimi-k3-free)→true跨原始/编码两种拼写等价slugEquivalenceKey是有意有损的——单斜杠规则强制a/b与a-b归入同一编码形式。目录过滤与持久化同步共享此键因此保持一致但会在提供商同时发布两个拼写时静默超额授权over-grant。slugEquals/slugsEquivalent的存在保证了遗留原始全斜杠配置如disabledModels、subagentModels无论以何种形式存储都能继续生效。4.#2491选择解析器resolveSlugSelectionresolveSlugSelection(provider, selection, knownIds)返回SlugSelectionMatch { matched, exact, ambiguous }把「这个选择到底命中了谁」显式暴露给调用方先决条件若 roster 确实发布了原生 idacme/turbo自我命名空间则字面拼写按原生 id 处理而不是按「provider 限定的turbo」否则一个已发布的acme/turbo会变得不可达而兄弟 idturbo会悄悄吞掉该选择ocx models remove正是从该解析器读取匹配此歧义会指向破坏性命令。两个拼写都存在时报ambiguous: true同时给出exact操作者字面键入的那一行由调用方决定是严格收紧到精确行还是容忍整个撞车类。roster 缺失某个已发布 id 时返回空匹配——绝不发明一个。目录Catalog接入单斜杠 slug 的发射与冲突处理发射规则build-entries.ts 的buildCatalogEntries中路由模型目录条目使用routedSlug(m.provider, m.id)生成 slug、display_name同步采用该编码 slug而base_instructions中的身份文本必须使用原生 model id——即 jawcode 元数据键是原生的openrouteranthropic/...编码别名切片无法命中元数据表。测试 slug-codec.test.ts 断言buildCatalogEntries(..., [{provider: zenmux, id: moonshotai/kimi-k3-free}])产出slug zenmux/moonshotai-kimi-k3-free且slug.split(/)长度恰为 2其base_instructions文本包含moonshotai/kimi-k3-free原生而非moonshotai-kimi-k3-free。jawcode 元数据在原生 id 上解析模板 空模板双分支const meta getModelMetadata(openrouter, anthropic/claude-sonnet-5); // contextWindow 1_000_000input_modalities [text, image]对{ provider: openrouter, id: anthropic/claude-sonnet-5 }无论是否有原生目录模板template 与 null-template 两条分支编码条目openrouter/anthropic-claude-sonnet-5的context_window与input_modalities都必须来自原生 id 的元数据查找——applyJawcodeCatalogMetadata的签名改为(entry, provider, nativeModelId, contextCap)绝不从编码 slug 反推 provider/id。撞车处理警告一次、原生连字符优先当同一提供商的两个原生 id 编码为同一个别名如a/b与a-b目录槽位原生连字符拼写a-b胜出与解码优先级一致失败者a/b被丢弃但依然可通过其原始全斜杠选择器调用警告console.warn每个 provideralias 只触发一次——测试中两次构建buildCatalogEntries后console.warn恰好被调用 1 次重复编码 slug 永不发射。路由器Router接入编码请求还原为原生 idsrc/router.ts 的显式提供商命名空间分支约 L742-L763是代理层解码的核心const known knownModelIdsForProvider(provName, prov, config); // 自我命名空间原生 id如 orcarouter/auto整体路由不做切片 if (known.includes(modelId)) { return routeResult(config, provName, prov, modelId, explicit-provider, explicit-provider-namespace); } // Codex 面对面的别名 idprovider/vendor-model通过精确已知 id 查找解码回原生斜杠 id const requestedModel modelId.slice(slash 1); const decoded decodeRoutedModelIdOrThrow(requestedModel, known); const nativeModel known.includes(decoded) ? decoded : resolveModelAlias(config, prov, known, requestedModel) ?? decoded; return routeResult(config, provName, prov, nativeModel, explicit-provider, explicit-provider-namespace);knownModelIdsForProvider将三类来源合并为「已知原生 id 并集」配置层config.providers[provName].models、defaultModel、customModels仅限该 provider 的行注册表层PROVIDER_REGISTRY条目的静态modelsseed以及 registry 中各类以原生 id 为键的 hint mapmodelWireDefaults、modelDisplayNames、modelContextWindows、modelReasoningEfforts、keyAuthServiceTier.modelSupportsServiceTier等实时缓存层getStaleCached(provName)拉取过的模型列表。另有两条编码回退分支defaultModel与providers[].models中的裸 id如vendor-m-1在走默认模型/模型列表匹配时也通过编码形式比较因此routeModel(config, vendor-m-1)能路由到other提供商的vendor/m-1。实战冷缓存注册表 seed 与实时缓存边界静态 seed冷缓存也能解码zenmux 注册表条目补充了静态models: [moonshotai/kimi-k3-free, moonshotai/kimi-k3]2026-07-18 经 zenmux.ai/api/v1/models 实测验证替换了原先的 FREEZE 注释。这意味着即便没有实时缓存routeModel(config, zenmux/moonshotai-kimi-k3-free)也能解码回moonshotai/kimi-k3-free。nvidia 这类没有静态 models 列表的提供商则依赖 registry 的 model-keyed hint map 作为解码种子routeModel(config, nvidia/moonshotai-kimi-k2.6)同样解码成功且其原始全斜杠形式nvidia/moonshotai/kimi-k2.6继续可达。已知边界诚实行为传输不匹配的提供商不继承解码提示若某提供商配置了与 registry 不一致的 baseUrl/传输其解码提示不生效编码 id 原样透传registry 解码提示本身不发布目录行仅存在于 hint map 的 id 不会因此出现在 catalog 中冷缓存解码依赖原生 id 含斜杠且无静态 seed 的提供商只能靠暖的实时缓存解码否则编码 id 原样透传并触发上游报错运行期撞车被严格拒绝自定义openai/gpt-5.5先被收录后若实时缓存又发现openai-gpt-5.5则routeModel抛ambiguous而不是静默二选一。集成面与 SoT 同步管理 APIsrc/server/management-api.ts/api/models命名空间列表、/api/injection-model可用列表等所有管理 picker 界面发射routedSlug(...)使存储的配置值disabledModels、injectionModel、subagentModels与 Codex 面对面的目录 slug 一致读取端统一slugEquals-宽容。Claude 代理侧src/claude/agents-inject.ts在调用claudeCodeAlias(provider, id)前先用同一 known-ids 并集解码 model-id 段保证原始原生 context-window 映射表context-windows.ts继续命中。上游保持原始形态/v1/modelsOpenAI 形态的命名空间可用列表、combo 目录 slug 等上游面对面的表面保持原始原生键不变不做编码。SoT 文档README 与 docs/codex-app-model-catalog.mdSlash-containing native ids 一节记录了该别名规则作为模型的单一事实来源SoT。验证与激活证据单元测试 slug-codec.test.ts 覆盖编码往返、解码优先级原生 唯一别名 透传、别名歧义拒绝、撞车警告一次、slugEquals/slugsEquivalent/slugEquivalenceKey等价关系、冷缓存 registry seed 解码、registry hint map 独立播种、默认模型与 models 列表编码回退、jawcode 原生元数据模板 空模板、撞车槽位裁决、featured 排名对原始/编码拼写双兼容以及#2491选择解析器的 9 个场景全量回归变更集相对 HEAD 基线失败集合完全一致15 个新绿测试现存 55 个失败均为预存的并行加载波动websocket 超时、oauth token-store 竞争、worktree-only GUI react 运行时解析与本变更无关目录端激活断言slash-id 模型产出的 slug 恰有一个/且编码请求经routeModel解码到原生 id。升级到本分支后的操作步骤从本分支重新安装/重启本地 ocx 服务运行ocx sync或重启应用使~/.codex/opencodex-catalog.json拾取单斜杠 slug下一次同步后陈旧的zenmux/moonshotai/kimi-k3-free条目被替换为新条目zenmux/moonshotai-kimi-k3-free验证Codex 模型选择器中出现zenmux/moonshotai-kimi-k3-free单斜杠其努力阶梯、上下文窗口等标签来自原生 id 元数据同时旧的原始全斜杠选择器zenmux/moonshotai/kimi-k3-free依然可路由。赞分享【免费下载链接】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点击查看免费下载相关推荐Hermes Desktop 斜杠命令执行机制解析从 slash.exec 路由管线到中央命令路由器的完整实现Hermes Desktop 斜杠命令执行机制解析从 slash.exec 路由管线到中央命令路由器的完整实现 导读 本文以 Hermes DesktopHAI 应用交互助手桌面应用Manim v0.17.1 修复解析LaTeX 路径正斜杠兼容与子字幕 Unicode 编码Manim v0.17.1 修复解析LaTeX 路径正斜杠兼容与子字幕 Unicode 编码 导读 ManimCommunity Edition简称 Ma图形学教育上一篇3分钟快速部署WorkshopDL跨平台游戏模组下载终极解决方案下一篇零基础用 Czkawka 快速找出重复文件与相似图片创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/25 14:38:12

ConvNeXt-Tiny工业部署全链路指南:从架构原理到边缘落地

1. 为什么ConvNeXt-Tiny不是“又一个CNN复刻”——它本质是一场架构范式的静默迁移你可能已经见过太多标题里带“革命”“颠覆”“重磅”的模型介绍,点进去却发现不过是ResNet加了个注意力、ViT换了个patch size。但ConvNeXt-Tiny不一样——它不是在旧框架上修修补补…

2026/9/25 14:38:12

用 ASP 实现 Access 数据库分页显示:TaoToken 配置与调试要点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 15:43:16

Atlas 300V 24G推理卡实战:YOLO多路视频流部署与调优

拿到一块Atlas 300V 24G的时候,我第一反应不是赶紧跑YOLO demo,而是先问自己一个问题:这卡到底是干嘛用的,和训练卡有什么区别,24G这个显存数字在推理场景里到底能带来多少真实收益。热搜词里天天有人在问“atlas 300v…

2026/9/25 15:43:16

windsurf Pro 获取详细教程:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 15:43:16

Atlas 300V 24G推理卡上部署YOLO:从环境到调优全流程解析

1. 项目概述:Atlas到底是什么,为什么大家都在聊它如果你最近在AI推理、边缘计算或端侧部署的圈子里逛,大概率会频繁撞见“Atlas”这个词。有人拿它跑YOLO目标检测,有人用它做视频流分析,还有人直接把它当“平民版GPU推…

2026/9/24 20:24:47

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

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

2026/9/23 12:06:55

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

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

2026/9/25 0:02:35

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:02:35

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:02:35

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

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
免费获取方案
☎咨询二维码 ☎ ↑