@sema-agent/client-core 0.105.0 → 0.107.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 (152) hide show
  1. package/CHANGELOG.md +301 -0
  2. package/README.md +40 -21
  3. package/dist/adapt/arms.js +10 -1
  4. package/dist/adapter/activeRunSelfHeal.d.ts +21 -2
  5. package/dist/adapter/activeRunSelfHeal.js +129 -28
  6. package/dist/adapter/downstream/eventToSdkMessage.d.ts +0 -5
  7. package/dist/adapter/downstream/eventToSdkMessage.js +20 -19
  8. package/dist/adapter/downstream/terminalToSdkResult.js +2 -3
  9. package/dist/adapter/downstream/wiringManifestView.d.ts +1 -3
  10. package/dist/adapter/downstream/wiringManifestView.js +0 -1
  11. package/dist/adapter/runStream.js +3 -4
  12. package/dist/approvalReachWire.d.ts +1 -0
  13. package/dist/approvalReachWire.js +4 -1
  14. package/dist/approvalSeat.d.ts +21 -0
  15. package/dist/approvalSeat.js +73 -0
  16. package/dist/assistantInbox.d.ts +2 -0
  17. package/dist/assistantInbox.js +3 -0
  18. package/dist/checkpointRowVerdict.d.ts +29 -0
  19. package/dist/checkpointRowVerdict.js +98 -0
  20. package/dist/coreValuePorts.d.ts +12 -1
  21. package/dist/coreValuePorts.js +10 -0
  22. package/dist/decideFailureNote.js +3 -1
  23. package/dist/decideReceipt.d.ts +9 -0
  24. package/dist/decideReceipt.js +29 -1
  25. package/dist/declared/supportFloorDeclared.js +2 -2
  26. package/dist/deviceRebind.d.ts +7 -0
  27. package/dist/deviceRebind.js +39 -5
  28. package/dist/displayUntrusted.d.ts +5 -3
  29. package/dist/displayUntrusted.js +50 -41
  30. package/dist/engineAddress.d.ts +3 -0
  31. package/dist/engineAddress.js +25 -0
  32. package/dist/engineDirectory.js +9 -17
  33. package/dist/engineErrorCodes.d.ts +8 -0
  34. package/dist/engineErrorCodes.js +8 -0
  35. package/dist/engineNoticeCodes.d.ts +38 -3
  36. package/dist/engineNoticeCodes.js +167 -11
  37. package/dist/engineRowRef.js +1 -1
  38. package/dist/errorSupplementRoles.js +4 -1
  39. package/dist/eventLeg.d.ts +2 -2
  40. package/dist/eventLeg.js +2 -1
  41. package/dist/executionLaneCapability.js +3 -2
  42. package/dist/executionLaneWords.d.ts +1 -0
  43. package/dist/executionLaneWords.js +3 -0
  44. package/dist/fleet/fleetProjection.js +26 -5
  45. package/dist/generated/engineFactTables.d.ts +2 -1
  46. package/dist/generated/engineFactTables.js +3 -1
  47. package/dist/generated/engineNoticeTables.js +28 -7
  48. package/dist/generated/sdkFactTables.d.ts +3 -0
  49. package/dist/generated/sdkFactTables.js +15 -0
  50. package/dist/generated/settingsSchemaFns.d.ts +11 -0
  51. package/dist/generated/settingsSchemaFns.js +2 -1
  52. package/dist/generated/settingsSchemaSafetyMergeSpec.js +1 -1
  53. package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -1
  54. package/dist/generated/settingsSchemaSettingsSources.js +22 -2
  55. package/dist/hitl/approvalLiveFace.d.ts +17 -0
  56. package/dist/hitl/approvalLiveFace.js +35 -0
  57. package/dist/hitl/approvalQueueRow.d.ts +21 -0
  58. package/dist/hitl/approvalQueueRow.js +69 -0
  59. package/dist/hitl/approvalResolution.d.ts +5 -1
  60. package/dist/hitl/approvalResolution.js +18 -1
  61. package/dist/hitl/approvalsFeed.d.ts +5 -4
  62. package/dist/hitl/approvalsFeed.js +39 -6
  63. package/dist/hitl/askParkRowRouting.d.ts +4 -3
  64. package/dist/hitl/askParkRowRouting.js +27 -3
  65. package/dist/hitl/automaticAnswerVerdict.js +13 -10
  66. package/dist/hitl/crashConverged.d.ts +5 -1
  67. package/dist/hitl/decisionConflict.js +2 -1
  68. package/dist/hitl/decisionRefusal.js +1 -1
  69. package/dist/hitl/decisionSend.d.ts +3 -0
  70. package/dist/hitl/decisionSend.js +32 -6
  71. package/dist/hitl/frameRouter.js +4 -5
  72. package/dist/hitl/hitlBridge.d.ts +6 -2
  73. package/dist/hitl/hitlBridge.js +53 -7
  74. package/dist/hitl/livePendingAsk.d.ts +5 -0
  75. package/dist/hitl/livePendingAsk.js +10 -3
  76. package/dist/hitl/parkOwnership.js +4 -5
  77. package/dist/hitl/parkResolver.js +9 -5
  78. package/dist/hitl/parkRowBirthWait.d.ts +7 -0
  79. package/dist/hitl/parkRowBirthWait.js +1 -1
  80. package/dist/hitl/parkRowDelegation.d.ts +6 -0
  81. package/dist/hitl/parkRowDelegation.js +33 -0
  82. package/dist/hitl/persistedRulesWire.d.ts +15 -3
  83. package/dist/hitl/persistedRulesWire.js +102 -20
  84. package/dist/hitl/planReviewCard.d.ts +2 -0
  85. package/dist/hitl/planReviewCard.js +21 -0
  86. package/dist/hitl/planReviewWire.d.ts +2 -2
  87. package/dist/hitl/planReviewWire.js +105 -38
  88. package/dist/hitl/sessionAllowRoute.d.ts +7 -0
  89. package/dist/hitl/sessionAllowRoute.js +49 -0
  90. package/dist/hitl/sessionPolicyWire.d.ts +1 -7
  91. package/dist/hitl/sessionPolicyWire.js +3 -43
  92. package/dist/hitl/standingRows.js +10 -10
  93. package/dist/hitl/subagentSource.d.ts +1 -0
  94. package/dist/hitl/subagentSource.js +13 -0
  95. package/dist/hitl/toolApprovalWire.d.ts +3 -2
  96. package/dist/hitl/toolApprovalWire.js +100 -44
  97. package/dist/hostSettingsSource.d.ts +4 -1
  98. package/dist/hostSettingsSource.js +11 -6
  99. package/dist/hostTurnSettings.d.ts +4 -5
  100. package/dist/hostTurnSettings.js +80 -19
  101. package/dist/i18n/messages.en.d.ts +41 -12
  102. package/dist/i18n/messages.en.js +42 -13
  103. package/dist/i18n/messages.zh.js +45 -13
  104. package/dist/index.d.ts +22 -2
  105. package/dist/index.js +12 -2
  106. package/dist/injectionLaneNotice.js +2 -1
  107. package/dist/liveInitToolFace.js +0 -1
  108. package/dist/liveModelCatalog.d.ts +15 -0
  109. package/dist/liveModelCatalog.js +40 -0
  110. package/dist/mcpWireCaps.js +1 -1
  111. package/dist/modelCapabilityProbe.js +66 -33
  112. package/dist/noticePresentation.js +2 -0
  113. package/dist/ownKey.d.ts +0 -1
  114. package/dist/ownKey.js +0 -2
  115. package/dist/permissionsDeclaration.d.ts +2 -2
  116. package/dist/permissionsDeclaration.js +12 -14
  117. package/dist/projectSeed.d.ts +39 -0
  118. package/dist/projectSeed.js +80 -0
  119. package/dist/promptDelivery.js +1 -1
  120. package/dist/replayBody.d.ts +7 -6
  121. package/dist/replayBody.js +62 -7
  122. package/dist/request/taskRequest.js +3 -4
  123. package/dist/ruleCompileVerdict.d.ts +0 -2
  124. package/dist/ruleCompileVerdict.js +0 -31
  125. package/dist/ruleRefusalSentence.js +0 -3
  126. package/dist/runReattachPolicy.d.ts +3 -0
  127. package/dist/runReattachPolicy.js +15 -2
  128. package/dist/runTerminal.js +30 -8
  129. package/dist/sandboxWire.d.ts +0 -3
  130. package/dist/sandboxWire.js +0 -9
  131. package/dist/sdkWireTransit.d.ts +1 -1
  132. package/dist/seam.d.ts +14 -7
  133. package/dist/seam.js +12 -0
  134. package/dist/seatContract.d.ts +58 -7
  135. package/dist/seatContract.js +135 -4
  136. package/dist/serverSupportRange.d.ts +18 -0
  137. package/dist/serverSupportRange.js +25 -0
  138. package/dist/sessionEngine.d.ts +156 -0
  139. package/dist/sessionEngine.js +464 -0
  140. package/dist/sessionMap.d.ts +11 -1
  141. package/dist/sessionMap.js +35 -9
  142. package/dist/sessionMemorySync.d.ts +31 -0
  143. package/dist/sessionMemorySync.js +95 -0
  144. package/dist/sessionRowTag.d.ts +4 -0
  145. package/dist/sessionRowTag.js +18 -0
  146. package/dist/settingsLayerAdmission.d.ts +1 -0
  147. package/dist/settingsLayerAdmission.js +4 -1
  148. package/dist/toolResult.js +1 -1
  149. package/dist/wireRefusalCopy.d.ts +6 -1
  150. package/dist/wireRefusalCopy.js +9 -7
  151. package/docs/INTEGRATION-CLIENTS.md +1393 -18
  152. package/package.json +5 -5
@@ -5,7 +5,7 @@ import { terminalPartsOfObserved, readRunCostFacts, terminalToSdkResult, TOOL_IN
5
5
  import { terminalRunIdOf, terminalUuidOf } from '../engineRowRef.js';
6
6
  import { publishSubagentContentEvent, subagentContentEventOf } from '../subagentContentStore.js';
7
7
  import { OUTPUT_INVALID, activeRunBusyCarrierOf, classifyActiveRunBusy, isCorruptSessionCode, isLimitsExceededCode } from '../engineErrorCodes.js';
8
- import { doneResultView, isReplayedTerminal } from '../replayBody.js';
8
+ import { doneResultView, isReplayedTerminal, terminalLayerOf } from '../replayBody.js';
9
9
  import { carriesAnswerText, guardedRead, readFrameStringKey } from '../ownKey.js';
10
10
  import { ccErrorOfProviderStatus } from '../providerRejection.js';
11
11
  import { corruptSessionContent } from '../corruptSessionCopy.js';
@@ -206,8 +206,7 @@ function terminalOwnerOfStream(ctx, busy, busyHandle, runId) {
206
206
  };
207
207
  }
208
208
  function engineResultOf(result) {
209
- const v = doneResultView(result);
210
- return v.replay ? (v.engine ?? result) : result;
209
+ return doneResultView(result).body;
211
210
  }
212
211
  function engineSessionIdOf(result) {
213
212
  const v = result?.sessionId;
@@ -371,7 +370,7 @@ function apiErrorTerminalFromFacts(x, facts) {
371
370
  return none();
372
371
  if (type === 'failed')
373
372
  return { carrier: mintToolHistoryCarrier(nonEmptyStr(ownDataBit(x, 'errorCode')), undefined, nonEmptyStr(ownDataBit(x, 'errorMessage'))), detail: undefined };
374
- const result = type === 'done' ? plainObjectOf(engineResultOf(ownDataBit(x, 'result'))) : x;
373
+ const result = type === 'done' ? plainObjectOf(terminalLayerOf(ownDataBit(x, 'result'))) : x;
375
374
  if (result === undefined)
376
375
  return none();
377
376
  const snap = ownTerminalSnapshot(result);
@@ -1,5 +1,6 @@
1
1
  import { CORE_APPROVAL_REACH } from './generated/engineFactTables.js';
2
2
  export type ApprovalReachWord = (typeof CORE_APPROVAL_REACH)[number];
3
+ export declare function isApprovalReachWord(v: {} | null | undefined): v is ApprovalReachWord;
3
4
  export declare function refuseBadApprovalReach(v: unknown, who: string): void;
4
5
  export type ApprovalReachWithheldCause = 'not_reported' | 'unsupported' | 'unprobed' | 'unreadable';
5
6
  export type ApprovalReachDeclaration = {
@@ -3,6 +3,9 @@ import { engineCapState, engineCapsSettled } from './engineCapsCache.js';
3
3
  const KEY = 'approvalReach';
4
4
  const APPROVAL_REACH_NONE = 'none';
5
5
  const WORDS = new Set(CORE_APPROVAL_REACH);
6
+ export function isApprovalReachWord(v) {
7
+ return typeof v === 'string' && WORDS.has(v);
8
+ }
6
9
  const shapeOf = (v) => {
7
10
  try {
8
11
  return v === null ? 'null' : Array.isArray(v) ? 'typeof=object / array' : typeof v === 'string' ? `typeof=string(长 ${v.length})` : `typeof=${typeof v}`;
@@ -14,7 +17,7 @@ const shapeOf = (v) => {
14
17
  export function refuseBadApprovalReach(v, who) {
15
18
  if (v === undefined || v === null)
16
19
  return;
17
- if (typeof v === 'string' && WORDS.has(v))
20
+ if (isApprovalReachWord(v))
18
21
  return;
19
22
  throw new TypeError(`${who}: approvalReach 只接受引擎闭集里的词(${[...CORE_APPROVAL_REACH].join(' / ')})或缺席(undefined/null)—— 收到 ${shapeOf(v)}。` +
20
23
  '这一位是「这条运行上没有人能答审批」的声明,值只经片段口 approvalReachDeclaration 铸;本层若把坏值折成缺席,这一发会照常发审批卡而声明方不会知道。' +
@@ -0,0 +1,21 @@
1
+ import { type ApprovalReachWord } from './approvalReachWire.js';
2
+ import { type SubmissionIdentity } from './request/submissionIdentity.js';
3
+ export declare const APPROVAL_SEAT_STATES: readonly ["seated", "unseated", "unknown"];
4
+ export type ApprovalSeatState = (typeof APPROVAL_SEAT_STATES)[number];
5
+ export declare const APPROVAL_SEAT_BASES: Readonly<{
6
+ seated: readonly ["interactive_lane", "host_seat"];
7
+ unseated: readonly ["engine_declared_none", "host_declined"];
8
+ unknown: readonly ["identity_unreadable", "word_unreadable", "fact_unreadable", "word_unmapped", "lane_without_approvals", "seat_unstated"];
9
+ }>;
10
+ export type ApprovalSeatReading = {
11
+ readonly [S in ApprovalSeatState]: {
12
+ readonly state: S;
13
+ readonly basis: (typeof APPROVAL_SEAT_BASES)[S][number];
14
+ };
15
+ }[ApprovalSeatState];
16
+ export interface ApprovalSeatInput {
17
+ readonly identity: SubmissionIdentity;
18
+ readonly approvalReach?: ApprovalReachWord | null | undefined;
19
+ readonly approverReachable?: boolean | null | undefined;
20
+ }
21
+ export declare function approvalSeatOf(input: ApprovalSeatInput): ApprovalSeatReading;
@@ -0,0 +1,73 @@
1
+ import { isApprovalReachWord } from './approvalReachWire.js';
2
+ import { requestLaneOf } from './request/submissionIdentity.js';
3
+ import { ownDataField } from './ownKey.js';
4
+ export const APPROVAL_SEAT_STATES = Object.freeze(['seated', 'unseated', 'unknown']);
5
+ export const APPROVAL_SEAT_BASES = Object.freeze({
6
+ seated: Object.freeze(['interactive_lane', 'host_seat']),
7
+ unseated: Object.freeze(['engine_declared_none', 'host_declined']),
8
+ unknown: Object.freeze(['identity_unreadable', 'word_unreadable', 'fact_unreadable', 'word_unmapped', 'lane_without_approvals', 'seat_unstated']),
9
+ });
10
+ const mint = (state, basis) => Object.freeze({ state, basis });
11
+ const READINGS = Object.freeze({
12
+ seated: Object.freeze({ interactive_lane: mint('seated', 'interactive_lane'), host_seat: mint('seated', 'host_seat') }),
13
+ unseated: Object.freeze({ engine_declared_none: mint('unseated', 'engine_declared_none'), host_declined: mint('unseated', 'host_declined') }),
14
+ unknown: Object.freeze({
15
+ identity_unreadable: mint('unknown', 'identity_unreadable'),
16
+ word_unreadable: mint('unknown', 'word_unreadable'),
17
+ fact_unreadable: mint('unknown', 'fact_unreadable'),
18
+ word_unmapped: mint('unknown', 'word_unmapped'),
19
+ lane_without_approvals: mint('unknown', 'lane_without_approvals'),
20
+ seat_unstated: mint('unknown', 'seat_unstated'),
21
+ }),
22
+ });
23
+ const SEAT_OF_WORD = Object.freeze({
24
+ none: READINGS.unseated.engine_declared_none,
25
+ });
26
+ const ABSENT = Symbol('absent');
27
+ const UNREADABLE = Symbol('unreadable');
28
+ const slotOf = (carrier, key) => {
29
+ try {
30
+ const v = ownDataField(carrier, key);
31
+ return v === undefined ? ABSENT : v;
32
+ }
33
+ catch {
34
+ return UNREADABLE;
35
+ }
36
+ };
37
+ const isCarrier = (x) => {
38
+ try {
39
+ return typeof x === 'object' && x !== null && !Array.isArray(x);
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ };
45
+ export function approvalSeatOf(input) {
46
+ const R = READINGS.unknown;
47
+ if (!isCarrier(input))
48
+ return R.identity_unreadable;
49
+ const identity = slotOf(input, 'identity');
50
+ const word = slotOf(input, 'approvalReach');
51
+ const declared = slotOf(input, 'approverReachable');
52
+ const lane = identity === ABSENT || identity === UNREADABLE || !isCarrier(identity) ? undefined : requestLaneOf(identity);
53
+ if (lane === undefined)
54
+ return R.identity_unreadable;
55
+ const wordIn = word === ABSENT || word === null ? undefined : word;
56
+ if (word === UNREADABLE || (wordIn !== undefined && !isApprovalReachWord(wordIn)))
57
+ return R.word_unreadable;
58
+ const reachable = declared === ABSENT || declared === null ? undefined : declared;
59
+ if (declared === UNREADABLE || (reachable !== undefined && reachable !== true && reachable !== false))
60
+ return R.fact_unreadable;
61
+ if (wordIn !== undefined && !Object.hasOwn(SEAT_OF_WORD, wordIn))
62
+ return R.word_unmapped;
63
+ switch (lane) {
64
+ case 'interactive':
65
+ return READINGS.seated.interactive_lane;
66
+ case 'utility':
67
+ return R.lane_without_approvals;
68
+ case 'print':
69
+ if (wordIn !== undefined)
70
+ return SEAT_OF_WORD[wordIn];
71
+ return reachable === true ? READINGS.seated.host_seat : reachable === false ? READINGS.unseated.host_declined : R.seat_unstated;
72
+ }
73
+ }
@@ -1,4 +1,5 @@
1
1
  import type { AgentClient } from '@sema-agent/sdk';
2
+ import { type CheckpointRowVerdictReading } from './checkpointRowVerdict.js';
2
3
  export type AssistantInboxVerb = Pick<AgentClient['assistant'], 'inbox'>;
3
4
  export interface AssistantInboxEntry {
4
5
  readonly sessionId: string;
@@ -13,6 +14,7 @@ export interface AssistantInboxEntry {
13
14
  readonly requiresRealApproval?: true;
14
15
  readonly mandated?: true;
15
16
  readonly hasBidiControls?: true;
17
+ readonly rowVerdict?: CheckpointRowVerdictReading;
16
18
  }
17
19
  export type AssistantInboxUnavailableReason = 'unauthorized' | 'unreadable' | 'failed';
18
20
  export type AssistantInboxReading = {
@@ -1,3 +1,4 @@
1
+ import { checkpointRowVerdictOf } from './checkpointRowVerdict.js';
1
2
  import { errCodes } from './controlRouter.js';
2
3
  import { readOwnDataValue } from './ownKey.js';
3
4
  import { isReadCredentialRefusal } from './readCredentialRefusal.js';
@@ -41,6 +42,7 @@ function entryOf(raw) {
41
42
  const objective = nonEmptyString(own(raw, 'objective'));
42
43
  const input = own(raw, 'input');
43
44
  const inputPreview = typeof input === 'string' && input !== '' ? input : undefined;
45
+ const rowVerdict = checkpointRowVerdictOf(raw);
44
46
  return Object.freeze({
45
47
  sessionId,
46
48
  ...(scope !== undefined ? { scope } : {}),
@@ -54,6 +56,7 @@ function entryOf(raw) {
54
56
  ...(own(raw, 'requiresRealApproval') === true ? { requiresRealApproval: true } : {}),
55
57
  ...(own(raw, 'mandated') === true ? { mandated: true } : {}),
56
58
  ...(own(raw, 'hasBidiControls') === true ? { hasBidiControls: true } : {}),
59
+ ...(rowVerdict !== undefined ? { rowVerdict } : {}),
57
60
  });
58
61
  }
59
62
  function isArraySafely(v) {
@@ -0,0 +1,29 @@
1
+ export type CheckpointRowVerdictReading = {
2
+ readonly kind: 'ok';
3
+ } | {
4
+ readonly kind: 'lacking' | 'damaged';
5
+ readonly code: string;
6
+ readonly reason?: string;
7
+ readonly requires?: readonly string[];
8
+ readonly sentence: string;
9
+ } | {
10
+ readonly kind: 'unknown';
11
+ readonly word: string;
12
+ readonly sentence?: string;
13
+ } | {
14
+ readonly kind: 'unreadable';
15
+ };
16
+ export declare function checkpointRowVerdictOf(row: object | null | undefined): CheckpointRowVerdictReading | undefined;
17
+ export type CheckpointRequirementsDamagedReading = {
18
+ readonly kind: 'judge_tripped';
19
+ readonly thrownName: string;
20
+ } | {
21
+ readonly kind: 'row_mismatch';
22
+ };
23
+ export declare function checkpointRequirementsDamagedOf(failure: object | null | undefined): CheckpointRequirementsDamagedReading | undefined;
24
+ export type CheckpointRowBar = Exclude<CheckpointRowVerdictReading, {
25
+ readonly kind: 'ok';
26
+ }>;
27
+ export declare function checkpointRowBarOf(row: object | null | undefined): CheckpointRowBar | undefined;
28
+ export declare const CHECKPOINT_ROW_BAR_SENTENCE: string;
29
+ export declare function checkpointRowBarSentence(bar: CheckpointRowBar): string;
@@ -0,0 +1,98 @@
1
+ import { readErrorString, slotReadOf } from './wireFailureShape.js';
2
+ import { msg, renderMessage } from './i18n/translate.js';
3
+ const UNREADABLE = Object.freeze({ kind: 'unreadable' });
4
+ const OK = Object.freeze({ kind: 'ok' });
5
+ function ownNonEmptyString(o, key) {
6
+ const r = slotReadOf(o, key);
7
+ return r.presence === 'present' && typeof r.value === 'string' && r.value !== '' ? r.value : undefined;
8
+ }
9
+ function ownWordList(o, key) {
10
+ const r = slotReadOf(o, key);
11
+ if (r.presence !== 'present')
12
+ return undefined;
13
+ const v = r.value;
14
+ try {
15
+ if (typeof v !== 'object' || v === null || !Array.isArray(v))
16
+ return undefined;
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ const len = slotReadOf(v, 'length');
22
+ if (len.presence !== 'present' || typeof len.value !== 'number' || !Number.isSafeInteger(len.value) || len.value < 0)
23
+ return undefined;
24
+ const out = [];
25
+ for (let i = 0; i < len.value; i++) {
26
+ const w = ownNonEmptyString(v, String(i));
27
+ if (w === undefined)
28
+ return undefined;
29
+ out.push(w);
30
+ }
31
+ return Object.freeze(out);
32
+ }
33
+ export function checkpointRowVerdictOf(row) {
34
+ try {
35
+ if (typeof row !== 'object' || row === null)
36
+ return undefined;
37
+ const slot = slotReadOf(row, 'rowVerdict');
38
+ if (slot.presence === 'absent')
39
+ return undefined;
40
+ if (slot.presence !== 'present')
41
+ return UNREADABLE;
42
+ const v = slot.value;
43
+ if (v === undefined)
44
+ return undefined;
45
+ if (typeof v !== 'object' || v === null)
46
+ return UNREADABLE;
47
+ if (Array.isArray(v))
48
+ return UNREADABLE;
49
+ const kind = slotReadOf(v, 'kind');
50
+ if (kind.presence !== 'present' || typeof kind.value !== 'string' || kind.value === '')
51
+ return UNREADABLE;
52
+ const word = kind.value;
53
+ if (word === 'ok')
54
+ return OK;
55
+ const sentence = ownNonEmptyString(v, 'sentence');
56
+ if (word === 'lacking' || word === 'damaged') {
57
+ const code = ownNonEmptyString(v, 'code');
58
+ if (code === undefined || sentence === undefined)
59
+ return UNREADABLE;
60
+ const reason = ownNonEmptyString(v, 'reason');
61
+ const requires = ownWordList(v, 'requires');
62
+ return Object.freeze({
63
+ kind: word,
64
+ code,
65
+ ...(reason !== undefined ? { reason } : {}),
66
+ ...(requires !== undefined ? { requires } : {}),
67
+ sentence,
68
+ });
69
+ }
70
+ return Object.freeze({ kind: 'unknown', word, ...(sentence !== undefined ? { sentence } : {}) });
71
+ }
72
+ catch {
73
+ return UNREADABLE;
74
+ }
75
+ }
76
+ const ROW_MISMATCH = Object.freeze({ kind: 'row_mismatch' });
77
+ const REQUIREMENTS_DAMAGED = 'requirements_damaged';
78
+ export function checkpointRequirementsDamagedOf(failure) {
79
+ try {
80
+ if ((typeof failure !== 'object' && typeof failure !== 'function') || failure === null)
81
+ return undefined;
82
+ if (readErrorString(failure, 'reason') !== REQUIREMENTS_DAMAGED)
83
+ return undefined;
84
+ const thrownName = readErrorString(failure, 'thrownName');
85
+ return thrownName !== undefined && thrownName !== '' ? Object.freeze({ kind: 'judge_tripped', thrownName }) : ROW_MISMATCH;
86
+ }
87
+ catch {
88
+ return undefined;
89
+ }
90
+ }
91
+ export function checkpointRowBarOf(row) {
92
+ const v = checkpointRowVerdictOf(row);
93
+ return v === undefined || v.kind === 'ok' ? undefined : v;
94
+ }
95
+ export const CHECKPOINT_ROW_BAR_SENTENCE = renderMessage(msg('approval.rowUnresumable.fallback'));
96
+ export function checkpointRowBarSentence(bar) {
97
+ return bar.kind !== 'unreadable' && typeof bar.sentence === 'string' && bar.sentence !== '' ? bar.sentence : CHECKPOINT_ROW_BAR_SENTENCE;
98
+ }
@@ -151,8 +151,17 @@ export interface CoreValuePorts {
151
151
  readToolFaces(declared: {} | null | undefined): McpToolFacesReadView;
152
152
  ruleNameCovers: (ruleName: string, toolName: string) => boolean;
153
153
  IMPORTED_SETTINGS_LAYERS: readonly ['userSettings', 'projectSettings', 'localSettings'];
154
+ runParkedOf(run: WorkflowRunParkedInputView): boolean;
155
+ parkedAgentsOf(agents: ReadonlyArray<WorkflowAgentStatusView>): WorkflowAgentStatusView[];
154
156
  }
155
- export declare const CORE_VALUE_PORT_NAMES: readonly ["resolveAutonomousLoopPrompt", "loosenReasons", "combinePolicies", "createAllowDenyPolicy", "MCP_NAMESPACE", "protocolOf", "ruleToolGrammarOf", "validatePermissionRules", "mintNamespacePrefix", "compileAllowList", "routeKeyOf", "joinRequestUrl", "resolveRouteCredential", "adjudicateModelRoute", "routePairingStatus", "judgeRuleToolName", "readRuleEntry", "readMcpToolAxes", "ANTHROPIC_DEFAULT_BASE_URL", "readToolFaces", "ruleNameCovers", "IMPORTED_SETTINGS_LAYERS"];
157
+ export interface WorkflowAgentStatusView {
158
+ readonly status: string;
159
+ }
160
+ export interface WorkflowRunParkedInputView {
161
+ readonly status: string;
162
+ readonly agents: ReadonlyArray<WorkflowAgentStatusView>;
163
+ }
164
+ export declare const CORE_VALUE_PORT_NAMES: readonly ["resolveAutonomousLoopPrompt", "loosenReasons", "combinePolicies", "createAllowDenyPolicy", "MCP_NAMESPACE", "protocolOf", "ruleToolGrammarOf", "validatePermissionRules", "mintNamespacePrefix", "compileAllowList", "routeKeyOf", "joinRequestUrl", "resolveRouteCredential", "adjudicateModelRoute", "routePairingStatus", "judgeRuleToolName", "readRuleEntry", "readMcpToolAxes", "ANTHROPIC_DEFAULT_BASE_URL", "readToolFaces", "ruleNameCovers", "IMPORTED_SETTINGS_LAYERS", "runParkedOf", "parkedAgentsOf"];
156
165
  export type CoreValuePortName = (typeof CORE_VALUE_PORT_NAMES)[number];
157
166
  export declare function installCoreValuePorts(ports: Partial<CoreValuePorts> | null): () => void;
158
167
  export declare function hasCoreValuePorts(): boolean;
@@ -184,3 +193,5 @@ export declare function anthropicDefaultBaseUrl(): string | undefined;
184
193
  export declare function readToolFaces(declared: {} | null | undefined): McpToolFacesReadView | undefined;
185
194
  export declare function ruleNameCovers(ruleName: string, toolName: string): boolean | undefined;
186
195
  export declare function importedSettingsLayers(): CoreValuePorts['IMPORTED_SETTINGS_LAYERS'] | undefined;
196
+ export declare function runParkedOf(run: WorkflowRunParkedInputView): boolean | undefined;
197
+ export declare function parkedAgentsOf(agents: ReadonlyArray<WorkflowAgentStatusView>): WorkflowAgentStatusView[] | undefined;
@@ -21,6 +21,8 @@ export const CORE_VALUE_PORT_NAMES = Object.freeze([
21
21
  'readToolFaces',
22
22
  'ruleNameCovers',
23
23
  'IMPORTED_SETTINGS_LAYERS',
24
+ 'runParkedOf',
25
+ 'parkedAgentsOf',
24
26
  ]);
25
27
  let installed = null;
26
28
  export function installCoreValuePorts(ports) {
@@ -127,3 +129,11 @@ export function ruleNameCovers(ruleName, toolName) {
127
129
  export function importedSettingsLayers() {
128
130
  return port('IMPORTED_SETTINGS_LAYERS');
129
131
  }
132
+ export function runParkedOf(run) {
133
+ const fn = port('runParkedOf');
134
+ return fn === undefined ? undefined : fn(run);
135
+ }
136
+ export function parkedAgentsOf(agents) {
137
+ const fn = port('parkedAgentsOf');
138
+ return fn === undefined ? undefined : fn(agents);
139
+ }
@@ -1,6 +1,6 @@
1
1
  import { corruptStoredRowContent, corruptStoredRowWhere, scenarioDenyFromError, scenarioNotAllowedContent } from './wireErrorTriage.js';
2
2
  import { checkpointUnsupportedVersionContent, checkpointUnsupportedVersionFromError, parkedResumeStartupContent, parkedResumeStartupFromError, resumePolicyBlockContent, resumePolicyBlockFromError, } from './resumeRefusalCopy.js';
3
- import { askGoneContent, askGoneFromError, decideParkMovedContent, decideParkMovedFromError } from './decideReceipt.js';
3
+ import { askGoneContent, askGoneFromError, decideParkMovedContent, decideParkMovedFromError, decideRequiresBindingContent, decideRequiresBindingFromError } from './decideReceipt.js';
4
4
  import { fieldLimitRefusalContent, fieldLimitRefusalFromError } from './wireRefusalCopy.js';
5
5
  import { DECISION_ANSWER_INVALID_CONTENT, decisionConflictOf, decisionGrantChangedContent } from './hitl/decisionConflict.js';
6
6
  export function decideFailureNote(err, decision) {
@@ -12,6 +12,7 @@ export function decideFailureNote(err, decision) {
12
12
  const scenario = scenarioDenyFromError(err);
13
13
  const unsupported = checkpointUnsupportedVersionFromError(err);
14
14
  const gone = askGoneFromError(err);
15
+ const missingBinding = decideRequiresBindingFromError(err);
15
16
  const conflict = decisionConflictOf(err);
16
17
  const answerInvalid = conflict === 'answer_invalid';
17
18
  return ((where === undefined ? '' : ` — ${corruptStoredRowContent(where)}`) +
@@ -22,6 +23,7 @@ export function decideFailureNote(err, decision) {
22
23
  (moved === null ? '' : ` — ${decideParkMovedContent(moved)}`) +
23
24
  (unsupported === null ? '' : ` — ${checkpointUnsupportedVersionContent(unsupported)}`) +
24
25
  (gone === null ? '' : ` — ${askGoneContent(gone)}`) +
26
+ (missingBinding === null ? '' : ` — ${decideRequiresBindingContent(missingBinding)}`) +
25
27
  (answerInvalid ? ` — ${DECISION_ANSWER_INVALID_CONTENT}` : '') +
26
28
  (conflict === 'grant_changed' ? ` — ${decisionGrantChangedContent()}` : ''));
27
29
  }
@@ -2,6 +2,8 @@ import { type GateOutcomeView } from './gateOutcome.js';
2
2
  import { type ResumeReopenDetail } from './hitl/suspendedReopen.js';
3
3
  import { type CrashConvergedRowReading } from './hitl/crashConverged.js';
4
4
  import type { AskRowEndingCause } from '@sema-agent/sdk';
5
+ import { SDK_DECIDE_BINDING_KEYS } from './generated/sdkFactTables.js';
6
+ import { type UiLanguage } from './env/uiLanguage.js';
5
7
  export interface DecideReceiptView {
6
8
  status?: string;
7
9
  taskId?: string;
@@ -31,6 +33,13 @@ export interface DecideParkMovedDetail {
31
33
  }
32
34
  export declare function decideParkMovedFromError(e: unknown): DecideParkMovedDetail | null;
33
35
  export declare function decideParkMovedContent(detail: Pick<DecideParkMovedDetail, 'code'>): string;
36
+ export type DecideBindingKey = (typeof SDK_DECIDE_BINDING_KEYS)[number];
37
+ export interface DecideRequiresBindingDetail {
38
+ readonly code: string;
39
+ readonly missingKeys?: readonly DecideBindingKey[];
40
+ }
41
+ export declare function decideRequiresBindingFromError(e: {} | null | undefined): DecideRequiresBindingDetail | null;
42
+ export declare function decideRequiresBindingContent(_detail?: DecideRequiresBindingDetail, lang?: UiLanguage | (string & {})): string;
34
43
  export interface AskGoneDetail {
35
44
  code: 'gone.ask';
36
45
  state?: 'VOID' | 'DENIED';
@@ -1,11 +1,14 @@
1
1
  import { gateOutcomeOf } from './gateOutcome.js';
2
2
  import { readOwnDataValue } from './ownKey.js';
3
3
  import { resumeReopenFromError } from './hitl/suspendedReopen.js';
4
- import { ASK_GONE, DECIDE_CLAIM_LOST, CONFLICT_NOT_RESUMABLE, GATE_NOT_TOOL_APPROVAL, DECIDE_GATE_MOVED, DECIDE_NOT_PARKED, DECIDE_WORKFLOW_HOST_UNKNOWN, DECIDE_WORKFLOW_LANE_CODES, DECIDE_WORKFLOW_PARK_FORKED, DECIDE_WORKFLOW_PARKS_UNREADABLE, DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED, isDecideParkMovedCode, } from './engineErrorCodes.js';
4
+ import { ASK_GONE, DECIDE_CLAIM_LOST, CONFLICT_NOT_RESUMABLE, GATE_NOT_TOOL_APPROVAL, DECIDE_GATE_MOVED, DECIDE_NOT_PARKED, DECIDE_REQUIRES_BINDING, DECIDE_WORKFLOW_HOST_UNKNOWN, DECIDE_WORKFLOW_LANE_CODES, DECIDE_WORKFLOW_PARK_FORKED, DECIDE_WORKFLOW_PARKS_UNREADABLE, DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED, isDecideParkMovedCode, } from './engineErrorCodes.js';
5
5
  import { effectiveWireErrorCode } from './wireErrorTriage.js';
6
6
  import { isSlotCarrier, readErrorString, readErrorStrictStringList, readThrownExtra } from './wireFailureShape.js';
7
7
  import { isCrashConvergedCause } from './hitl/crashConverged.js';
8
8
  import { askRowEndingCauseFor } from './hitl/approvalEndingCause.js';
9
+ import { SDK_DECIDE_BINDING_KEYS } from './generated/sdkFactTables.js';
10
+ import { isUiLanguage } from './env/uiLanguage.js';
11
+ import { msg, renderMessage } from './i18n/translate.js';
9
12
  const STATUS_RESUMING = 'resuming';
10
13
  function str(v) {
11
14
  return typeof v === 'string' && v.length > 0 ? v : undefined;
@@ -136,6 +139,31 @@ export function decideParkMovedContent(detail) {
136
139
  const extra = code === DECIDE_CLAIM_LOST ? '; if this approval is still listed, wait a little before deciding it again' : '';
137
140
  return `${what} · This decision was not applied — fetch the pending approvals again and decide from what is pending now${extra}`;
138
141
  }
142
+ const isDecideBindingKey = (v) => SDK_DECIDE_BINDING_KEYS.includes(v);
143
+ export function decideRequiresBindingFromError(e) {
144
+ try {
145
+ if (effectiveWireErrorCode(e) !== DECIDE_REQUIRES_BINDING)
146
+ return null;
147
+ const raw = readErrorStrictStringList(e, 'missingKeys');
148
+ const keys = [];
149
+ if (raw !== undefined) {
150
+ for (const k of raw) {
151
+ if (!isDecideBindingKey(k) || keys.includes(k)) {
152
+ keys.length = 0;
153
+ break;
154
+ }
155
+ keys.push(k);
156
+ }
157
+ }
158
+ return Object.freeze({ code: DECIDE_REQUIRES_BINDING, ...(keys.length > 0 ? { missingKeys: Object.freeze(keys) } : {}) });
159
+ }
160
+ catch {
161
+ return null;
162
+ }
163
+ }
164
+ export function decideRequiresBindingContent(_detail, lang) {
165
+ return renderMessage(msg('approval.decide.requiresBinding', { wayOut: msg('approval.decide.unboundWayOut') }), isUiLanguage(lang) ? lang : undefined);
166
+ }
139
167
  function askGoneRawCause(e) {
140
168
  let top;
141
169
  try {
@@ -1,5 +1,5 @@
1
1
  export const DECLARED_SUPPORT_FLOOR = Object.freeze({
2
- server: "7.129.1",
3
- core: "7.51.2",
2
+ server: "7.139.0",
3
+ core: "7.60.0",
4
4
  sdk: "23.1.0",
5
5
  });
@@ -95,6 +95,13 @@ export declare function listDevices(devices: DeviceListVerb | null | undefined,
95
95
  export declare function readSessionBinding(sessions: SessionExecutionPlacementVerb | null | undefined, rootSessionId: string, opts?: {
96
96
  readonly signal?: AbortSignal | undefined;
97
97
  }): Promise<DeviceSessionBindingOutcome>;
98
+ export interface SessionPlacementView {
99
+ readonly sessionId: string;
100
+ readonly executionLane?: string;
101
+ readonly onDevice: boolean;
102
+ readonly rev?: number;
103
+ }
104
+ export declare function foldSessionPlacement(held: SessionPlacementView | undefined, sessionId: string, body: {} | null | undefined): SessionPlacementView | undefined;
98
105
  export declare function rebindSession(devices: DeviceRebindVerb | null | undefined, req: DeviceRebindInput, opts?: {
99
106
  readonly signal?: AbortSignal | undefined;
100
107
  }): Promise<DeviceRebindOutcome>;
@@ -140,6 +140,17 @@ function placementReadFailureOf(e) {
140
140
  return v.status !== undefined ? refusedOf(v.status, v.code, e) : transportOf(v);
141
141
  }
142
142
  const isPlacementRole = (v) => typeof v === 'string' && EXECUTION_PLACEMENT_ROLES.includes(v);
143
+ function placementBodyOf(body) {
144
+ const role = own(body, 'role');
145
+ if (!isPlacementRole(role))
146
+ return { role: undefined, lane: undefined, device: null };
147
+ if (role !== 'writer')
148
+ return { role, lane: undefined, device: null };
149
+ const lane = own(body, 'lane');
150
+ if (typeof lane !== 'string' || lane === '')
151
+ return { role, lane: undefined, device: null };
152
+ return { role, lane, device: lane === EXECUTION_PLACEMENT_DEVICE_LANE ? bindingOf(own(body, 'device')) : null };
153
+ }
143
154
  export async function readSessionBinding(sessions, rootSessionId, opts) {
144
155
  if (typeof rootSessionId !== 'string' || rootSessionId === '') {
145
156
  return { kind: 'refused', status: 0, errorCode: 'request.id_invalid', message: 'the session id to read the execution placement of must be a non-empty string — nothing was sent' };
@@ -154,24 +165,47 @@ export async function readSessionBinding(sessions, rootSessionId, opts) {
154
165
  catch (e) {
155
166
  return placementReadFailureOf(e);
156
167
  }
157
- const role = own(body, 'role');
158
- if (!isPlacementRole(role)) {
168
+ const { role, lane, device: bound } = placementBodyOf(body);
169
+ if (role === undefined) {
159
170
  return { kind: 'unreadable', why: 'the execution placement it returned names no role this client knows (absent / writer / mirror / forking) — refusing to read it as "not bound"' };
160
171
  }
161
172
  if (role !== 'writer')
162
173
  return { kind: 'unbound', role };
163
- const lane = own(body, 'lane');
164
- if (typeof lane !== 'string' || lane === '') {
174
+ if (lane === undefined) {
165
175
  return { kind: 'unreadable', why: "the writer's execution lane in the execution placement is missing or not a word — refusing to guess whether a device is bound" };
166
176
  }
167
177
  if (lane !== EXECUTION_PLACEMENT_DEVICE_LANE)
168
178
  return { kind: 'unbound', role };
169
- const bound = bindingOf(own(body, 'device'));
170
179
  if (bound === null) {
171
180
  return { kind: 'unreadable', why: 'the session is written on the device lane but the execution placement names no readable device (deviceId + rev) — the device is unknown, not unbound' };
172
181
  }
173
182
  return { kind: 'ok', rootSessionId, boundDevice: bound };
174
183
  }
184
+ export function foldSessionPlacement(held, sessionId, body) {
185
+ try {
186
+ if (typeof sessionId !== 'string' || sessionId === '')
187
+ return held;
188
+ const heldOk = held !== null && typeof held === 'object';
189
+ if (heldOk && own(held, 'sessionId') !== sessionId)
190
+ return held;
191
+ const { role, lane, device } = placementBodyOf(body);
192
+ if (role === undefined)
193
+ return held;
194
+ const heldRev = heldOk ? nonNegInt(own(held, 'rev')) : undefined;
195
+ const rev = device?.rev;
196
+ if (heldRev !== undefined && (rev === undefined || rev < heldRev))
197
+ return held;
198
+ return Object.freeze({
199
+ sessionId,
200
+ ...(lane !== undefined ? { executionLane: lane } : {}),
201
+ onDevice: device !== null,
202
+ ...(rev !== undefined ? { rev } : {}),
203
+ });
204
+ }
205
+ catch {
206
+ return held;
207
+ }
208
+ }
175
209
  function rebindFailureOf(e) {
176
210
  const v = atMostOnceVerdictOf(e);
177
211
  const { status, code } = v;
@@ -2,6 +2,7 @@ export declare const REDACTION_MARKER_PREFIX = "\u00ABredacted";
2
2
  export declare function looksLikeKnownSecret(s: string): boolean;
3
3
  export declare function isDiagnosticValueWord(value: string): boolean;
4
4
  export declare function percentBoundaryReadingOf(text: string): string;
5
+ type BlankNet = 0 | 1 | 2;
5
6
  interface WashStats {
6
7
  passes: number;
7
8
  capped: boolean;
@@ -13,7 +14,7 @@ export interface DisplayFace {
13
14
  readonly unsafe: RegExp | null;
14
15
  readonly fold: boolean;
15
16
  readonly mark: DisplayMark;
16
- readonly keepBlanks?: boolean;
17
+ readonly blanks?: BlankNet;
17
18
  readonly keepCrlf?: boolean;
18
19
  }
19
20
  export declare function applyDisplayFace(text: string, face: DisplayFace): string;
@@ -26,8 +27,8 @@ export interface DisplayUntrustedOptions {
26
27
  readonly keepLayout?: boolean | 'crlf';
27
28
  readonly mark?: DisplayMark;
28
29
  readonly max?: number;
29
- readonly escapeBackslashes?: boolean;
30
- readonly blanks?: boolean | 'fillers';
30
+ readonly escapeBackslashes?: boolean | 'auto';
31
+ readonly blanks?: boolean | 'except-ideographic';
31
32
  }
32
33
  export interface DisplayMarkSpan {
33
34
  readonly start: number;
@@ -37,6 +38,7 @@ export interface DisplayMarkSpan {
37
38
  export interface DisplayUntrustedMarked {
38
39
  readonly text: string;
39
40
  readonly marks: readonly DisplayMarkSpan[];
41
+ readonly exact: boolean;
40
42
  }
41
43
  export declare const DISPLAY_DECISION_BODY: Readonly<DisplayUntrustedOptions>;
42
44
  export declare const ESCAPE_FACE: DisplayFace;