blun-king-cli 9.1.192 → 9.1.194
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/bin/repeated-user-message-projection.cjs +41 -0
- package/blun.mjs +76 -16
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const LONG_DUPLICATE_MIN_CHARS = 512;
|
|
4
|
+
const TELEGRAM_DELIVERY_LEDGER_LIMIT = 2_048;
|
|
4
5
|
|
|
5
6
|
function userMessageText(message) {
|
|
6
7
|
if (
|
|
@@ -31,6 +32,43 @@ function telegramDeliveryIdentity(text) {
|
|
|
31
32
|
return `${chatId}:${messageId}`;
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
function telegramDeliveryIdentityFromParts(input) {
|
|
36
|
+
if (!Array.isArray(input)) return '';
|
|
37
|
+
for (const part of input) {
|
|
38
|
+
if (part?.type !== 'text' || typeof part.text !== 'string') continue;
|
|
39
|
+
const identity = telegramDeliveryIdentity(part.text);
|
|
40
|
+
if (identity) return identity;
|
|
41
|
+
}
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
class TelegramDeliveryLedger {
|
|
46
|
+
constructor(limit = TELEGRAM_DELIVERY_LEDGER_LIMIT) {
|
|
47
|
+
this.limit = Math.max(1, Number.isInteger(limit) ? limit : TELEGRAM_DELIVERY_LEDGER_LIMIT);
|
|
48
|
+
this.identities = new Set();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
identity(input, origin) {
|
|
52
|
+
if (origin?.kind !== 'user') return '';
|
|
53
|
+
return telegramDeliveryIdentityFromParts(input);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
isDuplicate(input, origin) {
|
|
57
|
+
const identity = this.identity(input, origin);
|
|
58
|
+
return identity ? this.identities.has(identity) : false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
remember(input, origin) {
|
|
62
|
+
const identity = this.identity(input, origin);
|
|
63
|
+
if (!identity || this.identities.has(identity)) return identity;
|
|
64
|
+
this.identities.add(identity);
|
|
65
|
+
while (this.identities.size > this.limit) {
|
|
66
|
+
this.identities.delete(this.identities.values().next().value);
|
|
67
|
+
}
|
|
68
|
+
return identity;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
34
72
|
function repeatedUserMessageKey(message) {
|
|
35
73
|
const text = userMessageText(message);
|
|
36
74
|
if (!text) return '';
|
|
@@ -62,7 +100,10 @@ function dedupeRepeatedUserMessages(messages) {
|
|
|
62
100
|
|
|
63
101
|
module.exports = {
|
|
64
102
|
LONG_DUPLICATE_MIN_CHARS,
|
|
103
|
+
TELEGRAM_DELIVERY_LEDGER_LIMIT,
|
|
104
|
+
TelegramDeliveryLedger,
|
|
65
105
|
dedupeRepeatedUserMessages,
|
|
66
106
|
telegramDeliveryIdentity,
|
|
107
|
+
telegramDeliveryIdentityFromParts,
|
|
67
108
|
userMessageText,
|
|
68
109
|
};
|
package/blun.mjs
CHANGED
|
@@ -234922,7 +234922,7 @@ function restoreAgentRecord(agent, input) {
|
|
|
234922
234922
|
agent.goal.restoreForked(input);
|
|
234923
234923
|
return;
|
|
234924
234924
|
case "turn.prompt":
|
|
234925
|
-
agent.turn.restorePrompt();
|
|
234925
|
+
agent.turn.restorePrompt(input.input, input.origin);
|
|
234926
234926
|
return;
|
|
234927
234927
|
case "turn.steer":
|
|
234928
234928
|
agent.turn.restoreSteer(input.input, input.origin);
|
|
@@ -261209,7 +261209,7 @@ function toolResultText(result) {
|
|
|
261209
261209
|
function abandonedToolResultOutput(ended) {
|
|
261210
261210
|
return `Tool call did not complete: ${ended.reason === "cancelled" ? "the turn was cancelled" : ended.reason === "failed" ? `the turn failed${ended.error !== void 0 ? ` (${ended.error.message})` : ""}` : "the turn ended"} before its result was recorded. Do not assume the tool completed successfully.`;
|
|
261211
261211
|
}
|
|
261212
|
-
var BLUN_CORE_TOOL_NAMES, BLUN_LEAN_TOOL_NAMES, BLUN_ATTACHMENT_MARKER_RE, BLUN_TELEGRAM_OUTBOUND_TOOL_RE, BLUN_TELEGRAM_CHANNEL_RE, BLUN_TOOL_BUDGET_RATIO, createDeferredToolLoader, mediaGenerationToolNamesForText, toolSchemaBudgetTokens, projectRecurringCronHistory, LLM_NOT_SET_MESSAGE, GOAL_CONTINUATION_ORIGIN, GOAL_COMPLETION_REMINDER_NAME, GOAL_BLOCKED_REMINDER_NAME, GOAL_RATE_LIMIT_PAUSE_REASON, GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX, GOAL_PROVIDER_AUTH_PAUSE_PREFIX, GOAL_PROVIDER_API_PAUSE_PREFIX, GOAL_MODEL_CONFIG_PAUSE_PREFIX, GOAL_RUNTIME_PAUSE_PREFIX, GOAL_PROVIDER_FILTERED_PAUSE_REASON, GOAL_CONTINUATION_PROMPT, TurnFlow;
|
|
261212
|
+
var BLUN_CORE_TOOL_NAMES, BLUN_LEAN_TOOL_NAMES, BLUN_ATTACHMENT_MARKER_RE, BLUN_TELEGRAM_OUTBOUND_TOOL_RE, BLUN_TELEGRAM_CHANNEL_RE, BLUN_TOOL_BUDGET_RATIO, createDeferredToolLoader, mediaGenerationToolNamesForText, toolSchemaBudgetTokens, projectRecurringCronHistory, TelegramDeliveryLedger, LLM_NOT_SET_MESSAGE, GOAL_CONTINUATION_ORIGIN, GOAL_COMPLETION_REMINDER_NAME, GOAL_BLOCKED_REMINDER_NAME, GOAL_RATE_LIMIT_PAUSE_REASON, GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX, GOAL_PROVIDER_AUTH_PAUSE_PREFIX, GOAL_PROVIDER_API_PAUSE_PREFIX, GOAL_MODEL_CONFIG_PAUSE_PREFIX, GOAL_RUNTIME_PAUSE_PREFIX, GOAL_PROVIDER_FILTERED_PAUSE_REASON, GOAL_CONTINUATION_PROMPT, TurnFlow;
|
|
261213
261213
|
var init_turn = __esmMin((() => {
|
|
261214
261214
|
init_dist$4();
|
|
261215
261215
|
init_src$4();
|
|
@@ -261228,6 +261228,7 @@ var init_turn = __esmMin((() => {
|
|
|
261228
261228
|
init_assistant_message_offload();
|
|
261229
261229
|
({ CORE_TOOL_NAMES: BLUN_CORE_TOOL_NAMES, createDeferredToolLoader, mediaGenerationToolNamesForText, toolSchemaBudgetTokens } = createRequire(import.meta.url)("./bin/turn-tool-performance-policy.cjs"));
|
|
261230
261230
|
({ projectRecurringCronHistory } = createRequire(import.meta.url)("./bin/recurring-cron-history-policy.cjs"));
|
|
261231
|
+
({ TelegramDeliveryLedger } = createRequire(import.meta.url)("./bin/repeated-user-message-projection.cjs"));
|
|
261231
261232
|
BLUN_LEAN_TOOL_NAMES = new Set(BLUN_CORE_TOOL_NAMES);
|
|
261232
261233
|
BLUN_ATTACHMENT_MARKER_RE = /\b(?:attachment_file_id|telegram-anhang|telegram attachment)\b/i;
|
|
261233
261234
|
BLUN_TELEGRAM_OUTBOUND_TOOL_RE = /^mcp__[^\s]*telegram[^\s]*__(?:reply|react|edit_message)$/i;
|
|
@@ -261275,6 +261276,7 @@ var init_turn = __esmMin((() => {
|
|
|
261275
261276
|
TurnFlow = class {
|
|
261276
261277
|
agent;
|
|
261277
261278
|
loadedToolNames = /* @__PURE__ */ new Set();
|
|
261279
|
+
telegramDeliveryLedger = new TelegramDeliveryLedger();
|
|
261278
261280
|
steerBuffer = [];
|
|
261279
261281
|
nextSteerSequence = 0;
|
|
261280
261282
|
turnId = -1;
|
|
@@ -261298,16 +261300,25 @@ var init_turn = __esmMin((() => {
|
|
|
261298
261300
|
return this.promptWithAcceptance(input, origin).turnId;
|
|
261299
261301
|
}
|
|
261300
261302
|
promptWithAcceptance(input, origin = USER_PROMPT_ORIGIN) {
|
|
261301
|
-
this.
|
|
261302
|
-
|
|
261303
|
-
|
|
261304
|
-
|
|
261305
|
-
|
|
261303
|
+
if (this.telegramDeliveryLedger.isDuplicate(input, origin)) {
|
|
261304
|
+
this.agent.telemetry.track("telegram_delivery_duplicate_dropped", { intake: "prompt" });
|
|
261305
|
+
return {
|
|
261306
|
+
accepted: true,
|
|
261307
|
+
buffered: false,
|
|
261308
|
+
turnId: null
|
|
261309
|
+
};
|
|
261310
|
+
}
|
|
261306
261311
|
if (this.activeTurn !== null) return {
|
|
261307
261312
|
accepted: false,
|
|
261308
261313
|
buffered: false,
|
|
261309
261314
|
turnId: null
|
|
261310
261315
|
};
|
|
261316
|
+
this.telegramDeliveryLedger.remember(input, origin);
|
|
261317
|
+
this.agent.records.logRecord({
|
|
261318
|
+
type: "turn.prompt",
|
|
261319
|
+
input,
|
|
261320
|
+
origin
|
|
261321
|
+
});
|
|
261311
261322
|
const buffered = this.agent.fullCompaction.isCompacting;
|
|
261312
261323
|
const turnId = this.launch(input, origin);
|
|
261313
261324
|
return {
|
|
@@ -261317,6 +261328,11 @@ var init_turn = __esmMin((() => {
|
|
|
261317
261328
|
};
|
|
261318
261329
|
}
|
|
261319
261330
|
steer(input, origin = USER_PROMPT_ORIGIN) {
|
|
261331
|
+
if (this.telegramDeliveryLedger.isDuplicate(input, origin)) {
|
|
261332
|
+
this.agent.telemetry.track("telegram_delivery_duplicate_dropped", { intake: "steer" });
|
|
261333
|
+
return null;
|
|
261334
|
+
}
|
|
261335
|
+
this.telegramDeliveryLedger.remember(input, origin);
|
|
261320
261336
|
this.agent.records.logRecord({
|
|
261321
261337
|
type: "turn.steer",
|
|
261322
261338
|
input,
|
|
@@ -261332,6 +261348,11 @@ var init_turn = __esmMin((() => {
|
|
|
261332
261348
|
steerActive(input, expectedTurnId, origin = USER_PROMPT_ORIGIN) {
|
|
261333
261349
|
const active = this.activeTurn;
|
|
261334
261350
|
if (active === null || active === "resuming" || !active.acceptingSteers || expectedTurnId !== void 0 && expectedTurnId !== this.currentId) return null;
|
|
261351
|
+
if (this.telegramDeliveryLedger.isDuplicate(input, origin)) {
|
|
261352
|
+
this.agent.telemetry.track("telegram_delivery_duplicate_dropped", { intake: "active_steer" });
|
|
261353
|
+
return this.currentId;
|
|
261354
|
+
}
|
|
261355
|
+
this.telegramDeliveryLedger.remember(input, origin);
|
|
261335
261356
|
this.agent.records.logRecord({
|
|
261336
261357
|
type: "turn.steer",
|
|
261337
261358
|
input,
|
|
@@ -261378,7 +261399,8 @@ var init_turn = __esmMin((() => {
|
|
|
261378
261399
|
this.turnId += 1;
|
|
261379
261400
|
return this.turnId;
|
|
261380
261401
|
}
|
|
261381
|
-
restorePrompt() {
|
|
261402
|
+
restorePrompt(input, origin) {
|
|
261403
|
+
this.telegramDeliveryLedger.remember(input, origin);
|
|
261382
261404
|
if (this.activeTurn) return;
|
|
261383
261405
|
this.turnId += 1;
|
|
261384
261406
|
this.activeTurn = "resuming";
|
|
@@ -261396,6 +261418,7 @@ var init_turn = __esmMin((() => {
|
|
|
261396
261418
|
if (Number.isInteger(turnId) && turnId > this.turnId) this.turnId = turnId;
|
|
261397
261419
|
}
|
|
261398
261420
|
restoreSteer(input, origin) {
|
|
261421
|
+
this.telegramDeliveryLedger.remember(input, origin);
|
|
261399
261422
|
if (this.activeTurn) {
|
|
261400
261423
|
this.bufferSteer(input, origin);
|
|
261401
261424
|
return;
|
|
@@ -505287,6 +505310,7 @@ registerUiCatalogFragment({
|
|
|
505287
505310
|
"sessionEvent.mcp.connecting": "MCP server \"{name}\" connecting…",
|
|
505288
505311
|
"sessionEvent.skill.activated": "Activated skill: {skillName}",
|
|
505289
505312
|
"sessionEvent.watchdog.idle": "Turn running for {minutes} min; last tool: {tool}; repeated failures: {repetitions}.",
|
|
505313
|
+
"sessionEvent.watchdog.timeout": "Turn stopped after {minutes} min without progress; last tool: {tool}.",
|
|
505290
505314
|
"sessionEvent.watchdog.aborted": "Turn stopped after {repetitions} repeated failed calls to {tool}."
|
|
505291
505315
|
},
|
|
505292
505316
|
de: {
|
|
@@ -505316,6 +505340,7 @@ registerUiCatalogFragment({
|
|
|
505316
505340
|
"sessionEvent.mcp.connecting": "MCP-Server „{name}“ wird verbunden…",
|
|
505317
505341
|
"sessionEvent.skill.activated": "Skill aktiviert: {skillName}",
|
|
505318
505342
|
"sessionEvent.watchdog.idle": "Zug läuft seit {minutes} Min.; letztes Werkzeug: {tool}; wiederholte Fehler: {repetitions}.",
|
|
505343
|
+
"sessionEvent.watchdog.timeout": "Zug nach {minutes} Min. ohne Fortschritt beendet; letztes Werkzeug: {tool}.",
|
|
505319
505344
|
"sessionEvent.watchdog.aborted": "Zug nach {repetitions} wiederholten fehlgeschlagenen Aufrufen von {tool} beendet."
|
|
505320
505345
|
},
|
|
505321
505346
|
es: {
|
|
@@ -505345,6 +505370,7 @@ registerUiCatalogFragment({
|
|
|
505345
505370
|
"sessionEvent.mcp.connecting": "Conectando el servidor MCP «{name}»…",
|
|
505346
505371
|
"sessionEvent.skill.activated": "Skill activado: {skillName}",
|
|
505347
505372
|
"sessionEvent.watchdog.idle": "El turno lleva {minutes} min en curso; última herramienta: {tool}; fallos repetidos: {repetitions}.",
|
|
505373
|
+
"sessionEvent.watchdog.timeout": "Turno detenido tras {minutes} min sin progreso; última herramienta: {tool}.",
|
|
505348
505374
|
"sessionEvent.watchdog.aborted": "Turno detenido tras {repetitions} llamadas fallidas repetidas a {tool}."
|
|
505349
505375
|
},
|
|
505350
505376
|
fr: {
|
|
@@ -505374,6 +505400,7 @@ registerUiCatalogFragment({
|
|
|
505374
505400
|
"sessionEvent.mcp.connecting": "Connexion du serveur MCP « {name} »…",
|
|
505375
505401
|
"sessionEvent.skill.activated": "Skill activé : {skillName}",
|
|
505376
505402
|
"sessionEvent.watchdog.idle": "Tour en cours depuis {minutes} min ; dernier outil : {tool} ; échecs répétés : {repetitions}.",
|
|
505403
|
+
"sessionEvent.watchdog.timeout": "Tour arrêté après {minutes} min sans progression ; dernier outil : {tool}.",
|
|
505377
505404
|
"sessionEvent.watchdog.aborted": "Tour arrêté après {repetitions} appels répétés ayant échoué pour l'outil {tool}."
|
|
505378
505405
|
},
|
|
505379
505406
|
sv: {
|
|
@@ -505403,6 +505430,7 @@ registerUiCatalogFragment({
|
|
|
505403
505430
|
"sessionEvent.mcp.connecting": "Ansluter MCP-servern ”{name}”…",
|
|
505404
505431
|
"sessionEvent.skill.activated": "Skill aktiverad: {skillName}",
|
|
505405
505432
|
"sessionEvent.watchdog.idle": "Körningen har pågått i {minutes} min. Senaste verktyg: {tool}. Upprepade fel: {repetitions}.",
|
|
505433
|
+
"sessionEvent.watchdog.timeout": "Körningen stoppades efter {minutes} min utan framsteg. Senaste verktyg: {tool}.",
|
|
505406
505434
|
"sessionEvent.watchdog.aborted": "Körningen stoppades efter {repetitions} upprepade misslyckade anrop till {tool}."
|
|
505407
505435
|
},
|
|
505408
505436
|
cs: {
|
|
@@ -505432,6 +505460,7 @@ registerUiCatalogFragment({
|
|
|
505432
505460
|
"sessionEvent.mcp.connecting": "Server MCP \"{name}\" se připojuje…",
|
|
505433
505461
|
"sessionEvent.skill.activated": "Aktivována dovednost: {skillName}",
|
|
505434
505462
|
"sessionEvent.watchdog.idle": "Kolo běží {minutes} min; poslední nástroj: {tool}; opakovaná selhání: {repetitions}.",
|
|
505463
|
+
"sessionEvent.watchdog.timeout": "Kolo bylo zastaveno po {minutes} min bez pokroku; poslední nástroj: {tool}.",
|
|
505435
505464
|
"sessionEvent.watchdog.aborted": "Kolo bylo zastaveno po {repetitions} opakovaných neúspěšných voláních nástroje {tool}."
|
|
505436
505465
|
}
|
|
505437
505466
|
});
|
|
@@ -506583,18 +506612,22 @@ function isUserCancelledSubagentError(error) {
|
|
|
506583
506612
|
//#endregion
|
|
506584
506613
|
//#region src/tui/controllers/turn-watchdog.ts
|
|
506585
506614
|
const DEFAULT_IDLE_MINUTES = 20;
|
|
506615
|
+
const DEFAULT_HARD_IDLE_MINUTES = 30;
|
|
506586
506616
|
const DEFAULT_MAX_FAILED_REPETITIONS = 5;
|
|
506587
506617
|
const MIN_IDLE_MINUTES = 1;
|
|
506588
506618
|
const MAX_IDLE_MINUTES = 1440;
|
|
506589
506619
|
const MIN_FAILED_REPETITIONS = 2;
|
|
506590
506620
|
const MAX_FAILED_REPETITIONS = 100;
|
|
506591
506621
|
const TURN_WATCHDOG_IDLE_MINUTES_ENV = "BLUN_TURN_WATCHDOG_IDLE_MINUTES";
|
|
506622
|
+
const TURN_WATCHDOG_HARD_IDLE_MINUTES_ENV = "BLUN_TURN_WATCHDOG_HARD_IDLE_MINUTES";
|
|
506592
506623
|
const TURN_WATCHDOG_MAX_FAILED_REPETITIONS_ENV = "BLUN_TURN_WATCHDOG_MAX_FAILED_REPETITIONS";
|
|
506593
506624
|
function resolveTurnWatchdogConfig(env = process.env) {
|
|
506594
506625
|
const idleMinutes = parseBoundedInteger(env[TURN_WATCHDOG_IDLE_MINUTES_ENV], DEFAULT_IDLE_MINUTES, MIN_IDLE_MINUTES, MAX_IDLE_MINUTES);
|
|
506626
|
+
const hardIdleMinutes = parseBoundedInteger(env[TURN_WATCHDOG_HARD_IDLE_MINUTES_ENV], DEFAULT_HARD_IDLE_MINUTES, MIN_IDLE_MINUTES, MAX_IDLE_MINUTES);
|
|
506595
506627
|
const maxFailedRepetitions = parseBoundedInteger(env[TURN_WATCHDOG_MAX_FAILED_REPETITIONS_ENV], DEFAULT_MAX_FAILED_REPETITIONS, MIN_FAILED_REPETITIONS, MAX_FAILED_REPETITIONS);
|
|
506596
506628
|
return {
|
|
506597
506629
|
idleMs: idleMinutes * 6e4,
|
|
506630
|
+
hardIdleMs: hardIdleMinutes * 6e4,
|
|
506598
506631
|
maxFailedRepetitions
|
|
506599
506632
|
};
|
|
506600
506633
|
}
|
|
@@ -506644,6 +506677,7 @@ var TurnWatchdogController = class {
|
|
|
506644
506677
|
}
|
|
506645
506678
|
recordToolCall(toolCallId, name, args) {
|
|
506646
506679
|
if (!this.active) return;
|
|
506680
|
+
this.recordProgress();
|
|
506647
506681
|
this.lastToolName = name;
|
|
506648
506682
|
this.toolCalls.set(toolCallId, {
|
|
506649
506683
|
name,
|
|
@@ -506655,9 +506689,7 @@ var TurnWatchdogController = class {
|
|
|
506655
506689
|
const toolCall = this.toolCalls.get(toolCallId);
|
|
506656
506690
|
this.toolCalls.delete(toolCallId);
|
|
506657
506691
|
if (toolCall !== void 0) this.lastToolName = toolCall.name;
|
|
506658
|
-
this.
|
|
506659
|
-
this.idleReportedForProgressAtMs = void 0;
|
|
506660
|
-
this.scheduleIdleCheck();
|
|
506692
|
+
this.recordProgress();
|
|
506661
506693
|
if (!isError || toolCall === void 0) {
|
|
506662
506694
|
this.lastFailedKey = void 0;
|
|
506663
506695
|
this.failedRepetitions = 0;
|
|
@@ -506669,14 +506701,26 @@ var TurnWatchdogController = class {
|
|
|
506669
506701
|
this.failedRepetitions = 1;
|
|
506670
506702
|
}
|
|
506671
506703
|
if (this.failedRepetitions < this.config.maxFailedRepetitions) return;
|
|
506672
|
-
const snapshot =
|
|
506704
|
+
const snapshot = {
|
|
506705
|
+
...this.snapshot(),
|
|
506706
|
+
reason: "repeated_failures"
|
|
506707
|
+
};
|
|
506673
506708
|
this.stop();
|
|
506674
506709
|
this.onAbort(snapshot);
|
|
506675
506710
|
}
|
|
506711
|
+
recordProgress() {
|
|
506712
|
+
if (!this.active) return;
|
|
506713
|
+
this.lastProgressAtMs = this.now();
|
|
506714
|
+
this.idleReportedForProgressAtMs = void 0;
|
|
506715
|
+
this.scheduleIdleCheck();
|
|
506716
|
+
}
|
|
506676
506717
|
scheduleIdleCheck() {
|
|
506677
506718
|
if (!this.active) return;
|
|
506678
506719
|
if (this.timer !== void 0) this.clearTimer(this.timer);
|
|
506679
|
-
const
|
|
506720
|
+
const idleForMs = this.now() - this.lastProgressAtMs;
|
|
506721
|
+
const warningRemaining = this.idleReportedForProgressAtMs === this.lastProgressAtMs ? Number.POSITIVE_INFINITY : this.config.idleMs - idleForMs;
|
|
506722
|
+
const hardRemaining = this.config.hardIdleMs - idleForMs;
|
|
506723
|
+
const remaining = Math.max(0, Math.min(warningRemaining, hardRemaining));
|
|
506680
506724
|
this.timer = this.setTimer(() => {
|
|
506681
506725
|
this.timer = void 0;
|
|
506682
506726
|
this.checkIdle();
|
|
@@ -506684,16 +506728,26 @@ var TurnWatchdogController = class {
|
|
|
506684
506728
|
}
|
|
506685
506729
|
checkIdle() {
|
|
506686
506730
|
if (!this.active) return;
|
|
506687
|
-
|
|
506731
|
+
const idleForMs = this.now() - this.lastProgressAtMs;
|
|
506732
|
+
if (idleForMs >= this.config.hardIdleMs) {
|
|
506733
|
+
const snapshot = {
|
|
506734
|
+
...this.snapshot(),
|
|
506735
|
+
reason: "idle_timeout"
|
|
506736
|
+
};
|
|
506737
|
+
this.stop();
|
|
506738
|
+
this.onAbort(snapshot);
|
|
506739
|
+
return;
|
|
506740
|
+
}
|
|
506741
|
+
if (idleForMs >= this.config.idleMs && this.idleReportedForProgressAtMs !== this.lastProgressAtMs) {
|
|
506688
506742
|
this.idleReportedForProgressAtMs = this.lastProgressAtMs;
|
|
506689
506743
|
this.onIdle(this.snapshot());
|
|
506690
|
-
return;
|
|
506691
506744
|
}
|
|
506692
506745
|
this.scheduleIdleCheck();
|
|
506693
506746
|
}
|
|
506694
506747
|
snapshot() {
|
|
506695
506748
|
return {
|
|
506696
506749
|
elapsedMinutes: Math.max(1, Math.floor((this.now() - this.startedAtMs) / 6e4)),
|
|
506750
|
+
idleMinutes: Math.max(1, Math.floor((this.now() - this.lastProgressAtMs) / 6e4)),
|
|
506697
506751
|
lastToolName: this.lastToolName,
|
|
506698
506752
|
failedRepetitions: this.failedRepetitions
|
|
506699
506753
|
};
|
|
@@ -507012,6 +507066,7 @@ var SessionEventHandler = class {
|
|
|
507012
507066
|
requestRunningUpdateAtSafeBoundary(this.host);
|
|
507013
507067
|
}
|
|
507014
507068
|
handleStepBegin(event) {
|
|
507069
|
+
this.turnWatchdog.recordProgress();
|
|
507015
507070
|
this.host.commitQueuedSteerAtStepStart(event.turnId);
|
|
507016
507071
|
this.host.streamingUI.flushNow();
|
|
507017
507072
|
this.host.streamingUI.setStep(event.step);
|
|
@@ -507085,6 +507140,7 @@ var SessionEventHandler = class {
|
|
|
507085
507140
|
handleThinkingDelta(event) {
|
|
507086
507141
|
const { state, streamingUI } = this.host;
|
|
507087
507142
|
if (event.delta.length === 0 && !streamingUI.hasThinkingDraft()) return;
|
|
507143
|
+
if (event.delta.length > 0) this.turnWatchdog.recordProgress();
|
|
507088
507144
|
streamingUI.appendThinkingDelta(event.delta);
|
|
507089
507145
|
this.host.patchLivePane({ mode: "idle" });
|
|
507090
507146
|
if (state.appState.streamingPhase !== "thinking") this.host.setAppState({
|
|
@@ -507097,6 +507153,7 @@ var SessionEventHandler = class {
|
|
|
507097
507153
|
const { state, streamingUI } = this.host;
|
|
507098
507154
|
if (streamingUI.hasThinkingDraft()) streamingUI.flushThinkingToTranscript("idle");
|
|
507099
507155
|
if (event.delta.trim().length > 0) {
|
|
507156
|
+
this.turnWatchdog.recordProgress();
|
|
507100
507157
|
this.currentTurnHasAssistantText = true;
|
|
507101
507158
|
this.pendingModelBlockedFallback = void 0;
|
|
507102
507159
|
}
|
|
@@ -507157,6 +507214,7 @@ var SessionEventHandler = class {
|
|
|
507157
507214
|
}
|
|
507158
507215
|
handleToolCallDelta(event) {
|
|
507159
507216
|
if (event.toolCallId.length === 0) return;
|
|
507217
|
+
if (event.argumentsPart.length > 0) this.turnWatchdog.recordProgress();
|
|
507160
507218
|
const { state, streamingUI } = this.host;
|
|
507161
507219
|
streamingUI.accumulateToolCallDelta(event.toolCallId, event.name, event.argumentsPart);
|
|
507162
507220
|
const preview = streamingUI.getStreamingToolCallPreview(event.toolCallId);
|
|
@@ -507173,6 +507231,7 @@ var SessionEventHandler = class {
|
|
|
507173
507231
|
streamingUI.scheduleFlush();
|
|
507174
507232
|
}
|
|
507175
507233
|
handleToolProgress(event) {
|
|
507234
|
+
this.turnWatchdog.recordProgress();
|
|
507176
507235
|
if (event.update.kind === "custom" && event.update.customKind === MEDIA_PROGRESS_CUSTOM_KIND) {
|
|
507177
507236
|
this.host.updateMediaActivity(event.toolCallId, event.update.customData);
|
|
507178
507237
|
return;
|
|
@@ -507228,7 +507287,8 @@ var SessionEventHandler = class {
|
|
|
507228
507287
|
this.host.sendChannelTurnStatus?.(message);
|
|
507229
507288
|
}
|
|
507230
507289
|
abortWatchdogLoop(snapshot) {
|
|
507231
|
-
const message = uiText("sessionEvent.watchdog.aborted", {
|
|
507290
|
+
const message = uiText(snapshot.reason === "idle_timeout" ? "sessionEvent.watchdog.timeout" : "sessionEvent.watchdog.aborted", {
|
|
507291
|
+
minutes: snapshot.idleMinutes,
|
|
507232
507292
|
tool: snapshot.lastToolName,
|
|
507233
507293
|
repetitions: snapshot.failedRepetitions
|
|
507234
507294
|
});
|