Skip to Content
agent-apps

OpenRouter Decisions 契约

Frevana 包装 M1 客户端契约:O/F/L 与失败语义

2026-11-07 · 建议入库路径:docs/openrouter-decisions.md。范围仅官方 OpenRouterTeam/skills 的 openrouter-decisions。本稿可冻结请求构造、响应校验及失败语义;Frevana 服务端透传兼容、鉴权获取路径和真实 Host 行为未验,不宣称已完成线上契约验收。

整体边界见 Decisions 架构。

1. 来源与契约级别

标识含义
F:Frevana 声明本地完整 OpenAPI 和 slice 可直接证实的 endpoint、security、headers、200
O:官方形状Owner 提供的官方 SKILL 与 references 快照;用于定义兼容目标,Frevana OpenAPI 没有声明其 body/response 字段
L:本地策略本仓客户端主动收窄、校验、门控与诊断规则,不是服务端承诺
UNKNOWN需要实现核查或授权实验,当前不可作为可用能力依赖

Frevana operation:POST /openrouter/v1/decisions,operationId=OpenRouterCompatibleController_decisions,tag=OpenRouter Compatible,security=bearer(HTTP Bearer/JWT)。requestBody 缺省,不是“声明了空 JSON body”;responses 仅列 200、没有 schema。 不能从这里推导所有官方字段均已透传。

官方接口为 POST https://openrouter.ai/api/alpha/decisions;本项目只用 POST https://api.frevana.com/openrouter/v1/decisions 做推理。不把 messages/chat/completions、Responses 或 System One 路由拿来替代。本轮不实现其它 17 个官方 skills。

2. 官方与包装差异

项目官方 skill / OpenRouterFrevana 本项目
推理目标/api/alpha/decisionsF:/openrouter/v1/decisions
AuthorizationOpenRouter API keyF:Bearer JWT;按本任务约定为 Frevana 用户/会话凭据
JSON bodyO:model + state + questions采用 O 的兼容目标,F 无 schema,需验证
answers / usageO:typed answers 与使用信息按 O 校验;无 F schema,不预设外层 envelope
归因官方脚本不提供这组 Frevana 头F:5 个可选归因头,去重发送
选模公开 models catalog开发阶段仍读公开 catalog;F 无 decisions models endpoint
传输脚本官方 HTTP/SDK 直连官方推理改编为仅 Frevana;不保留官方默认推理 URL 和 key 环境变量
错误官方可有错误规范F 本地规格未列,客户端以 HTTP 状态和 unknown 错误体处理

3. 请求字段表

以下请求字段均为 O(Frevana OpenAPI 未声明);“必需”表示本稿兼容契约要求,不是 F schema 的 required。

字段类型 / 约束本轮处理
model非空 string,实际在线请求必需L:只收公开 catalog 确认的 canonical_slug 或版本化 id;禁止 alias;CLI 可补齐配置,但发出 body 必须有 model
statestring / JSON object / JSON array,必需优先具名 object,只发问题需要的字段;null、number、boolean 作为顶层 state 不合法
questions非空 object,key 为应用自定 question ID一题一个 primitive;key 用于结果匹配,不靠 key 向模型传达语义
questions.<id>.typenoul / choice / score / box,必需严格判别联合,不接受 chat 类型
questions.<id>.instructionsstring 或 JSON object/array,必需L:默认写清楚的字符串;问事实,不要求生成解释或操作指令
questions.<id>.criteria见下表与 instructions 同向;不包含 API 参数或业务阈值
session_id可选 string本地子集接受;F 透传及分组效果未验,不是登录会话或归因头替代品
user可选 string本地子集接受;不得冒充鉴权主体;默认省略,F 透传未验
trace、providerO 参考提到的观测/路由扩展,具体结构本稿不冻结官方捆绑脚本不接收;L:首轮拒绝,未来明确 schema 且核验 Frevana 后另评审
assetsO 图像扩展 map首轮本地子集拒绝,不因官方可用就宣称 F 支持;后续按图像能力单独评审
images、messages、temperature 等不在本轮 Decisions 请求子集L:拒绝,不能原样套用 chat body

首轮顶层 allowlist 为 model/state/questions/session_id/user;question 只接受 type/instructions/criteria。未知请求字段报本地 ValidationError,避免被静默丢弃。JSON 结构必须可序列化;函数、循环引用和非有限数不作为有效输入。

primitivecriteria 请求形状语义与适用条件
noul可省略;提供时恰好 {"true": criterion, "false": criterion}独立二元事实 P(yes);多标签可各问一题,不把中间概率读作中等强度
choiceoption-name → criterion 的 object,至少两项互斥选一;criterion 通常为字符串或 JSON 结构;官方脚本还允许 null,L 首轮要求明确非 null 描述
score有序 criterion array,至少两级,低到高一个维度的有序程度;不是金额、数量或算术计算器
box不允许 criteria指令指明目标与图像;所给官方快照限定 Jev 1.14,当前可用模型/版本须另查能力与探针

criterion/instructions 的 JSON 结构指 object/array 或 string,不是任意 boolean/number/null。choice 的 null 例外仅为上游脚本能力差异,首轮不使用。

图像与 box 的覆盖边界

四 primitive 均纳入契约设计,首轮 App 只演示文本 noul(choice 可选)。将来图像输入优先用顶层 state array:字符串说明旁放 {"type":"image_url","image_url":{"url":"data:image/png;base64,..."}},参考说明远程 http(s) 图像 URL 不会被拉取。不同模型的格式、尺寸与 token 限制不可互相套用,F 对图像的兼容和大小限制 UNKNOWN。

box 即使目标不存在也可能返回四条边;必须同请求配一个存在性 noul,仅在 yes 分支读取坐标。no 分支为无匹配,中间区 fallback。不要把非空 box 当存在证据。本轮不发送图像或 box 探针。

4. 响应字段表与运行时校验

以下也全部为 O 兼容目标(Frevana OpenAPI 未声明),数值示例不是 Frevana 实测。接收 HTTP 200 后仍将 body 视作 unknown,从顶层开始校验;不调用 .choices[0].message。

字段形状与要求本地处理
id可选 string有则可用于关联;不可作为幂等承诺
model必需 string,响应的实际 build记录并核对请求 pin;不匹配则阻断门控
provider可选 string缺省不捏造
answers必需 object,question ID → answerL:键集合与请求完全一致;缺失/多出/错误 type 都是 ProtocolError
usage必需 object(本地兼容目标)缺失时报告协议不兼容,不填零
usage.input_tokens / output_tokensnumberL:有限非负数,记录计量;不凭响应反推出原始 state
usage.cost可选 number,O 说明单位 USD有限非负;缺省为未知,不能当 0;不等于已确认的 Frevana 结算金额

每个 answer 必须有与 question 相等的 type,主结果字段不可省略:

answer.type必需主结果可选字段本地校验
noulnoul: numberprobabilities、confidence(如存在)noul 为有限 [0,1];不以 confidence 覆盖 noul
choicechoice: stringprobabilities: Record<string, number>、confidencechoice 必须在请求 criteria;有 probabilities 时 key 必须与选项对应,值有限 [0,1]
scorescore: numberprobabilities、legend: Record<string, criterion>、confidencen 级时 L 限于 [0,n−1];map key 对应 "0"…"n−1";legend 保持原 criteria 的结构
boxbox: {top,bottom,left,right},各 numberconfidenceL:坐标有限 [0,1],top≤bottom、left≤right;原点为左上角

probabilities、confidence、legend 是可选,读取前判存在;不存在不等于零。confidence 若有则要求有限 [0,1],它描述分布集中程度,不是正确率或行动授权。score 是层级位置的概率加权值,不据此反推精确数值。概率分布如需和为 1 的检查,实施时写明浮点容差,不能要求每个浮点结果精确相等;不得默默归一化后继续决策。

响应未知的附加字段允许保留为脱敏诊断,不让其参与业务;已知字段形状错误不能忽略。不凭空兼容 {data: ...}、SSE 或其它 envelope,观察到差异后先修订契约再适配。请求与响应都从 unknown 校验;缺答案、类型错、非 JSON、错误模型或越界值走错误/fallback,绝不默认批准。

5. 头字段、归因与鉴权

Header必需性 / 来源含义与约束
Authorization: Bearer <FREVANA_SESSION_JWT>F security 必需;凭据语义按 Owner 上下文Frevana 用户/会话 JWT;不能用 OpenRouter key、catalog key、Docs Basic 账号替换
Content-Type: application/jsonL 发送要求JSON body
x-frevana-agent-app-instance-idF 可选 string当前用户拥有的 App instance/team ID;vibe- 前缀可表示 vibe session。缺省不记录 Agent App 用量归因
x-frevana-agent-run-idF 可选 stringrun ID,文档说明写入 usage.run_id
x-frevana-agent-channel-idF 可选 string执行通道/会话标识,文档说明写入 channel_id
x-frevana-agent-job-idF 可选 stringJob ID,文档说明写入 job_id;hello 无 Job,不伪造
x-frevana-agent-trigger-typeF 可选 stringmanual/scheduled/workflow/audit 是示例,不是 OpenAPI enum;hello 可传 manual

OpenAPI 对五个归因头各定义两次,共十条 parameter。客户端按不区分大小写的 header name 去重,每名只发送一个值,合并描述而不发逗号拼接双份。其它归因值不从用户自由文本/state 提取,也不能靠 getRootPath 推导。API 允许可选不等于本项目完成用量追踪:正式归因验收必须有合法实例 ID 及服务端记录证据;缺 ID 时明确标“无归因”,不填假值。trace/session_id/user 不替代这组归因头。

Bearer 来源与传输路径:UNKNOWN

Host 文档只证实存在 auth shim 注入步骤与 frevana-auth-request 分发,没有在已读资料中给出可采用的认证方法签名。既不能断言 JWT 已注入页面,也不能断言必然要走 Host 代理。window.frevana.app.getRootPath、agent/files 等存在不证明认证链路可用。

设计首选 Host 受信侧代理加入 Bearer 和归因,App 注入一个本地 DecisionTransport。若之后确认有适合页面的受限凭据接口,再评估浏览器直发;必须取得实际 iframe 的 CSP/CORS/preflight 与刷新/退出证据。未取得合法机制时返回 AuthUnavailable,禁止在线提交。不得发明 window.frevana.auth.getToken() 或 frevana.fetch(),不得读 userData、Application Support、auth-preload、SQL 或账号文件“补齐认证”,不得将 token 打入 VITE_*、持久化或日志。

探测顺序:只读核对 shim/handler 签名与校验 → 记录 Host 版本和受信上下文 → 隔离 App 验方法与资源/网络能力 → 另经授权做一次最小 Frevana 付费请求,验证实际 response/model/归因。OPTIONS 不是推理验收;空 POST 也可能执行或收费。本轮全部停留在文档核查,无真实推理请求。

6. 合法样例:官方形状下的客户端输入

下面可通过拟议本地校验;不代表已在 Frevana 调通。模型字符串引用所给官方响应快照中的版本格式,不是本轮选定或确认仍在售的模型;正式运行须用实时公开 catalog 确认的 pin 替换。本例不提供可直接误运行的 curl。

目标为 POST https://api.frevana.com/openrouter/v1/decisions。头:Authorization 的值由受信传输层临时提供,Content-Type 为 application/json,可选 trigger-type=manual;其它归因头仅在有真实上下文时填写。

{
  "model": "typesafe/jev-1.13-20260917",
  "state": {
    "message": "我被重复扣款了,请退还多扣的费用。"
  },
  "questions": {
    "requests_refund": {
      "type": "noul",
      "instructions": "`message` 的发送者是否在请求退还已支付的费用?",
      "criteria": {
        "true": "发送者明确希望退还已经支付或被扣除的费用。",
        "false": "发送者只咨询退款政策、查询到账状态,或明确拒绝退款。"
      }
    }
  }
}

仅供离线协议测试的对应 response fixture(合成数值,未实测):

{
  "model": "typesafe/jev-1.13-20260917",
  "answers": {
    "requests_refund": { "type": "noul", "noul": 0.82 }
  },
  "usage": { "input_tokens": 100, "output_tokens": 8 }
}

可选字段被省略是合法情况,不能因为缺 confidence/cost 就补零。该 0.82 只能用于演示解析与分支,不是定阈值证据。

7. 非法样例:应在本地拒绝,不发网络

{
  "model": "typesafe/jev-1.13-20260917",
  "state": { "message": "我想了解退款政策。" },
  "questions": {
    "requests_refund": {
      "type": "noul",
      "instructions": "`message` 的发送者是否请求退还已支付费用?",
      "criteria": { "yes": "请求退款", "no": "仅咨询政策" }
    }
  }
}

非法点唯一且明确:noul.criteria 提供时必须是字符串键 true 和 false,不能是 yes/no。预期 ValidationError 指向 questions.requests_refund.criteria,不出站、不产生默认回答。不能断言 Frevana 对此一定返回 400,因为 F 没有错误 schema。

8. 官方七步 → 契约与验收

步骤本项目要求验收证据
1 判断 vs 计算退款意图为判断;金额运算、日期比较、计数、ID/路径抽取、确定政策留代码;规则已定结果则跳过模型policy 的规则表与空输入分支
2 primitivenoul 独立事实,choice 互斥,score 有序,box 定位;可共存标签不强塞 choice每题选型理由与四形状离线 fixture
3 最小 state只发问题读取的 message/上下文;不发根目录、凭据、UI 状态或只供代码规则使用的字段state builder 字段审查
4 questionsinstructions 和 criteria 含义完整,问事实、避免双重否定;question key 不承担说明;运行时选项用名字不靠数组位置人工仅看 state+question 能答;无其它题依赖
5 选模 + API开发时公开 catalog 筛选能力/上下文/价格/provider,pin canonical_slug 或版本 id;推理只到 Frevanacatalog 时间戳/摘要、pin、实际响应 model;本轮尚缺在线证据
6 门控阈值为命名常量,保留 raw probabilities;所有分支含 fallback;confidence 不等于正确/授权可复核真值表和边界测试
7 探针后信阈值代表性样本、含否定和攻击、留出集;改模型/问题/输入构造即重跑原始 request/answer、预期路由、模型、延迟、成本、阈值来源;本轮不运行

退款示例可暂用 REFUND_YES_MIN=0.7、REFUND_NO_MAX=0.3 作为未校准演示常量,不是生产结论:

前提 / 输出代码结果
空输入或代码规则直接确定本地提示/已定结果,跳过请求
合法回答 p≥YES_MIN展示“退款请求”建议;不实际退款
合法回答 p≤NO_MAX展示“其它请求”
NO_MAX < p < YES_MIN人工判断 fallback
鉴权/HTTP/超时/取消/协议或模型不匹配展示明确错误/取消;不能当作 no 或 yes

没有 fallback 的真正二分逻辑可从官方建议的 0.5 起步,但也须探针。choice 或 box 与 presence noul 配对时仅在 yes 分支消费;独立问题的概率不要求互补,不跨 primitive/模型复用阈值。noul 接近 0.5 是不确定,不是中度退款意图。

9. M1 冻结清单与后续验证

本稿冻结:官方形状下的本地请求 allowlist、四 primitive 的区别、逐问题响应匹配、Frevana 单推理目标、去重归因头、无合法认证即禁提交、原始概率与门控分离、合法/非法例的本地预期。

M1 评审可通过文档冻结;以下仍 OPEN,不因评审通过自动关闭:Frevana 对 body/可选字段/四 primitive/response 的实际兼容;JWT 获取与刷新;Host 代理或浏览器直发选择;实例归因链;模型可用性与版本保持;CORS/CSP;错误体/计费/重试语义。首轮仅 noul 在线验证也不能宣称其它 primitive 已实测。没有付费探针时阈值仍未校准。

10. 参考

本地依据(Owner 打包快照,2026-11-07):openrouter-decisions-SKILL.md(sha256 32e7f139e70b…0b65fc)、decisions-api.md(b9dba95c2a2a…9d1071d)、question-design.md(046243042511…2d17c2)、models.md(64f6083b79cb…8e24b39)、decision-model-limits.md(7981f8a7cb63…7495804);Frevana decisions OpenAPI slice(6a3a1e355221…fe8b219)与完整 OpenAPI 本地副本 .tmp-verify/frevana-openapi-full.json(sha256 前缀 454d5f6fe702bff8248f)。快照目录:/tmp/codex-arch-decisions/context/。外置资源与构建交付遵循 前端栈,其 UNKNOWN 不在本稿降级。整体边界见 Decisions 架构。

官方来源:openrouter-decisions、Decisions API。脚本改编仅限 lib.ts 的校验骨架与 decide.ts、models.ts 的职责参考;2026-11-07 只读核对相对浮动 main,上游 revision 未 pin,实施时锁 commit/license;不复制默认直连推理行为。Frevana Docs UI 与 OpenAPI 本轮使用本地副本,未进行 Basic 登录。

On this page