@11agents/cli 0.1.19 → 0.1.20
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/commands/runtime.js +49 -22
package/package.json
CHANGED
package/src/commands/runtime.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process'
|
|
2
2
|
import { createHash } from 'node:crypto'
|
|
3
3
|
import { appendFileSync, readFileSync } from 'node:fs'
|
|
4
|
-
import { appendFile, mkdir, readFile, rm, writeFile } from 'node:fs/promises'
|
|
4
|
+
import { appendFile, mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises'
|
|
5
5
|
import os from 'node:os'
|
|
6
6
|
import { dirname, resolve } from 'node:path'
|
|
7
7
|
import path from 'node:path'
|
|
@@ -86,27 +86,49 @@ function runtimeDeps(overrides = {}) {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
function
|
|
89
|
+
function legacyClaimPath(homeDir) {
|
|
90
90
|
return path.join(homeDir, '.11agents', 'claim_id')
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
function claimsDirPath(homeDir) {
|
|
94
|
+
return path.join(homeDir, '.11agents', 'claims')
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function claimFilePath(homeDir, taskId) {
|
|
98
|
+
return path.join(claimsDirPath(homeDir), `${sanitizeTaskId(taskId)}.json`)
|
|
99
|
+
}
|
|
100
|
+
|
|
93
101
|
async function writeCurrentClaim(deps, task, machineKey) {
|
|
94
102
|
const payload = {
|
|
95
103
|
task_id: String(task.id || ''),
|
|
96
104
|
runtime_id: String(task.runtime_id || task.runtime?.id || ''),
|
|
97
105
|
machine_key: String(task.runtime?.machine_key || machineKey || ''),
|
|
98
106
|
}
|
|
99
|
-
await mkdir(
|
|
100
|
-
await writeFile(
|
|
107
|
+
await mkdir(claimsDirPath(deps.homeDir), { recursive: true })
|
|
108
|
+
await writeFile(claimFilePath(deps.homeDir, task.id), JSON.stringify(payload))
|
|
101
109
|
return payload
|
|
102
110
|
}
|
|
103
111
|
|
|
104
|
-
async function
|
|
105
|
-
|
|
112
|
+
async function clearCurrentClaim(deps, taskId) {
|
|
113
|
+
await rm(claimFilePath(deps.homeDir, taskId), { force: true })
|
|
106
114
|
}
|
|
107
115
|
|
|
108
|
-
async function
|
|
109
|
-
|
|
116
|
+
async function readAllCurrentClaims(deps) {
|
|
117
|
+
const claims = []
|
|
118
|
+
// Backward compat: consume legacy single-claim file
|
|
119
|
+
const legacy = await readJsonFile(legacyClaimPath(deps.homeDir), null)
|
|
120
|
+
if (legacy?.task_id && legacy?.runtime_id) {
|
|
121
|
+
claims.push({ ...legacy, _path: legacyClaimPath(deps.homeDir) })
|
|
122
|
+
}
|
|
123
|
+
// Per-task claim files
|
|
124
|
+
const entries = await readdir(claimsDirPath(deps.homeDir)).catch(err => (err?.code === 'ENOENT' ? [] : Promise.reject(err)))
|
|
125
|
+
for (const entry of entries) {
|
|
126
|
+
if (!entry.endsWith('.json')) continue
|
|
127
|
+
const filePath = path.join(claimsDirPath(deps.homeDir), entry)
|
|
128
|
+
const claim = await readJsonFile(filePath, null)
|
|
129
|
+
if (claim?.task_id && claim?.runtime_id) claims.push({ ...claim, _path: filePath })
|
|
130
|
+
}
|
|
131
|
+
return claims
|
|
110
132
|
}
|
|
111
133
|
|
|
112
134
|
function errorMessage(error) {
|
|
@@ -339,15 +361,20 @@ function codexAssistantTextFromJsonl(text) {
|
|
|
339
361
|
return messages.join('\n\n')
|
|
340
362
|
}
|
|
341
363
|
|
|
342
|
-
async function
|
|
343
|
-
const
|
|
344
|
-
if (!
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
364
|
+
async function failAllPersistedClaims(flags, deps, comment) {
|
|
365
|
+
const claims = await readAllCurrentClaims(deps)
|
|
366
|
+
if (!claims.length) return false
|
|
367
|
+
const config = configFromFlags(flags)
|
|
368
|
+
for (const claim of claims) {
|
|
369
|
+
try {
|
|
370
|
+
await deps.requestJson('/api/runtime/tasks/complete', {
|
|
371
|
+
method: 'POST',
|
|
372
|
+
body: failedClaimCompletionBody(claim, comment),
|
|
373
|
+
config,
|
|
374
|
+
})
|
|
375
|
+
} catch {}
|
|
376
|
+
await rm(claim._path, { force: true })
|
|
377
|
+
}
|
|
351
378
|
return true
|
|
352
379
|
}
|
|
353
380
|
|
|
@@ -357,14 +384,14 @@ function installCurrentClaimExitHandlers(flags, deps) {
|
|
|
357
384
|
if (shuttingDown) return
|
|
358
385
|
shuttingDown = true
|
|
359
386
|
try {
|
|
360
|
-
await
|
|
387
|
+
await failAllPersistedClaims(
|
|
361
388
|
flags,
|
|
362
389
|
deps,
|
|
363
390
|
`Runtime task failed locally: daemon received ${signal} before the claimed task completed.`
|
|
364
391
|
)
|
|
365
392
|
} catch (error) {
|
|
366
393
|
deps.log(JSON.stringify({
|
|
367
|
-
warning: 'failed to mark current claimed
|
|
394
|
+
warning: 'failed to mark current claimed tasks failed during daemon shutdown',
|
|
368
395
|
signal,
|
|
369
396
|
error: errorMessage(error),
|
|
370
397
|
}, null, 2))
|
|
@@ -1365,7 +1392,7 @@ async function runOneRuntimeTaskSlot(runtime, config, machineKey, registration,
|
|
|
1365
1392
|
config,
|
|
1366
1393
|
})
|
|
1367
1394
|
), deps, retryState)
|
|
1368
|
-
await clearCurrentClaim(deps)
|
|
1395
|
+
await clearCurrentClaim(deps, runtimeTask.id)
|
|
1369
1396
|
deps.log(JSON.stringify(result, null, 2))
|
|
1370
1397
|
return true
|
|
1371
1398
|
}
|
|
@@ -1412,7 +1439,7 @@ export async function startRuntimeDaemon(flags = {}, deps = {}) {
|
|
|
1412
1439
|
const uninstallExitHandlers = installCurrentClaimExitHandlers(flags, resolvedDeps)
|
|
1413
1440
|
try {
|
|
1414
1441
|
let registration = await runWithDaemonRetry('register runtime', () => registerRuntime(flags, resolvedDeps), resolvedDeps, retryState)
|
|
1415
|
-
await runWithDaemonRetry('recover current claimed task', () =>
|
|
1442
|
+
await runWithDaemonRetry('recover current claimed task', () => failAllPersistedClaims(
|
|
1416
1443
|
flags,
|
|
1417
1444
|
resolvedDeps,
|
|
1418
1445
|
'Runtime task failed locally: daemon restarted with a persisted claimed task that had not completed.'
|
|
@@ -1447,7 +1474,7 @@ export async function startRuntimeDaemon(flags = {}, deps = {}) {
|
|
|
1447
1474
|
}
|
|
1448
1475
|
} catch (error) {
|
|
1449
1476
|
try {
|
|
1450
|
-
await
|
|
1477
|
+
await failAllPersistedClaims(
|
|
1451
1478
|
flags,
|
|
1452
1479
|
resolvedDeps,
|
|
1453
1480
|
`Runtime task failed locally: daemon exited with error before the claimed task completed: ${errorMessage(error)}`
|