diff --git a/CHANGELOG.md b/CHANGELOG.md index 175a6d4..ff182ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 未发布(issue #5 + #6) +## 1.0.6(2026-08-02) 推理开关能力建模与 `reasoning_tokens` 采集。`enable_thinking=False` 此前对 `minimax` / `openai` 两类源**完全不产生效果**——两个 profile 的 thinking 两档皆为空字典,`payload.update({})` 是空操作,而配置方以为关掉了推理。这比"不提供这个开关"更危险:不提供的话调用方会去找别的办法,提供了但静默失效,调用方就带着一个错误的前提往下走。一个下游项目正卡在这上面。 diff --git a/pyproject.toml b/pyproject.toml index c6cfc37..73aea52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "polygateway" -version = "1.0.5" +version = "1.0.6" description = "PolyGateway:实验室统一的大语言模型(LLM/VLM/OCR)调度与中转库——多源、限流、重试、熔断、缓存、遥测" requires-python = ">=3.11" dependencies = [ diff --git a/research-wiki/designs/2026-08-02-thinking-capability-design.md b/research-wiki/designs/2026-08-02-thinking-capability-design.md index ebe6f93..271186a 100644 --- a/research-wiki/designs/2026-08-02-thinking-capability-design.md +++ b/research-wiki/designs/2026-08-02-thinking-capability-design.md @@ -185,9 +185,13 @@ R3 与 R4 的极性相反,这是刻意的,借鉴 LiteLLM 的两极性纪律 |---|---|---| | unit | `resolve_thinking` 真值表(R1–R5)、`_coerce_reasoning_tokens` 形态防御、注入优先级、装配守卫报错、缓存指纹变化与不变性 | **是**(CI 可跑) | | integration | 遥测两后端新列写入与 ALTER 迁移 | **是** | -| **e2e(真实 API)** | 见 9.2 | 不进 CI 自动门,但**合并前必须真跑并存档报告** | +| **e2e(真实 API)** | 见 9.2 | 打 `slow` 标记被默认排除;**合并前必须 `-m slow` 真跑并存档报告** | -e2e 不进 CI 自动门的理由是外部不可用会误伤:实测中 kimi 渠道在 429 后被中转下线并返回 404。让外部波动阻断合并,会把测试变成噪声源。但"不自动门控"不等于"可跳过"——沿用项目既有 e2e 的口径(`tests/e2e/test_smoke_gateway.py:22` 的 reason 写着"验收前必须真跑")。 +不让本组阻断 CI 的理由是外部不可用会误伤:实测中 kimi 渠道在 429 后被中转下线并返回 404,另有一次 `network_error` 连续三次耗尽源导致 L2 假红。让外部波动阻断合并,会把测试变成噪声源。 + +**实现机制**:给本组打项目既有的 `slow` 标记。`pyproject.toml` 的 `addopts = "-m 'not slow'"` 默认排除它(该配置的注释原文:「慢速测试,CI 按需跑」),合并前用 `pytest -m slow tests/e2e/test_thinking_live.py` 显式真跑。实测效果:`make ci` 由 7 分钟降至 91 秒。 + +**一处必须澄清的事实**:`make test` 跑的是 `pytest tests/`,**包含 `tests/e2e/`**——只要 `.env` 有凭据,既有的轻量 e2e 冒烟就会真跑。所以「e2e 不进 CI」这句对本项目**并不成立**,只有打了 `slow` 的才被排除;本节初稿写成前者,是错的。「不自动门控」也不等于「可跳过」——沿用既有口径(`tests/e2e/test_smoke_gateway.py:22` 的 reason 写着「验收前必须真跑」)。 ### 9.2 e2e 覆盖矩阵 diff --git a/research-wiki/plans/2026-08-02-thinking-capability.md b/research-wiki/plans/2026-08-02-thinking-capability.md index 43ac10b..b386122 100644 --- a/research-wiki/plans/2026-08-02-thinking-capability.md +++ b/research-wiki/plans/2026-08-02-thinking-capability.md @@ -215,7 +215,7 @@ def _fingerprint_mark(s: SourceConfig) -> str: - [ ] **文件**:新建 `tests/e2e/test_thinking_live.py` -**行为**:沿用既有 e2e 约定(`tests/e2e/test_smoke_gateway.py:19-26`)——`dotenv_values(".env")` 读凭据、`pytestmark = pytest.mark.skipif(not _HAS_SOURCE, ...)`、结构化报告写入 `tests/outputs/e2e/`。**不新造开关机制**。 +**行为**:沿用既有 e2e 约定(`tests/e2e/test_smoke_gateway.py:19-26`)——`dotenv_values(".env")` 读凭据、`skipif(not _HAS_SOURCE, ...)`、结构化报告写入 `tests/outputs/e2e/`。**不新造开关机制**:另加项目既有的 `slow` 标记,靠 `pyproject.toml` 的 `addopts = "-m 'not slow'"` 把本组挡在 `make ci` 之外(137 次真实调用、约 7 分钟,且判据是统计性的,网络抖动会造成假红——执行期实测撞到过一次 `network_error` 耗尽源)。合并前用 `pytest -m slow tests/e2e/test_thinking_live.py` 显式真跑。 **源映射**:L1–L5、L8 的 MiniMax 行用现有的 `LLM__MINIMAX__1__*`(`MODEL=MiniMax-M3`);M2.7 / M2.5 行经 `dataclasses.replace(source, model=...)` 派生,不新增 `.env` 键。**L6 / L7 目前无对应源**——`.env` 里只有 MINIMAX 与 MONKEY 两类;需新增 `{SCOPE}__QWEN__1__*` 与 `{SCOPE}__DEEPSEEK__1__*`(同一中转 `BASE_URL` 与密钥,仅 `MODEL` 不同)。未配置时按既有 `skipif` 约定跳过,并在报告中记为「未覆盖」,**不得静默计入通过**。 diff --git a/src/polygateway/__init__.py b/src/polygateway/__init__.py index 88d63f9..cef3568 100644 --- a/src/polygateway/__init__.py +++ b/src/polygateway/__init__.py @@ -31,7 +31,7 @@ from polygateway.types import ( SourceConfig, ) -__version__ = "1.0.5" +__version__ = "1.0.6" __all__ = [ "DEFAULT_PROFILES", diff --git a/tests/e2e/test_thinking_live.py b/tests/e2e/test_thinking_live.py index 570ece7..3ec76d1 100644 --- a/tests/e2e/test_thinking_live.py +++ b/tests/e2e/test_thinking_live.py @@ -42,9 +42,16 @@ from polygateway.providers import DEFAULT_CAPABILITIES, get_capability _ENV = {k: v for k, v in {**dotenv_values(".env"), **os.environ}.items() if v is not None} _HAS_SOURCE = any(k.split("__")[0] == "LLM" and k.endswith("__API_KEY") for k in _ENV) -pytestmark = pytest.mark.skipif( - not _HAS_SOURCE, reason="需真实网关凭据: 在 .env 配置 LLM__{PROVIDER}__1__*(本组必须真跑)" -) +# slow: 本组 137 次真实调用、约 7 分钟,且判据是统计性的——网络抖动会让它偶发 +# 失败(实测有一次 network_error 连续三次耗尽源)。让它阻断 `make ci` 会把测试 +# 变成噪声源,故沿用项目既有的 slow 标记默认排除,合并前用 `-m slow` 显式真跑并 +# 存档报告。"不自动门控"不等于"可跳过"。 +pytestmark = [ + pytest.mark.slow, + pytest.mark.skipif( + not _HAS_SOURCE, reason="需真实网关凭据: 在 .env 配置 LLM__{PROVIDER}__1__*(本组必须真跑)" + ), +] _OUT_DIR = Path("tests/outputs/e2e") _ROUNDS = int(os.environ.get("PGW_E2E_THINKING_ROUNDS", "10"))