blun-king-cli 9.1.335 → 9.1.336
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/telegram-direct-focus-policy.cjs +54 -3
- package/blun.mjs +16 -3
- package/package.json +1 -1
|
@@ -56,6 +56,7 @@ function isExplicitPauseRequest(text) {
|
|
|
56
56
|
function createDirectFocusController(options = {}) {
|
|
57
57
|
const setTimer = options.setTimer ?? setTimeout;
|
|
58
58
|
const clearTimer = options.clearTimer ?? clearTimeout;
|
|
59
|
+
const now = options.now ?? Date.now;
|
|
59
60
|
const checkpoint = options.checkpoint ?? (() => {});
|
|
60
61
|
const resume = options.resume ?? (() => {});
|
|
61
62
|
const silenceMs = options.silenceMs ?? DEFAULT_SILENCE_MS;
|
|
@@ -89,16 +90,23 @@ function createDirectFocusController(options = {}) {
|
|
|
89
90
|
finishConversation(chatId, existing);
|
|
90
91
|
return { resumeGranted: true };
|
|
91
92
|
}
|
|
92
|
-
|
|
93
|
+
const startsConversation = conversations.size === 0;
|
|
94
|
+
if (startsConversation) {
|
|
93
95
|
savedCheckpoint = { ...checkpointValue, chatId };
|
|
94
|
-
checkpoint(savedCheckpoint);
|
|
95
96
|
}
|
|
96
97
|
const conversation = existing ?? { chatId };
|
|
97
98
|
clearConversationTimer(conversation);
|
|
99
|
+
const wasExplicitPause = conversation.explicitPause === true;
|
|
98
100
|
conversation.explicitPause = conversation.explicitPause === true || isExplicitPauseRequest(text);
|
|
99
101
|
conversation.waitingPermission = conversation.explicitPause;
|
|
100
102
|
conversation.closeAfterReply = isConversationClose(text);
|
|
101
103
|
conversations.set(chatId, conversation);
|
|
104
|
+
savedCheckpoint = {
|
|
105
|
+
...savedCheckpoint,
|
|
106
|
+
explicitPause: conversation.explicitPause,
|
|
107
|
+
resumeAfterAt: null,
|
|
108
|
+
};
|
|
109
|
+
if (startsConversation || wasExplicitPause !== conversation.explicitPause) checkpoint(savedCheckpoint);
|
|
102
110
|
return { resumeGranted: false, explicitPause: conversation.explicitPause };
|
|
103
111
|
}
|
|
104
112
|
|
|
@@ -109,10 +117,14 @@ function createDirectFocusController(options = {}) {
|
|
|
109
117
|
clearConversationTimer(conversation);
|
|
110
118
|
if (conversation.explicitPause === true) {
|
|
111
119
|
conversation.waitingPermission = true;
|
|
120
|
+
checkpoint({ ...savedCheckpoint, explicitPause: true, resumeAfterAt: null });
|
|
112
121
|
return true;
|
|
113
122
|
}
|
|
114
123
|
const delay = conversation.closeAfterReply ? 0 : silenceMs;
|
|
115
124
|
conversation.closeAfterReply = false;
|
|
125
|
+
const resumeAfterAt = new Date(now() + delay).toISOString();
|
|
126
|
+
savedCheckpoint = { ...savedCheckpoint, explicitPause: false, resumeAfterAt };
|
|
127
|
+
checkpoint(savedCheckpoint);
|
|
116
128
|
conversation.timer = setTimer(() => {
|
|
117
129
|
finishConversation(chatId, conversation);
|
|
118
130
|
}, delay);
|
|
@@ -125,6 +137,26 @@ function createDirectFocusController(options = {}) {
|
|
|
125
137
|
savedCheckpoint = undefined;
|
|
126
138
|
}
|
|
127
139
|
|
|
140
|
+
const initialCheckpoint = options.initialCheckpoint;
|
|
141
|
+
if (initialCheckpoint?.status === 'paused' && isPrivateTelegramChat(initialCheckpoint.chatId)) {
|
|
142
|
+
const chatId = String(initialCheckpoint.chatId);
|
|
143
|
+
const explicitPause = initialCheckpoint.explicitPause === true;
|
|
144
|
+
const conversation = {
|
|
145
|
+
chatId,
|
|
146
|
+
explicitPause,
|
|
147
|
+
waitingPermission: explicitPause,
|
|
148
|
+
};
|
|
149
|
+
savedCheckpoint = { ...initialCheckpoint, chatId };
|
|
150
|
+
conversations.set(chatId, conversation);
|
|
151
|
+
const resumeAfterMs = Date.parse(String(initialCheckpoint.resumeAfterAt ?? ''));
|
|
152
|
+
if (!explicitPause && Number.isFinite(resumeAfterMs)) {
|
|
153
|
+
conversation.timer = setTimer(
|
|
154
|
+
() => finishConversation(chatId, conversation),
|
|
155
|
+
Math.max(0, resumeAfterMs - now()),
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
128
160
|
return {
|
|
129
161
|
dispose,
|
|
130
162
|
isPaused: () => conversations.size > 0,
|
|
@@ -145,7 +177,13 @@ function writeDirectFocusCheckpoint(value, env = process.env) {
|
|
|
145
177
|
const record = {
|
|
146
178
|
version: 1,
|
|
147
179
|
status: value?.status === 'resumed' ? 'resumed' : 'paused',
|
|
148
|
-
pausedAt:
|
|
180
|
+
pausedAt: Number.isFinite(Date.parse(String(value?.pausedAt ?? '')))
|
|
181
|
+
? new Date(value.pausedAt).toISOString()
|
|
182
|
+
: new Date().toISOString(),
|
|
183
|
+
explicitPause: value?.explicitPause === true,
|
|
184
|
+
resumeAfterAt: Number.isFinite(Date.parse(String(value?.resumeAfterAt ?? '')))
|
|
185
|
+
? new Date(value.resumeAfterAt).toISOString()
|
|
186
|
+
: null,
|
|
149
187
|
chatId: isPrivateTelegramChat(value?.chatId) ? String(value.chatId) : null,
|
|
150
188
|
sessionId: value?.sessionId === undefined ? null : String(value.sessionId).slice(0, 160),
|
|
151
189
|
turnId: value?.turnId === undefined ? null : String(value.turnId),
|
|
@@ -160,6 +198,18 @@ function writeDirectFocusCheckpoint(value, env = process.env) {
|
|
|
160
198
|
return { path: target, record };
|
|
161
199
|
}
|
|
162
200
|
|
|
201
|
+
function readDirectFocusCheckpoint(env = process.env) {
|
|
202
|
+
const target = directFocusCheckpointPath(env);
|
|
203
|
+
try {
|
|
204
|
+
const record = JSON.parse(fs.readFileSync(target, 'utf8'));
|
|
205
|
+
if (record?.version !== 1 || (record.status !== 'paused' && record.status !== 'resumed')) return undefined;
|
|
206
|
+
return record;
|
|
207
|
+
} catch (error) {
|
|
208
|
+
if (error?.code === 'ENOENT') return undefined;
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
163
213
|
module.exports = {
|
|
164
214
|
DEFAULT_SILENCE_MS,
|
|
165
215
|
createDirectFocusController,
|
|
@@ -169,6 +219,7 @@ module.exports = {
|
|
|
169
219
|
isExplicitPauseRequest,
|
|
170
220
|
isPrivateTelegramChat,
|
|
171
221
|
isResumeApproval,
|
|
222
|
+
readDirectFocusCheckpoint,
|
|
172
223
|
rewriteTelegramDirectEnvelope,
|
|
173
224
|
telegramDirectMessage,
|
|
174
225
|
writeDirectFocusCheckpoint,
|
package/blun.mjs
CHANGED
|
@@ -419036,7 +419036,7 @@ registerUiCatalogFragment({
|
|
|
419036
419036
|
*/
|
|
419037
419037
|
var { projectUnaddressedTelegramContext } = createRequire(import.meta.url)("./bin/telegram-context-projection-policy.cjs");
|
|
419038
419038
|
var { enqueueTelegramUrgent, rewriteTelegramUrgentEnvelope, telegramUrgentMessage } = createRequire(import.meta.url)("./bin/telegram-urgent-policy.cjs");
|
|
419039
|
-
var { createDirectFocusController, enqueueTelegramDirect, rewriteTelegramDirectEnvelope, telegramDirectMessage, writeDirectFocusCheckpoint } = createRequire(import.meta.url)("./bin/telegram-direct-focus-policy.cjs");
|
|
419039
|
+
var { createDirectFocusController, enqueueTelegramDirect, readDirectFocusCheckpoint, rewriteTelegramDirectEnvelope, telegramDirectMessage, writeDirectFocusCheckpoint } = createRequire(import.meta.url)("./bin/telegram-direct-focus-policy.cjs");
|
|
419040
419040
|
var { removeQueuedReloadCommands, removeQueuedSlashCommands } = createRequire(import.meta.url)("./bin/reload-queue-policy.cjs");
|
|
419041
419041
|
const MAX_BUFFERED_CONTEXT_MESSAGES = 20;
|
|
419042
419042
|
const MAX_BUFFERED_CONTEXT_CHARS = 24e3;
|
|
@@ -509485,6 +509485,9 @@ var SessionReplayRenderer = class {
|
|
|
509485
509485
|
cleanupRuntime(context) {
|
|
509486
509486
|
this.flushAssistant(context);
|
|
509487
509487
|
this.host.streamingUI.cleanupAfterReplay(context.completedToolCallIds);
|
|
509488
|
+
this.host.setAppState({ streamingPhase: "idle" });
|
|
509489
|
+
this.host.resetLivePane();
|
|
509490
|
+
this.host.requestQueueDrain();
|
|
509488
509491
|
}
|
|
509489
509492
|
renderSkillActivation(context, skill) {
|
|
509490
509493
|
const { sessionEventHandler } = this.host;
|
|
@@ -516082,6 +516085,7 @@ var BlunTUI = class {
|
|
|
516082
516085
|
deliverOne: () => this.deliverQueuedChannelHead()
|
|
516083
516086
|
});
|
|
516084
516087
|
this.directFocusController = createDirectFocusController({
|
|
516088
|
+
initialCheckpoint: readDirectFocusCheckpoint(),
|
|
516085
516089
|
checkpoint: (checkpoint) => {
|
|
516086
516090
|
try {
|
|
516087
516091
|
writeDirectFocusCheckpoint(checkpoint);
|
|
@@ -516929,7 +516933,7 @@ var BlunTUI = class {
|
|
|
516929
516933
|
return this.restoreQueuedSteer(inFlight, error);
|
|
516930
516934
|
};
|
|
516931
516935
|
try {
|
|
516932
|
-
if (!(await this.harness.withInteractiveAgent(item.agentId ?? "main", () => session.steerActive(input, expectedTurnId === void 0 ? {} : { expectedTurnId }))).accepted) return
|
|
516936
|
+
if (!(await this.harness.withInteractiveAgent(item.agentId ?? "main", () => session.steerActive(input, expectedTurnId === void 0 ? {} : { expectedTurnId }))).accepted) return this.recoverRejectedActiveSteer(inFlight);
|
|
516933
516937
|
inFlight.accepted = true;
|
|
516934
516938
|
if (inFlight.turnEnded) return restoreHead();
|
|
516935
516939
|
this.commitQueuedSteerIfReady(inFlight);
|
|
@@ -516981,6 +516985,15 @@ var BlunTUI = class {
|
|
|
516981
516985
|
this.steerQueueFlushPrefix();
|
|
516982
516986
|
this.scheduleQueueDrain();
|
|
516983
516987
|
}
|
|
516988
|
+
recoverRejectedActiveSteer(inFlight) {
|
|
516989
|
+
const restored = this.restoreQueuedSteer(inFlight);
|
|
516990
|
+
if (!this.streamingUI.hasActiveTurn()) {
|
|
516991
|
+
this.setAppState({ streamingPhase: "idle" });
|
|
516992
|
+
this.resetLivePane();
|
|
516993
|
+
this.scheduleQueueDrain();
|
|
516994
|
+
}
|
|
516995
|
+
return restored;
|
|
516996
|
+
}
|
|
516984
516997
|
restoreQueuedSteer(inFlight, error) {
|
|
516985
516998
|
if (this.queueSteerInFlight !== inFlight) return false;
|
|
516986
516999
|
this.queueSteerInFlight = void 0;
|
|
@@ -517071,7 +517084,7 @@ var BlunTUI = class {
|
|
|
517071
517084
|
const expectedTurnId = turnId !== void 0 && /^\d+$/.test(turnId) ? Number(turnId) : void 0;
|
|
517072
517085
|
session.steerActive(items.map((item) => item.text.trim()).join("\n\n"), expectedTurnId === void 0 ? {} : { expectedTurnId }).then((result) => {
|
|
517073
517086
|
if (this.queueSteerInFlight !== inFlight) return;
|
|
517074
|
-
if (!result.accepted) this.
|
|
517087
|
+
if (!result.accepted) this.recoverRejectedActiveSteer(inFlight);
|
|
517075
517088
|
else {
|
|
517076
517089
|
inFlight.accepted = true;
|
|
517077
517090
|
if (inFlight.turnEnded) this.restoreQueuedSteer(inFlight);
|