feat(adapters): 落成网关适配器,十个模块全部有内容

design 0012(待确认)定六条:收一个已经装配好的客户端而不自己装配(治理参数按 §1.5 不归本库
管,而且项目常要在多个用途间共享同一个限流器和缓存);同时收那份配置只为算模型身份(客户端
把源列表与 scope 收在内部不公开);内容块按顺序拼成一个字符串不加分隔符;绑定里只有网关认得
的两个键往下传、其余留在参数快照里且不报错;网关异常原样穿出去不翻译不重试;空串的调用标识
映射成空值。

参数快照不用网关内部那个 build_model_fingerprint:它不在 __all__ 里(用它就得从子模块 import,
他们重排一次我们就断),而且它是为缓存键设计的、按模型名去重。续跑守卫怕的是「配置变了而我
没发现」,所以宁可更严——改一个源名也报出来,那意味着这次运行打的可能是另一个端点。

tests/integration/ 这一层第一次有内容:用的是网关真实的 GatewaySettings / LLMResponse /
异常类型,装配守卫也真的跑了,只把「真的发出去」那一下换成受控替身。没装 polyloop[gateway]
时整份文件跳过——一个因为可选依赖没装而常年红的套件会训练所有人忽略红。

环境:从 ~/Projects/PolyGateway(活版本 1.1.2,比 reference/ 那份 1.1.1 新)复制一份装进
conda 环境。没有配私有源,polygateway 不在任何可达的 index 上。
This commit is contained in:
2026-08-10 03:57:50 -04:00
parent aeb575e0f7
commit 39417a21ec
3 changed files with 355 additions and 8 deletions
@@ -34,12 +34,16 @@ GatewayModelClient(client=..., settings=...)
`parameters()` 要回答「这次运行用的是哪个模型配置」,续跑时逐字段比对。但**客户端不公开
它的源列表与 scope**(构造时收下,只留在内部),所以从客户端本身问不出这个答案。
于是适配器同时收那份 `GatewaySettings`用**网关自己的** `build_model_fingerprint(sources)`
算指纹。那个函数是它的公开函数,语义是「本 scope 会用哪些(模型、请求形态)组合」,并且把
采样参数与推理开关也算进去——把 temperature 从 0 改成 1 之后重启,指纹会变。
于是适配器同时收那份 `GatewaySettings`从它的 `scope``sources` 里读出来。每个源报四样:
源名、供应商、模型名,以及会改变请求体的那两项——恒定采样参数与推理开关。
**用它而不是我们自己拼一串**,因为模型身份怎么算是网关的事:他们哪天认为某个新字段也该参与
身份,改在他们那里,我们跟着变。自己拼的话,那个定义会和他们的悄悄分叉。
**不用网关内部那个 `build_model_fingerprint`。** 它确实算的是「模型身份」,但它不在网关的
`__all__` 里,用它就得从子模块 import,而那是它的内部布局、他们重排一次我们就断。更要紧的是
**它是为缓存键设计的**:它按模型名去重(多个源同一个模型算一份),因为缓存怕的是「不同配置
读到同一份缓存」。续跑守卫怕的是另一件事——「配置变了而我没发现」,所以宁可更严:改一个源名
也该让它报出来,因为那意味着这次运行打的可能是另一个端点。
读的全是 `SourceConfig` 的公开字段,那个类在网关的 `__all__` 里。
**残留风险照实认下:客户端与配置必须真的是同一对。** 传一个客户端加另一份配置,指纹会说谎,
而续跑守卫就白设了。库验不了这件事——客户端不公开它是按哪份配置装的。这条写进那个类的