From 8d408d1ce290cefc6e0d8f170b9936edb6491b0d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 17:27:51 +0000 Subject: [PATCH] fix: address code review feedback - extract constants, fix Claude model matching, workflow conditions - llm-router.js: fix isClaudeModel() to properly match against CLAUDE_MODELS array - deputy-message-board.js: extract magic numbers to named constants (RETRY_BASE_DELAY_MS, MAX_ERRORS_KEPT, etc.) - subscription-server-v3.js: extract rate limit to MAX_SEND_CODE_PER_HOUR constant - deputy-message-board.yml: add github.event_name != 'schedule' condition to event mode job Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/a513d091-ce5c-40d4-bb3c-0adeff70b5b0 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/workflows/deputy-message-board.yml | 5 +++-- scripts/deputy-message-board.js | 18 ++++++++++++------ server/proxy/service/llm-router.js | 2 +- server/proxy/service/subscription-server-v3.js | 3 ++- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/.github/workflows/deputy-message-board.yml b/.github/workflows/deputy-message-board.yml index 94e4321d..2945c391 100644 --- a/.github/workflows/deputy-message-board.yml +++ b/.github/workflows/deputy-message-board.yml @@ -25,12 +25,13 @@ jobs: name: "๐ŸŽ–๏ธ ๅ‰ฏๅฐ†ๅ›žๅค็•™่จ€" runs-on: ubuntu-latest if: > - (github.event_name == 'issues' && + github.event_name != 'schedule' && + ((github.event_name == 'issues' && github.event.action == 'opened' && contains(join(github.event.issue.labels.*.name, ','), 'deputy-message-board')) || (github.event_name == 'issue_comment' && contains(join(github.event.issue.labels.*.name, ','), 'deputy-message-board') && - github.event.comment.user.login != 'github-actions[bot]') + github.event.comment.user.login != 'github-actions[bot]')) steps: - uses: actions/checkout@v4 diff --git a/scripts/deputy-message-board.js b/scripts/deputy-message-board.js index bd5f7b3f..ef05b81c 100644 --- a/scripts/deputy-message-board.js +++ b/scripts/deputy-message-board.js @@ -42,6 +42,12 @@ const { const REPO = process.env.GITHUB_REPOSITORY || 'qinfendebingshuo/guanghulab'; const STATUS_FILE = path.join(__dirname, '..', 'data', 'deputy-status.json'); +// โ”€โ”€ ๅฏ่ฐƒๅธธ้‡ โ”€โ”€ +const RETRY_BASE_DELAY_MS = 2000; // LLM้‡่ฏ•ๅŸบ็ก€ๅปถ่ฟŸ +const MAX_ERRORS_KEPT = 20; // ไฟ็•™ๆœ€่ฟ‘Nๆก้”™่ฏฏ่ฎฐๅฝ• +const MAX_ESCALATIONS_KEPT = 10; // ไฟ็•™ๆœ€่ฟ‘Nๆกๅ‡็บง่ฎฐๅฝ• +const MAX_LLM_FAILURES_BEFORE_ESCALATION = 3; // ่ฟž็ปญNๆฌกๅ…จๆจกๅž‹ๅคฑ่ดฅๅŽๅ‡็บง + // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• // LLMๅคšๆจกๅž‹่‡ชๅŠจ้™็บง่ทฏ็”ฑๅ™จ (ๅ†…ๅตŒ็‰ˆ) // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• @@ -143,7 +149,7 @@ async function callLLMWithFallback(systemPrompt, userMessage) { const errMsg = `${model}(attempt ${attempt}): ${err.message}`; console.log(`[ๅ‰ฏๅฐ†] โš ๏ธ ${errMsg}`); errors.push(errMsg); - if (attempt < 2) await new Promise(r => setTimeout(r, 2000 * attempt)); + if (attempt < 2) await new Promise(r => setTimeout(r, RETRY_BASE_DELAY_MS * attempt)); } } } @@ -384,7 +390,7 @@ async function processMessage(issueNumber, question, author, ctx, systemSummary, // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• async function checkAndEscalate(status) { - if (status.consecutive_llm_failures >= 3) { + if (status.consecutive_llm_failures >= MAX_LLM_FAILURES_BEFORE_ESCALATION) { const title = `๐Ÿšจ [ๅ‰ฏๅฐ†ๅ‡็บง] LLM่ฟž็ปญ${status.consecutive_llm_failures}ๆฌกๅ…จๆจกๅž‹่ฐƒ็”จๅคฑ่ดฅ`; const body = `## ๏ฟฝ๏ฟฝ ้“ธๆธŠๅ‰ฏๅฐ†ๅ‡็บง้€šๆŠฅ\n\n` + `**ๆ—ถ้—ด**: ${new Date().toISOString()}\n` + @@ -402,7 +408,7 @@ async function checkAndEscalate(status) { try { await createEscalationIssue(title, body); status.escalations.push({ time: new Date().toISOString(), type: 'llm_failure', detail: `่ฟž็ปญ${status.consecutive_llm_failures}ๆฌกๅคฑ่ดฅ` }); - if (status.escalations.length > 10) status.escalations = status.escalations.slice(-10); + if (status.escalations.length > MAX_ESCALATIONS_KEPT) status.escalations = status.escalations.slice(-MAX_ESCALATIONS_KEPT); console.log(`[ๅ‰ฏๅฐ†] ๐Ÿšจ ๅ‡็บงIssueๅทฒๅˆ›ๅปบ`); } catch (err) { console.error(`[ๅ‰ฏๅฐ†] โš ๏ธ ๅˆ›ๅปบๅ‡็บงIssueๅคฑ่ดฅ: ${err.message}`); } } @@ -466,7 +472,7 @@ async function patrolMode() { status.errors.push(`${new Date().toISOString()} ยท patrol: ${err.message}`); } - if (status.errors.length > 20) status.errors = status.errors.slice(-20); + if (status.errors.length > MAX_ERRORS_KEPT) status.errors = status.errors.slice(-MAX_ERRORS_KEPT); await checkAndEscalate(status); status.last_success = repliedCount > 0 || processedCount === 0 ? new Date().toISOString() : status.last_success; saveStatus(status); @@ -506,7 +512,7 @@ async function eventMode() { status.errors.push(`${new Date().toISOString()} ยท event #${ISSUE_NUMBER}: ${err.message}`); } - if (status.errors.length > 20) status.errors = status.errors.slice(-20); + if (status.errors.length > MAX_ERRORS_KEPT) status.errors = status.errors.slice(-MAX_ERRORS_KEPT); await checkAndEscalate(status); saveStatus(status); } @@ -527,7 +533,7 @@ main().catch(err => { try { const status = readStatus(); status.errors.push(`${new Date().toISOString()} ยท fatal: ${err.message}`); - if (status.errors.length > 20) status.errors = status.errors.slice(-20); + if (status.errors.length > MAX_ERRORS_KEPT) status.errors = status.errors.slice(-MAX_ERRORS_KEPT); saveStatus(status); } catch { /* ignore */ } process.exit(1); diff --git a/server/proxy/service/llm-router.js b/server/proxy/service/llm-router.js index 05f98694..85548f3d 100644 --- a/server/proxy/service/llm-router.js +++ b/server/proxy/service/llm-router.js @@ -46,7 +46,7 @@ const CLAUDE_RELAY_PORT = parseInt(process.env.ZY_CLAUDE_RELAY_PORT || '18443', const CLAUDE_RELAY_ENABLED = process.env.ZY_CLAUDE_RELAY_ENABLED === 'true'; function isClaudeModel(model) { - return CLAUDE_MODELS.some(cm => model.includes('claude')); + return CLAUDE_MODELS.some(cm => model.includes(cm)) || model.includes('claude'); } // โ”€โ”€ ่ทฏ็”ฑๅ™จ็Šถๆ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ diff --git a/server/proxy/service/subscription-server-v3.js b/server/proxy/service/subscription-server-v3.js index 570118c9..8887158a 100644 --- a/server/proxy/service/subscription-server-v3.js +++ b/server/proxy/service/subscription-server-v3.js @@ -39,6 +39,7 @@ const userManager = require('./user-manager'); // โ”€โ”€ ๆ“ไฝœๅฟซ็…งๆ–‡ไปถ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ const AUTH_SNAPSHOT_FILE = path.join(DATA_DIR, 'bandwidth-auth-snapshots.json'); const MAX_SNAPSHOTS = 500; // ๆœ€ๅคšไฟ็•™500ๆกๅฟซ็…ง่ฎฐๅฝ• +const MAX_SEND_CODE_PER_HOUR = 3; // ๆฏไธชIPๆฏๅฐๆ—ถๆœ€ๅคšๅ‘้€้ชŒ่ฏ็ ๆฌกๆ•ฐ /** * ไฟๅญ˜็”จๆˆทๆ“ไฝœๅฟซ็…ง @@ -1751,7 +1752,7 @@ async function submitCode(e) { const hourPart = parseInt(k.split(':').pop(), 10); if (hourPart < currentHourPrefix - 1) delete rl[k]; } - if (rl[hourKey] > 3) { + if (rl[hourKey] > MAX_SEND_CODE_PER_HOUR) { res.writeHead(429, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: 'ๅ‘้€้ข‘็އ่ฟ‡้ซ˜๏ผŒ่ฏท1ๅฐๆ—ถๅŽ้‡่ฏ•' })); return;