@sema-agent/client-core 0.102.0 → 0.104.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.
Files changed (117) hide show
  1. package/CHANGELOG.md +172 -0
  2. package/README.md +23 -17
  3. package/dist/adapt/toolCards.d.ts +2 -1
  4. package/dist/adapt/toolCards.js +3 -1
  5. package/dist/adapter/downstream/eventToSdkMessage.d.ts +5 -1
  6. package/dist/adapter/downstream/eventToSdkMessage.js +23 -3
  7. package/dist/adapter/downstream/terminalToSdkResult.d.ts +0 -1
  8. package/dist/adapter/downstream/terminalToSdkResult.js +3 -2
  9. package/dist/adapter/downstream/wiringManifestView.js +4 -1
  10. package/dist/agentSession/engineAgentRegistryRead.js +3 -0
  11. package/dist/cloudConfigWireCaps.js +6 -3
  12. package/dist/coreValuePorts.d.ts +3 -1
  13. package/dist/coreValuePorts.js +5 -0
  14. package/dist/credentialPlaneCapability.d.ts +22 -0
  15. package/dist/credentialPlaneCapability.js +75 -0
  16. package/dist/deviceExecutorManagementCapability.d.ts +1 -0
  17. package/dist/deviceExecutorManagementCapability.js +3 -1
  18. package/dist/deviceRebind.d.ts +17 -4
  19. package/dist/deviceRebind.js +43 -14
  20. package/dist/engineAgentAbsence.d.ts +1 -0
  21. package/dist/engineErrorCodes.d.ts +1 -0
  22. package/dist/engineErrorCodes.js +3 -1
  23. package/dist/engineNoticeCodes.d.ts +26 -0
  24. package/dist/engineNoticeCodes.js +121 -12
  25. package/dist/engineRowRef.js +1 -0
  26. package/dist/errorSupplementRoles.js +1 -3
  27. package/dist/eventLeg.js +2 -1
  28. package/dist/executionPlacementWords.d.ts +3 -0
  29. package/dist/executionPlacementWords.js +2 -0
  30. package/dist/fleet/fleetProjection.js +15 -9
  31. package/dist/gateOutcome.d.ts +20 -0
  32. package/dist/gateOutcome.js +89 -0
  33. package/dist/generated/engineAskFaceTables.js +2 -2
  34. package/dist/generated/engineFactTables.d.ts +8 -3
  35. package/dist/generated/engineFactTables.js +58 -2
  36. package/dist/generated/engineNoticeTables.js +30 -0
  37. package/dist/generated/settingsSchemaDefaultModel.d.ts +1 -1
  38. package/dist/generated/settingsSchemaDefaultModel.js +2 -2
  39. package/dist/generated/settingsSchemaFns.d.ts +15 -0
  40. package/dist/generated/settingsSchemaFns.js +25 -2
  41. package/dist/generated/settingsSchemaHooksClassifier.js +109 -29
  42. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -1
  43. package/dist/generated/settingsSchemaMcpRequestEntry.js +213 -93
  44. package/dist/generated/settingsSchemaMcpServerName.d.ts +1 -0
  45. package/dist/generated/settingsSchemaMcpServerName.js +8 -0
  46. package/dist/generated/settingsSchemaOwnKeyRead.d.ts +1 -0
  47. package/dist/generated/settingsSchemaOwnKeyRead.js +172 -0
  48. package/dist/generated/settingsSchemaPlainJsonObject.d.ts +1 -0
  49. package/dist/generated/settingsSchemaPlainJsonObject.js +28 -0
  50. package/dist/generated/settingsSchemaSafetyMergeSpec.js +10 -7
  51. package/dist/generated/settingsSchemaTierWords.d.ts +1 -0
  52. package/dist/generated/settingsSchemaTierWords.js +7 -0
  53. package/dist/generated/settingsSchemaTypes.d.ts +3 -1
  54. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  55. package/dist/hitl/automaticAnswerVerdict.js +47 -11
  56. package/dist/hitl/decisionConflict.js +11 -11
  57. package/dist/hitl/decisionRefusal.d.ts +1 -0
  58. package/dist/hitl/decisionRefusal.js +4 -2
  59. package/dist/hitl/editedRuleTextPrecheck.d.ts +1 -0
  60. package/dist/hitl/editedRuleTextPrecheck.js +26 -1
  61. package/dist/hitl/persistedRulesWire.js +1 -0
  62. package/dist/hitl/planReviewWire.d.ts +2 -1
  63. package/dist/hitl/planReviewWire.js +8 -12
  64. package/dist/hitl/sessionPolicyDeliverable.d.ts +0 -1
  65. package/dist/hitl/sessionPolicyDeliverable.js +31 -10
  66. package/dist/hitl/sessionPolicyWire.js +1 -1
  67. package/dist/hitl/toolApprovalWire.d.ts +20 -7
  68. package/dist/hitl/toolApprovalWire.js +171 -19
  69. package/dist/host.d.ts +0 -3
  70. package/dist/hostTurnSettings.js +3 -1
  71. package/dist/humanTurn.js +2 -2
  72. package/dist/i18n/messages.en.d.ts +5 -0
  73. package/dist/i18n/messages.en.js +6 -1
  74. package/dist/i18n/messages.zh.js +6 -1
  75. package/dist/index.d.ts +8 -4
  76. package/dist/index.js +3 -1
  77. package/dist/inheritEnvWire.d.ts +1 -0
  78. package/dist/inheritEnvWire.js +8 -5
  79. package/dist/jsonFaithful.js +5 -3
  80. package/dist/mcpEngineLeg.d.ts +3 -0
  81. package/dist/mcpEngineLeg.js +4 -1
  82. package/dist/mcpLiveness.d.ts +18 -0
  83. package/dist/mcpLiveness.js +48 -1
  84. package/dist/mcpReconnect.d.ts +3 -0
  85. package/dist/mcpReconnect.js +6 -0
  86. package/dist/mcpStatusSupersetKeys.js +24 -1
  87. package/dist/mcpWireCaps.d.ts +2 -3
  88. package/dist/mcpWireCaps.js +10 -9
  89. package/dist/memoryEntriesWire.d.ts +35 -1
  90. package/dist/memoryEntriesWire.js +110 -14
  91. package/dist/modsFace.js +7 -3
  92. package/dist/postureKnob.js +1 -1
  93. package/dist/prepareRefusal.d.ts +0 -1
  94. package/dist/prepareRefusal.js +0 -3
  95. package/dist/printModelStatus.d.ts +1 -0
  96. package/dist/printModelStatus.js +6 -2
  97. package/dist/promptProfileWireCaps.d.ts +1 -3
  98. package/dist/promptProfileWireCaps.js +2 -2
  99. package/dist/request/taskRequest.d.ts +1 -1
  100. package/dist/request/taskRequest.js +3 -3
  101. package/dist/retryStatus.d.ts +20 -1
  102. package/dist/retryStatus.js +31 -7
  103. package/dist/ruleCompileVerdict.d.ts +1 -0
  104. package/dist/ruleCompileVerdict.js +3 -1
  105. package/dist/seatContract.d.ts +7 -7
  106. package/dist/seatContract.js +49 -10
  107. package/dist/sessionMemoryErase.js +24 -2
  108. package/dist/sessionRowTag.d.ts +24 -0
  109. package/dist/sessionRowTag.js +77 -0
  110. package/dist/systemReminderTag.js +14 -4
  111. package/dist/turnFailurePresentation.js +8 -1
  112. package/dist/wireFailureShape.d.ts +12 -1
  113. package/dist/wireFailureShape.js +58 -24
  114. package/dist/wireRefusalCopy.d.ts +0 -3
  115. package/dist/wireRefusalCopy.js +0 -17
  116. package/docs/INTEGRATION-CLIENTS.md +400 -14
  117. package/package.json +5 -5
@@ -3,6 +3,7 @@ import { askParkRowArm } from './askParkRowRouting.js';
3
3
  import { parkGateArmOf } from './frameRouter.js';
4
4
  import { seatSessionRowOf } from './standingRows.js';
5
5
  import { hostLog } from '../host.js';
6
+ import { trimEditedRuleText } from './editedRuleTextPrecheck.js';
6
7
  import { appendOwnElement, guardedRead, readAskOrigin, readOwnDataNonEmptyString, readOwnDataValue, readOwnNonEmptyString } from '../ownKey.js';
7
8
  import { ownReadingSlot } from '../engineWireFor.js';
8
9
  import { DEPLOYMENT_LIST_ASK_CLASSES, readAskClassPair } from './askClassPair.js';
@@ -12,7 +13,7 @@ import { readAllowRuleShadowFromWire, retiredAllowRuleShadowKeyPresent, RETIRED_
12
13
  import { createSessionSlot, DEFAULT_SESSION_KEY } from '../sessionSlot.js';
13
14
  import { readEngineActiveBgTasks } from '../fleet/fleetLedger.js';
14
15
  import { CORE_SKILL_TOOL_NAME } from '../generated/toolNameTables.js';
15
- import { CORE_ALLOW_ENTRY_INERT_REASONS } from '../generated/engineFactTables.js';
16
+ import { CORE_ALLOW_ENTRY_INERT_REASONS, CORE_PERSISTED_RULE_MATCHES } from '../generated/engineFactTables.js';
16
17
  import { msg, renderMessage } from '../i18n/translate.js';
17
18
  import { INTERRUPT_DENY_REASON, observeCancelByDeny, surfaceApprovalParking, surfaceRememberNotApplied, surfaceEditNotForwarded, surfaceEditRefusedOnBlindAsk, surfaceRuleArmNotSent, surfaceRuleArmRejected } from './hitlHostSurface.js';
18
19
  import { approvalCallKey, liveFrameCallKey } from './gateIdentity.js';
@@ -27,6 +28,7 @@ import { isApprovalMandateWord } from '../gateVocabulary.js';
27
28
  import { approvalDecidedByAdmitted } from '../approvalDecidedByCapability.js';
28
29
  import { decideFailureNote } from '../decideFailureNote.js';
29
30
  import { slotPresenceOf, wireFailureTextsOf } from '../wireFailureShape.js';
31
+ import { isPlainRecord } from '../jsonFaithful.js';
30
32
  import { DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED } from '../engineErrorCodes.js';
31
33
  import { readDecideReceipt } from '../decideReceipt.js';
32
34
  import { RULE_OFFER_MATCHES, RULE_OFFER_BATCH_MEMBER_KINDS, RULE_OFFER_UNCOVERED_REASONS, RULE_OFFERS_ABSENCE_REASONS, ASK_ORIGINS, } from '@sema-agent/sdk';
@@ -67,6 +69,8 @@ export function structurallyEqual(a, b) {
67
69
  return ka.every(k => structurallyEqual(a[k], b[k]));
68
70
  }
69
71
  export { RULE_OFFER_MATCHES, RULE_OFFER_BATCH_MEMBER_KINDS, RULE_OFFER_UNCOVERED_REASONS };
72
+ const _sdkRuleOfferMatchWithinEngine = true;
73
+ void _sdkRuleOfferMatchWithinEngine;
70
74
  export { RULE_OFFERS_ABSENCE_REASONS };
71
75
  export const ASK_ORIGIN_WORDS = ASK_ORIGINS;
72
76
  export const APPROVAL_DENY_SETTLED_BY_WORDS = Object.freeze(['human', 'policy']);
@@ -190,6 +194,11 @@ const PARK_ROW_ARGS_ABSENT_NOTE = "this request's tool arguments are not availab
190
194
  const PARK_ROW_ARGS_TRUNCATED_NOTE = "this request's tool arguments were too large to keep on the pending approval record and were replaced by a size marker, " +
191
195
  'so you are deciding without seeing them; deny it if you are not sure what it will do. ' +
192
196
  'Edits are not accepted on this card: there is no original input to edit';
197
+ const ARGS_REWRITTEN_NOTE = "this request's tool arguments were changed after the model made the call (for example by a hook) — " +
198
+ 'the arguments shown here are the changed ones recorded for this approval, and they differ from the call shown in the conversation';
199
+ const ARGS_FROM_MODEL_CALL_NOTE = 'this approval request did not carry usable tool arguments (for example because they were too large to include), ' +
200
+ "so the arguments shown are the model's original call from the conversation — " +
201
+ 'if they were changed after that call (for example by a hook), what runs differs from what is shown';
193
202
  const PARK_EDIT_REFUSED_REASON = "the card returned an edited approval, but this request's tool arguments are not available on this surface " +
194
203
  '(missing, or replaced by a size marker on the pending approval record), so the edit cannot be applied — nothing was sent; ' +
195
204
  'approve or deny it as it is';
@@ -202,6 +211,139 @@ function isParkRowInputSizeMarker(v) {
202
211
  const o = v;
203
212
  return o.truncated === true && typeof o.bytes === 'number' && Number.isFinite(o.bytes) && o.bytes >= 0;
204
213
  }
214
+ function recordedInputShapeOf(v) {
215
+ if (v === undefined || v === null)
216
+ return 'absent';
217
+ try {
218
+ if (typeof v !== 'object' || !isPlainRecord(v))
219
+ return 'other';
220
+ return isParkRowInputSizeMarker(v) ? 'size_marker' : 'input';
221
+ }
222
+ catch {
223
+ return 'other';
224
+ }
225
+ }
226
+ function argsProvablyDiffer(recorded, streamArgs) {
227
+ try {
228
+ if (typeof streamArgs !== 'object' || streamArgs === null || Array.isArray(streamArgs))
229
+ return false;
230
+ return jsonValuesDiffer(recorded, streamArgs, 0, { nodes: 0 }) === true;
231
+ }
232
+ catch {
233
+ return false;
234
+ }
235
+ }
236
+ function cardInputOf(recorded, stream) {
237
+ const shape = recordedInputShapeOf(recorded);
238
+ const streamPresent = stream !== undefined && stream !== null;
239
+ if (shape === 'input')
240
+ return { from: 'recorded', args: recorded, rewritten: streamPresent && argsProvablyDiffer(recorded, stream) };
241
+ if (streamPresent)
242
+ return { from: 'stream', args: stream, shape };
243
+ return { from: 'none', shape, recorded };
244
+ }
245
+ const CARD_ARGS_COMPARE_MAX_NODES = 20_000;
246
+ const CARD_ARGS_COMPARE_MAX_DEPTH = 256;
247
+ const NOT_COMPARABLE = Symbol('not comparable');
248
+ function ownDataForCompare(o, k) {
249
+ const d = Object.getOwnPropertyDescriptor(o, k);
250
+ return d !== undefined && Object.hasOwn(d, 'value') ? d.value : NOT_COMPARABLE;
251
+ }
252
+ const TO_JSON_CHAIN_MAX = 32;
253
+ function hasToJsonHook(o) {
254
+ let at = o;
255
+ for (let depth = 0; at !== null; depth++) {
256
+ if (depth >= TO_JSON_CHAIN_MAX)
257
+ return true;
258
+ const d = Object.getOwnPropertyDescriptor(at, 'toJSON');
259
+ if (d !== undefined)
260
+ return !Object.hasOwn(d, 'value') || typeof d.value === 'function';
261
+ at = Object.getPrototypeOf(at);
262
+ }
263
+ return false;
264
+ }
265
+ function jsonValueKindOf(v) {
266
+ if (v === null)
267
+ return 'null';
268
+ switch (typeof v) {
269
+ case 'boolean':
270
+ return 'boolean';
271
+ case 'string':
272
+ return 'string';
273
+ case 'number':
274
+ return Number.isFinite(v) ? 'number' : undefined;
275
+ case 'object':
276
+ if (Array.isArray(v))
277
+ return hasToJsonHook(v) ? undefined : 'array';
278
+ return isPlainRecord(v) && !hasToJsonHook(v) ? 'object' : undefined;
279
+ default:
280
+ return undefined;
281
+ }
282
+ }
283
+ function jsonValuesDiffer(a, b, depth, budget) {
284
+ if (++budget.nodes > CARD_ARGS_COMPARE_MAX_NODES || depth > CARD_ARGS_COMPARE_MAX_DEPTH)
285
+ return undefined;
286
+ const ka = jsonValueKindOf(a);
287
+ const kb = jsonValueKindOf(b);
288
+ if (ka === undefined || kb === undefined)
289
+ return undefined;
290
+ if (ka !== kb)
291
+ return true;
292
+ if (ka === 'array') {
293
+ const xa = a;
294
+ const xb = b;
295
+ const la = ownDataForCompare(xa, 'length');
296
+ const lb = ownDataForCompare(xb, 'length');
297
+ if (typeof la !== 'number' || typeof lb !== 'number')
298
+ return undefined;
299
+ if (la !== lb)
300
+ return true;
301
+ for (let i = 0; i < la; i++) {
302
+ const va = ownDataForCompare(xa, String(i));
303
+ const vb = ownDataForCompare(xb, String(i));
304
+ if (va === NOT_COMPARABLE || vb === NOT_COMPARABLE)
305
+ return undefined;
306
+ const d = jsonValuesDiffer(va, vb, depth + 1, budget);
307
+ if (d !== false)
308
+ return d;
309
+ }
310
+ return false;
311
+ }
312
+ if (ka === 'object') {
313
+ const ra = a;
314
+ const rb = b;
315
+ const keysA = Object.keys(ra);
316
+ const keysB = Object.keys(rb);
317
+ budget.nodes += keysA.length + keysB.length;
318
+ if (budget.nodes > CARD_ARGS_COMPARE_MAX_NODES)
319
+ return undefined;
320
+ const inA = new Set(keysA);
321
+ const inB = new Set(keysB);
322
+ for (const k of keysA) {
323
+ const va = ownDataForCompare(ra, k);
324
+ if (va === NOT_COMPARABLE)
325
+ return undefined;
326
+ if (!inB.has(k))
327
+ return jsonValueKindOf(va) === undefined ? undefined : true;
328
+ const vb = ownDataForCompare(rb, k);
329
+ if (vb === NOT_COMPARABLE)
330
+ return undefined;
331
+ const d = jsonValuesDiffer(va, vb, depth + 1, budget);
332
+ if (d !== false)
333
+ return d;
334
+ }
335
+ for (const k of keysB) {
336
+ if (inA.has(k))
337
+ continue;
338
+ const vb = ownDataForCompare(rb, k);
339
+ if (vb === NOT_COMPARABLE)
340
+ return undefined;
341
+ return jsonValueKindOf(vb) === undefined ? undefined : true;
342
+ }
343
+ return false;
344
+ }
345
+ return a === b ? false : true;
346
+ }
205
347
  function durableHoldKey(row, callKey) {
206
348
  const createdAt = typeof row.createdAt === 'number' && Number.isFinite(row.createdAt) ? row.createdAt : null;
207
349
  return JSON.stringify([typeof row.sessionId === 'string' ? row.sessionId : null, typeof row.taskId === 'string' ? row.taskId : null, callKey, createdAt]);
@@ -341,15 +483,10 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
341
483
  const at = { lane: 'decide', ...(gatedCallId !== undefined ? { gatedCallId } : {}) };
342
484
  const toolName = typeof pending.toolName === 'string' ? pending.toolName : '';
343
485
  const streamArgs = gatedCallId !== undefined ? argsByCall.get(gatedCallId) : undefined;
344
- const rowInput = pending.input;
345
- const rowArgsGap = streamArgs !== undefined && streamArgs !== null
346
- ? undefined
347
- : rowInput === undefined || rowInput === null
348
- ? 'absent'
349
- : isParkRowInputSizeMarker(rowInput)
350
- ? 'truncated'
351
- : undefined;
352
- const args = streamArgs !== undefined && streamArgs !== null ? streamArgs : rowArgsGap !== undefined ? {} : rowInput;
486
+ const reading = cardInputOf(pending.input, streamArgs);
487
+ const rowArgsGap = reading.from !== 'none' ? undefined : reading.shape === 'absent' ? 'absent' : reading.shape === 'size_marker' ? 'truncated' : undefined;
488
+ const args = reading.from !== 'none' ? reading.args : rowArgsGap !== undefined ? {} : reading.recorded;
489
+ const argsRewritten = reading.from === 'recorded' && reading.rewritten;
353
490
  if (typeof args !== 'object' || args === null) {
354
491
  return { kind: 'not_sent', ...at, cause: 'no_input', detail: 'gate has no tool input payload' };
355
492
  }
@@ -372,6 +509,7 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
372
509
  wireNote: rowArgsGap === 'truncated' ? PARK_ROW_ARGS_TRUNCATED_NOTE : PARK_ROW_ARGS_ABSENT_NOTE,
373
510
  }
374
511
  : {}),
512
+ ...(argsRewritten ? { argsRewritten: true, wireNote: ARGS_REWRITTEN_NOTE } : {}),
375
513
  ...(pending.governanceForced === true ? { governanceForced: true } : {}),
376
514
  ...(readRequiresRealApproval(pending) ? { requiresRealApproval: true } : {}),
377
515
  ...(hasOwnStrictTrue(pending, 'mandated') ? { mandated: true } : {}),
@@ -580,6 +718,7 @@ export const TOOL_APPROVAL_FRAME_KEYS_MIRROR = [
580
718
  'delegation',
581
719
  'outcome',
582
720
  'cause',
721
+ 'requestedBy',
583
722
  ];
584
723
  const _mirrorPin = [true];
585
724
  void _mirrorPin;
@@ -1085,7 +1224,7 @@ const UNREADABLE_EVIDENCE_KEYS = Object.freeze({
1085
1224
  ]),
1086
1225
  generic: Object.freeze([['ruleOffersAbsence', 'ruleOffersAbsence'], ['askClass', 'askClass'], ['classes', 'classes']]),
1087
1226
  });
1088
- function v1RiskUnreadable(card) {
1227
+ function riskSubtreeUnreadable(card) {
1089
1228
  if (slotPresenceOf(card, 'risk') === 'absent')
1090
1229
  return false;
1091
1230
  try {
@@ -1112,7 +1251,7 @@ function withUnreadableEvidence(carrier, leg, req, reported = []) {
1112
1251
  if (retiredAllowRuleShadowKeyPresent(carrier, shadowLeg))
1113
1252
  keys.add(RETIRED_SHADOW_EVIDENCE_LABEL[shadowLeg]);
1114
1253
  }
1115
- if (leg === 'v1' && v1RiskUnreadable(carrier))
1254
+ if ((leg === 'v1' || leg === 'frame') && riskSubtreeUnreadable(carrier))
1116
1255
  keys.add('risk');
1117
1256
  return keys.size === 0 ? req : { ...req, unreadableEvidence: Object.freeze([...keys].sort()) };
1118
1257
  }
@@ -1336,7 +1475,7 @@ export function readDenialLimitFallback(v) {
1336
1475
  };
1337
1476
  }
1338
1477
  function isRuleOfferMatch(v) {
1339
- return typeof v === 'string' && RULE_OFFER_MATCHES.includes(v);
1478
+ return typeof v === 'string' && CORE_PERSISTED_RULE_MATCHES.includes(v);
1340
1479
  }
1341
1480
  function readRuleTriple(v) {
1342
1481
  if (v === null || typeof v !== 'object')
@@ -1346,7 +1485,7 @@ function readRuleTriple(v) {
1346
1485
  return undefined;
1347
1486
  if (!isRuleOfferMatch(o.match))
1348
1487
  return undefined;
1349
- if (typeof o.command !== 'string' || o.command === '')
1488
+ if (typeof o.command !== 'string')
1350
1489
  return undefined;
1351
1490
  return { rule: o.rule, match: o.match, command: o.command };
1352
1491
  }
@@ -1506,10 +1645,19 @@ function cardFactsOf(carrier, leg, opts) {
1506
1645
  stream = opts.streamArgs;
1507
1646
  blind = opts.argsUnavailable === true;
1508
1647
  }
1509
- const raw = stream !== undefined && stream !== null ? stream : c.args !== undefined && c.args !== null ? c.args : undefined;
1510
- if (typeof raw === 'object' && raw !== null)
1511
- return blind ? { args: raw, argsUnavailable: true } : { args: raw };
1512
- const fallback = argsFallbackOf(c.message, c.argsOmitted);
1648
+ const reading = cardInputOf(c.args, stream);
1649
+ if (reading.from === 'recorded') {
1650
+ if (blind)
1651
+ return { args: reading.args, argsUnavailable: true };
1652
+ return reading.rewritten ? { args: reading.args, argsRewritten: true, wireNote: ARGS_REWRITTEN_NOTE } : { args: reading.args };
1653
+ }
1654
+ if (reading.from === 'stream' && typeof reading.args === 'object' && reading.args !== null) {
1655
+ if (blind)
1656
+ return { args: reading.args, argsUnavailable: true };
1657
+ return { args: reading.args, wireNote: ARGS_FROM_MODEL_CALL_NOTE };
1658
+ }
1659
+ const omitted = c.argsOmitted === true || reading.shape === 'size_marker';
1660
+ const fallback = argsFallbackOf(c.message, omitted);
1513
1661
  const note = blind ? SUSPENDED_ASK_ARGS_NOTE : fallback.omittedNote;
1514
1662
  return { args: fallback.args, argsUnavailable: true, ...(note !== undefined ? { wireNote: note } : {}) };
1515
1663
  }
@@ -1535,6 +1683,8 @@ function cardFactsOf(carrier, leg, opts) {
1535
1683
  out.wireNote = argsPart.wireNote;
1536
1684
  if (argsPart.argsUnavailable === true)
1537
1685
  out.argsUnavailable = true;
1686
+ if (argsPart.argsRewritten === true)
1687
+ out.argsRewritten = true;
1538
1688
  if (full) {
1539
1689
  v1Bit(() => {
1540
1690
  if (c.governanceForced === true)
@@ -1624,6 +1774,8 @@ function cardFactsOf(carrier, leg, opts) {
1624
1774
  if (o !== undefined)
1625
1775
  out.origin = o;
1626
1776
  });
1777
+ }
1778
+ if (leg !== 'generic') {
1627
1779
  v1Bit(() => {
1628
1780
  const w = readApprovalCardWord(carrier);
1629
1781
  if (w !== undefined)
@@ -1899,7 +2051,7 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
1899
2051
  const edited = card.persistRuleEdited === true;
1900
2052
  if (edited) {
1901
2053
  if (lane?.respondFreeFormRulesCapable === true) {
1902
- persistRule = card.persistRule;
2054
+ persistRule = trimEditedRuleText(card.persistRule);
1903
2055
  persistRuleEdited = true;
1904
2056
  }
1905
2057
  else {
package/dist/host.d.ts CHANGED
@@ -3,9 +3,6 @@ import type { WireHooksConfig } from './finalVerifyWire.js';
3
3
  import { type NotificationQueuePort } from './notifications.js';
4
4
  export type SettingsDocument = Record<string, unknown>;
5
5
  export type ManagedPolicyState = 'absent' | 'in-effect' | 'in-effect-pieces' | 'unreadable-covered' | 'unreadable-uncovered' | 'remote-unknown';
6
- export interface ManagedPolicyReading {
7
- readonly state: ManagedPolicyState;
8
- }
9
6
  export type HooksStartupMode = 'safe' | 'bare';
10
7
  export type PluginHookOptionValue = string | number | boolean;
11
8
  export interface PluginHookSensitiveOption {
@@ -454,8 +454,10 @@ function permissionsArm(src, side, adoption) {
454
454
  appendOwnElement(buckets[bucket], rule);
455
455
  origins[bucket].set(rule, origin);
456
456
  }
457
- else if (rank(origin) < rank(prev))
457
+ else if (rank(origin) < rank(prev)) {
458
+ origins[bucket].delete(rule);
458
459
  origins[bucket].set(rule, origin);
460
+ }
459
461
  };
460
462
  let projectionError;
461
463
  const portsProjection = newRulePortsProjection();
package/dist/humanTurn.js CHANGED
@@ -1,4 +1,4 @@
1
- import { CORE_MAX_PENDING_STEER_CHARS, CORE_MCP_IMAGE_MAX_BASE64, CORE_USER_ATTACHMENT_LABEL_MAX } from './generated/engineFactTables.js';
1
+ import { CORE_IMAGE_ADMISSION_HARD_IMAGE_BASE64_CHARS, CORE_MAX_PENDING_STEER_CHARS, CORE_USER_ATTACHMENT_LABEL_MAX } from './generated/engineFactTables.js';
2
2
  import { mintEnvelopeOf, mintReferenceOf, seatTextOf } from './userAttachmentEnvelope.js';
3
3
  import { readEncodingShares, readHumanTurnInput } from './humanTurnRead.js';
4
4
  import { putOwnKey } from './ownKey.js';
@@ -224,7 +224,7 @@ function encodeObjective(v) {
224
224
  let count = 0;
225
225
  let total = 0;
226
226
  const seat = (len) => {
227
- if (len > CORE_MCP_IMAGE_MAX_BASE64)
227
+ if (len > CORE_IMAGE_ADMISSION_HARD_IMAGE_BASE64_CHARS)
228
228
  return 'image_too_large';
229
229
  if (count + 1 > IMAGE_SEAT_MAX_COUNT)
230
230
  return 'seat_count';
@@ -184,6 +184,7 @@ declare const EN: {
184
184
  'config.mcp.nameEdgeWhitespace': string;
185
185
  'config.mcp.nameCollides': string;
186
186
  'config.mcp.nameTooLong': string;
187
+ 'config.mcp.nameReserved': string;
187
188
  'config.mcp.identityHeadersBothSet': string;
188
189
  'config.mcp.transportUnreadable': string;
189
190
  'config.mcp.transportInvalid': string;
@@ -584,6 +585,8 @@ declare const EN: {
584
585
  'notice.wayOut.switchModel': string;
585
586
  'notice.wayOut.wait': string;
586
587
  'notice.wayOut.fixRequest': string;
588
+ 'notice.askUnresolvable.remedy.approver': string;
589
+ 'notice.askUnresolvable.remedy.permissionMode': string;
587
590
  'rules.refusal.sentence.one': string;
588
591
  'rules.refusal.sentence.other': string;
589
592
  'rules.refusal.item': string;
@@ -780,6 +783,7 @@ declare const EN: {
780
783
  'rules.match.host': string;
781
784
  'rules.match.subdomain': string;
782
785
  'rules.match.pattern': string;
786
+ 'rules.match.tool': string;
783
787
  'rules.match.unreported': string;
784
788
  'rules.match.unknown': string;
785
789
  'model.tier.blurb.ultra': string;
@@ -1048,6 +1052,7 @@ declare const EN: {
1048
1052
  'config.mods.loader.failedNoReason': string;
1049
1053
  'config.mods.refusal.by': string;
1050
1054
  'config.mods.rewrite.resultInPlace': string;
1055
+ 'config.mods.rewrite.inputBy': string;
1051
1056
  };
1052
1057
  export declare const EN_MESSAGES: Readonly<typeof EN>;
1053
1058
  export type MessageKey = keyof typeof EN;
@@ -184,6 +184,7 @@ const EN = {
184
184
  'config.mcp.nameEdgeWhitespace': 'MCP server name {name}{where} cannot be used as written, so the server was not started: it would not match the same name in other settings (for example a list of disabled servers). Remove the extra whitespace from the name.',
185
185
  'config.mcp.nameCollides': 'MCP server name {name}{where} cannot be used as written, so the server was not started: without its leading or trailing whitespace it would be the same name as another MCP server entry. Remove the extra whitespace from the name, or delete the duplicate entry.',
186
186
  'config.mcp.nameTooLong': 'MCP server name {name}{where} cannot be used, so the server was not started: server names are limited to 128 characters. Shorten the name.',
187
+ 'config.mcp.nameReserved': 'MCP server name {name}{where} cannot be used, so the server was not started: names starting with "remote-" are kept for the MCP servers a connected device offers. Rename the server.',
187
188
  'config.mcp.identityHeadersBothSet': 'MCP server {name}{where} was not started: it sets both principalHeader and assertionHeader, which name the same identity header — keep only one of the two. The other MCP servers are unaffected.',
188
189
  'config.mcp.transportUnreadable': 'could not be read (a getter or proxy trap on the declaration threw)',
189
190
  'config.mcp.transportInvalid': 'MCP server {name}{where} was not started: its transport setting cannot be used — {path} {problem}. Fix that setting for this server (or remove the server); the other MCP servers are unaffected.',
@@ -302,7 +303,7 @@ const EN = {
302
303
  'session.inheritEnv.withheld.scrub': "Not sent with this request: the engine's version is not known yet, so the default-environment setting was left out; that has the same effect, because leaving it out also gives this run the default environment (credential-like variables removed).",
303
304
  'session.inheritEnv.withheld.unknown': 'Not sent with this request: the shell-environment setting was held back for a reason this version does not recognize.',
304
305
  'session.inheritEnv.refusal': "The engine refused this request as invalid, under a refusal code that many different request fields share · This request asked for the shell to inherit this machine's whole environment, which the engine accepts only when tools run directly on its own machine and the request belongs to a session; if that is what it refused, send it again without that setting (or with the default)",
305
- 'session.inheritEnv.refusalNamed': "The engine refused the setting that lets the shell inherit this machine's whole environment, which it accepts only when tools run directly on its own machine and the request belongs to a session · Send the request again without that setting (or with the default)",
306
+ 'session.inheritEnv.refusalNamed': "The engine refused this request's shell-environment setting: it accepts only the default or this machine's whole environment, and the whole environment only when tools run directly on its own machine and the request belongs to a session · Send the request again without that setting (or with the default)",
306
307
  'session.projectMemory.withheld.absent': 'Not sent with this request: this engine does not declare support for the setting that stops project instruction files from being read, and an engine that does not know it refuses the whole request, so it was held back; those files are still sent to the model.',
307
308
  'session.projectMemory.withheld.declined': 'Not sent with this request: this engine declares that it does not support the setting that stops project instruction files from being read, so it was held back; those files are still sent to the model.',
308
309
  'session.projectMemory.withheld.unreadable': "Not sent with this request: the engine's capabilities could not be read, so it is not known whether it supports the setting that stops project instruction files from being read, and an engine that does not know it refuses the whole request, so it was held back; those files are still sent to the model.",
@@ -584,6 +585,8 @@ const EN = {
584
585
  'notice.wayOut.switchModel': 'The model service cannot serve this request right now — try another model',
585
586
  'notice.wayOut.wait': 'The model service is still working on this request — wait a moment, then try again',
586
587
  'notice.wayOut.fixRequest': 'The model service refused this request — change the request before sending it again; sending it as it is will not help',
588
+ 'notice.askUnresolvable.remedy.approver': 'Way out: connect an approver who can answer requests like this one, or make the connected approver reachable, then try again',
589
+ 'notice.askUnresolvable.remedy.permissionMode': 'Another way out, if this deployment allows it: the {mode} permission mode lets requests like this one through without anyone answering them, and each request let through this way is marked on the tool call it applied to',
587
590
  'rules.refusal.sentence.one': 'permissions: 1 rule will not be enforced — {list}',
588
591
  'rules.refusal.sentence.other': 'permissions: {count} rules will not be enforced — {list}',
589
592
  'rules.refusal.item': '{rule} ({reason})',
@@ -780,6 +783,7 @@ const EN = {
780
783
  'rules.match.host': 'web domain match (one host)',
781
784
  'rules.match.subdomain': 'web domain match (every host under the domain)',
782
785
  'rules.match.pattern': 'command pattern match (a star placed anywhere in the command)',
786
+ 'rules.match.tool': 'whole-tool match (every call to the tool)',
783
787
  'rules.match.unreported': 'an unreported match form',
784
788
  'rules.match.unknown': 'a match form this build does not know',
785
789
  'model.tier.blurb.ultra': 'reserved above max — binds when a stronger model lands',
@@ -1048,5 +1052,6 @@ const EN = {
1048
1052
  'config.mods.loader.failedNoReason': '{name} could not be loaded',
1049
1053
  'config.mods.refusal.by': 'Refused by {by}',
1050
1054
  'config.mods.rewrite.resultInPlace': 'Answered by {by} in place of the tool',
1055
+ 'config.mods.rewrite.inputBy': 'Arguments changed by {by} before the call was let through',
1051
1056
  };
1052
1057
  export const EN_MESSAGES = Object.freeze(EN);
@@ -184,6 +184,7 @@ const ZH = {
184
184
  'config.mcp.nameEdgeWhitespace': 'MCP 服务器名 {name}{where} 不能照原样使用,所以没有启动:它与其他设置里的同名对不上(例如禁用服务器列表)。请去掉名字里多余的空白。',
185
185
  'config.mcp.nameCollides': 'MCP 服务器名 {name}{where} 不能照原样使用,所以没有启动:去掉首尾空白后会与另一条 MCP 服务器重名。请去掉名字里多余的空白,或删掉重复的一条。',
186
186
  'config.mcp.nameTooLong': 'MCP 服务器名 {name}{where} 不可用,所以没有启动:服务器名最长 128 个字符。请缩短名字。',
187
+ 'config.mcp.nameReserved': 'MCP 服务器名 {name}{where} 不可用,所以没有启动:以 "remote-" 开头的名字留给已连接设备提供的 MCP 服务器。请给这台服务器换个名字。',
187
188
  'config.mcp.identityHeadersBothSet': 'MCP 服务器 {name}{where} 没有启动:它同时设置了 principalHeader 和 assertionHeader,而这两项指的是同一个身份头 —— 只保留其中一项。其他 MCP 服务器不受影响。',
188
189
  'config.mcp.transportUnreadable': '读不出(声明上的取值器或代理陷阱抛了错)',
189
190
  'config.mcp.transportInvalid': 'MCP 服务器 {name}{where} 没有启动:它的传输设置不可用 —— {path} {problem}。请修正这台服务器的这项设置(或删掉这台服务器);其他 MCP 服务器不受影响。',
@@ -302,7 +303,7 @@ const ZH = {
302
303
  'session.inheritEnv.withheld.scrub': '这次请求没有带上它:引擎的版本还不知道,所以缺省环境这项设置没有带;效果相同,因为不带它同样让这次 run 拿到缺省环境(看着像凭据的变量已去掉)。',
303
304
  'session.inheritEnv.withheld.unknown': '这次请求没有带上它:shell 环境这项设置因为一个这个版本不认识的原因被扣下了。',
304
305
  'session.inheritEnv.refusal': '引擎把这次请求当作无效拒掉了,用的是许多不同请求字段共用的一个拒绝码 · 这次请求要求 shell 继承本机的整份环境,而引擎只有在工具直接跑在它自己那台机器上、且请求属于某个会话时才接受这一项;如果它拒的正是这一项,请去掉这项设置(或改用缺省)再发一次',
305
- 'session.inheritEnv.refusalNamed': '引擎拒掉了「让 shell 继承本机整份环境」这项设置,它只有在工具直接跑在它自己那台机器上、且请求属于某个会话时才接受这一项 · 请去掉这项设置(或改用缺省)再发一次',
306
+ 'session.inheritEnv.refusalNamed': '引擎拒掉了这次请求里的 shell 环境设置:这一项只收缺省或本机整份环境两种取值,而整份环境只有在工具直接跑在它自己那台机器上、且请求属于某个会话时才接受 · 请去掉这项设置(或改用缺省)再发一次',
306
307
  'session.projectMemory.withheld.absent': '这次请求没有带上它:这台引擎没有声明支持「别读项目指令文件」这项设置,而不认识它的引擎会拒掉整个请求,所以先扣下了;项目指令文件仍会发给模型。',
307
308
  'session.projectMemory.withheld.declined': '这次请求没有带上它:这台引擎声明了不支持「别读项目指令文件」这项设置,所以先扣下了;项目指令文件仍会发给模型。',
308
309
  'session.projectMemory.withheld.unreadable': '这次请求没有带上它:引擎的能力声明没读到,所以不知道它是否支持「别读项目指令文件」这项设置,而不认识它的引擎会拒掉整个请求,所以先扣下了;项目指令文件仍会发给模型。',
@@ -584,6 +585,8 @@ const ZH = {
584
585
  'notice.wayOut.switchModel': '模型服务此刻无法处理这个请求 —— 请换一个模型试试',
585
586
  'notice.wayOut.wait': '模型服务仍在处理这个请求 —— 请稍等片刻后重试',
586
587
  'notice.wayOut.fixRequest': '模型服务拒绝了这个请求 —— 请修改请求后再发送;原样重发不会有变化',
588
+ 'notice.askUnresolvable.remedy.approver': '出路:接一个能答这类请求的审批人,或让已接的审批人可达,然后重试',
589
+ 'notice.askUnresolvable.remedy.permissionMode': '另一条出路(须本部署允许):{mode} 权限模式会不经人作答就放行这类请求,每一次这样放行都会标在它所放行的那次工具调用上',
587
590
  'rules.refusal.sentence.one': '权限:有 1 条规则不会被执行 —— {list}',
588
591
  'rules.refusal.sentence.other': '权限:有 {count} 条规则不会被执行 —— {list}',
589
592
  'rules.refusal.item': '{rule}({reason})',
@@ -780,6 +783,7 @@ const ZH = {
780
783
  'rules.match.host': '网站域名匹配(单个主机)',
781
784
  'rules.match.subdomain': '网站域名匹配(该域名下的每个主机)',
782
785
  'rules.match.pattern': '命令模式匹配(命令里带星号)',
786
+ 'rules.match.tool': '整个工具匹配(这个工具的每一次调用)',
783
787
  'rules.match.unreported': '没有报告匹配形式',
784
788
  'rules.match.unknown': '这个版本不认识的匹配形式',
785
789
  'model.tier.blurb.ultra': '预留在 max 之上 —— 等更强的模型出现时再绑定',
@@ -1048,6 +1052,7 @@ const ZH = {
1048
1052
  'config.mods.loader.failedNoReason': '{name} 装载失败',
1049
1053
  'config.mods.refusal.by': '被 {by} 拒绝',
1050
1054
  'config.mods.rewrite.resultInPlace': '由 {by} 代替工具作答',
1055
+ 'config.mods.rewrite.inputBy': '参数在放行前被 {by} 改过',
1051
1056
  };
1052
1057
  export const ZH_MESSAGES = Object.freeze(ZH);
1053
1058
  export const TERM_SLOTS = Object.freeze({
package/dist/index.d.ts CHANGED
@@ -50,6 +50,7 @@ export * from './memoryOriginCapability.js';
50
50
  export * from './memoryEntriesWire.js';
51
51
  export * from './memoryVerbsWire.js';
52
52
  export * from './deviceExecutorManagementCapability.js';
53
+ export * from './credentialPlaneCapability.js';
53
54
  export * from './mcpReconnect.js';
54
55
  export * from './hitl/parkExpiryJudgements.js';
55
56
  export * from './usageAnalytics.js';
@@ -118,7 +119,7 @@ export { stripSystemReminderBlocks, unwrapSystemReminder } from './systemReminde
118
119
  export { findSystemReminderOpenTag, type SystemReminderOpenTagSpan } from './systemReminderTag.js';
119
120
  export { ACTIVE_RUN_BUSY_ERROR_CODE, APPROVAL_EXPIRED, ASK_GONE, asModelFallbackReason, CAPABILITY_IMAGE_INDEX_REQUIRED, CAPABILITY_K8S_LANE_REQUIRED, CAPABILITY_OPERATOR_PRINCIPALS_REQUIRED, CAPABILITY_SELF_ORCHESTRATION_REQUIRED, CONFIG_AGENT_UNKNOWN_TOOL, CONFIG_DELEGATION_ENTRY_CAPS, CONFIG_IMAGE_INVALID, CONFIG_LEGACY_TOOL_NAME, CONFIG_LIMIT_INVALID, CONFIG_LIMIT_UNKNOWN_KEY, CONFIG_MCP_SERVER_NAME_COLLISION, CONFIG_MEMORY_PROJECT_KEY_SPELLING, CONFIG_MEMORY_WRITE_SCOPE_MISMATCH, CONFIG_OUTPUT_STYLE_INVALID, CONFIG_TOOL_FACE_CONTROL, CONFLICT_IDEMPOTENCY_PAYLOAD_MISMATCH, CORRUPT_SESSION_ERROR_CODE, DECIDE_CLAIM_LOST, DECIDE_GATE_MOVED, DECIDE_NOT_PARKED, DECIDE_PARK_MOVED_CODES, DECIDE_ROW_UNREVIVABLE, DECIDE_WORKFLOW_HOST_UNKNOWN, DECIDE_WORKFLOW_LANE_CODES, DECIDE_WORKFLOW_PARK_FORKED, DECIDE_WORKFLOW_PARKS_UNREADABLE, DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED, DELEGATION_CAP_CODES, DELEGATION_CONCURRENCY_CAP, DELEGATION_SESSION_CAP, delegationCapDispositionOf, DRAINING_ERROR_CODE, ENGINE_STOP_REASONS, engineStopReasonToCc, ENV_LIFETIME_EXPIRED, FLEET_LEASE_UNAVAILABLE, GATE_PARKED_ERROR_CODE, idempotencyPayloadMismatchContent, isConfigRefusalCode, isCorruptSessionCode, isDecideParkMovedCode, isDecideRowUnrevivableCode, isDelegationCapCode, isIdempotencyPayloadMismatchCode, isInterruptedToolEndCode, isLimitsExceededCode, isRewindFamilyCode, isRulesRefusalCode, isStatusDerivedCoarseCode, isWorkflowParkRefusalCode, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, MCP_SERVER_REVOKED, MCP_TOOL_DECLARATION_CHANGED, MCP_TOOL_LISTING_UNREACHED, MODEL_FALLBACK_INHERIT_NO_TIER_BINDING, operatorGateRefusalContent, OUTPUT_INVALID, PARKED_RESUME_STARTUP_FAILED, PROMPT_ASSEMBLED_ROLE_REFUSED, REQUEST_AUTONOMY_LANE_REFUSED, RESUME_AT_ERROR_CODE_PREFIX, RESUME_CONTEXT_UNAVAILABLE, RESUME_ENV_FAILED, RESUME_PLACEMENT_MISMATCH, RESUME_POLICY_FOLD_CODE, RESUME_PREFLIGHT_REJECTED, RESUME_REOPEN_CODES, RESUME_RETRY_LATER_CODES, RESUME_TOOL_CONTRACT_MISMATCH, RESUME_TOOL_UNAVAILABLE, RESUME_USAGE_WINDOW_EXHAUSTED, REWIND_ERROR_CODE_PREFIXES, RUN_ORPHANED, RUN_STALLED, runDeathVerdictNoteOf, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, SCENARIO_NOT_ALLOWED_ERROR_CODE, STREAM_MAX_DURATION, TOOL_END_INTERRUPTED_NEVER_STARTED, TOOL_END_INTERRUPTED_OUTCOME_UNKNOWN, USAGE_WINDOW_EXHAUSTED, USER_ATTACHMENT_INVALID_ERROR_CODE, USER_INVOKED_SKILL_UNKNOWN_ERROR_CODE, WORKFLOW_PARK_REFUSAL_CODES, } from './engineErrorCodes.js';
120
121
  export type { DelegationCapDisposition, ModelFallbackReason, OperatorGateRefusal, RunDeathVerdictCode, } from './engineErrorCodes.js';
121
- export { imageInvalidFailureNoteOf, prepareRefusalCodeOf, prepareRefusalNoteOf, type PrepareRefusalCode, type PrepareRefusalNoteFacts } from './prepareRefusal.js';
122
+ export { prepareRefusalCodeOf, prepareRefusalNoteOf, type PrepareRefusalCode, type PrepareRefusalNoteFacts } from './prepareRefusal.js';
122
123
  export * from './agentsWireCaps.js';
123
124
  export { engineToolDirectoryOf } from './engineToolDirectory.js';
124
125
  export type { EngineToolDirectory, EngineToolDirectorySource } from './engineToolDirectory.js';
@@ -360,13 +361,16 @@ export { BACKGROUND_HANDOFF_ABORT_REASON, handoffInteractiveRun, handedOffRunsOf
360
361
  export type { BackgroundHandoffRequest, BackgroundHandoffOutcome, BackgroundRun, BackgroundRunSettlement, HandedOffRunRow, HandedOffRunsReading, } from './sessionBackgroundHandoff.js';
361
362
  export { listDevices, readSessionBinding, rebindSession, reconcileRebindOutcome, rebindProvesRequestNotApplied } from './deviceRebind.js';
362
363
  export { issueEnrollToken, enrollDevice, revokeDevice, deviceIdentityMismatchOf, deviceIdentityMismatchLine, deviceRegistrationOutcomeLine } from './deviceRebind.js';
363
- export type { DeviceSummary, DeviceListResult, DeviceBinding, DeviceSessionBinding, DeviceRebindRequest, DeviceRevokeRequest, DeviceRebindResult, DeviceEnrollToken, DeviceEnrollRequest, DeviceEnrollResult, DeviceRevokeResult, } from '@sema-agent/sdk';
364
- export type { DeviceListVerb, DeviceSessionBindingVerb, DeviceRebindVerb, DeviceRosterRow, DeviceBindingReading, DeviceRefused, DeviceLaneAbsent, DeviceTransport, DeviceUnreadable, DeviceUnarmed, DeviceListOutcome, DeviceSessionBindingOutcome, DeviceRebindInput, DeviceRebindUnconfirmed, DeviceRebindOutcome, DeviceRebindReconcileVerdict, DeviceIssueEnrollTokenVerb, DeviceEnrollVerb, DeviceRevokeVerb, DeviceEnrollOptions, DeviceRateLimited, DeviceEnrollTokenOutcome, DeviceEnrollOutcome, DeviceRevokeOutcome, DeviceRegistrationVerb, DeviceIdentityMismatch, } from './deviceRebind.js';
364
+ export type { DeviceSummary, DeviceListResult, DeviceRebindRequest, DeviceRevokeRequest, DeviceRebindResult, DeviceEnrollToken, DeviceEnrollRequest, DeviceEnrollResult, DeviceRevokeResult, } from '@sema-agent/sdk';
365
+ export type { ExecutionPlacementRole } from './executionPlacementWords.js';
366
+ export type { DeviceListVerb, SessionExecutionPlacementVerb, DeviceFaceUnsupported, DeviceRebindVerb, DeviceRosterRow, DeviceBindingReading, DeviceRefused, DeviceLaneAbsent, DeviceTransport, DeviceUnreadable, DeviceUnarmed, DeviceListOutcome, DeviceSessionBindingOutcome, DeviceRebindInput, DeviceRebindUnconfirmed, DeviceRebindOutcome, DeviceRebindReconcileVerdict, DeviceIssueEnrollTokenVerb, DeviceEnrollVerb, DeviceRevokeVerb, DeviceEnrollOptions, DeviceRateLimited, DeviceEnrollTokenOutcome, DeviceEnrollOutcome, DeviceRevokeOutcome, DeviceRegistrationVerb, DeviceIdentityMismatch, } from './deviceRebind.js';
365
367
  export { resolveEngineEnvSourcing, engineEnvView } from './engineEnvSourcing.js';
366
368
  export type { EngineEnvView, EngineEnvGroupDecl, EngineEnvSourcingInput, EngineEnvTouchedKey, EngineEnvGroupReading, EngineEnvKeyReason, EngineEnvSourcingVerdict, } from './engineEnvSourcing.js';
367
369
  export * from './compensations.js';
368
370
  export * from './request/printNotification.js';
369
371
  export * from './seatContract.js';
372
+ export { sessionRowTagOf, sessionRowPatchRefusalOf } from './sessionRowTag.js';
373
+ export type { SessionRowCurrentReading, SessionRowPatchRefusal } from './sessionRowTag.js';
370
374
  export { mcpToolTogglesToExcludeTools } from './mcpToolToggles.js';
371
375
  export type { McpToolToggleKey, McpMountedServers } from './mcpToolToggles.js';
372
376
  export { readThinkingLatch, writeThinkingLatch, thinkingLatchView, thinkingLatchSentence, thinkingLatchRowWordOf, readSeatThinkingLatch } from './thinkingLatch.js';
@@ -403,7 +407,7 @@ export * from './env/uiLanguage.js';
403
407
  export { EN_MESSAGES, type MessageKey } from './i18n/messages.en.js';
404
408
  export { ZH_MESSAGES } from './i18n/messages.zh.js';
405
409
  export { createMissLedger, createTranslator, DATA_FACE_LANGUAGE, msg, renderMessage, translate, uiMissLedger, type MessageParam, type MessageParams, type MessageRef, type MissLedger, type Translator, } from './i18n/translate.js';
406
- export type { PendingCheckpoint, RuleSuggestion } from '@sema-agent/sdk';
410
+ export type { PendingCheckpoint } from '@sema-agent/sdk';
407
411
  export * from './ruleRemovalConsequence.js';
408
412
  export { engineCredentialRequirementOf } from './engineCredentialRequirement.js';
409
413
  export type { EngineProbeAnswer, EngineCredentialNeed } from './engineCredentialRequirement.js';
package/dist/index.js CHANGED
@@ -41,6 +41,7 @@ export * from './memoryOriginCapability.js';
41
41
  export * from './memoryEntriesWire.js';
42
42
  export * from './memoryVerbsWire.js';
43
43
  export * from './deviceExecutorManagementCapability.js';
44
+ export * from './credentialPlaneCapability.js';
44
45
  export * from './mcpReconnect.js';
45
46
  export * from './hitl/parkExpiryJudgements.js';
46
47
  export * from './usageAnalytics.js';
@@ -99,7 +100,7 @@ export * from './classifierVerdictWire.js';
99
100
  export { stripSystemReminderBlocks, unwrapSystemReminder } from './systemReminderTag.js';
100
101
  export { findSystemReminderOpenTag } from './systemReminderTag.js';
101
102
  export { ACTIVE_RUN_BUSY_ERROR_CODE, APPROVAL_EXPIRED, ASK_GONE, asModelFallbackReason, CAPABILITY_IMAGE_INDEX_REQUIRED, CAPABILITY_K8S_LANE_REQUIRED, CAPABILITY_OPERATOR_PRINCIPALS_REQUIRED, CAPABILITY_SELF_ORCHESTRATION_REQUIRED, CONFIG_AGENT_UNKNOWN_TOOL, CONFIG_DELEGATION_ENTRY_CAPS, CONFIG_IMAGE_INVALID, CONFIG_LEGACY_TOOL_NAME, CONFIG_LIMIT_INVALID, CONFIG_LIMIT_UNKNOWN_KEY, CONFIG_MCP_SERVER_NAME_COLLISION, CONFIG_MEMORY_PROJECT_KEY_SPELLING, CONFIG_MEMORY_WRITE_SCOPE_MISMATCH, CONFIG_OUTPUT_STYLE_INVALID, CONFIG_TOOL_FACE_CONTROL, CONFLICT_IDEMPOTENCY_PAYLOAD_MISMATCH, CORRUPT_SESSION_ERROR_CODE, DECIDE_CLAIM_LOST, DECIDE_GATE_MOVED, DECIDE_NOT_PARKED, DECIDE_PARK_MOVED_CODES, DECIDE_ROW_UNREVIVABLE, DECIDE_WORKFLOW_HOST_UNKNOWN, DECIDE_WORKFLOW_LANE_CODES, DECIDE_WORKFLOW_PARK_FORKED, DECIDE_WORKFLOW_PARKS_UNREADABLE, DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED, DELEGATION_CAP_CODES, DELEGATION_CONCURRENCY_CAP, DELEGATION_SESSION_CAP, delegationCapDispositionOf, DRAINING_ERROR_CODE, ENGINE_STOP_REASONS, engineStopReasonToCc, ENV_LIFETIME_EXPIRED, FLEET_LEASE_UNAVAILABLE, GATE_PARKED_ERROR_CODE, idempotencyPayloadMismatchContent, isConfigRefusalCode, isCorruptSessionCode, isDecideParkMovedCode, isDecideRowUnrevivableCode, isDelegationCapCode, isIdempotencyPayloadMismatchCode, isInterruptedToolEndCode, isLimitsExceededCode, isRewindFamilyCode, isRulesRefusalCode, isStatusDerivedCoarseCode, isWorkflowParkRefusalCode, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, MCP_SERVER_REVOKED, MCP_TOOL_DECLARATION_CHANGED, MCP_TOOL_LISTING_UNREACHED, MODEL_FALLBACK_INHERIT_NO_TIER_BINDING, operatorGateRefusalContent, OUTPUT_INVALID, PARKED_RESUME_STARTUP_FAILED, PROMPT_ASSEMBLED_ROLE_REFUSED, REQUEST_AUTONOMY_LANE_REFUSED, RESUME_AT_ERROR_CODE_PREFIX, RESUME_CONTEXT_UNAVAILABLE, RESUME_ENV_FAILED, RESUME_PLACEMENT_MISMATCH, RESUME_POLICY_FOLD_CODE, RESUME_PREFLIGHT_REJECTED, RESUME_REOPEN_CODES, RESUME_RETRY_LATER_CODES, RESUME_TOOL_CONTRACT_MISMATCH, RESUME_TOOL_UNAVAILABLE, RESUME_USAGE_WINDOW_EXHAUSTED, REWIND_ERROR_CODE_PREFIXES, RUN_ORPHANED, RUN_STALLED, runDeathVerdictNoteOf, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, SCENARIO_NOT_ALLOWED_ERROR_CODE, STREAM_MAX_DURATION, TOOL_END_INTERRUPTED_NEVER_STARTED, TOOL_END_INTERRUPTED_OUTCOME_UNKNOWN, USAGE_WINDOW_EXHAUSTED, USER_ATTACHMENT_INVALID_ERROR_CODE, USER_INVOKED_SKILL_UNKNOWN_ERROR_CODE, WORKFLOW_PARK_REFUSAL_CODES, } from './engineErrorCodes.js';
102
- export { imageInvalidFailureNoteOf, prepareRefusalCodeOf, prepareRefusalNoteOf } from './prepareRefusal.js';
103
+ export { prepareRefusalCodeOf, prepareRefusalNoteOf } from './prepareRefusal.js';
103
104
  export * from './agentsWireCaps.js';
104
105
  export { engineToolDirectoryOf } from './engineToolDirectory.js';
105
106
  export * from './attachmentsWireCaps.js';
@@ -298,6 +299,7 @@ export { resolveEngineEnvSourcing, engineEnvView } from './engineEnvSourcing.js'
298
299
  export * from './compensations.js';
299
300
  export * from './request/printNotification.js';
300
301
  export * from './seatContract.js';
302
+ export { sessionRowTagOf, sessionRowPatchRefusalOf } from './sessionRowTag.js';
301
303
  export { mcpToolTogglesToExcludeTools } from './mcpToolToggles.js';
302
304
  export { readThinkingLatch, writeThinkingLatch, thinkingLatchView, thinkingLatchSentence, thinkingLatchRowWordOf, readSeatThinkingLatch } from './thinkingLatch.js';
303
305
  export { devicesFaceOf, devicesWritesAllowed, devicesFaceDetail } from './devicesFace.js';
@@ -16,6 +16,7 @@ export declare function inheritEnvWithheldNotice(withheld: InheritEnvWithheld, l
16
16
  export interface InheritEnvRefusalDetail {
17
17
  readonly code: string;
18
18
  readonly field?: 'inheritEnv';
19
+ readonly reason?: string;
19
20
  }
20
21
  export declare function inheritEnvRefusalFromError(err: unknown, sentRequest: TaskRequestLike | undefined): InheritEnvRefusalDetail | null;
21
22
  export declare function inheritEnvRefusalContent(detail: InheritEnvRefusalDetail, lang?: UiLanguage): string;
@@ -1,6 +1,6 @@
1
1
  import { msg, renderMessage } from './i18n/translate.js';
2
2
  import { INHERIT_ENV_WORDS, isInheritEnvWord } from './request/taskRequest.js';
3
- import { readRefusalNamedFields } from './wireFailureShape.js';
3
+ import { readRefusalNamedFields, readRefusalSlots } from './wireFailureShape.js';
4
4
  import { engineVersionTier } from './supportFloor.js';
5
5
  import { guardedRead, readOwnDataValue } from './ownKey.js';
6
6
  const EMPTY_DECLARATION = Object.freeze({ field: Object.freeze({}) });
@@ -47,7 +47,8 @@ function readGuarded(o, key) {
47
47
  }
48
48
  export function inheritEnvRefusalFromError(err, sentRequest) {
49
49
  try {
50
- if (readGuarded(sentRequest, 'inheritEnv') !== 'all')
50
+ const sent = readGuarded(sentRequest, 'inheritEnv');
51
+ if (sent === undefined)
51
52
  return null;
52
53
  if (readGuarded(err, 'errorCode') !== FIELD_INVALID)
53
54
  return null;
@@ -55,9 +56,11 @@ export function inheritEnvRefusalFromError(err, sentRequest) {
55
56
  return null;
56
57
  const named = readRefusalNamedFields(err);
57
58
  if (named.length === 0)
58
- return Object.freeze({ code: FIELD_INVALID });
59
- if (named.includes(INHERIT_ENV_FIELD))
60
- return Object.freeze({ code: FIELD_INVALID, field: INHERIT_ENV_FIELD });
59
+ return sent === 'all' ? Object.freeze({ code: FIELD_INVALID }) : null;
60
+ if (named.includes(INHERIT_ENV_FIELD)) {
61
+ const reason = guardedRead(() => readRefusalSlots(err, ['reason']).reason.word);
62
+ return Object.freeze({ code: FIELD_INVALID, field: INHERIT_ENV_FIELD, ...(typeof reason === 'string' && reason.length > 0 ? { reason } : {}) });
63
+ }
61
64
  return null;
62
65
  }
63
66
  catch {
@@ -19,14 +19,16 @@ export const isPlainRecord = (v) => {
19
19
  return true;
20
20
  if (typeof proto !== 'object')
21
21
  return false;
22
- if (!Object.prototype.hasOwnProperty.call(proto, 'constructor'))
22
+ const ctorDesc = Object.getOwnPropertyDescriptor(proto, 'constructor');
23
+ if (ctorDesc === undefined || !Object.hasOwn(ctorDesc, 'value'))
23
24
  return false;
24
- const ctor = proto.constructor;
25
+ const ctor = ctorDesc.value;
25
26
  if (typeof ctor !== 'function')
26
27
  return false;
27
28
  if (Function.prototype.toString.call(ctor) !== Function.prototype.toString.call(Object))
28
29
  return false;
29
- return ctor.prototype === proto;
30
+ const protoDesc = Object.getOwnPropertyDescriptor(ctor, 'prototype');
31
+ return protoDesc !== undefined && Object.hasOwn(protoDesc, 'value') && protoDesc.value === proto;
30
32
  };
31
33
  export const materializeJsonFaithful = (v, path, seen = new Set(), opts = {}) => {
32
34
  const guard = opts.guard;
@@ -1,4 +1,5 @@
1
1
  import type { WiringManifestMcpEntryView } from './adapter/downstream/eventToSdkMessage.js';
2
+ import { type McpAuthorizationView } from './mcpLiveness.js';
2
3
  export type McpEngineLegLiveness = {
3
4
  kind: 'unobserved';
4
5
  } | {
@@ -24,6 +25,8 @@ export type McpEngineLegConnection = {
24
25
  errorCode?: string;
25
26
  delivered?: string;
26
27
  httpStatus?: number;
28
+ authorization?: McpAuthorizationView;
29
+ authorizationUnreadable?: true;
27
30
  } | {
28
31
  state: 'not_connected';
29
32
  cause: 'skipped' | 'not_listed';