@songsid/agend 2.1.11-beta.3 → 2.1.11-beta.5
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/backend/codex.d.ts +2 -0
- package/dist/backend/codex.js +55 -14
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/muse.d.ts +50 -5
- package/dist/backend/muse.js +166 -32
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/types.d.ts +39 -1
- package/dist/backend/types.js.map +1 -1
- package/dist/command-table.d.ts +33 -0
- package/dist/command-table.js +45 -0
- package/dist/command-table.js.map +1 -1
- package/dist/daemon.d.ts +93 -1
- package/dist/daemon.js +456 -31
- package/dist/daemon.js.map +1 -1
- package/dist/darwin-memory.d.ts +34 -0
- package/dist/darwin-memory.js +160 -0
- package/dist/darwin-memory.js.map +1 -0
- package/dist/fleet-manager.d.ts +10 -0
- package/dist/fleet-manager.js +30 -7
- package/dist/fleet-manager.js.map +1 -1
- package/dist/host-memory.d.ts +3 -2
- package/dist/host-memory.js +14 -0
- package/dist/host-memory.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +11 -0
- package/dist/instance-lifecycle.js +45 -8
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +11 -0
- package/dist/locale.js.map +1 -1
- package/dist/memory-pressure.d.ts +20 -1
- package/dist/memory-pressure.js +87 -6
- package/dist/memory-pressure.js.map +1 -1
- package/dist/resource-report.d.ts +1 -1
- package/dist/resource-report.js +5 -4
- package/dist/resource-report.js.map +1 -1
- package/dist/spawn-gate.d.ts +4 -0
- package/dist/spawn-gate.js +36 -8
- package/dist/spawn-gate.js.map +1 -1
- package/dist/tmux-manager.d.ts +7 -0
- package/dist/tmux-manager.js +19 -0
- package/dist/tmux-manager.js.map +1 -1
- package/dist/topic-commands.d.ts +16 -2
- package/dist/topic-commands.js +85 -94
- package/dist/topic-commands.js.map +1 -1
- package/dist/turn-reply-guard.d.ts +3 -0
- package/dist/turn-reply-guard.js +12 -2
- package/dist/turn-reply-guard.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { HostMemory } from "./host-memory.js";
|
|
2
|
+
export declare const DARWIN_MEMORY_DEADLINE_MS = 2000;
|
|
3
|
+
export declare const DARWIN_MEMORY_CACHE_MS = 30000;
|
|
4
|
+
export declare function unknownDarwinMemory(totalBytes: number): HostMemory;
|
|
5
|
+
/** vm_stat's printed free count excludes speculative pages. Purgeable can overlap inactive. */
|
|
6
|
+
export declare function parseDarwinAvailable(text: string, totalBytes: number): number | null;
|
|
7
|
+
/** sysctl prints binary MiB to two decimals, including the valid unallocated 0/0 pool. */
|
|
8
|
+
export declare function parseDarwinSwap(text: string): Pick<HostMemory, "swapTotalBytes" | "swapFreeBytes">;
|
|
9
|
+
export interface MemoryCommand {
|
|
10
|
+
result: Promise<string | null>;
|
|
11
|
+
/** Physical child close, independent of logical timeout/result. */
|
|
12
|
+
stopped: Promise<void>;
|
|
13
|
+
kill(): void;
|
|
14
|
+
}
|
|
15
|
+
export type MemoryCommandRunner = (file: string, args: string[]) => MemoryCommand;
|
|
16
|
+
export declare const runMemoryCommand: MemoryCommandRunner;
|
|
17
|
+
interface Options {
|
|
18
|
+
run?: MemoryCommandRunner;
|
|
19
|
+
totalmem?: () => number;
|
|
20
|
+
now?: () => number;
|
|
21
|
+
}
|
|
22
|
+
/** One bounded logical read and at most one physical pair, even across stop/restart. */
|
|
23
|
+
export declare class DarwinMemoryProbe {
|
|
24
|
+
private readonly run;
|
|
25
|
+
private readonly total;
|
|
26
|
+
private readonly now;
|
|
27
|
+
private flight;
|
|
28
|
+
private cache;
|
|
29
|
+
private epoch;
|
|
30
|
+
constructor(options?: Options);
|
|
31
|
+
read(): Promise<HostMemory>;
|
|
32
|
+
stop(): void;
|
|
33
|
+
}
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { totalmem } from "node:os";
|
|
3
|
+
export const DARWIN_MEMORY_DEADLINE_MS = 2_000;
|
|
4
|
+
export const DARWIN_MEMORY_CACHE_MS = 30_000;
|
|
5
|
+
const MAX_OUTPUT = 32 * 1024;
|
|
6
|
+
export function unknownDarwinMemory(totalBytes) {
|
|
7
|
+
return { totalBytes, availableBytes: null, availableKind: "unknown", swapTotalBytes: null, swapFreeBytes: null };
|
|
8
|
+
}
|
|
9
|
+
/** vm_stat's printed free count excludes speculative pages. Purgeable can overlap inactive. */
|
|
10
|
+
export function parseDarwinAvailable(text, totalBytes) {
|
|
11
|
+
const headers = [...text.matchAll(/^Mach Virtual Memory Statistics: \(page size of (\d+) bytes\)\s*$/gm)];
|
|
12
|
+
if (headers.length !== 1 || [...text.matchAll(/^Mach Virtual Memory Statistics:/gm)].length !== 1)
|
|
13
|
+
return null;
|
|
14
|
+
const pageSize = Number(headers[0][1]);
|
|
15
|
+
if (!Number.isSafeInteger(pageSize) || pageSize < 1024 || pageSize > 1024 * 1024 || Math.log2(pageSize) % 1 !== 0)
|
|
16
|
+
return null;
|
|
17
|
+
const counts = [];
|
|
18
|
+
for (const name of ["free", "speculative", "inactive", "purgeable"]) {
|
|
19
|
+
const rows = [...text.matchAll(new RegExp(`^Pages ${name}:\\s+(\\d+)\\.\\s*$`, "gm"))];
|
|
20
|
+
if (rows.length !== 1 || [...text.matchAll(new RegExp(`^Pages ${name}:`, "gm"))].length !== 1)
|
|
21
|
+
return null;
|
|
22
|
+
const count = Number(rows[0][1]);
|
|
23
|
+
if (!Number.isSafeInteger(count) || count < 0)
|
|
24
|
+
return null;
|
|
25
|
+
counts.push(count);
|
|
26
|
+
}
|
|
27
|
+
const [free, speculative, inactive, purgeable] = counts;
|
|
28
|
+
const bytes = (free + speculative + Math.max(inactive, purgeable)) * pageSize;
|
|
29
|
+
return Number.isSafeInteger(bytes) && Number.isFinite(totalBytes) && totalBytes > 0 && bytes <= totalBytes ? bytes : null;
|
|
30
|
+
}
|
|
31
|
+
/** sysctl prints binary MiB to two decimals, including the valid unallocated 0/0 pool. */
|
|
32
|
+
export function parseDarwinSwap(text) {
|
|
33
|
+
const unknown = { swapTotalBytes: null, swapFreeBytes: null };
|
|
34
|
+
const rows = [...text.matchAll(/^vm\.swapusage:\s+total = (\d+(?:\.\d+)?)M\s+used = (\d+(?:\.\d+)?)M\s+free = (\d+(?:\.\d+)?)M\s*(?:\(encrypted\))?\s*$/gm)];
|
|
35
|
+
if (rows.length !== 1)
|
|
36
|
+
return unknown;
|
|
37
|
+
const [total, used, free] = rows[0].slice(1).map(Number);
|
|
38
|
+
if (![total, used, free].every(Number.isFinite) || free > total || used > total || Math.abs(total - used - free) > 0.02)
|
|
39
|
+
return unknown;
|
|
40
|
+
const totalBytes = Math.round(total * 1024 ** 2), freeBytes = Math.round(free * 1024 ** 2);
|
|
41
|
+
if (!Number.isSafeInteger(totalBytes) || !Number.isSafeInteger(freeBytes))
|
|
42
|
+
return unknown;
|
|
43
|
+
return { swapTotalBytes: totalBytes, swapFreeBytes: freeBytes };
|
|
44
|
+
}
|
|
45
|
+
export const runMemoryCommand = (file, args) => {
|
|
46
|
+
let resolveResult;
|
|
47
|
+
let resolveStopped;
|
|
48
|
+
const result = new Promise(resolve => { resolveResult = resolve; });
|
|
49
|
+
const stopped = new Promise(resolve => { resolveStopped = resolve; });
|
|
50
|
+
try {
|
|
51
|
+
const child = execFile(file, args, {
|
|
52
|
+
encoding: "utf8", env: { ...process.env, LC_ALL: "C", LANG: "C" },
|
|
53
|
+
timeout: 1_500, killSignal: "SIGKILL", maxBuffer: MAX_OUTPUT,
|
|
54
|
+
}, (error, stdout) => resolveResult(error ? null : stdout));
|
|
55
|
+
child.once("close", resolveStopped);
|
|
56
|
+
// A spawn error normally also emits close. Keep the physical reservation until then.
|
|
57
|
+
child.once("error", () => resolveResult(null));
|
|
58
|
+
return { result, stopped, kill: () => { try {
|
|
59
|
+
child.kill("SIGKILL");
|
|
60
|
+
}
|
|
61
|
+
catch { /* wait for close */ } } };
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
resolveResult(null);
|
|
65
|
+
resolveStopped();
|
|
66
|
+
return { result, stopped, kill: () => { } };
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
/** One bounded logical read and at most one physical pair, even across stop/restart. */
|
|
70
|
+
export class DarwinMemoryProbe {
|
|
71
|
+
run;
|
|
72
|
+
total;
|
|
73
|
+
now;
|
|
74
|
+
flight = null;
|
|
75
|
+
cache = null;
|
|
76
|
+
epoch = 0;
|
|
77
|
+
constructor(options = {}) {
|
|
78
|
+
this.run = options.run ?? runMemoryCommand;
|
|
79
|
+
this.total = options.totalmem ?? totalmem;
|
|
80
|
+
this.now = options.now ?? (() => performance.now());
|
|
81
|
+
}
|
|
82
|
+
read() {
|
|
83
|
+
if (this.cache && this.now() - this.cache.at < DARWIN_MEMORY_CACHE_MS)
|
|
84
|
+
return Promise.resolve({ ...this.cache.memory });
|
|
85
|
+
// A timed-out or cancelled pair still owns its physical reservation.
|
|
86
|
+
if (this.flight) {
|
|
87
|
+
const flight = this.flight;
|
|
88
|
+
if (flight.completed)
|
|
89
|
+
return Promise.resolve(unknownDarwinMemory(this.total()));
|
|
90
|
+
return flight.result.then(value => flight.epoch === this.epoch ? { ...value } : unknownDarwinMemory(this.total()));
|
|
91
|
+
}
|
|
92
|
+
const epoch = ++this.epoch, totalBytes = this.total(), deadlineAt = this.now() + DARWIN_MEMORY_DEADLINE_MS;
|
|
93
|
+
const unknown = unknownDarwinMemory(totalBytes);
|
|
94
|
+
const commands = [];
|
|
95
|
+
let settle;
|
|
96
|
+
let completed = false;
|
|
97
|
+
let timer = null;
|
|
98
|
+
const result = new Promise(resolve => { settle = resolve; });
|
|
99
|
+
const finish = (value) => {
|
|
100
|
+
if (completed)
|
|
101
|
+
return;
|
|
102
|
+
completed = true;
|
|
103
|
+
flight.completed = true;
|
|
104
|
+
if (timer)
|
|
105
|
+
clearTimeout(timer);
|
|
106
|
+
if (epoch === this.epoch)
|
|
107
|
+
this.cache = { at: this.now(), memory: { ...value } };
|
|
108
|
+
settle(value);
|
|
109
|
+
};
|
|
110
|
+
const cancel = () => {
|
|
111
|
+
finish(unknown);
|
|
112
|
+
for (const command of commands) {
|
|
113
|
+
try {
|
|
114
|
+
command.kill();
|
|
115
|
+
}
|
|
116
|
+
catch { /* retain until close */ }
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const flight = { completed: false, epoch, result, cancel };
|
|
120
|
+
this.flight = flight;
|
|
121
|
+
// Start the deadline before either constructor; a slow constructor cannot earn extra time.
|
|
122
|
+
timer = setTimeout(cancel, DARWIN_MEMORY_DEADLINE_MS);
|
|
123
|
+
timer.unref?.();
|
|
124
|
+
for (const [file, args] of [["/usr/bin/vm_stat", []], ["/usr/sbin/sysctl", ["vm.swapusage"]]]) {
|
|
125
|
+
if (this.now() >= deadlineAt) {
|
|
126
|
+
cancel();
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
commands.push(this.run(file, [...args]));
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
commands.push({ result: Promise.resolve(null), stopped: Promise.resolve(), kill: () => { } });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
void Promise.all(commands.map(command => command.result.catch(() => null))).then(outputs => {
|
|
137
|
+
if (completed)
|
|
138
|
+
return;
|
|
139
|
+
if (epoch !== this.epoch || this.now() >= deadlineAt) {
|
|
140
|
+
cancel();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const available = outputs[0] === null || outputs[0] === undefined ? null : parseDarwinAvailable(outputs[0], totalBytes);
|
|
144
|
+
finish(available === null ? unknown : { totalBytes, availableBytes: available, availableKind: "available",
|
|
145
|
+
...parseDarwinSwap(outputs[1] ?? "") });
|
|
146
|
+
});
|
|
147
|
+
// Never release on kill request/result alone. Rejected cleanup remains reserved.
|
|
148
|
+
void Promise.all(commands.map(command => command.stopped.catch(() => new Promise(() => { })))).then(() => {
|
|
149
|
+
if (this.flight === flight)
|
|
150
|
+
this.flight = null;
|
|
151
|
+
});
|
|
152
|
+
return result.then(value => ({ ...value }));
|
|
153
|
+
}
|
|
154
|
+
stop() {
|
|
155
|
+
this.epoch++;
|
|
156
|
+
this.cache = null;
|
|
157
|
+
this.flight?.cancel();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=darwin-memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"darwin-memory.js","sourceRoot":"","sources":["../src/darwin-memory.ts"],"names":[],"mappings":"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"}
|
package/dist/fleet-manager.d.ts
CHANGED
|
@@ -955,6 +955,11 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
|
|
|
955
955
|
};
|
|
956
956
|
/** Start the primary adapter (backward-compatible, sets this.adapter) */
|
|
957
957
|
private startSingleAdapter;
|
|
958
|
+
/**
|
|
959
|
+
* Register a Telegram connection's command menus; any other kind of channel has none to register. Started, not
|
|
960
|
+
* awaited: a slow api.telegram.org must never hold up the adapter's login (each call has its own timeout). Never fatal.
|
|
961
|
+
*/
|
|
962
|
+
private registerTelegramCommandsFor;
|
|
958
963
|
/** Start an additional (non-primary) adapter */
|
|
959
964
|
private startAdditionalAdapter;
|
|
960
965
|
/** Connect IPC to a single instance with all handlers */
|
|
@@ -2131,6 +2136,11 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
|
|
|
2131
2136
|
private effortSuffix;
|
|
2132
2137
|
/** Read recent chat log for agent context */
|
|
2133
2138
|
private getRecentChatLog;
|
|
2139
|
+
/**
|
|
2140
|
+
* The ClassicBot /start replies say how to talk to the agent, and that differs by platform (#1196): on Telegram
|
|
2141
|
+
* you @mention the bot; on Discord, @mention or `/chat`. The chat's platform is the adapter it came through.
|
|
2142
|
+
*/
|
|
2143
|
+
private classicStartKey;
|
|
2134
2144
|
/** Return a user-facing blocker without mutating ClassicBot state. */
|
|
2135
2145
|
private validateClassicStart;
|
|
2136
2146
|
private isBackendInstalled;
|
package/dist/fleet-manager.js
CHANGED
|
@@ -988,6 +988,10 @@ export class FleetManager {
|
|
|
988
988
|
this.logger.debug({ hostMemory: snapshot }, "Host memory sample");
|
|
989
989
|
}
|
|
990
990
|
const changed = snapshot.level !== this.memoryLogLevel;
|
|
991
|
+
if (this.memoryPressure.allowsUnknown(snapshot)) {
|
|
992
|
+
this.memoryLogLevel = snapshot.level;
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
991
995
|
if (snapshot.level === "normal") {
|
|
992
996
|
if (this.memoryLogLevel === "critical" || this.memoryLogLevel === "elevated") {
|
|
993
997
|
this.logger.info({ hostMemory: snapshot }, "Host memory recovered");
|
|
@@ -2790,10 +2794,8 @@ export class FleetManager {
|
|
|
2790
2794
|
// it before lifecycle.start() can turn a crash-loop daemon's dead pane into
|
|
2791
2795
|
// a falsely running instance when lifecycle.start() returns early.
|
|
2792
2796
|
this.instanceProcessStatus.delete(name);
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
}
|
|
2796
|
-
catch { /* consumed or absent */ }
|
|
2797
|
+
// Recovery intent belongs to Daemon.start. lifecycle.start can return
|
|
2798
|
+
// before reaching it, so an await here is not proof the marker was read.
|
|
2797
2799
|
// Auto-connect IPC — daemon.start() ensures socket is ready before resolving
|
|
2798
2800
|
await this.connectIpcToInstance(name);
|
|
2799
2801
|
this.requestDiscordUsagePresenceRefresh();
|
|
@@ -4513,7 +4515,8 @@ export class FleetManager {
|
|
|
4513
4515
|
return;
|
|
4514
4516
|
await this.dispatchSlash(data, adapterId, adapter);
|
|
4515
4517
|
}, this.logger, "adapter.slash_command"));
|
|
4516
|
-
|
|
4518
|
+
// This adapter's own Telegram menus — each Telegram adapter registers its own when it starts (#1191).
|
|
4519
|
+
this.registerTelegramCommandsFor(channelConfig);
|
|
4517
4520
|
// Background-probe each backend's CLI env (version/models) → cli-env cache.
|
|
4518
4521
|
// Non-blocking: /model & status views read the cache; never delays startup.
|
|
4519
4522
|
this.probeCliEnvs();
|
|
@@ -4568,6 +4571,15 @@ export class FleetManager {
|
|
|
4568
4571
|
this.pruneStaleExternalSessions().catch(err => this.logger.debug({ err }, "Session prune failed"));
|
|
4569
4572
|
}, 5 * 60 * 1000);
|
|
4570
4573
|
}
|
|
4574
|
+
/**
|
|
4575
|
+
* Register a Telegram connection's command menus; any other kind of channel has none to register. Started, not
|
|
4576
|
+
* awaited: a slow api.telegram.org must never hold up the adapter's login (each call has its own timeout). Never fatal.
|
|
4577
|
+
*/
|
|
4578
|
+
registerTelegramCommandsFor(channelConfig) {
|
|
4579
|
+
if (channelConfig.type !== "telegram")
|
|
4580
|
+
return;
|
|
4581
|
+
void this.topicCommands.registerBotCommands(channelConfig).catch(e => this.logger.warn({ err: e, adapterId: channelConfig.id ?? channelConfig.type }, "registerBotCommands failed (non-fatal)"));
|
|
4582
|
+
}
|
|
4571
4583
|
/** Start an additional (non-primary) adapter */
|
|
4572
4584
|
async startAdditionalAdapter(channelConfig, registerCommands = true, onStarted) {
|
|
4573
4585
|
const adapterId = channelConfig.id ?? channelConfig.type;
|
|
@@ -4643,6 +4655,9 @@ export class FleetManager {
|
|
|
4643
4655
|
this.logger.error({ err, adapterId }, "Additional adapter fatal error");
|
|
4644
4656
|
this.restartAdapter(adapter, adapterId).catch(() => { });
|
|
4645
4657
|
});
|
|
4658
|
+
// A secondary Telegram connection (a ClassicBot next to a Discord fleet, say) has menus of its own to register —
|
|
4659
|
+
// at fleet start, on retry, and when Settings rebinds it or rotates its token: all of them start it here (#1191).
|
|
4660
|
+
this.registerTelegramCommandsFor(channelConfig);
|
|
4646
4661
|
// Register lifecycle listeners before login; a fast ready/error must not be lost.
|
|
4647
4662
|
await adapter.start();
|
|
4648
4663
|
if (channelConfig.group_id) {
|
|
@@ -11919,6 +11934,14 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
11919
11934
|
return undefined;
|
|
11920
11935
|
}
|
|
11921
11936
|
}
|
|
11937
|
+
/**
|
|
11938
|
+
* The ClassicBot /start replies say how to talk to the agent, and that differs by platform (#1196): on Telegram
|
|
11939
|
+
* you @mention the bot; on Discord, @mention or `/chat`. The chat's platform is the adapter it came through.
|
|
11940
|
+
*/
|
|
11941
|
+
classicStartKey(key, adapterId) {
|
|
11942
|
+
const adapter = (adapterId ? this.worlds.get(adapterId)?.adapter : undefined) ?? this.adapter;
|
|
11943
|
+
return adapter?.type === "telegram" ? `${key}.telegram` : key;
|
|
11944
|
+
}
|
|
11922
11945
|
/** Return a user-facing blocker without mutating ClassicBot state. */
|
|
11923
11946
|
validateClassicStart(channelId, userId, guildId, adapterId) {
|
|
11924
11947
|
if (!this.classicChannels)
|
|
@@ -11940,7 +11963,7 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
11940
11963
|
return t("classic.not_authorized_guild");
|
|
11941
11964
|
}
|
|
11942
11965
|
if (this.classicChannels.isClassicChannel(channelId, adapterId))
|
|
11943
|
-
return t("classic.already_active");
|
|
11966
|
+
return t(this.classicStartKey("classic.already_active", adapterId));
|
|
11944
11967
|
if (this.routing.resolve(channelId))
|
|
11945
11968
|
return t("classic.topic_bound");
|
|
11946
11969
|
return undefined;
|
|
@@ -12127,7 +12150,7 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
12127
12150
|
classicChannels.toggleCollab(channelId, adapterId);
|
|
12128
12151
|
}
|
|
12129
12152
|
this.logger.info({ channelId, adapterId, instanceName, userId }, "Classic channel started");
|
|
12130
|
-
return t("classic.started");
|
|
12153
|
+
return t(this.classicStartKey("classic.started", adapterId));
|
|
12131
12154
|
}
|
|
12132
12155
|
/** Handle /stop slash command — unregister classic channel */
|
|
12133
12156
|
async handleClassicStop(channelId, adapterId) {
|