@11agents/cli 0.1.19 → 0.1.21
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 -24
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))
|
|
@@ -972,7 +999,6 @@ function buildCodexPrompt(task) {
|
|
|
972
999
|
issue: task.issue,
|
|
973
1000
|
trigger_summary: task.trigger_summary,
|
|
974
1001
|
thread_memory: task.thread_memory,
|
|
975
|
-
project_knowledge: task.project_knowledge,
|
|
976
1002
|
}),
|
|
977
1003
|
'',
|
|
978
1004
|
'Assigned agent context:',
|
|
@@ -984,7 +1010,6 @@ function buildCodexPrompt(task) {
|
|
|
984
1010
|
memory: task.agent?.memory,
|
|
985
1011
|
permissions: task.agent?.permissions,
|
|
986
1012
|
triggers: task.agent?.triggers,
|
|
987
|
-
skills: task.agent?.skills,
|
|
988
1013
|
}),
|
|
989
1014
|
'',
|
|
990
1015
|
'Thread comments:',
|
|
@@ -1365,7 +1390,7 @@ async function runOneRuntimeTaskSlot(runtime, config, machineKey, registration,
|
|
|
1365
1390
|
config,
|
|
1366
1391
|
})
|
|
1367
1392
|
), deps, retryState)
|
|
1368
|
-
await clearCurrentClaim(deps)
|
|
1393
|
+
await clearCurrentClaim(deps, runtimeTask.id)
|
|
1369
1394
|
deps.log(JSON.stringify(result, null, 2))
|
|
1370
1395
|
return true
|
|
1371
1396
|
}
|
|
@@ -1412,7 +1437,7 @@ export async function startRuntimeDaemon(flags = {}, deps = {}) {
|
|
|
1412
1437
|
const uninstallExitHandlers = installCurrentClaimExitHandlers(flags, resolvedDeps)
|
|
1413
1438
|
try {
|
|
1414
1439
|
let registration = await runWithDaemonRetry('register runtime', () => registerRuntime(flags, resolvedDeps), resolvedDeps, retryState)
|
|
1415
|
-
await runWithDaemonRetry('recover current claimed task', () =>
|
|
1440
|
+
await runWithDaemonRetry('recover current claimed task', () => failAllPersistedClaims(
|
|
1416
1441
|
flags,
|
|
1417
1442
|
resolvedDeps,
|
|
1418
1443
|
'Runtime task failed locally: daemon restarted with a persisted claimed task that had not completed.'
|
|
@@ -1447,7 +1472,7 @@ export async function startRuntimeDaemon(flags = {}, deps = {}) {
|
|
|
1447
1472
|
}
|
|
1448
1473
|
} catch (error) {
|
|
1449
1474
|
try {
|
|
1450
|
-
await
|
|
1475
|
+
await failAllPersistedClaims(
|
|
1451
1476
|
flags,
|
|
1452
1477
|
resolvedDeps,
|
|
1453
1478
|
`Runtime task failed locally: daemon exited with error before the claimed task completed: ${errorMessage(error)}`
|