@xn-intenton-z2a/agentic-lib 7.1.101 → 7.1.102
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.
|
@@ -231,18 +231,26 @@ jobs:
|
|
|
231
231
|
const tomlPath = 'agentic-lib.toml';
|
|
232
232
|
if (!fs.existsSync(tomlPath)) return;
|
|
233
233
|
let toml = fs.readFileSync(tomlPath, 'utf8');
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
234
|
+
// Extract the [tuning] section, then replace within it.
|
|
235
|
+
// Previous regex [^\[]*? failed when comments contained '[' characters.
|
|
236
|
+
const tuningSectionRegex = /(\[tuning\])([\s\S]*?)(?=\n\[|$)/;
|
|
237
|
+
const tuningMatch = toml.match(tuningSectionRegex);
|
|
238
|
+
if (tuningMatch) {
|
|
239
|
+
let section = tuningMatch[0];
|
|
240
|
+
if (model) {
|
|
241
|
+
const updated = section.replace(/^(\s*model\s*=\s*)"[^"]*"/m, `$1"${model}"`);
|
|
242
|
+
if (updated !== section) {
|
|
243
|
+
toml = toml.replace(section, updated);
|
|
244
|
+
section = updated;
|
|
245
|
+
core.info(`Updated [tuning].model to: ${model}`);
|
|
246
|
+
}
|
|
239
247
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
248
|
+
if (profile) {
|
|
249
|
+
const updated = section.replace(/^(\s*profile\s*=\s*)"[^"]*"/m, `$1"${profile}"`);
|
|
250
|
+
if (updated !== section) {
|
|
251
|
+
toml = toml.replace(section, updated);
|
|
252
|
+
core.info(`Updated [tuning].profile to: ${profile}`);
|
|
253
|
+
}
|
|
246
254
|
}
|
|
247
255
|
}
|
|
248
256
|
fs.writeFileSync(tomlPath, toml);
|
|
@@ -40,6 +40,7 @@ on:
|
|
|
40
40
|
permissions:
|
|
41
41
|
contents: write
|
|
42
42
|
actions: write
|
|
43
|
+
issues: write
|
|
43
44
|
|
|
44
45
|
jobs:
|
|
45
46
|
test:
|
|
@@ -119,7 +120,7 @@ jobs:
|
|
|
119
120
|
if: >-
|
|
120
121
|
!cancelled()
|
|
121
122
|
&& github.ref == 'refs/heads/main'
|
|
122
|
-
&& (github.event_name == 'push' || github.event_name == 'schedule')
|
|
123
|
+
&& (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_call')
|
|
123
124
|
&& github.repository != 'xn-intenton-z2a/agentic-lib'
|
|
124
125
|
&& (needs.test.result == 'failure' || needs.behaviour.result == 'failure')
|
|
125
126
|
runs-on: ubuntu-latest
|
|
@@ -154,3 +155,92 @@ jobs:
|
|
|
154
155
|
--repo "${{ github.repository }}" \
|
|
155
156
|
-f mode=full \
|
|
156
157
|
-f message="Build broken on main: agentic-lib-test run ${{ github.run_id }} failed. Please fix."
|
|
158
|
+
|
|
159
|
+
# ─── Report instability: create/update GitHub issue on test failure ──
|
|
160
|
+
report-instability:
|
|
161
|
+
needs: [test, behaviour]
|
|
162
|
+
if: >-
|
|
163
|
+
!cancelled()
|
|
164
|
+
&& github.ref == 'refs/heads/main'
|
|
165
|
+
&& github.repository != 'xn-intenton-z2a/agentic-lib'
|
|
166
|
+
&& (needs.test.result == 'failure' || needs.behaviour.result == 'failure')
|
|
167
|
+
runs-on: ubuntu-latest
|
|
168
|
+
steps:
|
|
169
|
+
- name: Determine failure type
|
|
170
|
+
id: failure-type
|
|
171
|
+
run: |
|
|
172
|
+
UNIT="${{ needs.test.result }}"
|
|
173
|
+
BEHAVIOUR="${{ needs.behaviour.result }}"
|
|
174
|
+
if [ "$UNIT" = "failure" ] && [ "$BEHAVIOUR" = "failure" ]; then
|
|
175
|
+
echo "type=both" >> $GITHUB_OUTPUT
|
|
176
|
+
elif [ "$UNIT" = "failure" ]; then
|
|
177
|
+
echo "type=unit" >> $GITHUB_OUTPUT
|
|
178
|
+
else
|
|
179
|
+
echo "type=behaviour" >> $GITHUB_OUTPUT
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
- name: Collect failure logs
|
|
183
|
+
id: logs
|
|
184
|
+
env:
|
|
185
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
186
|
+
run: |
|
|
187
|
+
RUN_ID="${{ github.run_id }}"
|
|
188
|
+
# Get failed job logs via gh CLI
|
|
189
|
+
gh run view "$RUN_ID" --repo "${{ github.repository }}" --log-failed > /tmp/failed-logs.txt 2>&1 || true
|
|
190
|
+
# Trim to reasonable size (keep last 400 lines — generous context)
|
|
191
|
+
tail -400 /tmp/failed-logs.txt > /tmp/trimmed-logs.txt
|
|
192
|
+
|
|
193
|
+
- name: Create or update instability issue
|
|
194
|
+
uses: actions/github-script@v8
|
|
195
|
+
with:
|
|
196
|
+
script: |
|
|
197
|
+
const fs = require('fs');
|
|
198
|
+
const failureType = '${{ steps.failure-type.outputs.type }}';
|
|
199
|
+
const runId = '${{ github.run_id }}';
|
|
200
|
+
const runUrl = `https://github.com/${{ github.repository }}/actions/runs/${runId}`;
|
|
201
|
+
const logs = fs.readFileSync('/tmp/trimmed-logs.txt', 'utf8').slice(0, 60000);
|
|
202
|
+
|
|
203
|
+
const title = `instability: ${failureType} test failure on main`;
|
|
204
|
+
const body = [
|
|
205
|
+
`## Test Failure Report`,
|
|
206
|
+
``,
|
|
207
|
+
`**Type**: ${failureType}`,
|
|
208
|
+
`**Run**: [${runId}](${runUrl})`,
|
|
209
|
+
`**Trigger**: ${context.eventName}`,
|
|
210
|
+
`**Time**: ${new Date().toISOString()}`,
|
|
211
|
+
``,
|
|
212
|
+
`## Failure Logs`,
|
|
213
|
+
``,
|
|
214
|
+
'```',
|
|
215
|
+
logs,
|
|
216
|
+
'```',
|
|
217
|
+
].join('\n');
|
|
218
|
+
|
|
219
|
+
// Check for existing open instability issue of the same failure type
|
|
220
|
+
const { data: existing } = await github.rest.issues.listForRepo({
|
|
221
|
+
...context.repo, state: 'open', labels: 'instability', per_page: 10,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const match = existing.find(i => i.title.includes(failureType));
|
|
225
|
+
if (match) {
|
|
226
|
+
// Add a comment with the new failure logs instead of creating a duplicate
|
|
227
|
+
await github.rest.issues.createComment({
|
|
228
|
+
...context.repo, issue_number: match.number,
|
|
229
|
+
body: `## Recurrence — run [${runId}](${runUrl})\n\n**Trigger**: ${context.eventName}\n**Time**: ${new Date().toISOString()}\n\n` + '```\n' + logs.slice(0, 30000) + '\n```',
|
|
230
|
+
});
|
|
231
|
+
core.info(`Updated existing instability issue #${match.number}`);
|
|
232
|
+
} else {
|
|
233
|
+
// Ensure instability label exists
|
|
234
|
+
try {
|
|
235
|
+
await github.rest.issues.createLabel({
|
|
236
|
+
...context.repo, name: 'instability',
|
|
237
|
+
color: 'e11d48', description: 'Automated: test instability on main',
|
|
238
|
+
});
|
|
239
|
+
} catch (e) { /* label already exists */ }
|
|
240
|
+
|
|
241
|
+
const { data: issue } = await github.rest.issues.create({
|
|
242
|
+
...context.repo, title, body,
|
|
243
|
+
labels: ['instability', 'ready', 'automated'],
|
|
244
|
+
});
|
|
245
|
+
core.info(`Created instability issue #${issue.number}`);
|
|
246
|
+
}
|
|
@@ -319,6 +319,16 @@ jobs:
|
|
|
319
319
|
labels: i.labels.map(l => l.name),
|
|
320
320
|
}));
|
|
321
321
|
|
|
322
|
+
// W7: Check for open instability issues (mechanical priority override)
|
|
323
|
+
const { data: instabilityIssues } = await github.rest.issues.listForRepo({
|
|
324
|
+
owner, repo, state: 'open', labels: 'instability',
|
|
325
|
+
sort: 'created', direction: 'asc', per_page: 10,
|
|
326
|
+
});
|
|
327
|
+
const instabilityNumbers = instabilityIssues.map(i => i.number);
|
|
328
|
+
if (instabilityNumbers.length > 0) {
|
|
329
|
+
core.info(`Found ${instabilityNumbers.length} instability issue(s): ${instabilityNumbers.join(', ')}`);
|
|
330
|
+
}
|
|
331
|
+
|
|
322
332
|
// Open PRs
|
|
323
333
|
const { data: prs } = await github.rest.pulls.list({
|
|
324
334
|
owner, repo, state: 'open', per_page: 10,
|
|
@@ -419,6 +429,7 @@ jobs:
|
|
|
419
429
|
|
|
420
430
|
const telemetry = {
|
|
421
431
|
issues: issuesSummary,
|
|
432
|
+
instabilityIssues: instabilityNumbers,
|
|
422
433
|
prs: prsSummary,
|
|
423
434
|
recentRuns: runsSummary,
|
|
424
435
|
mission: mission.slice(0, 500),
|
|
@@ -962,6 +973,17 @@ jobs:
|
|
|
962
973
|
core.setOutput('issue-number', specificIssue);
|
|
963
974
|
return;
|
|
964
975
|
}
|
|
976
|
+
// W7: Mechanical instability override — prioritise instability issues
|
|
977
|
+
// before any other ready issues, regardless of supervisor decisions
|
|
978
|
+
const { data: instabilityIssues } = await github.rest.issues.listForRepo({
|
|
979
|
+
...context.repo, state: 'open', labels: 'instability',
|
|
980
|
+
sort: 'created', direction: 'asc', per_page: 1,
|
|
981
|
+
});
|
|
982
|
+
if (instabilityIssues.length > 0) {
|
|
983
|
+
core.setOutput('issue-number', String(instabilityIssues[0].number));
|
|
984
|
+
core.info(`Instability override: targeting issue #${instabilityIssues[0].number}: ${instabilityIssues[0].title}`);
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
965
987
|
// Find oldest open issue with 'ready' label
|
|
966
988
|
const { data: issues } = await github.rest.issues.listForRepo({
|
|
967
989
|
...context.repo, state: 'open', labels: 'ready',
|
|
@@ -1024,15 +1046,33 @@ jobs:
|
|
|
1024
1046
|
echo "tests-passed=true" >> $GITHUB_OUTPUT
|
|
1025
1047
|
echo "All tests passed"
|
|
1026
1048
|
|
|
1049
|
+
- name: Run behaviour tests before committing
|
|
1050
|
+
id: pre-commit-behaviour-test
|
|
1051
|
+
if: steps.issue.outputs.issue-number != '' && steps.pre-commit-test.outputs.tests-passed == 'true' && (hashFiles('playwright.config.js') != '' || hashFiles('playwright.config.ts') != '')
|
|
1052
|
+
run: |
|
|
1053
|
+
npx playwright install --with-deps chromium 2>/dev/null || true
|
|
1054
|
+
npm run build:web 2>/dev/null || true
|
|
1055
|
+
set +e
|
|
1056
|
+
npm run --if-present test:behaviour 2>&1 | tail -30
|
|
1057
|
+
EXIT_CODE=$?
|
|
1058
|
+
set -e
|
|
1059
|
+
if [ $EXIT_CODE -ne 0 ]; then
|
|
1060
|
+
echo "tests-passed=false" >> $GITHUB_OUTPUT
|
|
1061
|
+
echo "WARNING: Behaviour tests failed (exit $EXIT_CODE) — skipping commit and PR"
|
|
1062
|
+
exit 0
|
|
1063
|
+
fi
|
|
1064
|
+
echo "tests-passed=true" >> $GITHUB_OUTPUT
|
|
1065
|
+
echo "Behaviour tests passed"
|
|
1066
|
+
|
|
1027
1067
|
- name: Commit and push
|
|
1028
|
-
if: github.repository != 'xn-intenton-z2a/agentic-lib' && steps.issue.outputs.issue-number != '' && needs.params.outputs.dry-run != 'true' && steps.pre-commit-test.outputs.tests-passed == 'true'
|
|
1068
|
+
if: github.repository != 'xn-intenton-z2a/agentic-lib' && steps.issue.outputs.issue-number != '' && needs.params.outputs.dry-run != 'true' && steps.pre-commit-test.outputs.tests-passed == 'true' && steps.pre-commit-behaviour-test.outputs.tests-passed != 'false'
|
|
1029
1069
|
uses: ./.github/agentic-lib/actions/commit-if-changed
|
|
1030
1070
|
with:
|
|
1031
1071
|
commit-message: "agentic-step: transform issue #${{ steps.issue.outputs.issue-number }}"
|
|
1032
1072
|
push-ref: ${{ steps.branch.outputs.branchName }}
|
|
1033
1073
|
|
|
1034
1074
|
- name: Create PR and attempt merge
|
|
1035
|
-
if: github.repository != 'xn-intenton-z2a/agentic-lib' && steps.issue.outputs.issue-number != '' && needs.params.outputs.dry-run != 'true' && steps.pre-commit-test.outputs.tests-passed == 'true'
|
|
1075
|
+
if: github.repository != 'xn-intenton-z2a/agentic-lib' && steps.issue.outputs.issue-number != '' && needs.params.outputs.dry-run != 'true' && steps.pre-commit-test.outputs.tests-passed == 'true' && steps.pre-commit-behaviour-test.outputs.tests-passed != 'false'
|
|
1036
1076
|
uses: actions/github-script@v8
|
|
1037
1077
|
with:
|
|
1038
1078
|
script: |
|
package/package.json
CHANGED
|
@@ -106,6 +106,9 @@ Check the Recent Activity log and Recently Closed Issues for patterns:
|
|
|
106
106
|
- If the last 3+ cycles show the pattern: create issue → review closes as resolved → no transform → create identical issue, the pipeline is stuck. Check if acceptance criteria are truly met (use `mission-complete`) or if review is wrong (create a more specific issue). If neither works, use `mission-failed`.
|
|
107
107
|
- Look for `transform: nop` or `transform: transformed` patterns in the activity log to distinguish productive iterations from idle ones.
|
|
108
108
|
|
|
109
|
+
**Dedup deadlock recovery:**
|
|
110
|
+
- If your issue creation is blocked by the dedup guard (similar to a recently closed issue), do NOT retry the same issue title. Instead, create an issue with a different scope — e.g. "fix: resolve failing tests on main" or "fix: align code and test expectations" — with both the `instability` and `ready` labels. This sidesteps the dedup guard and directs the dev job to the actual problem. The `instability` label gives the issue mechanical priority over other `ready` issues.
|
|
111
|
+
|
|
109
112
|
## Discussions Awareness
|
|
110
113
|
|
|
111
114
|
Check the Recent Activity log for discussion bot referrals (lines containing `discussion-request-supervisor`). These indicate a user asked the bot something that requires supervisor action. **Prioritise responding to these referrals.**
|