arisa 5.1.68 → 5.2.7
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/README.md +7 -4
- package/package.json +1 -1
- package/src/core/agent/agent-manager.js +46 -6
- package/src/core/agent/agent-session-lifecycle.js +80 -3
- package/src/core/agent/core-tools.js +1 -1
- package/src/core/agent/pi-auth-login.js +1 -1
- package/src/core/agent/pi-runtime.js +1 -1
- package/src/core/agent/runtime-context.js +1 -1
- package/src/core/agent/worker-heap-circuit-breaker.js +122 -0
- package/src/core/artifacts/artifact-store.js +1 -1
- package/src/core/capabilities/capability-service.js +1 -1
- package/src/core/config/config-defaults.js +30 -1
- package/src/core/config/config-store.js +1 -1
- package/src/core/conversation/session-seed-store.js +1 -1
- package/src/core/tasks/task-store.js +1 -1
- package/src/core/tools/daemon-client.js +180 -0
- package/src/core/tools/daemon-processes.js +19 -3
- package/src/core/tools/daemon-protocol.js +72 -0
- package/src/core/tools/daemon-runtime.js +13 -490
- package/src/core/tools/daemon-worker.js +310 -0
- package/src/core/tools/ipc-client.js +2 -2
- package/src/core/tools/memory-pressure.js +56 -0
- package/src/core/tools/official-tool-installer.js +1 -1
- package/src/core/tools/tool-config.js +1 -1
- package/src/core/tools/tool-process-output.js +100 -0
- package/src/core/tools/tool-process-runner.js +175 -0
- package/src/core/tools/tool-registry.js +99 -187
- package/src/core/tools/tool-resource-note-store.js +1 -1
- package/src/core/tools/tool-usage-store.js +1 -1
- package/src/core/tools/weighted-resource-governor.js +188 -38
- package/src/index.js +14 -2
- package/src/official-tools.lock.json +424 -50
- package/src/platform/paths.js +152 -0
- package/src/runtime/bootstrap-cli.js +121 -0
- package/src/runtime/bootstrap-config.js +97 -0
- package/src/runtime/bootstrap-telegram.js +325 -0
- package/src/runtime/bootstrap.js +6 -543
- package/src/runtime/doctor.js +6 -3
- package/src/runtime/flush.js +1 -1
- package/src/runtime/ipc/ipc-server.js +1 -1
- package/src/runtime/log-viewer.js +1 -1
- package/src/runtime/oom-protection.js +20 -0
- package/src/runtime/paths.js +3 -151
- package/src/runtime/restart-receipt.js +1 -1
- package/src/runtime/service-manager.js +1 -1
- package/src/runtime/service-supervisor.js +14 -0
- package/src/runtime/slave-cli.js +1 -1
- package/src/runtime/tool-process-supervisor.js +1 -1
- package/src/runtime/tui.js +200 -0
- package/src/runtime/update-manager.js +1 -1
- package/src/runtime/worker-recovery-report.js +142 -0
- package/src/transport/telegram/bot.js +42 -320
- package/src/transport/telegram/prompt-builders.js +8 -3
- package/src/transport/telegram/telegram-prompt-controller.js +346 -0
- package/src/transport/telegram/workspace-topic-store.js +1 -1
- package/test/agent-session-lifecycle.test.js +92 -0
- package/test/architecture-boundaries.test.js +29 -0
- package/test/bootstrap.test.js +65 -0
- package/test/daemon-process-invocation.test.js +27 -0
- package/test/daemon-runtime.test.js +36 -1
- package/test/doctor.test.js +22 -0
- package/test/memory-pressure.test.js +36 -0
- package/test/model-selection.test.js +11 -1
- package/test/official-tool-dependencies.test.js +1 -1
- package/test/official-tool-installer.test.js +18 -1
- package/test/oom-protection.test.js +32 -0
- package/test/paths.test.js +7 -0
- package/test/pi-compaction.test.js +9 -0
- package/test/service-manager.test.js +6 -1
- package/test/telegram-prompt-controller.test.js +81 -0
- package/test/telegram-text-artifact.test.js +30 -0
- package/test/tool-registry-run.test.js +108 -4
- package/test/tui.test.js +41 -0
- package/test/weighted-resource-governor.test.js +97 -5
- package/test/worker-heap-circuit-breaker.test.js +79 -0
- package/test/worker-recovery-report.test.js +69 -0
- package/test-fixtures/fake-daemon.js +5 -0
|
@@ -1,11 +1,32 @@
|
|
|
1
|
+
import { memoryPressureReason, readMemoryPressure } from "./memory-pressure.js";
|
|
2
|
+
|
|
1
3
|
const defaultCapacity = 2;
|
|
2
4
|
const defaultMaxQueuedPerClass = 100;
|
|
5
|
+
const defaultMaxWorkerRssMb = 384;
|
|
6
|
+
const defaultMaxSwapUsedPercent = 95;
|
|
7
|
+
const defaultInitialToolMemoryMb = 384;
|
|
8
|
+
const defaultMinimumToolMemoryMb = 128;
|
|
9
|
+
const defaultMaximumToolMemoryMb = 4096;
|
|
10
|
+
const defaultSystemReserveMb = 128;
|
|
11
|
+
const defaultCoreReserveMb = 384;
|
|
12
|
+
const defaultToolHeapPercent = 65;
|
|
13
|
+
const defaultToolMemoryHighPercent = 85;
|
|
14
|
+
const defaultToolSwapMaxMb = 128;
|
|
15
|
+
const defaultMaxToolHeapMb = 4096;
|
|
16
|
+
const defaultMaxToolMemoryMb = 16_384;
|
|
17
|
+
const defaultMaxToolOutputBytes = 1_048_576;
|
|
18
|
+
const mebibyte = 1024 * 1024;
|
|
3
19
|
|
|
4
20
|
function positiveInteger(value, fallback) {
|
|
5
21
|
const parsed = Number(value);
|
|
6
22
|
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
7
23
|
}
|
|
8
24
|
|
|
25
|
+
function boundedInteger(value, fallback, minimum, maximum) {
|
|
26
|
+
const parsed = Number(value);
|
|
27
|
+
return Number.isSafeInteger(parsed) && parsed >= minimum ? Math.min(parsed, maximum) : fallback;
|
|
28
|
+
}
|
|
29
|
+
|
|
9
30
|
function resourceClassName(value) {
|
|
10
31
|
const name = String(value || "").trim();
|
|
11
32
|
if (!name) return "";
|
|
@@ -20,14 +41,17 @@ export function normalizeToolExecution(execution) {
|
|
|
20
41
|
if (!execution || typeof execution !== "object" || Array.isArray(execution)) {
|
|
21
42
|
throw new Error("Tool execution policy must be an object");
|
|
22
43
|
}
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
const weight = positiveInteger(
|
|
44
|
+
const configured = execution;
|
|
45
|
+
const resourceClass = resourceClassName(configured.resourceClass || "default");
|
|
46
|
+
const weight = configured.weight == null ? 1 : positiveInteger(configured.weight, 0);
|
|
26
47
|
if (!weight) throw new Error("Tool execution weight must be a positive integer");
|
|
27
48
|
return {
|
|
28
49
|
resourceClass,
|
|
29
50
|
weight,
|
|
30
|
-
deduplicateConcurrent:
|
|
51
|
+
deduplicateConcurrent: configured.deduplicateConcurrent === true,
|
|
52
|
+
maxHeapMb: boundedInteger(configured.maxHeapMb, defaultMaxToolHeapMb, 64, 4096),
|
|
53
|
+
maxMemoryMb: boundedInteger(configured.maxMemoryMb, defaultMaxToolMemoryMb, 128, 16_384),
|
|
54
|
+
maxOutputBytes: boundedInteger(configured.maxOutputBytes, defaultMaxToolOutputBytes, 65_536, 16_777_216)
|
|
31
55
|
};
|
|
32
56
|
}
|
|
33
57
|
|
|
@@ -42,6 +66,16 @@ export function normalizeToolExecutionPolicy(policy = {}) {
|
|
|
42
66
|
return {
|
|
43
67
|
defaultCapacity: positiveInteger(policy?.defaultCapacity, defaultCapacity),
|
|
44
68
|
maxQueuedPerClass: positiveInteger(policy?.maxQueuedPerClass, defaultMaxQueuedPerClass),
|
|
69
|
+
maxWorkerRssMb: boundedInteger(policy?.maxWorkerRssMb, defaultMaxWorkerRssMb, 64, 65_536),
|
|
70
|
+
maxSwapUsedPercent: boundedInteger(policy?.maxSwapUsedPercent, defaultMaxSwapUsedPercent, 1, 100),
|
|
71
|
+
initialToolMemoryMb: boundedInteger(policy?.initialToolMemoryMb, defaultInitialToolMemoryMb, 128, 16_384),
|
|
72
|
+
minimumToolMemoryMb: boundedInteger(policy?.minimumToolMemoryMb, defaultMinimumToolMemoryMb, 64, 4096),
|
|
73
|
+
maximumToolMemoryMb: boundedInteger(policy?.maximumToolMemoryMb, defaultMaximumToolMemoryMb, 128, 16_384),
|
|
74
|
+
systemReserveMb: boundedInteger(policy?.systemReserveMb, defaultSystemReserveMb, 32, 65_536),
|
|
75
|
+
coreReserveMb: boundedInteger(policy?.coreReserveMb, defaultCoreReserveMb, 64, 65_536),
|
|
76
|
+
toolHeapPercent: boundedInteger(policy?.toolHeapPercent, defaultToolHeapPercent, 25, 90),
|
|
77
|
+
toolMemoryHighPercent: boundedInteger(policy?.toolMemoryHighPercent, defaultToolMemoryHighPercent, 50, 95),
|
|
78
|
+
toolSwapMaxMb: boundedInteger(policy?.toolSwapMaxMb, defaultToolSwapMaxMb, 0, 4096),
|
|
45
79
|
capacities
|
|
46
80
|
};
|
|
47
81
|
}
|
|
@@ -51,14 +85,26 @@ function noopLease() {
|
|
|
51
85
|
}
|
|
52
86
|
|
|
53
87
|
export class WeightedResourceGovernor {
|
|
54
|
-
constructor({
|
|
88
|
+
constructor({
|
|
89
|
+
policy,
|
|
90
|
+
logger,
|
|
91
|
+
now = () => Date.now(),
|
|
92
|
+
memoryUsage = () => process.memoryUsage(),
|
|
93
|
+
memoryPressure = readMemoryPressure
|
|
94
|
+
} = {}) {
|
|
55
95
|
this.policy = normalizeToolExecutionPolicy(policy);
|
|
56
96
|
this.logger = logger;
|
|
57
97
|
this.now = now;
|
|
58
98
|
this.memoryUsage = memoryUsage;
|
|
99
|
+
this.memoryPressure = memoryPressure;
|
|
59
100
|
this.resources = new Map();
|
|
101
|
+
this.memoryProfiles = new Map();
|
|
102
|
+
this.activeMemoryMb = 0;
|
|
103
|
+
this.lastMemoryBudgetMb = 0;
|
|
60
104
|
this.peakRssBytes = 0;
|
|
61
105
|
this.lastLoggedRssBytes = 0;
|
|
106
|
+
this.lastPressure = null;
|
|
107
|
+
this.draining = false;
|
|
62
108
|
}
|
|
63
109
|
|
|
64
110
|
capacityFor(resourceClass) {
|
|
@@ -78,75 +124,179 @@ export class WeightedResourceGovernor {
|
|
|
78
124
|
const rss = Number(this.memoryUsage()?.rss) || 0;
|
|
79
125
|
if (rss <= this.peakRssBytes) return;
|
|
80
126
|
this.peakRssBytes = rss;
|
|
81
|
-
const logStepBytes = 8 *
|
|
127
|
+
const logStepBytes = 8 * mebibyte;
|
|
82
128
|
if (this.lastLoggedRssBytes && rss - this.lastLoggedRssBytes < logStepBytes) return;
|
|
83
129
|
this.lastLoggedRssBytes = rss;
|
|
84
|
-
this.logger?.log("tools", `worker RSS peak ${Math.ceil(rss /
|
|
130
|
+
this.logger?.log("tools", `worker RSS peak ${Math.ceil(rss / mebibyte)} MiB while using ${resourceClass}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
memoryBudgetMb(snapshot) {
|
|
134
|
+
const totalMb = Math.floor((Number(snapshot?.totalBytes) || 0) / mebibyte);
|
|
135
|
+
const configuredMaximum = this.policy.maximumToolMemoryMb;
|
|
136
|
+
if (!totalMb) return configuredMaximum;
|
|
137
|
+
return Math.max(0, Math.min(
|
|
138
|
+
configuredMaximum,
|
|
139
|
+
totalMb - this.policy.systemReserveMb - this.policy.coreReserveMb
|
|
140
|
+
));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
requestedMemoryMb(execution, label, budgetMb) {
|
|
144
|
+
const learned = this.memoryProfiles.get(label)?.recommendedMemoryMb;
|
|
145
|
+
const requested = learned || this.policy.initialToolMemoryMb;
|
|
146
|
+
return Math.min(requested, execution.maxMemoryMb, this.policy.maximumToolMemoryMb, budgetMb);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
heapLimitMb(execution, memoryLimitMb) {
|
|
150
|
+
const proportional = Math.max(64, Math.floor(memoryLimitMb * this.policy.toolHeapPercent / 100));
|
|
151
|
+
return Math.min(execution.maxHeapMb, proportional);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
recordOutcome(label, memoryLimitMb, outcome = {}) {
|
|
155
|
+
const current = this.memoryProfiles.get(label) || {
|
|
156
|
+
recommendedMemoryMb: this.policy.initialToolMemoryMb,
|
|
157
|
+
memoryLimitFailures: 0,
|
|
158
|
+
successes: 0
|
|
159
|
+
};
|
|
160
|
+
if (outcome.memoryLimited) {
|
|
161
|
+
current.memoryLimitFailures += 1;
|
|
162
|
+
current.recommendedMemoryMb = Math.min(
|
|
163
|
+
this.policy.maximumToolMemoryMb,
|
|
164
|
+
Math.max(current.recommendedMemoryMb, memoryLimitMb + 128, Math.ceil(memoryLimitMb * 1.5))
|
|
165
|
+
);
|
|
166
|
+
this.logger?.log("tools", `${label} memory recommendation raised to ${current.recommendedMemoryMb} MiB after isolated limit failure`);
|
|
167
|
+
} else if (outcome.success) {
|
|
168
|
+
current.successes += 1;
|
|
169
|
+
}
|
|
170
|
+
this.memoryProfiles.set(label, current);
|
|
85
171
|
}
|
|
86
172
|
|
|
87
|
-
createLease(
|
|
173
|
+
createLease(request, waitedMs) {
|
|
88
174
|
let released = false;
|
|
89
175
|
return {
|
|
90
176
|
waitedMs,
|
|
91
|
-
|
|
177
|
+
memoryLimitMb: request.memoryMb,
|
|
178
|
+
heapLimitMb: this.heapLimitMb(request.execution, request.memoryMb),
|
|
179
|
+
memoryHighPercent: this.policy.toolMemoryHighPercent,
|
|
180
|
+
swapMaxMb: this.policy.toolSwapMaxMb,
|
|
181
|
+
release: (outcome = {}) => {
|
|
92
182
|
if (released) return;
|
|
93
183
|
released = true;
|
|
94
|
-
const state = this.stateFor(resourceClass);
|
|
95
|
-
state.activeWeight = Math.max(0, state.activeWeight - weight);
|
|
96
|
-
this.
|
|
97
|
-
this.
|
|
184
|
+
const state = this.stateFor(request.resourceClass);
|
|
185
|
+
state.activeWeight = Math.max(0, state.activeWeight - request.weight);
|
|
186
|
+
this.activeMemoryMb = Math.max(0, this.activeMemoryMb - request.memoryMb);
|
|
187
|
+
this.recordOutcome(request.label, request.memoryMb, outcome);
|
|
188
|
+
this.observeMemory(request.resourceClass);
|
|
189
|
+
this.drainAll().catch((error) => {
|
|
190
|
+
this.logger?.error("tools", `could not drain tool execution queues: ${error?.message || String(error)}`);
|
|
191
|
+
});
|
|
98
192
|
}
|
|
99
193
|
};
|
|
100
194
|
}
|
|
101
195
|
|
|
102
|
-
grant(
|
|
103
|
-
const state = this.stateFor(resourceClass);
|
|
196
|
+
grant(request) {
|
|
197
|
+
const state = this.stateFor(request.resourceClass);
|
|
104
198
|
state.activeWeight += request.weight;
|
|
199
|
+
this.activeMemoryMb += request.memoryMb;
|
|
105
200
|
const waitedMs = Math.max(0, this.now() - request.queuedAt);
|
|
106
|
-
this.observeMemory(resourceClass);
|
|
201
|
+
this.observeMemory(request.resourceClass);
|
|
107
202
|
if (waitedMs > 0) {
|
|
108
|
-
this.logger?.log("tools", `${request.label} acquired ${resourceClass} capacity after ${waitedMs}ms`);
|
|
203
|
+
this.logger?.log("tools", `${request.label} acquired ${request.resourceClass} capacity and ${request.memoryMb} MiB after ${waitedMs}ms`);
|
|
109
204
|
}
|
|
110
|
-
request.resolve(this.createLease(
|
|
205
|
+
request.resolve(this.createLease(request, waitedMs));
|
|
111
206
|
}
|
|
112
207
|
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
208
|
+
async pressureSnapshot(label, resourceClass) {
|
|
209
|
+
const pressure = await this.memoryPressure();
|
|
210
|
+
this.lastPressure = pressure;
|
|
211
|
+
this.lastMemoryBudgetMb = this.memoryBudgetMb(pressure);
|
|
212
|
+
const reason = memoryPressureReason(pressure, this.policy);
|
|
213
|
+
if (!reason) return pressure;
|
|
214
|
+
const error = new Error(`Tool ${label} was not started because ${reason}`);
|
|
215
|
+
error.code = "TOOL_RESOURCE_PRESSURE";
|
|
216
|
+
this.logger?.log("tools", `${label} rejected for ${resourceClass}: ${reason}`);
|
|
217
|
+
throw error;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
canGrant(request) {
|
|
221
|
+
const state = this.stateFor(request.resourceClass);
|
|
222
|
+
return state.activeWeight + request.weight <= this.capacityFor(request.resourceClass)
|
|
223
|
+
&& this.activeMemoryMb + request.memoryMb <= this.lastMemoryBudgetMb;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async drainAll() {
|
|
227
|
+
if (this.draining) return;
|
|
228
|
+
this.draining = true;
|
|
229
|
+
try {
|
|
230
|
+
let progressed = true;
|
|
231
|
+
while (progressed) {
|
|
232
|
+
progressed = false;
|
|
233
|
+
for (const [resourceClass, state] of this.resources) {
|
|
234
|
+
const next = state.queue[0];
|
|
235
|
+
if (!next) continue;
|
|
236
|
+
try {
|
|
237
|
+
const pressure = await this.pressureSnapshot(next.label, resourceClass);
|
|
238
|
+
const budgetMb = this.memoryBudgetMb(pressure);
|
|
239
|
+
next.memoryMb = this.requestedMemoryMb(next.execution, next.label, budgetMb);
|
|
240
|
+
if (next.memoryMb < this.policy.minimumToolMemoryMb || !this.canGrant(next)) continue;
|
|
241
|
+
state.queue.shift();
|
|
242
|
+
this.grant(next);
|
|
243
|
+
progressed = true;
|
|
244
|
+
} catch (error) {
|
|
245
|
+
state.queue.shift();
|
|
246
|
+
next.reject(error);
|
|
247
|
+
progressed = true;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
} finally {
|
|
252
|
+
this.draining = false;
|
|
121
253
|
}
|
|
122
254
|
}
|
|
123
255
|
|
|
124
|
-
acquire(
|
|
125
|
-
|
|
256
|
+
async acquire(rawExecution, label = "tool") {
|
|
257
|
+
const execution = normalizeToolExecution(rawExecution);
|
|
258
|
+
if (!execution) return noopLease();
|
|
126
259
|
const resourceClass = execution.resourceClass;
|
|
127
260
|
const capacity = this.capacityFor(resourceClass);
|
|
128
261
|
const weight = Math.min(execution.weight, capacity);
|
|
129
262
|
const state = this.stateFor(resourceClass);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
263
|
+
const pressure = await this.pressureSnapshot(label, resourceClass);
|
|
264
|
+
const budgetMb = this.memoryBudgetMb(pressure);
|
|
265
|
+
const memoryMb = this.requestedMemoryMb(execution, label, budgetMb);
|
|
266
|
+
if (budgetMb < this.policy.minimumToolMemoryMb || memoryMb < this.policy.minimumToolMemoryMb) {
|
|
267
|
+
const error = new Error(`Tool ${label} was not started because the global tool memory pool is ${budgetMb} MiB`);
|
|
268
|
+
error.code = "TOOL_RESOURCE_PRESSURE";
|
|
269
|
+
throw error;
|
|
270
|
+
}
|
|
271
|
+
const request = {
|
|
272
|
+
execution,
|
|
273
|
+
resourceClass,
|
|
274
|
+
weight,
|
|
275
|
+
memoryMb,
|
|
276
|
+
label,
|
|
277
|
+
queuedAt: this.now()
|
|
278
|
+
};
|
|
279
|
+
if (!state.queue.length && this.canGrant(request)) {
|
|
280
|
+
return new Promise((resolve) => this.grant({ ...request, resolve }));
|
|
137
281
|
}
|
|
138
282
|
if (state.queue.length >= this.policy.maxQueuedPerClass) {
|
|
139
283
|
throw new Error(`Tool execution queue is full for resource class ${resourceClass}`);
|
|
140
284
|
}
|
|
141
|
-
this.logger?.log("tools", `${label} queued for ${resourceClass} capacity (${
|
|
142
|
-
return new Promise((resolve) => {
|
|
143
|
-
state.queue.push({
|
|
285
|
+
this.logger?.log("tools", `${label} queued for ${resourceClass} capacity and global memory (${this.activeMemoryMb}/${budgetMb} MiB)`);
|
|
286
|
+
return new Promise((resolve, reject) => {
|
|
287
|
+
state.queue.push({ ...request, resolve, reject });
|
|
144
288
|
});
|
|
145
289
|
}
|
|
146
290
|
|
|
147
291
|
snapshot() {
|
|
148
292
|
return {
|
|
149
293
|
peakRssBytes: this.peakRssBytes,
|
|
294
|
+
memoryPressure: this.lastPressure,
|
|
295
|
+
memory: {
|
|
296
|
+
budgetMb: this.lastMemoryBudgetMb,
|
|
297
|
+
activeMb: this.activeMemoryMb,
|
|
298
|
+
profiles: Object.fromEntries([...this.memoryProfiles.entries()].map(([name, profile]) => [name, { ...profile }]))
|
|
299
|
+
},
|
|
150
300
|
resources: Object.fromEntries([...this.resources.entries()].map(([name, state]) => [name, {
|
|
151
301
|
capacity: this.capacityFor(name),
|
|
152
302
|
activeWeight: state.activeWeight,
|
package/src/index.js
CHANGED
|
@@ -6,11 +6,14 @@ import { loadConfig } from "./core/config/config-store.js";
|
|
|
6
6
|
import { createLogger } from "./runtime/logger.js";
|
|
7
7
|
import { getServiceStatus, handoffServiceRestart, registerServiceProcess, restartService, serviceEntryFile, startService, stopService, unregisterServiceProcess } from "./runtime/service-manager.js";
|
|
8
8
|
import { createServiceSupervisor } from "./runtime/service-supervisor.js";
|
|
9
|
+
import { recordUnexpectedWorkerExit } from "./runtime/worker-recovery-report.js";
|
|
9
10
|
import { flushArisaHome } from "./runtime/flush.js";
|
|
10
11
|
import { readPackageVersion, showServiceLogs } from "./runtime/log-viewer.js";
|
|
11
|
-
import { arisaPackageDir } from "./
|
|
12
|
+
import { arisaPackageDir } from "./platform/paths.js";
|
|
12
13
|
import { runSlaveCli } from "./runtime/slave-cli.js";
|
|
13
14
|
import { unregisterSlaveServiceProcess } from "./runtime/slave-service.js";
|
|
15
|
+
import { protectCoreFromOom } from "./runtime/oom-protection.js";
|
|
16
|
+
import { runTui } from "./runtime/tui.js";
|
|
14
17
|
|
|
15
18
|
process.env.ARISA_PACKAGE_DIR = arisaPackageDir;
|
|
16
19
|
|
|
@@ -25,6 +28,9 @@ const slaveCommand = command === "slave";
|
|
|
25
28
|
const slaveServiceRunner = slaveCommand && serviceRunner;
|
|
26
29
|
const runtimeOverrides = toNestedOverrides(cli.nestedFlags);
|
|
27
30
|
const logger = createLogger({ verbose });
|
|
31
|
+
if (command === "run" || command === "tui" || serviceRunner || serviceWorker || slaveServiceRunner) {
|
|
32
|
+
await protectCoreFromOom({ logger });
|
|
33
|
+
}
|
|
28
34
|
let activeApp = null;
|
|
29
35
|
let shuttingDown = false;
|
|
30
36
|
|
|
@@ -245,7 +251,8 @@ async function main() {
|
|
|
245
251
|
restartBackoffMs: persistedConfig.service.workerRestartBackoffMs,
|
|
246
252
|
restartBackoffMaxMs: persistedConfig.service.workerRestartBackoffMaxMs,
|
|
247
253
|
stableRuntimeMs: persistedConfig.service.workerStableRuntimeMs,
|
|
248
|
-
logger
|
|
254
|
+
logger,
|
|
255
|
+
onUnexpectedExit: recordUnexpectedWorkerExit
|
|
249
256
|
});
|
|
250
257
|
activeApp = supervisor;
|
|
251
258
|
await supervisor.start();
|
|
@@ -257,6 +264,11 @@ async function main() {
|
|
|
257
264
|
return;
|
|
258
265
|
}
|
|
259
266
|
|
|
267
|
+
if (command === "tui") {
|
|
268
|
+
await runTui({ logger });
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
|
|
260
272
|
if (command === "start") {
|
|
261
273
|
const bootstrapResult = await bootstrapIfNeeded({ force: forceBootstrap });
|
|
262
274
|
if (bootstrapResult.configCreated && bootstrapResult.viaTelegram && !bootstrapResult.startInBackground) {
|