arisa 5.1.66 → 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-health.js +5 -2
- 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 +130 -186
- 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 +192 -38
- package/src/index.js +14 -2
- package/src/official-tools.lock.json +430 -60
- 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 +2 -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 +56 -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/slave-cli.test.js +20 -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 +147 -4
- package/test/tui.test.js +41 -0
- package/test/weighted-resource-governor.test.js +103 -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,11 +41,18 @@ 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
|
-
return {
|
|
48
|
+
return {
|
|
49
|
+
resourceClass,
|
|
50
|
+
weight,
|
|
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)
|
|
55
|
+
};
|
|
28
56
|
}
|
|
29
57
|
|
|
30
58
|
export function normalizeToolExecutionPolicy(policy = {}) {
|
|
@@ -38,6 +66,16 @@ export function normalizeToolExecutionPolicy(policy = {}) {
|
|
|
38
66
|
return {
|
|
39
67
|
defaultCapacity: positiveInteger(policy?.defaultCapacity, defaultCapacity),
|
|
40
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),
|
|
41
79
|
capacities
|
|
42
80
|
};
|
|
43
81
|
}
|
|
@@ -47,14 +85,26 @@ function noopLease() {
|
|
|
47
85
|
}
|
|
48
86
|
|
|
49
87
|
export class WeightedResourceGovernor {
|
|
50
|
-
constructor({
|
|
88
|
+
constructor({
|
|
89
|
+
policy,
|
|
90
|
+
logger,
|
|
91
|
+
now = () => Date.now(),
|
|
92
|
+
memoryUsage = () => process.memoryUsage(),
|
|
93
|
+
memoryPressure = readMemoryPressure
|
|
94
|
+
} = {}) {
|
|
51
95
|
this.policy = normalizeToolExecutionPolicy(policy);
|
|
52
96
|
this.logger = logger;
|
|
53
97
|
this.now = now;
|
|
54
98
|
this.memoryUsage = memoryUsage;
|
|
99
|
+
this.memoryPressure = memoryPressure;
|
|
55
100
|
this.resources = new Map();
|
|
101
|
+
this.memoryProfiles = new Map();
|
|
102
|
+
this.activeMemoryMb = 0;
|
|
103
|
+
this.lastMemoryBudgetMb = 0;
|
|
56
104
|
this.peakRssBytes = 0;
|
|
57
105
|
this.lastLoggedRssBytes = 0;
|
|
106
|
+
this.lastPressure = null;
|
|
107
|
+
this.draining = false;
|
|
58
108
|
}
|
|
59
109
|
|
|
60
110
|
capacityFor(resourceClass) {
|
|
@@ -74,75 +124,179 @@ export class WeightedResourceGovernor {
|
|
|
74
124
|
const rss = Number(this.memoryUsage()?.rss) || 0;
|
|
75
125
|
if (rss <= this.peakRssBytes) return;
|
|
76
126
|
this.peakRssBytes = rss;
|
|
77
|
-
const logStepBytes = 8 *
|
|
127
|
+
const logStepBytes = 8 * mebibyte;
|
|
78
128
|
if (this.lastLoggedRssBytes && rss - this.lastLoggedRssBytes < logStepBytes) return;
|
|
79
129
|
this.lastLoggedRssBytes = rss;
|
|
80
|
-
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);
|
|
81
171
|
}
|
|
82
172
|
|
|
83
|
-
createLease(
|
|
173
|
+
createLease(request, waitedMs) {
|
|
84
174
|
let released = false;
|
|
85
175
|
return {
|
|
86
176
|
waitedMs,
|
|
87
|
-
|
|
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 = {}) => {
|
|
88
182
|
if (released) return;
|
|
89
183
|
released = true;
|
|
90
|
-
const state = this.stateFor(resourceClass);
|
|
91
|
-
state.activeWeight = Math.max(0, state.activeWeight - weight);
|
|
92
|
-
this.
|
|
93
|
-
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
|
+
});
|
|
94
192
|
}
|
|
95
193
|
};
|
|
96
194
|
}
|
|
97
195
|
|
|
98
|
-
grant(
|
|
99
|
-
const state = this.stateFor(resourceClass);
|
|
196
|
+
grant(request) {
|
|
197
|
+
const state = this.stateFor(request.resourceClass);
|
|
100
198
|
state.activeWeight += request.weight;
|
|
199
|
+
this.activeMemoryMb += request.memoryMb;
|
|
101
200
|
const waitedMs = Math.max(0, this.now() - request.queuedAt);
|
|
102
|
-
this.observeMemory(resourceClass);
|
|
201
|
+
this.observeMemory(request.resourceClass);
|
|
103
202
|
if (waitedMs > 0) {
|
|
104
|
-
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`);
|
|
105
204
|
}
|
|
106
|
-
request.resolve(this.createLease(
|
|
205
|
+
request.resolve(this.createLease(request, waitedMs));
|
|
107
206
|
}
|
|
108
207
|
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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;
|
|
117
253
|
}
|
|
118
254
|
}
|
|
119
255
|
|
|
120
|
-
acquire(
|
|
121
|
-
|
|
256
|
+
async acquire(rawExecution, label = "tool") {
|
|
257
|
+
const execution = normalizeToolExecution(rawExecution);
|
|
258
|
+
if (!execution) return noopLease();
|
|
122
259
|
const resourceClass = execution.resourceClass;
|
|
123
260
|
const capacity = this.capacityFor(resourceClass);
|
|
124
261
|
const weight = Math.min(execution.weight, capacity);
|
|
125
262
|
const state = this.stateFor(resourceClass);
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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 }));
|
|
133
281
|
}
|
|
134
282
|
if (state.queue.length >= this.policy.maxQueuedPerClass) {
|
|
135
283
|
throw new Error(`Tool execution queue is full for resource class ${resourceClass}`);
|
|
136
284
|
}
|
|
137
|
-
this.logger?.log("tools", `${label} queued for ${resourceClass} capacity (${
|
|
138
|
-
return new Promise((resolve) => {
|
|
139
|
-
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 });
|
|
140
288
|
});
|
|
141
289
|
}
|
|
142
290
|
|
|
143
291
|
snapshot() {
|
|
144
292
|
return {
|
|
145
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
|
+
},
|
|
146
300
|
resources: Object.fromEntries([...this.resources.entries()].map(([name, state]) => [name, {
|
|
147
301
|
capacity: this.capacityFor(name),
|
|
148
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) {
|