test(adapters): 逐适配器两向能力断言 + AdapterIngress 访问器

用户要求:16 个适配器逐个验证两个方向(出向序列化 / 入向解析)重构后都没坏。

- 新增 VM.AdapterIngress(name):暴露适配器认领的入站路径,供运维面与测试查看。
- 新增 TestEveryBundledAdapterTwoDirections:对每个内置适配器断言
  1) 上游向 transform_request 存在且可调用;
  2) 出向 — 声明了 serialize_response 的必须可调用且产出合法 JSON/SSE,
     未声明的确认走内核 OpenAI 兜底(两种都合法);
  3) 入向 — 声明了 adapter.ingress 的必须同时实现 deserialize_request
     (否则内核会让出给空解析器),实现了钩子却没声明 ingress 的也报错
     (内核永远不会调用它)。
  12 个内置适配器全部通过。

隔离实例实测(19 源 + 16 适配器):
- 启动无解密失败/崩溃,16 适配器全加载。
- 入向让出决定性实证:装入认领 /v1/messages 的 zzclaimer 并移除 anthropic 后,
  畸形 body 被适配器解析成 model=ZZ-CLAIMER-WAS-HERE,内核据此路由得
  404 model_not_found —— 证明内核确实让出(活实例复现,非仅单测)。
- 真实请求两向贯通:deepseek-v4-flash / sensenova-6.8-flash-lite 返回 200 真实响应;
  其余源返回上游 502(配额/渠道),说明请求正确到达了各适配器的上游。
This commit is contained in:
JianFeeeee
2026-10-12 16:37:23 +08:00
parent 3c59c33c58
commit d6d41209d9
2 changed files with 108 additions and 0 deletions

View File

@ -1621,6 +1621,20 @@ func (v *VM) AdapterVersion(name string) string {
return p.static.version
}
// AdapterIngress returns the client-facing endpoint path an adapter CLAIMS
// (its static.ingress), or "" when it claims none. Exported so operator-facing
// surfaces (and tests) can see which adapter, if any, has taken over parsing of
// an inbound endpoint — the same declaration AdapterForIngress consults.
func (v *VM) AdapterIngress(name string) string {
p := v.pool(name)
if p == nil {
return ""
}
p.mu.Lock()
defer p.mu.Unlock()
return p.static.ingress
}
// EffectiveAdapterName resolves the name an adapter is actually registered
// under, given the key it was loaded with.
//