修正 Codex Action 重複輸出最後回答 #3

Merged
jiantw83 merged 5 commits from ai-review-resolve/20260624102518 into develop 2026-06-24 14:30:13 +00:00
Member

變更摘要

  • 改用 codex exec --output-last-message 取得最後回答,避免直接顯示 Codex stdout transcript 時出現同一段回答兩次。
  • Action 不再串流 codex exec 的 stdout transcript,只在結束後輸出 last message 一次,並將同一份內容寫入 GITHUB_OUTPUT
  • 保留 stdout 收集作為 last-message 檔不存在時的 fallback,避免假 CLI 或舊行為沒有輸出檔時完全失去 output。
  • 補上回歸測試,模擬 Codex stdout 同時包含 transcript 與 final answer,驗證 stdout 與 GITHUB_OUTPUT 都只保留 final answer 一次。

驗證

  • node --check app/main.js
  • bash tests/entrypoint_test.sh
  • git diff --check
  • bash tests/docker_image_test.sh(本機 Docker daemon 不可用,測試依腳本略過)
## 變更摘要 - 改用 `codex exec --output-last-message` 取得最後回答,避免直接顯示 Codex stdout transcript 時出現同一段回答兩次。 - Action 不再串流 `codex exec` 的 stdout transcript,只在結束後輸出 last message 一次,並將同一份內容寫入 `GITHUB_OUTPUT`。 - 保留 stdout 收集作為 last-message 檔不存在時的 fallback,避免假 CLI 或舊行為沒有輸出檔時完全失去 output。 - 補上回歸測試,模擬 Codex stdout 同時包含 transcript 與 final answer,驗證 stdout 與 `GITHUB_OUTPUT` 都只保留 final answer 一次。 ## 驗證 - `node --check app/main.js` - `bash tests/entrypoint_test.sh` - `git diff --check` - `bash tests/docker_image_test.sh`(本機 Docker daemon 不可用,測試依腳本略過)

🤖 AI Code Review 團隊

👤 角色 🎯 面向 🧠 個性
🗡️ Assassin security 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard style 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo maintainability 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage logic 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya testing 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
Rogue efficiency 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」

🔍 服務:opencode 模型:gemini-2.5-flash

## 🤖 AI Code Review 團隊 | 👤 角色 | 🎯 面向 | 🧠 個性 | |--------|--------|--------| | **🗡️ Assassin** | security | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | **🎼 Bard** | style | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | **🧰 Leo** | maintainability | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | **🔮 Mage** | logic | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | **🧪 Maya** | testing | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | **⚡ Rogue** | efficiency | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 | > 🔍 服務:opencode 模型:gemini-2.5-flash
gitea-actions bot reviewed 2026-06-24 14:15:09 +00:00
gitea-actions bot left a comment

AI Code Review 統計

類型 🔴 嚴重 🟡 警告 🔵 建議 無法標示
新問題 0 筆 1 筆 2 筆 0 筆
舊問題 0 筆 0 筆 0 筆 0 筆

🤖 AI 助理使用量

本次審查(opencode / gemini-2.5-flash,共 10 次呼叫)

提示 token 回應 token 合計
85,613 3,373 137,865

剩餘可用

剩餘可用:無法計算百分比(自架服務,無帳號額度概念)

## AI Code Review 統計 | 類型 | 🔴 嚴重 | 🟡 警告 | 🔵 建議 | ⚪ 無法標示 | | --- | --- | --- | --- | --- | | 新問題 | 0 筆 | 1 筆 | 2 筆 | 0 筆 | | 舊問題 | 0 筆 | 0 筆 | 0 筆 | 0 筆 | ## 🤖 AI 助理使用量 **本次審查**(opencode / gemini-2.5-flash,共 10 次呼叫) | 提示 token | 回應 token | 合計 | | --- | --- | --- | | 85,613 | 3,373 | 137,865 | **剩餘可用** 剩餘可用:無法計算百分比(自架服務,無帳號額度概念)
@@ -197,7 +199,10 @@ function codexExecArgs(model, prompt) {
function runCodex(model, prompt) {
return new Promise((resolve) => {

嚴重等級🔵 建議
審查員:Rogue
問題:每次執行 runCodex 都在建立新的 temp 目錄與追蹤檔案,這種重複性的檔案系統配置開銷對於高頻率呼叫來說是完全浪費的資源。
建議:如果執行環境是持續存在的,應快取 tempDir 路徑或使用預設的共享路徑,避免頻繁的檔案系統建立與追蹤開銷。

**嚴重等級**:🔵 建議 **審查員**:Rogue **問題**:每次執行 runCodex 都在建立新的 temp 目錄與追蹤檔案,這種重複性的檔案系統配置開銷對於高頻率呼叫來說是完全浪費的資源。 **建議**:如果執行環境是持續存在的,應快取 tempDir 路徑或使用預設的共享路徑,避免頻繁的檔案系統建立與追蹤開銷。
Ghost marked this conversation as resolved
app/main.js Outdated
@@ -239,0 +242,4 @@
let lastMessage = "";
try {
lastMessage = fs.readFileSync(lastMessageFile, "utf8");
} catch {

嚴重等級🟡 警告
審查員:Bard
問題:在 runCodex 函式中,對 lastMessageFile 的讀取缺乏明確的錯誤處理策略,直接將錯誤靜默處理並初始化為空字串,可能掩蓋真正的檔案系統問題,且導致邏輯錯誤。
建議:建議在 catch 區塊中至少加入簡單的日誌記錄(如 console.error),並明確區分錯誤類型(如檔案不存在 vs 權限問題),給予清晰的回饋。

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:在 `runCodex` 函式中,對 `lastMessageFile` 的讀取缺乏明確的錯誤處理策略,直接將錯誤靜默處理並初始化為空字串,可能掩蓋真正的檔案系統問題,且導致邏輯錯誤。 **建議**:建議在 `catch` 區塊中至少加入簡單的日誌記錄(如 `console.error`),並明確區分錯誤類型(如檔案不存在 vs 權限問題),給予清晰的回饋。
Ghost marked this conversation as resolved
app/main.js Outdated
@@ -239,0 +245,4 @@
} catch {
lastMessage = "";
}

嚴重等級🔵 建議
審查員:Bard
問題:在 resolve 函式的回傳值邏輯中使用了 lastMessage || output.toString(),這種基於真值判斷(truthiness)的邏輯若 lastMessage 為空字串但 output 亦為空,會導致語意不明,且與前面處理錯誤的情境交織,增加閱讀複雜度。
建議:建議明確區分 lastMessage 的來源,若確定檔案應存在,請使用更明確的判斷方式(如檢查檔案是否存在或長度),提升程式碼的可預測性。

**嚴重等級**:🔵 建議 **審查員**:Bard **問題**:在 `resolve` 函式的回傳值邏輯中使用了 `lastMessage || output.toString()`,這種基於真值判斷(truthiness)的邏輯若 `lastMessage` 為空字串但 `output` 亦為空,會導致語意不明,且與前面處理錯誤的情境交織,增加閱讀複雜度。 **建議**:建議明確區分 `lastMessage` 的來源,若確定檔案應存在,請使用更明確的判斷方式(如檢查檔案是否存在或長度),提升程式碼的可預測性。
Ghost marked this conversation as resolved
jiantw83 closed this pull request 2026-06-24 14:15:25 +00:00
jiantw83 reopened this pull request 2026-06-24 14:15:49 +00:00
jiantw83 added 3 commits 2026-06-24 14:18:03 +00:00
chore: update ai-review findings [ai-review-bot][success]
CI / 工具測試 (pull_request) Successful in 10s
CI / 計算版本號 (pull_request) Successful in 2s
AI / Code Review (pull_request) Successful in 2s
49061fe033
jiantw83 force-pushed ai-review-resolve/20260624102518 from 98aa4f33fd to 49061fe033 2026-06-24 14:18:03 +00:00 Compare
jiantw83 added 1 commit 2026-06-24 14:22:44 +00:00
fix(app): 停止串流 Codex transcript
CI / 計算版本號 (pull_request) Successful in 2s
CI / 工具測試 (pull_request) Successful in 9s
AI / Code Review (pull_request) Successful in 23s
ab56c56206

🤖 AI Code Review 團隊

👤 角色 🎯 面向 🧠 個性
🗡️ Assassin security 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard style 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo maintainability 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage logic 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya testing 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
Rogue efficiency 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」

🔍 服務:opencode 模型:gemini-2.5-flash

## 🤖 AI Code Review 團隊 | 👤 角色 | 🎯 面向 | 🧠 個性 | |--------|--------|--------| | **🗡️ Assassin** | security | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | **🎼 Bard** | style | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | **🧰 Leo** | maintainability | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | **🔮 Mage** | logic | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | **🧪 Maya** | testing | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | **⚡ Rogue** | efficiency | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 | > 🔍 服務:opencode 模型:gemini-2.5-flash
gitea-actions bot reviewed 2026-06-24 14:23:08 +00:00
gitea-actions bot left a comment

AI Code Review 統計

類型 🔴 嚴重 🟡 警告 🔵 建議 無法標示
新問題 0 筆 1 筆 1 筆 0 筆
舊問題 0 筆 0 筆 0 筆 0 筆

🤖 AI 助理使用量

本次審查(opencode / gemini-2.5-flash,共 10 次呼叫)

提示 token 回應 token 合計
52,986 2,446 139,274

剩餘可用

剩餘可用:無法計算百分比(自架服務,無帳號額度概念)

## AI Code Review 統計 | 類型 | 🔴 嚴重 | 🟡 警告 | 🔵 建議 | ⚪ 無法標示 | | --- | --- | --- | --- | --- | | 新問題 | 0 筆 | 1 筆 | 1 筆 | 0 筆 | | 舊問題 | 0 筆 | 0 筆 | 0 筆 | 0 筆 | ## 🤖 AI 助理使用量 **本次審查**(opencode / gemini-2.5-flash,共 10 次呼叫) | 提示 token | 回應 token | 合計 | | --- | --- | --- | | 52,986 | 2,446 | 139,274 | **剩餘可用** 剩餘可用:無法計算百分比(自架服務,無帳號額度概念)
@@ -237,2 +239,3 @@
resolve({ status: code ?? 1, output: output.toString() });
const lastMessage = fs.existsSync(lastMessageFile) ? fs.readFileSync(lastMessageFile, "utf8") : null;
const diagnosticOutput = output.toString();

嚴重等級🟡 警告
審查員:Bard
問題runCodexresultOutput 的計算邏輯過於緊湊且不易維護,且直接進行檔案同步讀取,若檔案過大可能阻塞 Node.js 事件循環。
建議:建議拆解複雜的邏輯為獨立的輔助函數,並改用非同步的檔案讀取方式。

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:`runCodex` 中 `resultOutput` 的計算邏輯過於緊湊且不易維護,且直接進行檔案同步讀取,若檔案過大可能阻塞 Node.js 事件循環。 **建議**:建議拆解複雜的邏輯為獨立的輔助函數,並改用非同步的檔案讀取方式。
@@ -312,6 +318,9 @@ function setupAuth(oauth, codexHome) {
async function runCodexAction({ oauth, model, codexHome, prompt }) {
const lockHandle = setupAuth(oauth, codexHome);
const result = await runCodex(model, prompt);
if (result.output) {

嚴重等級🔵 建議
審查員:Bard
問題:確保字串結尾換行的樣板程式碼邏輯重複出現。
建議:建立 ensureNewline 共用工具函式。

**嚴重等級**:🔵 建議 **審查員**:Bard **問題**:確保字串結尾換行的樣板程式碼邏輯重複出現。 **建議**:建立 `ensureNewline` 共用工具函式。
admin added 1 commit 2026-06-24 14:23:10 +00:00
chore: update ai-review findings [ai-review-bot][success]
AI / Code Review (pull_request) Successful in 2s
CI / 計算版本號 (pull_request) Successful in 3s
CI / 工具測試 (pull_request) Successful in 9s
9f7a2e97c3
jiantw83 merged commit 9018aeccbb into develop 2026-06-24 14:30:13 +00:00
jiantw83 deleted branch ai-review-resolve/20260624102518 2026-06-24 14:30:13 +00:00
Sign in to join this conversation.
No Reviewers
No labels
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: old-actions/codex#3