blun-king-cli 9.1.363 → 9.1.364
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.
|
@@ -230,6 +230,94 @@ function createCognitiveTurnLifecycle({ home, tenantId, agentId, runtimeId, now
|
|
|
230
230
|
return commitDurableStage(`focus-${input.snapshotId}`, observations);
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
+
function commitExplicitFocusRevision(kind, input) {
|
|
234
|
+
const correction = kind === 'correction';
|
|
235
|
+
const allowed = correction
|
|
236
|
+
? new Set(['requestId', 'targetObservationId', 'domain', 'key', 'value', 'scope', 'authority', 'confirmation', 'occurredAt', 'source'])
|
|
237
|
+
: new Set(['requestId', 'targetObservationId', 'domain', 'key', 'scope', 'authority', 'confirmation', 'occurredAt', 'source']);
|
|
238
|
+
if (!exactKeys(input, allowed)) fail('COGNITIVE_REVISION_INVALID');
|
|
239
|
+
const requestId = safeId(input.requestId);
|
|
240
|
+
const targetObservationId = safeId(input.targetObservationId);
|
|
241
|
+
const domain = String(input.domain ?? '');
|
|
242
|
+
const key = cleanLabel(input.key, 128);
|
|
243
|
+
const scope = cleanLabel(input.scope, 128);
|
|
244
|
+
const occurredAt = String(input.occurredAt ?? '').trim();
|
|
245
|
+
const source = input.source;
|
|
246
|
+
if (input.authority !== 'runtime_user_prompt_hook' || input.confirmation !== 'explicit_user_request') {
|
|
247
|
+
fail('COGNITIVE_REVISION_EXPLICIT_USER_REQUIRED');
|
|
248
|
+
}
|
|
249
|
+
if (!requestId || !targetObservationId || !FOCUS_DOMAINS.has(domain) || !key
|
|
250
|
+
|| AUTHORITY_KEY_RE.test(key) || !scope || scope === 'runtime'
|
|
251
|
+
|| Number.isNaN(Date.parse(occurredAt))
|
|
252
|
+
|| !exactKeys(source, new Set(['provider', 'actorId', 'contextId', 'messageId']))) {
|
|
253
|
+
fail('COGNITIVE_REVISION_INVALID');
|
|
254
|
+
}
|
|
255
|
+
const normalizedSource = {
|
|
256
|
+
provider: safeId(source.provider),
|
|
257
|
+
actor_id: safeId(source.actorId),
|
|
258
|
+
context_id: safeId(source.contextId),
|
|
259
|
+
message_id: safeId(source.messageId),
|
|
260
|
+
};
|
|
261
|
+
if (Object.values(normalizedSource).some((value) => !value)) fail('COGNITIVE_REVISION_INVALID');
|
|
262
|
+
const value = correction ? cleanLabel(input.value, 512) : 'withdrawn';
|
|
263
|
+
if (!value) fail('COGNITIVE_REVISION_INVALID');
|
|
264
|
+
const eventId = digestId('revision', [tenant, agent, kind, requestId]);
|
|
265
|
+
const observationId = digestId('revisionobs', [eventId]);
|
|
266
|
+
const observation = {
|
|
267
|
+
observation_id: observationId,
|
|
268
|
+
domain,
|
|
269
|
+
key,
|
|
270
|
+
value,
|
|
271
|
+
confidence: 1,
|
|
272
|
+
scope,
|
|
273
|
+
...(correction ? { supersedes: targetObservationId } : { withdraws: targetObservationId }),
|
|
274
|
+
};
|
|
275
|
+
const normalizedOccurredAt = new Date(occurredAt).toISOString();
|
|
276
|
+
for (let attempt = 0; attempt < 4; attempt += 1) {
|
|
277
|
+
const current = store.read({ tenantId: tenant, agentId: agent });
|
|
278
|
+
const existing = current.observations.find((item) => item.observation_id === observationId);
|
|
279
|
+
if (existing) {
|
|
280
|
+
const matches = existing.domain === observation.domain && existing.key === observation.key
|
|
281
|
+
&& existing.value === observation.value && existing.confidence === 1
|
|
282
|
+
&& existing.scope === observation.scope && existing.occurred_at === normalizedOccurredAt
|
|
283
|
+
&& existing.supersedes === (observation.supersedes ?? null)
|
|
284
|
+
&& existing.withdraws === (observation.withdraws ?? null)
|
|
285
|
+
&& existing.source.provider === normalizedSource.provider
|
|
286
|
+
&& existing.source.actor_id === normalizedSource.actor_id
|
|
287
|
+
&& existing.source.context_id === normalizedSource.context_id
|
|
288
|
+
&& existing.source.message_id === normalizedSource.message_id;
|
|
289
|
+
if (!matches) fail('COGNITIVE_REVISION_REQUEST_REUSE');
|
|
290
|
+
return { version: current.version, idempotent: true };
|
|
291
|
+
}
|
|
292
|
+
const target = current.observations.find((item) => item.observation_id === targetObservationId);
|
|
293
|
+
if (target && Date.parse(normalizedOccurredAt) < Date.parse(target.occurred_at)) {
|
|
294
|
+
fail('COGNITIVE_REVISION_TIME_ORDER');
|
|
295
|
+
}
|
|
296
|
+
try {
|
|
297
|
+
return store.commit({
|
|
298
|
+
tenantId: tenant,
|
|
299
|
+
agentId: agent,
|
|
300
|
+
eventId,
|
|
301
|
+
expectedVersion: current.version,
|
|
302
|
+
occurredAt: normalizedOccurredAt,
|
|
303
|
+
source: normalizedSource,
|
|
304
|
+
observations: [observation],
|
|
305
|
+
});
|
|
306
|
+
} catch (error) {
|
|
307
|
+
if (error?.code !== 'COGNITIVE_VERSION_CONFLICT' || attempt === 3) throw error;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
fail('COGNITIVE_VERSION_CONFLICT');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function correctFocusObservation(input) {
|
|
314
|
+
return commitExplicitFocusRevision('correction', input);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function withdrawFocusObservation(input) {
|
|
318
|
+
return commitExplicitFocusRevision('withdrawal', input);
|
|
319
|
+
}
|
|
320
|
+
|
|
233
321
|
function toolFields(input, allowedKeys) {
|
|
234
322
|
if (!exactKeys(input, allowedKeys)) fail('COGNITIVE_LIFECYCLE_INVALID');
|
|
235
323
|
const turnId = safeTurnId(input.turnId);
|
|
@@ -337,6 +425,8 @@ function createCognitiveTurnLifecycle({ home, tenantId, agentId, runtimeId, now
|
|
|
337
425
|
recordToolResult,
|
|
338
426
|
recordToolBatch,
|
|
339
427
|
recordFocusSnapshot,
|
|
428
|
+
correctFocusObservation,
|
|
429
|
+
withdrawFocusObservation,
|
|
340
430
|
authorizeAttention,
|
|
341
431
|
projectForTurn,
|
|
342
432
|
endTurn,
|