blun-king-cli 9.1.305 → 9.1.306

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,8 @@ const { openCognitiveStateStore } = require('./cognitive-state-store.cjs');
6
6
  const SAFE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
7
7
  const RIGHTS_AUTHORITIES = new Set(['runtime_user_prompt_hook', 'runtime_tool_policy']);
8
8
  const RIGHTS_DECISIONS = new Set(['passed', 'blocked', 'not_applicable']);
9
+ const TOOL_POLICY_DECISIONS = new Set(['passed', 'blocked', 'error']);
10
+ const TOOL_OUTCOMES = new Set(['success', 'error', 'cancelled']);
9
11
  const TURN_REASONS = new Set(['completed', 'cancelled', 'filtered', 'failed']);
10
12
 
11
13
  function fail(code) {
@@ -28,6 +30,11 @@ function safeTurnId(value) {
28
30
  return Number.isSafeInteger(value) && value >= 0 ? value : null;
29
31
  }
30
32
 
33
+ function cleanLabel(value, max = 128) {
34
+ const text = String(value ?? '').replace(/[\u0000-\u001f\u007f]+/gu, ' ').replace(/\s+/gu, ' ').trim();
35
+ return text && text.length <= max ? text : '';
36
+ }
37
+
31
38
  function digestId(prefix, values) {
32
39
  const digest = crypto.createHash('sha256').update(values.join('\0')).digest('hex').slice(0, 40);
33
40
  return `${prefix}-${digest}`;
@@ -132,9 +139,44 @@ function createCognitiveTurnLifecycle({ home, tenantId, agentId, runtimeId, now
132
139
  ]);
133
140
  }
134
141
 
142
+ function toolFields(input, allowedKeys) {
143
+ if (!exactKeys(input, allowedKeys)) fail('COGNITIVE_LIFECYCLE_INVALID');
144
+ const turnId = safeTurnId(input.turnId);
145
+ const toolCallId = cleanLabel(input.toolCallId, 256);
146
+ const toolName = cleanLabel(input.toolName, 128);
147
+ if (turnId === null || !toolCallId || !toolName) fail('COGNITIVE_LIFECYCLE_INVALID');
148
+ return { turnId, toolCallId, toolName, callKey: digestId('call', [toolCallId]).slice(0, 21) };
149
+ }
150
+
151
+ function recordToolPolicy(input) {
152
+ const { turnId, toolCallId, toolName, callKey } = toolFields(input, new Set(['turnId', 'toolCallId', 'toolName', 'decision']));
153
+ const decision = String(input.decision ?? '');
154
+ if (!TOOL_POLICY_DECISIONS.has(decision)) fail('COGNITIVE_LIFECYCLE_INVALID');
155
+ return commitStage(`turn-${turnId}-${callKey}-policy`, [{
156
+ domain: 'world',
157
+ key: `turn:${turnId}:${callKey}:tool-policy`,
158
+ value: `${decision}:runtime_tool_policy:${toolName}`,
159
+ confidence: 1,
160
+ scope: 'runtime',
161
+ }]);
162
+ }
163
+
164
+ function recordToolResult(input) {
165
+ const { turnId, toolCallId, toolName, callKey } = toolFields(input, new Set(['turnId', 'toolCallId', 'toolName', 'outcome', 'durationMs']));
166
+ const outcome = String(input.outcome ?? '');
167
+ const durationMs = Number(input.durationMs);
168
+ if (!TOOL_OUTCOMES.has(outcome) || !Number.isSafeInteger(durationMs) || durationMs < 0) fail('COGNITIVE_LIFECYCLE_INVALID');
169
+ return commitStage(`turn-${turnId}-${callKey}-result`, [
170
+ { domain: 'expected_evidence', key: `turn:${turnId}:${callKey}:tool-result`, value: `${outcome}:${durationMs}ms:${toolName}`, confidence: 1, scope: 'runtime' },
171
+ { domain: 'next_trigger', key: `turn:${turnId}:${callKey}:tool-next`, value: outcome === 'success' ? 'continue-after-tool' : 'inspect-tool-failure', confidence: 1, scope: 'runtime' },
172
+ ]);
173
+ }
174
+
135
175
  return {
136
176
  startTurn,
137
177
  recordRightsCheck,
178
+ recordToolPolicy,
179
+ recordToolResult,
138
180
  endTurn,
139
181
  read: () => store.read({ tenantId: tenant, agentId: agent }),
140
182
  verify: () => store.verify({ tenantId: tenant, agentId: agent }),
package/blun.mjs CHANGED
@@ -262214,7 +262214,24 @@ var init_turn = __esmMin((() => {
262214
262214
  if (cached !== null) return { syntheticResult: cached };
262215
262215
  },
262216
262216
  authorizeToolExecution: async (ctx) => {
262217
- return this.agent.permission.beforeToolCall(ctx);
262217
+ try {
262218
+ const resolution = await this.agent.permission.beforeToolCall(ctx);
262219
+ this.recordCognitiveStage("recordToolPolicy", {
262220
+ turnId,
262221
+ toolCallId: ctx.toolCall.id,
262222
+ toolName: ctx.toolCall.name,
262223
+ decision: resolution?.block === true ? "blocked" : "passed"
262224
+ });
262225
+ return resolution;
262226
+ } catch (error) {
262227
+ this.recordCognitiveStage("recordToolPolicy", {
262228
+ turnId,
262229
+ toolCallId: ctx.toolCall.id,
262230
+ toolName: ctx.toolCall.name,
262231
+ decision: "error"
262232
+ });
262233
+ throw error;
262234
+ }
262218
262235
  },
262219
262236
  finalizeToolResult: async (ctx) => {
262220
262237
  const finalResult = await deduper.finalizeResult(ctx.toolCall.id, ctx.toolCall.name, ctx.args, ctx.result);
@@ -262356,6 +262373,13 @@ var init_turn = __esmMin((() => {
262356
262373
  };
262357
262374
  const errorType = outcome === "error" ? telemetryToolErrorType(event.result) : void 0;
262358
262375
  if (errorType !== void 0) properties["error_type"] = errorType;
262376
+ this.recordCognitiveStage("recordToolResult", {
262377
+ turnId,
262378
+ toolCallId: event.toolCallId,
262379
+ toolName: started.name,
262380
+ outcome,
262381
+ durationMs: Date.now() - started.startedAt
262382
+ });
262359
262383
  this.agent.telemetry.track("tool_call", properties);
262360
262384
  this.agent.feedRootMissionContract("result", {
262361
262385
  toolCallId: event.toolCallId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.305",
3
+ "version": "9.1.306",
4
4
  "description": "BLUN CLI - your own AI agent with a Telegram channel. Get it done. With BLUN.",
5
5
  "license": "MIT",
6
6
  "bin": {