@xn-intenton-z2a/agentic-lib 7.4.13 → 7.4.14
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/.github/workflows/agentic-lib-workflow.yml +31 -51
- package/agentic-lib.toml +2 -2
- package/package.json +1 -1
- package/src/actions/agentic-step/index.js +19 -24
- package/src/actions/agentic-step/logging.js +2 -12
- package/src/actions/agentic-step/tasks/direct.js +11 -4
- package/src/actions/agentic-step/tasks/supervise.js +14 -6
- package/src/actions/commit-if-changed/action.yml +2 -1
- package/src/copilot/config.js +1 -1
- package/src/copilot/guards.js +11 -5
- package/src/seeds/zero-package.json +1 -1
|
@@ -178,16 +178,16 @@ jobs:
|
|
|
178
178
|
echo "dry-run=${DRY_RUN}" >> $GITHUB_OUTPUT
|
|
179
179
|
CONFIG='${{ inputs.config-path }}'
|
|
180
180
|
echo "config-path=${CONFIG:-${{ env.configPath }}}" >> $GITHUB_OUTPUT
|
|
181
|
-
# Bot config: log
|
|
182
|
-
|
|
181
|
+
# Bot config: log prefix, log branch, screenshot file
|
|
182
|
+
LOG_PREFIX=""
|
|
183
183
|
LOG_BRANCH=""
|
|
184
184
|
SCREENSHOT=""
|
|
185
185
|
if [ -f "${{ env.configPath }}" ]; then
|
|
186
|
-
|
|
186
|
+
LOG_PREFIX=$(grep '^\s*log-prefix' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/' || true)
|
|
187
187
|
LOG_BRANCH=$(grep '^\s*log-branch' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/' || true)
|
|
188
188
|
SCREENSHOT=$(grep '^\s*screenshot-file' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/' || true)
|
|
189
189
|
fi
|
|
190
|
-
echo "log-
|
|
190
|
+
echo "log-prefix=${LOG_PREFIX:-agent-log-}" >> $GITHUB_OUTPUT
|
|
191
191
|
echo "log-branch=${LOG_BRANCH:-agentic-lib-logs}" >> $GITHUB_OUTPUT
|
|
192
192
|
echo "screenshot-file=${SCREENSHOT:-SCREENSHOT_INDEX.png}" >> $GITHUB_OUTPUT
|
|
193
193
|
outputs:
|
|
@@ -200,7 +200,7 @@ jobs:
|
|
|
200
200
|
pr-number: ${{ steps.normalise.outputs.pr-number }}
|
|
201
201
|
dry-run: ${{ steps.normalise.outputs.dry-run }}
|
|
202
202
|
config-path: ${{ steps.normalise.outputs.config-path }}
|
|
203
|
-
log-
|
|
203
|
+
log-prefix: ${{ steps.normalise.outputs.log-prefix }}
|
|
204
204
|
log-branch: ${{ steps.normalise.outputs.log-branch }}
|
|
205
205
|
screenshot-file: ${{ steps.normalise.outputs.screenshot-file }}
|
|
206
206
|
|
|
@@ -373,7 +373,6 @@ jobs:
|
|
|
373
373
|
id: gather
|
|
374
374
|
uses: actions/github-script@v8
|
|
375
375
|
env:
|
|
376
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
377
376
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
378
377
|
with:
|
|
379
378
|
script: |
|
|
@@ -478,32 +477,28 @@ jobs:
|
|
|
478
477
|
const missionComplete = fs.existsSync('MISSION_COMPLETE.md');
|
|
479
478
|
const missionFailed = fs.existsSync('MISSION_FAILED.md');
|
|
480
479
|
|
|
481
|
-
// Activity log stats (
|
|
482
|
-
const logFile = process.env.LOG_FILE || 'intentïon.md';
|
|
480
|
+
// Activity log stats (from agent-log files on log branch)
|
|
483
481
|
const logBranch = process.env.LOG_BRANCH || 'agentic-lib-logs';
|
|
484
482
|
let activityStats = null;
|
|
485
483
|
try {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
484
|
+
const { data: tree } = await github.rest.git.getTree({
|
|
485
|
+
owner, repo, tree_sha: logBranch, recursive: false,
|
|
486
|
+
});
|
|
487
|
+
const logFiles = tree.tree
|
|
488
|
+
.filter(f => f.path.startsWith('agent-log-') && f.path.endsWith('.md'))
|
|
489
|
+
.sort((a, b) => a.path.localeCompare(b.path));
|
|
490
|
+
activityStats = { entries: logFiles.length, totalTransformCost: 0 };
|
|
491
|
+
// Sum costs from the most recent 10 log files
|
|
492
|
+
const recent = logFiles.slice(-10);
|
|
493
|
+
for (const lf of recent) {
|
|
489
494
|
try {
|
|
490
495
|
const { data } = await github.rest.repos.getContent({
|
|
491
|
-
owner, repo, path: lf, ref: logBranch,
|
|
496
|
+
owner, repo, path: lf.path, ref: logBranch,
|
|
492
497
|
});
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
// Fall back to local file
|
|
498
|
-
if (!log) {
|
|
499
|
-
const logPath = fs.existsSync(logFile) ? logFile : (fs.existsSync('intention.md') ? 'intention.md' : null);
|
|
500
|
-
if (logPath) log = fs.readFileSync(logPath, 'utf8');
|
|
501
|
-
}
|
|
502
|
-
if (log) {
|
|
503
|
-
const entries = log.split('\n## ').length - 1;
|
|
504
|
-
const costMatches = [...log.matchAll(/\*\*agentic-lib transformation cost:\*\* (\d+)/g)];
|
|
505
|
-
const totalCost = costMatches.reduce((sum, m) => sum + parseInt(m[1], 10), 0);
|
|
506
|
-
activityStats = { entries, totalTransformCost: totalCost };
|
|
498
|
+
const content = Buffer.from(data.content, 'base64').toString('utf8');
|
|
499
|
+
const costMatches = [...content.matchAll(/\*\*agentic-lib transformation cost:\*\* (\d+)/g)];
|
|
500
|
+
activityStats.totalTransformCost += costMatches.reduce((sum, m) => sum + parseInt(m[1], 10), 0);
|
|
501
|
+
} catch { /* skip unreadable files */ }
|
|
507
502
|
}
|
|
508
503
|
} catch (e) {}
|
|
509
504
|
|
|
@@ -592,13 +587,10 @@ jobs:
|
|
|
592
587
|
|
|
593
588
|
- name: Fetch log and screenshot from log branch
|
|
594
589
|
env:
|
|
595
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
596
590
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
597
591
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
598
592
|
run: |
|
|
599
|
-
|
|
600
|
-
git show "origin/${LOG_BRANCH}:${f}" > "$f" 2>/dev/null || true
|
|
601
|
-
done
|
|
593
|
+
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
602
594
|
|
|
603
595
|
- name: Check mission-complete signal
|
|
604
596
|
id: mission-check
|
|
@@ -708,7 +700,7 @@ jobs:
|
|
|
708
700
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
709
701
|
env:
|
|
710
702
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
711
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh
|
|
703
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
712
704
|
|
|
713
705
|
# ─── Implementation Review: traces mission elements through code/tests/website ──
|
|
714
706
|
implementation-review:
|
|
@@ -729,13 +721,10 @@ jobs:
|
|
|
729
721
|
|
|
730
722
|
- name: Fetch log and agent logs from log branch
|
|
731
723
|
env:
|
|
732
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
733
724
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
734
725
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
735
726
|
run: |
|
|
736
|
-
|
|
737
|
-
git show "origin/${LOG_BRANCH}:${f}" > "$f" 2>/dev/null || true
|
|
738
|
-
done
|
|
727
|
+
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
739
728
|
mkdir -p .agent-logs
|
|
740
729
|
git fetch origin "${LOG_BRANCH}" 2>/dev/null || true
|
|
741
730
|
for f in $(git ls-tree --name-only "origin/${LOG_BRANCH}" 2>/dev/null | grep '^agent-log-' || true); do
|
|
@@ -776,7 +765,7 @@ jobs:
|
|
|
776
765
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
777
766
|
env:
|
|
778
767
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
779
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh
|
|
768
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
780
769
|
|
|
781
770
|
# ─── Director: LLM evaluates mission status (complete/failed/in-progress) ──
|
|
782
771
|
director:
|
|
@@ -797,13 +786,10 @@ jobs:
|
|
|
797
786
|
|
|
798
787
|
- name: Fetch log and screenshot from log branch
|
|
799
788
|
env:
|
|
800
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
801
789
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
802
790
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
803
791
|
run: |
|
|
804
|
-
|
|
805
|
-
git show "origin/${LOG_BRANCH}:${f}" > "$f" 2>/dev/null || true
|
|
806
|
-
done
|
|
792
|
+
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
807
793
|
|
|
808
794
|
- uses: actions/setup-node@v6
|
|
809
795
|
with:
|
|
@@ -840,7 +826,7 @@ jobs:
|
|
|
840
826
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
841
827
|
env:
|
|
842
828
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
843
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh
|
|
829
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
844
830
|
|
|
845
831
|
# ─── Supervisor: LLM decides what to do (after director evaluates) ──
|
|
846
832
|
supervisor:
|
|
@@ -860,13 +846,10 @@ jobs:
|
|
|
860
846
|
|
|
861
847
|
- name: Fetch log and screenshot from log branch
|
|
862
848
|
env:
|
|
863
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
864
849
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
865
850
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
866
851
|
run: |
|
|
867
|
-
|
|
868
|
-
git show "origin/${LOG_BRANCH}:${f}" > "$f" 2>/dev/null || true
|
|
869
|
-
done
|
|
852
|
+
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
870
853
|
|
|
871
854
|
- uses: actions/setup-node@v6
|
|
872
855
|
with:
|
|
@@ -903,7 +886,7 @@ jobs:
|
|
|
903
886
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
904
887
|
env:
|
|
905
888
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
906
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh
|
|
889
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
907
890
|
|
|
908
891
|
# ─── Fix stuck PRs with failing checks ─────────────────────────────
|
|
909
892
|
fix-stuck:
|
|
@@ -1299,13 +1282,10 @@ jobs:
|
|
|
1299
1282
|
|
|
1300
1283
|
- name: Fetch log and screenshot from log branch
|
|
1301
1284
|
env:
|
|
1302
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
1303
1285
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
1304
1286
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
1305
1287
|
run: |
|
|
1306
|
-
|
|
1307
|
-
git show "origin/${LOG_BRANCH}:${f}" > "$f" 2>/dev/null || true
|
|
1308
|
-
done
|
|
1288
|
+
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
1309
1289
|
|
|
1310
1290
|
- uses: actions/setup-node@v6
|
|
1311
1291
|
with:
|
|
@@ -1475,7 +1455,7 @@ jobs:
|
|
|
1475
1455
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
1476
1456
|
env:
|
|
1477
1457
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
1478
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh
|
|
1458
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
1479
1459
|
|
|
1480
1460
|
- name: Create PR and attempt merge
|
|
1481
1461
|
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'
|
package/agentic-lib.toml
CHANGED
|
@@ -114,6 +114,6 @@ min-dedicated-tests = 0 # minimum test files that import from src/lib
|
|
|
114
114
|
max-source-todos = 0 # max TODO comments allowed in ./src (0 = none)
|
|
115
115
|
|
|
116
116
|
[bot]
|
|
117
|
-
log-
|
|
118
|
-
log-branch = "agentic-lib-logs"
|
|
117
|
+
log-prefix = "tmp/agent-log-" #@dist "agent-log-"
|
|
118
|
+
log-branch = "main" #@dist "agentic-lib-logs"
|
|
119
119
|
screenshot-file = "SCREENSHOT_INDEX.png"
|
package/package.json
CHANGED
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
import * as core from "@actions/core";
|
|
9
9
|
import * as github from "@actions/github";
|
|
10
10
|
import { loadConfig, getWritablePaths } from "./config-loader.js";
|
|
11
|
-
import {
|
|
12
|
-
import { readFileSync, existsSync } from "fs";
|
|
11
|
+
import { generateClosingNotes, writeAgentLog } from "./logging.js";
|
|
12
|
+
import { readFileSync, existsSync, readdirSync } from "fs";
|
|
13
13
|
import {
|
|
14
14
|
buildMissionMetrics, buildMissionReadiness,
|
|
15
|
-
computeTransformationCost,
|
|
15
|
+
computeTransformationCost, buildLimitsStatus,
|
|
16
16
|
} from "../../copilot/telemetry.js";
|
|
17
17
|
import {
|
|
18
18
|
checkInstabilityLabel, countDedicatedTests,
|
|
@@ -63,9 +63,22 @@ async function run() {
|
|
|
63
63
|
if (!handler) throw new Error(`Unknown task: ${task}. Available: ${Object.keys(TASKS).join(", ")}`);
|
|
64
64
|
|
|
65
65
|
// Resolve log and screenshot paths (fetched from agentic-lib-logs branch by workflow)
|
|
66
|
-
const
|
|
66
|
+
const logPrefix = config.intentionBot?.logPrefix || "agent-log-";
|
|
67
67
|
const screenshotFile = config.intentionBot?.screenshotFile || "SCREENSHOT_INDEX.png";
|
|
68
|
-
|
|
68
|
+
// Find the most recent agent-log file matching the prefix for LLM context
|
|
69
|
+
const logDir = logPrefix.includes("/") ? logPrefix.substring(0, logPrefix.lastIndexOf("/")) : ".";
|
|
70
|
+
const logBase = logPrefix.includes("/") ? logPrefix.substring(logPrefix.lastIndexOf("/") + 1) : logPrefix;
|
|
71
|
+
let logFilePath = null;
|
|
72
|
+
try {
|
|
73
|
+
const logFiles = readdirSync(logDir)
|
|
74
|
+
.filter(f => f.startsWith(logBase) && f.endsWith(".md"))
|
|
75
|
+
.sort();
|
|
76
|
+
if (logFiles.length > 0) {
|
|
77
|
+
const newest = logFiles[logFiles.length - 1];
|
|
78
|
+
const candidate = logDir === "." ? newest : `${logDir}/${newest}`;
|
|
79
|
+
if (existsSync(candidate)) logFilePath = candidate;
|
|
80
|
+
}
|
|
81
|
+
} catch { /* no log files yet */ }
|
|
69
82
|
const screenshotFilePath = existsSync(screenshotFile) ? screenshotFile : null;
|
|
70
83
|
|
|
71
84
|
const context = {
|
|
@@ -96,8 +109,7 @@ async function run() {
|
|
|
96
109
|
&& await checkInstabilityLabel(context, issueNumber);
|
|
97
110
|
if (isInstability) core.info(`Issue #${issueNumber} has instability label — does not count against budget`);
|
|
98
111
|
const transformationCost = computeTransformationCost(task, result.outcome, isInstability);
|
|
99
|
-
const
|
|
100
|
-
const cumulativeCost = readCumulativeCost(intentionFilepath) + transformationCost;
|
|
112
|
+
const cumulativeCost = transformationCost;
|
|
101
113
|
|
|
102
114
|
if (result.dedicatedTestCount == null || result.dedicatedTestCount === 0) {
|
|
103
115
|
try {
|
|
@@ -123,23 +135,6 @@ async function run() {
|
|
|
123
135
|
|
|
124
136
|
const missionMetrics = buildMissionMetrics(config, result, limitsStatus, cumulativeCost, featureIssueCount, maintenanceIssueCount);
|
|
125
137
|
|
|
126
|
-
if (intentionFilepath) {
|
|
127
|
-
logActivity({
|
|
128
|
-
filepath: intentionFilepath, task, outcome: result.outcome || "completed",
|
|
129
|
-
issueNumber, prNumber: result.prNumber, commitUrl: result.commitUrl,
|
|
130
|
-
tokensUsed: result.tokensUsed, inputTokens: result.inputTokens,
|
|
131
|
-
outputTokens: result.outputTokens, cost: result.cost, durationMs,
|
|
132
|
-
model: result.model || model, details: result.details,
|
|
133
|
-
workflowUrl: `${process.env.GITHUB_SERVER_URL}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`,
|
|
134
|
-
profile: config.tuning?.profileName || "unknown",
|
|
135
|
-
changes: result.changes, contextNotes: result.contextNotes,
|
|
136
|
-
limitsStatus, promptBudget: result.promptBudget,
|
|
137
|
-
missionReadiness: buildMissionReadiness(missionMetrics),
|
|
138
|
-
missionMetrics, closingNotes: result.closingNotes || generateClosingNotes(limitsStatus),
|
|
139
|
-
transformationCost, narrative: result.narrative,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
138
|
// Write standalone agent log file (pushed to agentic-lib-logs branch by workflow)
|
|
144
139
|
try {
|
|
145
140
|
const agentLogFile = writeAgentLog({
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
// Appends structured entries to the intentïon.md activity log,
|
|
6
6
|
// including commit URLs and safety-check outcomes.
|
|
7
7
|
|
|
8
|
-
import { writeFileSync, readFileSync, appendFileSync, existsSync, mkdirSync,
|
|
9
|
-
import { dirname
|
|
8
|
+
import { writeFileSync, readFileSync, appendFileSync, existsSync, mkdirSync, readdirSync } from "fs";
|
|
9
|
+
import { dirname } from "path";
|
|
10
10
|
import { join } from "path";
|
|
11
11
|
import * as core from "@actions/core";
|
|
12
12
|
|
|
@@ -160,16 +160,6 @@ export function logActivity({
|
|
|
160
160
|
writeFileSync(filepath, `# intentïon Activity Log\n${entry}`);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
// Write ASCII fallback copy (intention.md) for systems that can't handle UTF-8 filenames
|
|
164
|
-
const name = basename(filepath);
|
|
165
|
-
if (name !== "intention.md" && name.includes("intenti")) {
|
|
166
|
-
const fallbackPath = join(dirname(filepath), "intention.md");
|
|
167
|
-
try {
|
|
168
|
-
copyFileSync(filepath, fallbackPath);
|
|
169
|
-
} catch {
|
|
170
|
-
// Best-effort — don't fail the log if the copy fails
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
163
|
}
|
|
174
164
|
|
|
175
165
|
/**
|
|
@@ -261,10 +261,17 @@ export async function direct(context) {
|
|
|
261
261
|
|
|
262
262
|
// --- Gather context (similar to supervisor but focused on metrics) ---
|
|
263
263
|
const mission = readOptionalFile(config.paths.mission.path);
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
264
|
+
// Read cumulative cost from agent-log files
|
|
265
|
+
let cumulativeTransformationCost = 0;
|
|
266
|
+
try {
|
|
267
|
+
const { readdirSync } = await import("fs");
|
|
268
|
+
const logFiles = readdirSync(".").filter(f => f.startsWith("agent-log-") && f.endsWith(".md")).sort();
|
|
269
|
+
for (const f of logFiles) {
|
|
270
|
+
const content = readOptionalFile(f);
|
|
271
|
+
const costMatches = content.matchAll(/\*\*agentic-lib transformation cost:\*\* (\d+)/g);
|
|
272
|
+
cumulativeTransformationCost += [...costMatches].reduce((sum, m) => sum + parseInt(m[1], 10), 0);
|
|
273
|
+
}
|
|
274
|
+
} catch { /* no agent-log files yet */ }
|
|
268
275
|
|
|
269
276
|
const missionComplete = existsSync("MISSION_COMPLETE.md");
|
|
270
277
|
const missionFailed = existsSync("MISSION_FAILED.md");
|
|
@@ -106,12 +106,20 @@ async function postDirectReply(octokit, repo, nodeId, body) {
|
|
|
106
106
|
|
|
107
107
|
async function gatherContext(octokit, repo, config, t) {
|
|
108
108
|
const mission = readOptionalFile(config.paths.mission.path);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
// Read recent activity from agent-log files
|
|
110
|
+
let recentActivity = "";
|
|
111
|
+
let cumulativeTransformationCost = 0;
|
|
112
|
+
try {
|
|
113
|
+
const { readdirSync } = await import("fs");
|
|
114
|
+
const logFiles = readdirSync(".").filter(f => f.startsWith("agent-log-") && f.endsWith(".md")).sort();
|
|
115
|
+
const recent = logFiles.slice(-5);
|
|
116
|
+
recentActivity = recent.map(f => readOptionalFile(f)).join("\n---\n").split("\n").slice(-40).join("\n");
|
|
117
|
+
for (const f of logFiles) {
|
|
118
|
+
const content = readOptionalFile(f);
|
|
119
|
+
const costMatches = content.matchAll(/\*\*agentic-lib transformation cost:\*\* (\d+)/g);
|
|
120
|
+
cumulativeTransformationCost += [...costMatches].reduce((sum, m) => sum + parseInt(m[1], 10), 0);
|
|
121
|
+
}
|
|
122
|
+
} catch { /* no agent-log files yet */ }
|
|
115
123
|
|
|
116
124
|
// Check mission-complete signal
|
|
117
125
|
const missionComplete = existsSync("MISSION_COMPLETE.md");
|
|
@@ -29,7 +29,8 @@ runs:
|
|
|
29
29
|
# Unstage workflow files — GITHUB_TOKEN cannot push workflow changes
|
|
30
30
|
git reset HEAD -- '.github/workflows/' 2>/dev/null || true
|
|
31
31
|
# Unstage log/screenshot files — these live on the agentic-lib-logs branch
|
|
32
|
-
git reset HEAD -- 'intentïon.md' '
|
|
32
|
+
git reset HEAD -- 'intentïon.md' 'SCREENSHOT_INDEX.png' 2>/dev/null || true
|
|
33
|
+
git reset HEAD -- agent-log-*.md 2>/dev/null || true
|
|
33
34
|
if git diff --cached --quiet; then
|
|
34
35
|
echo "No changes to commit"
|
|
35
36
|
fi
|
package/src/copilot/config.js
CHANGED
|
@@ -261,7 +261,7 @@ export function loadConfig(configPath) {
|
|
|
261
261
|
transformationBudget: tuning.transformationBudget,
|
|
262
262
|
seeding: toml.seeding || {},
|
|
263
263
|
intentionBot: {
|
|
264
|
-
|
|
264
|
+
logPrefix: bot["log-prefix"] || "agent-log-",
|
|
265
265
|
logBranch: bot["log-branch"] || "agentic-lib-logs",
|
|
266
266
|
screenshotFile: bot["screenshot-file"] || "SCREENSHOT_INDEX.png",
|
|
267
267
|
},
|
package/src/copilot/guards.js
CHANGED
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
// (transform.js, fix-code.js, maintain-features.js, maintain-library.js)
|
|
7
7
|
// before Phase 4 convergence replaced them with unconditional runCopilotSession().
|
|
8
8
|
|
|
9
|
-
import { existsSync } from "fs";
|
|
9
|
+
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
10
10
|
import { resolve } from "path";
|
|
11
11
|
import { execSync } from "child_process";
|
|
12
|
-
import { readCumulativeCost } from "./telemetry.js";
|
|
13
12
|
|
|
14
13
|
/**
|
|
15
14
|
* Task-to-guard mapping. Each task has an ordered list of guards.
|
|
@@ -71,9 +70,16 @@ export function checkGuards(taskName, config, workspacePath, { logger } = {}) {
|
|
|
71
70
|
case "budget-exhausted": {
|
|
72
71
|
const budget = config.transformationBudget || 0;
|
|
73
72
|
if (budget > 0) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
// Read cumulative cost from agent-log files in workspace
|
|
74
|
+
let cumulativeCost = 0;
|
|
75
|
+
try {
|
|
76
|
+
const logFiles = readdirSync(wsPath).filter(f => f.startsWith("agent-log-") && f.endsWith(".md"));
|
|
77
|
+
for (const f of logFiles) {
|
|
78
|
+
const content = readFileSync(resolve(wsPath, f), "utf8");
|
|
79
|
+
const costMatches = content.matchAll(/\*\*agentic-lib transformation cost:\*\* (\d+)/g);
|
|
80
|
+
cumulativeCost += [...costMatches].reduce((sum, m) => sum + parseInt(m[1], 10), 0);
|
|
81
|
+
}
|
|
82
|
+
} catch { /* no agent-log files */ }
|
|
77
83
|
if (cumulativeCost >= budget) {
|
|
78
84
|
return { skip: true, reason: `Transformation budget exhausted (${cumulativeCost}/${budget})` };
|
|
79
85
|
}
|