@sebastianandreasson/pi-autonomous-agents 0.5.2 → 0.7.0
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/README.md +28 -9
- package/SETUP.md +6 -0
- package/docs/PI_SUPERVISOR.md +16 -65
- package/package.json +6 -3
- package/pi.config.json +1 -2
- package/src/cli.mjs +1 -1
- package/src/index.mjs +3 -0
- package/src/pi-client.mjs +68 -119
- package/src/pi-config.mjs +3 -3
- package/src/pi-sdk-turn.mjs +654 -0
- package/src/pi-supervisor.mjs +73 -0
- package/src/pi-telemetry.mjs +4 -0
- package/src/pi-visualizer-server.mjs +522 -0
- package/src/pi-visualizer-shared.mjs +219 -0
- package/src/pi-visualizer.mjs +16 -0
- package/templates/pi.config.example.json +1 -2
- package/src/pi-rpc-adapter.mjs +0 -668
package/src/pi-supervisor.mjs
CHANGED
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
shouldPersistLatestTesterFeedback,
|
|
50
50
|
} from './pi-flow.mjs'
|
|
51
51
|
import { runStartupPreflight } from './pi-preflight.mjs'
|
|
52
|
+
import { startVisualizerServer } from './pi-visualizer-server.mjs'
|
|
52
53
|
|
|
53
54
|
let stopRequested = false
|
|
54
55
|
let shutdownEscalationTimer = null
|
|
@@ -337,6 +338,15 @@ async function runAgentInvocation({
|
|
|
337
338
|
sessionId,
|
|
338
339
|
sessionFile,
|
|
339
340
|
}) {
|
|
341
|
+
await updateRunOwnership(config, {
|
|
342
|
+
status: 'agent_running',
|
|
343
|
+
iteration,
|
|
344
|
+
phase,
|
|
345
|
+
activeKind: kind,
|
|
346
|
+
activeRole: role,
|
|
347
|
+
activeReason: reason,
|
|
348
|
+
})
|
|
349
|
+
|
|
340
350
|
const beforeSnapshot = getRepoSnapshot(config.cwd)
|
|
341
351
|
const resolvedModel = resolveRoleModel(config, role)
|
|
342
352
|
const promptSnapshot = [
|
|
@@ -513,6 +523,15 @@ async function runHarnessGitFinalize({
|
|
|
513
523
|
phase,
|
|
514
524
|
commitPlan,
|
|
515
525
|
}) {
|
|
526
|
+
await updateRunOwnership(config, {
|
|
527
|
+
status: 'git_finalize_running',
|
|
528
|
+
iteration,
|
|
529
|
+
phase,
|
|
530
|
+
activeKind: 'git_finalize',
|
|
531
|
+
activeRole: '',
|
|
532
|
+
activeReason: '',
|
|
533
|
+
})
|
|
534
|
+
|
|
516
535
|
const beforeSnapshot = getRepoSnapshot(config.cwd)
|
|
517
536
|
const dirtyFiles = new Set(listChangedFiles(config.cwd))
|
|
518
537
|
const requestedFiles = Array.isArray(commitPlan.files) ? commitPlan.files.filter(Boolean) : []
|
|
@@ -624,6 +643,15 @@ async function runHarnessGitFinalize({
|
|
|
624
643
|
}
|
|
625
644
|
|
|
626
645
|
async function runVerificationStep({ config, iteration, phase, kind }) {
|
|
646
|
+
await updateRunOwnership(config, {
|
|
647
|
+
status: 'verification_running',
|
|
648
|
+
iteration,
|
|
649
|
+
phase,
|
|
650
|
+
activeKind: kind,
|
|
651
|
+
activeRole: '',
|
|
652
|
+
activeReason: '',
|
|
653
|
+
})
|
|
654
|
+
|
|
627
655
|
const beforeSnapshot = getRepoSnapshot(config.cwd)
|
|
628
656
|
const verification = await runVerification(config)
|
|
629
657
|
const afterSnapshot = getRepoSnapshot(config.cwd)
|
|
@@ -988,6 +1016,15 @@ async function runTesterCommitTurn({
|
|
|
988
1016
|
}
|
|
989
1017
|
|
|
990
1018
|
async function runVisualReview({ config, iteration, phase, task, changedFiles }) {
|
|
1019
|
+
await updateRunOwnership(config, {
|
|
1020
|
+
status: 'visual_capture_running',
|
|
1021
|
+
iteration,
|
|
1022
|
+
phase,
|
|
1023
|
+
activeKind: 'visual_capture',
|
|
1024
|
+
activeRole: '',
|
|
1025
|
+
activeReason: '',
|
|
1026
|
+
})
|
|
1027
|
+
|
|
991
1028
|
const capture = await runVisualCapture(config, {
|
|
992
1029
|
iteration,
|
|
993
1030
|
phase,
|
|
@@ -1035,6 +1072,15 @@ async function runVisualReview({ config, iteration, phase, task, changedFiles })
|
|
|
1035
1072
|
}
|
|
1036
1073
|
}
|
|
1037
1074
|
|
|
1075
|
+
await updateRunOwnership(config, {
|
|
1076
|
+
status: 'visual_review_running',
|
|
1077
|
+
iteration,
|
|
1078
|
+
phase,
|
|
1079
|
+
activeKind: 'visual_review',
|
|
1080
|
+
activeRole: 'visualReview',
|
|
1081
|
+
activeReason: '',
|
|
1082
|
+
})
|
|
1083
|
+
|
|
1038
1084
|
const visualReviewModel = resolveRoleModel(config, 'visualReview')
|
|
1039
1085
|
const reviewRequest = {
|
|
1040
1086
|
iteration,
|
|
@@ -1196,6 +1242,9 @@ async function runIteration({ config, state, iteration }) {
|
|
|
1196
1242
|
iteration,
|
|
1197
1243
|
phase,
|
|
1198
1244
|
task,
|
|
1245
|
+
activeKind: '',
|
|
1246
|
+
activeRole: '',
|
|
1247
|
+
activeReason: '',
|
|
1199
1248
|
})
|
|
1200
1249
|
const canResumePriorSession = (
|
|
1201
1250
|
state.lastTransport === config.transport
|
|
@@ -1576,6 +1625,9 @@ async function runIteration({ config, state, iteration }) {
|
|
|
1576
1625
|
task,
|
|
1577
1626
|
lastCompletedIteration: iteration,
|
|
1578
1627
|
lastStatus: finalStatus,
|
|
1628
|
+
activeKind: '',
|
|
1629
|
+
activeRole: '',
|
|
1630
|
+
activeReason: '',
|
|
1579
1631
|
})
|
|
1580
1632
|
|
|
1581
1633
|
await appendLog(
|
|
@@ -1681,11 +1733,13 @@ async function main() {
|
|
|
1681
1733
|
config.runTelemetryCsv = path.join(runDir, 'pi_telemetry.csv')
|
|
1682
1734
|
config.runStateFile = path.join(runDir, 'state.json')
|
|
1683
1735
|
config.runLastIterationSummaryFile = path.join(runDir, 'last-iteration.json')
|
|
1736
|
+
config.runLastAgentOutputFile = path.join(runDir, 'last-output.txt')
|
|
1684
1737
|
|
|
1685
1738
|
ensureRepo(config.cwd)
|
|
1686
1739
|
await ensureFileExists(config.taskFile, 'task file')
|
|
1687
1740
|
await ensureFileExists(config.developerInstructionsFile, 'developer instructions file')
|
|
1688
1741
|
await ensureFileExists(config.testerInstructionsFile, 'tester instructions file')
|
|
1742
|
+
let visualizer = null
|
|
1689
1743
|
const lockResult = await acquireRunLock(config.activeRunFile, {
|
|
1690
1744
|
runId,
|
|
1691
1745
|
pid: process.pid,
|
|
@@ -1704,6 +1758,16 @@ async function main() {
|
|
|
1704
1758
|
process.env.PI_RUN_LOG_FILE = config.runLogFile
|
|
1705
1759
|
await ensureTelemetryFiles(config)
|
|
1706
1760
|
await appendLog(config.logFile, `Run started pid=${process.pid} mode=${config.mode}`)
|
|
1761
|
+
if (config.mode === 'run' && process.env.PI_VISUALIZER !== '0' && process.env.PI_VISUALIZER !== 'false') {
|
|
1762
|
+
try {
|
|
1763
|
+
visualizer = await startVisualizerServer(config)
|
|
1764
|
+
await appendLog(config.logFile, `Visualizer started at ${visualizer.url}`)
|
|
1765
|
+
process.stderr.write(`[PI visualizer] ${visualizer.url}\n`)
|
|
1766
|
+
} catch (error) {
|
|
1767
|
+
await appendLog(config.logFile, `Visualizer failed to start: ${error instanceof Error ? error.message : String(error)}`)
|
|
1768
|
+
process.stderr.write(`[PI visualizer] failed to start: ${error instanceof Error ? error.message : String(error)}\n`)
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1707
1771
|
if (lockResult.staleLock) {
|
|
1708
1772
|
await appendLog(
|
|
1709
1773
|
config.logFile,
|
|
@@ -1728,6 +1792,9 @@ async function main() {
|
|
|
1728
1792
|
await updateRunOwnership(config, {
|
|
1729
1793
|
status: 'starting_iteration',
|
|
1730
1794
|
iteration,
|
|
1795
|
+
activeKind: '',
|
|
1796
|
+
activeRole: '',
|
|
1797
|
+
activeReason: '',
|
|
1731
1798
|
})
|
|
1732
1799
|
const result = await runIteration({ config, state, iteration })
|
|
1733
1800
|
await writeIterationSummary(config, result.iterationSummary ?? result.summary)
|
|
@@ -1754,7 +1821,13 @@ async function main() {
|
|
|
1754
1821
|
await updateRunOwnership(config, {
|
|
1755
1822
|
status: stopRequested ? 'stopped' : 'finished',
|
|
1756
1823
|
heartbeatAt: timestamp(),
|
|
1824
|
+
activeKind: '',
|
|
1825
|
+
activeRole: '',
|
|
1826
|
+
activeReason: '',
|
|
1757
1827
|
})
|
|
1828
|
+
if (visualizer) {
|
|
1829
|
+
await visualizer.close().catch(() => {})
|
|
1830
|
+
}
|
|
1758
1831
|
await releaseRunLock(config.activeRunFile, runId)
|
|
1759
1832
|
delete process.env.PI_RUN_ID
|
|
1760
1833
|
delete process.env.PI_RUN_LOG_FILE
|
package/src/pi-telemetry.mjs
CHANGED
|
@@ -10,6 +10,10 @@ function csvEscape(value) {
|
|
|
10
10
|
|
|
11
11
|
export async function ensureTelemetryFiles(config) {
|
|
12
12
|
await fs.writeFile(config.lastAgentOutputFile, '', 'utf8')
|
|
13
|
+
if (config.runLastAgentOutputFile && config.runLastAgentOutputFile !== config.lastAgentOutputFile) {
|
|
14
|
+
await fs.mkdir(path.dirname(config.runLastAgentOutputFile), { recursive: true })
|
|
15
|
+
await fs.writeFile(config.runLastAgentOutputFile, '', 'utf8')
|
|
16
|
+
}
|
|
13
17
|
await fs.writeFile(config.lastVerificationOutputFile, '', 'utf8')
|
|
14
18
|
await fs.writeFile(config.changedFilesFile, '', 'utf8')
|
|
15
19
|
await fs.writeFile(config.lastPromptFile, '', 'utf8')
|