@sema-agent/client-core 0.98.0 → 0.99.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 (192) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/README.md +35 -22
  3. package/dist/adapt/arms.js +61 -20
  4. package/dist/adapt/panelTasks.d.ts +1 -1
  5. package/dist/adapt/panelTasks.js +2 -2
  6. package/dist/adapter/activeRunSelfHeal.d.ts +4 -3
  7. package/dist/adapter/activeRunSelfHeal.js +162 -293
  8. package/dist/adapter/downstream/eventToSdkMessage.js +52 -4
  9. package/dist/adapter/runStream.js +52 -37
  10. package/dist/adapter/types.js +2 -1
  11. package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
  12. package/dist/agentsWireCaps.d.ts +0 -3
  13. package/dist/agentsWireCaps.js +33 -24
  14. package/dist/cloudConfigWireCaps.d.ts +1 -1
  15. package/dist/cloudConfigWireCaps.js +26 -4
  16. package/dist/controlRouter.d.ts +4 -2
  17. package/dist/controlRouter.js +39 -51
  18. package/dist/coreValuePorts.d.ts +26 -1
  19. package/dist/coreValuePorts.js +10 -0
  20. package/dist/corruptSessionCopy.d.ts +2 -1
  21. package/dist/corruptSessionCopy.js +3 -3
  22. package/dist/declared/supportFloorDeclared.js +1 -1
  23. package/dist/detachWire.js +3 -2
  24. package/dist/devicesFace.d.ts +34 -0
  25. package/dist/devicesFace.js +90 -0
  26. package/dist/displayUntrusted.d.ts +1 -0
  27. package/dist/displayUntrusted.js +3 -0
  28. package/dist/engineAgentPanelStore.d.ts +7 -0
  29. package/dist/engineAgentPanelStore.js +14 -0
  30. package/dist/engineCapReader.d.ts +2 -1
  31. package/dist/engineCapReader.js +7 -5
  32. package/dist/engineCapsCache.d.ts +8 -0
  33. package/dist/engineCapsCache.js +59 -6
  34. package/dist/engineCapsChange.d.ts +2 -0
  35. package/dist/engineCapsChange.js +9 -0
  36. package/dist/engineErrorCodes.d.ts +2 -1
  37. package/dist/engineErrorCodes.js +2 -7
  38. package/dist/engineRowRef.js +3 -0
  39. package/dist/engineSessionMessages.d.ts +1 -0
  40. package/dist/engineSessionMessages.js +7 -1
  41. package/dist/engineTargetSeat.d.ts +27 -0
  42. package/dist/engineTargetSeat.js +199 -0
  43. package/dist/engineWireFor.js +3 -8
  44. package/dist/env/uiLanguage.d.ts +2 -1
  45. package/dist/env/uiLanguage.js +3 -2
  46. package/dist/eventLeg.d.ts +8 -0
  47. package/dist/eventLeg.js +61 -41
  48. package/dist/fileHistoryCaptureCapability.d.ts +2 -1
  49. package/dist/fileHistoryCaptureCapability.js +12 -18
  50. package/dist/fileHistoryLegNotice.d.ts +2 -1
  51. package/dist/fileHistoryLegNotice.js +3 -3
  52. package/dist/frameBinding.d.ts +3 -0
  53. package/dist/frameBinding.js +12 -0
  54. package/dist/gateOutcome.js +16 -2
  55. package/dist/gateVocabulary.d.ts +8 -7
  56. package/dist/gateVocabulary.js +71 -73
  57. package/dist/generated/engineFactTables.d.ts +17 -1
  58. package/dist/generated/engineFactTables.js +29 -0
  59. package/dist/generated/engineNoticeTables.js +9 -3
  60. package/dist/generated/settingsSchemaFns.d.ts +6 -0
  61. package/dist/generated/settingsSchemaFns.js +57 -0
  62. package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
  63. package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
  64. package/dist/generated/settingsSchemaTables.d.ts +1 -0
  65. package/dist/generated/settingsSchemaTables.js +4 -0
  66. package/dist/generated/settingsSchemaTypes.d.ts +105 -0
  67. package/dist/generated/settingsSchemaTypes.js +1 -0
  68. package/dist/hitl/allowRuleShadow.d.ts +2 -1
  69. package/dist/hitl/allowRuleShadow.js +17 -14
  70. package/dist/hitl/approvalCardReasons.d.ts +3 -2
  71. package/dist/hitl/approvalCardReasons.js +27 -28
  72. package/dist/hitl/approvalHolds.d.ts +3 -0
  73. package/dist/hitl/approvalHolds.js +73 -29
  74. package/dist/hitl/askClassPair.d.ts +1 -1
  75. package/dist/hitl/askClassPair.js +16 -0
  76. package/dist/hitl/askGateWire.js +2 -1
  77. package/dist/hitl/askSettlementLine.d.ts +14 -4
  78. package/dist/hitl/askSettlementLine.js +67 -47
  79. package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
  80. package/dist/hitl/automaticAnswerVerdict.js +8 -8
  81. package/dist/hitl/crashConvergedNotice.d.ts +5 -4
  82. package/dist/hitl/crashConvergedNotice.js +28 -41
  83. package/dist/hitl/frameRouter.js +7 -8
  84. package/dist/hitl/hitlBridge.d.ts +1 -0
  85. package/dist/hitl/hitlBridge.js +3 -3
  86. package/dist/hitl/persistedRulesWire.d.ts +6 -5
  87. package/dist/hitl/persistedRulesWire.js +55 -73
  88. package/dist/hitl/planReviewWire.d.ts +5 -0
  89. package/dist/hitl/planReviewWire.js +8 -0
  90. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  91. package/dist/hitl/sessionPolicyDeliverable.js +46 -3
  92. package/dist/hitl/sessionPolicyWire.d.ts +2 -1
  93. package/dist/hitl/sessionPolicyWire.js +23 -24
  94. package/dist/hitl/suspendedReopen.d.ts +2 -1
  95. package/dist/hitl/suspendedReopen.js +7 -10
  96. package/dist/hitl/toolApprovalWire.d.ts +17 -5
  97. package/dist/hitl/toolApprovalWire.js +79 -40
  98. package/dist/hooksWireCaps.js +145 -56
  99. package/dist/host.d.ts +21 -0
  100. package/dist/hostTurnSettings.d.ts +71 -0
  101. package/dist/hostTurnSettings.js +291 -0
  102. package/dist/humanTurn.d.ts +14 -1
  103. package/dist/humanTurn.js +100 -12
  104. package/dist/humanTurnRead.d.ts +2 -0
  105. package/dist/humanTurnRead.js +22 -1
  106. package/dist/i18n/messages.en.d.ts +582 -0
  107. package/dist/i18n/messages.en.js +582 -0
  108. package/dist/i18n/messages.zh.js +718 -1
  109. package/dist/index.d.ts +29 -13
  110. package/dist/index.js +18 -9
  111. package/dist/inheritEnvCapability.d.ts +3 -2
  112. package/dist/inheritEnvCapability.js +3 -3
  113. package/dist/inheritEnvWire.d.ts +3 -2
  114. package/dist/inheritEnvWire.js +12 -14
  115. package/dist/interactiveHalt.js +17 -6
  116. package/dist/liveModelCatalog.d.ts +2 -1
  117. package/dist/liveModelCatalog.js +14 -8
  118. package/dist/mcpPanel.d.ts +10 -1
  119. package/dist/mcpPanel.js +40 -13
  120. package/dist/mcpProbeCapability.d.ts +2 -1
  121. package/dist/mcpProbeCapability.js +7 -11
  122. package/dist/mcpProbeWire.d.ts +3 -1
  123. package/dist/mcpProbeWire.js +5 -0
  124. package/dist/mcpWireCaps.d.ts +34 -0
  125. package/dist/mcpWireCaps.js +117 -17
  126. package/dist/memoryEntriesWire.js +5 -10
  127. package/dist/model/onboardJudgement.d.ts +93 -0
  128. package/dist/model/onboardJudgement.js +415 -0
  129. package/dist/model/tierVocabulary.d.ts +2 -0
  130. package/dist/model/tierVocabulary.js +17 -5
  131. package/dist/modelCapabilityProbe.d.ts +64 -0
  132. package/dist/modelCapabilityProbe.js +600 -0
  133. package/dist/modelIdentityResolvability.d.ts +3 -0
  134. package/dist/modelIdentityResolvability.js +26 -17
  135. package/dist/ownKey.d.ts +7 -0
  136. package/dist/ownKey.js +34 -0
  137. package/dist/panelReduce.d.ts +6 -1
  138. package/dist/panelReduce.js +50 -3
  139. package/dist/permissionRuleIssue.js +2 -0
  140. package/dist/permissionRulesWriteCapability.d.ts +2 -1
  141. package/dist/permissionRulesWriteCapability.js +8 -6
  142. package/dist/pluginHooksWire.d.ts +46 -3
  143. package/dist/pluginHooksWire.js +217 -11
  144. package/dist/printModelStatus.d.ts +63 -0
  145. package/dist/printModelStatus.js +155 -0
  146. package/dist/request/taskRequest.d.ts +11 -5
  147. package/dist/request/taskRequest.js +112 -16
  148. package/dist/resumeRefusalCopy.d.ts +12 -9
  149. package/dist/resumeRefusalCopy.js +70 -143
  150. package/dist/retryStatus.d.ts +37 -0
  151. package/dist/retryStatus.js +79 -0
  152. package/dist/scenarioRefusal.d.ts +9 -0
  153. package/dist/scenarioRefusal.js +111 -0
  154. package/dist/seam.d.ts +25 -1
  155. package/dist/seam.js +10 -1
  156. package/dist/seatContract.d.ts +260 -10
  157. package/dist/seatContract.js +692 -19
  158. package/dist/selfOrchestrationDenial.js +7 -19
  159. package/dist/sessionIdSegment.d.ts +6 -0
  160. package/dist/sessionIdSegment.js +24 -0
  161. package/dist/sessionMemoryStatus.js +6 -11
  162. package/dist/sessionPolicyCapability.d.ts +2 -1
  163. package/dist/sessionPolicyCapability.js +8 -6
  164. package/dist/settingsHooksSalvage.d.ts +44 -0
  165. package/dist/settingsHooksSalvage.js +211 -0
  166. package/dist/skillToolListsCapability.d.ts +2 -1
  167. package/dist/skillToolListsCapability.js +8 -6
  168. package/dist/sseIdleTriage.js +3 -2
  169. package/dist/subagent/engineSubagentResume.js +15 -9
  170. package/dist/subagentContentStore.d.ts +3 -0
  171. package/dist/subagentContentStore.js +22 -0
  172. package/dist/toolHistoryMismatch.js +3 -2
  173. package/dist/toolRoster.d.ts +3 -2
  174. package/dist/toolRoster.js +21 -20
  175. package/dist/turnFailurePresentation.d.ts +12 -1
  176. package/dist/turnFailurePresentation.js +212 -15
  177. package/dist/usageAnalytics.js +6 -11
  178. package/dist/userAttachmentEnvelope.d.ts +1 -0
  179. package/dist/userAttachmentEnvelope.js +37 -7
  180. package/dist/userAttachmentSeat.d.ts +21 -0
  181. package/dist/userAttachmentSeat.js +75 -0
  182. package/dist/userInvokedSkillsCapability.d.ts +11 -1
  183. package/dist/userInvokedSkillsCapability.js +31 -7
  184. package/dist/wireErrorTriage.d.ts +7 -0
  185. package/dist/wireErrorTriage.js +23 -1
  186. package/dist/wireFailureShape.js +2 -1
  187. package/dist/wireRefusalCopy.d.ts +13 -1
  188. package/dist/wireRefusalCopy.js +24 -28
  189. package/dist/workflowsJournalCapability.d.ts +2 -1
  190. package/dist/workflowsJournalCapability.js +8 -6
  191. package/docs/INTEGRATION-CLIENTS.md +542 -30
  192. package/package.json +5 -5
@@ -5,8 +5,8 @@ import { ccToolDenialKindForToolEnd, gateOutcomeOf } from '../../gateOutcome.js'
5
5
  import { projectToolRoster, projectToolRosterDelta } from '../../toolRoster.js';
6
6
  import { projectHandsSection } from '../../handsSeam.js';
7
7
  import { readMcpLiveness } from '../../mcpLiveness.js';
8
- import { contextUsageReadingOf, markMcpSectionDroppedNamedRows, readFrameTrueMark } from '../../ownKey.js';
9
- import { SEGMENT_END_IDENTITY_KEYS, stripToolUseSideChannels } from '../types.js';
8
+ import { contextUsageReadingOf, humanInputAttachmentsOf, markMcpSectionDroppedNamedRows, readFrameTrueMark } from '../../ownKey.js';
9
+ import { SEGMENT_END_IDENTITY_KEYS, eventSeq, stripToolUseSideChannels } from '../types.js';
10
10
  import { frozenSet } from '../../frozenSet.js';
11
11
  import { isCoreWorkflowRunTerminal } from '../../terminalStatuses.js';
12
12
  import { envelopeUuidOf, mintEngineRowRef, readBoundRun, wireEventIdOf } from '../../engineRowRef.js';
@@ -27,6 +27,7 @@ export const INTERNAL_SDK_ARM_TYPES = frozenSet([
27
27
  'terminal_fact',
28
28
  'retry_status',
29
29
  'task_progress',
30
+ 'task_started',
30
31
  'task_notification',
31
32
  'diagnostics',
32
33
  'steering_injected',
@@ -86,7 +87,7 @@ function withEngineIdentity(p, ev, ctx) {
86
87
  function projectEvent(ev, ctx) {
87
88
  switch (ev.type) {
88
89
  case 'task_started':
89
- return dropped('unsupported_arm', 'task_started');
90
+ return taskStartedProjection(ev, ctx);
90
91
  case 'text_end':
91
92
  return textEndProjection(ev, ctx);
92
93
  case 'reasoning_end':
@@ -671,6 +672,48 @@ function contextUsageProjection(ev, ctx) {
671
672
  ...identity,
672
673
  }))));
673
674
  }
675
+ function taskStartedProjection(frame, ctx) {
676
+ const ev = frame;
677
+ const { identity, bad } = identityOrMalformed(ev, 'task_started');
678
+ if (bad !== null)
679
+ return bad;
680
+ const str = (v) => (typeof v === 'string' && v.length > 0 ? v : undefined);
681
+ const num = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : undefined);
682
+ const taskId = str(ev.taskId);
683
+ if (taskId === undefined)
684
+ return dropped('malformed', 'task_started');
685
+ const sessionId = str(ev.sessionId);
686
+ const model = str(ev.model);
687
+ const taskType = str(ev.taskType);
688
+ const seq = num(ev.seq);
689
+ const workflowRunId = str(ev.workflowRunId);
690
+ const workflowAgentLabel = str(ev.workflowAgentLabel);
691
+ const parentTaskId = str(ev.parentTaskId);
692
+ const parentSessionId = str(ev.parentSessionId);
693
+ const rootSessionId = str(ev.rootSessionId);
694
+ const name = str(ev.name);
695
+ const spawnName = str(ev.spawnName);
696
+ const agentType = str(ev.agentType);
697
+ const startedAt = num(ev.startedAt);
698
+ return projected(internalArmExit(stamp(ctx, armBody({
699
+ type: 'task_started',
700
+ taskId,
701
+ ...(sessionId !== undefined ? { sessionId } : {}),
702
+ ...(model !== undefined ? { model } : {}),
703
+ ...(taskType !== undefined ? { taskType } : {}),
704
+ ...(seq !== undefined ? { seq } : {}),
705
+ ...(workflowRunId !== undefined ? { workflowRunId } : {}),
706
+ ...(workflowAgentLabel !== undefined ? { workflowAgentLabel } : {}),
707
+ ...(parentTaskId !== undefined ? { parentTaskId } : {}),
708
+ ...(parentSessionId !== undefined ? { parentSessionId } : {}),
709
+ ...(rootSessionId !== undefined ? { rootSessionId } : {}),
710
+ ...(name !== undefined ? { name } : {}),
711
+ ...(spawnName !== undefined ? { spawnName } : {}),
712
+ ...(agentType !== undefined ? { agentType } : {}),
713
+ ...(startedAt !== undefined ? { startedAt } : {}),
714
+ ...identity,
715
+ }))));
716
+ }
674
717
  function compactionOutcomeProjection(frame, ctx) {
675
718
  const ev = frame;
676
719
  const { identity, bad } = identityOrMalformed(ev, 'compaction_outcome');
@@ -767,6 +810,7 @@ function engineNoticeProjection(ev, ctx) {
767
810
  const detail = typeof rawDetail === 'object' && rawDetail !== null && !Array.isArray(rawDetail)
768
811
  ? rawDetail
769
812
  : {};
813
+ const seq = eventSeq(ev);
770
814
  return projected(stamp(ctx, armBody({
771
815
  type: 'engine_notice',
772
816
  code,
@@ -775,7 +819,7 @@ function engineNoticeProjection(ev, ctx) {
775
819
  ...(sessionId !== undefined ? { sessionId } : {}),
776
820
  ...(ts !== undefined ? { ts } : {}),
777
821
  ...(typeof ev.eventId === 'string' && ev.eventId.length > 0 ? { eventId: ev.eventId } : {}),
778
- ...(typeof ev.id === 'string' && ev.id.length > 0 ? { eventSeq: ev.id } : {}),
822
+ ...(seq !== undefined ? { eventSeq: seq } : {}),
779
823
  })));
780
824
  }
781
825
  function approvalFrameBody(ev) {
@@ -813,8 +857,12 @@ function humanInputProjection(ev, ctx) {
813
857
  ...(str(ev.entryId) !== undefined ? { entryId: str(ev.entryId) } : {}),
814
858
  ...(str(ev.eventId) !== undefined ? { eventId: str(ev.eventId) } : {}),
815
859
  ...(str(ev.parentToolCallId) !== undefined ? { parentToolCallId: str(ev.parentToolCallId) } : {}),
860
+ ...attachmentsKey(humanInputAttachmentsOf(ev)),
816
861
  })));
817
862
  }
863
+ function attachmentsKey(rows) {
864
+ return rows !== undefined ? { attachments: rows } : {};
865
+ }
818
866
  export function turnEndUsage(ev) {
819
867
  const rawValue = ev.usage;
820
868
  if (typeof rawValue !== 'object' || rawValue === null || Array.isArray(rawValue))
@@ -3,7 +3,7 @@ import { eventToSdkMessage, turnEndUsage } from './downstream/eventToSdkMessage.
3
3
  import { turnUsageToModelUsage } from './downstream/turnUsageToModelUsage.js';
4
4
  import { readRunCostFacts, terminalToSdkResult, TOOL_INPUT_JOIN_MAX_CALLS } from './downstream/terminalToSdkResult.js';
5
5
  import { terminalRunIdOf, terminalUuidOf } from '../engineRowRef.js';
6
- import { coerceOutput, publishSubagentContentEvent } from '../subagentContentStore.js';
6
+ import { publishSubagentContentEvent, subagentContentEventOf } from '../subagentContentStore.js';
7
7
  import { OUTPUT_INVALID, activeRunBusyCarrierOf, classifyActiveRunBusy, isCorruptSessionCode, isLimitsExceededCode } from '../engineErrorCodes.js';
8
8
  import { doneResultView, isReplayedTerminal } from '../replayBody.js';
9
9
  import { readFrameStringKey } from '../ownKey.js';
@@ -13,11 +13,25 @@ import { classifyToolHistoryMismatch, noteToolHistoryTerminal, openToolHistoryGe
13
13
  import { isReviewPark, readRunTerminal, runTerminalCode } from '../runTerminal.js';
14
14
  import { parkHeldCallIdOf } from '../engineRowRef.js';
15
15
  import { providerRejectionResend } from '../providerRejection.js';
16
- import { washCredentials } from '../displayUntrusted.js';
16
+ import { displayUntrusted, washCredentials } from '../displayUntrusted.js';
17
17
  import { PROMPT_BLOCKED_BY_HOOK_ROW_LEAD, runBlockedText } from '../promptBlockedCopy.js';
18
18
  import { ccToolDenialKindForToolEnd, gateDeniedBy, gateOutcomeOf } from '../gateOutcome.js';
19
19
  import { resumeReopenContent, resumeReopenFromError, suspendedReopenOf } from '../hitl/suspendedReopen.js';
20
20
  import { isCcToolDenialKind, isCcToolDenialKindADenial, isGateDeniedByWord } from '../gateVocabulary.js';
21
+ const ENGINE_TURN_USAGE_KEYS = Object.freeze(['inputTokens', 'totalInputTokens', 'outputTokens', 'cacheReadTokens', 'cacheWriteTokens', 'costMicroUsd']);
22
+ const _engineTurnUsageKeysPin = true;
23
+ void _engineTurnUsageKeysPin;
24
+ function closedEngineTurnUsage(raw) {
25
+ const out = {};
26
+ let unknownKeys = 0;
27
+ for (const k of Object.keys(raw)) {
28
+ if (ENGINE_TURN_USAGE_KEYS.includes(k))
29
+ out[k] = raw[k];
30
+ else
31
+ unknownKeys++;
32
+ }
33
+ return { usage: out, unknownKeys };
34
+ }
21
35
  const mainLane = () => ({ lane: 'main' });
22
36
  function emitChromeFireAndForget(ctx, event) {
23
37
  try {
@@ -111,7 +125,23 @@ export function isModelOutputErrorRowText(text) {
111
125
  return text.trimStart().startsWith(`${MODEL_OUTPUT_ERROR_PREFIX}:`);
112
126
  }
113
127
  export const OUTCOME_UNKNOWN_ROW_PREFIX = 'Outcome unknown';
114
- function syntheticTerminalRow(ctx, identity, replayed, text, historyKey, resend) {
128
+ function apiErrorRowBitsOf(read) {
129
+ try {
130
+ const status = read.carrier.status;
131
+ const providerCondition = read.detail !== undefined && ownDataBit(read.detail, 'kind') === PROVIDER_REJECTED_DETAIL ? nonEmptyStr(ownDataBit(read.detail, 'providerCondition')) : undefined;
132
+ const errorCode = nonEmptyStr(read.carrier.code);
133
+ const bits = {
134
+ ...(typeof status === 'number' && Number.isInteger(status) && status >= 100 && status <= 999 ? { status } : {}),
135
+ ...(providerCondition !== undefined ? { providerCondition } : {}),
136
+ ...(errorCode !== undefined ? { errorCode } : {}),
137
+ };
138
+ return Object.keys(bits).length > 0 ? bits : undefined;
139
+ }
140
+ catch {
141
+ return undefined;
142
+ }
143
+ }
144
+ function syntheticTerminalRow(ctx, identity, replayed, text, historyKey, resend, apiError) {
115
145
  return stamp(ctx, {
116
146
  uuid: identity.runId === undefined ? undefined : terminalUuidOf(identity.runId, identity.label),
117
147
  session_id: undefined,
@@ -121,6 +151,9 @@ function syntheticTerminalRow(ctx, identity, replayed, text, historyKey, resend)
121
151
  _sema_api_error_message: true,
122
152
  ...(historyKey !== undefined ? { _sema_tool_history_mismatch: historyKey } : {}),
123
153
  ...(resend !== undefined ? { _sema_provider_rejection_resend: { resend: resend.resend, text: resend.text, kind: resend.kind } } : {}),
154
+ ...(apiError?.status !== undefined ? { _sema_api_error_status: apiError.status } : {}),
155
+ ...(apiError?.providerCondition !== undefined ? { _sema_provider_condition: apiError.providerCondition } : {}),
156
+ ...(apiError?.errorCode !== undefined ? { _sema_api_error_code: apiError.errorCode } : {}),
124
157
  ...(replayed ? { _sema_replay: true } : {}),
125
158
  });
126
159
  }
@@ -233,7 +266,7 @@ function ownTerminalSnapshot(result) {
233
266
  const ts = ownDataCopy(t, ['kind', 'code', 'message']);
234
267
  const detail = plainObjectOf(ownDataBit(t, 'detail'));
235
268
  if (detail !== undefined)
236
- ts.detail = ownDataCopy(detail, ['kind', 'status', 'code']);
269
+ ts.detail = ownDataCopy(detail, ['kind', 'status', 'code', 'providerCondition']);
237
270
  snap.terminal = ts;
238
271
  return snap;
239
272
  }
@@ -314,12 +347,10 @@ function apiErrorTerminalOfRowFrame(ev, facts) {
314
347
  }
315
348
  const reportedDroppedTypes = new Set();
316
349
  const DROPPED_TYPE_MEMO_CAP = 64;
317
- const DROPPED_TYPE_DISPLAY_CAP = 60;
318
- function sanitizeFrameType(type) {
319
- const flattened = type.replace(/[\u0000-\u001f\u007f-\u009f]/g, '\uFFFD');
320
- return flattened.length > DROPPED_TYPE_DISPLAY_CAP
321
- ? `${flattened.slice(0, DROPPED_TYPE_DISPLAY_CAP)}…`
322
- : flattened;
350
+ const DROPPED_TYPE_DISPLAY_MAX = 60;
351
+ function droppedTypeForLog(type) {
352
+ const full = displayUntrusted(type);
353
+ return full.length > DROPPED_TYPE_DISPLAY_MAX ? `${displayUntrusted(type, { max: DROPPED_TYPE_DISPLAY_MAX })}…` : full;
323
354
  }
324
355
  const DROPPED_WHY_SENTENCE = Object.freeze({
325
356
  duplicate_seq: 'a frame with this event id was already consumed on this run stream, so it was dropped as a replay (durable idempotency, contract 02 §1.1). ' +
@@ -348,7 +379,7 @@ function reportDroppedFrame(why, type, ctx) {
348
379
  return;
349
380
  if (reportedDroppedTypes.size < DROPPED_TYPE_MEMO_CAP)
350
381
  reportedDroppedTypes.add(type);
351
- console.error(`[client-core] dropped an engine frame (${why}): type="${sanitizeFrameType(type)}" — ${droppedWhySentence(why)}`);
382
+ console.error(`[client-core] dropped an engine frame (${why}): type="${droppedTypeForLog(type)}" — ${droppedWhySentence(why)}`);
352
383
  }
353
384
  export function _resetDroppedFrameReportForTest() {
354
385
  reportedDroppedTypes.clear();
@@ -512,27 +543,9 @@ async function* runStreamInner(events, ctx, handle = {}) {
512
543
  }
513
544
  }
514
545
  }
515
- if ((ev.type === 'text_delta' ||
516
- ev.type === 'reasoning_delta' ||
517
- ev.type === 'text' ||
518
- ev.type === 'reasoning' ||
519
- ev.type === 'tool_start' ||
520
- ev.type === 'tool_end') &&
521
- typeof ev.parentToolCallId === 'string') {
522
- const sub = ev;
523
- publishSubagentContentEvent({
524
- type: sub.type,
525
- taskId: sub.taskId ?? sub.parentToolCallId,
526
- parentToolCallId: sub.parentToolCallId,
527
- delta: sub.delta,
528
- text: sub.text,
529
- eventId: sub.eventId,
530
- toolCallId: sub.toolCallId,
531
- toolName: sub.toolName,
532
- args: sub.args,
533
- output: coerceOutput(sub.output),
534
- isError: sub.isError,
535
- });
546
+ const sub = subagentContentEventOf(ev);
547
+ if (sub !== undefined) {
548
+ publishSubagentContentEvent(sub);
536
549
  if (!(ctx.lane === 'print' && (sub.type === 'tool_start' || sub.type === 'tool_end')))
537
550
  continue;
538
551
  }
@@ -546,10 +559,10 @@ async function* runStreamInner(events, ctx, handle = {}) {
546
559
  const responseModelRaw = turnEndLoose.responseModel;
547
560
  const responseModelWord = typeof responseModelRaw === 'string' && responseModelRaw.length > 0 ? responseModelRaw : undefined;
548
561
  const rawUsage = ev.usage;
549
- const engineUsage = typeof rawUsage === 'object' && rawUsage !== null && !Array.isArray(rawUsage)
550
- ? rawUsage
551
- : undefined;
552
- const usage = engineUsage !== undefined ? turnUsageToModelUsage(engineUsage) : undefined;
562
+ const closedUsage = typeof rawUsage === 'object' && rawUsage !== null && !Array.isArray(rawUsage) ? closedEngineTurnUsage(rawUsage) : undefined;
563
+ const engineUsage = closedUsage?.usage;
564
+ const usageUnknownKeys = closedUsage !== undefined && closedUsage.unknownKeys > 0 ? { engineUsageUnknownKeys: closedUsage.unknownKeys } : {};
565
+ const usage = closedUsage !== undefined ? turnUsageToModelUsage(rawUsage) : undefined;
553
566
  const measured = turnEndUsage(ev);
554
567
  if (engineUsage === undefined || usage === undefined) {
555
568
  usageMissingObserved = true;
@@ -577,6 +590,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
577
590
  laneProof: mainLane(),
578
591
  usage,
579
592
  engineUsage,
593
+ ...usageUnknownKeys,
580
594
  ...(usageMissing ? { usageMissing: true } : {}),
581
595
  ...(stopWord !== undefined ? { stopReason: stopWord } : {}),
582
596
  ...(responseModelWord !== undefined ? { responseModel: responseModelWord } : {}),
@@ -600,6 +614,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
600
614
  parentToolCallId: parent,
601
615
  usage,
602
616
  engineUsage,
617
+ ...usageUnknownKeys,
603
618
  ...(usageMissing ? { usageMissing: true } : {}),
604
619
  ...(stopWord !== undefined ? { stopReason: stopWord } : {}),
605
620
  ...(responseModelWord !== undefined ? { responseModel: responseModelWord } : {}),
@@ -680,7 +695,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
680
695
  : '';
681
696
  const resend = historyTerminal.detail !== undefined ? providerRejectionResend(historyTerminal.detail, historyTerminal.carrier) : undefined;
682
697
  const resendLine = resend !== undefined ? `\n${resend.text}` : '';
683
- yield syntheticTerminalRow(ctx, { runId: terminalRunId, label: 'terminal-row' }, replayed, `${sessionUnreadable ? `${rowText}\n${corruptSessionContent()}` : rowText}${abortNote !== undefined ? `\n${abortNote}` : ''}${rewindLine}${resendLine}`, historyMismatch === null ? undefined : toolHistoryMismatchRowKey(historyMismatch, historyRepeat, rewindOffered), resend);
698
+ yield syntheticTerminalRow(ctx, { runId: terminalRunId, label: 'terminal-row' }, replayed, `${sessionUnreadable ? `${rowText}\n${corruptSessionContent()}` : rowText}${abortNote !== undefined ? `\n${abortNote}` : ''}${rewindLine}${resendLine}`, historyMismatch === null ? undefined : toolHistoryMismatchRowKey(historyMismatch, historyRepeat, rewindOffered), resend, arm === 'apiError' ? apiErrorRowBitsOf(historyTerminal) : undefined);
684
699
  }
685
700
  else {
686
701
  const echoedSid = ev.type === 'done' ? engineSessionIdOf(engineResultOf(ev.result)) : undefined;
@@ -1,5 +1,6 @@
1
1
  export function eventSeq(ev) {
2
- return ev.id;
2
+ const id = ev.id;
3
+ return typeof id === 'string' && id.length > 0 ? id : undefined;
3
4
  }
4
5
  export function uuid() {
5
6
  const g = typeof globalThis !== 'undefined' ? globalThis.crypto : undefined;
@@ -4,7 +4,7 @@ import { clientHasVerbs, engineWireFor, INJECTED_WIRE_SETTLE_MS, noAnswerDetailF
4
4
  import { engineWireDebugEnabled } from '../engineWireTarget.js';
5
5
  import { hostLog } from '../host.js';
6
6
  import { isSessionIdPathSegment } from '../sessionIdSegment.js';
7
- import { wireFailureTextsOf } from '../wireFailureShape.js';
7
+ import { readThrownSlot, readThrownStatusSlot, THROWN_SLOT_UNREADABLE, wireFailureTextsOf } from '../wireFailureShape.js';
8
8
  import { DEFAULT_SESSION_KEY } from '../sessionSlot.js';
9
9
  const NOTHING_SENT = ' — nothing sent';
10
10
  const DETAIL_BAD_SESSION = `the session id must be a non-empty string that is not a dot segment${NOTHING_SENT}`;
@@ -155,13 +155,16 @@ function refusedWhyOf(rawCode, status) {
155
155
  return undefined;
156
156
  }
157
157
  function diagOf(e) {
158
- const o = e;
159
- const rawStatus = o.status ?? o.statusCode;
158
+ const rawStatus = readThrownStatusSlot(e);
159
+ const rawCode = readThrownSlot(e, 'errorCode', 'data');
160
+ if (rawStatus === THROWN_SLOT_UNREADABLE || rawCode === THROWN_SLOT_UNREADABLE)
161
+ return undefined;
160
162
  const status = typeof rawStatus === 'number' && Number.isInteger(rawStatus) ? rawStatus : undefined;
161
- const errorCode = typeof o.errorCode === 'string' && o.errorCode.length > 0 ? o.errorCode : undefined;
162
- const ra = o.retryAfterMs;
163
+ const errorCode = typeof rawCode === 'string' && rawCode.length > 0 ? rawCode : undefined;
164
+ const ra = readThrownSlot(e, 'retryAfterMs', 'data');
163
165
  const retryAfterMs = typeof ra === 'number' && Number.isFinite(ra) && ra >= 0 ? ra : undefined;
164
- const message = typeof o.message === 'string' && o.message.length > 0 ? o.message : undefined;
166
+ const rawMessage = readThrownSlot(e, 'message');
167
+ const message = typeof rawMessage === 'string' && rawMessage.length > 0 ? rawMessage : undefined;
165
168
  return {
166
169
  ...(status !== undefined ? { status } : {}),
167
170
  ...(errorCode !== undefined ? { errorCode } : {}),
@@ -169,6 +172,10 @@ function diagOf(e) {
169
172
  ...(message !== undefined ? { message } : {}),
170
173
  };
171
174
  }
175
+ function unreadableFailure() {
176
+ note('error (the failure could not be read)');
177
+ return { kind: 'error', detail: 'the stop request failed (the error could not be read)' };
178
+ }
172
179
  function classifyFailure(e) {
173
180
  try {
174
181
  if (typeof e !== 'object' || e === null) {
@@ -176,6 +183,8 @@ function classifyFailure(e) {
176
183
  return { kind: 'error', detail: `the stop request failed: ${wireFailureTextsOf(e).reason.slice(0, 200)}` };
177
184
  }
178
185
  const d = diagOf(e);
186
+ if (d === undefined)
187
+ return unreadableFailure();
179
188
  if (d.status === undefined && d.errorCode === undefined) {
180
189
  const noAnswer = noAnswerDetailFrom(e);
181
190
  if (noAnswer !== null) {
@@ -200,8 +209,7 @@ function classifyFailure(e) {
200
209
  return { kind: 'error', detail: (d.message ?? 'the stop request failed').slice(0, 300), ...diag };
201
210
  }
202
211
  catch {
203
- note('error (the failure could not be read)');
204
- return { kind: 'error', detail: 'the stop request failed (the error could not be read)' };
212
+ return unreadableFailure();
205
213
  }
206
214
  }
207
215
  export async function stopEngineSessionBackground(sessionId, body, opts) {
@@ -3,9 +3,6 @@ import type { ReasoningEffort } from './effortWire.js';
3
3
  import type { ToolRosterView } from './toolRoster.js';
4
4
  import { type AssemblyRefusal } from './wireFailureShape.js';
5
5
  export declare const MAX_TASK_AGENTS = 32;
6
- export declare const MAX_AGENT_TEXT_CHARS = 4096;
7
- export declare const MAX_AGENT_SYSTEM_PROMPT_CHARS = 65536;
8
- export declare const MAX_AGENT_SKILL_CONTENT_CHARS = 1048576;
9
6
  export declare const TASK_AGENT_WIRE_FIELDS: readonly ["name", "whenToUse", "whenToUseLean", "allowTools", "denyTools", "skills", "background", "isolation", "model", "thinking", "systemPrompt", "maxTurns", "memory", "observer", "observerMessage"];
10
7
  export type WireThinkingLevel = ReasoningEffort;
11
8
  export type TaskAgentWireSkill = {
@@ -8,11 +8,8 @@ import { CORE_PROTOCOL_PREFIXES } from './generated/toolNameTables.js';
8
8
  import { rosterMountedNames } from './rosterMountedNames.js';
9
9
  import { capForDisplay } from './fleetTaskDesc.js';
10
10
  import { deniedEntryToolName } from './engineToolDirectory.js';
11
- import { assemblyRefusal } from './wireFailureShape.js';
11
+ import { assemblyRefusal, withAssemblyRefusal } from './wireFailureShape.js';
12
12
  export const MAX_TASK_AGENTS = 32;
13
- export const MAX_AGENT_TEXT_CHARS = 4_096;
14
- export const MAX_AGENT_SYSTEM_PROMPT_CHARS = 65_536;
15
- export const MAX_AGENT_SKILL_CONTENT_CHARS = 1_048_576;
16
13
  export const TASK_AGENT_WIRE_FIELDS = [
17
14
  'name',
18
15
  'whenToUse',
@@ -98,6 +95,24 @@ function toolListFlawPhrase(f) {
98
95
  return `${entry} could not be checked here, because the engine's tool-name check is not available in this client`;
99
96
  return `${entry} differs from the tool ${JSON.stringify(f.currentName ?? '')} only in letter case`;
100
97
  }
98
+ function listShapeWord(v) {
99
+ try {
100
+ if (v === null)
101
+ return 'null';
102
+ if (typeof v === 'string')
103
+ return 'a string';
104
+ if (typeof v === 'object')
105
+ return 'an object';
106
+ return `a ${typeof v}`;
107
+ }
108
+ catch {
109
+ return 'unreadable';
110
+ }
111
+ }
112
+ function toolListShapeRefusal(agent, key, v) {
113
+ return withAssemblyRefusal(new TypeError(`projectAgentsForWire: agent "${capForDisplay(agent, 80)}" has ${key} written as ${listShapeWord(v)}, but it must be an array of tool-name strings — ` +
114
+ 'refusing to assemble the agents list (a list dropped silently would give the agent every tool, or remove a deny rule). Fix the definition.'), 'input_malformed');
115
+ }
101
116
  export function projectAgentsForWire(defs, deps) {
102
117
  const warnings = [];
103
118
  const customs = defs
@@ -121,25 +136,24 @@ export function projectAgentsForWire(defs, deps) {
121
136
  continue;
122
137
  seen.add(name);
123
138
  const item = { name };
124
- if (typeof def.whenToUse === 'string' && def.whenToUse.length > 0) {
125
- item.whenToUse =
126
- def.whenToUse.length > MAX_AGENT_TEXT_CHARS
127
- ? def.whenToUse.slice(0, MAX_AGENT_TEXT_CHARS)
128
- : def.whenToUse;
129
- if (def.whenToUse.length > MAX_AGENT_TEXT_CHARS) {
130
- warnings.push(`agents wire: agent "${name}" description truncated to ${MAX_AGENT_TEXT_CHARS} chars`);
131
- }
132
- }
139
+ if (typeof def.whenToUse === 'string' && def.whenToUse.length > 0)
140
+ item.whenToUse = def.whenToUse;
141
+ const rawTools = def.tools;
142
+ const rawDeny = def.disallowedTools;
143
+ if (rawTools !== undefined && !Array.isArray(rawTools))
144
+ throw toolListShapeRefusal(name, 'tools', rawTools);
145
+ if (rawDeny !== undefined && !Array.isArray(rawDeny))
146
+ throw toolListShapeRefusal(name, 'disallowedTools', rawDeny);
133
147
  const toolEntries = (list, label) => {
134
148
  const entries = list.filter((t) => typeof t === 'string' && t.length > 0);
135
149
  if (entries.length !== list.length)
136
150
  warnings.push(`agents wire: agent "${name}" ${label} had invalid entries — dropped`);
137
151
  return entries;
138
152
  };
139
- if (Array.isArray(def.tools))
140
- item.allowTools = toolEntries(def.tools, 'tools');
141
- if (Array.isArray(def.disallowedTools)) {
142
- const denyTools = toolEntries(def.disallowedTools, 'disallowedTools');
153
+ if (Array.isArray(rawTools))
154
+ item.allowTools = toolEntries(rawTools, 'tools');
155
+ if (Array.isArray(rawDeny)) {
156
+ const denyTools = toolEntries(rawDeny, 'disallowedTools');
143
157
  if (denyTools.length > 0)
144
158
  item.denyTools = denyTools;
145
159
  }
@@ -199,7 +213,7 @@ export function projectAgentsForWire(defs, deps) {
199
213
  if (typeof skillName !== 'string' || skillName.length === 0)
200
214
  continue;
201
215
  const spec = byName.get(skillName.toLowerCase());
202
- if (spec && spec.content.length > 0 && spec.content.length <= MAX_AGENT_SKILL_CONTENT_CHARS) {
216
+ if (spec && spec.content.length > 0) {
203
217
  joined.push(spec);
204
218
  }
205
219
  else {
@@ -236,13 +250,8 @@ export function projectAgentsForWire(defs, deps) {
236
250
  catch {
237
251
  prompt = undefined;
238
252
  }
239
- if (typeof prompt === 'string' && prompt.length > 0) {
240
- if (prompt.length > MAX_AGENT_SYSTEM_PROMPT_CHARS) {
241
- warnings.push(`agents wire: agent "${name}" system prompt truncated to ${MAX_AGENT_SYSTEM_PROMPT_CHARS} chars`);
242
- prompt = prompt.slice(0, MAX_AGENT_SYSTEM_PROMPT_CHARS);
243
- }
253
+ if (typeof prompt === 'string' && prompt.length > 0)
244
254
  item.systemPrompt = prompt;
245
- }
246
255
  }
247
256
  if (def.maxTurns !== undefined)
248
257
  item.maxTurns = def.maxTurns;
@@ -4,7 +4,7 @@ import type { EnvLike } from './hostEnv.js';
4
4
  export type { McpServerSpec };
5
5
  type Rec = Record<string, unknown>;
6
6
  export type { EnvLike };
7
- export type CloudMcpDropReason = 'disabled' | 'missing-field' | 'unknown-transport' | 'capped' | 'principal-and-assertion-header';
7
+ export type CloudMcpDropReason = 'disabled' | 'missing-field' | 'unknown-transport' | 'capped' | 'principal-and-assertion-header' | 'tool-axes-invalid' | 'elicitation-invalid';
8
8
  export interface CloudMcpDroppedServer {
9
9
  name?: string;
10
10
  reason: CloudMcpDropReason;
@@ -1,5 +1,6 @@
1
- import { MCP_CAPS, mcpAssertionHeaderNotSentNotice, readMcpHttpIdentityHeaders } from './mcpWireCaps.js';
1
+ import { MCP_CAPS, mcpAssertionHeaderNotSentNotice, mcpElicitationVerdict, mcpToolAxesVerdict, readMcpHttpIdentityHeaders } from './mcpWireCaps.js';
2
2
  import { toCappedSpec } from './skillsWireCaps.js';
3
+ import { msg, renderMessage } from './i18n/translate.js';
3
4
  import { TIER_ORDER } from './model/tierVocabulary.js';
4
5
  import { SETTINGS_NARROW_AT_MENTION } from './generated/settingsSchemaFns.js';
5
6
  import { modelsPolicyOf } from './model/modelsPolicy.js';
@@ -92,14 +93,27 @@ export function cloudMcpToSpecs(servers, env) {
92
93
  drop(name, 'unknown-transport');
93
94
  continue;
94
95
  }
96
+ const axesDeclared = s.toolAxes;
97
+ const axesVerdict = mcpToolAxesVerdict(axesDeclared);
98
+ if (axesVerdict.kind === 'bad') {
99
+ drop(name, 'tool-axes-invalid');
100
+ continue;
101
+ }
102
+ const axesShipped = axesVerdict.kind === 'ok' ? axesVerdict.toolAxes : axesDeclared;
103
+ const elVerdict = mcpElicitationVerdict(s.elicitation);
104
+ if (elVerdict.kind === 'bad') {
105
+ drop(name, 'elicitation-invalid');
106
+ continue;
107
+ }
108
+ const allowToolsWritten = Array.isArray(s.allowTools);
95
109
  const allowTools = asArr(s.allowTools).filter((a) => typeof a === 'string');
96
110
  specs.push({
97
111
  name,
98
112
  transport,
99
- ...(allowTools.length > 0 ? { allowTools } : {}),
100
- ...(s.elicitation === true ? { elicitation: true } : {}),
113
+ ...(allowToolsWritten ? { allowTools } : {}),
114
+ ...(elVerdict.elicitation !== undefined ? { elicitation: elVerdict.elicitation } : {}),
101
115
  ...(s.toolFaces !== undefined ? { toolFaces: s.toolFaces } : {}),
102
- ...(s.toolAxes !== undefined ? { toolAxes: s.toolAxes } : {}),
116
+ ...(axesShipped !== undefined ? { toolAxes: axesShipped } : {}),
103
117
  });
104
118
  }
105
119
  return { specs, missingEnv: [...new Set(missingEnv)], droppedServers };
@@ -654,6 +668,14 @@ const MCP_DROP_SENTENCES = {
654
668
  level: 'warn',
655
669
  text: (who) => `cloud config: MCP server entries left out because they set both principalHeader and assertionHeader, which name the same identity header — keep only one of the two: ${who}`,
656
670
  },
671
+ 'tool-axes-invalid': {
672
+ level: 'warn',
673
+ text: (who) => renderMessage(msg('config.mcp.cloudToolAxesInvalid', { who })),
674
+ },
675
+ 'elicitation-invalid': {
676
+ level: 'warn',
677
+ text: (who) => renderMessage(msg('config.mcp.cloudElicitationInvalid', { who })),
678
+ },
657
679
  capped: {
658
680
  level: 'warn',
659
681
  text: (who) => `cloud config: MCP server entries left out because more than ${MCP_CAPS.items} were served to you and this client passes at most ${MCP_CAPS.items} to the engine: ${who}`,
@@ -1,6 +1,7 @@
1
1
  import type { TaskRequest, RunReceipt, CancelAck, Scenario, SteerPriority, AssistantTaskStatus } from '@sema-agent/sdk';
2
2
  import { type SteerPriorityReading } from './steerPriorityCapability.js';
3
3
  import { type PreemptOutcome } from './preemptWire.js';
4
+ import type { UiLanguage } from './env/uiLanguage.js';
4
5
  export interface RunsResourceLike {
5
6
  create(req: TaskRequest, opts?: {
6
7
  idempotencyKey?: string | null;
@@ -75,6 +76,7 @@ export interface ErrCodes {
75
76
  status?: number | undefined;
76
77
  }
77
78
  export declare function errCodes(e: unknown): ErrCodes;
79
+ export type SteerHostQueueFact = 'queued_until_turn_end' | 'dropped' | 'unknown';
78
80
  export declare function steeringStatusIs4xx(e: object): boolean;
79
81
  export interface SteerRefusalAdvice {
80
82
  safety: ControlSafetyCode;
@@ -83,8 +85,8 @@ export interface SteerRefusalAdvice {
83
85
  nextStep: string;
84
86
  }
85
87
  export type SteeringRefusedBeforeEngine = SteerRefusalAdvice;
86
- export declare function steeringRefusedBeforeEngine(e: object): SteeringRefusedBeforeEngine | undefined;
87
- export declare function steerRefusalAdviceOf(e: object): SteerRefusalAdvice | undefined;
88
+ export declare function steeringRefusedBeforeEngine(e: object, hostQueue?: SteerHostQueueFact, lang?: UiLanguage): SteeringRefusedBeforeEngine | undefined;
89
+ export declare function steerRefusalAdviceOf(e: object, hostQueue?: SteerHostQueueFact, lang?: UiLanguage): SteerRefusalAdvice | undefined;
88
90
  export interface SteerBody {
89
91
  readonly text: string;
90
92
  readonly mode?: 'all' | 'one-at-a-time';