docs: record API key skill catalog delivery
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
# R2.7.4 任务报告
|
||||
|
||||
## 调查范围
|
||||
|
||||
- 官方仓库:`Wei-Shaw/sub2api`。
|
||||
- 最新主分支:`b1a6b8026764dedf6a5f76d02bdc292468d22753`。
|
||||
- 当前部署相关版本:`v0.1.159`,对应提交 `2a75d7d2387587d86ca3c5e5cd8ca96cf3d104c6`。
|
||||
- 调查只读取官方源码与 Codex 官方手册,没有修改 Sub2API、UniDesk CLI、配置、版本或运行面。
|
||||
|
||||
## 结论
|
||||
|
||||
- 现有 Sub2API 不能按下游 API Key 配置或自动加载 Codex skill。
|
||||
- 真正的 Codex skill 是客户端文件能力:
|
||||
- Codex 从 repo `.agents/skills`、用户 `$HOME/.agents/skills`、管理员 `/etc/codex/skills` 等位置发现 skill;
|
||||
- 首先加载名称、描述和路径,命中后再读取完整 `SKILL.md`、references 与 scripts;
|
||||
- API 请求中的 `instructions` 只能附加文本,不能把 skill 文件、脚本、参考资料或插件安装到员工机器。
|
||||
- 因此“请求时由 API Key 自动加载真正 skill”不符合 Codex 当前发现模型。真正 skill 必须在 Codex 启动或会话开始前已经安装或随仓库存在。
|
||||
- 如果“skill”实际只指强制公司提示词,则可以设计按 Key 的 instruction profile,但最新版仍缺该能力,严格按 Key 配置至少需要外部网关或 Sub2API 源码扩展。
|
||||
|
||||
## 官方源码证据
|
||||
|
||||
- API Key 鉴权已经具备请求级身份:
|
||||
- 中间件按 Bearer Key 查询完整 API Key;
|
||||
- 成功后把 `*service.APIKey` 放入 Gin context;
|
||||
- Responses handler 可读取 `apiKey.ID`、名称、用户和分组。
|
||||
- API Key 数据模型当前没有 skill、instruction profile 或 metadata 字段:
|
||||
- 只有名称、分组、状态、IP 规则、配额、有效期和限速;
|
||||
- 用户与管理员 API Key CRUD 也没有对应字段。
|
||||
- API Key 鉴权使用 L1/L2 快照缓存:
|
||||
- 当前快照版本为 15;
|
||||
- 若新增按 Key profile,必须进入最小查询、快照、版本升级和更新后的跨实例缓存失效链。
|
||||
- `v0.1.159` 和最新 main 已有全局
|
||||
`gateway.forced_codex_instructions_template_file`:
|
||||
- 模板启动时读盘并缓存;
|
||||
- 模板上下文只有已有 instructions 和四个模型字段;
|
||||
- 没有 API Key ID、名称、用户、分组或 profile;
|
||||
- 代码只在 `/v1/messages` 转 OpenAI OAuth Responses 的兼容路径调用;
|
||||
- 原生 `/v1/responses` 只在 instructions 为空时补默认 Codex instructions,没有调用该强制模板。
|
||||
- 所以该原生配置可以做全局、文本型、特定兼容路径注入,但不能满足每 Key 配置,也不能代表真正加载 skill。
|
||||
|
||||
## 候选方案
|
||||
|
||||
### 方案 A:零 Sub2API 源码改动,客户端分发真正 skill,推荐
|
||||
|
||||
- 公司级通用 skill:
|
||||
- 打包为 Codex plugin;
|
||||
- 发放 API Key 时同时给出一次安装或受控 bootstrap;
|
||||
- 安装到用户或管理员 skill 目录,后续由 Codex 隐式匹配。
|
||||
- 项目级 skill:
|
||||
- 直接随公司代码仓库提交到 `.agents/skills/<name>/SKILL.md`;
|
||||
- 员工 clone 仓库后自动进入 Codex skill 发现范围。
|
||||
- 永久、每次都必须执行的规则使用 `AGENTS.md`,不要包装成按请求触发的 skill。
|
||||
- 每 Key 差异由发 Key 的管理流程选择不同 plugin/profile 包,而不是让模型请求携带或解析 Key。
|
||||
- 优点:
|
||||
- 无 Sub2API 修改;
|
||||
- 是真正的 progressive-disclosure skill;
|
||||
- scripts、references、MCP 依赖都能工作;
|
||||
- 不增加每次请求 Token、TTFT 或网关改写风险。
|
||||
- 限制:
|
||||
- API Key 本身不会远程改变已经启动的 Codex 会话;
|
||||
- skill 更新需要客户端自动同步、插件更新或重新启动/刷新 Codex。
|
||||
|
||||
### 方案 B:零 Sub2API 源码改动,外部网关按 Key 注入 instructions,不推荐作为 skill
|
||||
|
||||
- 在 Sub2API 前增加薄反向代理:
|
||||
- 按 Bearer Key 的哈希映射 instruction profile;
|
||||
- 修改 Responses JSON 的 `instructions`;
|
||||
- 保留客户端原 instructions。
|
||||
- 优点:
|
||||
- 不改 Sub2API;
|
||||
- 可以真正按 Key 选择文本。
|
||||
- 缺点:
|
||||
- 只是提示词注入,不是 skill;
|
||||
- 必须覆盖 `/v1/responses`、compact、WebSocket、`/v1/messages` 和错误/流式语义;
|
||||
- 新增敏感 Key 处理面、请求体改写面和运维故障点;
|
||||
- 不能提供本地 scripts、references 或 MCP;
|
||||
- 不应作为首选。
|
||||
|
||||
### 方案 C:最小 Sub2API 源码扩展,按 Key instruction profile
|
||||
|
||||
- 适用于只需要按 Key 强制公司文本规则,不需要真正 skill 资产。
|
||||
- 推荐数据模型:
|
||||
- API Key 只保存 nullable `codex_instruction_profile` 标识;
|
||||
- profile 到模板文件的映射由服务配置管理;
|
||||
- 不把大段提示词复制进每条 API Key 或鉴权缓存。
|
||||
- 最小改动面:
|
||||
- migration 与 Ent APIKey schema;
|
||||
- service/repository/DTO;
|
||||
- 管理员 API Key CRUD,默认不允许员工自行切换 profile;
|
||||
- auth 最小查询与快照字段,提升快照版本并复用缓存失效;
|
||||
- 在安全审计前对原生 Responses、compact 和 messages bridge 统一组合 instructions;
|
||||
- 保留客户端 `ExistingInstructions`,输出只记录 profile ID 和内容 hash,不记录正文。
|
||||
- 该方案可复用现有 Go template 渲染器,但必须扩展到原生 Responses,并传入 API Key profile。
|
||||
- 这仍应命名为 instruction profile,而不是 skill auto-load。
|
||||
|
||||
### 方案 D:真正按 Key 管理 skill,完整方案
|
||||
|
||||
- Sub2API 保存每 Key 的 `skill_profile_id`。
|
||||
- 增加经 API Key 鉴权的只读 manifest:
|
||||
- profile ID、版本、兼容范围、bundle URL、SHA-256、签名和 ETag;
|
||||
- 不直接返回或记录完整 API Key。
|
||||
- 配套 Codex bootstrap/plugin 在启动时:
|
||||
- 用 Key 获取 manifest;
|
||||
- 验证签名与 hash;
|
||||
- 原子同步到用户或管理员 skill 目录;
|
||||
- 完成后启动/刷新 Codex。
|
||||
- 这能满足每 Key 管理和真正 skill,但同时涉及 Sub2API、分发服务、签名制品和客户端工具,不属于最小修改。
|
||||
|
||||
## 推荐顺序
|
||||
|
||||
1. 首选方案 A:
|
||||
- 公司通用工作流做 plugin;
|
||||
- 项目工作流放 repo `.agents/skills`;
|
||||
- 必须始终生效的规则放 `AGENTS.md`;
|
||||
- API Key 发放流程同时选择并安装相应公司 plugin。
|
||||
2. 若确实需要管理员在服务端立即控制每 Key 的文本规则,再做方案 C,并明确叫 instruction profile。
|
||||
3. 只有需要按 Key 远程版本管理 scripts/references/MCP 时才做方案 D。
|
||||
4. 不建议用 API Key 名称承载 profile、把完整 skill 塞入每次 instructions、让模板按原始 Key 分支,或把 skill bundle 暴露为持 Key 即可下载的无签名资源。
|
||||
|
||||
## 安全与行为边界
|
||||
|
||||
- API Key 是计费与访问凭据,不应成为可日志化的 skill selector 或下载 URL 参数。
|
||||
- 提示词注入不是策略强制;机械约束仍应放 hooks、CI、权限和审批。
|
||||
- skill scripts 在员工机器执行,必须固定来源、签名和 digest,更新需要可回退。
|
||||
- 每次请求动态拉 skill 会增加 TTFT、可用性依赖和 Token 成本,也与 Codex 会话启动时的 skill 发现模型冲突。
|
||||
- 任何网关注入必须保留客户端 instructions,并确保安全审计看到最终请求内容。
|
||||
@@ -0,0 +1,71 @@
|
||||
# R2.7.5 调查报告
|
||||
|
||||
## 结论
|
||||
|
||||
用户澄清后,目标可收敛为按下游 API Key 注入一组虚拟 skill 的 `name + description`。description 负责说明触发条件,并引导 Agent 从公司内网读取最新版说明、文件或脚本;Sub2API 不需要保存或分发完整 `SKILL.md`、references、scripts 或 bundle。
|
||||
|
||||
这会显著缩小实现面,但 Sub2API 当前仍没有同时满足“按 API Key 配置”和“覆盖原生 `/v1/responses`”的官方配置,因此严格服务端按 Key 控制无法只靠现有配置完成。
|
||||
|
||||
## 源码事实
|
||||
|
||||
- `backend/internal/server/middleware/api_key_auth.go` 已将完整 API Key 实体放入请求上下文,具备按 Key 选择配置的基础。
|
||||
- `backend/ent/schema/api_key.go` 当前没有 skill、catalog 或 instructions 字段。
|
||||
- `backend/internal/service/api_key_auth_cache.go` 与 `api_key_auth_cache_impl.go` 使用 API Key 鉴权快照;新增按 Key catalog 时必须进入快照并提升版本。
|
||||
- `gateway.forced_codex_instructions_template_file` 是全局配置,模板数据也不含 API Key 信息。
|
||||
- 该全局模板当前只用于 `/v1/messages` 到 OpenAI OAuth Responses 的桥接路径。
|
||||
- 原生 `/v1/responses` 路径只在 instructions 为空时补默认 Codex instructions,不会应用上述模板。
|
||||
|
||||
## 候选方案
|
||||
|
||||
### 现有全局模板
|
||||
|
||||
适合所有 Key 共用同一 description,且流量只走 `/v1/messages` 桥接的情况。它不能按 Key 区分,也不覆盖员工 Codex 常用的原生 `/v1/responses`,因此不满足完整目标。
|
||||
|
||||
### 外部反向代理
|
||||
|
||||
代理可按 Bearer Key 的指纹映射 catalog,并改写请求 `instructions`。这能做到不修改 Sub2API,但会新增一层敏感 Key 处理面,还要正确处理 Responses、compact、messages、流式和请求体兼容,运维复杂度高,不推荐作为默认方案。
|
||||
|
||||
### Sub2API 最小扩展
|
||||
|
||||
推荐在 API Key 上增加结构化字段,例如:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "company-dev",
|
||||
"description": "当任务涉及公司项目时使用。先从公司内网固定地址读取最新说明。"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
最小改动范围:
|
||||
|
||||
- API Key migration、Ent schema、repository/service 和管理员 CRUD。
|
||||
- 鉴权快照加入 catalog 并提升 snapshot version。
|
||||
- 鉴权完成后,将 catalog 追加到最终 Responses instructions,覆盖 `/v1/responses`、`/v1/responses/compact` 和 `/v1/messages` bridge。
|
||||
- 保留客户端已有 instructions,只追加企业 catalog,不覆盖用户内容。
|
||||
- 日志只记录 API Key 标识、catalog 名称或内容 hash,不记录完整 description。
|
||||
- 不增加文件、脚本、manifest 或 bundle 存储与分发能力。
|
||||
|
||||
建议注入文本保持短小稳定:
|
||||
|
||||
```md
|
||||
## Company Skills
|
||||
|
||||
- `company-dev`: 当任务涉及公司项目时使用。使用前从公司内网固定地址读取最新说明。
|
||||
```
|
||||
|
||||
## 能力边界
|
||||
|
||||
- 这是请求上下文里的虚拟 skill catalog,不是 Codex 客户端本地发现的 skill,不会自动出现在 `/skills` 或本地 skill selector。
|
||||
- description 应明确写出触发条件、内网入口和读取动作,自动命中仍依赖模型判断。
|
||||
- Agent 必须具备访问公司内网及其认证的权限;sandbox 或网络策略可能阻止拉取。
|
||||
- description 不应要求 Agent 把 Sub2API API Key 转发给内网服务。
|
||||
- 内网资源宜提供版本或内容 hash,避免同一个 description 指向的内容静默漂移。
|
||||
- 提示词注入不是安全强制机制;必须强制执行的企业策略仍需独立权限和服务端控制。
|
||||
|
||||
## 建议
|
||||
|
||||
若要求每个 API Key 独立配置,并确保 Codex 原生 Responses 请求生效,采用上述最小 Sub2API 扩展。若所有 Key 完全共用一条 description,可暂时使用现有全局模板验证交互文案,但它不是完整交付方案。
|
||||
|
||||
本轮仅完成只读源码调查和方案收敛,未修改 Sub2API 源码、版本、配置或运行面。
|
||||
@@ -0,0 +1,123 @@
|
||||
# R2.7.6 任务报告
|
||||
|
||||
## 结果
|
||||
|
||||
已在 `/root/superapi` 实现并启动独立的 description-only 企业虚拟 skill 上游加载器。当前链路为:
|
||||
|
||||
```text
|
||||
Codex -> https://superapi.hwpod.com/v1/responses
|
||||
-> SuperAPI 按 Bearer API Key 匹配 profile
|
||||
-> 追加 Company Skills name + description
|
||||
-> https://api.pikapython.com/v1/responses
|
||||
```
|
||||
|
||||
Sub2API 源码、版本、账号池和 runtime 配置均未修改。
|
||||
|
||||
## 规格与归属
|
||||
|
||||
- 按 Key catalog 主责归入 `PJ2026-010502 APIKey`。
|
||||
- Codex-compatible 透传关联 `PJ2026-010204 后端Profile`。
|
||||
- 域名、TLS 和 Caddy 关联 `PJ2026-010604 公开入口`。
|
||||
- 新增 `PJ2026-01050205 APIKey Skill Catalog` 规格。
|
||||
- UniDesk PR:<https://github.com/pikasTech/unidesk/pull/2522>。
|
||||
- merge commit:`8eb62cfbd4ec24f7d42423d6a53646bc3dcfbd46`。
|
||||
|
||||
## 实现
|
||||
|
||||
本地仓库:`/root/superapi`。
|
||||
|
||||
本地 commit:`29db775 feat: add per-key skill upstream loader`。
|
||||
|
||||
主要能力:
|
||||
|
||||
- `config/superapi.yaml` 是唯一配置真相:
|
||||
- native bind、port 和 probe;
|
||||
- 上游 base URL 与允许路径;
|
||||
- public URL、DNS、Caddy config 与 upstream;
|
||||
- API Key `sourceRef/sourceKey`;
|
||||
- 每个 Key profile 的 skill `name + description`。
|
||||
- API Key 从 `/root/.codex/auth.json.pika#OPENAI_API_KEY` 读取:
|
||||
- 仓库、CLI、状态和日志均不保存或输出完整 Key;
|
||||
- 正确 Key 使用恒定时间比较命中 profile;
|
||||
- 未配置 Key 在进入上游前返回 401。
|
||||
- `/v1/responses` 和 `/v1/responses/compact`:
|
||||
- 保留原字符串 instructions;
|
||||
- 追加稳定的 `Company Skills` catalog;
|
||||
- 请求与上游流式响应透明透传。
|
||||
- health 和日志只披露 profile、skill 数量、request id、状态和脱敏指标。
|
||||
- 项目 CLI 提供:
|
||||
- `config validate`;
|
||||
- `l0 probe`;
|
||||
- `native start|status|logs|stop`;
|
||||
- `public plan|apply|status`。
|
||||
|
||||
## L0 验证
|
||||
|
||||
执行:
|
||||
|
||||
```bash
|
||||
bun scripts/superapi-cli.ts l0 probe
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
- `RESULT=PASS`;
|
||||
- `KEY_MATCH=true`;
|
||||
- `INVALID_REJECT=true`;
|
||||
- `PRESERVED_EXISTING=true`;
|
||||
- profile 为 `pika`;
|
||||
- skill 数量为 1;
|
||||
- `VALUES_PRINTED=false`。
|
||||
|
||||
`bun run check` 使用只编译不执行的 Bun build 入口并通过。首次使用 `bun --check` 时发现该版本会实际执行入口,已改为构建到被忽略的 `.state/check`,没有保留误启动进程。
|
||||
|
||||
## L1 与公网验证
|
||||
|
||||
native 服务由项目 CLI 启动:
|
||||
|
||||
- 状态:`ready`;
|
||||
- bind:`127.0.0.1:18159`;
|
||||
- health:HTTP 200。
|
||||
|
||||
公网入口由 owning YAML 渲染的独占 Caddy managed block提供:
|
||||
|
||||
- URL:<https://superapi.hwpod.com>;
|
||||
- DNS:`152.53.229.148`,与 YAML `expectedA` 一致;
|
||||
- Caddy 完整配置 validate 通过;
|
||||
- public health:HTTP 200;
|
||||
- public status:`ready`。
|
||||
|
||||
错误 Key 的公网 `/v1/responses` 请求返回 401,没有进入上游。
|
||||
|
||||
## 真实 Codex 验证
|
||||
|
||||
Codex 使用隔离的 `CODEX_HOME`:
|
||||
|
||||
- `auth.json` 软链接到现有 `/root/.codex/auth.json.pika`;
|
||||
- 不含密钥的 smoke config 指向 `https://superapi.hwpod.com/v1`;
|
||||
- model 为 `gpt-5.5`,wire API 为 Responses。
|
||||
|
||||
首次请求使用域名根作为 base URL,Codex 实际请求 `/responses`,被 allowlist 正确拒绝为 404。将 smoke base URL 修正为 `https://superapi.hwpod.com/v1` 后成功。
|
||||
|
||||
最终真实流式请求证据:
|
||||
|
||||
- path:`/v1/responses`;
|
||||
- status:200;
|
||||
- profile:`pika`;
|
||||
- skillCount:1;
|
||||
- upstreamErrors:0;
|
||||
- 模型最终只返回 `SUPERAPI_SKILL_LOADED`。
|
||||
|
||||
这证明 Codex 实际收到注入的 `pika-company-dev` catalog,而不只是代理本地函数返回成功。
|
||||
|
||||
## 边界
|
||||
|
||||
- 这是虚拟 skill catalog,不会注册到 Codex 客户端 `/skills`。
|
||||
- 当前只保存并注入 `name + description`,不保存完整 skill 文件或脚本。
|
||||
- description 引导 Agent 从公司内网 skill registry 获取后续资料,但网络权限、内网认证和资源版本仍由公司内网负责。
|
||||
- 当前是用户要求的 L1 native 服务:
|
||||
- 进程由项目 CLI 管理;
|
||||
- 未配置 systemd 或容器级重启自恢复;
|
||||
- host 重启后需执行 `native start` 和 `public status`。
|
||||
- `/root/superapi` 当前是本地 Git 仓库,没有远端,因此只有本地 commit,没有 push 或 PR。
|
||||
- 公网开放后观察到常规扫描请求,全部被 allowedPaths 拒绝;业务 Key、description 和上游响应内容未进入日志。
|
||||
@@ -0,0 +1,77 @@
|
||||
# R2.7.7 任务报告
|
||||
|
||||
## 结果
|
||||
|
||||
已对公开入口 `https://superapi.hwpod.com/v1/responses` 完成一次真实同步 Responses 测试。测试使用 `/root/.codex/auth.json.pika` 中的 API Key,但命令输出、日志和报告均未披露 Key 值。
|
||||
|
||||
- request id:`superapi-request-diff-20260718-01`
|
||||
- profile:`pika`
|
||||
- skillCount:1
|
||||
- 上游状态:HTTP 200
|
||||
- 模型:`gpt-5.5`
|
||||
- Responses 状态:`completed`
|
||||
- 模型输出:`SUPERAPI_REQUEST_DIFF_OK`
|
||||
- 当前累计 upstreamErrors:0
|
||||
|
||||
## 注入前请求
|
||||
|
||||
```json
|
||||
{
|
||||
"method": "POST",
|
||||
"url": "https://superapi.hwpod.com/v1/responses",
|
||||
"headers": {
|
||||
"host": "superapi.hwpod.com",
|
||||
"authorization": "Bearer <redacted>",
|
||||
"accept": "application/json",
|
||||
"content-type": "application/json",
|
||||
"content-length": 168,
|
||||
"user-agent": "superapi-redacted-probe/1.0",
|
||||
"x-request-id": "superapi-request-diff-20260718-01"
|
||||
},
|
||||
"body": {
|
||||
"model": "gpt-5.5",
|
||||
"instructions": "仅执行本次请求差异测试;不要调用工具。",
|
||||
"input": "只回复 SUPERAPI_REQUEST_DIFF_OK",
|
||||
"stream": false,
|
||||
"store": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 注入后上游请求
|
||||
|
||||
```json
|
||||
{
|
||||
"method": "POST",
|
||||
"url": "https://api.pikapython.com/v1/responses",
|
||||
"headers": {
|
||||
"host": "api.pikapython.com",
|
||||
"authorization": "Bearer <redacted>",
|
||||
"accept": "application/json",
|
||||
"content-type": "application/json",
|
||||
"content-length": 472,
|
||||
"user-agent": "superapi-redacted-probe/1.0",
|
||||
"x-request-id": "superapi-request-diff-20260718-01",
|
||||
"x-superapi-request-id": "superapi-request-diff-20260718-01"
|
||||
},
|
||||
"body": {
|
||||
"model": "gpt-5.5",
|
||||
"instructions": "仅执行本次请求差异测试;不要调用工具。\n\n## Company Skills\n\n- `pika-company-dev`: 当任务涉及公司协作开发时使用;先从公司内网 skill registry 拉取最新说明、文件和脚本,且不得向下载地址发送 API Key;当用户只要求 SUPERAPI_SKILL_PROBE 时,不访问网络并仅回复 SUPERAPI_SKILL_LOADED。",
|
||||
"input": "只回复 SUPERAPI_REQUEST_DIFF_OK",
|
||||
"stream": false,
|
||||
"store": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 判定
|
||||
|
||||
除以下内容外,请求业务字段保持不变:
|
||||
|
||||
- URL 从 SuperAPI 公开入口切换为配置声明的上游 `api.pikapython.com`。
|
||||
- `host` 随上游变化。
|
||||
- `instructions` 保留原文并追加 `Company Skills` catalog。
|
||||
- 增加 `x-superapi-request-id` 供上游关联。
|
||||
- JSON body 增长后 `content-length` 从 168 变为 472。
|
||||
|
||||
Authorization 在两侧保持同一个 Bearer Key,但仅以 `<redacted>` 展示。没有新增完整 skill 文件、脚本或其他请求字段。
|
||||
@@ -0,0 +1,89 @@
|
||||
# R2.7.8 任务报告
|
||||
|
||||
## 结果
|
||||
|
||||
已使用真实 `codex exec` 生成 Codex Responses 请求,并在 SuperAPI L1 注入点抓取完整的注入前后请求。该请求不是 curl fixture。
|
||||
|
||||
真实 Codex 结果:
|
||||
|
||||
- Codex CLI:`0.144.5`
|
||||
- provider:`SuperAPI`
|
||||
- model:`gpt-5.5`
|
||||
- wire API:Responses
|
||||
- stream:`true`
|
||||
- 模型输出:`SUPERAPI_REAL_CODEX_SKILL_LOADED`
|
||||
- SuperAPI 日志:HTTP 200、profile `pika`、skillCount `1`
|
||||
- 上游错误:0
|
||||
|
||||
## 完整脱敏请求
|
||||
|
||||
- 注入前:
|
||||
- `/root/superapi/.state/captures/codex-real-20260718-01.before.sanitized.json`
|
||||
- 53,216 bytes
|
||||
- mode `0600`
|
||||
- 注入后:
|
||||
- `/root/superapi/.state/captures/codex-real-20260718-01.after.sanitized.json`
|
||||
- 53,562 bytes
|
||||
- mode `0600`
|
||||
|
||||
真实请求具有 13 个顶层 body 字段:
|
||||
|
||||
- `client_metadata`
|
||||
- `include`
|
||||
- `input`
|
||||
- `instructions`
|
||||
- `model`
|
||||
- `parallel_tool_calls`
|
||||
- `prompt_cache_key`
|
||||
- `reasoning`
|
||||
- `store`
|
||||
- `stream`
|
||||
- `text`
|
||||
- `tool_choice`
|
||||
- `tools`
|
||||
|
||||
请求包含 3 个 input item 和 8 个工具定义。注入前 instructions 为 21,335 字符,注入后为 21,508 字符。
|
||||
|
||||
## 差异判定
|
||||
|
||||
除 instructions 外的完整 body SHA-256 一致。原始 instructions 被完整保留,末尾追加:
|
||||
|
||||
```md
|
||||
## Company Skills
|
||||
|
||||
- `pika-company-dev`: 当任务涉及公司协作开发时使用;先从公司内网 skill registry 拉取最新说明、文件和脚本,且不得向下载地址发送 API Key;当用户只要求 SUPERAPI_SKILL_PROBE 时,不访问网络并仅回复 SUPERAPI_SKILL_LOADED。
|
||||
```
|
||||
|
||||
Codex 客户端使用 `https://superapi.hwpod.com/v1`。Caddy 终止 TLS 后,loader 捕获的入口 URL 为内部 `http://superapi.hwpod.com/v1/responses`,并保留 `x-forwarded-proto=https`;注入后上游 URL 为 `https://api.pikapython.com/v1/responses`。
|
||||
|
||||
## 脱敏验证
|
||||
|
||||
完整 sanitized artifacts 已验证:
|
||||
|
||||
- 真实 API Key:不存在
|
||||
- 未脱敏 Authorization:不存在
|
||||
- `/root` 绝对路径:不存在
|
||||
- IPv4:不存在
|
||||
- UUID:不存在
|
||||
- session/thread/turn/installation/request ID:值为 `<redacted>`
|
||||
- artifacts 权限:`0600`
|
||||
- JSON 结构:有效
|
||||
|
||||
## Workspace 与运行面
|
||||
|
||||
用户要求保留 workspace,已保留:
|
||||
|
||||
`/root/superapi/.worktree/codex-real-capture`
|
||||
|
||||
workspace 保留未提交的:
|
||||
|
||||
- Codex provider 一次性 `http_headers` capture ID
|
||||
- SuperAPI 请求对捕获补丁
|
||||
- 通用递归脱敏脚本
|
||||
|
||||
实验进程已停止。正式公网服务已重新从 `/root/superapi` master commit `29db775` 启动:
|
||||
|
||||
- native health:200
|
||||
- public health:200
|
||||
- public URL:`https://superapi.hwpod.com`
|
||||
- 正式 master 未包含捕获补丁
|
||||
@@ -0,0 +1,51 @@
|
||||
# R2.7.9 任务报告
|
||||
|
||||
## 结果
|
||||
|
||||
已将 `/root/superapi/.worktree/codex-real-capture` 中可复用的真实 Codex 请求捕获能力整理并快进合并到 SuperAPI `master`,提交为 `13f4070 feat: add YAML-controlled skill diagnostics`。一次性 Codex capture header 未进入 master,实验 workspace 按用户要求保留。
|
||||
|
||||
## YAML 开关
|
||||
|
||||
owning YAML `config/superapi.yaml` 新增:
|
||||
|
||||
- `gateway.skillInjection.enabled`:控制 Responses instructions 注入;关闭时不解析、不修改 body。
|
||||
- `gateway.requestCapture.enabled`:控制诊断捕获;关闭时即使请求携带捕获 header 也不落盘。
|
||||
- `gateway.requestCapture.headerName`:声明内部 capture header,代理转发前删除。
|
||||
- `gateway.requestCapture.outputDir`:声明捕获产物目录。
|
||||
|
||||
正式状态为 skill 注入开启、诊断捕获关闭。健康接口披露两个布尔开关,不披露 Secret。
|
||||
|
||||
## 实现
|
||||
|
||||
- `src/capture.ts`:受控 before/after 原始捕获、capture id 校验和递归脱敏。
|
||||
- `src/diagnostics.ts`:L0 探针与配置驱动的脱敏函数。
|
||||
- `scripts/superapi-cli.ts capture sanitize --id <capture-id>`:通过 owning YAML 和 profile SecretRef 生成 sanitized artifacts。
|
||||
- `src/proxy.ts`:仅在 YAML 开启且请求携带合法 capture id 时捕获;内部 header 不转发上游。
|
||||
- CLI 已按职责拆分到 293 行,未超过 300 行规范。
|
||||
|
||||
## 验证
|
||||
|
||||
- L0 注入开启:PASS,保留原 instructions,追加 1 个 skill。
|
||||
- L0 注入关闭:PASS,skillCount 为 0,原 instructions 完全不变。
|
||||
- L1 native:固定端口 `18159`,health 200。
|
||||
- 公网入口:`https://superapi.hwpod.com`,DNS、Caddy block、health 均 ready。
|
||||
- 捕获关闭真实 Codex:返回 `SUPERAPI_REAL_CODEX_SKILL_LOADED`,未生成 `.raw.json`。
|
||||
- 捕获开启真实 Codex:Codex CLI `0.144.5`,provider `SuperAPI`,model `gpt-5.5`,HTTP 200,skillCount 1,上游错误 0。
|
||||
|
||||
最终 master 捕获 ID 为 `codex-real-20260718-03`:
|
||||
|
||||
- before:`/root/superapi/.state/captures/codex-real-20260718-03.before.sanitized.json`
|
||||
- after:`/root/superapi/.state/captures/codex-real-20260718-03.after.sanitized.json`
|
||||
- 两份文件权限均为 `0600`。
|
||||
- body 顶层字段均为 13,input item 为 3,tools 为 11。
|
||||
- instructions 长度从 21,335 增加到 21,508。
|
||||
- 除 instructions 外的 body SHA-256 一致。
|
||||
- sanitized artifacts 不含真实 Key、`/root` 路径、IPv4 或 UUID。
|
||||
- capture header 未转发到上游。
|
||||
|
||||
## 最终状态
|
||||
|
||||
- `/root/superapi`:`master` commit `13f4070`,worktree 干净。
|
||||
- 正式 native:ready,诊断捕获已关闭。
|
||||
- 正式 public:ready,health 200。
|
||||
- 实验 workspace:保留,仅 `config/codex-smoke.toml` 保有一次性 capture id 修改。
|
||||
@@ -200,6 +200,24 @@
|
||||
#### R2.7.3 [completed]
|
||||
|
||||
结合管理端 `https://sub.yjxm1221.top grok` API Key 账号连接测试成功的新证据,复核 Codex Grok profile 经 Sub2API `/v1/responses` 的网关链路,区分账号直连测试与分组调度路径,完成任务后将详细报告写入[任务报告](./details/sub2api-upstream-reliability/R2.7.3_Task_Report.md)。
|
||||
#### R2.7.4 [completed]
|
||||
|
||||
只读调研 Sub2API 官方最新源码如何以最小改动或零改动支持按每个下游 API Key 配置并自动加载企业 Codex skill:核对 API Key 请求上下文、Responses instructions 转换、客户端 skill 发现机制、现有配置/API 扩展点与安全边界,比较客户端分发、网关注入和源码扩展方案并给出推荐;不修改 Sub2API、UniDesk CLI、运行面或版本,完成任务后将详细报告写入[任务报告](./details/sub2api-upstream-reliability/R2.7.4_Task_Report.md)。
|
||||
#### R2.7.5 [completed]
|
||||
|
||||
基于用户澄清收敛 R2.7.4:目标仅为按每个下游 API Key 注入企业虚拟 skill 的 name 与 description,由 description 引导 Agent 从公司内网拉取后续文件或脚本;评估现有全局模板、外部代理零源码方案和 Sub2API 最小按 Key 字段及 Responses 注入改动,不实现代码或运行面变更,完成任务后将详细报告写入[任务报告](./details/sub2api-upstream-reliability/R2.7.5_Task_Report.md)。
|
||||
#### R2.7.6 [completed]
|
||||
|
||||
在独立 `../superapi` 实现并验证 description-only 企业虚拟 skill 上游加载器:以 YAML 声明 API Key sourceRef、skill name/description、native 端口、上游 `api.pikapython.com` 和 `superapi.hwpod.com` 公网入口;完成 L0 函数注入测试、L1 native 生命周期与 Codex `.pika` Key 真实 Responses 透传测试,不修改 Sub2API 源码或版本,完成任务后将详细报告写入[任务报告](./details/sub2api-upstream-reliability/R2.7.6_Task_Report.md)。
|
||||
#### R2.7.7 [completed]
|
||||
|
||||
对已部署 SuperAPI 做一次真实 Responses 注入测试,完整展示脱敏后的入口请求与追加虚拟 skill catalog 后的上游请求,核对 request id、profile、skillCount、上游状态和模型 marker,不披露 Authorization 或 API Key,完成任务后将详细报告写入[任务报告](./details/sub2api-upstream-reliability/R2.7.7_Task_Report.md)。
|
||||
#### R2.7.8 [completed]
|
||||
|
||||
使用真实 `codex exec` 产生 Responses 请求,在 SuperAPI L1 注入点做一次可撤销的脱敏 before/after 捕获,验证真实 Codex 请求中的完整字段、skill catalog 追加位置、上游透传结果和 marker;完成后撤销捕获补丁并恢复服务,完成任务后将详细报告写入[任务报告](./details/sub2api-upstream-reliability/R2.7.8_Task_Report.md)。
|
||||
#### R2.7.9 [completed]
|
||||
|
||||
将 SuperAPI 真实 Codex 捕获 workspace 的可复用能力语义合并进 master:由 owning YAML 显式控制 skill 注入与诊断捕获,关闭时透明透传且不落盘;保留一次性 smoke header 和原始捕获产物于实验 workspace,不纳入生产配置;完成 L0、L1、真实 codex exec before/after 脱敏复测并记录证据,完成任务后将详细报告写入[任务报告](./details/sub2api-upstream-reliability/R2.7.9_Task_Report.md)。
|
||||
### R2.8 [completed]
|
||||
|
||||
整理本 MDTODO FILE 的职责层级和编号,并把同一 SUBITEM 下的直接 SUBSUBITEM 一般不超过 20 固化到 mdtodo-edit skill,完成任务后将详细报告写入[任务报告](./details/sub2api-upstream-reliability/R2.8_Task_Report.md)。
|
||||
|
||||
Reference in New Issue
Block a user