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

Merged
jiantw83 merged 5 commits from ai-review-resolve/20260624102518 into develop 2026-06-24 14:30:13 +00:00
Showing only changes of commit cab7507ddb - Show all commits
+18 -4
View File
@@ -183,11 +183,13 @@ function readExecutionConfig() {
}; };
} }
function codexExecArgs(model, prompt) { function codexExecArgs(model, prompt, lastMessageFile) {
return [ return [
"exec", "exec",
"--dangerously-bypass-approvals-and-sandbox", "--dangerously-bypass-approvals-and-sandbox",
"--skip-git-repo-check", "--skip-git-repo-check",
"--output-last-message",
lastMessageFile,
"--model", "--model",
model, model,
prompt, prompt,
@@ -197,7 +199,10 @@ function codexExecArgs(model, prompt) {
function runCodex(model, prompt) { function runCodex(model, prompt) {
return new Promise((resolve) => { return new Promise((resolve) => {
Ghost marked this conversation as resolved
Review

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

**嚴重等級**:🔵 建議 **審查員**:Rogue **問題**:每次執行 runCodex 都在建立新的 temp 目錄與追蹤檔案,這種重複性的檔案系統配置開銷對於高頻率呼叫來說是完全浪費的資源。 **建議**:如果執行環境是持續存在的,應快取 tempDir 路徑或使用預設的共享路徑,避免頻繁的檔案系統建立與追蹤開銷。
const { timeoutMs, outputLimitBytes, workspace } = readExecutionConfig(); const { timeoutMs, outputLimitBytes, workspace } = readExecutionConfig();
const args = codexExecArgs(model, prompt); const tempDir = makeTempDir(process.env.CODEX_HOME || "/root/.codex");
const lastMessageFile = path.join(tempDir, "last-message.txt");
tempFiles.trackFile(lastMessageFile);
const args = codexExecArgs(model, prompt, lastMessageFile);
// This Docker Action runs inside an ephemeral CI container where Codex must be // This Docker Action runs inside an ephemeral CI container where Codex must be
// able to edit the checked-out workspace without interactive approvals. // able to edit the checked-out workspace without interactive approvals.
@@ -210,7 +215,6 @@ function runCodex(model, prompt) {
output.append(Buffer.from(`Codex execution timed out after ${timeoutMs} ms.\n`)); output.append(Buffer.from(`Codex execution timed out after ${timeoutMs} ms.\n`));
}, timeoutMs); }, timeoutMs);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stdout); child.stderr.pipe(process.stdout);
child.stdout.on("data", (chunk) => { child.stdout.on("data", (chunk) => {
@@ -235,7 +239,14 @@ function runCodex(model, prompt) {
output.append(Buffer.from(`Codex process terminated by signal ${signal}.\n`)); output.append(Buffer.from(`Codex process terminated by signal ${signal}.\n`));
} }
Review

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

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:`runCodex` 中 `resultOutput` 的計算邏輯過於緊湊且不易維護,且直接進行檔案同步讀取,若檔案過大可能阻塞 Node.js 事件循環。 **建議**:建議拆解複雜的邏輯為獨立的輔助函數,並改用非同步的檔案讀取方式。
resolve({ status: code ?? 1, output: output.toString() }); let lastMessage = "";
try {
lastMessage = fs.readFileSync(lastMessageFile, "utf8");
} catch {
lastMessage = "";
}
resolve({ status: code ?? 1, output: lastMessage || output.toString() });
}); });
}); });
} }
1
@@ -312,6 +323,9 @@ function setupAuth(oauth, codexHome) {
async function runCodexAction({ oauth, model, codexHome, prompt }) { async function runCodexAction({ oauth, model, codexHome, prompt }) {
const lockHandle = setupAuth(oauth, codexHome); const lockHandle = setupAuth(oauth, codexHome);
const result = await runCodex(model, prompt); const result = await runCodex(model, prompt);
if (result.output) {
process.stdout.write(result.output.endsWith("\n") ? result.output : `${result.output}\n`);
}
appendGithubOutput(result.status === 0 ? "completed" : "failed", result.output); appendGithubOutput(result.status === 0 ? "completed" : "failed", result.output);
if (lockHandle !== undefined) { if (lockHandle !== undefined) {