Merge remote-tracking branch 'origin/main' into codex/p0-obs-002-20260715
This commit is contained in:
@@ -4,7 +4,7 @@ AWOOOI API Configuration
|
||||
Pydantic Settings + Environment Variables
|
||||
|
||||
ADR-005: BFF Architecture
|
||||
ADR-006: AI Fallback Strategy (Ollama -> Gemini -> Claude)
|
||||
ADR-006: AI Fallback Strategy (GCP-A -> GCP-B -> host111 -> Gemini)
|
||||
|
||||
Four Iron Laws:
|
||||
1. Async-First
|
||||
@@ -418,12 +418,63 @@ class Settings(BaseSettings):
|
||||
default=["bge-m3:latest", "qwen2.5:7b-instruct", "qwen3:14b", "deepseek-r1:14b", "hermes3:latest"],
|
||||
description="HeartbeatReportService 探測必要模型是否載入",
|
||||
)
|
||||
# 2026-04-25 critic-fix Part2 H7 by Claude Engineer-C2
|
||||
# Gemini 帳單熔斷:每日呼叫上限,超過改走 188+Nemotron
|
||||
# 超過上限後寫 Redis key ollama:gemini_daily_count:{date},TTL 86400s
|
||||
# Gemini is the final paid fallback after GCP-A -> GCP-B -> host111.
|
||||
# All generation calls atomically reserve requests/tokens/cost in Redis.
|
||||
GEMINI_MODEL: str = Field(
|
||||
default="gemini-2.5-flash-lite",
|
||||
min_length=1,
|
||||
description=(
|
||||
"Gemini 最終付費備援模型;成本閘只允許具有已查核 pricing policy 的模型"
|
||||
),
|
||||
)
|
||||
GEMINI_DAILY_QUOTA: int = Field(
|
||||
default=1000,
|
||||
description="每日 Gemini 呼叫上限,超過切到 188+Nemotron(P1.1 帳單熔斷)",
|
||||
default=500,
|
||||
ge=1,
|
||||
description="Gemini 每日 generation request 上限(單一權威值)",
|
||||
)
|
||||
GEMINI_RPM_LIMIT: int = Field(
|
||||
default=10,
|
||||
ge=1,
|
||||
description="Gemini 每分鐘 generation request 上限",
|
||||
)
|
||||
GEMINI_DAILY_TOKEN_LIMIT: int = Field(
|
||||
default=100_000,
|
||||
ge=1,
|
||||
description="Gemini 每日 token 上限(含尚未完成的原子 reservation)",
|
||||
)
|
||||
GEMINI_DAILY_COST_LIMIT_USD: float = Field(
|
||||
default=5.0,
|
||||
gt=0,
|
||||
description="Gemini 單日成本硬上限(USD)",
|
||||
)
|
||||
GEMINI_TOTAL_COST_LIMIT_USD: float = Field(
|
||||
default=5.0,
|
||||
gt=0,
|
||||
description="Gemini 累積成本硬上限(USD)",
|
||||
)
|
||||
GEMINI_COST_ALERT_THRESHOLD_USD: float = Field(
|
||||
default=4.0,
|
||||
gt=0,
|
||||
description="Gemini 累積成本告警閾值(USD,必須不高於硬上限)",
|
||||
)
|
||||
GEMINI_MAX_OUTPUT_TOKENS: int = Field(
|
||||
default=2048,
|
||||
ge=1,
|
||||
description="Gemini generation output 上限與 pre-call token reservation 基準",
|
||||
)
|
||||
GEMINI_USAGE_RECEIPT_TTL_SECONDS: int = Field(
|
||||
default=604_800,
|
||||
ge=86_400,
|
||||
description=(
|
||||
"Gemini non-secret auth-status receipt 保存秒數(預設七日);"
|
||||
"generation receipt 與 run identity 不設 TTL"
|
||||
),
|
||||
)
|
||||
GEMINI_FAILURE_COOLDOWN_SECONDS: int = Field(
|
||||
default=60,
|
||||
ge=1,
|
||||
le=3600,
|
||||
description="Gemini failed generation work-item cooldown seconds",
|
||||
)
|
||||
# Deprecated: use OPENCLAW_URL instead
|
||||
CLAWBOT_URL: str = Field(
|
||||
@@ -522,15 +573,18 @@ class Settings(BaseSettings):
|
||||
)
|
||||
|
||||
# ==========================================================================
|
||||
# AI Fallback Strategy (ADR-006 v1.3 + ADR-036)
|
||||
# Order: Ollama (local) -> NVIDIA NIM -> Gemini (cloud) -> Claude (cloud)
|
||||
# Tool Calling: Nemotron (專用) -> Gemini -> Claude
|
||||
# 2026-04-28 ogt + Claude Opus 4.7: 補 nvidia 對齊 ConfigMap (k8s/awoooi-prod/04-configmap.yaml)
|
||||
# 之前 default 缺 nvidia 與 ConfigMap drift,feedback_ai_fallback_order.md 鐵律
|
||||
# Runtime fallback strategy. Alert/incident order is enforced as:
|
||||
# GCP-A -> GCP-B -> host111 Ollama -> Gemini. No paid/provider insertion.
|
||||
# ==========================================================================
|
||||
AI_FALLBACK_ORDER: list[str] = Field(
|
||||
default=["ollama", "nvidia", "gemini", "claude"],
|
||||
description="AI provider fallback order",
|
||||
default=["ollama_gcp_a", "ollama_gcp_b", "ollama_local", "gemini"],
|
||||
description=(
|
||||
"唯一 production provider chain: GCP-A -> GCP-B -> host111 -> Gemini"
|
||||
),
|
||||
)
|
||||
ENABLE_GEMINI: bool = Field(
|
||||
default=False,
|
||||
description="Gemini paid final fallback explicit opt-in; default disabled",
|
||||
)
|
||||
GEMINI_API_KEY: str = Field(default="", description="Google Gemini API key")
|
||||
CLAUDE_API_KEY: str = Field(default="", description="Anthropic Claude API key")
|
||||
@@ -558,6 +612,13 @@ class Settings(BaseSettings):
|
||||
"then local 111 before cloud backup providers such as Gemini."
|
||||
),
|
||||
)
|
||||
ALERT_AI_STRICT_PROVIDER_CHAIN: bool = Field(
|
||||
default=True,
|
||||
description=(
|
||||
"Forbid direct OpenClaw/Nemo/NVIDIA/Claude incident delegation; "
|
||||
"the only alert route is GCP-A, GCP-B, host111, then Gemini."
|
||||
),
|
||||
)
|
||||
ALERT_OLLAMA_MODEL: str = Field(
|
||||
default="qwen3:14b",
|
||||
description=(
|
||||
@@ -595,9 +656,9 @@ class Settings(BaseSettings):
|
||||
def parse_ai_fallback(cls, v: str | list[str]) -> list[str]:
|
||||
"""
|
||||
解析 AI_FALLBACK_ORDER,支援三種格式:
|
||||
1. JSON: '["gemini","ollama","claude"]'
|
||||
2. CSV: 'gemini,ollama,claude'
|
||||
3. List: ["gemini", "ollama", "claude"]
|
||||
1. JSON: '["ollama_gcp_a","ollama_gcp_b","ollama_local","gemini"]'
|
||||
2. CSV: 'ollama_gcp_a,ollama_gcp_b,ollama_local,gemini'
|
||||
3. List: ["ollama_gcp_a", "ollama_gcp_b", "ollama_local", "gemini"]
|
||||
|
||||
2026-03-27 修復: ConfigMap 用 JSON 格式,原本只支援 CSV
|
||||
"""
|
||||
@@ -609,12 +670,23 @@ class Settings(BaseSettings):
|
||||
if v.startswith("["):
|
||||
try:
|
||||
parsed = json.loads(v)
|
||||
return [p.strip().lower() for p in parsed]
|
||||
values = [p.strip().lower() for p in parsed]
|
||||
except json.JSONDecodeError:
|
||||
pass # 降級到 CSV 解析
|
||||
# CSV 格式
|
||||
return [provider.strip().lower() for provider in v.split(",")]
|
||||
return [p.lower() for p in v]
|
||||
values = [provider.strip().lower() for provider in v.split(",")]
|
||||
else:
|
||||
values = [provider.strip().lower() for provider in v.split(",")]
|
||||
else:
|
||||
values = [p.strip().lower() for p in v]
|
||||
|
||||
expected = ["ollama_gcp_a", "ollama_gcp_b", "ollama_local", "gemini"]
|
||||
if values == ["ollama", "gemini"]:
|
||||
return expected
|
||||
if values != expected:
|
||||
raise ValueError(
|
||||
"AI_FALLBACK_ORDER must be exactly "
|
||||
"ollama_gcp_a,ollama_gcp_b,ollama_local,gemini"
|
||||
)
|
||||
return values
|
||||
|
||||
# ==========================================================================
|
||||
# Kubernetes / K3s (CTO-201)
|
||||
|
||||
Reference in New Issue
Block a user