@sema-agent/client-core 0.105.0 → 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 (132) hide show
  1. package/CHANGELOG.md +220 -0
  2. package/README.md +26 -11
  3. package/dist/adapt/arms.js +10 -1
  4. package/dist/adapter/activeRunSelfHeal.d.ts +13 -2
  5. package/dist/adapter/activeRunSelfHeal.js +80 -7
  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 +23 -0
  19. package/dist/checkpointRowVerdict.js +89 -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/engineAddress.d.ts +3 -0
  29. package/dist/engineAddress.js +25 -0
  30. package/dist/engineDirectory.js +9 -17
  31. package/dist/engineErrorCodes.d.ts +8 -0
  32. package/dist/engineErrorCodes.js +8 -0
  33. package/dist/engineNoticeCodes.d.ts +26 -3
  34. package/dist/engineNoticeCodes.js +52 -7
  35. package/dist/engineRowRef.js +1 -1
  36. package/dist/errorSupplementRoles.js +2 -0
  37. package/dist/eventLeg.d.ts +2 -2
  38. package/dist/eventLeg.js +2 -1
  39. package/dist/fleet/fleetProjection.js +26 -5
  40. package/dist/generated/engineFactTables.d.ts +2 -1
  41. package/dist/generated/engineFactTables.js +3 -1
  42. package/dist/generated/engineNoticeTables.js +19 -4
  43. package/dist/generated/sdkFactTables.d.ts +3 -0
  44. package/dist/generated/sdkFactTables.js +15 -0
  45. package/dist/generated/settingsSchemaFns.d.ts +11 -0
  46. package/dist/generated/settingsSchemaFns.js +2 -1
  47. package/dist/generated/settingsSchemaSafetyMergeSpec.js +1 -1
  48. package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -1
  49. package/dist/generated/settingsSchemaSettingsSources.js +22 -2
  50. package/dist/hitl/approvalLiveFace.d.ts +17 -0
  51. package/dist/hitl/approvalLiveFace.js +35 -0
  52. package/dist/hitl/approvalQueueRow.d.ts +21 -0
  53. package/dist/hitl/approvalQueueRow.js +69 -0
  54. package/dist/hitl/approvalsFeed.d.ts +5 -4
  55. package/dist/hitl/approvalsFeed.js +38 -6
  56. package/dist/hitl/askParkRowRouting.d.ts +4 -3
  57. package/dist/hitl/askParkRowRouting.js +15 -3
  58. package/dist/hitl/automaticAnswerVerdict.js +13 -10
  59. package/dist/hitl/crashConverged.d.ts +5 -1
  60. package/dist/hitl/decisionConflict.js +2 -1
  61. package/dist/hitl/decisionRefusal.js +1 -1
  62. package/dist/hitl/decisionSend.d.ts +1 -0
  63. package/dist/hitl/decisionSend.js +14 -2
  64. package/dist/hitl/frameRouter.js +4 -5
  65. package/dist/hitl/hitlBridge.d.ts +1 -1
  66. package/dist/hitl/hitlBridge.js +26 -5
  67. package/dist/hitl/livePendingAsk.d.ts +5 -0
  68. package/dist/hitl/livePendingAsk.js +6 -1
  69. package/dist/hitl/planReviewCard.d.ts +2 -0
  70. package/dist/hitl/planReviewCard.js +21 -0
  71. package/dist/hitl/planReviewWire.d.ts +2 -2
  72. package/dist/hitl/planReviewWire.js +101 -36
  73. package/dist/hitl/sessionAllowRoute.d.ts +2 -0
  74. package/dist/hitl/sessionAllowRoute.js +7 -0
  75. package/dist/hitl/sessionPolicyWire.d.ts +1 -7
  76. package/dist/hitl/sessionPolicyWire.js +3 -43
  77. package/dist/hitl/subagentSource.d.ts +1 -0
  78. package/dist/hitl/subagentSource.js +13 -0
  79. package/dist/hitl/toolApprovalWire.d.ts +3 -2
  80. package/dist/hitl/toolApprovalWire.js +79 -37
  81. package/dist/hostSettingsSource.d.ts +4 -1
  82. package/dist/hostSettingsSource.js +11 -6
  83. package/dist/hostTurnSettings.d.ts +4 -5
  84. package/dist/hostTurnSettings.js +80 -19
  85. package/dist/i18n/messages.en.d.ts +35 -12
  86. package/dist/i18n/messages.en.js +36 -13
  87. package/dist/i18n/messages.zh.js +38 -13
  88. package/dist/index.d.ts +21 -2
  89. package/dist/index.js +11 -2
  90. package/dist/liveInitToolFace.js +0 -1
  91. package/dist/liveModelCatalog.d.ts +15 -0
  92. package/dist/liveModelCatalog.js +40 -0
  93. package/dist/mcpWireCaps.js +1 -1
  94. package/dist/modelCapabilityProbe.js +66 -33
  95. package/dist/ownKey.d.ts +0 -1
  96. package/dist/ownKey.js +0 -2
  97. package/dist/permissionsDeclaration.d.ts +2 -2
  98. package/dist/permissionsDeclaration.js +12 -14
  99. package/dist/projectSeed.d.ts +39 -0
  100. package/dist/projectSeed.js +80 -0
  101. package/dist/promptDelivery.js +1 -1
  102. package/dist/replayBody.d.ts +7 -6
  103. package/dist/replayBody.js +62 -7
  104. package/dist/request/taskRequest.js +3 -4
  105. package/dist/ruleCompileVerdict.d.ts +0 -2
  106. package/dist/ruleCompileVerdict.js +0 -31
  107. package/dist/ruleRefusalSentence.js +0 -3
  108. package/dist/runReattachPolicy.d.ts +3 -0
  109. package/dist/runReattachPolicy.js +15 -2
  110. package/dist/runTerminal.js +30 -8
  111. package/dist/sandboxWire.d.ts +0 -3
  112. package/dist/sandboxWire.js +0 -9
  113. package/dist/seam.d.ts +14 -7
  114. package/dist/seam.js +12 -0
  115. package/dist/seatContract.d.ts +57 -7
  116. package/dist/seatContract.js +132 -3
  117. package/dist/serverSupportRange.d.ts +18 -0
  118. package/dist/serverSupportRange.js +25 -0
  119. package/dist/sessionEngine.d.ts +156 -0
  120. package/dist/sessionEngine.js +464 -0
  121. package/dist/sessionMap.d.ts +11 -1
  122. package/dist/sessionMap.js +35 -9
  123. package/dist/sessionMemorySync.d.ts +31 -0
  124. package/dist/sessionMemorySync.js +95 -0
  125. package/dist/sessionRowTag.d.ts +4 -0
  126. package/dist/sessionRowTag.js +18 -0
  127. package/dist/settingsLayerAdmission.d.ts +1 -0
  128. package/dist/settingsLayerAdmission.js +4 -1
  129. package/dist/toolResult.js +1 -1
  130. package/dist/wireRefusalCopy.js +2 -6
  131. package/docs/INTEGRATION-CLIENTS.md +1022 -16
  132. package/package.json +5 -5
@@ -6,6 +6,7 @@ import { DEFAULT_SESSION_KEY } from '../sessionSlot.js';
6
6
  import { ASK_PARK_AUTO_REOPEN_BLOCKS, askParkAutoReopenBlockedContent } from '../hitl/askParkAutoReopenBlock.js';
7
7
  import { corruptStoredRowContent, corruptStoredRowWhere, effectiveWireErrorCode } from '../wireErrorTriage.js';
8
8
  import { readThrownStatusSlot } from '../wireFailureShape.js';
9
+ import { guardedRead, readOwnDataNonEmptyString, readOwnDataValue } from '../ownKey.js';
9
10
  import { steerBodyOf, UNOBSERVED_STEER_PRIORITY } from '../controlRouter.js';
10
11
  import { atMostOnceFailureClass } from '../atMostOnce.js';
11
12
  import { readSteerReceipt } from '../steerReceipt.js';
@@ -28,7 +29,7 @@ function gateKindReadingOf(row) {
28
29
  return { leg: 'unreadable', kind: null };
29
30
  }
30
31
  if (typeof kind !== 'string' || kind === '')
31
- return { leg: 'absent', kind: null };
32
+ return { leg: 'unreadable', kind: null };
32
33
  if (APPROVAL_LEG_GATE_KINDS.includes(kind))
33
34
  return { leg: 'approval', kind };
34
35
  if (PLAN_LEG_GATE_KINDS.includes(kind))
@@ -42,7 +43,7 @@ export function durableDecideLegOf(row) {
42
43
  }
43
44
  export function askParkForeignGateKind(row) {
44
45
  const r = gateKindReadingOf(row);
45
- return r.leg === 'approval' || r.leg === 'absent' ? null : (r.kind ?? '(unreadable)');
46
+ return r.leg === 'approval' ? null : (r.kind ?? '(unreadable)');
46
47
  }
47
48
  export const PLAN_REVIEW_STATES = Object.freeze(['needs_review']);
48
49
  export const ASK_PARK_STATES = Object.freeze(['suspended']);
@@ -70,12 +71,20 @@ export function selfHealSubmissionDisposition(outcome) {
70
71
  return 'not-delivered';
71
72
  case 'running-attach':
72
73
  return 'not-delivered';
74
+ case 'injected-redundant':
75
+ return 'superseded';
76
+ case 'injected-deferred':
77
+ return 'deferred';
73
78
  default:
74
79
  return 'not-delivered';
75
80
  }
76
81
  }
77
82
  export function steerFollowIntent(outcome) {
78
- if (typeof outcome !== 'object' || outcome === null || outcome.kind !== 'running-steered')
83
+ if (typeof outcome !== 'object' || outcome === null)
84
+ return null;
85
+ if (outcome.kind === 'injected-redundant')
86
+ return { kind: 'follow-resumed', taskId: outcome.taskId };
87
+ if (outcome.kind !== 'running-steered')
79
88
  return null;
80
89
  const taskId = outcome.taskId;
81
90
  if (outcome.delivery === 'queued')
@@ -84,6 +93,58 @@ export function steerFollowIntent(outcome) {
84
93
  return { kind: 'after-wake', taskId };
85
94
  return { kind: 'tail', taskId };
86
95
  }
96
+ const injectedResubmitReleased = new WeakSet();
97
+ export function injectedResubmitAfter(outcome, runStatus) {
98
+ try {
99
+ if (typeof outcome !== 'object' || outcome === null || outcome.kind !== 'injected-deferred')
100
+ return false;
101
+ if (!isSdkRunTerminal(runStatus) && !isSdkRunParked(runStatus))
102
+ return false;
103
+ if (injectedResubmitReleased.has(outcome))
104
+ return false;
105
+ injectedResubmitReleased.add(outcome);
106
+ return true;
107
+ }
108
+ catch {
109
+ return false;
110
+ }
111
+ }
112
+ const PLAN_REVIEW_CARRIER_KEY = '_sema_planReviewOutcome';
113
+ function planReviewCarrierOf(item) {
114
+ const meta = guardedRead(() => (typeof item === 'object' && item !== null && !Array.isArray(item) ? readOwnDataValue(item, PLAN_REVIEW_CARRIER_KEY) : undefined));
115
+ if (guardedRead(() => typeof meta === 'object' && meta !== null && !Array.isArray(meta)) !== true)
116
+ return null;
117
+ return { run: guardedRead(() => readOwnDataNonEmptyString(meta, 'taskId')) };
118
+ }
119
+ function injectedCarrierVerdict(items, busyTaskId) {
120
+ const length = guardedRead(() => (Array.isArray(items) ? readOwnDataValue(items, 'length') : undefined));
121
+ if (typeof length !== 'number' || !Number.isSafeInteger(length) || length <= 0)
122
+ return null;
123
+ const keys = guardedRead(() => Object.keys(items));
124
+ if (!Array.isArray(keys))
125
+ return null;
126
+ let present = 0;
127
+ let carriers = 0;
128
+ let allNameBusyRun = true;
129
+ for (let k = 0; k < keys.length; k++) {
130
+ const key = keys[k];
131
+ const index = Number(key);
132
+ if (typeof key !== 'string' || !Number.isSafeInteger(index) || index < 0 || index >= length || String(index) !== key)
133
+ continue;
134
+ present++;
135
+ const carrier = planReviewCarrierOf(guardedRead(() => readOwnDataValue(items, key)));
136
+ if (carrier === null) {
137
+ allNameBusyRun = false;
138
+ continue;
139
+ }
140
+ carriers++;
141
+ if (carrier.run === undefined || carrier.run !== busyTaskId)
142
+ allNameBusyRun = false;
143
+ }
144
+ if (carriers === 0)
145
+ return null;
146
+ return allNameBusyRun && present === length ? 'redundant' : 'deferred';
147
+ }
87
148
  function sessionOpts(deps) {
88
149
  const sessionId = deps?.sessionId;
89
150
  return typeof sessionId === 'string' && sessionId.length > 0 ? { session: sessionId } : {};
@@ -523,7 +584,7 @@ export async function attemptActiveRunSelfHeal(signal, runs, deps) {
523
584
  };
524
585
  }
525
586
  const gateKind = signal.pendingGate?.kind ?? null;
526
- const gateLeg = gateKind !== null ? durableDecideLegOf({ gateKind }) : 'absent';
587
+ const gateLeg = durableDecideLegOf({ gateKind });
527
588
  const pendingCp = signal.pendingGate?.checkpointId;
528
589
  const sameTaskCp = pendingCp !== undefined && registeredPlanReviewCardFacts(DEFAULT_SESSION_KEY, taskId, pendingCp) !== undefined ? pendingCp : undefined;
529
590
  if (gateLeg === 'plan_review')
@@ -814,15 +875,16 @@ async function runningChoiceArm(taskId, status, busy, statusFromWire, runs, deps
814
875
  const notParked = { kind: 'not-parked', taskId, status };
815
876
  const offer = deps?.offerRunningChoice;
816
877
  const injected = deps?.submissionOrigin === 'injected';
878
+ const carrierVerdict = injected ? injectedCarrierVerdict(guardedRead(() => deps?.injectedCarriers), taskId) : null;
817
879
  if (typeof offer !== 'function' && !injected)
818
880
  return notParked;
819
881
  const text = typeof deps?.deniedMessage === 'string' ? deps.deniedMessage : '';
820
882
  const canSteer = typeof runs?.steer === 'function' && text.length > 0;
821
883
  const canCancel = typeof runs?.cancel === 'function' && typeof runs?.get === 'function';
822
884
  const canAttach = runningAttachOffered(deps?.canAttachRunning);
823
- if (!canSteer && !canCancel && !canAttach)
885
+ if (!canSteer && !canCancel && !canAttach && carrierVerdict === null)
824
886
  return notParked;
825
- if (injected && !canSteer)
887
+ if (injected && !canSteer && carrierVerdict === null)
826
888
  return notParked;
827
889
  const probeCallerAborted = () => deps?.signal?.aborted === true;
828
890
  if (statusFromWire && typeof runs?.get === 'function' && !probeCallerAborted()) {
@@ -847,6 +909,10 @@ async function runningChoiceArm(taskId, status, busy, statusFromWire, runs, deps
847
909
  if (injected) {
848
910
  if (probeCallerAborted())
849
911
  return notParked;
912
+ if (carrierVerdict === 'redundant')
913
+ return { kind: 'injected-redundant', taskId };
914
+ if (carrierVerdict === 'deferred')
915
+ return { kind: 'injected-deferred', taskId };
850
916
  choice = 'steer';
851
917
  }
852
918
  else if (typeof offer === 'function') {
@@ -998,7 +1064,7 @@ export function activeRunSelfHealRow(outcome, signal, copy, origin, follow, lang
998
1064
  if (typeof override === 'string')
999
1065
  return override;
1000
1066
  const following = follow?.following === true && steerFollowIntent(outcome)?.kind === 'tail';
1001
- if (origin === 'injected')
1067
+ if (origin === 'injected' || outcome.kind === 'injected-redundant' || outcome.kind === 'injected-deferred')
1002
1068
  return injectedSubmissionRow(outcome, following, lang);
1003
1069
  const engineDecide = copy?.engineDecidePath !== false;
1004
1070
  const keep = (outcome.kind === 'plan-review-reopen-failed' || outcome.kind === 'ask-reopen-failed') &&
@@ -1071,6 +1137,10 @@ function injectedSubmissionRow(outcome, following = false, lang) {
1071
1137
  return following
1072
1138
  ? say(lang, 'session.selfHeal.injected.handedOffFollowing', { lead, id })
1073
1139
  : say(lang, 'session.selfHeal.injected.handedOffWatch', { lead, id });
1140
+ case 'superseded':
1141
+ return say(lang, 'session.selfHeal.injected.redundant', { lead, id });
1142
+ case 'deferred':
1143
+ return say(lang, 'session.selfHeal.injected.deferred', { lead, id });
1074
1144
  case 'not-delivered': {
1075
1145
  const noView = (outcome.kind === 'ask-reopen-failed' || outcome.kind === 'plan-review-reopen-failed') && outcome.noPresentationSurface === true
1076
1146
  ? msg('session.selfHeal.noCardView.inParens')
@@ -1182,6 +1252,9 @@ function activeRunSelfHealBaseRow(outcome, wayOut, following = false, keepSessio
1182
1252
  return outcome.delivery === 'rejected'
1183
1253
  ? say(lang, 'session.selfHeal.row.steerFailed.rejected', { taskId: outcome.taskId, detail: outcome.detail })
1184
1254
  : say(lang, 'session.selfHeal.row.steerFailed.unknown', { taskId: outcome.taskId, detail: outcome.detail });
1255
+ case 'injected-redundant':
1256
+ case 'injected-deferred':
1257
+ return injectedSubmissionRow(outcome, following, lang);
1185
1258
  case 'running-attach':
1186
1259
  return say(lang, 'session.selfHeal.row.attach', { disclosure: resumeAttachReplayDisclosure(outcome.taskId) });
1187
1260
  case 'running-cancelled':
@@ -60,11 +60,6 @@ export interface WiringManifestAutoConsolidationView {
60
60
  export interface WiringManifestReadDenyView {
61
61
  builtinTiers: readonly string[];
62
62
  }
63
- export interface WiringManifestHookEntryView {
64
- family: string;
65
- owner: string;
66
- observational?: true;
67
- }
68
63
  export interface WiringManifestLspSeamView {
69
64
  mounted: boolean;
70
65
  lane?: string;
@@ -42,7 +42,9 @@ export const INTERNAL_SDK_ARM_TYPES = frozenSet([
42
42
  'wiring_manifest',
43
43
  'approval_request',
44
44
  'approval_revoke',
45
+ 'approval_complete',
45
46
  'message_committed',
47
+ 'session_titled',
46
48
  ]);
47
49
  function assistantArm(ctx, content, eventId, parentToolCallId, recovered) {
48
50
  const id = typeof eventId === 'string' && eventId.length > 0 ? eventId : undefined;
@@ -113,7 +115,14 @@ function projectEvent(ev, ctx) {
113
115
  return compactionStartedProjection(ev, ctx);
114
116
  if (isBeyondFloorArm(ev)) {
115
117
  const word = ev.type;
116
- return word === 'cross_boundary_taint' ? nothing('not_in_slice') : dropped('unsupported_arm', word);
118
+ if (word === 'cross_boundary_taint')
119
+ return nothing('not_in_slice');
120
+ if (word === 'session_titled')
121
+ return sessionTitledProjection(ev, ctx);
122
+ const body = approvalFrameBody(ev);
123
+ if (body === undefined)
124
+ return dropped('malformed', 'approval_complete');
125
+ return projected(internalArmExit(stamp(ctx, armBody({ type: 'approval_complete', ...body }))));
117
126
  }
118
127
  switch (ev.type) {
119
128
  case 'task_started':
@@ -632,7 +641,6 @@ function wiringManifestSupersetBody(ev) {
632
641
  const autoMode = projectAutoModeSection(ev.autoMode);
633
642
  const mcp = projectMcpSection(ev.mcp);
634
643
  const tools = projectToolRoster(ev);
635
- const hooks = projectHooksSection(ev.hooks);
636
644
  const lsp = projectLspSection(ev.lsp);
637
645
  const writeProtection = projectWriteProtectionSection(ev.writeProtection);
638
646
  const autoConsolidation = projectAutoConsolidationSection(ev.autoConsolidation);
@@ -642,14 +650,13 @@ function wiringManifestSupersetBody(ev) {
642
650
  const instructions = readInstructionsSegment(ev, 'instructions');
643
651
  const fleet = readFleetSegment(ev, 'fleet');
644
652
  const mods = projectModsSection(ev);
645
- if (modelGate === undefined && autoMode === undefined && mcp === undefined && tools === undefined && hooks === undefined && lsp === undefined && writeProtection === undefined && autoConsolidation === undefined && readDeny === undefined && hands === undefined && fileHistory === undefined && instructions === undefined && fleet === undefined && mods === undefined)
653
+ if (modelGate === undefined && autoMode === undefined && mcp === undefined && tools === undefined && lsp === undefined && writeProtection === undefined && autoConsolidation === undefined && readDeny === undefined && hands === undefined && fileHistory === undefined && instructions === undefined && fleet === undefined && mods === undefined)
646
654
  return undefined;
647
655
  return {
648
656
  ...(modelGate !== undefined ? { _sema_modelGate: modelGate } : {}),
649
657
  ...(autoMode !== undefined ? { _sema_autoMode: autoMode } : {}),
650
658
  ...(mcp !== undefined ? { _sema_mcp: mcp } : {}),
651
659
  ...(tools !== undefined ? { _sema_tools: tools } : {}),
652
- ...(hooks !== undefined ? { _sema_hooks: hooks } : {}),
653
660
  ...(lsp !== undefined ? { _sema_lsp: lsp } : {}),
654
661
  ...(writeProtection !== undefined ? { _sema_writeProtection: writeProtection } : {}),
655
662
  ...(autoConsolidation !== undefined ? { _sema_autoConsolidation: autoConsolidation } : {}),
@@ -710,20 +717,6 @@ function projectModsSection(holder) {
710
717
  return undefined;
711
718
  }
712
719
  }
713
- function projectHooksSection(raw) {
714
- if (!Array.isArray(raw))
715
- return undefined;
716
- const rows = [];
717
- for (const r of raw) {
718
- if (typeof r !== 'object' || r === null || Array.isArray(r))
719
- continue;
720
- const o = r;
721
- if (typeof o.family !== 'string' || o.family.length === 0 || typeof o.owner !== 'string' || o.owner.length === 0)
722
- continue;
723
- rows.push({ family: o.family, owner: o.owner, ...(o.observational === true ? { observational: true } : {}) });
724
- }
725
- return rows.length > 0 ? rows : undefined;
726
- }
727
720
  function projectLspSection(raw) {
728
721
  if (typeof raw !== 'object' || raw === null || Array.isArray(raw))
729
722
  return undefined;
@@ -809,6 +802,13 @@ function compactionOutcomeProjection(frame, ctx) {
809
802
  ...identity,
810
803
  }))));
811
804
  }
805
+ function sessionTitledProjection(frame, ctx) {
806
+ const sessionId = guardedRead(() => readOwnDataNonEmptyString(frame, 'sessionId'));
807
+ const title = guardedRead(() => readOwnDataNonEmptyString(frame, 'title'));
808
+ if (sessionId === undefined || title === undefined)
809
+ return dropped('malformed', 'session_titled');
810
+ return projected(internalArmExit(stamp(ctx, armBody({ type: 'session_titled', sessionId, title }))));
811
+ }
812
812
  function compactionStartedProjection(frame, ctx) {
813
813
  const ev = frame;
814
814
  const { identity, bad } = identityOrMalformed(ev, 'compaction_started');
@@ -917,7 +917,8 @@ function engineNoticeProjection(ev, ctx) {
917
917
  ...(seq !== undefined ? { eventSeq: seq } : {}),
918
918
  })));
919
919
  }
920
- function approvalFrameBody(ev) {
920
+ function approvalFrameBody(frame) {
921
+ const ev = frame;
921
922
  const schemaVersion = typeof ev.schemaVersion === 'number' && Number.isFinite(ev.schemaVersion)
922
923
  ? ev.schemaVersion
923
924
  : undefined;
@@ -702,12 +702,11 @@ export function doneToSdkResult(ev, ctx, observed) {
702
702
  }
703
703
  function doneToSdkResultBody(ev, ctx, observed) {
704
704
  const view = doneResultView(ev.result);
705
- const rRaw = view.engine;
705
+ const rRaw = view.body;
706
706
  const rec = typeof rRaw === 'object' && rRaw !== null ? rRaw : {};
707
707
  const r = rec;
708
708
  const stats = r.stats;
709
- const nestedSid = r.sessionId;
710
- const echoedSid = typeof nestedSid === 'string' && nestedSid.length > 0 ? nestedSid : view.row?.sessionId;
709
+ const echoedSid = r.sessionId;
711
710
  if (typeof echoedSid === 'string' && echoedSid.length > 0)
712
711
  ctx.sessionId = echoedSid;
713
712
  const terminal = readRunTerminal(ev.result);
@@ -1,11 +1,10 @@
1
- import type { WiringManifestModelGate, WiringManifestAutoMode, WiringManifestMcpEntryView, WiringManifestHookEntryView, WiringManifestLspSeamView, WiringManifestWriteProtectionView, WiringManifestAutoConsolidationView, WiringManifestReadDenyView, WiringManifestModView } from './eventToSdkMessage.js';
1
+ import type { WiringManifestModelGate, WiringManifestAutoMode, WiringManifestMcpEntryView, WiringManifestLspSeamView, WiringManifestWriteProtectionView, WiringManifestAutoConsolidationView, WiringManifestReadDenyView, WiringManifestModView } from './eventToSdkMessage.js';
2
2
  import type { ToolRosterView, WiringManifestHandsView } from '../../toolRoster.js';
3
3
  export type WiringManifestSections = {
4
4
  _sema_modelGate?: WiringManifestModelGate;
5
5
  _sema_autoMode?: WiringManifestAutoMode;
6
6
  _sema_mcp?: WiringManifestMcpEntryView[];
7
7
  _sema_tools?: ToolRosterView;
8
- _sema_hooks?: WiringManifestHookEntryView[];
9
8
  _sema_lsp?: WiringManifestLspSeamView;
10
9
  _sema_writeProtection?: WiringManifestWriteProtectionView;
11
10
  _sema_autoConsolidation?: WiringManifestAutoConsolidationView;
@@ -27,7 +26,6 @@ export interface WiringManifestView {
27
26
  autoMode?: WiringManifestAutoMode;
28
27
  mcp?: readonly WiringManifestMcpEntryView[];
29
28
  tools?: ToolRosterView;
30
- hooks?: readonly WiringManifestHookEntryView[];
31
29
  lsp?: WiringManifestLspSeamView;
32
30
  writeProtection?: WiringManifestWriteProtectionView;
33
31
  autoConsolidation?: WiringManifestAutoConsolidationView;
@@ -51,7 +51,6 @@ export function wiringManifestViewOf(s) {
51
51
  ...(isObj(s._sema_autoMode) ? { autoMode: s._sema_autoMode } : {}),
52
52
  ...(Array.isArray(s._sema_mcp) ? { mcp: s._sema_mcp } : {}),
53
53
  ...(isObj(s._sema_tools) ? { tools: s._sema_tools } : {}),
54
- ...(Array.isArray(s._sema_hooks) ? { hooks: s._sema_hooks } : {}),
55
54
  ...(isObj(s._sema_lsp) ? { lsp: s._sema_lsp } : {}),
56
55
  ...(isObj(s._sema_writeProtection) ? { writeProtection: s._sema_writeProtection } : {}),
57
56
  ...(isObj(s._sema_autoConsolidation) ? { autoConsolidation: s._sema_autoConsolidation } : {}),
@@ -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,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
+ }