@sema-agent/client-core 0.104.1 → 0.106.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 (175) hide show
  1. package/CHANGELOG.md +310 -0
  2. package/README.md +36 -14
  3. package/dist/adapt/arms.js +23 -6
  4. package/dist/adapter/activeRunSelfHeal.d.ts +14 -2
  5. package/dist/adapter/activeRunSelfHeal.js +90 -12
  6. package/dist/adapter/downstream/eventToSdkMessage.d.ts +0 -5
  7. package/dist/adapter/downstream/eventToSdkMessage.js +24 -23
  8. package/dist/adapter/downstream/terminalToSdkResult.js +2 -3
  9. package/dist/adapter/downstream/wiringManifestView.d.ts +7 -3
  10. package/dist/adapter/downstream/wiringManifestView.js +25 -1
  11. package/dist/adapter/runStream.js +8 -5
  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 +23 -0
  19. package/dist/checkpointRowVerdict.js +89 -0
  20. package/dist/cloudConfigWireCaps.js +3 -0
  21. package/dist/compensations.js +6 -6
  22. package/dist/coreValuePorts.d.ts +14 -1
  23. package/dist/coreValuePorts.js +14 -0
  24. package/dist/decideFailureNote.js +3 -1
  25. package/dist/decideReceipt.d.ts +9 -0
  26. package/dist/decideReceipt.js +29 -1
  27. package/dist/declared/supportFloorDeclared.js +2 -2
  28. package/dist/deviceRebind.d.ts +7 -0
  29. package/dist/deviceRebind.js +39 -5
  30. package/dist/displayUntrusted.d.ts +4 -2
  31. package/dist/displayUntrusted.js +45 -22
  32. package/dist/engineAddress.d.ts +3 -0
  33. package/dist/engineAddress.js +25 -0
  34. package/dist/engineDirectory.js +9 -17
  35. package/dist/engineErrorCodes.d.ts +8 -0
  36. package/dist/engineErrorCodes.js +8 -0
  37. package/dist/engineGenerationPort.d.ts +11 -2
  38. package/dist/engineGenerationPort.js +63 -9
  39. package/dist/engineHealthFacts.d.ts +5 -0
  40. package/dist/engineHealthFacts.js +11 -0
  41. package/dist/engineNoticeCodes.d.ts +26 -3
  42. package/dist/engineNoticeCodes.js +52 -7
  43. package/dist/engineRowRef.js +1 -1
  44. package/dist/errorSupplementRoles.js +2 -0
  45. package/dist/eventLeg.d.ts +3 -3
  46. package/dist/eventLeg.js +25 -4
  47. package/dist/fleet/fleetProjection.js +26 -5
  48. package/dist/generated/engineFactTables.d.ts +3 -1
  49. package/dist/generated/engineFactTables.js +4 -1
  50. package/dist/generated/engineNoticeTables.js +19 -4
  51. package/dist/generated/sdkFactTables.d.ts +5 -0
  52. package/dist/generated/sdkFactTables.js +24 -0
  53. package/dist/generated/settingsSchemaFns.d.ts +11 -0
  54. package/dist/generated/settingsSchemaFns.js +2 -1
  55. package/dist/generated/settingsSchemaSafetyMergeSpec.js +1 -1
  56. package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -1
  57. package/dist/generated/settingsSchemaSettingsSources.js +22 -2
  58. package/dist/headlessReconnectWire.js +31 -4
  59. package/dist/hitl/approvalLiveFace.d.ts +17 -0
  60. package/dist/hitl/approvalLiveFace.js +35 -0
  61. package/dist/hitl/approvalQueueRow.d.ts +21 -0
  62. package/dist/hitl/approvalQueueRow.js +69 -0
  63. package/dist/hitl/approvalsFeed.d.ts +5 -4
  64. package/dist/hitl/approvalsFeed.js +38 -6
  65. package/dist/hitl/askGateWire.js +26 -2
  66. package/dist/hitl/askParkRowRouting.d.ts +4 -3
  67. package/dist/hitl/askParkRowRouting.js +15 -3
  68. package/dist/hitl/automaticAnswerVerdict.js +13 -10
  69. package/dist/hitl/crashConverged.d.ts +5 -1
  70. package/dist/hitl/decisionConflict.js +2 -1
  71. package/dist/hitl/decisionRefusal.js +1 -1
  72. package/dist/hitl/decisionSend.d.ts +1 -0
  73. package/dist/hitl/decisionSend.js +14 -2
  74. package/dist/hitl/frameRouter.d.ts +4 -0
  75. package/dist/hitl/frameRouter.js +18 -5
  76. package/dist/hitl/gateIdentity.d.ts +1 -0
  77. package/dist/hitl/gateIdentity.js +3 -0
  78. package/dist/hitl/hitlBridge.d.ts +1 -1
  79. package/dist/hitl/hitlBridge.js +26 -5
  80. package/dist/hitl/livePendingAsk.d.ts +5 -0
  81. package/dist/hitl/livePendingAsk.js +6 -1
  82. package/dist/hitl/planReviewCard.d.ts +23 -0
  83. package/dist/hitl/planReviewCard.js +250 -0
  84. package/dist/hitl/planReviewWire.d.ts +39 -14
  85. package/dist/hitl/planReviewWire.js +450 -163
  86. package/dist/hitl/sessionAllowRoute.d.ts +2 -0
  87. package/dist/hitl/sessionAllowRoute.js +7 -0
  88. package/dist/hitl/sessionPolicyWire.d.ts +1 -7
  89. package/dist/hitl/sessionPolicyWire.js +3 -43
  90. package/dist/hitl/subagentSource.d.ts +1 -0
  91. package/dist/hitl/subagentSource.js +13 -0
  92. package/dist/hitl/toolApprovalWire.d.ts +3 -2
  93. package/dist/hitl/toolApprovalWire.js +79 -37
  94. package/dist/hostSettingsSource.d.ts +5 -2
  95. package/dist/hostSettingsSource.js +19 -10
  96. package/dist/hostTurnSettings.d.ts +5 -6
  97. package/dist/hostTurnSettings.js +106 -26
  98. package/dist/i18n/messages.en.d.ts +85 -12
  99. package/dist/i18n/messages.en.js +85 -12
  100. package/dist/i18n/messages.zh.js +88 -12
  101. package/dist/index.d.ts +35 -4
  102. package/dist/index.js +19 -2
  103. package/dist/liveInitToolFace.js +0 -1
  104. package/dist/liveModelCatalog.d.ts +15 -0
  105. package/dist/liveModelCatalog.js +40 -0
  106. package/dist/mcpTransportKindsCapability.d.ts +18 -0
  107. package/dist/mcpTransportKindsCapability.js +75 -0
  108. package/dist/mcpWireCaps.d.ts +4 -1
  109. package/dist/mcpWireCaps.js +25 -14
  110. package/dist/modelCapabilityProbe.js +66 -33
  111. package/dist/notifications.d.ts +9 -0
  112. package/dist/notifications.js +11 -2
  113. package/dist/ownKey.d.ts +4 -1
  114. package/dist/ownKey.js +8 -2
  115. package/dist/permissionModeWriteCapability.d.ts +13 -0
  116. package/dist/permissionModeWriteCapability.js +35 -0
  117. package/dist/permissionsAllowGrantCapability.d.ts +3 -0
  118. package/dist/permissionsAllowGrantCapability.js +26 -3
  119. package/dist/permissionsDeclaration.d.ts +25 -3
  120. package/dist/permissionsDeclaration.js +69 -41
  121. package/dist/planReviewCardFacts.d.ts +116 -0
  122. package/dist/planReviewCardFacts.js +469 -0
  123. package/dist/projectSeed.d.ts +39 -0
  124. package/dist/projectSeed.js +80 -0
  125. package/dist/promptDelivery.js +1 -1
  126. package/dist/reattachWindow.d.ts +8 -1
  127. package/dist/reattachWindow.js +44 -12
  128. package/dist/replayBody.d.ts +7 -6
  129. package/dist/replayBody.js +62 -7
  130. package/dist/request/taskRequest.js +3 -4
  131. package/dist/ruleCompileVerdict.d.ts +0 -2
  132. package/dist/ruleCompileVerdict.js +0 -31
  133. package/dist/ruleRefusalSentence.js +0 -3
  134. package/dist/runFollow.d.ts +30 -0
  135. package/dist/runFollow.js +117 -0
  136. package/dist/runLedgerSnapshot.d.ts +20 -0
  137. package/dist/runLedgerSnapshot.js +272 -0
  138. package/dist/runPermissionModeSwitch.d.ts +57 -0
  139. package/dist/runPermissionModeSwitch.js +135 -0
  140. package/dist/runReattachPolicy.d.ts +16 -5
  141. package/dist/runReattachPolicy.js +72 -24
  142. package/dist/runTerminal.js +30 -8
  143. package/dist/sandboxWire.d.ts +0 -3
  144. package/dist/sandboxWire.js +0 -9
  145. package/dist/seam.d.ts +17 -7
  146. package/dist/seam.js +13 -1
  147. package/dist/seatContract.d.ts +57 -7
  148. package/dist/seatContract.js +133 -3
  149. package/dist/serverSupportRange.d.ts +18 -0
  150. package/dist/serverSupportRange.js +25 -0
  151. package/dist/sessionEngine.d.ts +156 -0
  152. package/dist/sessionEngine.js +464 -0
  153. package/dist/sessionMap.d.ts +11 -1
  154. package/dist/sessionMap.js +35 -9
  155. package/dist/sessionMemoryErase.d.ts +1 -1
  156. package/dist/sessionMemoryErase.js +5 -0
  157. package/dist/sessionMemoryStatus.d.ts +27 -1
  158. package/dist/sessionMemoryStatus.js +117 -0
  159. package/dist/sessionMemorySync.d.ts +31 -0
  160. package/dist/sessionMemorySync.js +95 -0
  161. package/dist/sessionRowTag.d.ts +4 -0
  162. package/dist/sessionRowTag.js +18 -0
  163. package/dist/settingsLayerAdmission.d.ts +1 -0
  164. package/dist/settingsLayerAdmission.js +4 -1
  165. package/dist/sseIdleTriage.d.ts +3 -1
  166. package/dist/sseIdleTriage.js +19 -4
  167. package/dist/subagent/engineSubagentTail.js +2 -0
  168. package/dist/subagentContentStore.d.ts +3 -0
  169. package/dist/subagentContentStore.js +10 -1
  170. package/dist/toolResult.js +1 -1
  171. package/dist/turnFailurePresentation.d.ts +5 -2
  172. package/dist/turnFailurePresentation.js +12 -4
  173. package/dist/wireRefusalCopy.js +2 -6
  174. package/docs/INTEGRATION-CLIENTS.md +1507 -18
  175. package/package.json +5 -5
@@ -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,23 @@
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;
@@ -0,0 +1,89 @@
1
+ import { readErrorString, slotReadOf } from './wireFailureShape.js';
2
+ const UNREADABLE = Object.freeze({ kind: 'unreadable' });
3
+ const OK = Object.freeze({ kind: 'ok' });
4
+ function ownNonEmptyString(o, key) {
5
+ const r = slotReadOf(o, key);
6
+ return r.presence === 'present' && typeof r.value === 'string' && r.value !== '' ? r.value : undefined;
7
+ }
8
+ function ownWordList(o, key) {
9
+ const r = slotReadOf(o, key);
10
+ if (r.presence !== 'present')
11
+ return undefined;
12
+ const v = r.value;
13
+ try {
14
+ if (typeof v !== 'object' || v === null || !Array.isArray(v))
15
+ return undefined;
16
+ }
17
+ catch {
18
+ return undefined;
19
+ }
20
+ const len = slotReadOf(v, 'length');
21
+ if (len.presence !== 'present' || typeof len.value !== 'number' || !Number.isSafeInteger(len.value) || len.value < 0)
22
+ return undefined;
23
+ const out = [];
24
+ for (let i = 0; i < len.value; i++) {
25
+ const w = ownNonEmptyString(v, String(i));
26
+ if (w === undefined)
27
+ return undefined;
28
+ out.push(w);
29
+ }
30
+ return Object.freeze(out);
31
+ }
32
+ export function checkpointRowVerdictOf(row) {
33
+ try {
34
+ if (typeof row !== 'object' || row === null)
35
+ return undefined;
36
+ const slot = slotReadOf(row, 'rowVerdict');
37
+ if (slot.presence === 'absent')
38
+ return undefined;
39
+ if (slot.presence !== 'present')
40
+ return UNREADABLE;
41
+ const v = slot.value;
42
+ if (v === undefined)
43
+ return undefined;
44
+ if (typeof v !== 'object' || v === null)
45
+ return UNREADABLE;
46
+ if (Array.isArray(v))
47
+ return UNREADABLE;
48
+ const kind = slotReadOf(v, 'kind');
49
+ if (kind.presence !== 'present' || typeof kind.value !== 'string' || kind.value === '')
50
+ return UNREADABLE;
51
+ const word = kind.value;
52
+ if (word === 'ok')
53
+ return OK;
54
+ const sentence = ownNonEmptyString(v, 'sentence');
55
+ if (word === 'lacking' || word === 'damaged') {
56
+ const code = ownNonEmptyString(v, 'code');
57
+ if (code === undefined || sentence === undefined)
58
+ return UNREADABLE;
59
+ const reason = ownNonEmptyString(v, 'reason');
60
+ const requires = ownWordList(v, 'requires');
61
+ return Object.freeze({
62
+ kind: word,
63
+ code,
64
+ ...(reason !== undefined ? { reason } : {}),
65
+ ...(requires !== undefined ? { requires } : {}),
66
+ sentence,
67
+ });
68
+ }
69
+ return Object.freeze({ kind: 'unknown', word, ...(sentence !== undefined ? { sentence } : {}) });
70
+ }
71
+ catch {
72
+ return UNREADABLE;
73
+ }
74
+ }
75
+ const ROW_MISMATCH = Object.freeze({ kind: 'row_mismatch' });
76
+ const REQUIREMENTS_DAMAGED = 'requirements_damaged';
77
+ export function checkpointRequirementsDamagedOf(failure) {
78
+ try {
79
+ if ((typeof failure !== 'object' && typeof failure !== 'function') || failure === null)
80
+ return undefined;
81
+ if (readErrorString(failure, 'reason') !== REQUIREMENTS_DAMAGED)
82
+ return undefined;
83
+ const thrownName = readErrorString(failure, 'thrownName');
84
+ return thrownName !== undefined && thrownName !== '' ? Object.freeze({ kind: 'judge_tripped', thrownName }) : ROW_MISMATCH;
85
+ }
86
+ catch {
87
+ return undefined;
88
+ }
89
+ }
@@ -149,11 +149,13 @@ export function cloudMcpToSpecs(servers, env) {
149
149
  let elicitationDeclared;
150
150
  let allowDeclared;
151
151
  let startupDeclared;
152
+ let sessionMetaKeyDeclared;
152
153
  try {
153
154
  axesDeclared = s.toolAxes;
154
155
  elicitationDeclared = s.elicitation;
155
156
  allowDeclared = s.allowTools;
156
157
  startupDeclared = s.startupTimeoutMs;
158
+ sessionMetaKeyDeclared = s.sessionMetaKey;
157
159
  }
158
160
  catch {
159
161
  recordDrop(name, 'entry-unreadable');
@@ -202,6 +204,7 @@ export function cloudMcpToSpecs(servers, env) {
202
204
  ...(facesShipped !== undefined ? { toolFaces: facesShipped } : {}),
203
205
  ...(axesShipped !== undefined ? { toolAxes: axesShipped } : {}),
204
206
  ...(startupDeclared !== undefined ? { startupTimeoutMs: startupDeclared } : {}),
207
+ ...(sessionMetaKeyDeclared !== undefined ? { sessionMetaKey: sessionMetaKeyDeclared } : {}),
205
208
  });
206
209
  }
207
210
  return { specs, missingEnv: [...new Set(missingEnv)], droppedServers, degradedServers };
@@ -77,12 +77,12 @@ export const MIGRATED_COMPENSATIONS = [
77
77
  },
78
78
  {
79
79
  id: 'T2',
80
- what: '去重键客户端重算(`[external:]taskId:status[:seq]`)—— wire 上没有「这次完成的唯一 id」',
80
+ what: '渲染去重的身份 —— 自算键(`[external:]taskId:status[:seq]`)恒在;终态、非 external 且带完成 id 的通知再加一把 `completion:<id>`;只有完成键见过的同一次完成不渲第二行,其余义务照做',
81
81
  disposition: 'in-library',
82
- libraryHalf: 'notifications.ts taskNotificationDedupKey + taskNotificationDedupKeyFromWire(裸 wire 入口)',
82
+ libraryHalf: 'notifications.ts taskNotificationRenderKeys(身份全集,适配器渲染去重读它)+ taskNotificationDedupKey / taskNotificationDedupKeyFromWire(自算键;裸 wire 入口)',
83
83
  chromeArm: null,
84
84
  hostHalf: null,
85
- retireOn: 'RL-36',
85
+ retireOn: null,
86
86
  },
87
87
  {
88
88
  id: 'T3',
@@ -103,16 +103,16 @@ export const MIGRATED_COMPENSATIONS = [
103
103
  libraryHalf: 'toolResult.ts 终态轮询卡臂的预 seed + notifications.markEngineWorkflowNotified',
104
104
  chromeArm: null,
105
105
  hostHalf: null,
106
- retireOn: 'RL-38',
106
+ retireOn: null,
107
107
  },
108
108
  {
109
109
  id: 'T53',
110
- what: '同一次完成四通道扇出 ⇒ 四道去重(设计稿列为最贵 #4)',
110
+ what: '同一次完成四通道扇出 ⇒ 四道去重(四通道扇出里最贵的一道;第四道是队列撤单,不是去重)',
111
111
  disposition: 'in-library',
112
112
  libraryHalf: 'adapt.ts task_notification / workflow_complete 两臂的四道门(逐道说明见本行上方注释)',
113
113
  chromeArm: null,
114
114
  hostHalf: null,
115
- retireOn: 'RL-39',
115
+ retireOn: null,
116
116
  },
117
117
  {
118
118
  id: 'T49',
@@ -150,8 +150,18 @@ export interface CoreValuePorts {
150
150
  ANTHROPIC_DEFAULT_BASE_URL: string;
151
151
  readToolFaces(declared: {} | null | undefined): McpToolFacesReadView;
152
152
  ruleNameCovers: (ruleName: string, toolName: string) => boolean;
153
+ IMPORTED_SETTINGS_LAYERS: readonly ['userSettings', 'projectSettings', 'localSettings'];
154
+ runParkedOf(run: WorkflowRunParkedInputView): boolean;
155
+ parkedAgentsOf(agents: ReadonlyArray<WorkflowAgentStatusView>): WorkflowAgentStatusView[];
153
156
  }
154
- 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"];
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"];
155
165
  export type CoreValuePortName = (typeof CORE_VALUE_PORT_NAMES)[number];
156
166
  export declare function installCoreValuePorts(ports: Partial<CoreValuePorts> | null): () => void;
157
167
  export declare function hasCoreValuePorts(): boolean;
@@ -182,3 +192,6 @@ export declare function readMcpToolAxes(declared: {} | null | undefined): McpToo
182
192
  export declare function anthropicDefaultBaseUrl(): string | undefined;
183
193
  export declare function readToolFaces(declared: {} | null | undefined): McpToolFacesReadView | undefined;
184
194
  export declare function ruleNameCovers(ruleName: string, toolName: string): boolean | undefined;
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;
@@ -20,6 +20,9 @@ export const CORE_VALUE_PORT_NAMES = Object.freeze([
20
20
  'ANTHROPIC_DEFAULT_BASE_URL',
21
21
  'readToolFaces',
22
22
  'ruleNameCovers',
23
+ 'IMPORTED_SETTINGS_LAYERS',
24
+ 'runParkedOf',
25
+ 'parkedAgentsOf',
23
26
  ]);
24
27
  let installed = null;
25
28
  export function installCoreValuePorts(ports) {
@@ -123,3 +126,14 @@ export function ruleNameCovers(ruleName, toolName) {
123
126
  const fn = port('ruleNameCovers');
124
127
  return fn === undefined ? undefined : fn(ruleName, toolName);
125
128
  }
129
+ export function importedSettingsLayers() {
130
+ return port('IMPORTED_SETTINGS_LAYERS');
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'), 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;
@@ -14,6 +14,7 @@ export interface DisplayFace {
14
14
  readonly fold: boolean;
15
15
  readonly mark: DisplayMark;
16
16
  readonly keepBlanks?: boolean;
17
+ readonly keepCrlf?: boolean;
17
18
  }
18
19
  export declare function applyDisplayFace(text: string, face: DisplayFace): string;
19
20
  export interface DisplayUntrustedOptions {
@@ -22,11 +23,11 @@ export interface DisplayUntrustedOptions {
22
23
  readonly controls?: boolean;
23
24
  readonly bidi?: boolean;
24
25
  readonly foldLines?: boolean;
25
- readonly keepLayout?: boolean;
26
+ readonly keepLayout?: boolean | 'crlf';
26
27
  readonly mark?: DisplayMark;
27
28
  readonly max?: number;
28
29
  readonly escapeBackslashes?: boolean;
29
- readonly blanks?: boolean;
30
+ readonly blanks?: boolean | 'fillers';
30
31
  }
31
32
  export interface DisplayMarkSpan {
32
33
  readonly start: number;
@@ -37,6 +38,7 @@ export interface DisplayUntrustedMarked {
37
38
  readonly text: string;
38
39
  readonly marks: readonly DisplayMarkSpan[];
39
40
  }
41
+ export declare const DISPLAY_DECISION_BODY: Readonly<DisplayUntrustedOptions>;
40
42
  export declare const ESCAPE_FACE: DisplayFace;
41
43
  export declare const LABEL_FACE: DisplayFace;
42
44
  export declare const PEER_NAME_FACE: DisplayFace;