Skip to content

chore: sync workflow templates#137

Merged
stranske merged 1 commit intomainfrom
sync/workflows-abfacabe3e5b
Jan 2, 2026
Merged

chore: sync workflow templates#137
stranske merged 1 commit intomainfrom
sync/workflows-abfacabe3e5b

Conversation

@stranske
Copy link
Copy Markdown
Owner

@stranske stranske commented Jan 2, 2026

Sync Summary

Files Updated

  • agents-keepalive-loop.yml: Keepalive loop - continues agent work until tasks complete
  • keepalive_loop.js: Core keepalive loop logic

Files Skipped

  • pr-00-gate.yml: File exists and sync_mode is create_only
  • ci.yml: File exists and sync_mode is create_only
  • dependabot.yml: File exists and sync_mode is create_only

Review Checklist

  • CI passes with updated workflows
  • No repo-specific customizations were overwritten

Source: stranske/Workflows
Manifest: .github/sync-manifest.yml

Automated sync from stranske/Workflows
Template hash: abfacabe3e5b

Changes synced from sync-manifest.yml
Copilot AI review requested due to automatic review settings January 2, 2026 22:43
@stranske stranske added sync Automated sync from Workflows automated Automated sync from Workflows labels Jan 2, 2026
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 2, 2026

⚠️ Action Required: Unable to determine source issue for PR #137. The PR title, branch name, or body must contain the issue number (e.g. #123, branch: issue-123, or the hidden marker ).

@github-actions github-actions bot added the autofix Triggers autofix on PR label Jan 2, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 2, 2026

🤖 Keepalive Loop Status

PR #137 | Agent: Codex | Iteration 0/5

Current State

Metric Value
Iteration progress [----------] 0/5
Action wait (missing-agent-label)
Disposition skipped (transient)
Gate success
Tasks 0/0 complete
Keepalive ❌ disabled
Autofix ❌ disabled

🔍 Failure Classification

| Error type | infrastructure |
| Error category | resource |
| Suggested recovery | Confirm the referenced resource exists (repo, PR, branch, workflow, or file). |

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 2, 2026

Status | ✅ no new diagnostics
History points | 0
Timestamp | 2026-01-02 22:44:07 UTC
Report artifact | autofix-report-pr-137
Remaining | ∅
New | ∅
No additional artifacts

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR syncs workflow templates from the stranske/Workflows repository, adding LLM-based task completion analysis and sophisticated rate limit detection to the keepalive loop system.

Key Changes

  • LLM Task Analysis Integration: Adds support for LLM-based task completion detection with provider tracking (GitHub Models, OpenAI, regex fallback) and confidence scoring, integrated into the auto-reconciliation workflow
  • Rate Limit Detection: Implements intelligent detection of gate cancellations due to rate limits by inspecting job annotations and logs, enabling automatic deferral with retry logic
  • Enhanced Status Display: Introduces disposition labels and improved summary formatting to clearly distinguish between transient failures, deferrals, and actual errors

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
.github/workflows/agents-keepalive-loop.yml Adds LLM completed tasks parsing and passes LLM provider metadata to summary update step
.github/scripts/keepalive_loop.js Implements rate limit detection, LLM task integration in reconciliation, force retry mechanism, and enhanced summary display with disposition labels

Comment on lines +1764 to +1767
const llmTasksLower = new Set((llmCompletedTasks || []).map(t => t.toLowerCase()));
const commitMatches = analysis.matches
.filter(m => m.confidence === 'high')
.filter(m => !llmTasksLower.has(m.task.toLowerCase()));
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The code assumes all elements in llmCompletedTasks are strings when calling .toLowerCase() on line 1764. If the LLM analysis returns non-string values (e.g., objects, numbers, null), this will throw a TypeError. Consider adding validation or type coercion to ensure all task values are strings before processing.

Suggested change
const llmTasksLower = new Set((llmCompletedTasks || []).map(t => t.toLowerCase()));
const commitMatches = analysis.matches
.filter(m => m.confidence === 'high')
.filter(m => !llmTasksLower.has(m.task.toLowerCase()));
const llmTasksLower = new Set(
(llmCompletedTasks || []).map(t => normalise(t).toLowerCase())
);
const commitMatches = analysis.matches
.filter(m => m.confidence === 'high')
.filter(m => !llmTasksLower.has(normalise(m.task).toLowerCase()));

Copilot uses AI. Check for mistakes.
Comment on lines +1748 to +1755
for (const task of llmCompletedTasks) {
highConfidence.push({
task,
reason: 'LLM session analysis',
confidence: 'high',
source: 'llm',
});
}
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The code doesn't validate that tasks from llmCompletedTasks are strings before using them. If the array contains non-string values, operations like .slice() on line 1797 and regex matching on line 1792 will fail. Consider filtering or normalizing the tasks to strings using a helper function like String(task) or filtering out non-string values.

Copilot uses AI. Check for mistakes.
Comment on lines +720 to +756
for (const job of jobs) {
if (canCheckAnnotations) {
const checkRunId = extractCheckRunId(job);
if (checkRunId) {
const params = {
owner: context.repo.owner,
repo: context.repo.repo,
check_run_id: checkRunId,
per_page: 100,
};
const annotations = github.paginate
? await github.paginate(github.rest.checks.listAnnotations, params)
: (await github.rest.checks.listAnnotations(params))?.data;
if (annotationsContainRateLimit(annotations)) {
return true;
}
}
}

if (canCheckLogs) {
const jobId = Number(job?.id) || 0;
if (jobId) {
try {
const logs = await github.rest.actions.downloadJobLogsForWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
job_id: jobId,
});
if (logContainsRateLimit(logs?.data)) {
return true;
}
} catch (error) {
if (core) core.info(`Failed to inspect Gate job logs for rate limits: ${error.message}`);
}
}
}
}
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The rate limit detection could make many API calls: for each job in the workflow run, it may call both listAnnotations (with pagination) and downloadJobLogsForWorkflowRun. For a gate workflow with many jobs, this could result in dozens of API calls and potentially hit rate limits itself. Consider:

  1. Checking annotations first for all jobs before falling back to logs (since logs are more expensive)
  2. Adding early termination after checking a few jobs if no rate limit signals are found
  3. Adding a comment explaining the performance tradeoff

Copilot uses AI. Check for mistakes.
Comment on lines +1230 to +1233
'### 🧠 Task Analysis',
`| Provider | ${providerIcon} ${providerLabel} |`,
`| Confidence | ${confidencePercent}% |`,
);
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The Task Analysis table is missing a header row and separator line, making it inconsistent with other tables in the summary (e.g., lines 1138-1139, 1164-1165). While this follows the same pattern as the Failure Classification section (line 1211), both should either include proper table headers and separators for consistency, or use a different format like a definition list or paragraph-style display.

Copilot uses AI. Check for mistakes.

const RATE_LIMIT_PATTERNS = [
/rate limit/i,
/rate[-\s]limit/i,
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The pattern /rate[-\s]limit/i on line 642 is redundant as it will match the same strings as both /rate limit/i (line 641) and /rate[-\s]limited/i (line 643). Consider removing this redundant pattern to simplify the array.

Suggested change
/rate[-\s]limit/i,

Copilot uses AI. Check for mistakes.
@stranske stranske merged commit f746d75 into main Jan 2, 2026
46 of 51 checks passed
@stranske stranske deleted the sync/workflows-abfacabe3e5b branch January 2, 2026 23:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autofix Triggers autofix on PR automated Automated sync from Workflows sync Automated sync from Workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants