@@ -1337,37 +1337,40 @@ jobs:
13371337 // Optional AI fallback for legacy issues where deterministic matching finds nothing.
13381338 if (useAiGameFallback && desiredGames.size === 0) {
13391339 aiGameAttempts += 1;
1340- try {
1341- const res = await fetch(
1342- `https://models.github.ai/orgs/${owner}/inference/chat/completions`,
1340+ const aiPayload = {
1341+ model: 'openai/gpt-4.1-mini',
1342+ temperature: 0.1,
1343+ max_tokens: 120,
1344+ messages: [
13431345 {
1344- method: 'POST',
1345- headers: {
1346- Accept: 'application/vnd.github+json',
1347- Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
1348- 'X-GitHub-Api-Version': '2026-03-10',
1349- 'Content-Type': 'application/json',
1350- },
1351- body: JSON.stringify({
1352- model: 'openai/gpt-4.1-mini',
1353- temperature: 0.1,
1354- max_tokens: 120,
1355- messages: [
1356- {
1357- role: 'system',
1358- content:
1359- 'Return JSON only. Identify the game referenced in this LinuxGSM issue with high precision.',
1360- },
1361- {
1362- role: 'user',
1363- content:
1364- `Title: ${title}\n\nBody:\n${body.slice(0, 2500)}\n\n` +
1365- 'Return JSON: {"detected_game":"string or null","game_confidence":"high|medium|low|null"}',
1366- },
1367- ],
1368- }),
1369- }
1370- );
1346+ role: 'system',
1347+ content: 'Return JSON only. Identify the game referenced in this LinuxGSM issue with high precision.',
1348+ },
1349+ {
1350+ role: 'user',
1351+ content:
1352+ `Title: ${title}\n\nBody:\n${body.slice(0, 2500)}\n\n` +
1353+ 'Return JSON: {"detected_game":"string or null","game_confidence":"high|medium|low|null"}',
1354+ },
1355+ ],
1356+ };
1357+ const aiUrl = `https://models.github.ai/orgs/${owner}/inference/chat/completions`;
1358+ const aiHeaders = {
1359+ Accept: 'application/vnd.github+json',
1360+ Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
1361+ 'X-GitHub-Api-Version': '2026-03-10',
1362+ 'Content-Type': 'application/json',
1363+ };
1364+ try {
1365+ let res = await fetch(aiUrl, { method: 'POST', headers: aiHeaders, body: JSON.stringify(aiPayload) });
1366+
1367+ // On 429 honour Retry-After (capped at 60 s) then retry once.
1368+ if (res.status === 429) {
1369+ const retryAfter = Math.min(Number.parseInt(res.headers.get('Retry-After') || '10', 10), 60);
1370+ console.log(`#${rawIssue.number}: AI fallback rate-limited — waiting ${retryAfter}s then retrying…`);
1371+ await new Promise((r) => setTimeout(r, retryAfter * 1000));
1372+ res = await fetch(aiUrl, { method: 'POST', headers: aiHeaders, body: JSON.stringify(aiPayload) });
1373+ }
13711374
13721375 if (res.ok) {
13731376 const data = await res.json();
0 commit comments