@11agents/cli 0.1.39 → 0.1.41
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 +31 -18
package/package.json
CHANGED
package/src/commands/runtime.js
CHANGED
|
@@ -83,7 +83,6 @@ function runtimeDeps(overrides = {}) {
|
|
|
83
83
|
sleep: overrides.sleep || sleep,
|
|
84
84
|
syncKnowledge: overrides.syncKnowledge || syncKnowledge,
|
|
85
85
|
mcpKnowledgeSync: overrides.mcpKnowledgeSync || mcpKnowledgeSync,
|
|
86
|
-
cpuCount: overrides.cpuCount ?? os.cpus().length,
|
|
87
86
|
}
|
|
88
87
|
}
|
|
89
88
|
|
|
@@ -248,7 +247,7 @@ export async function scanRuntime(flags = {}) {
|
|
|
248
247
|
return scan
|
|
249
248
|
}
|
|
250
249
|
|
|
251
|
-
export async function registerRuntime(flags = {}, deps = {}) {
|
|
250
|
+
export async function registerRuntime(flags = {}, deps = {}, { maxConcurrent } = {}) {
|
|
252
251
|
const { buildRuntimeScan: scanBuilder, log, requestJson: request } = runtimeDeps(deps)
|
|
253
252
|
const config = configFromFlags(flags)
|
|
254
253
|
if (!config.token) throw new Error('GTM_WRITES_TOKEN or --token is required')
|
|
@@ -256,9 +255,13 @@ export async function registerRuntime(flags = {}, deps = {}) {
|
|
|
256
255
|
const scan = await scanBuilder({ env: scanEnvWithOverrides(flags), cliVersion: CLI_VERSION })
|
|
257
256
|
if (!scan.runtimes.length) throw new Error('no local AI runtimes detected on PATH')
|
|
258
257
|
|
|
258
|
+
const body = maxConcurrent
|
|
259
|
+
? { ...scan, runtimes: scan.runtimes.map(r => ({ ...r, max_concurrent: maxConcurrent })) }
|
|
260
|
+
: scan
|
|
261
|
+
|
|
259
262
|
const result = await request('/api/runtime/machines/register', {
|
|
260
263
|
method: 'POST',
|
|
261
|
-
body
|
|
264
|
+
body,
|
|
262
265
|
config,
|
|
263
266
|
})
|
|
264
267
|
log(JSON.stringify(result, null, 2))
|
|
@@ -1641,11 +1644,7 @@ async function claimAndRunRuntimeTasks(registration, flags, deps, handlerModule,
|
|
|
1641
1644
|
const config = configFromFlags(flags)
|
|
1642
1645
|
const machineKey = registration?.machine?.machine_key || machineOverride(flags) || ''
|
|
1643
1646
|
|
|
1644
|
-
|
|
1645
|
-
// maxConcurrent is honoured when it exceeds the CPU-derived default.
|
|
1646
|
-
const perRuntime = Math.max(1, (deps.cpuCount ?? os.cpus().length) - 1)
|
|
1647
|
-
const effectiveConcurrent = Math.max(maxConcurrent, runtimes.length * perRuntime)
|
|
1648
|
-
const slots = Array.from({ length: effectiveConcurrent }, (_, i) => runtimes[i % runtimes.length])
|
|
1647
|
+
const slots = Array.from({ length: maxConcurrent }, (_, i) => runtimes[i % runtimes.length])
|
|
1649
1648
|
const results = await Promise.allSettled(
|
|
1650
1649
|
slots.map(runtime => runOneRuntimeTaskSlot(runtime, config, machineKey, registration, flags, deps, handlerModule, retryState, heartbeatIntervalMs))
|
|
1651
1650
|
)
|
|
@@ -1653,12 +1652,28 @@ async function claimAndRunRuntimeTasks(registration, flags, deps, handlerModule,
|
|
|
1653
1652
|
}
|
|
1654
1653
|
|
|
1655
1654
|
async function drainRuntimeTasks(registration, flags, deps, handlerModule, retryState = createRetryState(), heartbeatIntervalMs = 15000, maxConcurrent = 1) {
|
|
1655
|
+
if (!handlerModule) return 0
|
|
1656
|
+
const runtimes = (registration?.runtimes || []).filter(r => r?.id)
|
|
1657
|
+
if (!runtimes.length) return 0
|
|
1658
|
+
const config = configFromFlags(flags)
|
|
1659
|
+
const machineKey = registration?.machine?.machine_key || machineOverride(flags) || ''
|
|
1660
|
+
|
|
1656
1661
|
let completed = 0
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
+
// Worker pool: each worker loops claiming tasks until the queue is empty,
|
|
1663
|
+
// so a fast worker immediately picks up the next task without waiting for
|
|
1664
|
+
// slow workers to finish (unlike the old batched Promise.allSettled approach).
|
|
1665
|
+
const workers = Array.from({ length: maxConcurrent }, (_, i) => {
|
|
1666
|
+
const runtime = runtimes[i % runtimes.length]
|
|
1667
|
+
return (async () => {
|
|
1668
|
+
while (true) {
|
|
1669
|
+
const ran = await runOneRuntimeTaskSlot(runtime, config, machineKey, registration, flags, deps, handlerModule, retryState, heartbeatIntervalMs)
|
|
1670
|
+
if (!ran) break
|
|
1671
|
+
completed++
|
|
1672
|
+
}
|
|
1673
|
+
})()
|
|
1674
|
+
})
|
|
1675
|
+
await Promise.allSettled(workers)
|
|
1676
|
+
return completed
|
|
1662
1677
|
}
|
|
1663
1678
|
|
|
1664
1679
|
export async function startRuntimeDaemon(flags = {}, deps = {}) {
|
|
@@ -1667,11 +1682,9 @@ export async function startRuntimeDaemon(flags = {}, deps = {}) {
|
|
|
1667
1682
|
const scanIntervalMs = Number(flag(flags, 'scan-interval', '60')) * 1000
|
|
1668
1683
|
const taskIntervalMs = Number(flag(flags, 'task-interval', flag(flags, 'heartbeat-interval', '15'))) * 1000
|
|
1669
1684
|
const projectRefreshIntervalMs = Number(flag(flags, 'project-refresh-interval', '1800')) * 1000
|
|
1670
|
-
const cpuCount = resolvedDeps.cpuCount ?? os.cpus().length
|
|
1671
|
-
const cpuDefault = Math.max(1, cpuCount - 1)
|
|
1672
1685
|
const envMax = Number(process.env.DAEMON_MAX_CONCURRENCY)
|
|
1673
|
-
const envConcurrency = Number.isInteger(envMax) && envMax > 0
|
|
1674
|
-
const maxConcurrent = envConcurrency ?? Math.max(1, Number(flag(flags, 'concurrency',
|
|
1686
|
+
const envConcurrency = Number.isInteger(envMax) && envMax > 0 ? envMax : null
|
|
1687
|
+
const maxConcurrent = envConcurrency ?? Math.max(1, Number(flag(flags, 'concurrency', '10')) || 10)
|
|
1675
1688
|
const once = Boolean(flags.once)
|
|
1676
1689
|
const handlerPath = flag(flags, 'handler')
|
|
1677
1690
|
|
|
@@ -1692,7 +1705,7 @@ export async function startRuntimeDaemon(flags = {}, deps = {}) {
|
|
|
1692
1705
|
const retryState = createRetryState()
|
|
1693
1706
|
const uninstallExitHandlers = installCurrentClaimExitHandlers(flags, resolvedDeps)
|
|
1694
1707
|
try {
|
|
1695
|
-
let registration = await runWithDaemonRetry('register runtime', () => registerRuntime(flags, resolvedDeps), resolvedDeps, retryState)
|
|
1708
|
+
let registration = await runWithDaemonRetry('register runtime', () => registerRuntime(flags, resolvedDeps, { maxConcurrent }), resolvedDeps, retryState)
|
|
1696
1709
|
await runWithDaemonRetry('recover current claimed task', () => failAllPersistedClaims(
|
|
1697
1710
|
flags,
|
|
1698
1711
|
resolvedDeps,
|