blun-king-cli 9.1.342 → 9.1.344
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/cognitive-turn-lifecycle.cjs +45 -0
- package/bin/telegram-direct-focus-policy.cjs +17 -0
- package/blun.mjs +46 -5
- package/package.json +1 -1
|
@@ -198,6 +198,50 @@ function createCognitiveTurnLifecycle({ home, tenantId, agentId, runtimeId, now
|
|
|
198
198
|
]);
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
function recordToolBatch(input) {
|
|
202
|
+
if (!exactKeys(input, new Set(['turnId', 'entries']))) fail('COGNITIVE_LIFECYCLE_INVALID');
|
|
203
|
+
const turnId = safeTurnId(input.turnId);
|
|
204
|
+
if (turnId === null || !Array.isArray(input.entries) || input.entries.length < 1 || input.entries.length > 10) {
|
|
205
|
+
fail('COGNITIVE_LIFECYCLE_INVALID');
|
|
206
|
+
}
|
|
207
|
+
const observations = [];
|
|
208
|
+
const stageParts = [];
|
|
209
|
+
for (const entry of input.entries) {
|
|
210
|
+
const { toolCallId, toolName, callKey } = toolFields(
|
|
211
|
+
{ turnId, ...entry },
|
|
212
|
+
new Set(['turnId', 'toolCallId', 'toolName', 'decision', 'outcome', 'durationMs']),
|
|
213
|
+
);
|
|
214
|
+
const decision = String(entry.decision ?? '');
|
|
215
|
+
const outcome = String(entry.outcome ?? '');
|
|
216
|
+
const durationMs = Number(entry.durationMs);
|
|
217
|
+
if (!TOOL_POLICY_DECISIONS.has(decision) || !TOOL_OUTCOMES.has(outcome)
|
|
218
|
+
|| !Number.isSafeInteger(durationMs) || durationMs < 0) fail('COGNITIVE_LIFECYCLE_INVALID');
|
|
219
|
+
stageParts.push(`${toolCallId}:${decision}:${outcome}:${durationMs}`);
|
|
220
|
+
observations.push({
|
|
221
|
+
domain: 'world',
|
|
222
|
+
key: `turn:${turnId}:${callKey}:tool-policy`,
|
|
223
|
+
value: `${decision}:runtime_tool_policy:${toolName}`,
|
|
224
|
+
confidence: 1,
|
|
225
|
+
scope: 'runtime',
|
|
226
|
+
}, {
|
|
227
|
+
domain: 'expected_evidence',
|
|
228
|
+
key: `turn:${turnId}:${callKey}:tool-result`,
|
|
229
|
+
value: `${outcome}:${durationMs}ms:${toolName}`,
|
|
230
|
+
confidence: 1,
|
|
231
|
+
scope: 'runtime',
|
|
232
|
+
}, {
|
|
233
|
+
domain: 'next_trigger',
|
|
234
|
+
key: `turn:${turnId}:${callKey}:tool-next`,
|
|
235
|
+
value: outcome === 'success' ? 'continue-after-tool' : 'inspect-tool-failure',
|
|
236
|
+
confidence: 1,
|
|
237
|
+
scope: 'runtime',
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
const batchKey = digestId('toolbatch', stageParts);
|
|
241
|
+
const result = commitStage(`turn-${turnId}-${batchKey}`, observations);
|
|
242
|
+
return { ...result, events: 1, entries: input.entries.length };
|
|
243
|
+
}
|
|
244
|
+
|
|
201
245
|
function projectForTurn(input) {
|
|
202
246
|
if (!exactKeys(input, new Set(['turnId', 'focusScopes']))) fail('COGNITIVE_LIFECYCLE_INVALID');
|
|
203
247
|
const turnId = safeTurnId(input.turnId);
|
|
@@ -226,6 +270,7 @@ function createCognitiveTurnLifecycle({ home, tenantId, agentId, runtimeId, now
|
|
|
226
270
|
recordRightsCheck,
|
|
227
271
|
recordToolPolicy,
|
|
228
272
|
recordToolResult,
|
|
273
|
+
recordToolBatch,
|
|
229
274
|
recordFocusSnapshot,
|
|
230
275
|
authorizeAttention,
|
|
231
276
|
projectForTurn,
|
|
@@ -8,6 +8,8 @@ const DEFAULT_SILENCE_MS = 60_000;
|
|
|
8
8
|
const RESUME_APPROVAL = /^(?:ja|yes|weiter|mach(?:e)? weiter|du kannst weiter(?:machen)?|bitte weiter|fortsetzen|resume|go)(?:[\s.!?,].*)?$/iu;
|
|
9
9
|
const CONVERSATION_CLOSE = /^(?:danke(?: dir)?|dankesch(?:oe|\u00f6)n|alles klar|ok(?:ay)?|passt|das war(?:'s| es| alles)|mehr nicht|fertig)(?:[\s.!?,].*)?$/iu;
|
|
10
10
|
const EXPLICIT_PAUSE = /^(?:(?:bitte\s+)?(?:pause|pausier(?:e)?|stop|stopp|warte|halt(?:e)?\s+an|nicht\s+weiter(?:machen)?))(?:[\s.!?,].*)?$/iu;
|
|
11
|
+
const DIRECT_TELEGRAM_CHANNEL = /<channel\b(?=[^>]*\bsource=["']telegram["'])(?=[^>]*\bpriority=["']direct["'])[^>]*>/iu;
|
|
12
|
+
const TELEGRAM_REPLY_TOOL = /^mcp__[^\s]*telegram[^\s]*__reply$/iu;
|
|
11
13
|
|
|
12
14
|
function isPrivateTelegramChat(chatId) {
|
|
13
15
|
return /^[1-9]\d*$/u.test(String(chatId ?? '').trim());
|
|
@@ -53,6 +55,20 @@ function isExplicitPauseRequest(text) {
|
|
|
53
55
|
return EXPLICIT_PAUSE.test(String(text ?? '').trim());
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
function createDirectReplyTurnStop(inputText) {
|
|
59
|
+
const direct = DIRECT_TELEGRAM_CHANNEL.test(String(inputText ?? ''));
|
|
60
|
+
let delivered = false;
|
|
61
|
+
return {
|
|
62
|
+
noteToolResult(toolName, isError) {
|
|
63
|
+
if (direct && isError !== true && TELEGRAM_REPLY_TOOL.test(String(toolName ?? ''))) {
|
|
64
|
+
delivered = true;
|
|
65
|
+
}
|
|
66
|
+
return delivered;
|
|
67
|
+
},
|
|
68
|
+
shouldStop: () => delivered,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
56
72
|
function createDirectFocusController(options = {}) {
|
|
57
73
|
const setTimer = options.setTimer ?? setTimeout;
|
|
58
74
|
const clearTimer = options.clearTimer ?? clearTimeout;
|
|
@@ -213,6 +229,7 @@ function readDirectFocusCheckpoint(env = process.env) {
|
|
|
213
229
|
module.exports = {
|
|
214
230
|
DEFAULT_SILENCE_MS,
|
|
215
231
|
createDirectFocusController,
|
|
232
|
+
createDirectReplyTurnStop,
|
|
216
233
|
directFocusCheckpointPath,
|
|
217
234
|
enqueueTelegramDirect,
|
|
218
235
|
isConversationClose,
|
package/blun.mjs
CHANGED
|
@@ -261553,6 +261553,8 @@ var init_turn = __esmMin((() => {
|
|
|
261553
261553
|
currentStep = 0;
|
|
261554
261554
|
cognitiveLifecycle;
|
|
261555
261555
|
cognitiveLifecycleUnavailable = false;
|
|
261556
|
+
cognitiveToolPolicyByCall = /* @__PURE__ */ new Map();
|
|
261557
|
+
cognitiveToolBatchesByTurn = /* @__PURE__ */ new Map();
|
|
261556
261558
|
constructor(agent) {
|
|
261557
261559
|
this.agent = agent;
|
|
261558
261560
|
}
|
|
@@ -261587,6 +261589,40 @@ var init_turn = __esmMin((() => {
|
|
|
261587
261589
|
this.agent.telemetry.track("cognitive_lifecycle_error", { stage: method, error_type: error?.code ?? error?.name ?? "Error" });
|
|
261588
261590
|
}
|
|
261589
261591
|
}
|
|
261592
|
+
bufferCognitiveToolPolicy(input) {
|
|
261593
|
+
this.cognitiveToolPolicyByCall.set(input.toolCallId, input);
|
|
261594
|
+
}
|
|
261595
|
+
bufferCognitiveToolResult(input) {
|
|
261596
|
+
const policy = this.cognitiveToolPolicyByCall.get(input.toolCallId);
|
|
261597
|
+
if (policy === void 0 || policy.turnId !== input.turnId) {
|
|
261598
|
+
this.recordCognitiveStage("recordToolResult", input);
|
|
261599
|
+
return;
|
|
261600
|
+
}
|
|
261601
|
+
this.cognitiveToolPolicyByCall.delete(input.toolCallId);
|
|
261602
|
+
const entries = this.cognitiveToolBatchesByTurn.get(input.turnId) ?? [];
|
|
261603
|
+
entries.push({
|
|
261604
|
+
toolCallId: input.toolCallId,
|
|
261605
|
+
toolName: input.toolName,
|
|
261606
|
+
decision: policy.decision,
|
|
261607
|
+
outcome: input.outcome,
|
|
261608
|
+
durationMs: input.durationMs
|
|
261609
|
+
});
|
|
261610
|
+
this.cognitiveToolBatchesByTurn.set(input.turnId, entries);
|
|
261611
|
+
}
|
|
261612
|
+
flushCognitiveToolEvidence(turnId, includePending) {
|
|
261613
|
+
const entries = this.cognitiveToolBatchesByTurn.get(turnId) ?? [];
|
|
261614
|
+
this.cognitiveToolBatchesByTurn.delete(turnId);
|
|
261615
|
+
for (let offset = 0; offset < entries.length; offset += 10) this.recordCognitiveStage("recordToolBatch", {
|
|
261616
|
+
turnId,
|
|
261617
|
+
entries: entries.slice(offset, offset + 10)
|
|
261618
|
+
});
|
|
261619
|
+
if (!includePending) return;
|
|
261620
|
+
for (const [toolCallId, policy] of this.cognitiveToolPolicyByCall) {
|
|
261621
|
+
if (policy.turnId !== turnId) continue;
|
|
261622
|
+
this.cognitiveToolPolicyByCall.delete(toolCallId);
|
|
261623
|
+
this.recordCognitiveStage("recordToolPolicy", policy);
|
|
261624
|
+
}
|
|
261625
|
+
}
|
|
261590
261626
|
projectCognitiveState(turnId) {
|
|
261591
261627
|
try {
|
|
261592
261628
|
return this.getCognitiveLifecycle()?.projectForTurn({ turnId }) ?? null;
|
|
@@ -261948,6 +261984,7 @@ var init_turn = __esmMin((() => {
|
|
|
261948
261984
|
durationMs: Date.now() - startedAt
|
|
261949
261985
|
};
|
|
261950
261986
|
this.agent.usage.endTurn();
|
|
261987
|
+
this.flushCognitiveToolEvidence(turnId, true);
|
|
261951
261988
|
this.recordCognitiveStage("endTurn", { turnId, reason: ended.reason, durationMs: ended.durationMs ?? 0 });
|
|
261952
261989
|
this.agent.emitEvent(ended);
|
|
261953
261990
|
return ended;
|
|
@@ -262062,6 +262099,7 @@ var init_turn = __esmMin((() => {
|
|
|
262062
262099
|
mode: this.telemetryModeByTurn.get(turnId) ?? this.telemetryMode(),
|
|
262063
262100
|
...this.requestProviderProps()
|
|
262064
262101
|
});
|
|
262102
|
+
this.flushCognitiveToolEvidence(turnId, true);
|
|
262065
262103
|
this.recordCognitiveStage("endTurn", { turnId, reason: ended.reason, durationMs: ended.durationMs ?? 0 });
|
|
262066
262104
|
this.agent.emitEvent(ended);
|
|
262067
262105
|
this.agent.endResponderTurn();
|
|
@@ -262140,6 +262178,7 @@ var init_turn = __esmMin((() => {
|
|
|
262140
262178
|
async runStepLoop(turnId, signal, input, origin) {
|
|
262141
262179
|
let stopHookContinuationUsed = false;
|
|
262142
262180
|
let goalOutcomeMessageContinuationUsed = false;
|
|
262181
|
+
const directReplyTurnStop = createDirectReplyTurnStop(blunExtractText(input));
|
|
262143
262182
|
const deduper = new ToolCallDeduplicator({ telemetry: this.agent.telemetry });
|
|
262144
262183
|
if (blunTurnNeedsInitialMcp(input, origin)) await this.agent.mcp?.waitForInitialLoad(signal);
|
|
262145
262184
|
const personalMemoryRecall = await this.agent.injection.injectPersonalMemoryForTurn(turnId, input, origin, signal);
|
|
@@ -262269,13 +262308,14 @@ var init_turn = __esmMin((() => {
|
|
|
262269
262308
|
},
|
|
262270
262309
|
afterStep: async ({ usage }) => {
|
|
262271
262310
|
previousStepToolOutcome = currentStepHadTool ? currentStepHadFailure ? "failure" : "success" : "none";
|
|
262311
|
+
this.flushCognitiveToolEvidence(turnId, false);
|
|
262272
262312
|
this.agent.usage.record(this.agent.activeResponderModel ?? model, usage, "turn");
|
|
262273
262313
|
if (stopForGoalBudget) this.setActiveSteerAcceptance(turnId, false);
|
|
262274
262314
|
await this.agent.toolResultBatchOffload.detect();
|
|
262275
262315
|
await this.agent.fullCompaction.afterStep(signal);
|
|
262276
262316
|
if (compactConversationTool !== void 0 && this.agent.fullCompaction.isProactiveCompactionEligible() && !selectedTools.includes(compactConversationTool)) selectedTools.push(compactConversationTool);
|
|
262277
262317
|
deduper.endStep();
|
|
262278
|
-
return stopForGoalBudget ? { stopTurn: true } : void 0;
|
|
262318
|
+
return stopForGoalBudget || directReplyTurnStop.shouldStop() ? { stopTurn: true } : void 0;
|
|
262279
262319
|
},
|
|
262280
262320
|
shouldContinueAfterStop: async (ctx) => {
|
|
262281
262321
|
const { signal } = ctx;
|
|
@@ -262321,7 +262361,7 @@ var init_turn = __esmMin((() => {
|
|
|
262321
262361
|
authorizeToolExecution: async (ctx) => {
|
|
262322
262362
|
try {
|
|
262323
262363
|
const resolution = await this.agent.permission.beforeToolCall(ctx);
|
|
262324
|
-
this.
|
|
262364
|
+
this.bufferCognitiveToolPolicy({
|
|
262325
262365
|
turnId,
|
|
262326
262366
|
toolCallId: ctx.toolCall.id,
|
|
262327
262367
|
toolName: ctx.toolCall.name,
|
|
@@ -262329,7 +262369,7 @@ var init_turn = __esmMin((() => {
|
|
|
262329
262369
|
});
|
|
262330
262370
|
return resolution;
|
|
262331
262371
|
} catch (error) {
|
|
262332
|
-
this.
|
|
262372
|
+
this.bufferCognitiveToolPolicy({
|
|
262333
262373
|
turnId,
|
|
262334
262374
|
toolCallId: ctx.toolCall.id,
|
|
262335
262375
|
toolName: ctx.toolCall.name,
|
|
@@ -262343,6 +262383,7 @@ var init_turn = __esmMin((() => {
|
|
|
262343
262383
|
const { isError, output } = finalResult;
|
|
262344
262384
|
currentStepHadTool = true;
|
|
262345
262385
|
if (isError === true) currentStepHadFailure = true;
|
|
262386
|
+
directReplyTurnStop.noteToolResult(ctx.toolCall.name, isError);
|
|
262346
262387
|
const event = isError === true ? "PostToolUseFailure" : "PostToolUse";
|
|
262347
262388
|
this.agent.hooks?.fireAndForgetTrigger(event, {
|
|
262348
262389
|
matcherValue: ctx.toolCall.name,
|
|
@@ -262478,7 +262519,7 @@ var init_turn = __esmMin((() => {
|
|
|
262478
262519
|
};
|
|
262479
262520
|
const errorType = outcome === "error" ? telemetryToolErrorType(event.result) : void 0;
|
|
262480
262521
|
if (errorType !== void 0) properties["error_type"] = errorType;
|
|
262481
|
-
this.
|
|
262522
|
+
this.bufferCognitiveToolResult({
|
|
262482
262523
|
turnId,
|
|
262483
262524
|
toolCallId: event.toolCallId,
|
|
262484
262525
|
toolName: started.name,
|
|
@@ -419037,7 +419078,7 @@ registerUiCatalogFragment({
|
|
|
419037
419078
|
*/
|
|
419038
419079
|
var { projectUnaddressedTelegramContext } = createRequire(import.meta.url)("./bin/telegram-context-projection-policy.cjs");
|
|
419039
419080
|
var { enqueueTelegramUrgent, rewriteTelegramUrgentEnvelope, telegramUrgentMessage } = createRequire(import.meta.url)("./bin/telegram-urgent-policy.cjs");
|
|
419040
|
-
var { createDirectFocusController, enqueueTelegramDirect, readDirectFocusCheckpoint, rewriteTelegramDirectEnvelope, telegramDirectMessage, writeDirectFocusCheckpoint } = createRequire(import.meta.url)("./bin/telegram-direct-focus-policy.cjs");
|
|
419081
|
+
var { createDirectFocusController, createDirectReplyTurnStop, enqueueTelegramDirect, readDirectFocusCheckpoint, rewriteTelegramDirectEnvelope, telegramDirectMessage, writeDirectFocusCheckpoint } = createRequire(import.meta.url)("./bin/telegram-direct-focus-policy.cjs");
|
|
419041
419082
|
var { removeQueuedReloadCommands, removeQueuedSlashCommands } = createRequire(import.meta.url)("./bin/reload-queue-policy.cjs");
|
|
419042
419083
|
const MAX_BUFFERED_CONTEXT_MESSAGES = 20;
|
|
419043
419084
|
const MAX_BUFFERED_CONTEXT_CHARS = 24e3;
|