feat(ai): 建立 PixelRAG application portfolio
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
python scripts/ops/check_production_version_truth.py
|
||||
|
||||
目前最新版本仍以 production `https://mo.wooo.work/health` readback 為準。
|
||||
本輪 source target 為 `V10.747`;部署完成前不得宣稱正式環境已是 `V10.747`。
|
||||
本輪 source target 為 `V10.748`;部署完成前不得宣稱正式環境已是 `V10.748`。
|
||||
舊 iCloud checkout 不是 Gitea dev worktree,不得拿來當最新版本真相。
|
||||
|
||||
================================================================================
|
||||
@@ -59,6 +59,7 @@ P6. DB apply authorization / signing / closeout
|
||||
P0-2026-07-09. PixelRAG / MCP / RAG 全自動主線
|
||||
- 已完成:多電商 PixelRAG visual evidence lane 與 external MCP/RAG integration readback。
|
||||
- 已完成:PixelRAG receipt → internal RAG candidate replay,以及 OCR/VLM replay contract no-write readback。
|
||||
- 已完成:PixelRAG application portfolio,把可整合/可運用場景整理成 API/CLI 可讀的 priority lane、status、next machine action 與 forbidden guardrail。
|
||||
- 進行中:MCP/RAG runtime health → AI automation smoke。
|
||||
- 未開始:Ollama-first OCR/VLM extraction worker、Ollama-first visual embedding benchmark、pgvector-compatible visual metadata、Coupang platform probe / structured API、跨平台 source contracts。
|
||||
- 主線文件:`docs/guides/ai_automation_mainline_work_items.md`。
|
||||
|
||||
@@ -402,7 +402,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
|
||||
# ==========================================
|
||||
# 系統版本與路徑
|
||||
# ==========================================
|
||||
SYSTEM_VERSION = "V10.747"
|
||||
SYSTEM_VERSION = "V10.748"
|
||||
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
|
||||
public_url = PUBLIC_URL # 用於模板顯示
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# PChome 業績成長自動化作戰系統 — AI 競價情報模組 Single Source of Truth
|
||||
|
||||
> **最後更新**: 2026-07-09 (台北時間)
|
||||
> **狀態**: 🟢 四 AI Agent 自動化閉環已落地;LLM 路由紅線升級為 Ollama-first 三主機級聯;PChome 後台業績匯入韌性已補強;產品定位正名為「PChome 業績成長自動化作戰系統」;外部市場來源正規化層、自動同步、作戰清單與價格參考表優先讀取、CSV 備援預檢、前台操作入口、高可見頁面繁中化守門、比價/作戰 UI 工作台化、AI 密集工作台文字密度守門、跨平台來源治理、商品身份 UI 契約、sitewide visual QA runtime readback、external MCP/RAG integration monitoring、PixelRAG RAG candidate replay monitoring、PixelRAG OCR/VLM replay contract monitoring、PChome auto-policy authorization guard monitoring、decision preflight machine evidence monitoring、decision closeout monitoring、authorization issuer gate monitoring、signing decision preflight monitoring、signing decision closeout monitoring、signing issuer guard monitoring、signing issuer closeout monitoring、signing execution preflight monitoring、signing execution closeout monitoring、signed receipt preflight monitoring、signed receipt closeout monitoring、signed receipt evidence intake monitoring、detached verification evidence validation monitoring、verifier receipt closeout monitoring、authorization evidence execution preflight monitoring、authorization evidence execution closeout monitoring、controlled apply final preflight monitoring、controlled dry-run package monitoring 與 controlled dry-run receipt closeout monitoring 已建立,GCP embedding 熔斷延後處理、110 proxy rescue 與 direct host health skip 已建立
|
||||
> **適用版本**: V10.747
|
||||
> **狀態**: 🟢 四 AI Agent 自動化閉環已落地;LLM 路由紅線升級為 Ollama-first 三主機級聯;PChome 後台業績匯入韌性已補強;產品定位正名為「PChome 業績成長自動化作戰系統」;外部市場來源正規化層、自動同步、作戰清單與價格參考表優先讀取、CSV 備援預檢、前台操作入口、高可見頁面繁中化守門、比價/作戰 UI 工作台化、AI 密集工作台文字密度守門、跨平台來源治理、商品身份 UI 契約、sitewide visual QA runtime readback、external MCP/RAG integration monitoring、PixelRAG RAG candidate replay monitoring、PixelRAG OCR/VLM replay contract monitoring、PixelRAG application portfolio、PChome auto-policy authorization guard monitoring、decision preflight machine evidence monitoring、decision closeout monitoring、authorization issuer gate monitoring、signing decision preflight monitoring、signing decision closeout monitoring、signing issuer guard monitoring、signing issuer closeout monitoring、signing execution preflight monitoring、signing execution closeout monitoring、signed receipt preflight monitoring、signed receipt closeout monitoring、signed receipt evidence intake monitoring、detached verification evidence validation monitoring、verifier receipt closeout monitoring、authorization evidence execution preflight monitoring、authorization evidence execution closeout monitoring、controlled apply final preflight monitoring、controlled dry-run package monitoring 與 controlled dry-run receipt closeout monitoring 已建立,GCP embedding 熔斷延後處理、110 proxy rescue 與 direct host health skip 已建立
|
||||
> **適用版本**: V10.748
|
||||
|
||||
---
|
||||
|
||||
@@ -115,6 +115,7 @@
|
||||
- 2026-07-09 起 external MCP/RAG integration 必須進入 AI automation runtime monitoring:`/api/ai-automation/external-mcp-rag-integration` 與 `scripts/ops/report_external_mcp_rag_integration.py` 需輸出 9 個 capability 的 absorbed / unresolved 狀態、內部治理落點與 runtime flags;`/api/ai-automation/smoke` 需包含 `External MCP/RAG integration readback`,`/api/ai-automation/scheduled-health-summary` 需輸出 `external_mcp_rag_integration` family。`MCP_ROUTER_ENABLED=false` 或 `RAG_ENABLED=false` 必須被視為 runtime gap,不得因 registry 已完成就宣稱 MCP/RAG runtime 已全面啟用。
|
||||
- 2026-07-09 起 PixelRAG visual receipts 必須可轉為內部 RAG candidate replay readback:`/api/ai-automation/pixelrag-rag-candidate-replay` 與 `scripts/ops/report_pixelrag_rag_candidate_replay.py` 只讀 `capture_receipt.json`,拆分 eligible / blocked / invalid receipts,輸出 tile/missing/barrier count、candidate text、promotion boundary 與 next machine action;`/api/ai-automation/smoke` 需包含 `PixelRAG RAG candidate replay`,`/api/ai-automation/scheduled-health-summary` 需輸出 `pixelrag_rag_candidate_replay` family。blocked / 403 / captcha / access denied / verify traffic page 只能進 platform probe 或 structured API 策略,不得當作商品資料、不得寫正式價格表、不得直接寫 `ai_insights`。
|
||||
- 2026-07-09 起 PixelRAG visual receipts 進入 OCR/VLM 前必須先輸出 no-write replay contract:`/api/ai-automation/pixelrag-ocr-vlm-replay` 與 `scripts/ops/report_pixelrag_ocr_vlm_replay.py` 只讀 saved tiles,輸出欄位 schema、輸出 schema、confidence/evidence validation rules、Ollama-first route contract 與 next machine action;`/api/ai-automation/smoke` 需包含 `PixelRAG OCR/VLM replay contract`,`/api/ai-automation/scheduled-health-summary` 需輸出 `pixelrag_ocr_vlm_replay` family。此 contract 不執行 OCR/VLM、不呼叫模型、不讀 secret、不連外、不寫 DB、不寫 `ai_insights`、不寫正式價格表;blocked / 403 / captcha / access denied / verify traffic page 只能進 platform probe 或 structured API 策略。
|
||||
- 2026-07-09 起 PixelRAG 可整合/可運用範圍必須有機器可讀 application portfolio:`/api/ai-automation/pixelrag-application-portfolio` 與 `scripts/ops/report_pixelrag_application_portfolio.py` 需輸出 commerce、RAG、UX、ops、marketing、governance lanes,每條 lane 必須包含 priority、status、integrates_with、use_cases、current_capability、next_machine_action、no-write 邊界與 forbidden guardrails。此 portfolio 不抓外站、不呼叫模型、不讀 secret、不寫 DB;其用途是把「還可以整合哪些」變成可排程、可驗證、可拒絕違規場景的主線工作項目。
|
||||
- 2026-07-02 起 `/ai_intelligence` 商品明細與單品作戰詳情的四格價格證據必須可測:PChome 價格、MOMO 參考價、差距、可信度需以 `data-evidence` 固定,並以 `aria-label="價格證據"` 對應可掃描區塊;候選待確認或缺資料只能顯示「候選待確認 / 待補」,不得捏造價格或讓使用者打開 raw payload 才知道判斷依據。
|
||||
- 2026-07-02 起 `/ai_intelligence` 必須是密集 AI 工作台,不得退回大段文字說明頁:首屏與明細可見內容只保留短狀態、數字、四格證據與下一步按鈕;KPI note、benchmark detail、alert 副句、策略說明、decision copy、來源長句與單品 reason list 不得佔用第一層視覺。`tests/test_ai_intelligence_text_density_guardrails.py` 必須鎖住 `data-density-guardrail="compact-ai-workbench"`、短任務文案、detail meta 與 hidden explanatory copy。
|
||||
- 2026-07-02 起 `/observability/overview` 也必須採密集 AI 觀測工作台:首屏以 `data-density-guardrail="compact-observability-workbench"`、`AI 觀測 / 風險優先 / 下一步` 與 golden signals 先呈現狀態、數字與操作入口;hero lede、signal note、route desc、host meta 與資料來源長句不得佔用第一層視覺。`tests/test_observability_text_density_guardrails.py` 必須鎖住 compact marker 與 hidden explanatory copy。
|
||||
@@ -876,6 +877,7 @@ POSTGRES_HOST=momo-db
|
||||
| 2026-07-09 | PChome auto-policy controlled dry-run receipt closeout 必須有 runtime monitoring | V10.745 起 `/api/ai-automation/smoke`、`/api/ai-automation/scheduled-health-summary` 與 `/metrics` 必須輸出 `PChome auto-policy controlled dry-run receipt closeout` / `pchome_auto_policy_controlled_dry_run_receipt_closeout`;此 runtime check 自動驗證 controlled dry-run package carry-forward、dry-run result parser、receipt validation report、command-shape hash、rollback binding、post-apply verifier binding、12 個 receipt closeout checks、12 個 closeout fields、10 個 acceptance gates、same-run production truth 與 future runner readiness,但明確標記 `receipt_validation_status=preview_validated_not_executed`、`validation_execution_performed=false`、`validation_stdout_included=false`、`validation_stderr_included=false`、`validation_database_apply_authorized=false`、`reads_secret_count=0`、`executes_script_count=0`、`executes_sql_count=0`、`writes_database_count=0`、`signs_database_apply_authorization_count=0`、`primary_human_gate_count=0`、`executes_authorization_evidence=false`、`executes_database_apply=false`、`ready_for_database_apply_now=false`、`database_apply_authorized=false`、`issues_database_apply_authorization=false`、`signs_database_apply_authorization=false`,不讀 secret、不執行 dry-run、不捕捉 stdout/stderr、不執行 authorization evidence、不執行 database apply、不執行 endpoint/SQL、不寫 DB、不簽發 apply authorization,只允許進入下一段 controlled dry-run runner readiness lane。 |
|
||||
| 2026-07-09 | PixelRAG / external MCP/RAG 必須有 runtime monitoring 與 candidate replay | V10.746 起 `/api/ai-automation/smoke`、`/api/ai-automation/scheduled-health-summary` 必須輸出 `External MCP/RAG integration readback` / `external_mcp_rag_integration` 與 `PixelRAG RAG candidate replay` / `pixelrag_rag_candidate_replay`;external MCP/RAG readback 回報 9 個 capability 的 absorbed / unresolved 與 `MCP_ROUTER_ENABLED`、`RAG_ENABLED` runtime flags,PixelRAG replay 只讀 visual receipt,拆分 eligible / blocked / invalid,並明確標記 blocked page 不是商品資料。此路徑不讀 secret、不呼叫外部網路、不寫 DB、不寫 `ai_insights`、不寫正式價格表;eligible receipt 仍需 OCR/VLM replay、identity matcher replay、PromotionGate 與 embedding signature guard。 |
|
||||
| 2026-07-09 | PixelRAG OCR/VLM replay contract 必須有 runtime monitoring | V10.747 起 `/api/ai-automation/pixelrag-ocr-vlm-replay`、`scripts/ops/report_pixelrag_ocr_vlm_replay.py`、`/api/ai-automation/smoke` 與 `/api/ai-automation/scheduled-health-summary` 必須輸出 no-write OCR/VLM replay contract / `pixelrag_ocr_vlm_replay` family;readback 只讀 saved tiles 與 RAG candidate replay,輸出 ready / blocked / invalid contracts、field schema、output schema、validation rules、Ollama-first route contract、blocked page guard 與 next machine action。此階段明確標記 `extraction_execution_performed=false`、`ocr_execution_performed=false`、`vlm_execution_performed=false`、`writes_database=false`、`writes_ai_insights=false`、`writes_price_tables=false`、`network_call=false`、`secret_read=false`、`primary_human_gate_count=0`;ready receipt 才能進下一段 `run_ollama_first_vlm_replay_worker`,blocked receipt 只能進 platform probe 或 structured API 策略。 |
|
||||
| 2026-07-09 | PixelRAG application portfolio 必須把可整合場景轉成主線工作項目 | V10.748 起 `/api/ai-automation/pixelrag-application-portfolio` 與 `scripts/ops/report_pixelrag_application_portfolio.py` 必須輸出 PixelRAG 在 commerce、RAG、UX、ops、marketing、governance 的可整合/可運用 lanes;每條 lane 需有 priority、status、integrates_with、use_cases、current_capability、next_machine_action、no-write 邊界與 forbidden guardrails。此 readback 依據 PixelRAG visual-RAG pattern、Google Merchant product data、Google Product structured data 與 Baymard product list UX 轉成內部工作項目;它不抓外站、不呼叫模型、不讀 secret、不寫 DB、不把像素結果當正式價格。 |
|
||||
| 2026-06-29 | PChome DB apply 授權 lane 必須先通過 no-write guard / decision preflight / decision closeout / issuer gate / signing-decision preflight / signing-decision closeout / signing-issuer guard | V10.725 的 PChome mapping backlog auto-policy 已新增 `/api/ai/pchome-growth/mapping-backlog/auto-policy-db-apply-authorization-lane-guard`、`/api/ai/pchome-growth/mapping-backlog/auto-policy-db-apply-authorization-decision-preflight`、`/api/ai/pchome-growth/mapping-backlog/auto-policy-db-apply-authorization-decision-closeout`、`/api/ai/pchome-growth/mapping-backlog/auto-policy-db-apply-authorization-issuer-gate`、`/api/ai/pchome-growth/mapping-backlog/auto-policy-db-apply-authorization-signing-decision-preflight`、`/api/ai/pchome-growth/mapping-backlog/auto-policy-db-apply-authorization-signing-decision-closeout` 與 `/api/ai/pchome-growth/mapping-backlog/auto-policy-db-apply-authorization-signing-issuer-guard`;這些 endpoint 只驗證 final exact request package、same-run production truth requirement、secret rejection、rollback boundary、lane entry requirements、decision input requirements、rejection policy、post-apply verifier、future authorization decision package、final nonsecret authorization envelope、signing decision preflight inputs、unsigned signing decision package 與 signable request boundary,不讀 secret、不執行 shell/SQL、不寫 DB,也不簽發 database apply authorization。 |
|
||||
| 2026-06-29 | PChome DB apply 授權簽署發行者 lane 必須先產出 final signable request package | V10.725 的 PChome mapping backlog auto-policy 新增 `/api/ai/pchome-growth/mapping-backlog/auto-policy-db-apply-authorization-signing-issuer-closeout`;此 endpoint 只把 signing-issuer guard 的 signable request boundary 收斂成 final signable request package 與 closeout contract,確認 fresh production truth、post-apply verifier、migration hash、secret boundary 與 no-side-effect checks,不讀 secret、不簽發 authorization、不執行 shell/SQL、不寫 DB,也不代表正式 DB apply 已授權。 |
|
||||
| 2026-06-29 | PChome DB apply 授權簽署執行 lane 必須先通過 operator-held secret boundary preflight | V10.725 的 PChome mapping backlog auto-policy 新增 `/api/ai/pchome-growth/mapping-backlog/auto-policy-db-apply-authorization-signing-execution-preflight`;此 endpoint 只把 final signable request package 轉成 future signing execution preflight package、operator-held secret boundary contract、nonsecret signing inputs、command-shape preview、rollback boundary 與 abort conditions,不讀 secret、不接受 plaintext secret、不簽發 authorization、不執行 shell/SQL、不寫 DB,也不代表正式 DB apply 已授權。 |
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
| Completed | Multi-commerce PixelRAG visual evidence lane for momo, pchome, shopee_tw, coupang_tw, yahoo_shopping_tw, etmall_tw, friday_tw, rakuten_tw | API and CLI can emit expansion plans and marketplace manifests; PChome parser failures can queue manifests. |
|
||||
| Completed | External MCP/RAG capability inventory absorbed into internal governance readback | `/api/ai-automation/external-mcp-rag-integration` and `scripts/ops/report_external_mcp_rag_integration.py` expose 9 capabilities, absorbed/unresolved counts, and runtime flags. |
|
||||
| Completed | PixelRAG receipts to internal RAG candidate replay | `/api/ai-automation/pixelrag-rag-candidate-replay` and `scripts/ops/report_pixelrag_rag_candidate_replay.py` read receipts, split eligible vs blocked, and require OCR/VLM replay plus PromotionGate before knowledge writes. |
|
||||
| Completed | PixelRAG application portfolio and integration lanes | `/api/ai-automation/pixelrag-application-portfolio` and `scripts/ops/report_pixelrag_application_portfolio.py` expose commerce, RAG, UX, ops, marketing, and governance uses with priority, status, next machine action, and forbidden guardrails. |
|
||||
| In progress | MCP/RAG runtime health in AI automation smoke | `/api/ai-automation/smoke` and `/api/ai-automation/scheduled-health-summary` include external MCP/RAG integration, PixelRAG RAG candidate replay, and PixelRAG OCR/VLM replay contract families. |
|
||||
| In progress | Formal production deploy/readback discipline | Every mainline change must update version, push Gitea main/dev, deploy to 188 without touching `momo-db`, and read back `/health` plus new endpoints. |
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
或 `python scripts/ops/report_pixelrag_rag_candidate_replay.py` 可讀回 eligible / blocked / invalid receipts,且 blocked page 不得被視為商品資料。
|
||||
- PixelRAG 視覺 receipt 進入 OCR/VLM 自動化前,必須確認 `/api/ai-automation/pixelrag-ocr-vlm-replay`
|
||||
或 `python scripts/ops/report_pixelrag_ocr_vlm_replay.py` 可讀回 ready / blocked / invalid replay contracts、field schema、validation rules 與 Ollama-first 下一步,且目前不執行 OCR/VLM、不寫正式價格。
|
||||
- PixelRAG 可整合/可運用場景盤點必須確認 `/api/ai-automation/pixelrag-application-portfolio`
|
||||
或 `python scripts/ops/report_pixelrag_application_portfolio.py` 可讀回 area、priority、status、use cases、next machine action 與 forbidden guardrails;不得只存在聊天結論。
|
||||
- AI automation smoke 必須包含 external MCP/RAG integration、PixelRAG RAG candidate replay 與 PixelRAG OCR/VLM replay contract family,避免 registry 已完成但 runtime flag / receipt replay / VLM contract 未完成時被誤報為全自動閉環。
|
||||
- AI 自動化 Prometheus 指標變更必須同步檢查 `docker/grafana/provisioning/dashboards/json/ai-automation-overview.json` 是否需要新增 panel 或查詢。
|
||||
- 188 線上 active monitoring stack 以 `monitoring/prometheus.yml` 為準;110 gateway 另有 `/home/wooo/monitoring/prometheus.yml`。若 dashboard 無資料,先確認 Prometheus `momo-app` target 與 `momo-network` 連線;所有 Blackbox HTTP target 必須打 `/health`,不可打 Dashboard 首頁 `/`。
|
||||
|
||||
@@ -101,6 +101,8 @@ rakuten_tw
|
||||
python scripts/ops/report_pixelrag_crawler_integration.py
|
||||
python scripts/ops/report_pixelrag_crawler_integration.py --platform momo
|
||||
python scripts/ops/report_pixelrag_crawler_integration.py --ecommerce-expansion-plan
|
||||
python scripts/ops/report_pixelrag_application_portfolio.py
|
||||
python scripts/ops/report_pixelrag_application_portfolio.py --area commerce
|
||||
python scripts/ops/report_pixelrag_crawler_integration.py --platform shopee_tw --marketplace-keyword "防曬乳"
|
||||
python scripts/ops/report_pixelrag_crawler_integration.py --platform coupang_tw --marketplace-keyword "iphone"
|
||||
python scripts/ops/report_pixelrag_crawler_integration.py --capability ollama_multimodal_ready --capability pgvector_visual_ready
|
||||
@@ -118,6 +120,8 @@ python scripts/ops/report_pixelrag_crawler_integration.py \
|
||||
```text
|
||||
/api/ai-automation/pixelrag-crawler-integration?platform=momo
|
||||
/api/ai-automation/pixelrag-crawler-integration?expansion_plan=true
|
||||
/api/ai-automation/pixelrag-application-portfolio
|
||||
/api/ai-automation/pixelrag-application-portfolio?area=commerce
|
||||
/api/ai-automation/pixelrag-crawler-integration?platform=shopee_tw&marketplace_keyword=%E9%98%B2%E6%9B%AC%E4%B9%B3
|
||||
/api/ai-automation/pixelrag-crawler-integration?platform=coupang_tw&marketplace_keyword=iphone
|
||||
/api/ai-automation/pixelrag-crawler-integration?platform=pchome&manifest_url=https://24h.pchome.com.tw/prod/TEST-000000001&crawler=PChomeCrawler.search_products&trigger_reason=parser_empty
|
||||
@@ -180,6 +184,16 @@ python scripts/ops/report_pixelrag_ocr_vlm_replay.py --platform shopee_tw --plat
|
||||
|
||||
此 contract 只把 saved tiles、欄位 schema、輸出 schema、confidence/evidence 規則與 Ollama-first worker 下一步打包;目前不執行 OCR/VLM、不呼叫模型、不寫 RAG、不寫 `ai_insights`、不寫正式價格表。ready receipt 進 `run_ollama_first_vlm_replay_worker`,blocked / 403 / captcha / access denied receipt 進 platform probe 或 structured API 策略。
|
||||
|
||||
Application portfolio:
|
||||
|
||||
```bash
|
||||
python scripts/ops/report_pixelrag_application_portfolio.py
|
||||
python scripts/ops/report_pixelrag_application_portfolio.py --area commerce
|
||||
python scripts/ops/report_pixelrag_application_portfolio.py --area rag --include-forbidden
|
||||
```
|
||||
|
||||
此 portfolio 把 PixelRAG 可整合範圍正式分成 commerce、RAG、UX、ops、marketing、governance lanes。每個 lane 都必須有 priority、status、可整合對象、use cases、next machine action 與 no-write 邊界;forbidden lane 明確拒絕 login-only、cart、checkout、private coupon、session 與 anti-bot bypass。
|
||||
|
||||
安全邊界:
|
||||
|
||||
- read-only;不登入、不下單、不加入購物車、不寫第三方狀態。
|
||||
|
||||
@@ -733,6 +733,26 @@ def ai_automation_pixelrag_ocr_vlm_replay_api():
|
||||
))
|
||||
|
||||
|
||||
@system_public_bp.route('/api/ai-automation/pixelrag-application-portfolio')
|
||||
@login_required
|
||||
def ai_automation_pixelrag_application_portfolio_api():
|
||||
"""Read-only PixelRAG application and integration portfolio."""
|
||||
from services.pixelrag_application_portfolio_service import (
|
||||
build_pixelrag_application_portfolio,
|
||||
)
|
||||
|
||||
include_forbidden = str(request.args.get('include_forbidden') or '').lower() in {
|
||||
'1',
|
||||
'true',
|
||||
'yes',
|
||||
}
|
||||
return jsonify(build_pixelrag_application_portfolio(
|
||||
area=str(request.args.get('area') or '').strip() or None,
|
||||
priority=str(request.args.get('priority') or '').strip() or None,
|
||||
include_forbidden=include_forbidden,
|
||||
))
|
||||
|
||||
|
||||
@system_public_bp.route('/api/ai-automation/external-mcp-rag-integration')
|
||||
@login_required
|
||||
def ai_automation_external_mcp_rag_integration_api():
|
||||
|
||||
50
scripts/ops/report_pixelrag_application_portfolio.py
Executable file
50
scripts/ops/report_pixelrag_application_portfolio.py
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Report the PixelRAG application portfolio as machine-readable JSON."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
if str(ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from services.pixelrag_application_portfolio_service import ( # noqa: E402
|
||||
build_pixelrag_application_portfolio,
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="輸出 PixelRAG 還可整合/運用場景的機器可讀 portfolio。"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--area",
|
||||
help="限制 area,例如 commerce / rag / ux / ops / marketing / governance。",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--priority",
|
||||
help="限制 priority,例如 P0 / P1 / P2 / P3。",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--include-forbidden",
|
||||
action="store_true",
|
||||
help="包含 forbidden guardrail lane。",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
payload = build_pixelrag_application_portfolio(
|
||||
area=args.area,
|
||||
priority=args.priority,
|
||||
include_forbidden=args.include_forbidden,
|
||||
)
|
||||
print(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True))
|
||||
return 0 if payload.get("success") else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
446
services/pixelrag_application_portfolio_service.py
Normal file
446
services/pixelrag_application_portfolio_service.py
Normal file
@@ -0,0 +1,446 @@
|
||||
"""Read-only PixelRAG application portfolio and integration inventory.
|
||||
|
||||
This module converts the product strategy for PixelRAG into machine-readable
|
||||
lanes. It is intentionally no-write: it does not crawl, call models, read
|
||||
secrets, or promote visual evidence into price truth.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import Counter
|
||||
from copy import deepcopy
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Mapping
|
||||
|
||||
|
||||
POLICY = "read_only_pixelrag_application_portfolio_v1"
|
||||
|
||||
SOURCE_BASIS = [
|
||||
{
|
||||
"id": "pixelrag_visual_rag_pattern",
|
||||
"basis": "render_public_pages_as_screenshot_tiles_for_visual_retrieval_and_vlm_reading",
|
||||
"url": "https://medium.com/open-intelligence/pixelrag-proves-that-the-biggest-bottleneck-in-web-rag-was-the-text-parser-all-along-d6ce53c78b02",
|
||||
},
|
||||
{
|
||||
"id": "google_merchant_product_data",
|
||||
"basis": "normalize_offer_evidence_around_product_title_price_availability_image_link_and_related_attributes",
|
||||
"url": "https://support.google.com/merchants/answer/7052112",
|
||||
},
|
||||
{
|
||||
"id": "google_product_structured_data",
|
||||
"basis": "use_product_price_availability_reviews_shipping_and_visual_rich-result_fields_as_validation_targets",
|
||||
"url": "https://developers.google.com/search/docs/appearance/structured-data/product",
|
||||
},
|
||||
{
|
||||
"id": "baymard_product_list_ux",
|
||||
"basis": "product_list_cards_need_scannable_visuals_and_key_attributes_for_comparison",
|
||||
"url": "https://baymard.com/research/ecommerce-product-lists",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
LANES: list[dict[str, Any]] = [
|
||||
{
|
||||
"id": "commerce.marketplace_visual_offer_cards",
|
||||
"priority": "P0",
|
||||
"status": "production_contract_ready",
|
||||
"area": "commerce",
|
||||
"title": "Multi-commerce public offer card visual evidence",
|
||||
"integrates_with": [
|
||||
"momo",
|
||||
"pchome",
|
||||
"shopee_tw",
|
||||
"coupang_tw",
|
||||
"yahoo_shopping_tw",
|
||||
"etmall_tw",
|
||||
"friday_tw",
|
||||
"rakuten_tw",
|
||||
],
|
||||
"use_cases": [
|
||||
"Rendered product cards",
|
||||
"Promotion badges",
|
||||
"Seller and delivery badges",
|
||||
"Rating and sold-count signals",
|
||||
"Parser-empty or parser-low-confidence fallback",
|
||||
],
|
||||
"current_capability": [
|
||||
"visual_manifest_generation",
|
||||
"visual_capture_receipts",
|
||||
"rag_candidate_replay",
|
||||
"ocr_vlm_replay_contract",
|
||||
],
|
||||
"next_machine_action": "run_ollama_first_vlm_replay_worker",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": True,
|
||||
},
|
||||
{
|
||||
"id": "commerce.product_feed_and_structured_data_gap_check",
|
||||
"priority": "P0",
|
||||
"status": "source_contract_design_ready",
|
||||
"area": "commerce",
|
||||
"title": "Product feed / structured data gap detection",
|
||||
"integrates_with": [
|
||||
"Google Merchant product data",
|
||||
"Google Product structured data",
|
||||
"brand sites",
|
||||
"Shopify storefronts",
|
||||
"marketplace offer pages",
|
||||
],
|
||||
"use_cases": [
|
||||
"Compare visible product card fields against feed/structured-data fields",
|
||||
"Detect missing image, price, availability, review, shipping, or product URL evidence",
|
||||
"Build source contracts before platform data enters growth opportunities",
|
||||
],
|
||||
"current_capability": [
|
||||
"source_readiness_contract",
|
||||
"external_offer_evidence_contract",
|
||||
"pixelrag_field_contract",
|
||||
],
|
||||
"next_machine_action": "build_pixelrag_source_contract_gap_readback",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": True,
|
||||
},
|
||||
{
|
||||
"id": "commerce.promotion_coupon_delivery_badge_extraction",
|
||||
"priority": "P1",
|
||||
"status": "contract_ready_worker_not_started",
|
||||
"area": "commerce",
|
||||
"title": "Promotion, coupon, discount, and delivery badge extraction",
|
||||
"integrates_with": [
|
||||
"Shopee promotion chips",
|
||||
"Coupang delivery badges",
|
||||
"MOMO campaign blocks",
|
||||
"PChome campaign badges",
|
||||
"Yahoo/ETMall coupon panels",
|
||||
],
|
||||
"use_cases": [
|
||||
"Detect visible discounts that structured parsers miss",
|
||||
"Separate base price from coupon/member/delivery incentives",
|
||||
"Feed promotion evidence into no-write candidate receipts",
|
||||
],
|
||||
"current_capability": ["ocr_vlm_replay_contract"],
|
||||
"next_machine_action": "run_ollama_first_vlm_replay_worker_then_promotion_gate",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": True,
|
||||
},
|
||||
{
|
||||
"id": "commerce.product_identity_visual_matching",
|
||||
"priority": "P1",
|
||||
"status": "requires_worker_and_identity_replay",
|
||||
"area": "commerce",
|
||||
"title": "Product identity visual matching",
|
||||
"integrates_with": [
|
||||
"product images",
|
||||
"package size/spec text",
|
||||
"brand/logo regions",
|
||||
"variant cards",
|
||||
"unit price evidence",
|
||||
],
|
||||
"use_cases": [
|
||||
"Reduce false same-product matches",
|
||||
"Use package/spec visual evidence before accepting competitor offer candidates",
|
||||
"Keep unit basis evidence attached to each candidate",
|
||||
],
|
||||
"current_capability": ["field_contract", "identity_matcher_required_boundary"],
|
||||
"next_machine_action": "build_visual_identity_matcher_replay_contract",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": True,
|
||||
},
|
||||
{
|
||||
"id": "commerce.availability_delivery_stock_signal",
|
||||
"priority": "P1",
|
||||
"status": "source_contract_design_ready",
|
||||
"area": "commerce",
|
||||
"title": "Availability, stock, delivery, and shipping signal evidence",
|
||||
"integrates_with": [
|
||||
"PChome stock hints",
|
||||
"MOMO availability text",
|
||||
"Coupang rocket delivery badge",
|
||||
"Shopee shipping badge",
|
||||
"merchant listing structured data",
|
||||
],
|
||||
"use_cases": [
|
||||
"Avoid recommending unavailable or slow-delivery products for promotion",
|
||||
"Detect delivery advantage as a sales-action signal",
|
||||
"Flag missing availability in source contracts",
|
||||
],
|
||||
"current_capability": ["ocr_vlm_replay_contract", "source_readiness_contract"],
|
||||
"next_machine_action": "build_availability_delivery_evidence_replay",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": True,
|
||||
},
|
||||
{
|
||||
"id": "commerce.platform_barrier_classifier",
|
||||
"priority": "P0",
|
||||
"status": "production_contract_ready",
|
||||
"area": "governance",
|
||||
"title": "Blocked page / captcha / login barrier classifier",
|
||||
"integrates_with": [
|
||||
"PixelRAG capture receipts",
|
||||
"Shopee/Coupang probes",
|
||||
"structured API fallback strategy",
|
||||
"source contract status",
|
||||
],
|
||||
"use_cases": [
|
||||
"Prevent AI from treating 403/captcha/login pages as product data",
|
||||
"Route blocked pages to platform probe or structured API strategy",
|
||||
"Keep anti-bot boundaries explicit",
|
||||
],
|
||||
"current_capability": ["visual_barrier_reason", "blocked_pages_are_not_product_data"],
|
||||
"next_machine_action": "build_platform_probe_or_structured_api_strategy",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": True,
|
||||
},
|
||||
{
|
||||
"id": "rag.visual_evidence_to_internal_knowledge",
|
||||
"priority": "P1",
|
||||
"status": "contract_ready_worker_not_started",
|
||||
"area": "rag",
|
||||
"title": "Visual evidence to internal RAG learning candidates",
|
||||
"integrates_with": [
|
||||
"rag_service",
|
||||
"learning_episode_candidate_preview",
|
||||
"PromotionGate",
|
||||
"embedding signature guard",
|
||||
"pgvector metadata lane",
|
||||
],
|
||||
"use_cases": [
|
||||
"Turn accepted visual receipts into replayable learning candidates",
|
||||
"Attach screenshot/tile evidence to every extracted field",
|
||||
"Only promote after OCR/VLM, identity replay, PromotionGate, and signature guard pass",
|
||||
],
|
||||
"current_capability": ["rag_candidate_replay", "ocr_vlm_replay_contract"],
|
||||
"next_machine_action": "run_vlm_extraction_then_rag_candidate_promotion_preflight",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": True,
|
||||
},
|
||||
{
|
||||
"id": "rag.pgvector_visual_metadata",
|
||||
"priority": "P2",
|
||||
"status": "not_started",
|
||||
"area": "rag",
|
||||
"title": "pgvector-compatible visual evidence metadata",
|
||||
"integrates_with": [
|
||||
"pgvector",
|
||||
"BGE-M3 text metadata",
|
||||
"Qwen3-VL or approved local visual model",
|
||||
"visual receipt file refs",
|
||||
],
|
||||
"use_cases": [
|
||||
"Search visual evidence by platform, field, tile, and confidence",
|
||||
"Avoid FAISS in production until ADR approves a separate store",
|
||||
"Keep retrieval metadata in the same governance boundary as text RAG",
|
||||
],
|
||||
"current_capability": ["deferred_until_ollama_first_visual_embedding_benchmark"],
|
||||
"next_machine_action": "run_ollama_first_visual_embedding_benchmark",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": True,
|
||||
},
|
||||
{
|
||||
"id": "ux.product_listing_quality_benchmark",
|
||||
"priority": "P2",
|
||||
"status": "source_contract_design_ready",
|
||||
"area": "ux",
|
||||
"title": "Product listing/card UX quality benchmark",
|
||||
"integrates_with": [
|
||||
"Baymard product list heuristics",
|
||||
"PChome growth dashboard",
|
||||
"AI surface visual QA",
|
||||
"external marketplace screenshots",
|
||||
],
|
||||
"use_cases": [
|
||||
"Benchmark whether our product cards show enough scannable evidence",
|
||||
"Detect text-heavy or missing-attribute cards",
|
||||
"Turn external marketplace patterns into product UX guardrails",
|
||||
],
|
||||
"current_capability": ["sitewide_visual_qa_readback", "pixelrag_visual_receipts"],
|
||||
"next_machine_action": "build_product_card_visual_ux_benchmark_readback",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": False,
|
||||
},
|
||||
{
|
||||
"id": "ops.visual_regression_for_public_pages",
|
||||
"priority": "P2",
|
||||
"status": "partially_integrated",
|
||||
"area": "ops",
|
||||
"title": "Public page visual regression and evidence capture",
|
||||
"integrates_with": [
|
||||
"sitewide visual QA",
|
||||
"AI automation smoke",
|
||||
"product landing pages",
|
||||
"crawler diagnostics pages",
|
||||
],
|
||||
"use_cases": [
|
||||
"Catch layout breaks that HTML tests do not see",
|
||||
"Keep evidence screenshots attached to smoke history",
|
||||
"Detect content overlap and text-heavy regressions",
|
||||
],
|
||||
"current_capability": ["sitewide_visual_qa_readback"],
|
||||
"next_machine_action": "merge_pixelrag_tile_receipts_with_sitewide_visual_qa_artifacts",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": False,
|
||||
},
|
||||
{
|
||||
"id": "marketing.ad_landing_and_creative_evidence",
|
||||
"priority": "P3",
|
||||
"status": "not_started",
|
||||
"area": "marketing",
|
||||
"title": "Ad landing page and creative evidence checks",
|
||||
"integrates_with": [
|
||||
"Google Shopping landing pages",
|
||||
"Meta commerce public landing pages",
|
||||
"public brand campaign pages",
|
||||
"product feed destination URLs",
|
||||
],
|
||||
"use_cases": [
|
||||
"Verify landing page visible price/image availability against feed contract",
|
||||
"Detect promotional creative mismatch before campaign decisions",
|
||||
"Keep evidence read-only and public-page-only",
|
||||
],
|
||||
"current_capability": ["manifest_contract_possible"],
|
||||
"next_machine_action": "build_public_landing_visual_evidence_contract",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": True,
|
||||
},
|
||||
{
|
||||
"id": "forbidden.personalized_or_private_state",
|
||||
"priority": "P0_guardrail",
|
||||
"status": "forbidden",
|
||||
"area": "governance",
|
||||
"title": "Personalized, cart, checkout, account, or anti-bot bypass states",
|
||||
"integrates_with": [],
|
||||
"use_cases": [
|
||||
"Explicitly reject login-only prices, carts, checkout pages, private coupons, sessions, and anti-bot bypass",
|
||||
"Prevent hidden manual or credentialed scraping from entering the automation plan",
|
||||
],
|
||||
"current_capability": ["guardrail_only"],
|
||||
"next_machine_action": "reject_and_route_to_official_api_or_manual_csv_contract",
|
||||
"writes_database": False,
|
||||
"promotion_required_before_price_truth": True,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def _selected_lanes(
|
||||
*,
|
||||
area: str | None = None,
|
||||
priority: str | None = None,
|
||||
include_forbidden: bool = False,
|
||||
) -> list[dict[str, Any]]:
|
||||
area_key = str(area or "").strip().lower()
|
||||
priority_key = str(priority or "").strip().upper()
|
||||
selected: list[dict[str, Any]] = []
|
||||
for lane in LANES:
|
||||
if not include_forbidden and lane["status"] == "forbidden":
|
||||
continue
|
||||
if area_key and lane["area"] != area_key:
|
||||
continue
|
||||
if priority_key and lane["priority"] != priority_key:
|
||||
continue
|
||||
selected.append(deepcopy(lane))
|
||||
return selected
|
||||
|
||||
|
||||
def _counts(lanes: list[Mapping[str, Any]], key: str) -> dict[str, int]:
|
||||
return dict(sorted(Counter(str(item.get(key) or "unknown") for item in lanes).items()))
|
||||
|
||||
|
||||
def _recommended_order(lanes: list[Mapping[str, Any]]) -> list[dict[str, Any]]:
|
||||
order = {"P0": 0, "P0_guardrail": 1, "P1": 2, "P2": 3, "P3": 4}
|
||||
actionable = [
|
||||
item for item in lanes
|
||||
if str(item.get("status")) not in {"forbidden"}
|
||||
]
|
||||
ranked = sorted(
|
||||
actionable,
|
||||
key=lambda item: (
|
||||
order.get(str(item.get("priority")), 99),
|
||||
str(item.get("status")),
|
||||
str(item.get("id")),
|
||||
),
|
||||
)
|
||||
return [
|
||||
{
|
||||
"rank": index + 1,
|
||||
"id": item["id"],
|
||||
"priority": item["priority"],
|
||||
"status": item["status"],
|
||||
"next_machine_action": item["next_machine_action"],
|
||||
}
|
||||
for index, item in enumerate(ranked[:8])
|
||||
]
|
||||
|
||||
|
||||
def build_pixelrag_application_portfolio(
|
||||
*,
|
||||
area: str | None = None,
|
||||
priority: str | None = None,
|
||||
include_forbidden: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
"""Return the product-level PixelRAG integration portfolio."""
|
||||
lanes = _selected_lanes(area=area, priority=priority, include_forbidden=include_forbidden)
|
||||
ready_count = sum(
|
||||
1 for item in lanes
|
||||
if str(item.get("status")) in {"production_contract_ready", "source_contract_design_ready", "partially_integrated"}
|
||||
)
|
||||
blocked_or_forbidden_count = sum(
|
||||
1 for item in lanes
|
||||
if str(item.get("status")) in {"forbidden"}
|
||||
)
|
||||
worker_required_count = sum(
|
||||
1 for item in lanes
|
||||
if "worker" in str(item.get("status")) or "worker" in str(item.get("next_machine_action"))
|
||||
)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"policy": POLICY,
|
||||
"generated_at": datetime.now(timezone.utc).isoformat(),
|
||||
"status": "portfolio_ready",
|
||||
"filters": {
|
||||
"area": str(area or "").strip().lower() or None,
|
||||
"priority": str(priority or "").strip().upper() or None,
|
||||
"include_forbidden": include_forbidden,
|
||||
},
|
||||
"summary": {
|
||||
"lane_count": len(lanes),
|
||||
"ready_or_partially_integrated_count": ready_count,
|
||||
"worker_required_count": worker_required_count,
|
||||
"blocked_or_forbidden_count": blocked_or_forbidden_count,
|
||||
"area_counts": _counts(lanes, "area"),
|
||||
"priority_counts": _counts(lanes, "priority"),
|
||||
"status_counts": _counts(lanes, "status"),
|
||||
},
|
||||
"source_basis": SOURCE_BASIS,
|
||||
"lanes": lanes,
|
||||
"recommended_order": _recommended_order(lanes),
|
||||
"answer_to_owner": (
|
||||
"PixelRAG should become the visual evidence layer for public product cards, "
|
||||
"feed/structured-data gap detection, promotion/delivery badge extraction, "
|
||||
"identity matching evidence, internal RAG candidate promotion, and product UX "
|
||||
"benchmarking. It must stay no-write until OCR/VLM replay, identity replay, "
|
||||
"PromotionGate, and source contracts pass."
|
||||
),
|
||||
"not_recommended": [
|
||||
"Do not use PixelRAG for login-only prices, cart/checkout state, private coupons, sessions, or anti-bot bypass.",
|
||||
"Do not write competitor_prices, competitor_price_history, ai_insights, or RAG truth directly from pixels.",
|
||||
"Do not use hosted VLM/embedding APIs as the default path; use Ollama-first verification.",
|
||||
"Do not put FAISS into production visual retrieval without a separate ADR; prefer pgvector-compatible metadata first.",
|
||||
],
|
||||
"controlled_apply": {
|
||||
"network_call": False,
|
||||
"db_write": False,
|
||||
"secret_read": False,
|
||||
"production_price_write": False,
|
||||
"artifact_write": False,
|
||||
"primary_human_gate_count": 0,
|
||||
},
|
||||
"next_machine_action": (
|
||||
"run_ollama_first_vlm_replay_worker"
|
||||
if worker_required_count
|
||||
else "keep_pixelrag_application_portfolio_monitoring"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
__all__ = ["POLICY", "build_pixelrag_application_portfolio"]
|
||||
86
tests/test_pixelrag_application_portfolio_service.py
Normal file
86
tests/test_pixelrag_application_portfolio_service.py
Normal file
@@ -0,0 +1,86 @@
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def test_pixelrag_application_portfolio_prioritizes_commerce_and_guardrails():
|
||||
from services.pixelrag_application_portfolio_service import (
|
||||
POLICY,
|
||||
build_pixelrag_application_portfolio,
|
||||
)
|
||||
|
||||
payload = build_pixelrag_application_portfolio(include_forbidden=True)
|
||||
lanes = {item["id"]: item for item in payload["lanes"]}
|
||||
|
||||
assert payload["policy"] == POLICY
|
||||
assert payload["status"] == "portfolio_ready"
|
||||
assert payload["summary"]["lane_count"] >= 10
|
||||
assert payload["summary"]["worker_required_count"] >= 1
|
||||
assert "commerce.marketplace_visual_offer_cards" in lanes
|
||||
assert lanes["commerce.marketplace_visual_offer_cards"]["priority"] == "P0"
|
||||
assert lanes["commerce.marketplace_visual_offer_cards"]["next_machine_action"] == (
|
||||
"run_ollama_first_vlm_replay_worker"
|
||||
)
|
||||
assert "Google Merchant product data" in lanes[
|
||||
"commerce.product_feed_and_structured_data_gap_check"
|
||||
]["integrates_with"]
|
||||
assert lanes["commerce.platform_barrier_classifier"]["status"] == (
|
||||
"production_contract_ready"
|
||||
)
|
||||
assert lanes["forbidden.personalized_or_private_state"]["status"] == "forbidden"
|
||||
assert payload["controlled_apply"]["db_write"] is False
|
||||
assert payload["controlled_apply"]["primary_human_gate_count"] == 0
|
||||
assert any(item["id"] == "pixelrag_visual_rag_pattern" for item in payload["source_basis"])
|
||||
assert payload["recommended_order"][0]["priority"] == "P0"
|
||||
|
||||
|
||||
def test_pixelrag_application_portfolio_filters_area_without_forbidden_by_default():
|
||||
from services.pixelrag_application_portfolio_service import build_pixelrag_application_portfolio
|
||||
|
||||
payload = build_pixelrag_application_portfolio(area="governance")
|
||||
|
||||
assert {item["area"] for item in payload["lanes"]} == {"governance"}
|
||||
assert all(item["status"] != "forbidden" for item in payload["lanes"])
|
||||
assert payload["summary"]["lane_count"] == 1
|
||||
assert payload["lanes"][0]["id"] == "commerce.platform_barrier_classifier"
|
||||
|
||||
|
||||
def test_pixelrag_application_portfolio_cli_outputs_machine_readable_json():
|
||||
completed = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
"scripts/ops/report_pixelrag_application_portfolio.py",
|
||||
"--area",
|
||||
"commerce",
|
||||
"--priority",
|
||||
"P1",
|
||||
],
|
||||
capture_output=True,
|
||||
check=False,
|
||||
text=True,
|
||||
)
|
||||
|
||||
assert completed.returncode == 0
|
||||
payload = json.loads(completed.stdout)
|
||||
assert payload["success"] is True
|
||||
assert payload["filters"]["area"] == "commerce"
|
||||
assert payload["filters"]["priority"] == "P1"
|
||||
assert {item["priority"] for item in payload["lanes"]} == {"P1"}
|
||||
assert payload["controlled_apply"]["network_call"] is False
|
||||
|
||||
|
||||
def test_pixelrag_application_portfolio_route_returns_readback():
|
||||
from flask import Flask
|
||||
from routes import system_public_routes as routes
|
||||
|
||||
app = Flask(__name__)
|
||||
with app.test_request_context(
|
||||
"/api/ai-automation/pixelrag-application-portfolio?area=rag"
|
||||
):
|
||||
response = routes.ai_automation_pixelrag_application_portfolio_api.__wrapped__()
|
||||
payload = response.get_json()
|
||||
|
||||
assert payload["policy"] == "read_only_pixelrag_application_portfolio_v1"
|
||||
assert payload["filters"]["area"] == "rag"
|
||||
assert {item["area"] for item in payload["lanes"]} == {"rag"}
|
||||
assert payload["next_machine_action"] == "run_ollama_first_vlm_replay_worker"
|
||||
Reference in New Issue
Block a user