@sema-agent/client-core 0.85.2 → 0.87.0
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/CHANGELOG.md +263 -0
- package/README.md +25 -16
- package/dist/adapt/arms.js +14 -1
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +3 -3
- package/dist/adapter/downstream/terminalToSdkResult.js +4 -1
- package/dist/adapter/runStream.js +75 -2
- package/dist/adapter/types.d.ts +3 -0
- package/dist/agentSession/backgroundView.js +7 -1
- package/dist/agentSession/contract.d.ts +1 -1
- package/dist/centerWiringCapability.d.ts +38 -0
- package/dist/centerWiringCapability.js +202 -0
- package/dist/decideFailureNote.js +3 -0
- package/dist/decideReceipt.d.ts +1 -1
- package/dist/decideReceipt.js +1 -1
- package/dist/detachWire.d.ts +6 -1
- package/dist/detachWire.js +22 -1
- package/dist/engineCapReader.d.ts +8 -0
- package/dist/engineCapReader.js +15 -0
- package/dist/engineErrorCodes.d.ts +3 -0
- package/dist/engineErrorCodes.js +8 -0
- package/dist/engineNoticeCodes.d.ts +62 -0
- package/dist/engineNoticeCodes.js +247 -29
- package/dist/executionLaneCapability.d.ts +6 -0
- package/dist/executionLaneCapability.js +55 -2
- package/dist/fleet/fleetProjection.js +6 -8
- package/dist/fleet/workflowSizeWarning.js +2 -5
- package/dist/gateOutcome.d.ts +13 -0
- package/dist/gateOutcome.js +48 -1
- package/dist/gateVocabulary.d.ts +6 -3
- package/dist/gateVocabulary.js +7 -15
- package/dist/generated/engineFactTables.d.ts +10 -0
- package/dist/generated/engineFactTables.js +113 -0
- package/dist/generated/engineNoticeTables.js +14 -0
- package/dist/hitl/crashConverged.d.ts +1 -0
- package/dist/hitl/crashConverged.js +17 -2
- package/dist/hitl/hitlBridge.d.ts +4 -0
- package/dist/hitl/hitlBridge.js +6 -0
- package/dist/hitl/parkResolver.js +17 -12
- package/dist/hitl/refusedToolNameProse.d.ts +4 -0
- package/dist/hitl/refusedToolNameProse.js +7 -0
- package/dist/hitl/sessionPolicyDeliverable.js +9 -5
- package/dist/hitl/sessionPolicyWire.d.ts +16 -0
- package/dist/hitl/sessionPolicyWire.js +49 -1
- package/dist/hitl/suspendedReopen.d.ts +7 -0
- package/dist/hitl/suspendedReopen.js +38 -7
- package/dist/hitl/toolApprovalWire.js +4 -5
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -1
- package/dist/inheritEnvWire.d.ts +22 -0
- package/dist/inheritEnvWire.js +84 -0
- package/dist/peerFrames.js +2 -10
- package/dist/printInitToolFace.d.ts +6 -0
- package/dist/printInitToolFace.js +115 -2
- package/dist/readCredentialRefusal.d.ts +2 -0
- package/dist/readCredentialRefusal.js +7 -0
- package/dist/request/taskRequest.d.ts +4 -5
- package/dist/request/taskRequest.js +33 -23
- package/dist/resumeRefusalCopy.d.ts +2 -7
- package/dist/resumeRefusalCopy.js +2 -24
- package/dist/rewindArchiveCapability.js +5 -0
- package/dist/runTerminal.js +2 -6
- package/dist/seam.d.ts +11 -1
- package/dist/seam.js +7 -0
- package/dist/sqlEngineCapability.js +15 -2
- package/dist/storePostureCapability.d.ts +25 -0
- package/dist/storePostureCapability.js +132 -0
- package/dist/toolHistoryMismatch.d.ts +63 -0
- package/dist/toolHistoryMismatch.js +425 -0
- package/dist/toolResult.js +2 -47
- package/dist/wireErrorTriage.d.ts +1 -0
- package/dist/wireErrorTriage.js +3 -0
- package/dist/wireFailureShape.d.ts +3 -0
- package/dist/wireFailureShape.js +44 -0
- package/dist/wireRefusalCopy.d.ts +39 -1
- package/dist/wireRefusalCopy.js +350 -2
- package/dist/workflowClient.d.ts +7 -2
- package/dist/workflowClient.js +15 -7
- package/docs/INTEGRATION-CLIENTS.md +942 -16
- package/package.json +2 -2
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
export const TOOL_HISTORY_MISMATCH_KINDS = Object.freeze([
|
|
2
|
+
'tool_use_without_result',
|
|
3
|
+
'orphan_tool_result',
|
|
4
|
+
'duplicate_tool_use_id',
|
|
5
|
+
]);
|
|
6
|
+
const ID_AFTER_COLON = /^:\s*([^\s,;]+)/;
|
|
7
|
+
export const TOOL_HISTORY_MISMATCH_ANCHORS = Object.freeze([
|
|
8
|
+
Object.freeze({
|
|
9
|
+
kind: 'tool_use_without_result',
|
|
10
|
+
template: /^`?tool_use`? ids were found without `?tool_result`? blocks immediately after\b/,
|
|
11
|
+
idAfter: ID_AFTER_COLON,
|
|
12
|
+
}),
|
|
13
|
+
Object.freeze({
|
|
14
|
+
kind: 'orphan_tool_result',
|
|
15
|
+
template: /^unexpected `?tool_use_id`? found in `?tool_result`?(?: blocks?)?(?=[\s:,.]|$)/,
|
|
16
|
+
idAfter: ID_AFTER_COLON,
|
|
17
|
+
}),
|
|
18
|
+
Object.freeze({
|
|
19
|
+
kind: 'duplicate_tool_use_id',
|
|
20
|
+
template: /^`?tool_use`? ids must be unique\b/,
|
|
21
|
+
idAfter: null,
|
|
22
|
+
}),
|
|
23
|
+
]);
|
|
24
|
+
const ENGINE_HTTP_400_LEAD = /^(?:\[invalid_request\]\s*)?[^\n:]{0,60}?\bHTTP 400:\s*/;
|
|
25
|
+
const MESSAGES_LOCATOR = /^messages(?:\.[A-Za-z0-9_]+)+\s*:\s*/;
|
|
26
|
+
const PROVIDER_REJECTED_REQUEST_CODE = 'invalid_request';
|
|
27
|
+
function idOfToken(after, idAfter, endIsBoundary) {
|
|
28
|
+
const hit = idAfter.exec(after);
|
|
29
|
+
if (hit === null || hit[1] === undefined)
|
|
30
|
+
return undefined;
|
|
31
|
+
if (hit[0].length >= after.length && !endIsBoundary)
|
|
32
|
+
return undefined;
|
|
33
|
+
const next = after[hit[0].length];
|
|
34
|
+
let id = hit[1];
|
|
35
|
+
if (next !== ',' && next !== ';') {
|
|
36
|
+
if (id.endsWith('.'))
|
|
37
|
+
id = id.slice(0, -1);
|
|
38
|
+
if (id.endsWith('.') || id.endsWith(':'))
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
return ROW_KEY_ID.test(id) ? id : undefined;
|
|
42
|
+
}
|
|
43
|
+
function matchAnchoredSentence(sentence, endIsBoundary) {
|
|
44
|
+
const rest = sentence.replace(MESSAGES_LOCATOR, '');
|
|
45
|
+
for (const anchor of TOOL_HISTORY_MISMATCH_ANCHORS) {
|
|
46
|
+
const hit = anchor.template.exec(rest);
|
|
47
|
+
if (hit === null)
|
|
48
|
+
continue;
|
|
49
|
+
if (anchor.idAfter === null)
|
|
50
|
+
return { kind: anchor.kind };
|
|
51
|
+
const id = idOfToken(rest.slice(hit[0].length), anchor.idAfter, endIsBoundary);
|
|
52
|
+
return id !== undefined ? { kind: anchor.kind, toolUseId: id } : { kind: anchor.kind };
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
function envelopeMessages(body) {
|
|
57
|
+
const out = [];
|
|
58
|
+
const n = body.length;
|
|
59
|
+
let i = 0;
|
|
60
|
+
const skipWs = () => {
|
|
61
|
+
while (i < n && (body[i] === ' ' || body[i] === '\t' || body[i] === '\n' || body[i] === '\r'))
|
|
62
|
+
i++;
|
|
63
|
+
};
|
|
64
|
+
const readString = () => {
|
|
65
|
+
i++;
|
|
66
|
+
let text = '';
|
|
67
|
+
while (i < n) {
|
|
68
|
+
const c = body[i];
|
|
69
|
+
if (c === '"') {
|
|
70
|
+
i++;
|
|
71
|
+
return { text, closed: true };
|
|
72
|
+
}
|
|
73
|
+
if (c === '\\') {
|
|
74
|
+
const e = body[i + 1];
|
|
75
|
+
if (e === undefined) {
|
|
76
|
+
i = n;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
if (e === 'u') {
|
|
80
|
+
const hex = body.slice(i + 2, i + 6);
|
|
81
|
+
if (!/^[0-9A-Fa-f]{4}$/.test(hex)) {
|
|
82
|
+
i = n;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
text += String.fromCharCode(parseInt(hex, 16));
|
|
86
|
+
i += 6;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
text += e === 'n' ? '\n' : e === 't' ? '\t' : e === 'r' ? '\r' : e === 'b' ? '\b' : e === 'f' ? '\f' : e;
|
|
90
|
+
i += 2;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
text += c;
|
|
94
|
+
i++;
|
|
95
|
+
}
|
|
96
|
+
return { text, closed: false };
|
|
97
|
+
};
|
|
98
|
+
skipWs();
|
|
99
|
+
if (body[i] !== '{')
|
|
100
|
+
return out;
|
|
101
|
+
const path = [];
|
|
102
|
+
const want = [];
|
|
103
|
+
const onEnvelopePath = () => (path.length === 1 && path[0] === 'message') || (path.length === 2 && path[0] === 'error' && path[1] === 'message');
|
|
104
|
+
i++;
|
|
105
|
+
path.push(undefined);
|
|
106
|
+
want.push('key');
|
|
107
|
+
while (i < n && path.length > 0 && out.length < 4) {
|
|
108
|
+
skipWs();
|
|
109
|
+
if (i >= n)
|
|
110
|
+
break;
|
|
111
|
+
const c = body[i];
|
|
112
|
+
const top = want.length - 1;
|
|
113
|
+
const state = want[top];
|
|
114
|
+
const inArray = path[top] === null;
|
|
115
|
+
if (state === 'key') {
|
|
116
|
+
if (c === '}') {
|
|
117
|
+
i++;
|
|
118
|
+
path.pop();
|
|
119
|
+
want.pop();
|
|
120
|
+
if (want.length > 0)
|
|
121
|
+
want[want.length - 1] = 'next';
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (c !== '"')
|
|
125
|
+
break;
|
|
126
|
+
const key = readString();
|
|
127
|
+
if (!key.closed)
|
|
128
|
+
break;
|
|
129
|
+
path[top] = key.text;
|
|
130
|
+
want[top] = 'colon';
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (state === 'colon') {
|
|
134
|
+
if (c !== ':')
|
|
135
|
+
break;
|
|
136
|
+
i++;
|
|
137
|
+
want[top] = 'value';
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (state === 'next') {
|
|
141
|
+
if (c === ',') {
|
|
142
|
+
i++;
|
|
143
|
+
want[top] = inArray ? 'value' : 'key';
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (c === (inArray ? ']' : '}')) {
|
|
147
|
+
i++;
|
|
148
|
+
path.pop();
|
|
149
|
+
want.pop();
|
|
150
|
+
if (want.length > 0)
|
|
151
|
+
want[want.length - 1] = 'next';
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
if (inArray && c === ']') {
|
|
157
|
+
i++;
|
|
158
|
+
path.pop();
|
|
159
|
+
want.pop();
|
|
160
|
+
if (want.length > 0)
|
|
161
|
+
want[want.length - 1] = 'next';
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (c === '"') {
|
|
165
|
+
const value = readString();
|
|
166
|
+
if (!path.includes(null) && onEnvelopePath())
|
|
167
|
+
out.push(value);
|
|
168
|
+
want[top] = 'next';
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (c === '{' || c === '[') {
|
|
172
|
+
i++;
|
|
173
|
+
want[top] = 'next';
|
|
174
|
+
path.push(c === '{' ? undefined : null);
|
|
175
|
+
want.push(c === '{' ? 'key' : 'value');
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
const lit = /^(?:true|false|null|-?[0-9][0-9.eE+-]*)/.exec(body.slice(i, i + 64));
|
|
179
|
+
if (lit === null)
|
|
180
|
+
break;
|
|
181
|
+
i += lit[0].length;
|
|
182
|
+
want[top] = 'next';
|
|
183
|
+
}
|
|
184
|
+
return out;
|
|
185
|
+
}
|
|
186
|
+
export function classifyToolHistoryMismatch(err) {
|
|
187
|
+
if (typeof err !== 'object' || err === null)
|
|
188
|
+
return null;
|
|
189
|
+
let code;
|
|
190
|
+
let status;
|
|
191
|
+
let rawMessage;
|
|
192
|
+
try {
|
|
193
|
+
code = err.code;
|
|
194
|
+
status = err.status;
|
|
195
|
+
rawMessage = err.message;
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
if (typeof rawMessage !== 'string' || rawMessage.length === 0)
|
|
201
|
+
return null;
|
|
202
|
+
if (typeof status === 'number' && status !== 400)
|
|
203
|
+
return null;
|
|
204
|
+
if (typeof code === 'string' && code.length > 0 && code !== PROVIDER_REJECTED_REQUEST_CODE)
|
|
205
|
+
return null;
|
|
206
|
+
let detail = rawMessage.trimStart();
|
|
207
|
+
const lead = ENGINE_HTTP_400_LEAD.exec(detail);
|
|
208
|
+
if (lead !== null)
|
|
209
|
+
detail = detail.slice(lead[0].length);
|
|
210
|
+
else if (status !== 400)
|
|
211
|
+
return null;
|
|
212
|
+
const body = detail.replace(/^400\s+/, '');
|
|
213
|
+
const direct = matchAnchoredSentence(body, false);
|
|
214
|
+
if (direct !== null)
|
|
215
|
+
return direct;
|
|
216
|
+
for (const value of envelopeMessages(body)) {
|
|
217
|
+
const hit = matchAnchoredSentence(value.text, value.closed);
|
|
218
|
+
if (hit !== null)
|
|
219
|
+
return hit;
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
export const TOOL_HISTORY_REWIND_SENTENCE = 'Run /rewind to recover the conversation.';
|
|
224
|
+
export function toolHistoryRepeatSentence(n) {
|
|
225
|
+
return `The same error has now happened ${n} times in a row; /rewind is the only way to recover this conversation.`;
|
|
226
|
+
}
|
|
227
|
+
let conversationRewindJudge;
|
|
228
|
+
export function _wireConversationRewindJudge(judge) {
|
|
229
|
+
conversationRewindJudge = judge;
|
|
230
|
+
}
|
|
231
|
+
export function toolHistoryRewindOffered(declared) {
|
|
232
|
+
const decl = declared;
|
|
233
|
+
if (decl === true)
|
|
234
|
+
return true;
|
|
235
|
+
if (typeof decl !== 'object' || decl === null)
|
|
236
|
+
return false;
|
|
237
|
+
try {
|
|
238
|
+
if (Array.isArray(decl))
|
|
239
|
+
return false;
|
|
240
|
+
const base = decl.engineBaseUrl;
|
|
241
|
+
const judge = conversationRewindJudge;
|
|
242
|
+
if (typeof base !== 'string' || base.length === 0 || judge === undefined)
|
|
243
|
+
return true;
|
|
244
|
+
return judge(base) !== 'unavailable';
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const isKind = (v) => typeof v === 'string' && TOOL_HISTORY_MISMATCH_KINDS.includes(v);
|
|
251
|
+
const ROW_KEY_ID = /^[A-Za-z0-9_.:-]{1,128}$/;
|
|
252
|
+
export function toolHistoryMismatchRowKey(m, consecutive) {
|
|
253
|
+
return {
|
|
254
|
+
kind: m.kind,
|
|
255
|
+
...(m.toolUseId !== undefined ? { toolUseId: m.toolUseId } : {}),
|
|
256
|
+
...(consecutive !== undefined && consecutive >= 2 ? { consecutive } : {}),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
export function readToolHistoryMismatchKey(v) {
|
|
260
|
+
if (typeof v !== 'object' || v === null || Array.isArray(v))
|
|
261
|
+
return undefined;
|
|
262
|
+
try {
|
|
263
|
+
const got = v;
|
|
264
|
+
const kind = got.kind;
|
|
265
|
+
if (!isKind(kind))
|
|
266
|
+
return undefined;
|
|
267
|
+
const id = got.toolUseId;
|
|
268
|
+
const n = got.consecutive;
|
|
269
|
+
return {
|
|
270
|
+
kind,
|
|
271
|
+
...(typeof id === 'string' && ROW_KEY_ID.test(id) ? { toolUseId: id } : {}),
|
|
272
|
+
...(typeof n === 'number' && Number.isSafeInteger(n) && n >= 2 ? { consecutive: n } : {}),
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
return undefined;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
export const TOOL_HISTORY_LEDGER_CAP = 64;
|
|
280
|
+
const PRIOR_RUN_IDS_CAP = 16;
|
|
281
|
+
const ECHOED_SESSION_IDS_CAP = TOOL_HISTORY_LEDGER_CAP * 4;
|
|
282
|
+
const toolHistoryLedger = new Map();
|
|
283
|
+
let toolHistoryGenerationSeq = 0;
|
|
284
|
+
const echoedSessionIds = new Set();
|
|
285
|
+
let unattributedTerminalSeq = 0;
|
|
286
|
+
function rememberEchoedSession(sessionId) {
|
|
287
|
+
echoedSessionIds.delete(sessionId);
|
|
288
|
+
echoedSessionIds.add(sessionId);
|
|
289
|
+
while (echoedSessionIds.size > ECHOED_SESSION_IDS_CAP) {
|
|
290
|
+
const oldest = echoedSessionIds.values().next();
|
|
291
|
+
if (oldest.done === true)
|
|
292
|
+
break;
|
|
293
|
+
echoedSessionIds.delete(oldest.value);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
export function openToolHistoryGeneration() {
|
|
297
|
+
toolHistoryGenerationSeq += 1;
|
|
298
|
+
return toolHistoryGenerationSeq;
|
|
299
|
+
}
|
|
300
|
+
const fingerprintOf = (m) => `${m.kind}\u0000${m.toolUseId ?? ''}`;
|
|
301
|
+
export function noteToolHistoryTerminal(note) {
|
|
302
|
+
const { sessionId, generation, runId, replay, mismatch } = note;
|
|
303
|
+
if (typeof sessionId !== 'string' || sessionId.length === 0) {
|
|
304
|
+
unattributedTerminalSeq += 1;
|
|
305
|
+
return undefined;
|
|
306
|
+
}
|
|
307
|
+
if (note.sessionEchoed === true)
|
|
308
|
+
rememberEchoedSession(sessionId);
|
|
309
|
+
else if (!echoedSessionIds.has(sessionId))
|
|
310
|
+
unattributedTerminalSeq += 1;
|
|
311
|
+
const row = toolHistoryLedger.get(sessionId);
|
|
312
|
+
const fingerprint = mismatch === null ? null : fingerprintOf(mismatch);
|
|
313
|
+
const run = !replay && typeof runId === 'string' && runId.length > 0 ? runId : undefined;
|
|
314
|
+
if (row !== undefined && generation < row.writtenGeneration) {
|
|
315
|
+
if (row.fingerprint !== fingerprint) {
|
|
316
|
+
touchLedgerRow(sessionId, {
|
|
317
|
+
fingerprint,
|
|
318
|
+
segmentRunIds: new Set(),
|
|
319
|
+
writtenGeneration: row.writtenGeneration,
|
|
320
|
+
unattributedMark: unattributedTerminalSeq,
|
|
321
|
+
lastRunId: undefined,
|
|
322
|
+
recentRunIds: run !== undefined ? [...row.recentRunIds, run].slice(-PRIOR_RUN_IDS_CAP) : row.recentRunIds,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
return undefined;
|
|
326
|
+
}
|
|
327
|
+
if (row !== undefined)
|
|
328
|
+
row.writtenGeneration = generation;
|
|
329
|
+
const interrupted = row !== undefined && row.unattributedMark < unattributedTerminalSeq;
|
|
330
|
+
if (run !== undefined && row !== undefined && (row.segmentRunIds.has(run) || row.recentRunIds.includes(run))) {
|
|
331
|
+
return !interrupted && row.lastRunId === run && fingerprint !== null && row.fingerprint === fingerprint ? row.segmentRunIds.size : undefined;
|
|
332
|
+
}
|
|
333
|
+
if (row !== undefined && row.fingerprint === fingerprint && !(interrupted && fingerprint !== null && run !== undefined)) {
|
|
334
|
+
if (run === undefined)
|
|
335
|
+
return undefined;
|
|
336
|
+
if (fingerprint !== null)
|
|
337
|
+
row.segmentRunIds.add(run);
|
|
338
|
+
row.lastRunId = run;
|
|
339
|
+
row.recentRunIds = [...row.recentRunIds, run].slice(-PRIOR_RUN_IDS_CAP);
|
|
340
|
+
touchLedgerRow(sessionId, row);
|
|
341
|
+
return fingerprint === null ? undefined : row.segmentRunIds.size;
|
|
342
|
+
}
|
|
343
|
+
touchLedgerRow(sessionId, {
|
|
344
|
+
fingerprint,
|
|
345
|
+
segmentRunIds: fingerprint !== null && run !== undefined ? new Set([run]) : new Set(),
|
|
346
|
+
writtenGeneration: generation,
|
|
347
|
+
unattributedMark: unattributedTerminalSeq,
|
|
348
|
+
lastRunId: run,
|
|
349
|
+
recentRunIds: run !== undefined ? [...(row?.recentRunIds ?? []), run].slice(-PRIOR_RUN_IDS_CAP) : [...(row?.recentRunIds ?? [])],
|
|
350
|
+
});
|
|
351
|
+
return fingerprint !== null && run !== undefined ? 1 : undefined;
|
|
352
|
+
}
|
|
353
|
+
function touchLedgerRow(sessionId, row) {
|
|
354
|
+
toolHistoryLedger.delete(sessionId);
|
|
355
|
+
toolHistoryLedger.set(sessionId, row);
|
|
356
|
+
while (toolHistoryLedger.size > TOOL_HISTORY_LEDGER_CAP) {
|
|
357
|
+
const oldest = toolHistoryLedger.keys().next();
|
|
358
|
+
if (oldest.done === true)
|
|
359
|
+
break;
|
|
360
|
+
toolHistoryLedger.delete(oldest.value);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
export function _resetToolHistoryLedgerForTest() {
|
|
364
|
+
toolHistoryLedger.clear();
|
|
365
|
+
echoedSessionIds.clear();
|
|
366
|
+
}
|
|
367
|
+
export const TOOL_HISTORY_UNDECIDABLE_REASONS = Object.freeze([
|
|
368
|
+
'no-mismatch',
|
|
369
|
+
'no-tool-use-id',
|
|
370
|
+
'id-not-found',
|
|
371
|
+
'prompt-not-found',
|
|
372
|
+
'prompt-without-handle',
|
|
373
|
+
'unreadable-rows',
|
|
374
|
+
]);
|
|
375
|
+
const listHas = (list, id) => Array.isArray(list) && list.includes(id);
|
|
376
|
+
export function resolveToolHistoryRewindTarget(rows, mismatch) {
|
|
377
|
+
let kind;
|
|
378
|
+
try {
|
|
379
|
+
if (typeof mismatch !== 'object' || mismatch === null)
|
|
380
|
+
return { undecidable: 'no-mismatch' };
|
|
381
|
+
kind = mismatch.kind;
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
return { undecidable: 'no-mismatch' };
|
|
385
|
+
}
|
|
386
|
+
if (!isKind(kind))
|
|
387
|
+
return { undecidable: 'no-mismatch' };
|
|
388
|
+
let id;
|
|
389
|
+
try {
|
|
390
|
+
id = mismatch.toolUseId;
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
return { undecidable: 'no-mismatch' };
|
|
394
|
+
}
|
|
395
|
+
if (typeof id !== 'string' || id.length === 0)
|
|
396
|
+
return { undecidable: 'no-tool-use-id' };
|
|
397
|
+
try {
|
|
398
|
+
if (!Array.isArray(rows))
|
|
399
|
+
return { undecidable: 'unreadable-rows' };
|
|
400
|
+
let hit = -1;
|
|
401
|
+
for (let i = 0; i < rows.length; i++) {
|
|
402
|
+
const r = rows[i];
|
|
403
|
+
if (typeof r !== 'object' || r === null || r.local === true)
|
|
404
|
+
continue;
|
|
405
|
+
if (listHas(r.toolUseIds, id) || listHas(r.toolResultIds, id)) {
|
|
406
|
+
hit = i;
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (hit < 0)
|
|
411
|
+
return { undecidable: 'id-not-found' };
|
|
412
|
+
for (let j = hit; j >= 0; j--) {
|
|
413
|
+
const r = rows[j];
|
|
414
|
+
if (typeof r !== 'object' || r === null || r.local === true || r.prompt !== true)
|
|
415
|
+
continue;
|
|
416
|
+
if (r.sessionRoot === true)
|
|
417
|
+
return { rootReopen: true };
|
|
418
|
+
return typeof r.engineHandle === 'string' && r.engineHandle.length > 0 ? { target: r } : { undecidable: 'prompt-without-handle' };
|
|
419
|
+
}
|
|
420
|
+
return { undecidable: 'prompt-not-found' };
|
|
421
|
+
}
|
|
422
|
+
catch {
|
|
423
|
+
return { undecidable: 'unreadable-rows' };
|
|
424
|
+
}
|
|
425
|
+
}
|
package/dist/toolResult.js
CHANGED
|
@@ -3,53 +3,8 @@ import { markEngineWorkflowNotified, registerOutstandingBgTask, registerOutstand
|
|
|
3
3
|
import { parseWorkflowPollEnvelope, projectWorkflowTaskOutput } from './workflow.js';
|
|
4
4
|
import { asModelFallbackReason } from './engineErrorCodes.js';
|
|
5
5
|
import { frozenSet } from './frozenSet.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
'create',
|
|
9
|
-
'update',
|
|
10
|
-
'bash',
|
|
11
|
-
'notebook-edit',
|
|
12
|
-
'notebook',
|
|
13
|
-
'text',
|
|
14
|
-
'grep',
|
|
15
|
-
'glob',
|
|
16
|
-
'mcp',
|
|
17
|
-
'agent',
|
|
18
|
-
'task',
|
|
19
|
-
'task-list',
|
|
20
|
-
'task-output',
|
|
21
|
-
'workflow-run',
|
|
22
|
-
'web-fetch',
|
|
23
|
-
'web-search',
|
|
24
|
-
'todo',
|
|
25
|
-
'cron-create',
|
|
26
|
-
'cron-delete',
|
|
27
|
-
'cron-list',
|
|
28
|
-
'image',
|
|
29
|
-
'task-stop',
|
|
30
|
-
'tool-search',
|
|
31
|
-
'repo-map',
|
|
32
|
-
'fork',
|
|
33
|
-
'enter-plan-mode',
|
|
34
|
-
'exit-plan-mode',
|
|
35
|
-
'file_unchanged',
|
|
36
|
-
'worktree',
|
|
37
|
-
'monitor-start',
|
|
38
|
-
'path_not_in_root',
|
|
39
|
-
'readonly_out_of_root',
|
|
40
|
-
'report-findings',
|
|
41
|
-
'schedule-wakeup',
|
|
42
|
-
'send-message',
|
|
43
|
-
'agent-transcript',
|
|
44
|
-
'a2a',
|
|
45
|
-
'document',
|
|
46
|
-
'ask-question',
|
|
47
|
-
'bash_invalid_timeout',
|
|
48
|
-
'read_path_denied',
|
|
49
|
-
'list-agents',
|
|
50
|
-
'artifact',
|
|
51
|
-
'read-inbox',
|
|
52
|
-
]);
|
|
6
|
+
import { CORE_ENGINE_CARD_TYPES } from './generated/engineFactTables.js';
|
|
7
|
+
export const STRUCTURED_DETAIL_TYPES = frozenSet(CORE_ENGINE_CARD_TYPES);
|
|
53
8
|
export function structuredDetailType(structured) {
|
|
54
9
|
if (typeof structured !== 'object' || structured === null)
|
|
55
10
|
return undefined;
|
package/dist/wireErrorTriage.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readErrorNumber, readErrorString, readErrorStringList } from './wireFailureShape.js';
|
|
2
2
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
3
|
+
import { fleetLeaseUnavailableFromError } from './wireRefusalCopy.js';
|
|
3
4
|
import { DRAINING_ERROR_CODE, isCorruptSessionCode, RESUME_AT_ERROR_CODE_PREFIX, RESUME_POLICY_FOLD_CODE, RESUME_RETRY_LATER_CODES, RESUME_USAGE_WINDOW_EXHAUSTED, SCENARIO_NOT_ALLOWED_ERROR_CODE, } from './engineErrorCodes.js';
|
|
4
5
|
export const WIRE_NETWORK_ERROR_PATTERN = /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|EHOSTUNREACH|ENETUNREACH|EPIPE|socket hang up|UND_ERR|terminated|other side closed/i;
|
|
5
6
|
function wireErrorDetail(err) {
|
|
@@ -16,6 +17,7 @@ export function classifyTurnWireError(err) {
|
|
|
16
17
|
const message = typeof e.message === 'string' && e.message.length > 0 ? e.message : String(err);
|
|
17
18
|
const storedRowWhere = corruptStoredRowWhere(err);
|
|
18
19
|
const sessionUnreadable = isCorruptSessionCode(effectiveWireErrorCode(err));
|
|
20
|
+
const leaseUnavailable = fleetLeaseUnavailableFromError(err) !== null;
|
|
19
21
|
return {
|
|
20
22
|
kind: 'http',
|
|
21
23
|
status: e.status,
|
|
@@ -23,6 +25,7 @@ export function classifyTurnWireError(err) {
|
|
|
23
25
|
message,
|
|
24
26
|
...(storedRowWhere !== undefined ? { storedRowWhere } : {}),
|
|
25
27
|
...(sessionUnreadable ? { sessionUnreadable: true } : {}),
|
|
28
|
+
...(leaseUnavailable ? { leaseUnavailable: true } : {}),
|
|
26
29
|
};
|
|
27
30
|
}
|
|
28
31
|
const errName = typeof err === 'object' && err !== null && typeof err.name === 'string'
|
|
@@ -3,10 +3,13 @@ interface WireFailureShape {
|
|
|
3
3
|
errorCode?: string;
|
|
4
4
|
retryAfterSec?: number;
|
|
5
5
|
committed?: 'no' | 'unknown' | 'unreadable';
|
|
6
|
+
bodyField?: string;
|
|
7
|
+
bodyName?: string;
|
|
6
8
|
message: string;
|
|
7
9
|
}
|
|
8
10
|
export declare function readErrorNumber(o: object, key: string): number | undefined;
|
|
9
11
|
export declare function readErrorString(o: object, key: string): string | undefined;
|
|
10
12
|
export declare function readErrorStringList(o: object, key: string): readonly string[] | undefined;
|
|
13
|
+
export declare function readErrorStrictStringList(o: object, key: string): readonly string[] | undefined;
|
|
11
14
|
export declare function wireFailureShapeOf(e: unknown): WireFailureShape;
|
|
12
15
|
export {};
|
package/dist/wireFailureShape.js
CHANGED
|
@@ -52,6 +52,33 @@ export function readErrorStringList(o, key) {
|
|
|
52
52
|
const v = readErrorSlot(o, key, (x) => Array.isArray(x));
|
|
53
53
|
return Array.isArray(v) ? v.filter((x) => typeof x === 'string') : undefined;
|
|
54
54
|
}
|
|
55
|
+
export function readErrorStrictStringList(o, key) {
|
|
56
|
+
const strict = (x) => {
|
|
57
|
+
if (!Array.isArray(x))
|
|
58
|
+
return false;
|
|
59
|
+
for (let i = 0; i < x.length; i++)
|
|
60
|
+
if (typeof x[i] !== 'string')
|
|
61
|
+
return false;
|
|
62
|
+
return true;
|
|
63
|
+
};
|
|
64
|
+
const v = readErrorSlot(o, key, strict);
|
|
65
|
+
if (!Array.isArray(v))
|
|
66
|
+
return undefined;
|
|
67
|
+
try {
|
|
68
|
+
const out = [];
|
|
69
|
+
const len = v.length;
|
|
70
|
+
for (let i = 0; i < len; i++) {
|
|
71
|
+
const item = v[i];
|
|
72
|
+
if (typeof item !== 'string')
|
|
73
|
+
return undefined;
|
|
74
|
+
out.push(item);
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
55
82
|
export function wireFailureShapeOf(e) {
|
|
56
83
|
const o = e ?? {};
|
|
57
84
|
const status = readGuarded(o, 'status');
|
|
@@ -85,6 +112,21 @@ export function wireFailureShapeOf(e) {
|
|
|
85
112
|
}
|
|
86
113
|
}
|
|
87
114
|
}
|
|
115
|
+
const ownString = (key) => {
|
|
116
|
+
if (extraObj === undefined)
|
|
117
|
+
return undefined;
|
|
118
|
+
try {
|
|
119
|
+
if (!Object.hasOwn(extraObj, key))
|
|
120
|
+
return undefined;
|
|
121
|
+
const v = extraObj[key];
|
|
122
|
+
return typeof v === 'string' ? v : undefined;
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const bodyField = ownString('field');
|
|
129
|
+
const bodyName = ownString('name');
|
|
88
130
|
let message;
|
|
89
131
|
try {
|
|
90
132
|
message = typeof rawMessage === 'string' && rawMessage !== '' ? rawMessage : String(e);
|
|
@@ -107,6 +149,8 @@ export function wireFailureShapeOf(e) {
|
|
|
107
149
|
...(typeof errorCode === 'string' ? { errorCode } : {}),
|
|
108
150
|
...(sec !== undefined ? { retryAfterSec: sec } : {}),
|
|
109
151
|
...(committed !== undefined ? { committed } : {}),
|
|
152
|
+
...(bodyField !== undefined ? { bodyField } : {}),
|
|
153
|
+
...(bodyName !== undefined ? { bodyName } : {}),
|
|
110
154
|
message,
|
|
111
155
|
};
|
|
112
156
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
|
|
1
|
+
import { FLEET_LEASE_UNAVAILABLE, USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
|
|
2
|
+
import type { TaskRequestLike } from './request/taskRequest.js';
|
|
2
3
|
export declare const CONFLICT_APPROVAL_SETTLED = "conflict.approval_settled";
|
|
3
4
|
export declare const CONFLICT_RUN_NOT_RUNNING = "conflict.run_not_running";
|
|
4
5
|
export type CancelConflictKind = 'approval_settled' | 'run_not_running' | 'unrecognized';
|
|
@@ -14,6 +15,13 @@ export interface UsageWindowExhaustedDetail {
|
|
|
14
15
|
}
|
|
15
16
|
export declare function usageWindowExhaustedFromError(err: unknown): UsageWindowExhaustedDetail | null;
|
|
16
17
|
export declare function usageWindowExhaustedContent(detail: UsageWindowExhaustedDetail): string;
|
|
18
|
+
export interface FleetLeaseUnavailableDetail {
|
|
19
|
+
code: typeof FLEET_LEASE_UNAVAILABLE;
|
|
20
|
+
reason?: string;
|
|
21
|
+
retryAfterSec?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function fleetLeaseUnavailableFromError(err: unknown): FleetLeaseUnavailableDetail | null;
|
|
24
|
+
export declare function fleetLeaseUnavailableContent(detail: FleetLeaseUnavailableDetail): string;
|
|
17
25
|
export type DenyAttributionRefusalKind = 'not_in_proof' | 'decision_conflict' | 'attribution_rejected';
|
|
18
26
|
export interface DenyAttributionRefusalDetail {
|
|
19
27
|
kind: DenyAttributionRefusalKind;
|
|
@@ -33,3 +41,33 @@ export interface SessionDeleteConflictDetail {
|
|
|
33
41
|
}
|
|
34
42
|
export declare function sessionDeleteConflictFromError(err: unknown): SessionDeleteConflictDetail | null;
|
|
35
43
|
export declare function sessionDeleteConflictContent(detail: Pick<SessionDeleteConflictDetail, 'kind' | 'remaining' | 'activeTaskId'>): string;
|
|
44
|
+
export type SettingsPermissionBucket = 'allow' | 'deny' | 'ask';
|
|
45
|
+
export type SettingsPermissionBucketRefusalReason = 'over_cap' | 'bad_entry';
|
|
46
|
+
export interface SettingsPermissionBucketRefusalDetail {
|
|
47
|
+
readonly bucket: SettingsPermissionBucket;
|
|
48
|
+
readonly reason: SettingsPermissionBucketRefusalReason;
|
|
49
|
+
readonly count?: number;
|
|
50
|
+
readonly cap?: number;
|
|
51
|
+
readonly index?: number;
|
|
52
|
+
readonly folded?: true;
|
|
53
|
+
}
|
|
54
|
+
export declare function settingsPermissionBucketRefusalFromError(err: unknown): SettingsPermissionBucketRefusalDetail | null;
|
|
55
|
+
export declare function settingsPermissionBucketRefusalContent(detail: SettingsPermissionBucketRefusalDetail): string;
|
|
56
|
+
export interface ToolDeclarationRefusalDetail {
|
|
57
|
+
readonly code: string;
|
|
58
|
+
}
|
|
59
|
+
export declare function toolDeclarationRefusalFromError(err: unknown): ToolDeclarationRefusalDetail | null;
|
|
60
|
+
export declare function toolDeclarationRefusalContent(_detail: Pick<ToolDeclarationRefusalDetail, 'code'>): string;
|
|
61
|
+
export interface BodyShapeRefusalDetail {
|
|
62
|
+
readonly unknownKeys?: readonly string[];
|
|
63
|
+
readonly unsupportedKeys?: readonly string[];
|
|
64
|
+
}
|
|
65
|
+
export declare function bodyShapeRefusalFromError(err: unknown): BodyShapeRefusalDetail | null;
|
|
66
|
+
export declare function bodyShapeRefusalTouchesSettings(detail: BodyShapeRefusalDetail | null | undefined, sentBody?: TaskRequestLike): boolean | undefined;
|
|
67
|
+
export interface HostPostureRefusalDetail {
|
|
68
|
+
readonly code: string;
|
|
69
|
+
readonly askedWholeEnvironment?: true;
|
|
70
|
+
readonly askedOpenWriteFace?: true;
|
|
71
|
+
}
|
|
72
|
+
export declare function hostPostureRefusalFromError(err: unknown, sentRequest?: TaskRequestLike): HostPostureRefusalDetail | null;
|
|
73
|
+
export declare function hostPostureRefusalContent(detail: Pick<HostPostureRefusalDetail, 'askedWholeEnvironment' | 'askedOpenWriteFace'>): string;
|