Your Name
|
35fe37c82a
|
fix(api): route direct ollama callers through ordered fallback
Code Review / ai-code-review (push) Successful in 23s
CD Pipeline / tests (push) Successful in 5m51s
CD Pipeline / build-and-deploy (push) Successful in 3m29s
CD Pipeline / post-deploy-checks (push) Successful in 1m14s
|
2026-05-19 12:56:13 +08:00 |
|
Your Name
|
5b34877429
|
feat(awooop): expose drift repeat fingerprint
Code Review / ai-code-review (push) Successful in 11s
CD Pipeline / tests (push) Successful in 1m17s
CD Pipeline / build-and-deploy (push) Successful in 3m20s
CD Pipeline / post-deploy-checks (push) Successful in 1m13s
|
2026-05-13 07:36:21 +08:00 |
|
Your Name
|
c4854bb355
|
fix(ai): isolate heavy Ollama workloads from GCP alert lane
CD Pipeline / tests (push) Successful in 54s
Code Review / ai-code-review (push) Successful in 10s
CD Pipeline / build-and-deploy (push) Successful in 3m19s
CD Pipeline / post-deploy-checks (push) Successful in 3m12s
|
2026-05-05 23:06:07 +08:00 |
|
Your Name
|
b1ef05fa8c
|
feat(ollama): ADR-110 GCP 三層容災架構(GCP-A → GCP-B → Local → Gemini)
Code Review / ai-code-review (push) Successful in 50s
CD Pipeline / tests (push) Failing after 1m14s
CD Pipeline / build-and-deploy (push) Has been skipped
CD Pipeline / post-deploy-checks (push) Has been skipped
## 變更摘要
- Primary: http://34.143.170.20:11434 (GCP-A SSD, 9x 載速 + 2x 推理)
- Secondary: http://34.21.145.224:11434 (GCP-B SSD)
- Fallback: http://192.168.0.111:11434 (M1 Pro Local HDD,最後防線)
- 廢止 ADR-105「111 唯一鐵律」,新建 ADR-110
## 核心改動
- config.py: 新增 OLLAMA_SECONDARY_URL;validator 加 GCP IP 白名單(34.143.170.20, 34.21.145.224)
- ollama_failover_manager.py: 三層 Ollama 決策矩陣;並行健康檢查三台;health_111 → health_gcp_a
- ollama_health_monitor.py: host label 萃取改為通用版(支援 GCP 公網 IP)
- failover_alerter.py: 故障/恢復主機動態顯示,不再硬編碼「Ollama 111 (GPU)」
- ollama_auto_recovery.py: notify_recovery 改為 ollama_gcp_a;recovered_host 動態
- k8s/awoooi-prod: configmap + deployment + network-policy 同步更新(egress 加 GCP /32)
- 服務層: 10 個服務檔案硬編碼 192.168.0.111 改為讀 settings.OLLAMA_URL
- 測試: URL 常數更新,新增三層容災場景,GCP IP 白名單驗證測試
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-03 22:49:23 +08:00 |
|
Your Name
|
54d60d04f5
|
feat(drift+target): P0.1+P0.2+P0.3 三修 — drift 分頁分類 + AI 推薦 + target 追 trace
統帥三問決議:全做;AI 推薦 0.85 門檻純顯示不自動;先查 aol 再修
## RCA: awoooi-service 失敗來源
- /api/v1/aiops/kpi 顯示過去 24h 有 1 筆 playbook_executed actor=approval_execution status=failed
- grep codebase: 無任何程式碼寫死 awoooi-service(只有歷史 comment)
- 最可能源: alert_rule_engine._extract_vars 從 labels.service 取值當 Deployment 名
- cf5050c/4f2e122(2026-04-18)已修 NEMOTRON 幻覺雙路徑;本次修第三條路徑
## 修復
### P0.3a alert_rule_engine._extract_vars
- labels.service 降級:-service 結尾先剝 suffix 視為 base name
- match_rule 回傳新增 target_source 欄位追 trace
- 下次 awoooi-service 復發可直接看來源(label.service(stripped) 等)
### P0.3c approval_execution._log_aol_started.input
- 補 parsed_target/operation/namespace 欄位
- 未來 aol 查 failed 可直接看 target,無需推敲
### P0.1 telegram_gateway._send_drift_diff_detail
- 分頁(10 項/頁)取代一次洗版 30 項
- header 3 桶分類計數: 人工高風險 / 一般修改 / K8s 自動
- 底部 ⬅️/➡️ 分頁按鈕(callback: drift_view_page:{report_id}_{page})
- security_interceptor INFO_ACTIONS 加 drift_view_page 白名單
### P0.2 drift_narrator recommendation
- LLM prompt 加 recommendation 欄位(action/confidence/reason)
- action ∈ {adopt, revert, ignore, investigate}
- 卡片頂部顯示「🎯 AI 建議:⏪ 回滾 (85%) — reason」
- LLM 失敗走 _fallback_recommendation(規則式依 intent 對應)
- 卡片 diff_summary 上限 500 → 1500 字容納推薦 + narrative + items
- 統帥指令:純顯示不自動執行(門檻 0.85 保留未來)
## 驗證
- 90 個 pytest test 全過(drift + rule_engine + approval_execution)
- 5 檔 AST syntax check 過
## 下次驗收
1. 下次 drift 觸發 → 卡片頂部有「🎯 AI 建議」
2. drift_view 按下 → 3 桶分類 header + ⬅️/➡️
3. awoooi-service 若復發 → automation_operation_log.input.parsed_target 直接查
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-04-20 04:04:13 +08:00 |
|
OG T
|
b0d560dbb3
|
fix(drift-narrator): shortener 用 replace — 包容 LLM 加 'Resource/Name:' 前綴幻覺
CD Pipeline / build-and-deploy (push) Successful in 10m50s
2026-04-18 下午(台北時區)— ogt + Claude Opus 4.7
Round 4 LLM 自己在 field 前加資源識別符:
'Deployment/awoooi-web: spec.template.spec.containers'
導致 startswith 模式 shortener 失效(前綴不在開頭)。
防禦式修法: startswith 不中 → 改用 replace 清除任何位置的前綴。
結果:
'Deployment/awoooi-web: containers' ✅
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-04-18 18:12:15 +08:00 |
|
OG T
|
b63aed72df
|
fix(drift-narrator): 砍 spec.template.spec. 前綴 — 修 Telegram 自動換行醜陋排版
CD Pipeline / build-and-deploy (push) Successful in 12m1s
2026-04-18 下午(台北時區)— ogt + Claude Opus 4.7
統帥實彈三輪視覺回報: 字段名 'spec.template.spec.volumes' 共 24 字元,
加上 emoji+': '+summary 超過 Telegram <pre> 視覺寬度,自動換行
造成 emoji 與 field name 斷開、單獨成行的醜狀。
修復: _shorten_field_path() 砍 3 種常見前綴:
- 'spec.template.spec.' → ''
- 'spec.template.' → '' (後備)
- 'spec.' → '' (後備)
效果對比:
前: '🟡 spec.template.spec.affinity.podAntiAffinity.preferredDuringS: [清單 3 項]'
後: '🟡 affinity.podAntiAffinity.preferredDuringS: [清單 3 項]'
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-04-18 17:10:20 +08:00 |
|
OG T
|
f3960f36d2
|
fix(drift-narrator): fallback 強化 — 標註 K8s 預設值補齊 + 可操作數獨立計算
CD Pipeline / build-and-deploy (push) Successful in 10m37s
2026-04-18 下午(台北時區)—— ogt + Claude Opus 4.7 (1M)
統帥實彈測試回報: 卡片顯示「securityContext: (未設) → {物件 0 欄位}」毫無意義。
根因: _fallback_items 對「K8s controller 自動補齊空物件」的噪音
誤當成真實變更輸出。且「還有 29 項」數字包含白名單 + trivial。
修復 3 項:
1. _is_trivial_drift() 新判定函數
None/空字串/{}/[]/false/0 等互相視為「無實質變更」
捕捉 K8s controller 自動補齊場景
2. _summarize_item() 替代原本 smart_shorten
- trivial → "K8s 預設值補齊 (無實質變更)"
- None → value → "新增 xxx"
- value → None → "已刪除 (原: xxx)"
- 其他 → "from → to"
3. _fallback_items() 改進
- 按 level 排序 (HIGH 優先)
- 白名單 + HPA allowlist 先過濾
4. _count_nontrivial_drift() + Telegram 呈現
- 新增「可操作」計數 (去掉白名單 + trivial)
- 「還有 N 項」用可操作數,不會誤導
- items 為空時顯示「全為白名單或預設值補齊」
預期效果:
之前: "... 還有 29 項" (其實只 1 個是真實 drift)
現在: "... 還有 0 項" 或 "(全部為白名單或預設值補齊)"
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-04-18 16:29:49 +08:00 |
|
OG T
|
1606093dd2
|
fix(drift-narrator): 兩個 hotfix — NEMOTRON wrapper 解析 + tags asyncpg 型別
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-04-18 下午(台北時區)—— ogt + Claude Opus 4.7 (1M)
Live-fire test (report_id=80a34b58) 暴露兩個 bug:
## Bug 1: LLM JSON 被 NEMOTRON wrapper 吞掉
根因: openclaw.call() 經 NEMOTRON 路由時強制回 {description,...} 結構,
我的 prompt 要 {narrative, items} 無法穿透。
(同 1ff3405 早前碰過的 JSON 裸奔問題根源)
修復: 三路 fallback 解析
- Path 1: 直接我們的 {narrative, items}(Ollama 或 LLM 守規矩)
- Path 2: NEMOTRON wrapper,description 巢狀 JSON 含我們結構
- Path 3: description 是純敘述 → 當 narrative + Python fallback_items
## Bug 2: tags 參數 asyncpg DataError
根因: 傳 '{drift,type4d,llm_summary}' 字面量字串,asyncpg 要求 Python list
'(a sized iterable container expected (got type str))'
修復: tags 改傳 ['drift','type4d','llm_summary'] Python list,移除 CAST AS text[]
asyncpg 自動推斷 text[]
Live-fire 結果驗證:
- narrative ✅ 生成(fallback path)
- items ⚠️ 只 1 筆(NEMOTRON 未吐我們結構)
- DB write ❌ tags 型別錯
- Telegram ✅ 送出(雖 fallback 內容但視覺 OK)
本 commit 後預期:
- LLM 回應走 Path 2/3 → narrative + Python fallback items(5 筆 smart summary)
- DB write 成功 → automation_operation_log + ai_collaboration_trace 皆有記錄
- 若 LLM 未來學會走 Path 1(給我們 {narrative, items}),自動升級
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-04-18 16:26:17 +08:00 |
|
OG T
|
a156566b17
|
feat(drift-narrator): ADR-090-C L4 稽核閉環 — notification_formatted op 入庫
CD Pipeline / build-and-deploy (push) Successful in 10m47s
run-migration / migrate (push) Failing after 14s
2026-04-18 下午(台北時區)—— ogt + Claude Opus 4.7 (1M)
架構鐵律執行:
「沒有被記錄的 AI 決策,就等於沒有發生過。」
drift_narrator 每次呼叫 LLM 生成摘要,必須完整寫入
automation_operation_log + ai_collaboration_trace,形成 L4 稽核 + RLHF 語料。
本 commit 兩件事:
1. apps/api/migrations/adr090c_notification_formatted_op_type.sql
- 擴充 automation_operation_log.operation_type CHECK 加 'notification_formatted'
- DROP + ADD CONSTRAINT idempotent 模式
- 已用 awoooi(表 owner)apply 進 prod 驗證通過
2. apps/api/src/services/drift_narrator_service.py
- 新增 _log_ai_action_to_db() 負責 DB 稽核寫入
- 在 _generate_narrative_and_items() 結尾(success / fallback 都寫)呼叫
- automation_operation_log:
* operation_type='notification_formatted'
* actor='drift_narrator'
* input = {report_id, namespace, counts, items_scanned}
* output = {narrative, items, items_count}
* duration_ms, tags=['drift','type4d','llm_summary']
* parent_op_id 查詢 alert_fired 鏈路(未來 drift → alert 關聯)
- ai_collaboration_trace:
* agent='drift_narrator', model=provider (ollama / nemotron / 等)
* prompt(限 8000 字)+ response(JSONB)
* accepted = LLM JSON 解析成功 flag(未來 RLHF 訓料金礦)
- 錯誤處理: DB 寫入 try/except 包住,永不破壞 Telegram 通知主流程
P2.4 事件關聯:
- SELECT parent op via input->>'report_id' 或 'drift_report_id'
- 若找到則綁定 parent_op_id(形成 alert_fired → notification_formatted 追溯鏈)
- 目前 drift 本身不經 alert_fired,parent 為 NULL(等未來鏈路接通)
P2.5 RLHF 語料:
- ai_collaboration_trace.accepted=true 的紀錄即為「LLM 解析成功」樣本
- 未來統帥按 Telegram [✅ 採納變更] / [⏪ 回滾] 時,對應 trace 也可更新
outcome flag,形成完整 Human-in-the-loop 語料
技術細節:
- get_db_context() auto-commit(src/db/base.py:128),無需手動 commit
- prompt 最長 8000 字(一般 drift 約 2-3k)
- raw_response 保留前 500 字在 trace.response JSON 中
相關:
- feedback_ai_autonomous_direction.md L4 北極星
- feedback_secrets_leak_incidents_2026-04-18.md L1-L4 分層
- ADR-090 11 張神經網路表
- commit fb88512(B 方案視覺層)
IDE 可能顯示 src.db.base 找不到 —— 那是誤報(drift_repository.py 用同一條路徑)。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-04-18 16:04:23 +08:00 |
|
OG T
|
fb88512fcb
|
fix(drift-narrator): B 方案 LLM 驅動智能摘要 — 徹底消滅 str()[:30] 暴力截斷
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-04-18 下午(台北時區)—— ogt + Claude Opus 4.7 (1M)
根因:
_format_drift_summary() 對 dict/list 型別的 git_value/actual_value
直接呼叫 str()[:30] 暴力截斷,產生像 "[{'name': 'repair-ssh-key', 's"
這種亂碼掉半個 dict key 的亂七八糟輸出,徹底違背「AI 自主化」原則。
B 方案架構決策:
「捨棄 Python 寫死的字串解析邏輯。將原始 Config Diff 結構直接作為
Context,餵給 Hermes/NemoTron,利用 prompt 規定輸出格式,讓 LLM 自己
消化並輸出包含紅黃燈標示的 Top 5 人類易讀摘要。」
實作:
1. _NARRATIVE_PROMPT 重寫 — 要求 LLM 回傳 {narrative, items[]} JSON
- drift items 以 JSON serialize 餵進 prompt(保留 200 字 context)
- items 限 5 筆,HIGH 優先
- summary 30 字繁中口語(非技術 repr)
2. _generate_narrative_and_items() 新方法 — 解析 LLM JSON 並驗證結構
3. _format_drift_for_llm() 新方法 — 結構化 JSON 給 LLM(取代舊 str 版)
4. _render_telegram_body() 新方法 — 組裝乾淨的 Telegram 卡片
範例輸出:
🤖 AI 研判
<LLM 4-5 行敘述>
📊 漂移明細 (HIGH: 1 | MEDIUM: 29)
🔴 spec.template.spec.volumes: 新增 2 項 repair-ssh-key 掛載
🟡 spec.template.spec.serviceAccount: (未設) → awoooi-executor
... 還有 27 項 (按 🔍 查看 Diff)
5. Fallback 強化 — _smart_shorten() + _fallback_items()
LLM 失敗時用型別感知的 Python 摘要(dict/list 顯示大小,不暴力 repr)
移除:
- _format_drift_summary() — 舊的暴力截斷實作
- _generate_narrative() — 只回 string 的舊介面
保留:
- _fallback_narrative() / _format_intent_summary() — 仍有用
- Redis 快取 / trigger 條件 / DB update — 邏輯不變
MVP 階段:
本 commit 只改視覺呈現,沒動 automation_operation_log / ai_collaboration_trace
稽核寫入。等 Telegram 視覺驗證 OK 後再做 Phase 2 加入 DB 稽核。
相關:
- feedback_ai_autonomous_direction.md 北極星原則
- 1ff3405 今早的 JSON 裸奔 hotfix(只修了 narrative,沒修 items)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-04-18 15:54:16 +08:00 |
|
OG T
|
1ff3405755
|
fix(drift-narrator): 修復 JSON 裸奔 — 從 NEMOTRON 回傳解析 description 欄位
CD Pipeline / build-and-deploy (push) Successful in 10m44s
根因:openclaw.call() 經 NEMOTRON 路由後強制輸出 JSON(NEMOTRON_SYSTEM_PROMPT 鐵律)
但 _generate_narrative 期待純文字 → JSON 整包吐到 Telegram <pre> 區塊裸奔
修復:收到 text 後先嘗試 JSON 解析
- 成功 → 按優先順序取 description / action_title / reasoning
- 失敗(非 JSON)→ 原文使用(向下相容 Ollama qwen 純文字回傳)
效果:Telegram Config Drift 卡片顯示繁中人話摘要,不再吐原始 JSON
2026-04-17 ogt + Claude Sonnet 4.6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-04-18 01:08:32 +08:00 |
|
OG T
|
58d9c0637a
|
fix(drift): drift_narrator 改用 OpenClaw AI Router — 修復「研判原因」空白
根因:drift_narrator_service.py 的 _generate_narrative() 直接呼叫
Ollama httpx (192.168.0.111:11434),繞過 AI Router,無 fallback。
192.168.0.111 為死亡 IP → httpx 連線失敗 → 降級 fallback_narrative()
→ fallback 中 interpretation.explanation 存在但顯示層截斷 → 空白
修復:改用 get_openclaw().call(prompt),統一走 AI Router
同 drift_interpreter.py 的修法(d952435)
移除 unused httpx import
2026-04-17 ogt + Claude Sonnet 4.6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-04-17 13:28:16 +08:00 |
|
OG T
|
eda0cfd034
|
fix(adr075): drift 通知改用 send_drift_card,補齊所有呼叫點
CD Pipeline / build-and-deploy (push) Successful in 14m13s
- drift.py: 移除死碼 send_text(),改由 narrate_and_notify() 統一發卡片
- drift_narrator_service: _send_telegram() 改呼 send_drift_card() 帶四顆按鈕
- webhooks.py /alerts 路徑: 補傳 alert_category 啟用動態按鈕
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-04-12 20:20:47 +08:00 |
|
OG T
|
f2c18c4e63
|
feat(D1): models.json 集中化 — ADR-067 五大 Ollama 應用 hardcode 消除
CD Pipeline / build-and-deploy (push) Successful in 12m56s
- models.json v1.3.0: providers.ollama.models 新增 9 個 purpose keys
(drift_summary/drift_intent/log_anomaly/nemoclaw/playbook_draft/
code_review/embedding/rag_generate/image_analysis)
- drift_narrator_service: NARRATOR_MODEL → get_model("ollama","drift_summary")
- drift_interpreter: MODEL → get_model("ollama","drift_intent")
- log_summary_service: SUMMARY_MODEL → get_model("ollama","log_anomaly")
- local_code_review_service: _MODEL_OLLAMA → get_model("ollama","code_review")
- image_analysis_service: _MODEL → get_model("ollama","image_analysis")
- decision_manager: nemoclaw + playbook_draft 兩處 → get_model()
- embedding_service: get_embedding_service() factory → get_model("ollama","embedding")
- knowledge_service: OllamaEmbeddingService(model=...) → get_model()
所有模型名稱現在統一由 models.json 管理,修改模型只需改一個檔案。
LOGBOOK 更新:D1 完成 + B2 已完成確認
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-04-11 20:45:53 +08:00 |
|
OG T
|
b24fae313e
|
fix(drift_narrator): 補寫 narrative_text 到 DB + drift_repository.update_narrative
CD Pipeline / build-and-deploy (push) Has been cancelled
|
2026-04-10 11:06:50 +08:00 |
|
OG T
|
1c4bdedc64
|
fix(drift_narrator): send_text → send_notification + DriftLevel case fix
CD Pipeline / build-and-deploy (push) Successful in 14m43s
|
2026-04-10 10:48:36 +08:00 |
|
OG T
|
68e9ef5d26
|
fix(drift_narrator): DriftItem.severity → drift_level.value 欄位名稱修正
CD Pipeline / build-and-deploy (push) Has been cancelled
|
2026-04-10 10:24:41 +08:00 |
|
OG T
|
89015d4527
|
feat(phase30): Drift 報告 AI 人話摘要 (ADR-067)
CD Pipeline / build-and-deploy (push) Has been cancelled
- 新增 DriftNarratorService — qwen2.5:7b-instruct (Ollama 111)
- 觸發條件: high >= 1 or medium >= 3(HPA replicas 白名單)
- Redis 快取: drift_narrative:{report_id} TTL 1h
- LLM 失敗時 graceful fallback 結構化文字
- drift.py _analyze_and_notify: 接入 narrator(Phase 30 標記)
- Migration: drift_reports.narrative_text TEXT (已在 prod 執行)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-04-10 01:37:43 +08:00 |
|