blun-king-cli 9.1.435 → 9.1.437
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.
|
@@ -6,6 +6,7 @@ const { join } = require('node:path');
|
|
|
6
6
|
const STATUS_FILE = 'telegram-console-status.json';
|
|
7
7
|
const MAX_STATUS_BYTES = 16_384;
|
|
8
8
|
const MAX_TASK_CHARS = 240;
|
|
9
|
+
const MAX_TOOL_NAME_CHARS = 80;
|
|
9
10
|
|
|
10
11
|
function validInstant(value) {
|
|
11
12
|
if (typeof value !== 'string' || value.length === 0) return undefined;
|
|
@@ -18,6 +19,39 @@ function boundedTask(value) {
|
|
|
18
19
|
return title.length > 0 ? title.slice(0, MAX_TASK_CHARS) : undefined;
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
function boundedToolName(value) {
|
|
23
|
+
if (typeof value !== 'string') return undefined;
|
|
24
|
+
const name = value.replace(/\s+/gu, ' ').trim();
|
|
25
|
+
return name.length > 0 ? name.slice(0, MAX_TOOL_NAME_CHARS) : undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function instantFromMilliseconds(value) {
|
|
29
|
+
if (!Number.isFinite(value) || value < 0) return undefined;
|
|
30
|
+
try {
|
|
31
|
+
return new Date(value).toISOString();
|
|
32
|
+
} catch {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function buildTurnDiagnostics(turnActive, activity) {
|
|
38
|
+
if (!turnActive || activity?.active !== true) return {};
|
|
39
|
+
const turnStartedAt = instantFromMilliseconds(activity.startedAtMs);
|
|
40
|
+
const lastProgressAt = instantFromMilliseconds(activity.lastProgressAtMs);
|
|
41
|
+
const lastToolName = boundedToolName(activity.lastToolName);
|
|
42
|
+
const failedRepetitions = Number.isSafeInteger(activity.failedRepetitions)
|
|
43
|
+
&& activity.failedRepetitions >= 0
|
|
44
|
+
&& activity.failedRepetitions <= 100
|
|
45
|
+
? activity.failedRepetitions
|
|
46
|
+
: undefined;
|
|
47
|
+
return {
|
|
48
|
+
...(turnStartedAt === undefined ? {} : { turnStartedAt }),
|
|
49
|
+
...(lastProgressAt === undefined ? {} : { lastProgressAt }),
|
|
50
|
+
...(lastToolName === undefined ? {} : { lastToolName }),
|
|
51
|
+
...(failedRepetitions === undefined ? {} : { failedRepetitions }),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
21
55
|
function buildTelegramConsoleStatus(input = {}) {
|
|
22
56
|
const capturedAt = validInstant(input.capturedAt);
|
|
23
57
|
const processStartedAt = validInstant(input.processStartedAt);
|
|
@@ -38,6 +72,7 @@ function buildTelegramConsoleStatus(input = {}) {
|
|
|
38
72
|
turnActive: input.turnActive,
|
|
39
73
|
step,
|
|
40
74
|
...(activeTask === undefined ? {} : { activeTask }),
|
|
75
|
+
...buildTurnDiagnostics(input.turnActive, input.turnActivity),
|
|
41
76
|
};
|
|
42
77
|
}
|
|
43
78
|
|
|
@@ -53,6 +88,25 @@ function parseTelegramConsoleStatus(value, options = {}) {
|
|
|
53
88
|
|| typeof parsed.turnActive !== 'boolean'
|
|
54
89
|
|| !Number.isSafeInteger(parsed.step) || parsed.step < 0) return undefined;
|
|
55
90
|
const activeTask = boundedTask(parsed.activeTask);
|
|
91
|
+
const hasTurnStartedAt = Object.hasOwn(parsed, 'turnStartedAt');
|
|
92
|
+
const hasLastProgressAt = Object.hasOwn(parsed, 'lastProgressAt');
|
|
93
|
+
const hasLastToolName = Object.hasOwn(parsed, 'lastToolName');
|
|
94
|
+
const hasFailedRepetitions = Object.hasOwn(parsed, 'failedRepetitions');
|
|
95
|
+
const turnStartedAt = validInstant(parsed.turnStartedAt);
|
|
96
|
+
const lastProgressAt = validInstant(parsed.lastProgressAt);
|
|
97
|
+
const lastToolName = boundedToolName(parsed.lastToolName);
|
|
98
|
+
const failedRepetitions = parsed.failedRepetitions;
|
|
99
|
+
if ((hasTurnStartedAt && turnStartedAt === undefined)
|
|
100
|
+
|| (hasLastProgressAt && lastProgressAt === undefined)
|
|
101
|
+
|| (hasLastToolName && lastToolName === undefined)
|
|
102
|
+
|| (hasFailedRepetitions && (!Number.isSafeInteger(failedRepetitions)
|
|
103
|
+
|| failedRepetitions < 0 || failedRepetitions > 100))) return undefined;
|
|
104
|
+
const diagnostics = parsed.turnActive ? {
|
|
105
|
+
...(turnStartedAt === undefined ? {} : { turnStartedAt }),
|
|
106
|
+
...(lastProgressAt === undefined ? {} : { lastProgressAt }),
|
|
107
|
+
...(lastToolName === undefined ? {} : { lastToolName }),
|
|
108
|
+
...(hasFailedRepetitions ? { failedRepetitions } : {}),
|
|
109
|
+
} : {};
|
|
56
110
|
return {
|
|
57
111
|
version: 1,
|
|
58
112
|
pid: parsed.pid,
|
|
@@ -61,6 +115,7 @@ function parseTelegramConsoleStatus(value, options = {}) {
|
|
|
61
115
|
turnActive: parsed.turnActive,
|
|
62
116
|
step: parsed.step,
|
|
63
117
|
...(parsed.turnActive && activeTask !== undefined ? { activeTask } : {}),
|
|
118
|
+
...diagnostics,
|
|
64
119
|
};
|
|
65
120
|
} catch {
|
|
66
121
|
return undefined;
|
|
@@ -76,6 +76,14 @@ function buildTelegramRemoteStatus(input) {
|
|
|
76
76
|
? [
|
|
77
77
|
`Arbeitsstatus: aktiv, Schritt ${input.consoleStatus.step}`,
|
|
78
78
|
...(input.consoleStatus.activeTask === undefined ? [] : [`Aktive Aufgabe: ${input.consoleStatus.activeTask}`]),
|
|
79
|
+
...(formatAge(input.consoleStatus.turnStartedAt, input.capturedAt) === undefined
|
|
80
|
+
? [] : [`Zugbeginn: ${formatAge(input.consoleStatus.turnStartedAt, input.capturedAt)}`]),
|
|
81
|
+
...(formatAge(input.consoleStatus.lastProgressAt, input.capturedAt) === undefined
|
|
82
|
+
? [] : [`Letzter Fortschritt: ${formatAge(input.consoleStatus.lastProgressAt, input.capturedAt)}`]),
|
|
83
|
+
...(input.consoleStatus.lastToolName === undefined
|
|
84
|
+
? [] : [`Letztes Werkzeug: ${input.consoleStatus.lastToolName}`]),
|
|
85
|
+
...(input.consoleStatus.failedRepetitions === undefined
|
|
86
|
+
? [] : [`Wiederholte Fehler: ${input.consoleStatus.failedRepetitions}`]),
|
|
79
87
|
]
|
|
80
88
|
: ['Arbeitsstatus: Leerlauf'];
|
|
81
89
|
return [
|
package/blun.mjs
CHANGED
|
@@ -419609,6 +419609,7 @@ var TelegramChannelController = class {
|
|
|
419609
419609
|
}
|
|
419610
419610
|
try {
|
|
419611
419611
|
writeFileSync(this.leaseFile, String(process.pid));
|
|
419612
|
+
this.host.streamingUI?.publishTelegramConsoleStatus?.();
|
|
419612
419613
|
} catch (error) {
|
|
419613
419614
|
this.host.warn(uiText("telegramChannel.leaseWriteFailed", { error: String(error) }));
|
|
419614
419615
|
}
|
|
@@ -507622,6 +507623,7 @@ var TurnWatchdogController = class {
|
|
|
507622
507623
|
clearTimer;
|
|
507623
507624
|
onIdle;
|
|
507624
507625
|
onAbort;
|
|
507626
|
+
onSnapshot;
|
|
507625
507627
|
toolCalls = /* @__PURE__ */ new Map();
|
|
507626
507628
|
active = false;
|
|
507627
507629
|
startedAtMs = 0;
|
|
@@ -507638,6 +507640,7 @@ var TurnWatchdogController = class {
|
|
|
507638
507640
|
this.clearTimer = options.clearTimer ?? clearTimeout;
|
|
507639
507641
|
this.onIdle = options.onIdle;
|
|
507640
507642
|
this.onAbort = options.onAbort;
|
|
507643
|
+
this.onSnapshot = options.onSnapshot ?? (() => {});
|
|
507641
507644
|
}
|
|
507642
507645
|
start() {
|
|
507643
507646
|
this.stop();
|
|
@@ -507649,20 +507652,23 @@ var TurnWatchdogController = class {
|
|
|
507649
507652
|
this.lastFailedKey = void 0;
|
|
507650
507653
|
this.failedRepetitions = 0;
|
|
507651
507654
|
this.idleReportedForProgressAtMs = void 0;
|
|
507655
|
+
this.publishSnapshot();
|
|
507652
507656
|
this.scheduleIdleCheck();
|
|
507653
507657
|
}
|
|
507654
507658
|
stop() {
|
|
507659
|
+
const wasActive = this.active;
|
|
507655
507660
|
this.active = false;
|
|
507656
507661
|
this.toolCalls.clear();
|
|
507657
507662
|
if (this.timer !== void 0) {
|
|
507658
507663
|
this.clearTimer(this.timer);
|
|
507659
507664
|
this.timer = void 0;
|
|
507660
507665
|
}
|
|
507666
|
+
if (wasActive) this.publishSnapshot();
|
|
507661
507667
|
}
|
|
507662
507668
|
recordToolCall(toolCallId, name, args) {
|
|
507663
507669
|
if (!this.active) return;
|
|
507664
|
-
this.recordProgress();
|
|
507665
507670
|
this.lastToolName = name;
|
|
507671
|
+
this.recordProgress();
|
|
507666
507672
|
this.toolCalls.set(toolCallId, {
|
|
507667
507673
|
name,
|
|
507668
507674
|
key: `${name}\0${canonicalJson(args)}`
|
|
@@ -507677,6 +507683,7 @@ var TurnWatchdogController = class {
|
|
|
507677
507683
|
if (!isError || toolCall === void 0) {
|
|
507678
507684
|
this.lastFailedKey = void 0;
|
|
507679
507685
|
this.failedRepetitions = 0;
|
|
507686
|
+
this.publishSnapshot();
|
|
507680
507687
|
return;
|
|
507681
507688
|
}
|
|
507682
507689
|
if (toolCall.key === this.lastFailedKey) this.failedRepetitions += 1;
|
|
@@ -507684,6 +507691,7 @@ var TurnWatchdogController = class {
|
|
|
507684
507691
|
this.lastFailedKey = toolCall.key;
|
|
507685
507692
|
this.failedRepetitions = 1;
|
|
507686
507693
|
}
|
|
507694
|
+
this.publishSnapshot();
|
|
507687
507695
|
if (this.failedRepetitions < this.config.maxFailedRepetitions) return;
|
|
507688
507696
|
const snapshot = {
|
|
507689
507697
|
...this.snapshot(),
|
|
@@ -507696,8 +507704,20 @@ var TurnWatchdogController = class {
|
|
|
507696
507704
|
if (!this.active) return;
|
|
507697
507705
|
this.lastProgressAtMs = this.now();
|
|
507698
507706
|
this.idleReportedForProgressAtMs = void 0;
|
|
507707
|
+
this.publishSnapshot();
|
|
507699
507708
|
this.scheduleIdleCheck();
|
|
507700
507709
|
}
|
|
507710
|
+
publishSnapshot() {
|
|
507711
|
+
try {
|
|
507712
|
+
this.onSnapshot(this.active ? {
|
|
507713
|
+
active: true,
|
|
507714
|
+
startedAtMs: this.startedAtMs,
|
|
507715
|
+
lastProgressAtMs: this.lastProgressAtMs,
|
|
507716
|
+
lastToolName: this.lastToolName,
|
|
507717
|
+
failedRepetitions: this.failedRepetitions
|
|
507718
|
+
} : { active: false });
|
|
507719
|
+
} catch {}
|
|
507720
|
+
}
|
|
507701
507721
|
scheduleIdleCheck() {
|
|
507702
507722
|
if (!this.active) return;
|
|
507703
507723
|
if (this.timer !== void 0) this.clearTimer(this.timer);
|
|
@@ -507775,7 +507795,8 @@ var SessionEventHandler = class {
|
|
|
507775
507795
|
});
|
|
507776
507796
|
this.turnWatchdog = new TurnWatchdogController({
|
|
507777
507797
|
onIdle: (snapshot) => this.reportWatchdogIdle(snapshot),
|
|
507778
|
-
onAbort: (snapshot) => this.abortWatchdogLoop(snapshot)
|
|
507798
|
+
onAbort: (snapshot) => this.abortWatchdogLoop(snapshot),
|
|
507799
|
+
onSnapshot: (snapshot) => this.host.streamingUI.setRemoteTurnActivity(snapshot)
|
|
507779
507800
|
});
|
|
507780
507801
|
}
|
|
507781
507802
|
backgroundTasks = /* @__PURE__ */ new Map();
|
|
@@ -508327,8 +508348,10 @@ var SessionEventHandler = class {
|
|
|
508327
508348
|
this.host.sendChannelTurnStatus?.(message);
|
|
508328
508349
|
}
|
|
508329
508350
|
abortWatchdogLoop(snapshot) {
|
|
508330
|
-
const message =
|
|
508351
|
+
const message = snapshot.reason === "idle_timeout" ? uiText("sessionEvent.watchdog.timeout", {
|
|
508331
508352
|
minutes: snapshot.idleMinutes,
|
|
508353
|
+
tool: snapshot.lastToolName
|
|
508354
|
+
}) : uiText("sessionEvent.watchdog.aborted", {
|
|
508332
508355
|
tool: snapshot.lastToolName,
|
|
508333
508356
|
repetitions: snapshot.failedRepetitions
|
|
508334
508357
|
});
|
|
@@ -511183,6 +511206,7 @@ var StreamingUIController = class {
|
|
|
511183
511206
|
_currentTurnId = void 0;
|
|
511184
511207
|
_currentStep = 0;
|
|
511185
511208
|
_remoteTodos = [];
|
|
511209
|
+
_remoteTurnActivity = { active: false };
|
|
511186
511210
|
_remoteProcessStartedAt = new Date(Date.now() - process.uptime() * 1e3).toISOString();
|
|
511187
511211
|
_liveTurnStartedAtMs = void 0;
|
|
511188
511212
|
_liveOutputTokens = new LiveOutputTokenCounter();
|
|
@@ -511215,6 +511239,13 @@ var StreamingUIController = class {
|
|
|
511215
511239
|
this._currentStep = step;
|
|
511216
511240
|
this.publishTelegramConsoleStatus();
|
|
511217
511241
|
}
|
|
511242
|
+
setRemoteTurnActivity(activity) {
|
|
511243
|
+
const previous = this._remoteTurnActivity;
|
|
511244
|
+
this._remoteTurnActivity = activity?.active === true ? activity : { active: false };
|
|
511245
|
+
if (previous.active !== this._remoteTurnActivity.active
|
|
511246
|
+
|| previous.lastToolName !== this._remoteTurnActivity.lastToolName
|
|
511247
|
+
|| previous.failedRepetitions !== this._remoteTurnActivity.failedRepetitions) this.publishTelegramConsoleStatus();
|
|
511248
|
+
}
|
|
511218
511249
|
publishTelegramConsoleStatus() {
|
|
511219
511250
|
if (!telegramChannelAttachEnabled()) return;
|
|
511220
511251
|
try {
|
|
@@ -511225,6 +511256,7 @@ var StreamingUIController = class {
|
|
|
511225
511256
|
processStartedAt: this._remoteProcessStartedAt,
|
|
511226
511257
|
step: this._currentStep,
|
|
511227
511258
|
todos: this._remoteTodos,
|
|
511259
|
+
turnActivity: this._remoteTurnActivity,
|
|
511228
511260
|
turnActive: this._currentTurnId !== void 0
|
|
511229
511261
|
});
|
|
511230
511262
|
} catch {}
|
|
@@ -511536,6 +511568,7 @@ var StreamingUIController = class {
|
|
|
511536
511568
|
this._currentTurnId = void 0;
|
|
511537
511569
|
this._currentStep = 0;
|
|
511538
511570
|
this._remoteTodos = [];
|
|
511571
|
+
this._remoteTurnActivity = { active: false };
|
|
511539
511572
|
this._streamingToolCallArguments.clear();
|
|
511540
511573
|
this.pendingToolCallFlushIds.clear();
|
|
511541
511574
|
this.publishTelegramConsoleStatus();
|