diff --git a/CHANGELOG.md b/CHANGELOG.md index 344ff79..4859cca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 1.4.0(2026-10-01) +## 1.3.9(2026-10-01) - 新增 `chat(response_mode="openai")`,返回 `LLMResponse.completion`:assistant 消息、工具调用、finish_reason、上游 response_id、usage 快照;支持流式聚合及非流式。 - 修复 SSE 顶层 error 后接 DONE 被当成功、同帧 content/reasoning_content 丢失;工具实际进展纳入看门狗、首 token 与中段对冲。 @@ -9,7 +9,6 @@ - 新模式不绕过 managed/raw 冲突校验;raw-only 仍须源级/请求级均无受管意图。`Transport.complete` 新增必填 `response_mode`,自定义实现需适配。 - 分发采用 Apache-2.0;README 补充常驻事件循环线程桥接,不新增同步 API。 - ## 1.3.8(2026-09-14) 流式中段沉默的计量与应对(issue #27 / #28):`generation_ms` 口径重定义为**净生成时间**(扣除所有超阈值中段沉默)并配 `stall_ms`/`stall_count` 归因字段与遥测两列;另加一条**默认关闭**的中段沉默对冲(主路首 token 之后相邻增量 chunk 间隔超阈值时,向异源并发再发一次)。两键均不设时行为逐字等于 1.3.7(默认关闭回归门: 既有 unit/contracts 全套件语义断言一行未改)。 diff --git a/CLAUDE.md b/CLAUDE.md index cb59b1e..8a19b99 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,10 +2,12 @@ > [!URGENT] > **实验室内部通用基础库(生产级、非 MVP、零业务假设)** +> > 1. 本项目是被多个科研/生产项目依赖的**库**,不是应用:稳定性、并发性、防御性、可观测与测试不可为"简单"让步(YAGNI 仍适用,但不削减健壮性)。库的 bug 会同时击穿所有下游项目。 > 2. 你的所有思考过程和回复必须使用 **简体中文**。 ## 1. 项目元数据 + - **核心目标**: PolyGateway = 统一的大语言模型(LLM/VLM/OCR,音频预留)调度与中转库。治理单位是**一次模型调用**:请求封装、多源多账号、限流、错误分类与重试、熔断、Redis 响应缓存、流式看门狗、遥测(含成本)、结构化输出策略。全组件端口化可插拔。 - **架构权威文档**: `research-wiki/ARCHITECTURE.md`(架构单一事实源,含 D1-D14 决策及讨论过程、子系统设计、三项目迁移验收标准;**不受 400 行设计文档限制**,以无歧义传达既有讨论为准绳)。开发顺序见 `research-wiki/ROADMAP.md`;`research-wiki/designs/` 仅存放每次实现具体功能的设计文档。 - **参考项目**: `reference/` 下三个项目是本库的需求来源与代码蓝本(**只读,勿改**;M4 起"只读"指工作区文件与 main 检出不变——迁移实施经 `git worktree` 在 `~/Projects/m4-worktrees/` 的 feature 分支进行,worktree 的 git 操作会写 `reference/*/.git` 元数据,属预期);库必须能按 ARCHITECTURE.md §11 被它们迁移接入,否则即边界缺口。 @@ -35,11 +37,13 @@ make ci # 只读验证(check + test) > **同一理由适用于长跑命令**: 需要后台跑时(如全套件测试),命令末尾**不得接管道**,否则退出码失真;要判完成用 `wait`/轮询 PID,不要用会匹配到自身的 `pgrep -f "<完整命令串>"`。 ### Phase 1: 规划与设计 + 1. 涉及**公共 API、端口签名、架构边界、新子系统**的变更**必须**调用 `brainstorming`(产出 2-3 备选方案+权衡)并经**人类确认**后实施;其余任务自判(判据: 是否改变库对下游的承诺)。动手前查阅 `research-wiki/`(单一事实源)。 2. 功能产生运行时数据时**必须**调用 `structured-logging`。 3. **里程碑级/跨多文件**功能编码前**必须**调用 `writing-plans`;小改动自判。审核门控: design 走 Claude 自审 → Codex 审 → **人类审**;plan 走 Claude 自审 → Codex 审 → 直接执行。 ### Phase 2: 执行与验证 + 1. **测试结果门**: 合并前每个行为变更必须有"先失败后通过"的测试证据(`test-driven-development`);bug 修复必带回归测试;不规定中间怎么走。 2. **独立验证**: 里程碑级/跨多文件/合并前**必须**派全新上下文的 verifier subagent(`verification-before-completion`);任何规模的完成声明都必须逐条对应本会话内的工具输出(证据化声明,禁止虚报)。 3. **反 gold-plating**: 不做任务外的重构、抽象与"顺手清理"。 @@ -47,6 +51,7 @@ make ci # 只读验证(check + test) ## 4. 核心规则 ### 4.1 核心原则(按优先级) + - **P1 YAGNI**: 不写当前用不到的代码;但并发控制、防御校验、可观测埋点、错误隔离与测试是"当前需要",不在削减之列。 - **P2 高可读性**: 领域术语命名;注释解释"为什么"。 - **P3 单一职责**: 一句话说不清职责(需要"和")= 拆分。 @@ -58,7 +63,7 @@ make ci # 只读验证(check + test) ### 4.2 库铁律(本项目特有,违反即 bug) | 铁律 | 内容 | -|---|---| +| --- | --- | | 零业务假设 | 库内禁止出现任何下游业务领域词汇(视频/文书/超声等)与业务 fixtures;扩展点一律 Protocol | | 纯 asyncio 中立 | 无全局状态、无框架假设、无模块级单例;同一 `GatewayClient` 在 arq worker 与裸脚本中行为一致 | | 取消可穿透 | `asyncio.CancelledError` 永不捕获吞没;重试循环、限流等待、流式读取全部可被取消;in-flight 资源在 finally 释放 | @@ -69,6 +74,7 @@ make ci # 只读验证(check + test) | 无缓存毒化 | 缓存 key 必含 model + messages 摘要 + 命名空间/租户 + salt;多模态 content 先摘要再 hash | ### 4.3 代码开发规范 + - 模块/类/方法必须有**中文 Docstring**;复杂逻辑用 `# Phase N` 注释组织。 - 校验分层: 外部输入校验用显式异常(Python `-O` 移除 assert,禁止 assert 承担生产校验);assert 仅用于内部不变量。 - 类名 `PascalCase`,私有前缀 `_`;导入顺序标准库→第三方→项目内。 @@ -76,6 +82,7 @@ make ci # 只读验证(check + test) - 不考虑向后兼容,直接修改原文件。**例外**: `LLMResponse` 等已被三项目消费的公共类型,字段只增不删不改名(迁移兼容约束,见 ARCHITECTURE.md §5.1)。 ### 4.4 Git 工作流 + - 一切开发在 feature 分支,严禁直改 main;频繁语义化提交;提交**必须**调用 `commit` skill;大改动前先提交回滚点。 ### 4.4.1 发布流程(每步都是历史欠账换来的,不得跳步) @@ -87,7 +94,7 @@ make ci # 只读验证(check + test) 按顺序执行,**构建之前**必须先改完所有文档: | # | 动作 | 要点 | -|---|---|---| +| --- | --- | --- | | 1 | **更新 README** | 打包会把当时的 README 固化进 sdist,**发布后再改就来不及了**(包里那份永远是旧的)。逐项核对: 安装命令的版本约束(`==1.1.*` 这类**极易漏改**,漏了下游就被锁在旧版)、能力表是否覆盖新行为、数字型断言是否仍成立(如遥测字段数,须用 `inspect.signature` 实测而非凭记忆) | | 2 | CHANGELOG 定版 | "未发布" → `## X.Y.Z(日期)` | | 3 | 版本号 | `pyproject.toml` + `src/polygateway/__init__.py` 两处必须一致 | @@ -106,11 +113,13 @@ Gitea 包 registry 是 **owner 级**(`/iomgaa/-/packages/`)不是仓库级;PyPI 发布验证补充(2026-09-09 实测):私有索引不镜像 setuptools,下载 sdist 时 pip 即使带 `--no-deps` 仍可能尝试安装构建依赖;已具备构建工具的 conda 环境可加 `--no-build-isolation`,仍须核对下载来源与散列。包关联 POST 本次返回400,但匿名包页面和认证 GET 包 API 均证实已关联目标仓库;**400本身不算成功,也不能直接推断已关联**,必须读取实际 `repository.full_name` 与页面链接。包 API 可能要求认证(匿名401),页面仍应匿名亲查;不要为重试关联先解绑现有正确关系。 ### 4.5 配置管理 + - 工程配置走 `pydantic-settings` + `.env`(模板 `.env.example`,敏感项不提交);严禁硬编码默认值;缺失关键配置直接报错。 - 多源命名约定 `{SCOPE}__{PROVIDER}__{N}__{FIELD}`;韧性参数键名沿用三项目习惯(`LLM_TIMEOUT` 等),降低迁移成本。 - 装配只有两条路: `GatewayClient.from_env()`/`from_settings()`(工厂)或构造函数全量注入(测试/高级);库内部任何组件不得自读环境变量。 ### 4.6 测试组织 + - `tests/{unit,integration,e2e}`;真实场景优先(录制的真实网关响应二次构造优于凭空 mock)。 - 覆盖率目标 80%;并发/韧性行为是一等测试对象: 重试穿透取消、熔断开路半开、限流结算退款、Redis 掉线降级方向、缓存 key 隔离。 - Redis 相关测试用真实 Redis(integration),不 mock Lua 行为;限流契约测试随实现一起交付(参考 CHSAnalyzer `tests/contracts_limiter.py`)。 @@ -140,7 +149,7 @@ project_root/ ## 6. 上下文导航 | 需求 | 路径 | -|---|---| +| --- | --- | | 架构全貌: 决策 D1-D14 及讨论过程、端口清单、错误分类、子系统设计、迁移验收 | `research-wiki/ARCHITECTURE.md`(单一事实源) | | 开发顺序与里程碑状态 | `research-wiki/ROADMAP.md`(活文档,随进度更新) | | 三项目迁移文档(ARCHITECTURE §11 的展开,库设计的常驻约束) | `research-wiki/migrations/`(govdoc-saas / video-tree-trm5 / chsanalyzer) | @@ -154,6 +163,7 @@ project_root/ | 第一次抽库尝试(教训与蓝本) | `reference/GovDoc-SaaS/packages/docagent-core/` | ## 7. 输出规范 + - 所有输出**中文**;文档优先表格/伪代码/Mermaid;禁止超 15 行代码块入文档、禁止连续超 5 条碎片列点;设计 ≤400 行、计划 ≤1000 行、报告 ≤300 行。 - **例外**: `research-wiki/ARCHITECTURE.md` 不受行数限制——它的准绳是"后来的 AI/人类无需还原原始讨论即可准确理解全部决策及理由",宁详勿略(详细 ≠ 琐碎:记录论证与取舍,不堆砌实现细节)。 @@ -163,7 +173,7 @@ project_root/ > **Skill 的 description 即触发边界。** 下表标注 **MANDATORY** 的情形是硬门(设计人类门、合并前测试证据门、合并前独立验证门、commit 格式),不得跳过;其余情形按 description 边界自判——自判看任务实质(规模/风险/是否触及公共承诺),不是省事。任何 skill 流程不得引入任务外的重构或抽象。优先级: 用户显式指令 > Skill 详细流程 > 本文件宏观规则。 | Skill | 触发边界 | -|-------|---------| +| ------- | --------- | | `brainstorming` | **MANDATORY**: 公共 API/端口签名/架构边界/新子系统变更;其余自判 | | `writing-plans` | **MANDATORY**: 里程碑级/跨多文件功能;小改动自判 | | `test-driven-development`(测试结果门) | **MANDATORY**: 合并前——行为变更须有先失败后通过的测试证据 | diff --git a/README.md b/README.md index 8c0516d..309d8c3 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ | 调用期限 | 一次逻辑调用可选一条**墙钟硬边界**(`{SCOPE}__CALL_DEADLINE_S` 或 `chat(call_deadline_s=...)`,缺省不启用):治理的是**等待**——重试退避、配额轮询、熔断冷却、结构化重问与 embedding 分批共享同一份期限。三条须知:①**返回时刻 = 期限 + 清理耗时**(遥测/结算/缓存收尾在 `finally` 里跑完,允许超期;实测构造达期限的 5–7 倍),库只承诺切断等待、不给返回上界;②**到期 ≠ 未产出、≠ 未计费**,上游可能已算完并计费;③**不配置即逐字保持 1.3.5 语义**(纯 429 序列仍可能长等、有限大 `Retry-After` 仍照睡)。到期抛 `CallDeadlineExceeded`,**不属四分类、不属 `GatewayUnavailableError` 族** | | 长尾对冲 | **默认关闭**的可选加速(`{SCOPE}__HEDGE__AFTER_S`,仅 chat):一次尝试挂起超阈值时向**异源**并发再发一次,先回者赢、输家取消。流式以「首 token 未至」为触发判据(不误杀慢生成),非流式只有纯总时长阈值;对冲走完整限流/熔断准入,拿不到配额静默放弃。成本须知:开启即用配额换延迟(触发窗口内 in-flight 翻倍),输家取消按 est 保留预扣且**可能已被上游计费**(取消止不住上游);输家不喂熔断,遥测 attempt 行标 `error="hedge_cancelled"` 可按 `logical_call_id` join 对账;两路皆败只计一次重试预算;与 `call_deadline_s` 正交组合(装配守卫强制对冲阈值 < 期限) | 中段沉默对冲(可选,超业界现状能力) | **默认关闭**(`{SCOPE}__HEDGE__STALL_AFTER_S`,仅流式 chat):主路**首 token 之后**相邻增量 chunk 沉默超阈值时向异源并发再发一次,与首 token 对冲 `HEDGE__AFTER_S` **独立生效**、可独设可组合;仅设它且请求非流式 → 逐字走单路(中段沉默无非流式概念)。**诚实标注:中段沉默触发并发副本在主流网关/库中无公开先例**(业界收敛为看门狗掐流重试)。成本须知:下游实测沉默 >20s 占 19.0%,触发率远高于首 token 对冲,开启即用配额换延迟,输家可能已被上游计费;看门狗掐死**喂**熔断而对冲输家取消**不喂**(不对称声明),详见[1.3.8 生成时间口径与中段沉默对冲](#138-生成时间口径与中段沉默对冲) | -| OpenAI 消息保真(1.4.0) | `chat(response_mode="openai")` 返回完整 assistant 消息/工具调用、finish_reason、上游 ID 与 usage;单 choice,复用治理,不执行工具;默认仍为文本模式 | +| OpenAI 消息保真(1.3.9) | `chat(response_mode="openai")` 返回完整 assistant 消息/工具调用、finish_reason、上游 ID 与 usage;单 choice,复用治理,不执行工具;默认仍为文本模式 | | 响应缓存 | Redis/内存;key 含 model + messages 摘要 + namespace(缓存隔离单位)+ salt + 采样参数 + 请求级推理档位(同 messages 跑 low 与 max 不互相命中),多模态 content 先摘要再 hash(防毒化);可 per-call 绕过(科研重采样) | | 流式看门狗 | TTFT / inter-token / 总超时三层活性;thinking token 刷活性不计结果;截断流(缺 `[DONE]`)判瞬时不入缓存 | | 推理可观测性 | "这次到底推理没推理"由多信号裁定(推理正文压倒 usage 明细),三态落在 `LLMResponse.thinking_observation`:`observed` / `absent` / `unknown`——**`unknown` 是"本次判不出",不是"没推理"**;本次实发档位与实测观测矛盾时按 `(源, 模型, 生效档位)` 各告警一次(能力表过期、开启未生效、注入了却观测不到;同一模型的 low 与 max 是两个独立的矛盾,不共用节流键);裁定结果随遥测落库 | @@ -146,7 +146,7 @@ stats.total_latency_ms # 含缓存 IO、退避、准入等待、重 ```bash pip install --extra-index-url https://gitea.iomgaa.online/api/packages/iomgaa/pypi/simple/ \ - "polygateway[redis,postgres,structured]>=1.4.0,<2" + "polygateway[redis,postgres,structured]>=1.3.9,<2" ``` 核心仅依赖 `httpx` + `pydantic`;按需选 extras: @@ -612,7 +612,7 @@ make ci # 只读全量验证 `LLMResponse` 等被下游消费的公共类型,字段**只增不删不改名**且新增字段必带默认值;`{SCOPE}__{PROVIDER}__{N}__{FIELD}` 与平铺韧性键名(`LLM_TIMEOUT` 等)沿用三项目既有习惯,不做破坏性改名。实验室内部库,随实验室项目需求演进。 -## 1.4.0 OpenAI 工具消息保真(单 choice) +## 1.3.9 OpenAI 工具消息保真(单 choice) `chat(..., response_mode="openai")` 仍返回 `LLMResponse`,完整协议结果在 `response.completion`:`message`、`finish_reason`、`response_id`、`usage`。 @@ -637,7 +637,7 @@ SSE 支持 role/content/reasoning_content/tool_calls,未知增量字段会明 上游实际模型仍读 `model_reported`,配置别名是 `model`。 | 边界 | 行为 | -|---|---| +| --- | --- | | 空文本且有完整工具 | 正常成功;不完整工具或无任何有效产物仍失败 | | error 帧 | 所有模式立即判失败并走已有重试;后续 DONE 不挽救 | | 缺 DONE | 保真模式不受 salvage 放宽,防截断工具被执行 | diff --git a/pyproject.toml b/pyproject.toml index fc06554..cae2f35 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "polygateway" -version = "1.4.0" +version = "1.3.9" description = "PolyGateway:实验室统一的大语言模型(LLM/VLM/OCR)调度与中转库——多源、限流、重试、熔断、缓存、遥测" # registry 包页面的正文只认这一项:缺了页面就是一片空白(1.1.2 的教训,twine 会警告 # long_description missing 但不阻塞上传)。README 在打包时被固化进产物,发布后再改无效。 diff --git a/research-wiki/ROADMAP.md b/research-wiki/ROADMAP.md index 9b7f663..b9fd4a2 100644 --- a/research-wiki/ROADMAP.md +++ b/research-wiki/ROADMAP.md @@ -13,7 +13,7 @@ ## 1. 总览与状态 | 阶段 | 内容 | 接入方 | 状态 | -|---|---|---|---| +| --- | --- | --- | --- | | P0 奠基 | 调研、ARCHITECTURE.md、CLAUDE.md、skill Fable 5 改造、hooks 硬边界、脚手架(git/pyproject/Makefile/conda 环境/CI 绿) | — | ✅ 完成(2026-07-20) | | M1 核心 | 内核类型 + httpx transport + 治理中间件(内存后端)+ 多源多账号 + 缓存 + SQLite 遥测 + 结构化输出 + from_env | GovDoc、Video-Tree | ✅ 完成(2026-07-20;239 测试全绿、覆盖 92%、真实网关+真实 Redis 验收通过、独立 verifier 问题清零;见 designs/2026-07-20-m1-core-design.md 状态行) | | M2 分布式 | Redis 限流/熔断后端、多源 × Redis 联合验证、背压、Postgres 遥测、成本、Embedding(Q3)、压测 harness | CHSAnalyzer(治理) | ✅ 完成(2026-07-21;契约双后端全绿 + 时间语义真实等待变体 10/10、跨连接联合验证、CHS 对标十项打钩、P3 真实验收 300 次双进程七不变量 PASS、独立 verifier 0 Critical 且 Important 清零;见 designs/2026-07-20-m2-distributed-design.md 与 findings/m2-verifier-fixes.md。压测收官: P5 故障混编 40 次八不变量 PASS,P6 首跑 58.1% 暴露三大治理盲区(findings/2026-07-21-p6-soak-baseline.md)→ **M2.5 治理韧性**六轮迭代(双通道熔断/健康选源/AIMD/429 免预算/健康门槛降权/连败抑制)后同场景 **98.96%**、八不变量全 PASS,验收见 findings/2026-07-21-m25-acceptance.md 与 designs/2026-07-21-m25-resilience-design.md) | @@ -25,7 +25,7 @@ **内部开发顺序**(编号即依赖顺序,同号可并行): | 步 | 内容 | 顺序理由 | -|---|---|---| +| --- | --- | --- | | 1 | `types.py` + `errors.py` + `ports.py` 全量设计与冻结 | 原则 2:公共承诺先行;这是 M1 设计文档(人类门)的主体 | | 2a | `streaming.py` 看门狗移植 | 原则 4:纯函数,零依赖,直接移植+补测 | | 2b | `providers.py` 注册表 | 叶子模块;transport 的前置(思考流字段声明;thinking 注入的**决策**已于 issue #16/#17 搬到 `thinking.py`,这里只留形态声明) | @@ -75,6 +75,6 @@ ## 7. 开放决策依赖 | 决策 | 阻塞点 | 需拍板时间 | -|---|---|---| +| --- | --- | --- | | Q1 打包分发(git+ssh vs 内网 index) | 不阻塞开发,阻塞 M4 发布 | M4 前 | | Q3 Embedding 是否纳入 | ~~影响 M2 范围~~ **已拍板纳入 M2**(2026-07-20) | ✅ 已决 | diff --git a/research-wiki/designs/2026-10-01-issue29-openai-fidelity-design.md b/research-wiki/designs/2026-10-01-issue29-openai-fidelity-design.md index d9c2884..0c86232 100644 --- a/research-wiki/designs/2026-10-01-issue29-openai-fidelity-design.md +++ b/research-wiki/designs/2026-10-01-issue29-openai-fidelity-design.md @@ -7,7 +7,7 @@ date: 2026-10-01 # #29 OpenAI 消息保真设计 -> 状态:方向已获人类批准;计划独立审查 P1/P2 已修订并实施,首轮独立代码审查发现的缓存空产物及测试双向依赖已修复,等待父会话最终复核;1.4.0 发布准备,尚未发布。 +> 状态:方向已获人类批准;计划独立审查 P1/P2 已修订并实施,首轮独立代码审查发现的缓存空产物及测试双向依赖已修复,等待父会话最终复核;按人类最终指定准备 1.3.9,取代未发布的 1.4.0;尚未发布。 > 基线:`0e29deac1a72bfee348ed2f8061ea2c33be217e8` / 1.3.8;日期:2026-10-01。 > 需求:[issue #29](https://gitea.iomgaa.online/iomgaa/PolyGateway/issues/29)。 > 权威约束:ARCHITECTURE §2.3、§5、§6、§7.1–7.8;实现前按本文修订对应架构段落。 @@ -23,7 +23,7 @@ Codex 不可用,人类已授权原生 subagent 替代独立审查。具体 API ## 2. 源码核验与方案比较 | 已核实接缝 | 现状与修复目标 | -|---|---| +| --- | --- | | `transports/openai_compat.py::_sse_delta` | 只读首 choice;content 早返回丢同帧 reasoning;忽略 tool_calls/error | | `_complete_stream` / `_complete_once` | 纯文本判空;raw 只存 usage;需新增协议快照与 tool-only 成功语义 | | `client.py::chat` / `_build_payload` | messages 已直传,overlay 已合并,无需白名单重写 | @@ -32,7 +32,7 @@ Codex 不可用,人类已授权原生 subagent 替代独立审查。具体 API | `middleware/cache.py` | 已有完整消息/overlay 身份,但嵌套新类型需重建、模式需隔离 | | 方案 | 优势 | 代价/结论 | -|---|---|---| +| --- | --- | --- | | A:chat 显式模式 + LLMResponse 内嵌协议结果 | 生命周期、取消、缓存、遥测和对冲单一实现;兼容旧投影 | 需定义组合约束和缓存身份;**选定** | | B:新增 chat_completion 入口,复用私有核心 | 接口像 OpenAI | 重复公共签名、输入校验和终态封装,收益不足,否决 | | C:独立 SDK 客户端或代理自聚合 | 局部改动直观 | 无法自动解决响应上浮/缓存/线路错误,复制治理,否决 | @@ -64,7 +64,7 @@ completion 是独立于上游容器的深拷贝 JSON 快照;frozen 只保证 ### 3.2 请求与组合校验 | 条件 | 规则 | -|---|---| +| --- | --- | | 未知模式 | 公共入口 ValueError,尚未创建逻辑调用上下文 | | openai + structured 非 None | 公共入口 ValueError;不注入 schema、不自动重问;overlay 的 response_format 仍可直传 | | openai + n | 仅允许缺省或严格整数 1(不接受 bool);调用 overlay 在入口校验,选中源 extra_body 及最终 payload 在 HTTP 前校验,不接受被 overlay 遮蔽的非法源级 n | @@ -93,7 +93,7 @@ response_id 是上游 id,允许未上报为 None,绝不拿 call_id 补齐; 每次 complete 独立创建聚合器,不放 transport 实例共享状态。逐 JSON 帧先校验对象并查 error,再读取 choices/delta、元信息和 usage;坏类型统一转 TransientError,不让 AttributeError/TypeError 逃出治理。 | 字段 | 合并规则 | -|---|---| +| --- | --- | | content / reasoning_content | 非 null 必为 str,逐片拼接;同帧同时收集;不 trim;从未出现则不造键,仅 null 则保留 null | | role | openai 模式若出现必须 assistant;只出现 role 不算活性;最终成功必须含 assistant role;缺失失败,不伪造字段 | | tool_calls | 必为列表;每项 index 必为非负严格整数;按 index 分桶,末尾按 index 排序,索引不输出到最终工具对象 | @@ -110,7 +110,7 @@ SSE、非流式及缓存最终快照均要求 role="assistant";缺失或其他 ### 4.2 成功、截断与错误 | 场景 | 行为 | -|---|---| +| --- | --- | | openai:空正文 + 有完整工具 | 成功,不触发空补全重试 | | openai:非空投影正文、无工具 | 成功;存在任何不完整工具则仍拒绝,不用正文掩盖坏工具 | | openai:无正文且无有效工具 | 维持 empty_completion 瞬时失败;reasoning-only 不算成功 | @@ -146,7 +146,7 @@ CacheMW 显式序列化和重建 OpenAIChatCompletion,读时验证容器、单 ## 7. 旧行为审计与非功能约束 | 既有行为 | 处置 | -|---|---| +| --- | --- | | 旧字段/默认文本/structured 阶梯/受管推理 | 保留;默认文本同帧漏 reasoning 属修复 | | HTTP 分类、retry/backoff、两类对冲、TPM/熔断 | 保留,不改算法与预算 | | 空补全、missing_done salvage | 文本保留;openai tool-only 放行、缺 DONE 强制失败 | diff --git a/research-wiki/graph/edges.json b/research-wiki/graph/edges.json index d0bbe77..2bb45e0 100644 --- a/research-wiki/graph/edges.json +++ b/research-wiki/graph/edges.json @@ -240,6 +240,16 @@ "id": "review:2026-10-01-issue29-cache-review", "label": "保真缓存审查修复与1.4.0准备", "type": "review" + }, + { + "id": "plan:2026-09-10-24-hedged-requests", + "label": "issue #24 长尾对冲请求与裸生成时间实施计划", + "type": "plan" + }, + { + "id": "design:2026-09-10-24-hedged-requests-design", + "label": "长尾对冲请求(issue #24)设计", + "type": "design" } ], "links": [ @@ -508,6 +518,13 @@ "relation": "informs", "evidence": "统一缓存与transport的有效产物判据,保持内核依赖边界", "added": "2026-10-01T18:27:16.434742+00:00" + }, + { + "source": "plan:2026-09-10-24-hedged-requests", + "target": "design:2026-09-10-24-hedged-requests-design", + "relation": "implements", + "evidence": "计划头部与设计 §9 批准状态(2026-09-10 H1-H8 全数获批)", + "added": "2026-09-10T16:48:37.849653+00:00" } ] } \ No newline at end of file diff --git a/research-wiki/index.md b/research-wiki/index.md index 2672b77..22f0f3b 100644 --- a/research-wiki/index.md +++ b/research-wiki/index.md @@ -1,8 +1,9 @@ # Research Wiki 索引 -> 自动生成,更新时间:2026-10-01 18:27 UTC +> 自动生成,更新时间:2026-10-02 02:23 UTC ## design (47) + - [1.3.4 推理意图与测试证据设计](designs/2026-09-09-134-thinking-contracts-design.md) `design:2026-09-09-134-thinking-contracts-design` - [2026-07-20-m1-core-design](designs/2026-07-20-m1-core-design.md) `design:2026-07-20-m1-core-design` - [2026-07-20-m2-distributed-design](designs/2026-07-20-m2-distributed-design.md) `design:2026-07-20-m2-distributed-design` @@ -52,6 +53,7 @@ - [采样参数透传设计(issue #4)](designs/sampling-params.md) `design:sampling-params` ## finding (22) + - [1.3.4 推理契约验证与发布准备](findings/2026-09-09-134-thinking-contracts-validation.md) `finding:2026-09-09-134-thinking-contracts-validation` - [1.3.5 T2/T3/T4 验收证据:36 列遥测、失败终态、PG 存储兼容与变异矩阵](findings/2026-09-09-135-call-observability-validation.md) `finding:2026-09-09-135-call-observability-validation` - [1.3.5 发布完成与外部验收:合并后门、registry 产物与页面亲查](findings/2026-09-09-135-release-completion.md) `finding:2026-09-09-135-release-completion` @@ -76,6 +78,7 @@ - [推理开关与 reasoning_tokens: 供应商实测与业界做法](findings/2026-08-02-thinking-switch-and-reasoning-tokens.md) `finding:2026-08-02-thinking-switch-and-reasoning-tokens` ## plan (42) + - [1.3.4 推理契约实施计划](plans/2026-09-09-134-thinking-contracts.md) `plan:2026-09-09-134-thinking-contracts` - [1.3.5 逻辑调用统计与结构化失败诊断实施计划](plans/2026-09-09-135-call-observability.md) `plan:2026-09-09-135-call-observability` - [1.3.6 可选调用期限与取消结算修复实施计划](plans/2026-09-10-136-call-deadline.md) `plan:2026-09-10-136-call-deadline` @@ -120,6 +123,7 @@ - [采样参数透传实现计划(issue #4)](plans/sampling-params-plan.md) `plan:sampling-params-plan` ## review (6) + - [2026-09-11-138-branch-review](reviews/2026-09-11-138-branch-review.md) `review:2026-09-11-138-branch-review` - [2026-09-11-138-verifier](reviews/2026-09-11-138-verifier.md) `review:2026-09-11-138-verifier` - [2026-09-11-streaming-stall-design-review](reviews/2026-09-11-streaming-stall-design-review.md) `review:2026-09-11-streaming-stall-design-review` @@ -128,8 +132,10 @@ - [整分支审查: issue #14 熔断等待档](reviews/issue14-branch-review.md) `review:issue14-branch-review` ## schema (1) + - [表结构: llm_calls(遥测 36 字段)](schemas/llm-calls.md) `schema:llm-calls` ## metric (2) + - [OCR 治理调用成功率与错误分类分布](metrics/ocr-call-success.md) `metric:ocr-call-success` - [每次调用必录覆盖率(含缓存命中/失败/取消)](metrics/call-telemetry-coverage.md) `metric:call-telemetry-coverage` diff --git a/research-wiki/log.md b/research-wiki/log.md index 44c492b..4de5a99 100644 --- a/research-wiki/log.md +++ b/research-wiki/log.md @@ -160,6 +160,8 @@ - [2026-09-09 13:42 UTC] 重建索引: 100 篇页面 - [2026-09-09 16:49 UTC] 重建索引: 101 篇页面 - [2026-09-09 18:01 UTC] 重建索引: 102 篇页面 +- [2026-09-10 16:48 UTC] 新增边: plan:2026-09-10-24-hedged-requests --implements--> design:2026-09-10-24-hedged-requests-design +- [2026-09-10 16:48 UTC] 重建索引: 107 篇页面 - [2026-10-01 17:52 UTC] 新增 design: OpenAI消息保真设计 (design:2026-10-01-issue29-openai-fidelity-design) - [2026-10-01 17:52 UTC] 新增 plan: OpenAI消息保真实现计划 (plan:2026-10-01-issue29-openai-fidelity) - [2026-10-01 17:52 UTC] 新增边: plan:2026-10-01-issue29-openai-fidelity --implements--> design:2026-10-01-issue29-openai-fidelity-design @@ -168,3 +170,4 @@ - [2026-10-01 18:24 UTC] 新增 review: 保真缓存审查修复与1.4.0准备 (review:2026-10-01-issue29-cache-review) - [2026-10-01 18:27 UTC] 新增边: review:2026-10-01-issue29-cache-review --informs--> design:2026-10-01-issue29-openai-fidelity-design - [2026-10-01 18:27 UTC] 重建索引: 120 篇页面 +- [2026-10-02 02:23 UTC] 重建索引: 120 篇页面 diff --git a/research-wiki/plans/2026-09-11-streaming-stall.md b/research-wiki/plans/2026-09-11-streaming-stall.md index 4a63804..f0b57e8 100644 --- a/research-wiki/plans/2026-09-11-streaming-stall.md +++ b/research-wiki/plans/2026-09-11-streaming-stall.md @@ -228,7 +228,7 @@ generation_sink.append((wall_ms, stall_ms_i, stall_count_i)) | --- | --- | | loader | `_load_hedge`(:745-769)扩读 `STALL_AFTER_S`:`_first` + `_cast` + `ensure_call_deadline`(origin 传实际命中键名),返回字典加 `"hedge_stall_after_s"` 键;未设 = None(关闭) | | 字段 | `GatewaySettings` 加 `hedge_stall_after_s: float \| None = None`;`_validate_hedge`(:382-392)扩传 | -| 守卫(全部落进 `check_hedge_assembly` :772-849,签名加 keyword-only `stall_after_s` 参;**返回契约钉死(审查 B2)**:返回 `tuple[float | None, float | None]` = (归一化 after_s, 归一化 stall_after_s),`config.py:384` 与 `client.py:252` 两处调用点随之解构,`test_config.py:1174/:1184` 列入 T4 同步清单(`is None` 断言按新返回形态改写);**两阈值皆 None 才早退**——"同 `after is None` 早退形态"字面执行会让仅 stall 配置绕过守卫②③④,禁止) | ①值域 = `ensure_call_deadline` 同款(有限正数);②`stall_after_s ≥ min over sources of (inter_token_timeout_s or timeout_s)`(有效最小值,与 openai_compat.py:573 回落同款)→ **ValueError**(对冲窗永不开,装配期直接拒绝;stall 场景无非流式残留收益,warning 论证不足,N5);③`stall_after_s ≥ call_deadline_s`(两者皆设)→ ValueError(与 `after_s` 同款,config.py:825-828 邻域);④单源 scope 设阈值 → warning 允许(1.3.7 §5 同款);⑤**B4**:Embedding/OCR scope 装配 warning 落 `EmbeddingSettings.__post_init__`(:865-869 邻域)与 `OcrSettings`(新增 `__post_init__`):内嵌 gateway 的 `hedge_after_s` **或** `hedge_stall_after_s` 非 None → warning"对冲键仅对 chat scope 生效,本 scope 非流式静默退化"(1.3.7 `AFTER_S` 同病顺带补齐,缺陷修复不扩公共面);chat 侧装配 warning 明确不做(per-call stream,装配期无信号,B4 裁决) | +| 守卫(全部落进 `check_hedge_assembly` :772-849,签名加 keyword-only `stall_after_s` 参;**返回契约钉死(审查 B2)**:返回 `tuple[float | None, float | None]`= (归一化 after_s, 归一化 stall_after_s),`config.py:384` 与 `client.py:252`两处调用点随之解构,`test_config.py:1174/:1184`列入 T4 同步清单(`is None` 断言按新返回形态改写);**两阈值皆 None 才早退**——"同 `after is None` 早退形态"字面执行会让仅 stall 配置绕过守卫②③④,禁止) | ①值域 = `ensure_call_deadline` 同款(有限正数);②`stall_after_s ≥ min over sources of (inter_token_timeout_s or timeout_s)`(有效最小值,与 openai_compat.py:573 回落同款)→ **ValueError**(对冲窗永不开,装配期直接拒绝;stall 场景无非流式残留收益,warning 论证不足,N5);③`stall_after_s ≥ call_deadline_s`(两者皆设)→ ValueError(与 `after_s` 同款,config.py:825-828 邻域);④单源 scope 设阈值 → warning 允许(1.3.7 §5 同款);⑤**B4**:Embedding/OCR scope 装配 warning 落 `EmbeddingSettings.__post_init__`(:865-869 邻域)与 `OcrSettings`(新增 `__post_init__`):内嵌 gateway 的 `hedge_after_s` **或** `hedge_stall_after_s` 非 None → warning"对冲键仅对 chat scope 生效,本 scope 非流式静默退化"(1.3.7 `AFTER_S` 同病顺带补齐,缺陷修复不扩公共面);chat 侧装配 warning 明确不做(per-call stream,装配期无信号,B4 裁决) | | client | `GatewayClient.__init__` 加 `hedge_stall_after_s: float \| None = None` keyword-only,:252-257 守卫调用扩传;RetryMW 构造(:264-283)传 `stall_after_s=` 归一化值(取守卫返回二元组第二元,B2);`from_settings`(:525 邻域)透传 | ### 3.6 T4:retry 编排改动(P2 唯一实现形态) diff --git a/research-wiki/plans/2026-10-01-issue29-openai-fidelity.md b/research-wiki/plans/2026-10-01-issue29-openai-fidelity.md index 95af718..ccc50e6 100644 --- a/research-wiki/plans/2026-10-01-issue29-openai-fidelity.md +++ b/research-wiki/plans/2026-10-01-issue29-openai-fidelity.md @@ -7,7 +7,7 @@ date: 2026-10-01 # #29 OpenAI 消息保真实现计划 -> 状态:计划及首轮代码独审已完成,P1/P2 均采纳;缓存空产物和测试双向依赖已修复,1.4.0 发布准备由本轮落实,最终独审与 T8 外部发布仍由父会话执行。 +> 状态:计划及首轮代码独审已完成,P1/P2 均采纳;缓存空产物和测试双向依赖已修复,发布目标按人类最终指定改为 1.3.9(取代未发布的 1.4.0),最终独审与 T8 外部发布仍由父会话执行。 > 设计:[批准方向的设计落实稿](../designs/2026-10-01-issue29-openai-fidelity-design.md)。 > 目标:同一 chat 治理链返回可供下游继续工具对话的完整单 choice 协议结果,拒绝截断和 error 帧伪成功。 > 方案:增加 response_mode 与嵌套 completion;协议解析与聚合内聚在 transport 内部模块,治理层仅传模式/搬结果;旧文本默认保持兼容。 @@ -16,7 +16,7 @@ date: 2026-10-01 ## 0. 工作区、审批与执行纪律 | 项目 | 已核验值 | -|---|---| +| --- | --- | | 工作目录 | `/home/iomgaa/.config/superpowers/worktrees/PolyGateway/issue29-openai-fidelity` | | 分支 | `feat/issue29-openai-fidelity` | | 基线 | `0e29deac1a72bfee348ed2f8061ea2c33be217e8` / 1.3.8 | @@ -33,7 +33,7 @@ date: 2026-10-01 ## 1. 文件结构与职责锁定 | 路径(相对工作目录) | 动作与职责 | -|---|---| +| --- | --- | | `src/polygateway/types.py` | 新 ResponseMode/OpenAIChatCompletion;末尾追加 ChatRequest.response_mode、两个响应 completion | | `src/polygateway/__init__.py` | 导出新公共类型;最终发布时同步版本 | | `src/polygateway/ports.py` | complete 增必填模式参数;说明工具进展与单 choice 契约 | @@ -147,12 +147,12 @@ conda run -n PolyGateway pytest tests/unit/test_types.py tests/unit/test_client. 补测 SSE/非流式/缓存缺 role、非 assistant role;合法 role-only 起始帧后工具成功。先红测试至少含下表各组;复用现有 SSE/MockTransport,不引入第二套 HTTP fake 框架。 | 组 | 输入与精确预期 | -|---|---| +| --- | --- | | 并行工具 | 2 工具交错 index;同帧两工具;name/arguments 分片;空白/Unicode/引号逐字相等;最终按 index 排序 | | 身份 | id/type 同值重复只保留一次,冲突失败;缺 id/type/name/arguments、重复 id、bool/负数 index、非 function 类型失败 | | 文本 | 同帧正文+推理均保留;缺省/null/空串区别;原消息 think 标签不剥,旧投影仍剥 | | envelope | 顶层数组/null、choices/delta/tool_calls 非容器、坏字段类型、多 choice/非零 choice index 均受控失败 | -| 非流式 |完整消息、扩展字段、usage/finish/id 全保留;工具参数不做业务 JSON 修复;原响应对象改动不影响快照 | +| 非流式 | 完整消息、扩展字段、usage/finish/id 全保留;工具参数不做业务 JSON 修复;原响应对象改动不影响快照 | | error | 首帧 error、正文后 error+usage+DONE、error=null、error={}、salvage 配置下 error 都立即失败;text/openai 两模式参数化 | 复用现有 summarize_body/compose_message,断言异常与遥测诊断有界,不打印工具参数正文。默认文本模式不因无用工具字段的严格 finish 校验而新增失败,但不吞顶层 error。无新 HTTP 状态映射。 @@ -198,7 +198,7 @@ conda run -n PolyGateway lint-imports 先红→绿证据须覆盖真实 OpenAICompatTransport 接入 GatewayClient,而不是只用返回预制 completion 的 fake 证明解析成功: | 场景 | 断言 | -|---|---| +| --- | --- | | 第一次部分正文/工具→error→DONE,第二次正常 | 只返回第二次 completion,attempts=2;第一次 error 的字段不会污染结果或缓存 | | 工具持续进展 | 首 token 对冲及时止窗,中段 event 复位,未错误触发 | | 真沉默触发对冲 | 副路完整工具结果胜出,返回自己的 id/usage,输家不泄露半成品 | @@ -220,7 +220,7 @@ conda run -n PolyGateway pytest tests/integration/test_governance_stack.py tests 文件:LICENSE、pyproject.toml、test_package.py、新 license-audit finding、README、CHANGELOG、.env.example、ARCHITECTURE;设计/计划 Wiki 注册关系。 | 工作 | 验收 | -|---|---| +| --- | --- | | 来源审计复核(初审前置 T0) | 查 tracked 分发文件的移植/参考/版权注释及具体片段;列内部原创授权记录,外部只读 reference 的路径/许可/实际使用范围;未发现不等于法律认证 | | 第三方义务 | 对实际复制片段核实许可、保留通知;发现 AGPL 不兼容复制须上报,不借用户授权覆盖第三方 | | LICENSE | 使用标准 Apache-2.0 全文,不自行重写;版权归属沿项目元数据,不猜用户真实姓名;NOTICE 仅在实际需要时新增 | @@ -258,10 +258,10 @@ make ci ### T8 — 发布与 issue 外部验收(父会话持有,不由本设计任务执行) -发布版本由父会话按新增公共能力确定,不能在规划中冒称已发布。遵守 CLAUDE.md §4.4.1 全步骤:README/CHANGELOG/两处版本先完成 → 合并 main/push → 合并后 lint/全套件/相交 slow → tag push → 构建/twine check → registry 上传 → 实际下载核验 → Release/挂库/包页核验。 +发布版本已由人类最终指定为 1.3.9(取代未发布的 1.4.0),不能在规划中冒称已发布。遵守 CLAUDE.md §4.4.1 全步骤:README/CHANGELOG/两处版本先完成 → 合并 main/push → 合并后 lint/全套件/相交 slow → tag push → 构建/twine check → registry 上传 → 实际下载核验 → Release/挂库/包页核验。 | 发布门 | 可接受证据 | -|---|---| +| --- | --- | | 构建 | `conda run -n PolyGateway python -m build` 和 twine check 成功;解包核 LICENSE、许可元数据、completion 类型/参数/解析器均在产物中 | | 安装 | 在独立临时环境从私有索引下载/安装已发布版本;必要时 --no-build-isolation 避免索引无 setuptools;核来源/hash,不误用本地 editable | | 外部页面 | registry 包正文与仓库链接、Gitea Release/tag 实际可见;不以 POST 返回码代替最终状态 | @@ -271,7 +271,7 @@ make ci ## 4. 自审清单与残余边界 | 需求 | 覆盖任务 | -|---|---| +| --- | --- | | 工具双并行、消息往返、raw=max、非流式 | T1–T3、T7 | | error+DONE 所有模式失败、attempts=2 | T2、T5 | | 缺 DONE 不 salvage 工具、length 不修复 | T3 | @@ -288,7 +288,7 @@ P1 最终 assistant role、P2 来源核查前置均已采纳,证据见来源 T1–T6 代码/文档/许可已落实;T7 工具真实冒烟、Redis、质量门已执行,独立代码审查由父会话接续;T8 禁止本 worker 执行。 | 验证 | 实际结果/证据 | -|---|---| +| --- | --- | | 基线红 | tests/outputs/issue29/baseline-red.log:error+DONE 未抛、双文本丢 reasoning、模式 API 缺失,3 failed | | 扩展红绿 | expanded-red.log 19 failed(git archive 0e29dea 的 src,不改主树);expanded-green.log 同19 passed | | 防御红绿 | defense-red.log 3 failed:usage 裸错误/空 tool_calls 丢失;defense-green.log 同3 passed | @@ -305,13 +305,12 @@ Wiki add_entity 会覆写无frontmatter同名文件,现场检查发现后已 补充最终证据:unit-final.log 1678 passed(23.84s),smoke.log + smoke.exit=0 为既有真实 chat 冒烟4 passed(97.18s);未跑昂贵全模型矩阵。源代码最后变更早于 ci-final,后续只增测试/文档;最后单元覆盖全部新增测试。 - ## 6. 审查修复与1.4.0准备(2026-10-01,未发布) 已读取首轮独立报告并核验采纳 P2 空产物缓存、Minor 测试双向依赖,详见 [审查处置](../reviews/2026-10-01-issue29-cache-review.md)。本轮只在隔离 feature 树写入,主树既有脏文档未改;不合并、不 push/tag/上传、不关issue。 | 本轮命令/证据(日志均在 tests/outputs/issue29,不提交) | 实际结果 | -|---|---| +| --- | --- | | 新缓存回归修复前:review-cache-red.log | 10 failed、1 passed:五种无效产物×两种缓存投影误命中;合法tool-only通过 | | 四模块定向:review-cache-green.log | 268 passed,17.71s;包含11项新增缓存回归 | | 真实Redis+包测试:review-redis-package.log | 13 passed,2.66s(6 Redis、7包) | @@ -326,3 +325,21 @@ wheel SHA256 `3186d01d7710c3b5ef727b59f95e8c2db0821277a79491ffb913dd2ce34a888d` 跳过项仍为17个独立slow Redis时间变体及6个缺私有图像语料OCR;110 slow未选中。本轮不重复付费网关:复用前轮流式/非流式工具双轮2通过和chat冒烟4通过,当前生产改动只统一空产物判据,工具/文本正常行为已有定向与全套件证明;合并后slow发布门由父执行。构建有setuptools许可表格弃用提醒(兼容setuptools>=68设计),并有基础conda RequestsDependencyWarning;均不等于当前构建或测试失败。 按commit skill提交feature全部实现、修复、许可与发布准备,原main脏文件及运行产物不纳入。提交后交父最终独立复核;T8外部发布尚未完成,不能提前关闭#29。 + +## 7. 版本定案与历史文档归档(2026-10-01 EDT / 2026-10-02 UTC) + +用户最终指定本次发布 __1.3.9__,取代尚未打 tag/上传的 1.4.0。上节 1.4.0 构建散列、测试结果与历史提交标题均是当时实证,保留原样,不冒充 1.3.9 产物。README 安装约束、能力标题、CHANGELOG 与两处版本同步;自定义 `Transport.complete(response_mode=...)` 适配要求及旧缓存更换 namespace/salt 提醒保持不变。CHANGELOG 使用执行环境本地日期 2026-10-01(EDT),知识库时间戳明确使用 UTC。 + +历史六文档独立归档提交 `ce10881`;采纳独审发现,仅补 #24 implements 边缺少的 plan/design 两节点。验证旧新节点/边/日志并集完整、120 个索引链接与计数一致、三文件仅空白/空引用格式、无冲突标记。剩余 15 个历史未注册端点以及 wiki lint 的 15 条孤立/稀疏提示均未扩大处理。原始备份 `/tmp/pgw140-release` 及 stash 保留。 + +本轮只准备与本地构建,不合并、不 push/tag/上传、不关闭 issue;后续独审及发布外部验收仍是硬门。相关功能代码未变,可复用 `/tmp/pgw140-release/main-ci.log` 的 1828 项通过、95% 覆盖及 `main-slow.log` 的 6 项真实网关通过(205.81s);本轮另执行包/协议定向、质量检查和 1.3.9 构建解包验证。 + +| 本轮证据(`/tmp/pgw139-prepare/`) | 实际结果 | +| --- | --- | +| source.log / tests.log | 显式 `PYTHONPATH=/home/iomgaa/Projects/PolyGateway/src` 确认源码位置及1.3.9;包+缓存+协议四模块276 passed,12.43s,无新增行为测试 | +| check.log | `make check` 格式、ruff、依赖契约通过,1 kept/0 broken | +| docs-validation.log / wiki-lint.log | #24两端点补齐;原新记录保全、120链接计数通过;存量15个端点缺口及15条lint提示未清理 | +| remote-tags.txt / registry-simple.html | 2026-10-02 UTC读取远端tag与匿名simple均无1.3.9/1.4.0,无版本冲突;发布前仍须复查 | +| build.log / twine.log / artifacts.log / unpacked-import.log | 1.3.9 wheel/sdist构建、twine及全Python源码/README/LICENSE逐字核验通过;解包路径独立导入成功,38遥测字段实测不变 | + +本地 wheel SHA256 `45306557152fd44f8135928041e47924834c3b4039c586f72d521f51b4590dd3`;sdist SHA256 `8f455973e7fef71811e2b86f5a14cb03469d893ac9720b902f522d2b1a8dcd40`。产物位于 `/tmp/pgw139-prepare/dist`,不是已发布包。构建仅有已知许可证表格弃用提示、conda基础环境依赖警告;不为清警告增加依赖。 diff --git a/research-wiki/reviews/2026-10-01-issue29-cache-review.md b/research-wiki/reviews/2026-10-01-issue29-cache-review.md index c2cd447..505e070 100644 --- a/research-wiki/reviews/2026-10-01-issue29-cache-review.md +++ b/research-wiki/reviews/2026-10-01-issue29-cache-review.md @@ -7,11 +7,10 @@ date: 2026-10-01 # 保真缓存审查修复与1.4.0准备 - ## 审查采纳 | 级别/问题 | 核验与处置 | -|---|---| +| --- | --- | | Important/P2:空协议缓存绕过成功判据 | 已实证:新测试在修复前 10 failed、1 passed;role-only、null/空/空白正文+空工具、reasoning-only,分别带空投影/伪造旧投影均误命中。采纳并修复。 | | Minor:协议/治理测试互相导入 | 已核验双向依赖;将帧构造放基础协议测试中,上层 fidelity 单向复用,没有新增 helpers 抽象。 | @@ -24,3 +23,7 @@ date: 2026-10-01 ## 发布准备边界 1.4.0 对应新增公共协议支持及 transport 端口参数;2026-10-01 远端 tags 和匿名 registry simple 最大版本均1.3.8,无1.4.0冲突。README安装约束、能力表、CHANGELOG定版、两处版本同步。新增 `.env.example` 仅四行说明,无凭据。源码/许可来源核查复用已独审 finding;新产物仍须父会话最终复核后发布。本轮不合并、不 push/tag/上传、不关issue;原main脏文件未改。 + +## 后续版本定案(2026-10-01 EDT / 2026-10-02 UTC) + +用户最终指定发布 **1.3.9**,取代本文当时准备但从未发布的 1.4.0。本文标题、历史构建及审查证据保留原值;当前发布目标与新构建核验见[计划 §7](../plans/2026-10-01-issue29-openai-fidelity.md)。版本号变更不撤销自定义 Transport 的 `response_mode` 适配要求。 diff --git a/src/polygateway/__init__.py b/src/polygateway/__init__.py index 9d9ea7c..c76eca6 100644 --- a/src/polygateway/__init__.py +++ b/src/polygateway/__init__.py @@ -54,7 +54,7 @@ from polygateway.types import ( ThinkingObservation, ) -__version__ = "1.4.0" +__version__ = "1.3.9" __all__ = [ "DEFAULT_PROFILES",