Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions .github/scripts/keepalive_loop.js
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,11 @@ async function analyzeTaskCompletion({ github, context, prNumber, baseSha, headS
const matches = [];
const log = (msg) => core?.info?.(msg) || console.log(msg);

if (!context?.repo?.owner || !context?.repo?.repo) {
log('Skipping task analysis: missing repo context.');
return { matches, summary: 'Missing repo context for task analysis' };
}

if (!taskText || !baseSha || !headSha) {
log('Skipping task analysis: missing task text or commit range.');
return { matches, summary: 'Insufficient data for task analysis' };
Expand Down Expand Up @@ -1810,6 +1815,17 @@ async function analyzeTaskCompletion({ github, context, prNumber, baseSha, headS
*/
async function autoReconcileTasks({ github, context, prNumber, baseSha, headSha, llmCompletedTasks, core }) {
const log = (msg) => core?.info?.(msg) || console.log(msg);
const sources = { llm: 0, commit: 0 };

if (!context?.repo?.owner || !context?.repo?.repo || !prNumber) {
log('Skipping reconciliation: missing repo context or PR number.');
return {
updated: false,
tasksChecked: 0,
details: 'Missing repo context or PR number',
sources,
};
}

// Get current PR body
let pr;
Comment on lines 1815 to 1831
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSDoc return type documentation is incomplete. The function now returns an object with a sources property (containing llm and commit counts), but this is not documented in the return type annotation. The return type should be updated to include the sources field.

Copilot uses AI. Check for mistakes.
Expand All @@ -1830,7 +1846,7 @@ async function autoReconcileTasks({ github, context, prNumber, baseSha, headSha,

if (!taskText) {
log('Skipping reconciliation: no tasks found in PR body.');
return { updated: false, tasksChecked: 0, details: 'No tasks found in PR body' };
return { updated: false, tasksChecked: 0, details: 'No tasks found in PR body', sources };
}

// Build high-confidence matches from multiple sources
Expand All @@ -1846,6 +1862,7 @@ async function autoReconcileTasks({ github, context, prNumber, baseSha, headSha,
confidence: 'high',
source: 'llm',
});
sources.llm += 1;
}
}

Expand All @@ -1864,6 +1881,7 @@ async function autoReconcileTasks({ github, context, prNumber, baseSha, headSha,
log(`Commit analysis found ${commitMatches.length} additional task(s)`);
for (const match of commitMatches) {
highConfidence.push({ ...match, source: 'commit' });
sources.commit += 1;
}
}

Expand All @@ -1872,7 +1890,8 @@ async function autoReconcileTasks({ github, context, prNumber, baseSha, headSha,
return {
updated: false,
tasksChecked: 0,
details: analysis.summary + ' (no high-confidence matches for auto-check)'
details: analysis.summary + ' (no high-confidence matches for auto-check)',
sources,
};
}

Expand All @@ -1897,7 +1916,8 @@ async function autoReconcileTasks({ github, context, prNumber, baseSha, headSha,
return {
updated: false,
tasksChecked: 0,
details: 'Tasks matched but patterns not found in body'
details: 'Tasks matched but patterns not found in body',
sources,
};
}

Expand All @@ -1916,25 +1936,21 @@ async function autoReconcileTasks({ github, context, prNumber, baseSha, headSha,
updated: false,
tasksChecked: 0,
details: `Failed to update PR: ${error.message}`,
sources: { llm: 0, commit: 0 },
sources,
};
}

// Count matches by source for reporting
const llmCount = highConfidence.filter(m => m.source === 'llm').length;
const commitCount = highConfidence.filter(m => m.source === 'commit').length;

// Build detailed description
const sourceDesc = [];
if (llmCount > 0) sourceDesc.push(`${llmCount} from LLM analysis`);
if (commitCount > 0) sourceDesc.push(`${commitCount} from commit analysis`);
if (sources.llm > 0) sourceDesc.push(`${sources.llm} from LLM analysis`);
if (sources.commit > 0) sourceDesc.push(`${sources.commit} from commit analysis`);
const sourceInfo = sourceDesc.length > 0 ? ` (${sourceDesc.join(', ')})` : '';

return {
updated: true,
tasksChecked: checkedCount,
details: `Auto-checked ${checkedCount} task(s)${sourceInfo}: ${highConfidence.map(m => m.task.slice(0, 30) + '...').join(', ')}`,
sources: { llm: llmCount, commit: commitCount },
sources,
};
}

Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/agents-keepalive-loop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@ jobs:
- name: Auto-reconcile task checkboxes
if: needs.run-codex.outputs.changes-made == 'true'
uses: actions/github-script@v8
env:
LLM_COMPLETED_TASKS: ${{ needs.run-codex.outputs.llm-completed-tasks || '[]' }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
Expand All @@ -439,9 +441,9 @@ jobs:
const beforeSha = '${{ needs.evaluate.outputs.head_sha }}';
const headSha = '${{ needs.run-codex.outputs.commit-sha }}';

// Parse LLM completed tasks if available
// Parse LLM completed tasks if available (use env var to avoid JS string escaping issues)
let llmCompletedTasks = [];
const llmTasksJson = '${{ needs.run-codex.outputs.llm-completed-tasks || '[]' }}';
const llmTasksJson = process.env.LLM_COMPLETED_TASKS || '[]';
try {
llmCompletedTasks = JSON.parse(llmTasksJson);
if (llmCompletedTasks.length > 0) {
Expand Down
Loading