Files
awoooi/packages/awooop-contracts/schemas/policy_routing.json
Your Name 8629ac709b
Some checks failed
run-migration / migrate (push) Failing after 59s
Code Review / ai-code-review (push) Successful in 1m8s
Type Sync Check / check-type-sync (push) Successful in 2m27s
feat(awooop): Phase 1-8 完整實作 — AwoooP Agent Platform 六平面架構
## Phase 1-3: Control Plane + Contract System
- awooop_phase1_control_plane_2026-05-04.sql: 12 張核心表 + RLS
- awooop_phase1_batch1_rls_2026-05-04.sql: 全部 FORCE RLS + GRANT
- packages/awooop-contracts/: 六合約 JSON Schema + golden fixtures
- src/models/awooop_contracts.py: Pydantic v2 contract models(extra=forbid)
- src/repositories/contract_repository.py: contract lifecycle(draft→published→active)
- src/services/contract_service.py: HMAC publish sig + Redis multi-sig activate
- src/services/schema_validator.py: LLM output validator(retry×3, E-SCHEMA-001)

## Phase 2: Tenant Isolation
- awooop_phase2_budget_ledger_2026-05-04.sql: budget_ledger + RLS
- src/services/budget_service.py: Token Budget Hard Kill 三層防線
- src/core/context.py: PROJECT_ID ContextVar(31 background loop 自動繼承)
- src/db/base.py + models.py: project_id 欄位 + RLS set_config 注入
- src/hermes/nl_gateway.py: project_id Redis key 前綴(Phase A 雙寫)
- src/services/anomaly_counter.py: per-project 改造(Phase A fallback)

## Phase 4: Platform Shell in Shadow Mode
- awooop_phase4_run_state_2026-05-04.sql: run_state + step_journal + idempotency
- src/services/run_state_machine.py: 8-state FSM + SKIP LOCKED + stale reaper
- src/services/platform_runtime.py: UUID v7 + W3C trace_id + shadow_execute
- src/services/audit_sink.py: PII/secret redaction 9 patterns
- src/api/v1/platform/runs.py: POST/GET /v1/platform/runs(Router→Service 架構)
- src/workers/platform_worker.py: SKIP LOCKED worker + heartbeat + reaper loop
- src/main.py: platform router + lifespan worker start/stop

## Phase 5: MCP Gateway 五閘門
- awooop_phase5_mcp_gateway_2026-05-04.sql: 4 表 + RLS
- src/plugins/mcp/gateway.py: McpGateway(Gate 1~5, E-MCP-GATE-001~009)
- src/plugins/mcp/redaction_middleware.py: 雙層 redaction + 16K 截斷
- src/plugins/mcp/registry.py: __provider name mangling(ADR-116)
- src/plugins/mcp/credential_resolver.py: k8s secret ref 解析
- tests/test_mcp_credential_isolation.py: 10 個迴歸測試(secret leak 防再現)

## Phase 6-8: EwoooC + Channel Hub + Approval Token
- awooop_phase6_ewoooc_onboarding_2026-05-04.sql: ewoooc tenant + 4 read-only MCP tools
- awooop_phase7_channel_hub_2026-05-04.sql: conversation_event + outbound_message
- src/services/provider_proxy.py: ProviderProxy + PlatformEnvelope(ADR-115)
- src/services/channel_hub.py: Telegram inbound mirror + Progressive Feedback(30s)
- src/services/awooop_approval_token.py: HS256 + jti NX replay 防護 + suggest mode

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:53 +08:00

118 lines
3.6 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://awooop.platform/contracts/v1/policy_routing",
"title": "Policy Routing Contract",
"description": "AwoooP 路由/政策合約 — 定義 LLM 路由規則、fallback 順序與費用保護",
"type": "object",
"required": ["policy_id", "policy_name", "routing_rules"],
"additionalProperties": false,
"properties": {
"policy_id": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9_-]{1,127}$",
"description": "Policy 識別符"
},
"policy_name": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "人類可讀政策名稱"
},
"routing_rules": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["rule_id", "priority", "provider", "model"],
"additionalProperties": false,
"properties": {
"rule_id": {"type": "string"},
"priority": {
"type": "integer",
"minimum": 0,
"maximum": 9999,
"description": "數字越小優先級越高"
},
"provider": {
"type": "string",
"enum": ["anthropic", "openai", "ollama", "gemini", "nvidia", "openrouter"]
},
"model": {"type": "string"},
"condition": {
"type": "object",
"description": "路由條件task_type, token_budget, time_range 等)",
"properties": {
"task_types": {
"type": "array",
"items": {"type": "string"}
},
"max_prompt_tokens": {"type": "integer", "minimum": 1},
"time_range": {
"type": "object",
"properties": {
"start_utc": {"type": "string", "pattern": "^[0-2][0-9]:[0-5][0-9]$"},
"end_utc": {"type": "string", "pattern": "^[0-2][0-9]:[0-5][0-9]$"}
}
}
}
},
"weight": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 100,
"description": "同 priority 時的加權比例(用於 A/B 流量分割)"
}
}
},
"description": "路由規則清單(按 priority 升序評估)"
},
"fallback_provider": {
"type": "string",
"enum": ["anthropic", "openai", "ollama", "gemini", "nvidia", "openrouter"],
"description": "所有規則 miss 時的最終 fallback"
},
"fallback_model": {
"type": "string",
"description": "fallback_provider 使用的模型"
},
"max_cost_per_run_usd": {
"type": ["number", "null"],
"minimum": 0,
"description": "單次 run 費用上限null = 無限制"
},
"retry_policy": {
"type": "object",
"additionalProperties": false,
"properties": {
"max_retries": {
"type": "integer",
"minimum": 0,
"maximum": 10,
"default": 3
},
"backoff_base_seconds": {
"type": "number",
"minimum": 0.1,
"maximum": 60,
"default": 1.0
},
"retry_on_provider_errors": {
"type": "boolean",
"default": true
}
}
},
"effective_from": {
"type": "string",
"format": "date-time",
"description": "政策生效起始時間ISO 8601"
},
"effective_to": {
"type": ["string", "null"],
"format": "date-time",
"description": "政策生效結束時間null = 永久有效"
}
}
}