@themoltnet/agent-daemon 0.22.2 → 0.24.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/dist/main.js +101 -14
- package/package.json +5 -5
package/dist/main.js
CHANGED
|
@@ -4399,6 +4399,16 @@ var RuntimeProfileToolName = String$1({
|
|
|
4399
4399
|
maxLength: 128,
|
|
4400
4400
|
pattern: "^[a-zA-Z0-9._/-]+$"
|
|
4401
4401
|
});
|
|
4402
|
+
var RuntimeProfileWorkspaceMode = Union([
|
|
4403
|
+
Literal("none"),
|
|
4404
|
+
Literal("shared_mount"),
|
|
4405
|
+
Literal("dedicated_worktree")
|
|
4406
|
+
]);
|
|
4407
|
+
var RuntimeProfileAllowedWorkspaceModes = _Array_(RuntimeProfileWorkspaceMode, {
|
|
4408
|
+
minItems: 1,
|
|
4409
|
+
maxItems: 3,
|
|
4410
|
+
uniqueItems: true
|
|
4411
|
+
});
|
|
4402
4412
|
var SandboxResumeCommandWhenSchema = _Object_({ workspaceMode: Optional(_Array_(Union([
|
|
4403
4413
|
Literal("shared_mount"),
|
|
4404
4414
|
Literal("dedicated_worktree"),
|
|
@@ -4502,6 +4512,14 @@ var RuntimeProfileMaxBatchSize = Integer({
|
|
|
4502
4512
|
minimum: 1,
|
|
4503
4513
|
maximum: 1e3
|
|
4504
4514
|
});
|
|
4515
|
+
var RuntimeProfileMaxTurns = Integer({
|
|
4516
|
+
minimum: 0,
|
|
4517
|
+
maximum: 1e4
|
|
4518
|
+
});
|
|
4519
|
+
var RuntimeProfileMaxBashTimeouts = Integer({
|
|
4520
|
+
minimum: 0,
|
|
4521
|
+
maximum: 1e3
|
|
4522
|
+
});
|
|
4505
4523
|
_Object_({
|
|
4506
4524
|
id: String$1({ format: "uuid" }),
|
|
4507
4525
|
teamId: String$1({ format: "uuid" }),
|
|
@@ -4519,6 +4537,8 @@ _Object_({
|
|
|
4519
4537
|
sandbox: RuntimeProfileSandbox,
|
|
4520
4538
|
sessionStorageMode: Literal("local"),
|
|
4521
4539
|
workspaceStorageMode: Literal("local"),
|
|
4540
|
+
defaultWorkspaceMode: Union([RuntimeProfileWorkspaceMode, Null()]),
|
|
4541
|
+
allowedWorkspaceModes: RuntimeProfileAllowedWorkspaceModes,
|
|
4522
4542
|
sessionTtlSec: Integer({
|
|
4523
4543
|
minimum: 1,
|
|
4524
4544
|
maximum: 86400
|
|
@@ -4530,6 +4550,8 @@ _Object_({
|
|
|
4530
4550
|
leaseTtlSec: RuntimeProfileLeaseTtlSec,
|
|
4531
4551
|
heartbeatIntervalMs: RuntimeProfileHeartbeatIntervalMs,
|
|
4532
4552
|
maxBatchSize: RuntimeProfileMaxBatchSize,
|
|
4553
|
+
maxTurns: RuntimeProfileMaxTurns,
|
|
4554
|
+
maxBashTimeouts: RuntimeProfileMaxBashTimeouts,
|
|
4533
4555
|
requiredEnv: _Array_(RuntimeProfileEnvName, { maxItems: 100 }),
|
|
4534
4556
|
requiredTools: _Array_(RuntimeProfileToolName, { maxItems: 100 }),
|
|
4535
4557
|
context: _Array_(RuntimeProfileContext, { maxItems: 5 }),
|
|
@@ -9449,9 +9471,9 @@ function slugifySessionComponent(input) {
|
|
|
9449
9471
|
}
|
|
9450
9472
|
//#endregion
|
|
9451
9473
|
//#region src/lib/task-execution-plan.ts
|
|
9452
|
-
function buildDaemonTaskExecutionPlan(task, stateDirs, identity, warmSessionTtlSec) {
|
|
9474
|
+
function buildDaemonTaskExecutionPlan(task, stateDirs, identity, warmSessionTtlSec, runtimeProfileWorkspacePolicy = {}) {
|
|
9453
9475
|
const descriptor = deriveTaskSessionDescriptor(task);
|
|
9454
|
-
const workspaceMode = resolveTaskWorkspaceMode(task, descriptor.policy);
|
|
9476
|
+
const workspaceMode = resolveTaskWorkspaceMode(task, descriptor.policy, runtimeProfileWorkspacePolicy);
|
|
9455
9477
|
const slotKey = warmSessionTtlSec > 0 ? descriptor.sessionKey : null;
|
|
9456
9478
|
const workspaceScope = slotKey !== null ? descriptor.policy.workspaceScope : "attempt";
|
|
9457
9479
|
const slotId = slotKey ? buildDaemonSlotId(identity, slotKey) : null;
|
|
@@ -9501,14 +9523,40 @@ function resolveTaskWorktreeBranch(task, workspaceMode) {
|
|
|
9501
9523
|
}
|
|
9502
9524
|
return `task/${slugifyAsciiLower(task.taskType, 60) || "task"}-${task.id.slice(0, 8)}`;
|
|
9503
9525
|
}
|
|
9504
|
-
function resolveTaskWorkspaceMode(task, policy) {
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
|
|
9526
|
+
function resolveTaskWorkspaceMode(task, policy, runtimeProfileWorkspacePolicy) {
|
|
9527
|
+
const allowed = resolveAllowedWorkspaceModes(runtimeProfileWorkspacePolicy);
|
|
9528
|
+
const profileDefault = runtimeProfileWorkspacePolicy.defaultWorkspaceMode ?? null;
|
|
9529
|
+
const requestedWorkspace = policy.acceptsInputWorkspaceOverride && typeof task.input.execution?.workspace === "string" ? task.input.execution.workspace : null;
|
|
9530
|
+
if (isRuntimeProfileWorkspaceMode(requestedWorkspace)) {
|
|
9531
|
+
if (allowed.has(requestedWorkspace)) return toDaemonWorkspaceMode(requestedWorkspace);
|
|
9532
|
+
}
|
|
9533
|
+
if (profileDefault && allowed.has(profileDefault)) return toDaemonWorkspaceMode(profileDefault);
|
|
9534
|
+
if (allowed.has(policy.workspaceMode)) return policy.workspaceMode;
|
|
9535
|
+
return toDaemonWorkspaceMode(firstAllowedWorkspaceMode(allowed));
|
|
9536
|
+
}
|
|
9537
|
+
var ALL_WORKSPACE_MODES = [
|
|
9538
|
+
"none",
|
|
9539
|
+
"shared_mount",
|
|
9540
|
+
"dedicated_worktree"
|
|
9541
|
+
];
|
|
9542
|
+
var WORKSPACE_MODE_FALLBACK_ORDER = [
|
|
9543
|
+
"none",
|
|
9544
|
+
"dedicated_worktree",
|
|
9545
|
+
"shared_mount"
|
|
9546
|
+
];
|
|
9547
|
+
function resolveAllowedWorkspaceModes(policy) {
|
|
9548
|
+
const modes = policy.allowedWorkspaceModes && policy.allowedWorkspaceModes.length > 0 ? policy.allowedWorkspaceModes : ALL_WORKSPACE_MODES;
|
|
9549
|
+
return new Set(modes.filter((mode) => isRuntimeProfileWorkspaceMode(mode)));
|
|
9550
|
+
}
|
|
9551
|
+
function firstAllowedWorkspaceMode(allowed) {
|
|
9552
|
+
for (const mode of WORKSPACE_MODE_FALLBACK_ORDER) if (allowed.has(mode)) return mode;
|
|
9553
|
+
return "none";
|
|
9554
|
+
}
|
|
9555
|
+
function isRuntimeProfileWorkspaceMode(value) {
|
|
9556
|
+
return value === "none" || value === "shared_mount" || value === "dedicated_worktree";
|
|
9557
|
+
}
|
|
9558
|
+
function toDaemonWorkspaceMode(mode) {
|
|
9559
|
+
return mode === "none" ? "scratch_mount" : mode;
|
|
9512
9560
|
}
|
|
9513
9561
|
function resolveTaskWorkspaceId(task, executionPlan) {
|
|
9514
9562
|
if (executionPlan.workspaceScope === "session" && executionPlan.sessionKey !== null) return `session-${encodeURIComponent(executionPlan.sessionKey)}`;
|
|
@@ -9529,7 +9577,8 @@ function createExecutionPlanCache(args) {
|
|
|
9529
9577
|
const key = buildClaimedTaskKey(claimedTask);
|
|
9530
9578
|
const existing = cache.get(key);
|
|
9531
9579
|
if (existing) return existing;
|
|
9532
|
-
const plan = await maybeAttachWarmSlotContext(claimedTask, buildDaemonTaskExecutionPlan(claimedTask.task, args.stateDirs, args.slotIdentity, args.warmSessionTtlSec), args.stateDirs, args.slotRegistry);
|
|
9580
|
+
const plan = await maybeAttachWarmSlotContext(claimedTask, buildDaemonTaskExecutionPlan(claimedTask.task, args.stateDirs, args.slotIdentity, args.warmSessionTtlSec, args.workspacePolicy), args.stateDirs, args.slotRegistry);
|
|
9581
|
+
assertPlanAllowedByWorkspacePolicy(plan, args.workspacePolicy);
|
|
9533
9582
|
cache.set(key, plan);
|
|
9534
9583
|
return plan;
|
|
9535
9584
|
},
|
|
@@ -9538,6 +9587,20 @@ function createExecutionPlanCache(args) {
|
|
|
9538
9587
|
}
|
|
9539
9588
|
};
|
|
9540
9589
|
}
|
|
9590
|
+
function assertPlanAllowedByWorkspacePolicy(plan, policy) {
|
|
9591
|
+
const allowed = new Set(policy?.allowedWorkspaceModes && policy.allowedWorkspaceModes.length > 0 ? policy.allowedWorkspaceModes : [
|
|
9592
|
+
"none",
|
|
9593
|
+
"shared_mount",
|
|
9594
|
+
"dedicated_worktree"
|
|
9595
|
+
]);
|
|
9596
|
+
const effectiveMode = planToRuntimeProfileWorkspaceMode(plan);
|
|
9597
|
+
if (!allowed.has(effectiveMode)) throw new Error(`Runtime profile forbids final workspace mode "${effectiveMode}" for this task`);
|
|
9598
|
+
}
|
|
9599
|
+
function planToRuntimeProfileWorkspaceMode(plan) {
|
|
9600
|
+
if (plan.workspaceMode === "scratch_mount") return "none";
|
|
9601
|
+
if (plan.workspaceMode === "dedicated_worktree" && !plan.worktreeBranch) return "shared_mount";
|
|
9602
|
+
return plan.workspaceMode;
|
|
9603
|
+
}
|
|
9541
9604
|
function buildClaimedTaskKey(task) {
|
|
9542
9605
|
return `${task.task.id}:${task.attemptN}`;
|
|
9543
9606
|
}
|
|
@@ -9798,6 +9861,8 @@ function parseCommonOptions(args, options = {}) {
|
|
|
9798
9861
|
leaseTtlSec: options.runtimeDefaults?.leaseTtlSec ?? DEFAULTS.leaseTtlSec,
|
|
9799
9862
|
heartbeatIntervalMs: options.runtimeDefaults?.heartbeatIntervalMs ?? DEFAULTS.heartbeatIntervalMs,
|
|
9800
9863
|
maxBatchSize: options.runtimeDefaults?.maxBatchSize ?? DEFAULTS.maxBatchSize,
|
|
9864
|
+
maxTurns: options.runtimeDefaults?.maxTurns ?? DEFAULTS.maxTurns,
|
|
9865
|
+
maxBashTimeouts: options.runtimeDefaults?.maxBashTimeouts ?? DEFAULTS.maxBashTimeouts,
|
|
9801
9866
|
warmSessionTtlSec: options.runtimeDefaults?.warmSessionTtlSec ?? DEFAULTS.warmSessionTtlSec
|
|
9802
9867
|
};
|
|
9803
9868
|
if (!args.agent) throw new MissingRequiredOptionError("agent");
|
|
@@ -9808,8 +9873,8 @@ function parseCommonOptions(args, options = {}) {
|
|
|
9808
9873
|
heartbeatIntervalMs: parseNonNegativeInt(args["heartbeat-interval-ms"], "heartbeat-interval-ms", runtimeDefaults.heartbeatIntervalMs),
|
|
9809
9874
|
maxBatchSize: parsePositiveInt(args["max-batch-size"], "max-batch-size", runtimeDefaults.maxBatchSize),
|
|
9810
9875
|
flushIntervalMs: parseNonNegativeInt(args["flush-interval-ms"], "flush-interval-ms", DEFAULTS.flushIntervalMs),
|
|
9811
|
-
maxTurns: parseNonNegativeInt(args["max-turns"], "max-turns",
|
|
9812
|
-
maxBashTimeouts: parseNonNegativeInt(args["max-bash-timeouts"], "max-bash-timeouts",
|
|
9876
|
+
maxTurns: parseNonNegativeInt(args["max-turns"], "max-turns", runtimeDefaults.maxTurns),
|
|
9877
|
+
maxBashTimeouts: parseNonNegativeInt(args["max-bash-timeouts"], "max-bash-timeouts", runtimeDefaults.maxBashTimeouts),
|
|
9813
9878
|
warmSessionTtlSec: parseNonNegativeInt(args["warm-session-ttl-sec"], "warm-session-ttl-sec", runtimeDefaults.warmSessionTtlSec),
|
|
9814
9879
|
debug: args.debug === true
|
|
9815
9880
|
};
|
|
@@ -9941,8 +10006,12 @@ async function resolveRuntimeProfile(options) {
|
|
|
9941
10006
|
leaseTtlSec: profile.leaseTtlSec,
|
|
9942
10007
|
heartbeatIntervalMs: profile.heartbeatIntervalMs,
|
|
9943
10008
|
maxBatchSize: profile.maxBatchSize,
|
|
10009
|
+
maxTurns: profile.maxTurns,
|
|
10010
|
+
maxBashTimeouts: profile.maxBashTimeouts,
|
|
9944
10011
|
sessionTtlSec: profile.sessionTtlSec,
|
|
9945
10012
|
workspaceTtlSec: profile.workspaceTtlSec,
|
|
10013
|
+
defaultWorkspaceMode: profile.defaultWorkspaceMode ?? null,
|
|
10014
|
+
allowedWorkspaceModes: profile.allowedWorkspaceModes,
|
|
9946
10015
|
requiredEnv: profile.requiredEnv,
|
|
9947
10016
|
requiredTools: profile.requiredTools,
|
|
9948
10017
|
sandboxConfig: profile.sandbox,
|
|
@@ -10200,6 +10269,8 @@ async function runPolling(opts) {
|
|
|
10200
10269
|
leaseTtlSec: profile.leaseTtlSec,
|
|
10201
10270
|
heartbeatIntervalMs: profile.heartbeatIntervalMs,
|
|
10202
10271
|
maxBatchSize: profile.maxBatchSize,
|
|
10272
|
+
maxTurns: profile.maxTurns,
|
|
10273
|
+
maxBashTimeouts: profile.maxBashTimeouts,
|
|
10203
10274
|
warmSessionTtlSec: resolveProfileWarmSessionTtlSec(profile)
|
|
10204
10275
|
} });
|
|
10205
10276
|
const sandbox = {
|
|
@@ -10217,6 +10288,10 @@ async function runPolling(opts) {
|
|
|
10217
10288
|
stateDirs,
|
|
10218
10289
|
slotIdentity,
|
|
10219
10290
|
warmSessionTtlSec: common.warmSessionTtlSec,
|
|
10291
|
+
workspacePolicy: {
|
|
10292
|
+
defaultWorkspaceMode: profile.defaultWorkspaceMode,
|
|
10293
|
+
allowedWorkspaceModes: profile.allowedWorkspaceModes
|
|
10294
|
+
},
|
|
10220
10295
|
slotRegistry
|
|
10221
10296
|
});
|
|
10222
10297
|
runtimes.set(profile.id, {
|
|
@@ -10293,9 +10368,13 @@ async function runPolling(opts) {
|
|
|
10293
10368
|
sandbox: runtime.sandbox.path,
|
|
10294
10369
|
leaseTtlSec: runtime.common.leaseTtlSec,
|
|
10295
10370
|
heartbeatIntervalMs: runtime.common.heartbeatIntervalMs,
|
|
10371
|
+
maxTurns: runtime.common.maxTurns,
|
|
10372
|
+
maxBashTimeouts: runtime.common.maxBashTimeouts,
|
|
10296
10373
|
warmSessionTtlSec: runtime.common.warmSessionTtlSec,
|
|
10297
10374
|
profileSessionTtlSec: profile.sessionTtlSec,
|
|
10298
|
-
profileWorkspaceTtlSec: profile.workspaceTtlSec
|
|
10375
|
+
profileWorkspaceTtlSec: profile.workspaceTtlSec,
|
|
10376
|
+
defaultWorkspaceMode: profile.defaultWorkspaceMode,
|
|
10377
|
+
allowedWorkspaceModes: profile.allowedWorkspaceModes
|
|
10299
10378
|
};
|
|
10300
10379
|
}),
|
|
10301
10380
|
piAgentDir: piAgentDir.path,
|
|
@@ -10589,6 +10668,8 @@ async function runOnce(argv) {
|
|
|
10589
10668
|
leaseTtlSec: profile.leaseTtlSec,
|
|
10590
10669
|
heartbeatIntervalMs: profile.heartbeatIntervalMs,
|
|
10591
10670
|
maxBatchSize: profile.maxBatchSize,
|
|
10671
|
+
maxTurns: profile.maxTurns,
|
|
10672
|
+
maxBashTimeouts: profile.maxBashTimeouts,
|
|
10592
10673
|
warmSessionTtlSec: resolveProfileWarmSessionTtlSec(profile)
|
|
10593
10674
|
} });
|
|
10594
10675
|
const sandbox = {
|
|
@@ -10608,6 +10689,10 @@ async function runOnce(argv) {
|
|
|
10608
10689
|
stateDirs,
|
|
10609
10690
|
slotIdentity,
|
|
10610
10691
|
warmSessionTtlSec: opts.warmSessionTtlSec,
|
|
10692
|
+
workspacePolicy: {
|
|
10693
|
+
defaultWorkspaceMode: profile.defaultWorkspaceMode,
|
|
10694
|
+
allowedWorkspaceModes: profile.allowedWorkspaceModes
|
|
10695
|
+
},
|
|
10611
10696
|
slotRegistry
|
|
10612
10697
|
});
|
|
10613
10698
|
const otelShutdown = await initWorkerOtel({
|
|
@@ -10639,6 +10724,8 @@ async function runOnce(argv) {
|
|
|
10639
10724
|
taskId,
|
|
10640
10725
|
leaseTtlSec: opts.leaseTtlSec,
|
|
10641
10726
|
heartbeatIntervalMs: opts.heartbeatIntervalMs,
|
|
10727
|
+
maxTurns: opts.maxTurns,
|
|
10728
|
+
maxBashTimeouts: opts.maxBashTimeouts,
|
|
10642
10729
|
warmSessionTtlSec: opts.warmSessionTtlSec,
|
|
10643
10730
|
profileId: profile.id,
|
|
10644
10731
|
profileSessionTtlSec: profile.sessionTtlSec,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@themoltnet/agent-daemon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "MoltNet agent daemon — claims and executes tasks (fulfill_brief, assess_brief) from the MoltNet task-service via Pi-headless. CLI: moltnet-agent.",
|
|
@@ -45,17 +45,17 @@
|
|
|
45
45
|
"@opentelemetry/semantic-conventions": "^1.39.0",
|
|
46
46
|
"pino": "^10.3.1",
|
|
47
47
|
"pino-pretty": "^13.1.3",
|
|
48
|
-
"@themoltnet/agent-runtime": "0.
|
|
49
|
-
"@themoltnet/pi-extension": "0.
|
|
50
|
-
"@themoltnet/sdk": "0.
|
|
48
|
+
"@themoltnet/agent-runtime": "0.29.0",
|
|
49
|
+
"@themoltnet/pi-extension": "0.27.0",
|
|
50
|
+
"@themoltnet/sdk": "0.112.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"tsx": "^4.7.0",
|
|
54
54
|
"typescript": "~5.9.2",
|
|
55
55
|
"vite": "^8.0.0",
|
|
56
56
|
"vitest": "^3.0.0",
|
|
57
|
-
"@moltnet/bootstrap": "0.1.0",
|
|
58
57
|
"@moltnet/observability": "0.1.0",
|
|
58
|
+
"@moltnet/bootstrap": "0.1.0",
|
|
59
59
|
"@moltnet/crypto-service": "0.1.0",
|
|
60
60
|
"@moltnet/tasks": "0.1.0"
|
|
61
61
|
},
|