@sema-agent/client-core 0.89.0 → 0.90.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 +104 -0
- package/README.md +18 -13
- package/dist/adapter/runStream.d.ts +2 -0
- package/dist/adapter/runStream.js +157 -32
- package/dist/attachmentsWireCaps.d.ts +13 -2
- package/dist/attachmentsWireCaps.js +25 -5
- package/dist/coreValuePorts.d.ts +1 -0
- package/dist/engineCapReader.js +12 -1
- package/dist/engineNoticeCodes.d.ts +2 -9
- package/dist/engineNoticeCodes.js +19 -27
- package/dist/fileHistoryLegNotice.d.ts +20 -0
- package/dist/fileHistoryLegNotice.js +122 -0
- package/dist/gateOutcome.d.ts +1 -1
- package/dist/gateOutcome.js +1 -0
- package/dist/generated/engineFactTables.d.ts +1 -0
- package/dist/generated/engineFactTables.js +3 -0
- package/dist/generated/engineNoticeTables.js +0 -3
- package/dist/hookToolAliases.d.ts +3 -0
- package/dist/hookToolAliases.js +10 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +5 -0
- package/dist/permissionsAllowGrantCapability.d.ts +17 -0
- package/dist/permissionsAllowGrantCapability.js +75 -0
- package/dist/permissionsDeclaration.d.ts +25 -0
- package/dist/permissionsDeclaration.js +227 -0
- package/dist/promptDelivery.d.ts +5 -2
- package/dist/promptDelivery.js +8 -3
- package/dist/providerRejection.d.ts +2 -1
- package/dist/providerRejection.js +7 -1
- package/dist/request/taskRequest.js +27 -1
- package/dist/sdkRegistryTransit.d.ts +1 -0
- package/dist/sdkRegistryTransit.js +1 -0
- package/dist/supportFloor.d.ts +10 -0
- package/dist/supportFloor.js +42 -0
- package/dist/taskRequestWords.d.ts +1 -0
- package/dist/taskRequestWords.js +14 -0
- package/docs/INTEGRATION-CLIENTS.md +503 -13
- package/package.json +2 -2
|
@@ -140,11 +140,6 @@ function engineSessionIdOf(result) {
|
|
|
140
140
|
const v = result?.sessionId;
|
|
141
141
|
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
142
142
|
}
|
|
143
|
-
function providerFailureStatusOf(result) {
|
|
144
|
-
const af = result?.apiFailure;
|
|
145
|
-
const status = typeof af === 'object' && af !== null ? af.status : undefined;
|
|
146
|
-
return typeof status === 'number' && Number.isFinite(status) ? status : undefined;
|
|
147
|
-
}
|
|
148
143
|
export function isOutcomeUnknownRowText(text) {
|
|
149
144
|
return text.trimStart().startsWith(`${OUTCOME_UNKNOWN_ROW_PREFIX}:`);
|
|
150
145
|
}
|
|
@@ -155,6 +150,157 @@ export function isGovernanceTerminal(input) {
|
|
|
155
150
|
return true;
|
|
156
151
|
return input.errorCode === OUTPUT_INVALID;
|
|
157
152
|
}
|
|
153
|
+
function terminalRowFacts(ev) {
|
|
154
|
+
const doneTerminal = ev.type === 'done' ? readRunTerminal(ev.result) : null;
|
|
155
|
+
const errTextRaw = ev.type === 'failed'
|
|
156
|
+
? (ev.errorMessage ?? ev.errorCode ?? 'run failed')
|
|
157
|
+
: doneTerminal?.kind === 'failed'
|
|
158
|
+
? (doneTerminal.message ?? doneTerminal.code ?? 'run failed')
|
|
159
|
+
: doneTerminal?.kind === 'blocked'
|
|
160
|
+
? (doneTerminal.reason
|
|
161
|
+
? `Run blocked: ${doneTerminal.reason}`
|
|
162
|
+
: 'Run blocked (the agent reported it cannot proceed)')
|
|
163
|
+
: null;
|
|
164
|
+
const errText = errTextRaw === '' ? null : errTextRaw;
|
|
165
|
+
if (errText === null)
|
|
166
|
+
return { doneTerminal, errText, activeTaskId: undefined, busy: { busy: false, handle: null }, governance: false };
|
|
167
|
+
const activeTaskId = (ev.type === 'done' ? ev.result?.activeTaskId : undefined) ??
|
|
168
|
+
(ev.type === 'failed' ? ev.activeTaskId : undefined);
|
|
169
|
+
const busy = classifyActiveRunBusy({
|
|
170
|
+
errorCode: ev.type === 'failed' ? ev.errorCode : runTerminalCode(doneTerminal),
|
|
171
|
+
activeTaskId,
|
|
172
|
+
});
|
|
173
|
+
const governance = isGovernanceTerminal({
|
|
174
|
+
status: ev.type === 'failed' ? undefined : doneTerminal?.kind === 'blocked' ? 'blocked' : undefined,
|
|
175
|
+
errorCode: ev.type === 'failed' ? ev.errorCode : runTerminalCode(doneTerminal),
|
|
176
|
+
});
|
|
177
|
+
return { doneTerminal, errText, activeTaskId, busy, governance };
|
|
178
|
+
}
|
|
179
|
+
const PROVIDER_REJECTED_DETAIL = 'provider_rejected';
|
|
180
|
+
function ownDataBit(o, k) {
|
|
181
|
+
try {
|
|
182
|
+
const d = Object.getOwnPropertyDescriptor(o, k);
|
|
183
|
+
return d !== undefined && Object.prototype.hasOwnProperty.call(d, 'value') ? d.value : undefined;
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function plainObjectOf(v) {
|
|
190
|
+
if (typeof v !== 'object' || v === null)
|
|
191
|
+
return undefined;
|
|
192
|
+
try {
|
|
193
|
+
return Array.isArray(v) ? undefined : v;
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function ownDataCopy(o, keys) {
|
|
200
|
+
const out = Object.create(null);
|
|
201
|
+
for (const k of keys) {
|
|
202
|
+
const v = ownDataBit(o, k);
|
|
203
|
+
if (v !== undefined)
|
|
204
|
+
out[k] = v;
|
|
205
|
+
}
|
|
206
|
+
return out;
|
|
207
|
+
}
|
|
208
|
+
function ownTerminalSnapshot(result) {
|
|
209
|
+
let causePlane;
|
|
210
|
+
try {
|
|
211
|
+
causePlane = 'terminal' in result;
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
const snap = ownDataCopy(result, ['status', 'errorCode', 'errorMessage']);
|
|
217
|
+
if (!causePlane)
|
|
218
|
+
return snap;
|
|
219
|
+
let d;
|
|
220
|
+
try {
|
|
221
|
+
d = Object.getOwnPropertyDescriptor(result, 'terminal');
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
if (d === undefined || !Object.prototype.hasOwnProperty.call(d, 'value'))
|
|
227
|
+
return undefined;
|
|
228
|
+
const t = plainObjectOf(d.value);
|
|
229
|
+
if (t === undefined) {
|
|
230
|
+
snap.terminal = null;
|
|
231
|
+
return snap;
|
|
232
|
+
}
|
|
233
|
+
const ts = ownDataCopy(t, ['kind', 'code', 'message']);
|
|
234
|
+
const detail = plainObjectOf(ownDataBit(t, 'detail'));
|
|
235
|
+
if (detail !== undefined)
|
|
236
|
+
ts.detail = ownDataCopy(detail, ['kind', 'status', 'code']);
|
|
237
|
+
snap.terminal = ts;
|
|
238
|
+
return snap;
|
|
239
|
+
}
|
|
240
|
+
function nonEmptyStr(v) {
|
|
241
|
+
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
242
|
+
}
|
|
243
|
+
function mintToolHistoryCarrier(code, status, message) {
|
|
244
|
+
const out = Object.create(null);
|
|
245
|
+
if (code !== undefined)
|
|
246
|
+
out.code = code;
|
|
247
|
+
if (status !== undefined)
|
|
248
|
+
out.status = status;
|
|
249
|
+
if (message !== undefined)
|
|
250
|
+
out.message = message;
|
|
251
|
+
return Object.freeze(out);
|
|
252
|
+
}
|
|
253
|
+
export function toolHistoryErrorCarrierOf(terminalOrResult) {
|
|
254
|
+
const empty = () => mintToolHistoryCarrier(undefined, undefined, undefined);
|
|
255
|
+
try {
|
|
256
|
+
const x = plainObjectOf(terminalOrResult);
|
|
257
|
+
if (x === undefined)
|
|
258
|
+
return empty();
|
|
259
|
+
const type = ownDataBit(x, 'type');
|
|
260
|
+
const frame = (type === 'done' || type === 'failed' ? x : { type: 'done', result: x });
|
|
261
|
+
return toolHistoryCarrierFromFacts(x, terminalRowFacts(frame));
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return empty();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function toolHistoryCarrierFromFacts(x, facts) {
|
|
268
|
+
const empty = () => mintToolHistoryCarrier(undefined, undefined, undefined);
|
|
269
|
+
try {
|
|
270
|
+
const type = ownDataBit(x, 'type');
|
|
271
|
+
if (facts.errText === null || facts.busy.busy || facts.governance || isModelOutputErrorText(facts.errText))
|
|
272
|
+
return empty();
|
|
273
|
+
if (type === 'failed')
|
|
274
|
+
return mintToolHistoryCarrier(nonEmptyStr(ownDataBit(x, 'errorCode')), undefined, nonEmptyStr(ownDataBit(x, 'errorMessage')));
|
|
275
|
+
const result = type === 'done' ? plainObjectOf(ownDataBit(x, 'result')) : x;
|
|
276
|
+
if (result === undefined)
|
|
277
|
+
return empty();
|
|
278
|
+
const snap = ownTerminalSnapshot(result);
|
|
279
|
+
if (snap === undefined)
|
|
280
|
+
return empty();
|
|
281
|
+
const read = readRunTerminal(snap);
|
|
282
|
+
if (read === null || read.kind !== 'failed')
|
|
283
|
+
return empty();
|
|
284
|
+
const detail = plainObjectOf(ownDataBit(read, 'detail'));
|
|
285
|
+
const detailStatus = detail !== undefined && ownDataBit(detail, 'kind') === PROVIDER_REJECTED_DETAIL ? ownDataBit(detail, 'status') : undefined;
|
|
286
|
+
const apiFailure = plainObjectOf(ownDataBit(result, 'apiFailure'));
|
|
287
|
+
const apiStatus = apiFailure === undefined ? undefined : ownDataBit(apiFailure, 'status');
|
|
288
|
+
const status = typeof apiStatus === 'number' && Number.isFinite(apiStatus) ? apiStatus : typeof detailStatus === 'number' ? detailStatus : undefined;
|
|
289
|
+
return mintToolHistoryCarrier(nonEmptyStr(ownDataBit(read, 'code')), status, nonEmptyStr(ownDataBit(read, 'message')));
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
return empty();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function toolHistoryCarrierOfRowFrame(ev, facts) {
|
|
296
|
+
try {
|
|
297
|
+
const x = plainObjectOf(ev);
|
|
298
|
+
return x === undefined ? mintToolHistoryCarrier(undefined, undefined, undefined) : toolHistoryCarrierFromFacts(x, facts);
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
return mintToolHistoryCarrier(undefined, undefined, undefined);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
158
304
|
const reportedDroppedTypes = new Set();
|
|
159
305
|
const DROPPED_TYPE_MEMO_CAP = 64;
|
|
160
306
|
const DROPPED_TYPE_DISPLAY_CAP = 60;
|
|
@@ -477,30 +623,15 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
477
623
|
continue;
|
|
478
624
|
}
|
|
479
625
|
if (ev.type === 'done' || ev.type === 'failed') {
|
|
480
|
-
const
|
|
481
|
-
const
|
|
482
|
-
|
|
483
|
-
: doneTerminal?.kind === 'failed'
|
|
484
|
-
? (doneTerminal.message ?? doneTerminal.code ?? 'run failed')
|
|
485
|
-
: doneTerminal?.kind === 'blocked'
|
|
486
|
-
? (doneTerminal.reason
|
|
487
|
-
? `Run blocked: ${doneTerminal.reason}`
|
|
488
|
-
: 'Run blocked (the agent reported it cannot proceed)')
|
|
489
|
-
: null;
|
|
626
|
+
const rowFacts = terminalRowFacts(ev);
|
|
627
|
+
const doneTerminal = rowFacts.doneTerminal;
|
|
628
|
+
const errText = rowFacts.errText;
|
|
490
629
|
if (errText) {
|
|
491
|
-
const
|
|
492
|
-
(ev.type === 'failed' ? ev.activeTaskId : undefined);
|
|
493
|
-
const busy = classifyActiveRunBusy({
|
|
494
|
-
errorCode: ev.type === 'failed' ? ev.errorCode : runTerminalCode(doneTerminal),
|
|
495
|
-
activeTaskId,
|
|
496
|
-
});
|
|
630
|
+
const busy = rowFacts.busy;
|
|
497
631
|
const maxTokHint = /max_tokens/i.test(errText)
|
|
498
632
|
? '\nyour provider caps max_tokens lower — lower it in /model (press m, or M to type a value)'
|
|
499
633
|
: '';
|
|
500
|
-
const governance =
|
|
501
|
-
status: ev.type === 'failed' ? undefined : doneTerminal?.kind === 'blocked' ? 'blocked' : undefined,
|
|
502
|
-
errorCode: ev.type === 'failed' ? ev.errorCode : runTerminalCode(doneTerminal),
|
|
503
|
-
});
|
|
634
|
+
const governance = rowFacts.governance;
|
|
504
635
|
const busyHandle = busy.handle;
|
|
505
636
|
const rowText = busy.busy
|
|
506
637
|
? `This session is locked by an earlier run${busyHandle ? ` (run ${busyHandle})` : ''} that ` +
|
|
@@ -516,13 +647,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
516
647
|
const sessionUnreadable = ev.type === 'failed'
|
|
517
648
|
? isCorruptSessionCode(ev.errorCode)
|
|
518
649
|
: doneTerminal?.kind === 'failed' && isCorruptSessionCode(doneTerminal.code);
|
|
519
|
-
const historyMismatch =
|
|
520
|
-
? classifyToolHistoryMismatch({
|
|
521
|
-
code: ev.type === 'failed' ? ev.errorCode : runTerminalCode(doneTerminal),
|
|
522
|
-
status: ev.type === 'done' ? providerFailureStatusOf(ev.result) : undefined,
|
|
523
|
-
message: errText,
|
|
524
|
-
})
|
|
525
|
-
: null;
|
|
650
|
+
const historyMismatch = classifyToolHistoryMismatch(toolHistoryCarrierOfRowFrame(ev, rowFacts));
|
|
526
651
|
const historyEchoedSid = ev.type === 'done' ? engineSessionIdOf(ev.result) : undefined;
|
|
527
652
|
const historyRepeat = noteToolHistoryTerminal({
|
|
528
653
|
sessionId: historyEchoedSid ?? ctx.sessionId,
|
|
@@ -6,7 +6,6 @@ export interface AttachmentsSpec {
|
|
|
6
6
|
changedFiles?: true | {
|
|
7
7
|
maxFiles?: number;
|
|
8
8
|
};
|
|
9
|
-
planModeReminder?: true;
|
|
10
9
|
budgetUsd?: true;
|
|
11
10
|
backgroundTasks?: boolean;
|
|
12
11
|
toolsDelta?: true;
|
|
@@ -14,6 +13,18 @@ export interface AttachmentsSpec {
|
|
|
14
13
|
agentListing?: boolean;
|
|
15
14
|
skillsListing?: boolean;
|
|
16
15
|
}
|
|
17
|
-
export declare const ATTACHMENTS_SPEC_KEYS: readonly ["todoReminder", "todoReminderMode", "changedFiles", "
|
|
16
|
+
export declare const ATTACHMENTS_SPEC_KEYS: readonly ["todoReminder", "todoReminderMode", "changedFiles", "budgetUsd", "backgroundTasks", "toolsDelta", "mcpInstructions", "agentListing", "skillsListing"];
|
|
18
17
|
export declare const ATTACHMENTS_DEFAULT_ON_KEYS: readonly ["agentListing", "skillsListing", "backgroundTasks"];
|
|
18
|
+
export declare class AttachmentsSpecRefused extends TypeError {
|
|
19
|
+
readonly token: string;
|
|
20
|
+
readonly why: string;
|
|
21
|
+
readonly allowed: readonly string[];
|
|
22
|
+
readonly key?: string;
|
|
23
|
+
constructor(message: string, init: {
|
|
24
|
+
readonly token: string;
|
|
25
|
+
readonly why: string;
|
|
26
|
+
readonly allowed: readonly string[];
|
|
27
|
+
readonly key?: string;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
19
30
|
export declare function attachmentsForRequest(env?: EnvLike): AttachmentsSpec | undefined;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { hostEnv } from './hostEnv.js';
|
|
2
2
|
import { envFlagOff } from './envFlag.js';
|
|
3
|
+
import { retiredAttachmentsKeyWhy } from './taskRequestWords.js';
|
|
3
4
|
export const ATTACHMENTS_ENV = 'SEMA_ATTACHMENTS';
|
|
4
5
|
export const ATTACHMENTS_SPEC_KEYS = Object.freeze([
|
|
5
6
|
'todoReminder',
|
|
6
7
|
'todoReminderMode',
|
|
7
8
|
'changedFiles',
|
|
8
|
-
'planModeReminder',
|
|
9
9
|
'budgetUsd',
|
|
10
10
|
'backgroundTasks',
|
|
11
11
|
'toolsDelta',
|
|
@@ -17,7 +17,6 @@ export const ATTACHMENTS_DEFAULT_ON_KEYS = ['agentListing', 'skillsListing', 'ba
|
|
|
17
17
|
const OPT_IN_KEYS = [
|
|
18
18
|
'todoReminder',
|
|
19
19
|
'changedFiles',
|
|
20
|
-
'planModeReminder',
|
|
21
20
|
'budgetUsd',
|
|
22
21
|
'backgroundTasks',
|
|
23
22
|
'toolsDelta',
|
|
@@ -28,16 +27,37 @@ const DEFAULT_PAIR = ['backgroundTasks', 'toolsDelta'];
|
|
|
28
27
|
const _attachmentsKeyPins = [true, true, true, true, true, true];
|
|
29
28
|
void _attachmentsKeyPins;
|
|
30
29
|
const TODO_REMINDER_MODES = ['baseline', 'off'];
|
|
30
|
+
export class AttachmentsSpecRefused extends TypeError {
|
|
31
|
+
token;
|
|
32
|
+
why;
|
|
33
|
+
allowed;
|
|
34
|
+
constructor(message, init) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.name = 'AttachmentsSpecRefused';
|
|
37
|
+
this.token = init.token;
|
|
38
|
+
this.why = init.why;
|
|
39
|
+
this.allowed = Object.freeze([...init.allowed]);
|
|
40
|
+
if (init.key !== undefined)
|
|
41
|
+
this.key = init.key;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function legalAttachmentsTokens() {
|
|
45
|
+
return ['off', 'full', 'all', 'default', '<literalTrueKey>', '+<literalTrueKey>', ...DEFAULT_ON_ONLY_KEYS.map(k => `-${k}`), `todoReminderMode=${TODO_REMINDER_MODES.join('|')}`];
|
|
46
|
+
}
|
|
31
47
|
function refuse(token, why) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
`-agentListing | -skillsListing | todoReminderMode=baseline|off`);
|
|
48
|
+
const allowed = legalAttachmentsTokens();
|
|
49
|
+
throw new AttachmentsSpecRefused(`${ATTACHMENTS_ENV}: refusing token "${token}" — ${why}. Legal tokens: ${allowed.join(' | ')}`, { token, why, allowed });
|
|
35
50
|
}
|
|
36
51
|
export function attachmentsForRequest(env = hostEnv()) {
|
|
37
52
|
const raw = (env[ATTACHMENTS_ENV] ?? '').trim().toLowerCase();
|
|
38
53
|
if (envFlagOff(raw))
|
|
39
54
|
return allDefaultOnOff();
|
|
40
55
|
const tokens = raw.split(',').map(t => t.trim()).filter(t => t.length > 0);
|
|
56
|
+
for (const token of tokens) {
|
|
57
|
+
const named = retiredAttachmentsKeyWhy(token);
|
|
58
|
+
if (named !== undefined)
|
|
59
|
+
refuse(token, named);
|
|
60
|
+
}
|
|
41
61
|
if (tokens.length === 0)
|
|
42
62
|
return { backgroundTasks: true, toolsDelta: true };
|
|
43
63
|
if (tokens.length === 1 && (tokens[0] === 'full' || tokens[0] === 'all'))
|
package/dist/coreValuePorts.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export interface AllowDenyPolicyOptionsView {
|
|
|
16
16
|
deny?: string[];
|
|
17
17
|
onInvalidName?: 'throw' | 'skip';
|
|
18
18
|
onInvalidNameIssue?: (issue: AllowDenyInvalidNameIssueView) => void;
|
|
19
|
+
scope?: 'grant' | 'narrowing';
|
|
19
20
|
}
|
|
20
21
|
export interface AllowDenyInvalidNameIssueView {
|
|
21
22
|
entry: string;
|
package/dist/engineCapReader.js
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import { snapshotCapsGeneration, capsGenerationStillCurrent } from './engineCapsGenerationGuard.js';
|
|
2
|
+
function freezeReading(reading, seen = new Set()) {
|
|
3
|
+
if (reading === null || typeof reading !== 'object' || seen.has(reading))
|
|
4
|
+
return reading;
|
|
5
|
+
seen.add(reading);
|
|
6
|
+
Object.freeze(reading);
|
|
7
|
+
for (const d of Object.values(Object.getOwnPropertyDescriptors(reading))) {
|
|
8
|
+
if ('value' in d)
|
|
9
|
+
freezeReading(d.value, seen);
|
|
10
|
+
}
|
|
11
|
+
return reading;
|
|
12
|
+
}
|
|
2
13
|
export function createEngineCapReader(spec) {
|
|
3
14
|
const readingByBase = new Map();
|
|
4
15
|
return {
|
|
@@ -23,7 +34,7 @@ export function createEngineCapReader(spec) {
|
|
|
23
34
|
readingByBase.delete(baseUrl);
|
|
24
35
|
return;
|
|
25
36
|
}
|
|
26
|
-
readingByBase.set(baseUrl, reading);
|
|
37
|
+
readingByBase.set(baseUrl, freezeReading(reading));
|
|
27
38
|
},
|
|
28
39
|
observed(baseUrl) {
|
|
29
40
|
if (typeof baseUrl !== 'string' || baseUrl === '')
|
|
@@ -130,13 +130,6 @@ export interface ReadDenyUnappliedFactsView {
|
|
|
130
130
|
runId: string;
|
|
131
131
|
}
|
|
132
132
|
export declare function readReadDenyUnapplied(notice: unknown): ReadDenyUnappliedFactsView | undefined;
|
|
133
|
-
export interface LegacyModeSeedMigratedFactsView {
|
|
134
|
-
permissionMode?: string;
|
|
135
|
-
droppedKeys: readonly string[];
|
|
136
|
-
sessionId: string;
|
|
137
|
-
runId: string;
|
|
138
|
-
}
|
|
139
|
-
export declare function readLegacyModeSeedMigrated(notice: unknown): LegacyModeSeedMigratedFactsView | undefined;
|
|
140
133
|
export interface ToolTurnRepairView {
|
|
141
134
|
form: string;
|
|
142
135
|
toolCallIds: readonly string[];
|
|
@@ -172,9 +165,10 @@ export interface UserInputUndrainedFactsView {
|
|
|
172
165
|
taskId?: string;
|
|
173
166
|
sessionId?: string;
|
|
174
167
|
runId?: string;
|
|
168
|
+
childSessionId?: string;
|
|
175
169
|
}
|
|
176
170
|
export declare function readUserInputUndrained(notice: unknown): UserInputUndrainedFactsView | undefined;
|
|
177
|
-
export declare function userInputUndrainedNotice(facts: Pick<UserInputUndrainedFactsView, 'kind' | 'count' | 'cause'>): string | undefined;
|
|
171
|
+
export declare function userInputUndrainedNotice(facts: Pick<UserInputUndrainedFactsView, 'kind' | 'count' | 'cause' | 'childSessionId'>): string | undefined;
|
|
178
172
|
export declare const ENGINE_NOTICE_FACT_READERS: Readonly<{
|
|
179
173
|
readonly 'mcp.injection_dropped': typeof readMcpInjectionDrop;
|
|
180
174
|
readonly 'delegation.ask_unresolvable': typeof readAskUnresolvable;
|
|
@@ -190,7 +184,6 @@ export declare const ENGINE_NOTICE_FACT_READERS: Readonly<{
|
|
|
190
184
|
readonly 'config.permission_mode_unavailable': typeof readPermissionModeUnavailable;
|
|
191
185
|
readonly 'permission.ask_released_by_mode': typeof readAskReleasedByMode;
|
|
192
186
|
readonly 'permission.read_deny_unapplied': typeof readReadDenyUnapplied;
|
|
193
|
-
readonly 'resume.legacy_mode_seed_migrated': typeof readLegacyModeSeedMigrated;
|
|
194
187
|
readonly 'context.tool_turn_repaired': typeof readToolTurnRepaired;
|
|
195
188
|
readonly 'server.model_unreachable': typeof readModelUnreachable;
|
|
196
189
|
readonly 'task.tool_turn_incomplete': typeof readToolTurnIncomplete;
|
|
@@ -454,31 +454,6 @@ function readReadDenyUnappliedOf(notice) {
|
|
|
454
454
|
}
|
|
455
455
|
return { mode, toolCallId, tiers, rows, rowCount, sessionId, runId };
|
|
456
456
|
}
|
|
457
|
-
export function readLegacyModeSeedMigrated(notice) {
|
|
458
|
-
return guardedRead(notice, readLegacyModeSeedMigratedOf);
|
|
459
|
-
}
|
|
460
|
-
function readLegacyModeSeedMigratedOf(notice) {
|
|
461
|
-
if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
|
|
462
|
-
return undefined;
|
|
463
|
-
const n = notice;
|
|
464
|
-
if (ownSeat(n, 'code') !== 'resume.legacy_mode_seed_migrated')
|
|
465
|
-
return undefined;
|
|
466
|
-
const d = ownSeat(n, 'detail');
|
|
467
|
-
if (typeof d !== 'object' || d === null || Array.isArray(d))
|
|
468
|
-
return undefined;
|
|
469
|
-
const o = d;
|
|
470
|
-
const m = o.migrated;
|
|
471
|
-
if (typeof m !== 'object' || m === null || Array.isArray(m))
|
|
472
|
-
return undefined;
|
|
473
|
-
const mo = m;
|
|
474
|
-
const droppedKeys = nameList(mo.droppedKeys);
|
|
475
|
-
const sessionId = nonEmpty(o.sessionId);
|
|
476
|
-
const runId = nonEmpty(o.runId);
|
|
477
|
-
if (droppedKeys === undefined || sessionId === undefined || runId === undefined)
|
|
478
|
-
return undefined;
|
|
479
|
-
const permissionMode = nonEmpty(optionalSeat(mo, 'permissionMode'));
|
|
480
|
-
return { ...(permissionMode !== undefined ? { permissionMode } : {}), droppedKeys, sessionId, runId };
|
|
481
|
-
}
|
|
482
457
|
export function readToolTurnRepaired(notice) {
|
|
483
458
|
return guardedRead(notice, readToolTurnRepairedOf);
|
|
484
459
|
}
|
|
@@ -601,6 +576,7 @@ function readUserInputUndrainedOf(notice) {
|
|
|
601
576
|
const taskId = nonEmpty(optionalOwnSeat(o, 'taskId'));
|
|
602
577
|
const sessionId = nonEmpty(optionalOwnSeat(o, 'sessionId'));
|
|
603
578
|
const runId = nonEmpty(optionalOwnSeat(o, 'runId'));
|
|
579
|
+
const childSessionId = nonEmpty(optionalOwnSeat(o, 'childSessionId'));
|
|
604
580
|
return {
|
|
605
581
|
kind,
|
|
606
582
|
count,
|
|
@@ -608,6 +584,7 @@ function readUserInputUndrainedOf(notice) {
|
|
|
608
584
|
...(taskId !== undefined ? { taskId } : {}),
|
|
609
585
|
...(sessionId !== undefined ? { sessionId } : {}),
|
|
610
586
|
...(runId !== undefined ? { runId } : {}),
|
|
587
|
+
...(childSessionId !== undefined ? { childSessionId } : {}),
|
|
611
588
|
};
|
|
612
589
|
}
|
|
613
590
|
const messagesPhrase = (n, noun) => `${n} ${noun}${n === 1 ? '' : 's'}`;
|
|
@@ -623,12 +600,17 @@ const _steerSentencePin = true;
|
|
|
623
600
|
void _steerSentencePin;
|
|
624
601
|
const followUpUndrainedSentence = (n) => `${messagesPhrase(n, 'follow-up message')} you queued ${verbBe(n)} not used before the run ended and will not be delivered. ` +
|
|
625
602
|
`Send ${itThem(n)} again if you still need ${itThem(n)}.`;
|
|
603
|
+
const subagentSteerUndrainedSentence = (n) => `${messagesPhrase(n, 'message')} you sent while the run was in progress ${verbBe(n)} not used before a sub-agent's run ended and will not be delivered. ` +
|
|
604
|
+
`Send ${itThem(n)} again if you still need ${itThem(n)}.`;
|
|
605
|
+
const subagentFollowUpUndrainedSentence = (n) => `${messagesPhrase(n, 'follow-up message')} you queued ${verbBe(n)} not used before a sub-agent's run ended and will not be delivered. ` +
|
|
606
|
+
`Send ${itThem(n)} again if you still need ${itThem(n)}.`;
|
|
626
607
|
const unrecognizedUndrainedSentence = (n, kind) => `${kind === 'followUp' ? `${messagesPhrase(n, 'follow-up message')} you queued` : `${messagesPhrase(n, 'message')} you sent during a run`} may not have been used, ` +
|
|
627
608
|
`and the reason was not reported in a form this version recognizes. Check the run's transcript before sending ${itThem(n)} again.`;
|
|
628
609
|
export function userInputUndrainedNotice(facts) {
|
|
629
610
|
let kind;
|
|
630
611
|
let count;
|
|
631
612
|
let cause;
|
|
613
|
+
let child;
|
|
632
614
|
try {
|
|
633
615
|
if (facts === null || typeof facts !== 'object' || Array.isArray(facts))
|
|
634
616
|
return undefined;
|
|
@@ -639,12 +621,23 @@ export function userInputUndrainedNotice(facts) {
|
|
|
639
621
|
catch {
|
|
640
622
|
return undefined;
|
|
641
623
|
}
|
|
624
|
+
try {
|
|
625
|
+
child = Object.hasOwn(facts, 'childSessionId') ? facts.childSessionId : undefined;
|
|
626
|
+
}
|
|
627
|
+
catch {
|
|
628
|
+
child = undefined;
|
|
629
|
+
}
|
|
630
|
+
const fromSubagent = typeof child === 'string' && child.length > 0;
|
|
642
631
|
const n = positiveInt(count);
|
|
643
632
|
if (n === undefined || (kind !== 'steer' && kind !== 'followUp'))
|
|
644
633
|
return undefined;
|
|
645
634
|
if (kind === 'followUp') {
|
|
646
|
-
|
|
635
|
+
if (cause === undefined || cause === 'leg_end')
|
|
636
|
+
return fromSubagent ? subagentFollowUpUndrainedSentence(n) : followUpUndrainedSentence(n);
|
|
637
|
+
return unrecognizedUndrainedSentence(n, kind);
|
|
647
638
|
}
|
|
639
|
+
if (cause === 'leg_end' && fromSubagent)
|
|
640
|
+
return subagentSteerUndrainedSentence(n);
|
|
648
641
|
if (typeof cause === 'string' && Object.hasOwn(STEER_UNDRAINED_SENTENCE, cause)) {
|
|
649
642
|
return STEER_UNDRAINED_SENTENCE[cause](n);
|
|
650
643
|
}
|
|
@@ -665,7 +658,6 @@ export const ENGINE_NOTICE_FACT_READERS = Object.freeze({
|
|
|
665
658
|
'config.permission_mode_unavailable': readPermissionModeUnavailable,
|
|
666
659
|
'permission.ask_released_by_mode': readAskReleasedByMode,
|
|
667
660
|
'permission.read_deny_unapplied': readReadDenyUnapplied,
|
|
668
|
-
'resume.legacy_mode_seed_migrated': readLegacyModeSeedMigrated,
|
|
669
661
|
'context.tool_turn_repaired': readToolTurnRepaired,
|
|
670
662
|
'server.model_unreachable': readModelUnreachable,
|
|
671
663
|
'task.tool_turn_incomplete': readToolTurnIncomplete,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AgentEvent } from '@sema-agent/sdk';
|
|
2
|
+
import { type FileHistoryCaptureReading } from './fileHistoryCaptureCapability.js';
|
|
3
|
+
export type FileHistoryDeclarationFact = 'sent' | 'not_sent' | 'unknown';
|
|
4
|
+
export declare const FILE_HISTORY_LEG_VERDICTS: readonly ["not_honored", "not_offered", "honored", "not_declared", "unknown"];
|
|
5
|
+
export type FileHistoryLegNoticeVerdict = (typeof FILE_HISTORY_LEG_VERDICTS)[number];
|
|
6
|
+
export interface FileHistoryLegNoticeInput {
|
|
7
|
+
readonly capability: FileHistoryCaptureReading;
|
|
8
|
+
readonly declaration: FileHistoryDeclarationFact;
|
|
9
|
+
readonly captureOffByUser: boolean;
|
|
10
|
+
readonly legWord: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare function fileHistoryLegNoticeVerdict(input: FileHistoryLegNoticeInput): FileHistoryLegNoticeVerdict;
|
|
13
|
+
export declare function fileHistoryLegNoticeSentence(verdict: FileHistoryLegNoticeVerdict): string | null;
|
|
14
|
+
export declare function fileHistoryDeclarationOfBody(body: object | null | undefined): FileHistoryDeclarationFact;
|
|
15
|
+
export interface FileHistoryDeclarationLedger {
|
|
16
|
+
declared(requestKey: string, fact: FileHistoryDeclarationFact): boolean;
|
|
17
|
+
boundToRun(requestKey: string, runId: string, event: AgentEvent): boolean;
|
|
18
|
+
declarationOf(runId: string): FileHistoryDeclarationFact;
|
|
19
|
+
}
|
|
20
|
+
export declare function createFileHistoryDeclarationLedger(): FileHistoryDeclarationLedger;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { fileHistoryCaptureMode } from './fileHistoryCaptureCapability.js';
|
|
2
|
+
import { frameProvesDelivery } from './promptDelivery.js';
|
|
3
|
+
import { FILE_HISTORY_DISABLED } from './request/taskRequest.js';
|
|
4
|
+
export const FILE_HISTORY_LEG_VERDICTS = Object.freeze(['not_honored', 'not_offered', 'honored', 'not_declared', 'unknown']);
|
|
5
|
+
function ownRead(o, key) {
|
|
6
|
+
return Object.hasOwn(o, key) ? o[key] : undefined;
|
|
7
|
+
}
|
|
8
|
+
function declarationOfInput(v) {
|
|
9
|
+
return v === 'sent' || v === 'not_sent' ? v : 'unknown';
|
|
10
|
+
}
|
|
11
|
+
export function fileHistoryLegNoticeVerdict(input) {
|
|
12
|
+
if (typeof input !== 'object' || input === null)
|
|
13
|
+
return 'unknown';
|
|
14
|
+
let capability;
|
|
15
|
+
let declaration;
|
|
16
|
+
let offByUser;
|
|
17
|
+
let legWord;
|
|
18
|
+
try {
|
|
19
|
+
capability = ownRead(input, 'capability');
|
|
20
|
+
declaration = declarationOfInput(ownRead(input, 'declaration'));
|
|
21
|
+
offByUser = ownRead(input, 'captureOffByUser') === true;
|
|
22
|
+
legWord = ownRead(input, 'legWord');
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return 'unknown';
|
|
26
|
+
}
|
|
27
|
+
if (legWord !== 'on' && legWord !== FILE_HISTORY_DISABLED)
|
|
28
|
+
return 'unknown';
|
|
29
|
+
if (declaration === 'sent')
|
|
30
|
+
return legWord === 'on' ? 'not_honored' : 'honored';
|
|
31
|
+
if (!offByUser)
|
|
32
|
+
return 'not_declared';
|
|
33
|
+
const mode = fileHistoryCaptureMode(capability);
|
|
34
|
+
if (legWord === 'on' && mode === 'on-always')
|
|
35
|
+
return 'not_offered';
|
|
36
|
+
if (declaration === 'not_sent' && (legWord === FILE_HISTORY_DISABLED || mode === 'on-optional'))
|
|
37
|
+
return 'not_declared';
|
|
38
|
+
return 'unknown';
|
|
39
|
+
}
|
|
40
|
+
const NOT_HONORED_SENTENCE = 'The engine is still capturing file history for this session, though your settings asked it not to.';
|
|
41
|
+
const NOT_OFFERED_SENTENCE = 'This engine always captures file history and cannot turn it off per session, even though file checkpoints are off in your settings.';
|
|
42
|
+
export function fileHistoryLegNoticeSentence(verdict) {
|
|
43
|
+
if (verdict === 'not_honored')
|
|
44
|
+
return NOT_HONORED_SENTENCE;
|
|
45
|
+
if (verdict === 'not_offered')
|
|
46
|
+
return NOT_OFFERED_SENTENCE;
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
export function fileHistoryDeclarationOfBody(body) {
|
|
50
|
+
if (typeof body !== 'object' || body === null)
|
|
51
|
+
return 'unknown';
|
|
52
|
+
try {
|
|
53
|
+
if (Array.isArray(body))
|
|
54
|
+
return 'unknown';
|
|
55
|
+
if (typeof body.toJSON === 'function')
|
|
56
|
+
return 'unknown';
|
|
57
|
+
const d = Object.getOwnPropertyDescriptor(body, 'fileHistory');
|
|
58
|
+
const all = Object.getOwnPropertyDescriptors(body);
|
|
59
|
+
for (const k of Reflect.ownKeys(all)) {
|
|
60
|
+
const x = all[k];
|
|
61
|
+
if (x !== undefined && x.enumerable === true && !Object.hasOwn(x, 'value'))
|
|
62
|
+
return 'unknown';
|
|
63
|
+
}
|
|
64
|
+
const listed = Object.hasOwn(all, 'fileHistory') ? all.fileHistory : undefined;
|
|
65
|
+
const listedOn = listed !== undefined && listed.enumerable === true;
|
|
66
|
+
if (d === undefined || d.enumerable !== true)
|
|
67
|
+
return listedOn ? 'unknown' : 'not_sent';
|
|
68
|
+
if (!Object.hasOwn(d, 'value') || !listedOn || !Object.hasOwn(listed, 'value') || !Object.is(listed.value, d.value))
|
|
69
|
+
return 'unknown';
|
|
70
|
+
if (!Object.is(body.fileHistory, d.value))
|
|
71
|
+
return 'unknown';
|
|
72
|
+
if (typeof d.value === 'object' && d.value !== null)
|
|
73
|
+
return 'unknown';
|
|
74
|
+
return d.value === FILE_HISTORY_DISABLED ? 'sent' : 'not_sent';
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return 'unknown';
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const idOk = (v) => typeof v === 'string' && v.length > 0;
|
|
81
|
+
export function createFileHistoryDeclarationLedger() {
|
|
82
|
+
const factsByKey = new Map();
|
|
83
|
+
const keysByRun = new Map();
|
|
84
|
+
return Object.freeze({
|
|
85
|
+
declared(requestKey, fact) {
|
|
86
|
+
if (!idOk(requestKey) || (fact !== 'sent' && fact !== 'not_sent'))
|
|
87
|
+
return false;
|
|
88
|
+
let set = factsByKey.get(requestKey);
|
|
89
|
+
if (set === undefined)
|
|
90
|
+
factsByKey.set(requestKey, (set = new Set()));
|
|
91
|
+
set.add(fact);
|
|
92
|
+
return true;
|
|
93
|
+
},
|
|
94
|
+
boundToRun(requestKey, runId, event) {
|
|
95
|
+
if (!idOk(requestKey) || !idOk(runId) || !frameProvesDelivery(event))
|
|
96
|
+
return false;
|
|
97
|
+
let set = keysByRun.get(runId);
|
|
98
|
+
if (set === undefined)
|
|
99
|
+
keysByRun.set(runId, (set = new Set()));
|
|
100
|
+
set.add(requestKey);
|
|
101
|
+
return true;
|
|
102
|
+
},
|
|
103
|
+
declarationOf(runId) {
|
|
104
|
+
if (!idOk(runId))
|
|
105
|
+
return 'unknown';
|
|
106
|
+
const keys = keysByRun.get(runId);
|
|
107
|
+
if (keys === undefined)
|
|
108
|
+
return 'unknown';
|
|
109
|
+
let agreed;
|
|
110
|
+
for (const k of keys) {
|
|
111
|
+
const facts = factsByKey.get(k);
|
|
112
|
+
if (facts === undefined || facts.size !== 1)
|
|
113
|
+
return 'unknown';
|
|
114
|
+
const [only] = facts;
|
|
115
|
+
if (only === undefined || (agreed !== undefined && agreed !== only))
|
|
116
|
+
return 'unknown';
|
|
117
|
+
agreed = only;
|
|
118
|
+
}
|
|
119
|
+
return agreed ?? 'unknown';
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
}
|
package/dist/gateOutcome.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export interface SettlementWhoView {
|
|
|
40
40
|
approver?: string;
|
|
41
41
|
window?: string;
|
|
42
42
|
}
|
|
43
|
-
export declare const SETTLEMENT_KIND_WORDS: readonly ["human_allowed", "human_refused", "approval_window_expired", "denial_limit_window_expired", "park_sla_expired", "no_approver", "approver_unavailable", "approver_error", "approver_contract", "presentation_failed", "blanket_allow_refused", "policy_refused", "task_aborted"];
|
|
43
|
+
export declare const SETTLEMENT_KIND_WORDS: readonly ["human_allowed", "human_refused", "approval_window_expired", "denial_limit_window_expired", "park_sla_expired", "no_approver", "approver_unavailable", "approver_error", "approver_contract", "presentation_failed", "blanket_allow_refused", "policy_allowed", "policy_refused", "task_aborted"];
|
|
44
44
|
export interface SettlementView {
|
|
45
45
|
kind: Settlement['kind'] | (string & {});
|
|
46
46
|
who: SettlementWhoView;
|
package/dist/gateOutcome.js
CHANGED
|
@@ -9,3 +9,4 @@ export declare const CORE_PERMISSION_MODE_FOLD_REASONS: readonly string[];
|
|
|
9
9
|
export declare const CORE_ENGINE_CARD_TYPES: readonly string[];
|
|
10
10
|
export declare const CORE_TOOL_DECLARATION_CODES: readonly string[];
|
|
11
11
|
export declare const CORE_MODE_RELEASE_REASONS: readonly ["rule_unreadable"];
|
|
12
|
+
export declare const CORE_HOOK_TOOL_ALIASES: Readonly<Record<string, string>>;
|
|
@@ -114,3 +114,6 @@ export const CORE_TOOL_DECLARATION_CODES = Object.freeze([
|
|
|
114
114
|
export const CORE_MODE_RELEASE_REASONS = Object.freeze([
|
|
115
115
|
"rule_unreadable",
|
|
116
116
|
]);
|
|
117
|
+
export const CORE_HOOK_TOOL_ALIASES = Object.freeze(Object.assign(Object.create(null), Object.fromEntries([
|
|
118
|
+
["ListPeers", "ListAgents"],
|
|
119
|
+
])));
|