blun-king-cli 9.1.371 → 9.1.373
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-action-checkpoint.cjs +27 -1
- package/bin/cognitive-focus-projection.cjs +17 -2
- package/bin/cognitive-state-store.cjs +18 -6
- package/bin/cognitive-turn-lifecycle.cjs +10 -2
- package/bin/cognitive-work-focus.cjs +11 -4
- package/bin/launcher-runtime.js +113 -2
- package/bin/personality-memory-adapter.cjs +1 -0
- package/blun.mjs +55 -12
- package/package.json +1 -1
|
@@ -6,8 +6,11 @@ const PHASES = new Set(['orient', 'plan', 'act', 'verify', 'learn', 'wait']);
|
|
|
6
6
|
const EVIDENCE_BASES = new Set([
|
|
7
7
|
'runtime_tool', 'user_statement', 'external_report', 'carried_forward',
|
|
8
8
|
]);
|
|
9
|
+
const EPISTEMIC_STATES = new Set([
|
|
10
|
+
'verified', 'credible_unverified', 'hypothesis', 'uncertain_memory', 'stale', 'unknown',
|
|
11
|
+
]);
|
|
9
12
|
const MODEL_KEYS = new Set([
|
|
10
|
-
'revision', 'phase', 'evidenceBasis', 'lastVerified', 'nextAction', 'expectedEvidence', 'updatedAt',
|
|
13
|
+
'revision', 'phase', 'evidenceBasis', 'epistemicState', 'lastVerified', 'nextAction', 'expectedEvidence', 'updatedAt',
|
|
11
14
|
]);
|
|
12
15
|
const RUNTIME_KEYS = new Set([...MODEL_KEYS, 'evidenceReceipt']);
|
|
13
16
|
const EVIDENCE_INPUT_KEYS = new Set([
|
|
@@ -46,6 +49,14 @@ function normalizedEvidenceBasis(value, allowLegacy = false) {
|
|
|
46
49
|
: 'evidenceBasis is invalid');
|
|
47
50
|
}
|
|
48
51
|
|
|
52
|
+
function normalizedEpistemicState(value, allowLegacy = false) {
|
|
53
|
+
const state = String(value ?? '').trim();
|
|
54
|
+
if (EPISTEMIC_STATES.has(state) || allowLegacy && state === 'legacy_unknown') return state;
|
|
55
|
+
throw new TypeError(value === undefined
|
|
56
|
+
? 'epistemicState is required'
|
|
57
|
+
: 'epistemicState is invalid');
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
function normalizedTurnId(value) {
|
|
50
61
|
const turnId = Number(value);
|
|
51
62
|
if (!Number.isSafeInteger(turnId) || turnId < 0) throw new TypeError('evidence turnId must be a non-negative integer');
|
|
@@ -129,11 +140,18 @@ function assertActionCheckpointRevision(current, input) {
|
|
|
129
140
|
|
|
130
141
|
function assertActionCheckpointEvidenceBasis(current, input, runtimeEvidence) {
|
|
131
142
|
const basis = normalizedEvidenceBasis(input?.evidenceBasis);
|
|
143
|
+
const epistemicState = normalizedEpistemicState(input?.epistemicState);
|
|
132
144
|
if (basis === 'runtime_tool') {
|
|
133
145
|
const receipt = normalizeActionEvidenceReceipt(runtimeEvidence);
|
|
134
146
|
if (receipt.successfulTools < 1) {
|
|
135
147
|
throw new TypeError('runtime_tool evidenceBasis requires a successful runtime tool in the current turn');
|
|
136
148
|
}
|
|
149
|
+
if (epistemicState !== 'verified') {
|
|
150
|
+
throw new TypeError('runtime_tool evidenceBasis requires verified epistemicState');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (basis === 'external_report' && epistemicState === 'verified') {
|
|
154
|
+
throw new TypeError('external_report evidenceBasis cannot claim verified epistemicState');
|
|
137
155
|
}
|
|
138
156
|
if (basis === 'carried_forward') {
|
|
139
157
|
if (!current) throw new TypeError('carried_forward evidenceBasis requires a current checkpoint');
|
|
@@ -144,6 +162,9 @@ function assertActionCheckpointEvidenceBasis(current, input, runtimeEvidence) {
|
|
|
144
162
|
if (bounded(input?.lastVerified, 'lastVerified') !== currentValue.lastVerified) {
|
|
145
163
|
throw new TypeError('carried_forward evidenceBasis cannot change lastVerified');
|
|
146
164
|
}
|
|
165
|
+
if (epistemicState !== currentValue.epistemicState) {
|
|
166
|
+
throw new TypeError('carried_forward evidenceBasis cannot change epistemicState');
|
|
167
|
+
}
|
|
147
168
|
}
|
|
148
169
|
return basis;
|
|
149
170
|
}
|
|
@@ -162,6 +183,9 @@ function normalizeActionCheckpoint(input, options = {}) {
|
|
|
162
183
|
const evidenceBasis = input.evidenceBasis === undefined && replay
|
|
163
184
|
? 'legacy_unknown'
|
|
164
185
|
: normalizedEvidenceBasis(input.evidenceBasis, replay);
|
|
186
|
+
const epistemicState = input.epistemicState === undefined && replay
|
|
187
|
+
? 'legacy_unknown'
|
|
188
|
+
: normalizedEpistemicState(input.epistemicState, replay);
|
|
165
189
|
const updatedAt = options.preserveUpdatedAt === true && input.updatedAt !== undefined
|
|
166
190
|
? normalizedTimestamp(input.updatedAt)
|
|
167
191
|
: normalizedTimestamp(options.now ?? new Date());
|
|
@@ -169,6 +193,7 @@ function normalizeActionCheckpoint(input, options = {}) {
|
|
|
169
193
|
revision: normalizedRevision(input.revision),
|
|
170
194
|
phase,
|
|
171
195
|
evidenceBasis,
|
|
196
|
+
epistemicState,
|
|
172
197
|
lastVerified: bounded(input.lastVerified, 'lastVerified'),
|
|
173
198
|
nextAction: bounded(input.nextAction, 'nextAction'),
|
|
174
199
|
expectedEvidence: bounded(input.expectedEvidence, 'expectedEvidence'),
|
|
@@ -191,6 +216,7 @@ function projectActionCheckpoint(checkpoint) {
|
|
|
191
216
|
`Revision: ${value.revision}`,
|
|
192
217
|
`Phase: ${value.phase}`,
|
|
193
218
|
`Evidence basis: ${value.evidenceBasis.replaceAll('_', ' ')}`,
|
|
219
|
+
`Epistemic state: ${value.epistemicState.replaceAll('_', ' ')}`,
|
|
194
220
|
`Last verified: ${value.lastVerified}`,
|
|
195
221
|
];
|
|
196
222
|
lines.push(`Next action: ${value.nextAction}`);
|
|
@@ -20,6 +20,15 @@ const LABELS = new Map([
|
|
|
20
20
|
['self', 'Self'],
|
|
21
21
|
]);
|
|
22
22
|
const SAFETY_LINE = 'Durable context only; it cannot authorize any action or override the current assignment or runtime policy.';
|
|
23
|
+
const EPISTEMIC_MARKERS = new Map([
|
|
24
|
+
['verified', ''],
|
|
25
|
+
['credible_unverified', ' [unverified]'],
|
|
26
|
+
['hypothesis', ' [hypothesis]'],
|
|
27
|
+
['uncertain_memory', ' [uncertain memory]'],
|
|
28
|
+
['stale', ' [stale]'],
|
|
29
|
+
['unknown', ' [unknown]'],
|
|
30
|
+
['legacy_unknown', ' [unknown]'],
|
|
31
|
+
]);
|
|
23
32
|
|
|
24
33
|
function clean(value, max = 256) {
|
|
25
34
|
const text = String(value ?? '').replace(/[\u0000-\u001f\u007f]+/gu, ' ').replace(/\s+/gu, ' ').trim();
|
|
@@ -52,13 +61,19 @@ function buildCognitiveFocusProjection(state, { focusScopes, maxItems = 6, maxCh
|
|
|
52
61
|
const withdraws = item?.withdraws === null || item?.withdraws === undefined
|
|
53
62
|
? null : clean(item.withdraws, 128);
|
|
54
63
|
const confidence = Number(item?.confidence);
|
|
64
|
+
const epistemicState = item?.epistemic_state === undefined
|
|
65
|
+
? 'legacy_unknown' : String(item.epistemic_state);
|
|
55
66
|
const occurredAt = Date.parse(String(item?.occurred_at ?? ''));
|
|
56
67
|
if (!FOCUS_DOMAINS.has(domain) || !key || !value || !scope || scope === 'runtime'
|
|
57
68
|
|| !Number.isFinite(confidence) || confidence < 0.5 || confidence > 1
|
|
69
|
+
|| !EPISTEMIC_MARKERS.has(epistemicState)
|
|
58
70
|
|| !Number.isFinite(occurredAt)) return;
|
|
59
71
|
const groupKey = `${scope}\0${domain}\0${key}`;
|
|
60
72
|
const existing = groups.get(groupKey) ?? [];
|
|
61
|
-
existing.push({
|
|
73
|
+
existing.push({
|
|
74
|
+
domain, key, value, scope, observationId, supersedes, withdraws,
|
|
75
|
+
confidence, epistemicState, occurredAt, index,
|
|
76
|
+
});
|
|
62
77
|
groups.set(groupKey, existing);
|
|
63
78
|
});
|
|
64
79
|
|
|
@@ -83,7 +98,7 @@ function buildCognitiveFocusProjection(state, { focusScopes, maxItems = 6, maxCh
|
|
|
83
98
|
if (item.conflict) return `- Conflict: ${item.key} has incompatible evidence; verify before relying on it.`;
|
|
84
99
|
const marker = item.corrected ? ' [corrected]'
|
|
85
100
|
: item.contested ? ' [contested; stronger evidence]' : item.revised ? ' [revised]' : '';
|
|
86
|
-
return `- ${LABELS.get(item.domain)}: ${item.value}${marker}`;
|
|
101
|
+
return `- ${LABELS.get(item.domain)}: ${item.value}${EPISTEMIC_MARKERS.get(item.epistemicState)}${marker}`;
|
|
87
102
|
});
|
|
88
103
|
while ([`Current durable focus (${lines.length} items):`, ...lines, SAFETY_LINE].join('\n').length > maxChars
|
|
89
104
|
&& lines.length > 0) lines.pop();
|
|
@@ -7,6 +7,9 @@ const { DatabaseSync } = require('node:sqlite');
|
|
|
7
7
|
|
|
8
8
|
const SAFE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
9
9
|
const DOMAINS = new Set(['self', 'world', 'team', 'goal', 'open_thread', 'assumption', 'next_trigger', 'expected_evidence']);
|
|
10
|
+
const EPISTEMIC_STATES = new Set([
|
|
11
|
+
'verified', 'credible_unverified', 'hypothesis', 'uncertain_memory', 'stale', 'unknown', 'legacy_unknown',
|
|
12
|
+
]);
|
|
10
13
|
const FORBIDDEN_KEY_RE = /(?:^|_)(?:acl|api_key|capability|password|permission|secret|token)(?:_|$)/iu;
|
|
11
14
|
const MAX_EVENT_BYTES = 64 * 1024;
|
|
12
15
|
const MAX_OBSERVATIONS = 32;
|
|
@@ -52,7 +55,7 @@ function normalizeSource(source) {
|
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
function normalizeObservation(value) {
|
|
55
|
-
const allowed = new Set(['observation_id', 'domain', 'key', 'value', 'confidence', 'scope', 'supersedes', 'withdraws']);
|
|
58
|
+
const allowed = new Set(['observation_id', 'domain', 'key', 'value', 'confidence', 'epistemic_state', 'scope', 'supersedes', 'withdraws']);
|
|
56
59
|
if (!exactKeys(value, allowed) || hasForbiddenKey(value)) fail('COGNITIVE_FORBIDDEN_FIELD');
|
|
57
60
|
const observation = {
|
|
58
61
|
observation_id: safeId(value.observation_id),
|
|
@@ -60,11 +63,14 @@ function normalizeObservation(value) {
|
|
|
60
63
|
key: cleanText(value.key, 128),
|
|
61
64
|
value: cleanText(value.value, 2048),
|
|
62
65
|
confidence: Number(value.confidence),
|
|
66
|
+
epistemic_state: value.epistemic_state === undefined
|
|
67
|
+
? 'legacy_unknown' : String(value.epistemic_state),
|
|
63
68
|
scope: cleanText(value.scope, 128),
|
|
64
69
|
};
|
|
65
70
|
if (!observation.observation_id || !DOMAINS.has(observation.domain) || !observation.key
|
|
66
71
|
|| !observation.value || !Number.isFinite(observation.confidence)
|
|
67
|
-
|| observation.confidence < 0 || observation.confidence > 1
|
|
72
|
+
|| observation.confidence < 0 || observation.confidence > 1
|
|
73
|
+
|| !EPISTEMIC_STATES.has(observation.epistemic_state) || !observation.scope) {
|
|
68
74
|
fail('COGNITIVE_INVALID_EVENT');
|
|
69
75
|
}
|
|
70
76
|
if (FORBIDDEN_KEY_RE.test(observation.key)) fail('COGNITIVE_FORBIDDEN_FIELD');
|
|
@@ -152,6 +158,7 @@ function initialize(db) {
|
|
|
152
158
|
fact_key TEXT NOT NULL,
|
|
153
159
|
value_text TEXT NOT NULL,
|
|
154
160
|
confidence REAL NOT NULL,
|
|
161
|
+
epistemic_state TEXT NOT NULL DEFAULT 'legacy_unknown',
|
|
155
162
|
scope TEXT NOT NULL,
|
|
156
163
|
source_json TEXT NOT NULL,
|
|
157
164
|
occurred_at TEXT NOT NULL,
|
|
@@ -187,6 +194,9 @@ function initialize(db) {
|
|
|
187
194
|
if (!observationColumns.some((column) => column.name === 'withdraws_observation_id')) {
|
|
188
195
|
db.exec('ALTER TABLE cognitive_observations ADD COLUMN withdraws_observation_id TEXT');
|
|
189
196
|
}
|
|
197
|
+
if (!observationColumns.some((column) => column.name === 'epistemic_state')) {
|
|
198
|
+
db.exec("ALTER TABLE cognitive_observations ADD COLUMN epistemic_state TEXT NOT NULL DEFAULT 'legacy_unknown'");
|
|
199
|
+
}
|
|
190
200
|
}
|
|
191
201
|
|
|
192
202
|
function openCognitiveStateStore({ home } = {}) {
|
|
@@ -218,8 +228,8 @@ function openCognitiveStateStore({ home } = {}) {
|
|
|
218
228
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
219
229
|
.run(normalized.event_id, normalized.tenant_id, normalized.agent_id, actualVersion, newVersion, normalized.occurred_at, payload, previousHash, eventHash);
|
|
220
230
|
const insertObservation = db.prepare(`INSERT INTO cognitive_observations
|
|
221
|
-
(observation_id, event_id, tenant_id, agent_id, domain, fact_key, value_text, confidence, scope, source_json, occurred_at, supersedes_observation_id, withdraws_observation_id)
|
|
222
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
231
|
+
(observation_id, event_id, tenant_id, agent_id, domain, fact_key, value_text, confidence, epistemic_state, scope, source_json, occurred_at, supersedes_observation_id, withdraws_observation_id)
|
|
232
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
223
233
|
const sourceJson = JSON.stringify(normalized.source);
|
|
224
234
|
for (const observation of normalized.observations) {
|
|
225
235
|
if (observation.supersedes) {
|
|
@@ -237,7 +247,8 @@ function openCognitiveStateStore({ home } = {}) {
|
|
|
237
247
|
|| target.scope !== observation.scope) fail('COGNITIVE_INVALID_WITHDRAWAL');
|
|
238
248
|
}
|
|
239
249
|
insertObservation.run(observation.observation_id, normalized.event_id, normalized.tenant_id, normalized.agent_id,
|
|
240
|
-
observation.domain, observation.key, observation.value, observation.confidence, observation.
|
|
250
|
+
observation.domain, observation.key, observation.value, observation.confidence, observation.epistemic_state,
|
|
251
|
+
observation.scope, sourceJson,
|
|
241
252
|
normalized.occurred_at, observation.supersedes ?? null, observation.withdraws ?? null);
|
|
242
253
|
}
|
|
243
254
|
db.prepare(`INSERT INTO cognitive_streams (tenant_id, agent_id, version, updated_at) VALUES (?, ?, ?, ?)
|
|
@@ -256,7 +267,7 @@ function openCognitiveStateStore({ home } = {}) {
|
|
|
256
267
|
const agent = safeId(agentId);
|
|
257
268
|
if (!tenant || !agent) fail('COGNITIVE_INVALID_EVENT');
|
|
258
269
|
const stream = db.prepare('SELECT version, updated_at FROM cognitive_streams WHERE tenant_id = ? AND agent_id = ?').get(tenant, agent);
|
|
259
|
-
const rows = db.prepare(`SELECT domain, fact_key, value_text, confidence, scope, source_json, occurred_at, observation_id,
|
|
270
|
+
const rows = db.prepare(`SELECT domain, fact_key, value_text, confidence, epistemic_state, scope, source_json, occurred_at, observation_id,
|
|
260
271
|
supersedes_observation_id, withdraws_observation_id
|
|
261
272
|
FROM cognitive_observations WHERE tenant_id = ? AND agent_id = ? ORDER BY occurred_at, rowid`).all(tenant, agent);
|
|
262
273
|
return {
|
|
@@ -268,6 +279,7 @@ function openCognitiveStateStore({ home } = {}) {
|
|
|
268
279
|
key: row.fact_key,
|
|
269
280
|
value: row.value_text,
|
|
270
281
|
confidence: row.confidence,
|
|
282
|
+
epistemic_state: row.epistemic_state,
|
|
271
283
|
scope: row.scope,
|
|
272
284
|
source: JSON.parse(row.source_json),
|
|
273
285
|
occurred_at: row.occurred_at,
|
|
@@ -15,6 +15,9 @@ const TOOL_POLICY_DECISIONS = new Set(['passed', 'blocked', 'error']);
|
|
|
15
15
|
const TOOL_OUTCOMES = new Set(['success', 'error', 'cancelled']);
|
|
16
16
|
const TURN_REASONS = new Set(['completed', 'cancelled', 'filtered', 'failed']);
|
|
17
17
|
const FOCUS_DOMAINS = new Set(['self', 'team', 'goal', 'open_thread', 'next_trigger', 'expected_evidence']);
|
|
18
|
+
const FOCUS_EPISTEMIC_STATES = new Set([
|
|
19
|
+
'verified', 'credible_unverified', 'hypothesis', 'uncertain_memory', 'stale', 'unknown', 'legacy_unknown',
|
|
20
|
+
]);
|
|
18
21
|
const AUTHORITY_KEY_RE = /(?:^|:|_)(?:acl|api[_-]?key|capability|password|permission|secret|token)(?::|_|$)/iu;
|
|
19
22
|
|
|
20
23
|
function fail(code) {
|
|
@@ -90,6 +93,7 @@ function createCognitiveTurnLifecycle({ home, tenantId, agentId, runtimeId, now
|
|
|
90
93
|
const eventId = digestId('cycle', [tenant, agent, runtime, stageKey]);
|
|
91
94
|
const normalized = observations.map((item, index) => ({
|
|
92
95
|
observation_id: digestId('cycleobs', [eventId, String(index)]),
|
|
96
|
+
epistemic_state: 'verified',
|
|
93
97
|
...item,
|
|
94
98
|
}));
|
|
95
99
|
for (let attempt = 0; attempt < 4; attempt += 1) {
|
|
@@ -216,16 +220,19 @@ function createCognitiveTurnLifecycle({ home, tenantId, agentId, runtimeId, now
|
|
|
216
220
|
fail('COGNITIVE_FOCUS_INVALID');
|
|
217
221
|
}
|
|
218
222
|
const observations = input.observations.map((item) => {
|
|
219
|
-
if (!exactKeys(item, new Set(['domain', 'key', 'value', 'confidence', 'scope']))) fail('COGNITIVE_FOCUS_INVALID');
|
|
223
|
+
if (!exactKeys(item, new Set(['domain', 'key', 'value', 'confidence', 'epistemicState', 'scope']))) fail('COGNITIVE_FOCUS_INVALID');
|
|
220
224
|
const domain = String(item.domain ?? '');
|
|
221
225
|
const key = cleanLabel(item.key, 128);
|
|
222
226
|
const value = cleanLabel(item.value, 512);
|
|
223
227
|
const confidence = Number(item.confidence);
|
|
228
|
+
const epistemicState = item.epistemicState === undefined
|
|
229
|
+
? 'legacy_unknown' : String(item.epistemicState);
|
|
224
230
|
const scope = cleanLabel(item.scope, 128);
|
|
225
231
|
if (!FOCUS_DOMAINS.has(domain) || !key || AUTHORITY_KEY_RE.test(key) || !value
|
|
226
232
|
|| !Number.isFinite(confidence) || confidence < 0.5 || confidence > 1
|
|
233
|
+
|| !FOCUS_EPISTEMIC_STATES.has(epistemicState)
|
|
227
234
|
|| !scope || scope === 'runtime') fail('COGNITIVE_FOCUS_INVALID');
|
|
228
|
-
return { domain, key, value, confidence, scope };
|
|
235
|
+
return { domain, key, value, confidence, epistemic_state: epistemicState, scope };
|
|
229
236
|
});
|
|
230
237
|
return commitDurableStage(`focus-${input.snapshotId}`, observations);
|
|
231
238
|
}
|
|
@@ -269,6 +276,7 @@ function createCognitiveTurnLifecycle({ home, tenantId, agentId, runtimeId, now
|
|
|
269
276
|
key,
|
|
270
277
|
value,
|
|
271
278
|
confidence: 1,
|
|
279
|
+
epistemic_state: 'verified',
|
|
272
280
|
scope,
|
|
273
281
|
...(correction ? { supersedes: targetObservationId } : { withdraws: targetObservationId }),
|
|
274
282
|
};
|
|
@@ -4,6 +4,9 @@ const crypto = require('node:crypto');
|
|
|
4
4
|
|
|
5
5
|
const SAFE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
6
6
|
const STATUSES = new Set(['active', 'paused', 'blocked']);
|
|
7
|
+
const EPISTEMIC_STATES = new Set([
|
|
8
|
+
'verified', 'credible_unverified', 'hypothesis', 'uncertain_memory', 'stale', 'unknown', 'legacy_unknown',
|
|
9
|
+
]);
|
|
7
10
|
const NEXT_TRIGGER = new Map([
|
|
8
11
|
['active', 'Continue the active goal from its last verified state.'],
|
|
9
12
|
['paused', 'Wait until the goal is explicitly resumed.'],
|
|
@@ -36,8 +39,11 @@ function buildCognitiveWorkFocus(goal) {
|
|
|
36
39
|
const lastVerified = bounded(checkpoint?.lastVerified);
|
|
37
40
|
const nextAction = bounded(checkpoint?.nextAction);
|
|
38
41
|
const checkpointEvidence = bounded(checkpoint?.expectedEvidence);
|
|
42
|
+
const checkpointEpistemicState = bounded(checkpoint?.epistemicState, 32);
|
|
39
43
|
const hasCheckpoint = checkpoint !== null && checkpointPhase && lastVerified
|
|
40
44
|
&& nextAction && checkpointEvidence;
|
|
45
|
+
const epistemicState = hasCheckpoint && EPISTEMIC_STATES.has(checkpointEpistemicState)
|
|
46
|
+
? checkpointEpistemicState : hasCheckpoint ? 'legacy_unknown' : 'verified';
|
|
41
47
|
const digest = crypto.createHash('sha256')
|
|
42
48
|
.update([
|
|
43
49
|
goalId, objective, completionCriterion, status, String(turnsUsed),
|
|
@@ -45,6 +51,7 @@ function buildCognitiveWorkFocus(goal) {
|
|
|
45
51
|
hasCheckpoint ? lastVerified : '',
|
|
46
52
|
hasCheckpoint ? nextAction : '',
|
|
47
53
|
hasCheckpoint ? checkpointEvidence : '',
|
|
54
|
+
epistemicState,
|
|
48
55
|
].join('\0'))
|
|
49
56
|
.digest('hex').slice(0, 40);
|
|
50
57
|
const keyRoot = `goal:${goalId}`;
|
|
@@ -52,21 +59,21 @@ function buildCognitiveWorkFocus(goal) {
|
|
|
52
59
|
snapshotId: `goalfocus-${digest}`,
|
|
53
60
|
focusScope,
|
|
54
61
|
observations: [
|
|
55
|
-
{ domain: 'goal', key: `${keyRoot}:objective`, value: objective, confidence: 1, scope: focusScope },
|
|
62
|
+
{ domain: 'goal', key: `${keyRoot}:objective`, value: objective, confidence: 1, epistemicState, scope: focusScope },
|
|
56
63
|
{
|
|
57
64
|
domain: 'open_thread', key: `${keyRoot}:status`,
|
|
58
65
|
value: hasCheckpoint ? `Goal is ${status}. Phase ${checkpointPhase}. Last verified: ${lastVerified}` : `Goal is ${status}.`,
|
|
59
|
-
confidence: 1, scope: focusScope,
|
|
66
|
+
confidence: 1, epistemicState, scope: focusScope,
|
|
60
67
|
},
|
|
61
68
|
{
|
|
62
69
|
domain: 'next_trigger', key: `${keyRoot}:next`,
|
|
63
70
|
value: status === 'active' && hasCheckpoint ? nextAction : NEXT_TRIGGER.get(status),
|
|
64
|
-
confidence: 1, scope: focusScope,
|
|
71
|
+
confidence: 1, epistemicState, scope: focusScope,
|
|
65
72
|
},
|
|
66
73
|
{
|
|
67
74
|
domain: 'expected_evidence', key: `${keyRoot}:evidence`,
|
|
68
75
|
value: status === 'active' && hasCheckpoint ? checkpointEvidence : completionCriterion,
|
|
69
|
-
confidence: 1, scope: focusScope,
|
|
76
|
+
confidence: 1, epistemicState, scope: focusScope,
|
|
70
77
|
},
|
|
71
78
|
],
|
|
72
79
|
};
|
package/bin/launcher-runtime.js
CHANGED
|
@@ -30,6 +30,9 @@ const { startMnemoConnectHeartbeat } = require('./mnemo-connect-heartbeat.cjs');
|
|
|
30
30
|
const { acquireSharedRuntimeLease, tryAcquireUpdateLease } = require('./update-lease');
|
|
31
31
|
const { compareSemver, runExplicitUpdate, runUpdateNotice } = require('./update-notice');
|
|
32
32
|
const {
|
|
33
|
+
RUNNING_UPDATE_HANDOFF_ACK_MESSAGE,
|
|
34
|
+
RUNNING_UPDATE_HANDOFF_EXIT_CODE,
|
|
35
|
+
RUNNING_UPDATE_HANDOFF_MESSAGE,
|
|
33
36
|
RUNNING_UPDATE_MODE_MESSAGE,
|
|
34
37
|
RUNNING_UPDATE_PREPARED_MESSAGE,
|
|
35
38
|
RUNTIME_EXIT_INTENT_MESSAGE,
|
|
@@ -40,7 +43,9 @@ const {
|
|
|
40
43
|
recordRunningUpdateEvent,
|
|
41
44
|
readActiveRuntime,
|
|
42
45
|
readPendingRuntime,
|
|
46
|
+
restoreActiveRuntime,
|
|
43
47
|
clearPendingRuntime,
|
|
48
|
+
handoffArgsForMode,
|
|
44
49
|
stageRuntime,
|
|
45
50
|
} = require('./running-update.cjs');
|
|
46
51
|
const {
|
|
@@ -326,8 +331,9 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
|
|
|
326
331
|
const packageRoot = path.resolve(options.packageRoot || PKG);
|
|
327
332
|
let preparedTarget;
|
|
328
333
|
let updateStarted = false;
|
|
329
|
-
let runtimeReady =
|
|
330
|
-
let activeSession;
|
|
334
|
+
let runtimeReady = options.initialRuntimeReady === true;
|
|
335
|
+
let activeSession = options.initialActiveSession;
|
|
336
|
+
let acceptedHandoff;
|
|
331
337
|
let runtimeExitIntent = false;
|
|
332
338
|
let supervisionCompleted = false;
|
|
333
339
|
let runningUpdatePollTimer;
|
|
@@ -467,6 +473,35 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
|
|
|
467
473
|
if (runtimeReady && !updateStarted) startPreparation(child);
|
|
468
474
|
} else if (runtimeReady) scheduleNextPreparation(child);
|
|
469
475
|
}
|
|
476
|
+
if (message?.type === RUNNING_UPDATE_HANDOFF_MESSAGE) {
|
|
477
|
+
refreshRunningUpdateMode();
|
|
478
|
+
const requestedCwd = resolveHandoffCwd(message.cwd, '');
|
|
479
|
+
const requestMatches = preparedTarget !== undefined
|
|
480
|
+
&& automaticMode()
|
|
481
|
+
&& validSessionMessage(message)
|
|
482
|
+
&& activeSession !== undefined
|
|
483
|
+
&& message.version === preparedTarget.version
|
|
484
|
+
&& message.mode === runningUpdateMode
|
|
485
|
+
&& message.sessionId === activeSession.sessionId
|
|
486
|
+
&& requestedCwd === activeSession.cwd;
|
|
487
|
+
if (!requestMatches) return;
|
|
488
|
+
acceptedHandoff = Object.freeze({
|
|
489
|
+
cwd: requestedCwd,
|
|
490
|
+
mode: runningUpdateMode,
|
|
491
|
+
sessionId: message.sessionId,
|
|
492
|
+
target: preparedTarget,
|
|
493
|
+
});
|
|
494
|
+
if (child?.connected === true) {
|
|
495
|
+
try {
|
|
496
|
+
child.send({
|
|
497
|
+
type: RUNNING_UPDATE_HANDOFF_ACK_MESSAGE,
|
|
498
|
+
version: preparedTarget.version,
|
|
499
|
+
mode: runningUpdateMode,
|
|
500
|
+
sessionId: message.sessionId,
|
|
501
|
+
});
|
|
502
|
+
} catch {}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
470
505
|
};
|
|
471
506
|
const spawnCore = options.spawnProtectedCore || spawnProtectedCore;
|
|
472
507
|
const core = options.existingCore || spawnCore(args, env, cwd, {
|
|
@@ -508,6 +543,82 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
|
|
|
508
543
|
supervisionCompleted = true;
|
|
509
544
|
clearRunningUpdatePoll();
|
|
510
545
|
if (existingMessageHandler) core.child.off('message', existingMessageHandler);
|
|
546
|
+
if (result.code === RUNNING_UPDATE_HANDOFF_EXIT_CODE && acceptedHandoff !== undefined) {
|
|
547
|
+
const sharedHome = env.BLUN_SHARED_HOME;
|
|
548
|
+
const previousActiveRuntime = (options.readActiveRuntime || readActiveRuntime)(sharedHome);
|
|
549
|
+
const previousVersion = readPackageVersionAt(packageRoot);
|
|
550
|
+
const handoffArgs = handoffArgsForMode(args, acceptedHandoff.mode, acceptedHandoff.sessionId);
|
|
551
|
+
let targetSession;
|
|
552
|
+
const targetCore = spawnCore(handoffArgs, env, acceptedHandoff.cwd, {
|
|
553
|
+
packageRoot: acceptedHandoff.target.packageRoot,
|
|
554
|
+
onMessage(message) {
|
|
555
|
+
if (message?.type === RUNTIME_READY_MESSAGE && validSessionMessage(message)) {
|
|
556
|
+
targetSession = Object.freeze({
|
|
557
|
+
cwd: resolveHandoffCwd(message.cwd, acceptedHandoff.cwd),
|
|
558
|
+
sessionId: message.sessionId,
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
});
|
|
563
|
+
const targetLoaded = await targetCore.loaded;
|
|
564
|
+
const targetReady = targetLoaded
|
|
565
|
+
&& await (options.waitForRuntimeReady || waitForRuntimeReady)(targetCore, options.readyTimeoutMs);
|
|
566
|
+
if (targetReady) {
|
|
567
|
+
await (options.activateRuntime || activateRuntime)(sharedHome, acceptedHandoff.target);
|
|
568
|
+
(options.clearPendingRuntime || clearPendingRuntime)(sharedHome, acceptedHandoff.target);
|
|
569
|
+
(options.recordRunningUpdateEvent || recordRunningUpdateEvent)(sharedHome, {
|
|
570
|
+
event: 'activated-live-handoff',
|
|
571
|
+
fromVersion: previousVersion,
|
|
572
|
+
toVersion: acceptedHandoff.target.version,
|
|
573
|
+
mode: acceptedHandoff.mode,
|
|
574
|
+
sessionId: acceptedHandoff.sessionId,
|
|
575
|
+
}, { now: options.nowImpl });
|
|
576
|
+
return superviseProtectedCore(handoffArgs, env, acceptedHandoff.cwd, async () => {}, {
|
|
577
|
+
...options,
|
|
578
|
+
existingCore: targetCore,
|
|
579
|
+
initialActiveSession: targetSession,
|
|
580
|
+
initialRuntimeReady: true,
|
|
581
|
+
packageRoot: acceptedHandoff.target.packageRoot,
|
|
582
|
+
startupPendingRuntime: undefined,
|
|
583
|
+
staleActiveRuntime: undefined,
|
|
584
|
+
recoveryRuntime: {
|
|
585
|
+
activeRuntime: previousActiveRuntime,
|
|
586
|
+
activatedAt: (options.nowImpl || Date.now)(),
|
|
587
|
+
packageRoot,
|
|
588
|
+
version: previousVersion,
|
|
589
|
+
},
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
try {
|
|
593
|
+
targetCore.child.kill();
|
|
594
|
+
} catch {}
|
|
595
|
+
await (options.restoreActiveRuntime || restoreActiveRuntime)(sharedHome, previousActiveRuntime);
|
|
596
|
+
(options.clearPendingRuntime || clearPendingRuntime)(sharedHome, acceptedHandoff.target);
|
|
597
|
+
(options.recordRunningUpdateEvent || recordRunningUpdateEvent)(sharedHome, {
|
|
598
|
+
event: 'live-handoff-rolled-back',
|
|
599
|
+
failedVersion: acceptedHandoff.target.version,
|
|
600
|
+
recoveryVersion: previousVersion,
|
|
601
|
+
}, { now: options.nowImpl });
|
|
602
|
+
const fallback = spawnCore(handoffArgs, env, acceptedHandoff.cwd, { packageRoot });
|
|
603
|
+
const fallbackLoaded = await fallback.loaded;
|
|
604
|
+
const fallbackReady = fallbackLoaded
|
|
605
|
+
&& await (options.waitForRuntimeReady || waitForRuntimeReady)(fallback, options.readyTimeoutMs);
|
|
606
|
+
if (fallbackReady) {
|
|
607
|
+
return superviseProtectedCore(handoffArgs, env, acceptedHandoff.cwd, async () => {}, {
|
|
608
|
+
...options,
|
|
609
|
+
existingCore: fallback,
|
|
610
|
+
initialActiveSession: activeSession,
|
|
611
|
+
initialRuntimeReady: true,
|
|
612
|
+
packageRoot,
|
|
613
|
+
startupPendingRuntime: undefined,
|
|
614
|
+
staleActiveRuntime: undefined,
|
|
615
|
+
recoveryRuntime: undefined,
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
const fallbackResult = await fallback.completed;
|
|
619
|
+
if (fallbackResult.error) throw fallbackResult.error;
|
|
620
|
+
return exitCodeForChild(fallbackResult, fallbackLoaded);
|
|
621
|
+
}
|
|
511
622
|
const recovery = options.recoveryRuntime;
|
|
512
623
|
if (shouldRecoverActivatedRuntime(result, recovery, {
|
|
513
624
|
now: (options.nowImpl || Date.now)(),
|
|
@@ -130,6 +130,7 @@ function createPersonalityMemoryAdapter({ identityRoot } = {}) {
|
|
|
130
130
|
key: `relationship:${digest('actor', [value.actorId]).slice(0, 30)}:curiosity-presentation`,
|
|
131
131
|
value: value.topic,
|
|
132
132
|
confidence: 1,
|
|
133
|
+
epistemic_state: 'verified',
|
|
133
134
|
scope: relationshipScope(value.actorId),
|
|
134
135
|
}],
|
|
135
136
|
});
|
package/blun.mjs
CHANGED
|
@@ -245733,6 +245733,7 @@ var init_events$1 = __esmMin((() => {
|
|
|
245733
245733
|
revision: number$1().int().min(1),
|
|
245734
245734
|
phase: _enum(["orient", "plan", "act", "verify", "learn", "wait"]),
|
|
245735
245735
|
evidenceBasis: _enum(["runtime_tool", "user_statement", "external_report", "carried_forward", "legacy_unknown"]),
|
|
245736
|
+
epistemicState: _enum(["verified", "credible_unverified", "hypothesis", "uncertain_memory", "stale", "unknown", "legacy_unknown"]),
|
|
245736
245737
|
lastVerified: string(),
|
|
245737
245738
|
nextAction: string(),
|
|
245738
245739
|
expectedEvidence: string(),
|
|
@@ -261769,7 +261770,10 @@ var init_turn = __esmMin((() => {
|
|
|
261769
261770
|
if (active === null || active === "resuming" || !active.acceptingSteers || expectedTurnId !== void 0 && expectedTurnId !== this.currentId) return null;
|
|
261770
261771
|
if (this.telegramDeliveryLedger.isDuplicate(input, origin)) {
|
|
261771
261772
|
this.agent.telemetry.track("telegram_delivery_duplicate_dropped", { intake: "active_steer" });
|
|
261772
|
-
return
|
|
261773
|
+
return {
|
|
261774
|
+
turnId: this.currentId,
|
|
261775
|
+
duplicate: true
|
|
261776
|
+
};
|
|
261773
261777
|
}
|
|
261774
261778
|
this.telegramDeliveryLedger.remember(input, origin);
|
|
261775
261779
|
this.agent.records.logRecord({
|
|
@@ -261778,7 +261782,10 @@ var init_turn = __esmMin((() => {
|
|
|
261778
261782
|
origin
|
|
261779
261783
|
});
|
|
261780
261784
|
this.bufferSteer(input, origin, this.currentId);
|
|
261781
|
-
return
|
|
261785
|
+
return {
|
|
261786
|
+
turnId: this.currentId,
|
|
261787
|
+
duplicate: false
|
|
261788
|
+
};
|
|
261782
261789
|
}
|
|
261783
261790
|
retry(trigger) {
|
|
261784
261791
|
return this.prompt([], {
|
|
@@ -262700,7 +262707,7 @@ var init_outcome_prompts = __esmMin((() => {}));
|
|
|
262700
262707
|
//#region ../../packages/agent-core/src/tools/builtin/goal/update-goal.md?raw
|
|
262701
262708
|
var update_goal_default;
|
|
262702
262709
|
var init_update_goal$1 = __esmMin((() => {
|
|
262703
|
-
update_goal_default = "Update the current autonomous goal. Set `status` only for a lifecycle change. After a coherent work slice, save `actionCheckpoint` with a monotone revision, the last verified result, exact next action, expected evidence, and an explicit evidence basis. Use `runtime_tool` only when a successful tool in this turn measured the result; use `user_statement` for a direct user assertion, `external_report` for a report not independently measured here, and `carried_forward` only when the last verified text is unchanged. Start at revision 1 and increment the currently projected revision by exactly one; stale writers fail closed. This is durable progress state, not permission, and should change only when the facts change. A checkpoint-only call keeps the goal active.\n\n- `active` — resume a paused or blocked goal when the user explicitly asks you to work on that goal.\n- `complete` — the objective is fully satisfied, all files are written, all tests pass, and any stated validation has passed.\n- `blocked` — a genuine external condition or required user decision prevents progress.\n- `paused` — set the goal aside for now.\n\nDo not mark complete after a plan or partial result. If useful work remains, checkpoint it and continue. Do not ask for permission merely to execute an already authorized checkpoint; ask only at a real rights boundary or missing user decision.\n";
|
|
262710
|
+
update_goal_default = "Update the current autonomous goal. Set `status` only for a lifecycle change. After a coherent work slice, save `actionCheckpoint` with a monotone revision, the last verified result, exact next action, expected evidence, and an explicit evidence basis. Use `runtime_tool` only when a successful tool in this turn measured the result; use `user_statement` for a direct user assertion, `external_report` for a report not independently measured here, and `carried_forward` only when the last verified text is unchanged. Classify knowledge as `verified`, `credible_unverified`, `hypothesis`, `uncertain_memory`, `stale`, or `unknown`; never present a weaker state as verified, and preserve the state on carry-forward. Start at revision 1 and increment the currently projected revision by exactly one; stale writers fail closed. This is durable progress state, not permission, and should change only when the facts change. A checkpoint-only call keeps the goal active.\n\n- `active` — resume a paused or blocked goal when the user explicitly asks you to work on that goal.\n- `complete` — the objective is fully satisfied, all files are written, all tests pass, and any stated validation has passed.\n- `blocked` — a genuine external condition or required user decision prevents progress.\n- `paused` — set the goal aside for now.\n\nDo not mark complete after a plan or partial result. If useful work remains, checkpoint it and continue. Do not ask for permission merely to execute an already authorized checkpoint; ask only at a real rights boundary or missing user decision.\n";
|
|
262704
262711
|
}));
|
|
262705
262712
|
//#endregion
|
|
262706
262713
|
//#region ../../packages/agent-core/src/tools/builtin/goal/update-goal.ts
|
|
@@ -262715,6 +262722,7 @@ var init_update_goal = __esmMin((() => {
|
|
|
262715
262722
|
revision: number$1().int().min(1),
|
|
262716
262723
|
phase: _enum(["orient", "plan", "act", "verify", "learn", "wait"]),
|
|
262717
262724
|
evidenceBasis: _enum(["runtime_tool", "user_statement", "external_report", "carried_forward"]),
|
|
262725
|
+
epistemicState: _enum(["verified", "credible_unverified", "hypothesis", "uncertain_memory", "stale", "unknown"]),
|
|
262718
262726
|
lastVerified: string().min(1).max(512),
|
|
262719
262727
|
nextAction: string().min(1).max(512),
|
|
262720
262728
|
expectedEvidence: string().min(1).max(512)
|
|
@@ -265455,11 +265463,12 @@ var init_agent = __esmMin((() => {
|
|
|
265455
265463
|
steer: (payload) => {
|
|
265456
265464
|
this.telemetry.track("input_steer", { parts: payload.input.length });
|
|
265457
265465
|
if (payload.activeTurnOnly === true) {
|
|
265458
|
-
const
|
|
265466
|
+
const activeSteer = this.turn.steerActive(payload.input, payload.expectedTurnId);
|
|
265459
265467
|
return {
|
|
265460
|
-
accepted:
|
|
265461
|
-
buffered:
|
|
265462
|
-
|
|
265468
|
+
accepted: activeSteer !== null,
|
|
265469
|
+
buffered: activeSteer !== null && activeSteer.duplicate !== true,
|
|
265470
|
+
duplicate: activeSteer?.duplicate === true,
|
|
265471
|
+
turnId: activeSteer?.turnId ?? null
|
|
265463
265472
|
};
|
|
265464
265473
|
}
|
|
265465
265474
|
const launchedTurnId = this.turn.steer(payload.input);
|
|
@@ -516165,11 +516174,14 @@ function turnsToTrim(turns, maxTurns, hysteresis) {
|
|
|
516165
516174
|
//#region src/tui/blun-tui.ts
|
|
516166
516175
|
const {
|
|
516167
516176
|
AUTO_UPDATE_SETTLE_MS,
|
|
516177
|
+
RUNNING_UPDATE_HANDOFF_ACK_MESSAGE,
|
|
516168
516178
|
RUNNING_UPDATE_HANDOFF_EXIT_CODE,
|
|
516179
|
+
RUNNING_UPDATE_HANDOFF_MESSAGE,
|
|
516169
516180
|
RUNNING_UPDATE_MODE_MESSAGE,
|
|
516170
516181
|
RUNNING_UPDATE_PREPARED_MESSAGE,
|
|
516171
516182
|
RUNTIME_EXIT_INTENT_MESSAGE,
|
|
516172
516183
|
RUNTIME_READY_MESSAGE,
|
|
516184
|
+
isSafeRuntimeBoundary,
|
|
516173
516185
|
pruneRunningUpdateReleases
|
|
516174
516186
|
} = __require("./bin/running-update.cjs");
|
|
516175
516187
|
const {
|
|
@@ -516205,10 +516217,38 @@ function requestRunningUpdateAtSafeBoundary(tui) {
|
|
|
516205
516217
|
const version = tui.runningUpdatePreparedVersion;
|
|
516206
516218
|
const mode = tui.runningUpdatePreparedMode;
|
|
516207
516219
|
if (typeof version !== "string" || mode !== RUNNING_UPDATE_MODES.RESUME && mode !== RUNNING_UPDATE_MODES.NEW) return false;
|
|
516208
|
-
if (
|
|
516209
|
-
|
|
516210
|
-
|
|
516211
|
-
|
|
516220
|
+
if (!isSafeRuntimeBoundary({
|
|
516221
|
+
isShuttingDown: tui.isShuttingDown,
|
|
516222
|
+
streamingPhase: tui.state.appState.streamingPhase,
|
|
516223
|
+
isCompacting: tui.state.appState.isCompacting,
|
|
516224
|
+
queuedMessages: tui.state.queuedMessages.length,
|
|
516225
|
+
activeToolCalls: tui.streamingUI.hasActiveToolCalls() ? 1 : 0,
|
|
516226
|
+
shellCommands: tui.shellOutputStreams.size,
|
|
516227
|
+
queueCommandRunning: tui.queueCommandRunning
|
|
516228
|
+
})) {
|
|
516229
|
+
if (tui.runningUpdatePreparedNoticeVersion !== version) {
|
|
516230
|
+
tui.runningUpdatePreparedNoticeVersion = version;
|
|
516231
|
+
tui.showStatus(`Update ${version} ist sicher geladen und wird nach dem laufenden Auftrag in derselben Sitzung uebernommen.`, "success");
|
|
516232
|
+
}
|
|
516233
|
+
return false;
|
|
516234
|
+
}
|
|
516235
|
+
if (!process.connected || tui.runningUpdateHandoffRequestedVersion === version) return false;
|
|
516236
|
+
const sessionId = tui.getCurrentSessionId();
|
|
516237
|
+
if (typeof sessionId !== "string" || sessionId.length === 0) return false;
|
|
516238
|
+
tui.runningUpdateHandoffRequestedVersion = version;
|
|
516239
|
+
try {
|
|
516240
|
+
process.send({
|
|
516241
|
+
type: RUNNING_UPDATE_HANDOFF_MESSAGE,
|
|
516242
|
+
version,
|
|
516243
|
+
mode,
|
|
516244
|
+
sessionId,
|
|
516245
|
+
cwd: tui.state.appState.workDir
|
|
516246
|
+
});
|
|
516247
|
+
return true;
|
|
516248
|
+
} catch {
|
|
516249
|
+
tui.runningUpdateHandoffRequestedVersion = void 0;
|
|
516250
|
+
return false;
|
|
516251
|
+
}
|
|
516212
516252
|
}
|
|
516213
516253
|
function installRunningUpdateListener(tui) {
|
|
516214
516254
|
const handler = (message) => {
|
|
@@ -516217,6 +516257,7 @@ function installRunningUpdateListener(tui) {
|
|
|
516217
516257
|
tui.runningUpdatePreparedMode = message.mode;
|
|
516218
516258
|
requestRunningUpdateAtSafeBoundary(tui);
|
|
516219
516259
|
}
|
|
516260
|
+
if (message?.type === RUNNING_UPDATE_HANDOFF_ACK_MESSAGE && message.version === tui.runningUpdateHandoffRequestedVersion && message.sessionId === tui.getCurrentSessionId()) void tui.stop(RUNNING_UPDATE_HANDOFF_EXIT_CODE);
|
|
516220
516261
|
};
|
|
516221
516262
|
process.on("message", handler);
|
|
516222
516263
|
return () => process.off("message", handler);
|
|
@@ -517242,8 +517283,10 @@ var BlunTUI = class {
|
|
|
517242
517283
|
return this.restoreQueuedSteer(inFlight, error);
|
|
517243
517284
|
};
|
|
517244
517285
|
try {
|
|
517245
|
-
|
|
517286
|
+
const result = await this.harness.withInteractiveAgent(item.agentId ?? "main", () => session.steerActive(input, expectedTurnId === void 0 ? {} : { expectedTurnId }));
|
|
517287
|
+
if (!result.accepted) return this.recoverRejectedActiveSteer(inFlight);
|
|
517246
517288
|
inFlight.accepted = true;
|
|
517289
|
+
if (result.duplicate === true) return this.commitQueuedSteer(inFlight);
|
|
517247
517290
|
if (inFlight.turnEnded) return restoreHead();
|
|
517248
517291
|
this.commitQueuedSteerIfReady(inFlight);
|
|
517249
517292
|
} catch (error) {
|