docs: cut 1.3.3 notes for the tier work
CHANGELOG gets all five breaking changes, not the one the draft had: ThinkingCapability's constructor, two ports that grew a parameter with no default, resolve_thinking's new return type, and ProviderProfile's single wire field. Behaviour changes get their own section, including the one that is easy to miss — the openai fallback segment no longer refuses an unknown shape, so a downstream that parks a foreign model there and asks for thinking used to fail at assembly and now sends nothing at all. minimax is called out as the exception it is: the gateway proved M3 does not think without a parameter, so that segment keeps its medium and its downstreams see no change this release. The capability table is reported as it stands — 17 of 24 rows measured, 7 still on documentation, with the reason each one went unmeasured, so nobody reads "measured" into a row that is a guess. The auto limitation and its deliberate MiniMax-M3 inconsistency are written down rather than left for someone to trip over; issue #21 holds the real fix. ARCHITECTURE had five claims that measurement showed had gone false: the cache key formula, the field count, the reconcile predicate and its throttle key, and two field lists. README's FIELD set was missing the two new keys it calls exhaustive. docs-convention still opened by announcing a 17-page site that has not existed since August. It now says what is actually there — one placeholder page pointing at .env.example, CHANGELOG and the source docstrings — and says which four files carry the sync gate while the site is down.
This commit is contained in:
@@ -1,5 +1,77 @@
|
||||
# Changelog
|
||||
|
||||
## 1.3.3(2026-09-05)
|
||||
|
||||
推理从「开 / 关」升级为**档位**(issue #20)。`enable_thinking: bool | None` 表达不了新一代模型:GLM-5.3 官方强制推理、只接受 `low/high/max`,`none` 不是它的档位——二态布尔在它上面无档可填,下游只能手写 `extra_body`,而那条路会静默绕过本库为推理准备的三道机制。本版把档位做成一等公民:八档封闭词汇、源级与请求级两个入口、能力表按档位登记、缓存 key 与遥测各加一维。
|
||||
|
||||
**版号是 patch(2026-09-05 人类指令,不因破坏性变更走 minor),但本版含五处破坏性变更与四条行为变更。** patch 版号从设计上就不承担预警职责,预警只能由这份 CHANGELOG 扛,故全部置于最前。
|
||||
|
||||
### 请先读这一条(一):五处破坏性变更
|
||||
|
||||
| # | 位置 | 变更 | 谁会当场断 |
|
||||
|---|---|---|---|
|
||||
| 1 | `ThinkingCapability` | 构造签名 `can_disable: bool` → `supported_efforts: tuple[Effort, ...]` | 自建能力表、**按位置参数**构造的调用方 |
|
||||
| 2 | `ports.Transport.complete()` | 新增**无默认值**参数 `reasoning_effort` | 任何自建 transport 实现 |
|
||||
| 3 | `ports.TelemetryRecorder.record_llm_call()` | 新增无默认值参数 `reasoning_effort`(25 → 26 参) | 任何自建 recorder 实现 |
|
||||
| 4 | `thinking.resolve_thinking()` | 第三参数由 `bool` 换成 `Effort`,**返回类型由 `Mapping` 改为 `ThinkingResolution`** | 直调它的读侧代码一律断 |
|
||||
| 5 | `providers.ProviderProfile` | 两个字段 `thinking_on` / `thinking_off` → 单字段 `thinking: ThinkingWire` | 自建 profile 的调用方 |
|
||||
|
||||
第 1 条的 `can_disable` **保留为只读派生属性**(`Effort.NONE in supported_efforts`),只读它的代码一行不用改;不可兼容的只有位置参数构造。第 2、3 条按这两个端口的既有纪律**不设默认值**:库外没有第三方实现者,带默认值只会让漏传时静默落一个默认值。第 4 条的新返回值是 `ThinkingResolution(payload, applied_effort)`——原来那个 mapping 现在是 `.payload`,多出来的 `.applied_effort` 是开了 `nearest` 映射后**真正发出去**的那一档。
|
||||
|
||||
### 请先读这一条(二):不改一行代码也会变的四条行为
|
||||
|
||||
| # | 变更 | 影响 |
|
||||
|---|---|---|
|
||||
| 1 | `openai` / `anthropic` / `google` 三段的「开」由注入 `{"reasoning_effort":"medium"}` 改为**不注入任何档位**(`on_base={}`) | `ENABLE_THINKING=true` 的下游从此走模型自己的默认档。旧版那个 `medium` 是库替下游做的档位判断,而 `medium` 在 GLM / kimi / deepseek 的档位表里根本不存在,正是本版要消灭的东西。要指定强度请显式配 `REASONING_EFFORT` |
|
||||
| 2 | `openai` 段的**关闭形态**由「形态未知即报错」放宽为 OpenAI 标准形态 | 把别家模型挂在 `openai` 段下并配 `ENABLE_THINKING=true` 的下游:旧版在**装配期**报错,新版既不报错、也不注入任何字节 |
|
||||
| 3 | `kimi-k3` 由「不可关闭」改为**可关闭** | 1.3.x 此前给它配 `ENABLE_THINKING=false`(等价 `reasoning_effort=none`)会报错并把你指向 `low` 档;本版直接放行。改的依据是实测推翻了当初的保守登记:请求 `none` 后短提示词 5/5 轮 + 长上下文 3/3 轮无任何推理信号、completion 恒 9 token,与同模型 max 档的锚点可分 |
|
||||
| 4 | 缓存 key 加入 `reasoning_effort` | 只有**新配** `REASONING_EFFORT` 的源冷启动一次;只配 `ENABLE_THINKING` 或什么都没配的源,key 字面量逐字不变 |
|
||||
|
||||
**`minimax` 段是第 1 条的例外,本版对 minimax 下游没有任何行为变化。** 原本四段一并改,但真实网关实测显示 MiniMax-M3 在不带任何推理参数时**不推理**(5/5 轮),而 openai / anthropic / google 三家的模型默认推理。对 minimax 而言「不注入即为开」这个前提不成立,改了会让存量 `ENABLE_THINKING=true` 的调用**静默停止推理**,故该段的 `on_base` 维持旧的 `{"reasoning_effort": "medium"}` 逐字不变。
|
||||
|
||||
### 新增能力
|
||||
|
||||
| 新增 | 说明 |
|
||||
|---|---|
|
||||
| 八档 `Effort`:`none` / `auto` / `minimal` / `low` / `medium` / `high` / `xhigh` / `max` | 封闭词汇,取四家参考实现共同收敛的那一套。`none` = 要求不推理(与「不表态」是两回事),`auto` = 要求推理但不指定强度 |
|
||||
| `{SCOPE}__{PROVIDER}__{N}__REASONING_EFFORT` | 源级默认档。`ENABLE_THINKING` 保留,降为它的语法糖(`true` ≡ `auto`、`false` ≡ `none`、缺省 ≡ 不表态);两键语义矛盾(如 `true` + `none`)在**装配期**报错,不做「后者赢」的静默兜底 |
|
||||
| `{SCOPE}__{PROVIDER}__{N}__EFFORT_FALLBACK` | `error`(缺省,报错)或 `nearest`(映射到最近档并 warning)。默认报错的理由是钱:一次静默的 `medium → max` 在部分模型上是数倍账单 |
|
||||
| `chat(reasoning_effort=...)` | 请求级覆盖,优先级高于源级;裸字符串会在入口归一 |
|
||||
| `LLMResponse.applied_effort` | 本次**实际**跑在哪一档(开了 `nearest` 时与请求档分叉)。字段追加在末尾,既有字段只增不改名 |
|
||||
| 四个新 provider 段 `zhipu` / `moonshot` / `anthropic` / `google` | 连同既有 `qwen` / `deepseek` / `minimax` / `openai` 共八段 |
|
||||
| 包根新增导出 `Effort` / `EFFORT_ORDER` / `ThinkingWire` / `ThinkingResolution` | 深路径 import 会被内部重组打断,一律从 `polygateway` 包根取 |
|
||||
|
||||
档位不支持时**报错必带可执行替代**:模型关不掉推理时,错误文案直接给出该模型最省的那一档和该配的 env 键名。只报错不给出路,下游只会退回 `extra_body`——而那正是 issue #20 的成因。
|
||||
|
||||
### 遥测:第 26 个 INSERT 字段 `reasoning_effort`
|
||||
|
||||
`llm_calls` 新增一列 `reasoning_effort TEXT`(INSERT 字段 25 → 26,物理列 26 → 27)。列可空,`NULL` 表示调用方**没表态**;它与 `'none'`(明确要求不推理)是两回事,折叠成任一档都等于替上游声称了一件它没说过的事。加这一列是为了让「不同档位是不是真有用」这类压测在数据侧能分组——此前 25 列里没有任何一列能回答「这一行跑在哪档」。
|
||||
|
||||
**成功行与失败行不是同一把尺子。** 开了 `EFFORT_FALLBACK=nearest` 的源上,成功行记的是**映射后的实发档**(读 `response.applied_effort`);失败尝试没有响应、实发档无从得知,记的是**请求档**。故 `GROUP BY reasoning_effort` 不带 `error IS NULL` 时,两种尺子会混进同一个分组。缓存命中行与终态失败行同样只记请求档——它们手上没有选中源,源级档位与 `nearest` 映射都无从谈起。embedding / OCR 两条路径没有推理语义,该列恒 `NULL`。
|
||||
|
||||
补列走既有的 `PGW_TELEMETRY_SCHEMA_MODE`,两端 DDL 与 `COLUMNS` 同源。**manual 档的下游会看到一处文案变化**:旧表的缺列告警会多点名 `reasoning_effort` 这个维度,并附上对应的 `ALTER TABLE ADD COLUMN` 语句。
|
||||
|
||||
### 能力表口径:24 条里 17 条经 new-api 实测、7 条仍是文档推定
|
||||
|
||||
`DEFAULT_CAPABILITIES` 共 24 条,每条 `evidence` 自报家门(实测日期、轮数 N、判据、锚点,或「文档推定」及其四方出处)。**读能力表请以逐条 evidence 为准,本版不存在「能力表已全部实测」这回事。** 未能实测的 7 条与原因:
|
||||
|
||||
| 模型 | 未覆盖的原因 |
|
||||
|---|---|
|
||||
| `claude-opus-5`、`claude-sonnet-5` | 该渠道 claude 全系返回 429「api key 7 天限额已用完」,5/5 轮失败;`none` 档还额外依赖网关把 `reasoning_effort=none` 转成 `thinking` 关闭形态,同样未经验证 |
|
||||
| `gemini-3.1-pro` | 该渠道本型号上游报错(`bad_response_status_code` / `openai_error`),5/5 轮失败,连默认档基线都没取到。默认档「官方文档说 high、OpenRouter 说 medium」两源打架**仍未决**,本版不选边 |
|
||||
| `gpt-5.4` | 全账号限流(429 All available accounts are currently rate-limited),5/5 轮失败。同代的 `gpt-5.5` 已实测且与清单逐字相符,可作旁证但不是本型号的证据 |
|
||||
| `glm-5`、`glm-5.1`、`glm-5.2` | 请求这三个型号时,渠道 5/5 轮把流量路由到 `glm-5.3`(issue #20 记录的 6/6 复现);拿到的行为不属于本型号,整组数据作废 |
|
||||
|
||||
`glm-5.2` 的下游风险要单独说:在这条渠道上给它配 `none`,库会照文档推定放行,而真正服务请求的 `glm-5.3` **关不掉推理**;运行期对账会喊,但那是事后。
|
||||
|
||||
另有两条与实测相关的收获值得下游知道:同一批实测发现 `zhipu` / `moonshot` 这条渠道**不校验档位值**(未登记的 `medium` 也照单收下并返回 200),故「网关没报错」在这两家上**不构成**「该档受支持」的证据;而 `openai` 那条会校验(清单外的 `max` / `minimal` 被上游 400 拒)。
|
||||
|
||||
### 已知限制:`auto` 不等于「强制开推理」(issue #21)
|
||||
|
||||
`reasoning_effort=auto`(含它的语法糖 `ENABLE_THINKING=true`)在 `on_base={}` 的三个 provider 段(`openai` / `anthropic` / `google`)上表达的是「**用模型自己的默认档**」,库不注入任何字节。若某模型默认就不推理,这个配置**既不报错也不开推理**。正解是让 `auto` 受能力表约束——模型不支持「由模型自定」时报错并指路显式档位,属公共行为变更,留到下一版(gitea issue #21)。
|
||||
|
||||
与之相连有一处**刻意的不一致**,请勿误读:`DEFAULT_CAPABILITIES` 里 `MiniMax-M3` 的 `supported_efforts` **不含 `auto`**(实测结论——它的默认档不推理),而 `minimax` 段的 wire 会为 `auto` 注入 `{"reasoning_effort":"medium"}` 并被放行。`resolve_thinking` 的 Phase 5 对 `auto` 无条件放行(`auto` 不是写进 `effort_key` 的取值,而是「不写 `effort_key`」),**能力表拦不住这条路**;当前是由 wire 侧的权宜之计兜住的。别把它读成「能力表能挡住 auto」。
|
||||
|
||||
## 1.3.2(2026-08-28)
|
||||
|
||||
**本版不改库代码。** `tools/` 与 `tests/` 都不在 pip 包内(脚本随仓库分发,见 README),故 1.3.2 的 wheel 与 1.3.1 **除版本号外没有任何差异**(`__version__` 与包元数据是唯一的改动)。升级它不会改变任何库行为——本版的内容是运维脚本 `tools/telemetry_retention.py` 的一处契约扩展,以及测试隔离的重建。若你只用库本体,可以跳过本版。
|
||||
|
||||
Reference in New Issue
Block a user