@xn-intenton-z2a/agentic-lib 7.1.27 → 7.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/actions/commit-if-changed/action.yml +26 -7
- package/src/seeds/zero-package.json +1 -1
- package/src/workflows/agent-discussions-bot.yml +10 -3
- package/src/workflows/agent-flow-maintain.yml +3 -1
- package/src/workflows/agent-flow-review.yml +3 -1
- package/src/workflows/agent-flow-transform.yml +3 -1
- package/src/workflows/agent-supervisor.yml +66 -85
package/package.json
CHANGED
|
@@ -31,11 +31,30 @@ runs:
|
|
|
31
31
|
else
|
|
32
32
|
git commit -m "${{ inputs.commit-message }}"
|
|
33
33
|
REF="${{ inputs.push-ref }}"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
MAX_RETRIES=3
|
|
35
|
+
for attempt in $(seq 1 $MAX_RETRIES); do
|
|
36
|
+
if [ -n "$REF" ]; then
|
|
37
|
+
git pull --rebase origin "$REF" || {
|
|
38
|
+
echo "Rebase conflict on attempt $attempt — aborting rebase and retrying"
|
|
39
|
+
git rebase --abort 2>/dev/null || true
|
|
40
|
+
sleep $((attempt * 2))
|
|
41
|
+
continue
|
|
42
|
+
}
|
|
43
|
+
git push origin "$REF" && break
|
|
44
|
+
else
|
|
45
|
+
git pull --rebase || {
|
|
46
|
+
echo "Rebase conflict on attempt $attempt — aborting rebase and retrying"
|
|
47
|
+
git rebase --abort 2>/dev/null || true
|
|
48
|
+
sleep $((attempt * 2))
|
|
49
|
+
continue
|
|
50
|
+
}
|
|
51
|
+
git push && break
|
|
52
|
+
fi
|
|
53
|
+
if [ "$attempt" -eq "$MAX_RETRIES" ]; then
|
|
54
|
+
echo "::error::Failed to push after $MAX_RETRIES attempts"
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
echo "Push failed on attempt $attempt, retrying..."
|
|
58
|
+
sleep $((attempt * 2))
|
|
59
|
+
done
|
|
41
60
|
fi
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
name: agent-discussions-bot
|
|
9
9
|
run-name: "agent-discussions-bot [${{ github.ref_name }}]"
|
|
10
|
-
concurrency:
|
|
10
|
+
concurrency:
|
|
11
|
+
group: agentic-lib-bot-${{ github.event.discussion.node_id || github.run_id }}
|
|
12
|
+
cancel-in-progress: false
|
|
11
13
|
|
|
12
14
|
on:
|
|
13
15
|
discussion:
|
|
@@ -24,6 +26,11 @@ on:
|
|
|
24
26
|
- cron: "7 12 */28 * *" # schedule-1: every 28 days
|
|
25
27
|
workflow_dispatch:
|
|
26
28
|
inputs:
|
|
29
|
+
discussion-url:
|
|
30
|
+
description: "Discussion URL to respond to (required for supervisor-dispatched runs)"
|
|
31
|
+
type: string
|
|
32
|
+
required: false
|
|
33
|
+
default: ""
|
|
27
34
|
model:
|
|
28
35
|
description: "Copilot SDK model to use"
|
|
29
36
|
type: choice
|
|
@@ -76,8 +83,8 @@ jobs:
|
|
|
76
83
|
uses: actions/github-script@v7
|
|
77
84
|
with:
|
|
78
85
|
script: |
|
|
79
|
-
let url = '';
|
|
80
|
-
if (context.payload.discussion) {
|
|
86
|
+
let url = '${{ inputs.discussion-url }}' || '';
|
|
87
|
+
if (!url && context.payload.discussion) {
|
|
81
88
|
url = context.payload.discussion.html_url;
|
|
82
89
|
}
|
|
83
90
|
core.setOutput('url', url);
|
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
# Copyright (C) 2025-2026 Polycode Limited
|
|
3
3
|
# .github/workflows/agent-supervisor.yml
|
|
4
4
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
5
|
+
# Supervisor: reactive + proactive orchestration.
|
|
6
|
+
#
|
|
7
|
+
# Two modes:
|
|
8
|
+
# 1. Reactive (evaluate job): Hardcoded fast-path responses to workflow events.
|
|
9
|
+
# - Failed builds on PR branches → dispatch fix-code (with loop protection)
|
|
10
|
+
# - Stale conflicting PRs → remove automerge label
|
|
11
|
+
#
|
|
12
|
+
# 2. Proactive (supervise job): LLM-driven strategic decisions via agentic-step.
|
|
13
|
+
# - Gathers full repo context (issues, PRs, workflows, features, activity)
|
|
14
|
+
# - Chooses actions: dispatch workflows, create/label/close issues, respond to discussions
|
|
15
|
+
# - Runs on workflow_dispatch or schedule (set via agent-supervisor-schedule.yml)
|
|
12
16
|
|
|
13
17
|
name: agent-supervisor
|
|
14
18
|
run-name: "agent-supervisor [${{ github.ref_name }}]"
|
|
@@ -18,30 +22,52 @@ on:
|
|
|
18
22
|
workflows:
|
|
19
23
|
- test
|
|
20
24
|
- agent-flow-transform
|
|
21
|
-
- agent-flow-maintain
|
|
22
25
|
- agent-flow-fix-code
|
|
23
|
-
- agent-flow-review
|
|
24
|
-
- agent-discussions-bot
|
|
25
26
|
- ci-automerge
|
|
26
27
|
types:
|
|
27
28
|
- completed
|
|
28
29
|
workflow_dispatch:
|
|
30
|
+
inputs:
|
|
31
|
+
model:
|
|
32
|
+
description: "Copilot SDK model to use"
|
|
33
|
+
type: choice
|
|
34
|
+
required: false
|
|
35
|
+
default: "claude-sonnet-4"
|
|
36
|
+
options:
|
|
37
|
+
- claude-sonnet-4
|
|
38
|
+
- gpt-5-mini
|
|
39
|
+
- gpt-4.1
|
|
29
40
|
|
|
30
41
|
permissions:
|
|
31
42
|
actions: write
|
|
32
43
|
contents: read
|
|
33
|
-
issues:
|
|
44
|
+
issues: write
|
|
34
45
|
pull-requests: write
|
|
35
46
|
checks: read
|
|
47
|
+
discussions: write
|
|
36
48
|
|
|
37
49
|
env:
|
|
38
50
|
maxFixAttempts: "3"
|
|
39
|
-
staleDays: "14"
|
|
40
51
|
stalePrDays: "3"
|
|
52
|
+
configPath: ".github/agentic-lib/agents/agentic-lib.yml"
|
|
41
53
|
|
|
42
54
|
jobs:
|
|
55
|
+
params:
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
steps:
|
|
58
|
+
- name: Normalise params
|
|
59
|
+
id: normalise
|
|
60
|
+
shell: bash
|
|
61
|
+
run: |
|
|
62
|
+
MODEL='${{ inputs.model }}'
|
|
63
|
+
echo "model=${MODEL:-claude-sonnet-4}" >> $GITHUB_OUTPUT
|
|
64
|
+
outputs:
|
|
65
|
+
model: ${{ steps.normalise.outputs.model }}
|
|
66
|
+
|
|
67
|
+
# ─── Reactive: fast-path responses to workflow events ─────────────────
|
|
43
68
|
evaluate:
|
|
44
69
|
runs-on: ubuntu-latest
|
|
70
|
+
if: github.event_name == 'workflow_run'
|
|
45
71
|
steps:
|
|
46
72
|
- name: Check telemetry and dispatch
|
|
47
73
|
uses: actions/github-script@v7
|
|
@@ -55,7 +81,6 @@ jobs:
|
|
|
55
81
|
const branch = workflowRun?.head_branch || '';
|
|
56
82
|
const isAgenticBranch = branch && !['main', 'master'].includes(branch);
|
|
57
83
|
const maxFixAttempts = parseInt(process.env.maxFixAttempts) || 3;
|
|
58
|
-
const staleDays = parseInt(process.env.staleDays) || 14;
|
|
59
84
|
const stalePrDays = parseInt(process.env.stalePrDays) || 3;
|
|
60
85
|
|
|
61
86
|
core.info(`Supervisor: workflow="${workflowName}" conclusion="${conclusion}" branch="${branch}"`);
|
|
@@ -74,7 +99,6 @@ jobs:
|
|
|
74
99
|
const pr = prs[0];
|
|
75
100
|
const prNumber = pr.number;
|
|
76
101
|
|
|
77
|
-
// Count prior fix-code runs for this branch to prevent infinite loops
|
|
78
102
|
const { data: fixRuns } = await github.rest.actions.listWorkflowRuns({
|
|
79
103
|
owner, repo,
|
|
80
104
|
workflow_id: 'agent-flow-fix-code.yml',
|
|
@@ -109,76 +133,7 @@ jobs:
|
|
|
109
133
|
core.warning(`Fix-code dispatch failed: ${err.message}`);
|
|
110
134
|
}
|
|
111
135
|
|
|
112
|
-
// ─── 2.
|
|
113
|
-
|
|
114
|
-
try {
|
|
115
|
-
if (workflowName === 'ci-automerge' && conclusion === 'success') {
|
|
116
|
-
core.info('Automerge succeeded. Dispatching transform to pick up next issue.');
|
|
117
|
-
await github.rest.actions.createWorkflowDispatch({
|
|
118
|
-
owner, repo,
|
|
119
|
-
workflow_id: 'agent-flow-transform.yml',
|
|
120
|
-
ref: 'main',
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
} catch (err) {
|
|
124
|
-
core.warning(`Post-merge transform dispatch failed: ${err.message}`);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// ─── 3. Discussion bot follow-through ─────────────────────────────────
|
|
128
|
-
|
|
129
|
-
try {
|
|
130
|
-
if (workflowName === 'agent-discussions-bot' && conclusion === 'success') {
|
|
131
|
-
// Check the most recent run's jobs for the outcome
|
|
132
|
-
const runId = workflowRun.id;
|
|
133
|
-
const { data: jobs } = await github.rest.actions.listJobsForWorkflowRun({
|
|
134
|
-
owner, repo, run_id: runId,
|
|
135
|
-
});
|
|
136
|
-
const respondJob = jobs.jobs.find(j => j.name === 'respond');
|
|
137
|
-
if (respondJob) {
|
|
138
|
-
// Look through step names/outputs for action indicators
|
|
139
|
-
const steps = respondJob.steps || [];
|
|
140
|
-
const agenticStep = steps.find(s => s.name === 'Respond to discussion');
|
|
141
|
-
if (agenticStep && agenticStep.conclusion === 'success') {
|
|
142
|
-
core.info('Discussion bot completed. Dispatching maintain to pick up any new features.');
|
|
143
|
-
await github.rest.actions.createWorkflowDispatch({
|
|
144
|
-
owner, repo,
|
|
145
|
-
workflow_id: 'agent-flow-maintain.yml',
|
|
146
|
-
ref: 'main',
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
} catch (err) {
|
|
152
|
-
core.warning(`Discussion bot follow-through failed: ${err.message}`);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// ─── 4. Stale issues → dispatch review ────────────────────────────────
|
|
156
|
-
|
|
157
|
-
try {
|
|
158
|
-
const { data: issues } = await github.rest.issues.listForRepo({
|
|
159
|
-
owner, repo, state: 'open',
|
|
160
|
-
labels: 'automated',
|
|
161
|
-
sort: 'updated',
|
|
162
|
-
direction: 'asc',
|
|
163
|
-
per_page: 5,
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
const cutoff = new Date(Date.now() - staleDays * 24 * 60 * 60 * 1000);
|
|
167
|
-
const staleIssues = issues.filter(i => new Date(i.updated_at) < cutoff);
|
|
168
|
-
|
|
169
|
-
if (staleIssues.length > 0) {
|
|
170
|
-
core.info(`Found ${staleIssues.length} stale issue(s). Dispatching review.`);
|
|
171
|
-
await github.rest.actions.createWorkflowDispatch({
|
|
172
|
-
owner, repo,
|
|
173
|
-
workflow_id: 'agent-flow-review.yml',
|
|
174
|
-
ref: 'main',
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
} catch (err) {
|
|
178
|
-
core.warning(`Stale issue check failed: ${err.message}`);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// ─── 5. Stale conflicting PRs → remove automerge label ────────────────
|
|
136
|
+
// ─── 2. Stale conflicting PRs → remove automerge label ────────────────
|
|
182
137
|
|
|
183
138
|
try {
|
|
184
139
|
const { data: openPRs } = await github.rest.pulls.list({
|
|
@@ -196,7 +151,6 @@ jobs:
|
|
|
196
151
|
const isStale = new Date(pr.updated_at) < prCutoff;
|
|
197
152
|
if (!isStale) continue;
|
|
198
153
|
|
|
199
|
-
// Fetch full PR to get mergeable_state
|
|
200
154
|
const { data: fullPr } = await github.rest.pulls.get({
|
|
201
155
|
owner, repo, pull_number: pr.number,
|
|
202
156
|
});
|
|
@@ -217,3 +171,30 @@ jobs:
|
|
|
217
171
|
} catch (err) {
|
|
218
172
|
core.warning(`Stale PR check failed: ${err.message}`);
|
|
219
173
|
}
|
|
174
|
+
|
|
175
|
+
# ─── Proactive: LLM-driven strategic decisions ───────────────────────
|
|
176
|
+
supervise:
|
|
177
|
+
needs: params
|
|
178
|
+
if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
|
|
179
|
+
runs-on: ubuntu-latest
|
|
180
|
+
steps:
|
|
181
|
+
- uses: actions/checkout@v4
|
|
182
|
+
|
|
183
|
+
- uses: actions/setup-node@v4
|
|
184
|
+
with:
|
|
185
|
+
node-version: "24"
|
|
186
|
+
|
|
187
|
+
- name: Install agentic-step dependencies
|
|
188
|
+
working-directory: .github/agentic-lib/actions/agentic-step
|
|
189
|
+
run: npm ci
|
|
190
|
+
|
|
191
|
+
- name: Run supervisor
|
|
192
|
+
uses: ./.github/agentic-lib/actions/agentic-step
|
|
193
|
+
env:
|
|
194
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
195
|
+
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
|
|
196
|
+
with:
|
|
197
|
+
task: "supervise"
|
|
198
|
+
config: ${{ env.configPath }}
|
|
199
|
+
instructions: ".github/agentic-lib/agents/agent-supervisor.md"
|
|
200
|
+
model: ${{ needs.params.outputs.model }}
|