fix(gateway): 熔断计入持续 4xx + 去 assert + Protocol/transient 去重
P1-2 非可重试错误(持续 401/403)也 record_failure,坏 key 可触发熔断。 P1-9 _complete_structured 的 assert 改显式 raise ValueError(-O 安全)。 P2 GatewayRun 抽到 orchestrator/_protocols.py 单点(去 4 处重复); _is_transient 抽到 adapters/base.py is_transient_by_name(去 3 处重复); Gemini Protocol 改 async def;gateway._retrying 去无用 async。
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from ._protocols import GatewayRun
|
||||
from .collect import (
|
||||
CONTINUITY,
|
||||
FORESHADOW,
|
||||
@@ -43,7 +44,6 @@ from .review_node import (
|
||||
REVIEW_INCOMPLETE,
|
||||
REVIEW_OK,
|
||||
BoundReviewNode,
|
||||
GatewayRun,
|
||||
build_review_context,
|
||||
build_review_request,
|
||||
make_review_node,
|
||||
|
||||
17
packages/core/ww_core/orchestrator/_protocols.py
Normal file
17
packages/core/ww_core/orchestrator/_protocols.py
Normal file
@@ -0,0 +1,17 @@
|
||||
"""编排器节点对网关的最小依赖 Protocol(单点定义,DRY)。
|
||||
|
||||
仅依赖 `ww_llm_gateway.types`(无环)→ 各节点(review/generation/outline/style_extract)
|
||||
共用此单一定义,不再每模块各自重复声明(见 memory/gotchas.md 更新)。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Protocol
|
||||
|
||||
from ww_llm_gateway.types import LlmRequest, LlmResponse
|
||||
|
||||
|
||||
class GatewayRun(Protocol):
|
||||
"""编排器节点对网关的最小依赖——只需 `run`(注入真网关或 mock)。"""
|
||||
|
||||
async def run(self, req: LlmRequest) -> LlmResponse: ...
|
||||
@@ -25,7 +25,6 @@ from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
from collections.abc import Sequence
|
||||
from typing import Protocol
|
||||
|
||||
import structlog
|
||||
from pydantic import BaseModel
|
||||
@@ -37,21 +36,13 @@ from ww_agents import (
|
||||
ContinuityReview,
|
||||
WorldGenResult,
|
||||
)
|
||||
from ww_llm_gateway.types import Block, LlmRequest, LlmResponse, Scope
|
||||
from ww_llm_gateway.types import Block, LlmRequest, Scope
|
||||
|
||||
from ._protocols import GatewayRun
|
||||
|
||||
log = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
class GatewayRun(Protocol):
|
||||
"""生成节点对网关的最小依赖——只需 `run`(注入真网关或 mock)。
|
||||
|
||||
模块内部用(每模块各自声明,不跨模块复用、不在 orchestrator `__init__` 重复导出,
|
||||
见 gotchas 2026-06-18)。
|
||||
"""
|
||||
|
||||
async def run(self, req: LlmRequest) -> LlmResponse: ...
|
||||
|
||||
|
||||
def _build_request(
|
||||
spec: AgentSpec,
|
||||
*,
|
||||
|
||||
@@ -23,8 +23,9 @@ from ww_agents import (
|
||||
style_drift_spec,
|
||||
)
|
||||
|
||||
from ._protocols import GatewayRun
|
||||
from .collect import ReviewRecorder, collect_reviews
|
||||
from .review_node import GatewayRun, run_review
|
||||
from .review_node import run_review
|
||||
from .state import ChapterState
|
||||
from .write_node import GatewayStream, write_node
|
||||
|
||||
|
||||
@@ -16,21 +16,16 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
from typing import Protocol
|
||||
|
||||
import structlog
|
||||
from ww_agents import AgentSpec, OutlineResult
|
||||
from ww_llm_gateway.types import Block, LlmRequest, LlmResponse, Scope
|
||||
from ww_llm_gateway.types import Block, LlmRequest, Scope
|
||||
|
||||
from ._protocols import GatewayRun
|
||||
|
||||
log = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
class GatewayRun(Protocol):
|
||||
"""大纲节点对网关的最小依赖——只需 `run`(注入真网关或 mock)。"""
|
||||
|
||||
async def run(self, req: LlmRequest) -> LlmResponse: ...
|
||||
|
||||
|
||||
def build_outline_request(
|
||||
spec: AgentSpec,
|
||||
*,
|
||||
|
||||
@@ -19,12 +19,13 @@ M2 先接 **continuity**(C6 `continuity_spec`),设计成可扩——图按
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from typing import Any, Protocol
|
||||
from typing import Any
|
||||
|
||||
import structlog
|
||||
from ww_agents import AgentSpec
|
||||
from ww_llm_gateway.types import Block, LlmRequest, LlmResponse, Scope
|
||||
from ww_llm_gateway.types import Block, LlmRequest, Scope
|
||||
|
||||
from ._protocols import GatewayRun
|
||||
from .state import ChapterState
|
||||
|
||||
log = structlog.get_logger(__name__)
|
||||
@@ -36,11 +37,16 @@ REVIEW_INCOMPLETE = "incomplete" # 该审网关失败 → 标未完成,不阻
|
||||
# 已绑定 gateway 的节点形(图工厂 / T2.5 直接跑审稿时用)。
|
||||
BoundReviewNode = Callable[[ChapterState], Awaitable[dict[str, Any]]]
|
||||
|
||||
|
||||
class GatewayRun(Protocol):
|
||||
"""审稿节点对网关的最小依赖——只需 `run`(注入真网关或 mock)。"""
|
||||
|
||||
async def run(self, req: LlmRequest) -> LlmResponse: ...
|
||||
__all__ = [
|
||||
"REVIEW_INCOMPLETE",
|
||||
"REVIEW_OK",
|
||||
"BoundReviewNode",
|
||||
"GatewayRun",
|
||||
"build_review_context",
|
||||
"build_review_request",
|
||||
"make_review_node",
|
||||
"run_review",
|
||||
]
|
||||
|
||||
|
||||
def build_review_context(*, draft: str, stable_core: str, volatile: str) -> str:
|
||||
|
||||
@@ -17,25 +17,16 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
from typing import Protocol
|
||||
|
||||
import structlog
|
||||
from ww_agents import AgentSpec, StyleFingerprintResult
|
||||
from ww_llm_gateway.types import Block, LlmRequest, LlmResponse, Scope
|
||||
from ww_llm_gateway.types import Block, LlmRequest, Scope
|
||||
|
||||
from ._protocols import GatewayRun
|
||||
|
||||
log = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
class GatewayRun(Protocol):
|
||||
"""文风提取节点对网关的最小依赖——只需 `run`(注入真网关或 mock)。
|
||||
|
||||
模块内部用(每模块各自声明,不跨模块复用、不在 orchestrator `__init__` 重复导出,
|
||||
见 gotchas 2026-06-18)。
|
||||
"""
|
||||
|
||||
async def run(self, req: LlmRequest) -> LlmResponse: ...
|
||||
|
||||
|
||||
def build_style_extract_request(
|
||||
spec: AgentSpec,
|
||||
*,
|
||||
|
||||
Reference in New Issue
Block a user