@nowcrew/daemon 0.6.29 → 0.6.31
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/agent-ability/materializer.js +4 -4
- package/dist/config.js +3 -3
- package/dist/execution-runner.js +17 -13
- package/dist/host-execution-coordinator.js +169 -52
- package/dist/local-executor.js +107 -34
- package/dist/project-skills/reconciler.js +5 -2
- package/dist/remote/claude-bridge.js +558 -0
- package/dist/remote/claude-channel.js +164 -0
- package/dist/remote/codex-client.js +451 -0
- package/dist/remote/codex-runtime.js +77 -0
- package/dist/remote/config.js +135 -0
- package/dist/remote/gateway.js +879 -0
- package/dist/remote/identity.js +39 -0
- package/dist/remote/owner.js +77 -0
- package/dist/remote/protocol.js +211 -0
- package/dist/remote/remote-cli.js +254 -0
- package/dist/remote/runtime-probe.js +182 -0
- package/dist/remote/session-discovery.js +249 -0
- package/dist/remote/wrapper.js +40 -0
- package/dist/remote-web/assets/index-B_6VM_tw.js +94 -0
- package/dist/remote-web/assets/index-L6EiQbJn.css +1 -0
- package/dist/remote-web/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/remote-web/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/remote-web/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/remote-web/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/remote-web/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/remote-web/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/remote-web/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/remote-web/icons/nowwork-192.png +0 -0
- package/dist/remote-web/icons/nowwork-512.png +0 -0
- package/dist/remote-web/icons/nowwork.svg +7 -0
- package/dist/remote-web/index.html +20 -0
- package/dist/remote-web/manifest.webmanifest +13 -0
- package/dist/remote-web/sw.js +12 -0
- package/dist/runner.js +6 -1
- package/dist/runtime-startup-gate.js +47 -23
- package/dist/runtimes/codex-app-server-runner.js +6 -0
- package/dist/serve.js +55 -3
- package/dist/shared-execution-slots.js +75 -16
- package/package.json +1 -1
package/dist/serve.js
CHANGED
|
@@ -80,7 +80,11 @@ export function serve(config, opts = {}) {
|
|
|
80
80
|
let runtimeFacts = null;
|
|
81
81
|
const runtimeProbe = createRuntimeProbeCoordinator();
|
|
82
82
|
const hostCoordinator = opts.execution?.hostCoordinator
|
|
83
|
-
?? createHostExecutionCoordinator({
|
|
83
|
+
?? createHostExecutionCoordinator({
|
|
84
|
+
executionSlots: config.executionLimits.maxParallelTotal,
|
|
85
|
+
startupSlots: config.executionLimits.maxStartingTotal,
|
|
86
|
+
startupGapMs: config.executionLimits.startupGapMs,
|
|
87
|
+
});
|
|
84
88
|
const localSlots = createSharedSlotManager(config.executionLimits);
|
|
85
89
|
const sharedSlots = hostCoordinatedSlotManager(localSlots, hostCoordinator);
|
|
86
90
|
const runtimeStartupGate = hostCoordinatedStartupGate(createRuntimeStartupGate(config.executionLimits), hostCoordinator);
|
|
@@ -502,7 +506,9 @@ export function serve(config, opts = {}) {
|
|
|
502
506
|
task_key: spec.workspace.taskKey,
|
|
503
507
|
});
|
|
504
508
|
}
|
|
505
|
-
const executionClass =
|
|
509
|
+
const executionClass = pruneTraceId !== null
|
|
510
|
+
? "memory_prune"
|
|
511
|
+
: spec.context.scheduledRunId === undefined ? "normal" : "scheduled";
|
|
506
512
|
const reservation = sharedSlots.reserve(spec.agent.handle, "execution", executionClass);
|
|
507
513
|
if (!reservation.accepted) {
|
|
508
514
|
dslog("execution.machine_queue_rejected", "机器执行队列已满", {
|
|
@@ -604,19 +610,49 @@ export function serve(config, opts = {}) {
|
|
|
604
610
|
report: reportExecutionFrame,
|
|
605
611
|
startupGate: runtimeStartupGate,
|
|
606
612
|
startupTimeoutMs: config.executionLimits.startupTimeoutMs,
|
|
613
|
+
onRuntimePhase: (phase) => {
|
|
614
|
+
if (phase === "starting")
|
|
615
|
+
reservation.markStarting();
|
|
616
|
+
else
|
|
617
|
+
reservation.markRunning();
|
|
618
|
+
const snapshot = sharedSlots.snapshot();
|
|
619
|
+
dslog(`execution.runtime_${phase}`, `execution runtime ${phase}`, {
|
|
620
|
+
execution_id: spec.executionId,
|
|
621
|
+
agent_handle: spec.agent.handle,
|
|
622
|
+
execution_class: executionClass,
|
|
623
|
+
admitted_total: snapshot.admittedTotal,
|
|
624
|
+
preparing_total: snapshot.preparingTotal,
|
|
625
|
+
starting_total: snapshot.startingTotal,
|
|
626
|
+
running_total: snapshot.runningTotal,
|
|
627
|
+
queued_total: snapshot.queuedTotal,
|
|
628
|
+
memory_prune_preparing_total: snapshot.memoryPrunePreparingTotal,
|
|
629
|
+
memory_prune_starting_total: snapshot.memoryPruneStartingTotal,
|
|
630
|
+
memory_prune_running_total: snapshot.memoryPruneRunningTotal,
|
|
631
|
+
});
|
|
632
|
+
},
|
|
607
633
|
...(reservation.state === undefined ? {} : {
|
|
608
634
|
slot: {
|
|
609
635
|
state: reservation.state,
|
|
610
636
|
ready: reservation.ready.then(() => {
|
|
611
637
|
markExecutionTaskKeyActive();
|
|
638
|
+
reservation.markPreparing();
|
|
612
639
|
const snapshot = sharedSlots.snapshot();
|
|
613
640
|
dslog("execution.machine_slot_ready", "execution 获得机器执行名额", {
|
|
614
641
|
execution_id: spec.executionId,
|
|
615
642
|
agent_handle: spec.agent.handle,
|
|
616
643
|
execution_class: executionClass,
|
|
617
644
|
queue_ms: Date.now() - machineQueueEnteredAt,
|
|
618
|
-
active_total: snapshot.
|
|
645
|
+
active_total: snapshot.runningTotal,
|
|
646
|
+
admitted_total: snapshot.admittedTotal,
|
|
647
|
+
preparing_total: snapshot.preparingTotal,
|
|
648
|
+
starting_total: snapshot.startingTotal,
|
|
649
|
+
running_total: snapshot.runningTotal,
|
|
619
650
|
queued_total: snapshot.queuedTotal,
|
|
651
|
+
memory_prune_admitted_total: snapshot.memoryPruneAdmittedTotal,
|
|
652
|
+
memory_prune_queued_total: snapshot.memoryPruneQueuedTotal,
|
|
653
|
+
memory_prune_preparing_total: snapshot.memoryPrunePreparingTotal,
|
|
654
|
+
memory_prune_starting_total: snapshot.memoryPruneStartingTotal,
|
|
655
|
+
memory_prune_running_total: snapshot.memoryPruneRunningTotal,
|
|
620
656
|
});
|
|
621
657
|
}),
|
|
622
658
|
},
|
|
@@ -846,6 +882,7 @@ export function serve(config, opts = {}) {
|
|
|
846
882
|
});
|
|
847
883
|
}
|
|
848
884
|
await awaitWithCancellation(legacyReservation.ready, controller.cancellation);
|
|
885
|
+
legacyReservation.markPreparing();
|
|
849
886
|
const queueMs = Date.now() - queueWaitStart;
|
|
850
887
|
const machineSnapshot = sharedSlots.snapshot();
|
|
851
888
|
const threadLabel = threadId ?? null;
|
|
@@ -967,6 +1004,21 @@ export function serve(config, opts = {}) {
|
|
|
967
1004
|
cancellation: controller.cancellation,
|
|
968
1005
|
startupGate: runtimeStartupGate,
|
|
969
1006
|
startupTimeoutMs: config.executionLimits.startupTimeoutMs,
|
|
1007
|
+
onRuntimePhase: (phase) => {
|
|
1008
|
+
if (phase === "starting")
|
|
1009
|
+
legacyReservation?.markStarting();
|
|
1010
|
+
else
|
|
1011
|
+
legacyReservation?.markRunning();
|
|
1012
|
+
const snapshot = sharedSlots.snapshot();
|
|
1013
|
+
dslog(`run.runtime_${phase}`, `legacy runtime ${phase}`, {
|
|
1014
|
+
...runKeys,
|
|
1015
|
+
admitted_total: snapshot.admittedTotal,
|
|
1016
|
+
preparing_total: snapshot.preparingTotal,
|
|
1017
|
+
starting_total: snapshot.startingTotal,
|
|
1018
|
+
running_total: snapshot.runningTotal,
|
|
1019
|
+
queued_total: snapshot.queuedTotal,
|
|
1020
|
+
});
|
|
1021
|
+
},
|
|
970
1022
|
});
|
|
971
1023
|
});
|
|
972
1024
|
const result = mergeRunAgentResults(guarded.results);
|
|
@@ -1,25 +1,44 @@
|
|
|
1
1
|
export function createSharedSlotManager(limits) {
|
|
2
2
|
const activeByHandleAndClass = new Map();
|
|
3
3
|
const queue = [];
|
|
4
|
+
const entries = new Set();
|
|
4
5
|
let activeTotal = 0;
|
|
6
|
+
let activeMemoryPruneTotal = 0;
|
|
5
7
|
let exclusive = false;
|
|
6
|
-
const queuedFor = (handle) => queue.filter((entry) => !entry.released
|
|
8
|
+
const queuedFor = (handle, executionClass) => queue.filter((entry) => !entry.released
|
|
9
|
+
&& entry.handle === handle
|
|
10
|
+
&& (entry.executionClass === "memory_prune") === (executionClass === "memory_prune")).length;
|
|
7
11
|
const activeKey = (handle, executionClass) => `${handle}:${executionClass}`;
|
|
8
12
|
const maxParallelFor = (executionClass) => executionClass === "scheduled"
|
|
9
13
|
? limits.maxParallelScheduledPerAgent
|
|
10
|
-
:
|
|
14
|
+
: executionClass === "memory_prune"
|
|
15
|
+
? 1
|
|
16
|
+
: limits.maxParallelPerAgent;
|
|
11
17
|
const promote = () => {
|
|
12
|
-
while (
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
while (true) {
|
|
19
|
+
const foregroundIndex = activeTotal < limits.maxParallelTotal
|
|
20
|
+
? queue.findIndex((entry) => !entry.released
|
|
21
|
+
&& entry.executionClass !== "memory_prune"
|
|
22
|
+
&& (activeByHandleAndClass.get(activeKey(entry.handle, entry.executionClass)) ?? 0)
|
|
23
|
+
< maxParallelFor(entry.executionClass))
|
|
24
|
+
: -1;
|
|
25
|
+
const memoryPruneIndex = activeMemoryPruneTotal < 1
|
|
26
|
+
? queue.findIndex((entry) => !entry.released
|
|
27
|
+
&& entry.executionClass === "memory_prune"
|
|
28
|
+
&& (activeByHandleAndClass.get(activeKey(entry.handle, entry.executionClass)) ?? 0) < 1)
|
|
29
|
+
: -1;
|
|
30
|
+
const index = foregroundIndex >= 0 ? foregroundIndex : memoryPruneIndex;
|
|
16
31
|
if (index < 0)
|
|
17
32
|
return;
|
|
18
33
|
const [next] = queue.splice(index, 1);
|
|
19
34
|
if (!next || next.released)
|
|
20
35
|
continue;
|
|
21
36
|
next.promoted = true;
|
|
22
|
-
|
|
37
|
+
next.phase = "admitted";
|
|
38
|
+
if (next.executionClass === "memory_prune")
|
|
39
|
+
activeMemoryPruneTotal += 1;
|
|
40
|
+
else
|
|
41
|
+
activeTotal += 1;
|
|
23
42
|
const key = activeKey(next.handle, next.executionClass);
|
|
24
43
|
activeByHandleAndClass.set(key, (activeByHandleAndClass.get(key) ?? 0) + 1);
|
|
25
44
|
next.resolve();
|
|
@@ -29,12 +48,13 @@ export function createSharedSlotManager(limits) {
|
|
|
29
48
|
reserve: (handle, kind, executionClass = "normal") => {
|
|
30
49
|
const key = activeKey(handle, executionClass);
|
|
31
50
|
const activeForAgent = activeByHandleAndClass.get(key) ?? 0;
|
|
32
|
-
const queuedForAgent = queuedFor(handle);
|
|
51
|
+
const queuedForAgent = queuedFor(handle, executionClass);
|
|
52
|
+
const laneQueuedTotal = queue.filter((entry) => (entry.executionClass === "memory_prune") === (executionClass === "memory_prune")).length;
|
|
33
53
|
const facts = {
|
|
34
54
|
activeForAgent,
|
|
35
55
|
queuedForAgent,
|
|
36
|
-
activeTotal,
|
|
37
|
-
queuedTotal:
|
|
56
|
+
activeTotal: executionClass === "memory_prune" ? activeMemoryPruneTotal : activeTotal,
|
|
57
|
+
queuedTotal: laneQueuedTotal,
|
|
38
58
|
};
|
|
39
59
|
if (exclusive) {
|
|
40
60
|
return {
|
|
@@ -42,19 +62,27 @@ export function createSharedSlotManager(limits) {
|
|
|
42
62
|
facts,
|
|
43
63
|
ready: Promise.resolve(),
|
|
44
64
|
isQueued: () => false,
|
|
65
|
+
markPreparing: () => { },
|
|
66
|
+
markStarting: () => { },
|
|
67
|
+
markRunning: () => { },
|
|
45
68
|
release: () => { },
|
|
46
69
|
};
|
|
47
70
|
}
|
|
48
|
-
const canStartImmediately =
|
|
71
|
+
const canStartImmediately = (executionClass === "memory_prune"
|
|
72
|
+
? activeMemoryPruneTotal < 1
|
|
73
|
+
: activeTotal < limits.maxParallelTotal)
|
|
49
74
|
&& activeForAgent < maxParallelFor(executionClass)
|
|
50
|
-
&&
|
|
75
|
+
&& laneQueuedTotal === 0;
|
|
51
76
|
if (kind === "execution" && !canStartImmediately && (queuedForAgent >= limits.maxQueuedPerAgent
|
|
52
|
-
||
|
|
77
|
+
|| laneQueuedTotal >= limits.maxQueuedTotal)) {
|
|
53
78
|
return {
|
|
54
79
|
accepted: false,
|
|
55
80
|
facts,
|
|
56
81
|
ready: Promise.resolve(),
|
|
57
82
|
isQueued: () => false,
|
|
83
|
+
markPreparing: () => { },
|
|
84
|
+
markStarting: () => { },
|
|
85
|
+
markRunning: () => { },
|
|
58
86
|
release: () => { },
|
|
59
87
|
};
|
|
60
88
|
}
|
|
@@ -65,22 +93,36 @@ export function createSharedSlotManager(limits) {
|
|
|
65
93
|
executionClass,
|
|
66
94
|
released: false,
|
|
67
95
|
promoted: false,
|
|
96
|
+
phase: "queued",
|
|
68
97
|
resolve: resolveReady,
|
|
69
98
|
};
|
|
70
99
|
queue.push(entry);
|
|
100
|
+
entries.add(entry);
|
|
71
101
|
promote();
|
|
102
|
+
const markPhase = (phase) => {
|
|
103
|
+
if (!entry.released && entry.promoted)
|
|
104
|
+
entry.phase = phase;
|
|
105
|
+
};
|
|
72
106
|
return {
|
|
73
107
|
accepted: true,
|
|
74
108
|
facts,
|
|
75
109
|
state: entry.promoted ? "ready" : "queued",
|
|
76
110
|
ready,
|
|
77
111
|
isQueued: () => !entry.promoted && !entry.released,
|
|
112
|
+
markPreparing: () => markPhase("preparing"),
|
|
113
|
+
markStarting: () => markPhase("starting"),
|
|
114
|
+
markRunning: () => markPhase("running"),
|
|
78
115
|
release: () => {
|
|
79
116
|
if (entry.released)
|
|
80
117
|
return;
|
|
81
118
|
entry.released = true;
|
|
119
|
+
entries.delete(entry);
|
|
82
120
|
if (entry.promoted) {
|
|
83
|
-
|
|
121
|
+
if (entry.executionClass === "memory_prune") {
|
|
122
|
+
activeMemoryPruneTotal = Math.max(0, activeMemoryPruneTotal - 1);
|
|
123
|
+
}
|
|
124
|
+
else
|
|
125
|
+
activeTotal = Math.max(0, activeTotal - 1);
|
|
84
126
|
const nextForAgent = Math.max(0, (activeByHandleAndClass.get(key) ?? 1) - 1);
|
|
85
127
|
if (nextForAgent === 0)
|
|
86
128
|
activeByHandleAndClass.delete(key);
|
|
@@ -96,9 +138,26 @@ export function createSharedSlotManager(limits) {
|
|
|
96
138
|
},
|
|
97
139
|
};
|
|
98
140
|
},
|
|
99
|
-
snapshot: () =>
|
|
141
|
+
snapshot: () => {
|
|
142
|
+
const foreground = [...entries].filter((entry) => entry.executionClass !== "memory_prune");
|
|
143
|
+
const memoryPrune = [...entries].filter((entry) => entry.executionClass === "memory_prune");
|
|
144
|
+
const runningTotal = foreground.filter((entry) => entry.phase === "running").length;
|
|
145
|
+
return {
|
|
146
|
+
activeTotal: runningTotal,
|
|
147
|
+
queuedTotal: foreground.filter((entry) => entry.phase === "queued").length,
|
|
148
|
+
admittedTotal: foreground.filter((entry) => entry.promoted).length,
|
|
149
|
+
preparingTotal: foreground.filter((entry) => entry.phase === "preparing" || entry.phase === "admitted").length,
|
|
150
|
+
startingTotal: foreground.filter((entry) => entry.phase === "starting").length,
|
|
151
|
+
runningTotal,
|
|
152
|
+
memoryPruneAdmittedTotal: memoryPrune.filter((entry) => entry.promoted).length,
|
|
153
|
+
memoryPruneQueuedTotal: memoryPrune.filter((entry) => entry.phase === "queued").length,
|
|
154
|
+
memoryPrunePreparingTotal: memoryPrune.filter((entry) => entry.phase === "preparing" || entry.phase === "admitted").length,
|
|
155
|
+
memoryPruneStartingTotal: memoryPrune.filter((entry) => entry.phase === "starting").length,
|
|
156
|
+
memoryPruneRunningTotal: memoryPrune.filter((entry) => entry.phase === "running").length,
|
|
157
|
+
};
|
|
158
|
+
},
|
|
100
159
|
tryAcquireExclusive: () => {
|
|
101
|
-
if (exclusive || activeTotal !== 0 || queue.length !== 0)
|
|
160
|
+
if (exclusive || activeTotal !== 0 || activeMemoryPruneTotal !== 0 || queue.length !== 0)
|
|
102
161
|
return null;
|
|
103
162
|
exclusive = true;
|
|
104
163
|
let released = false;
|