@sema-agent/client-core 0.95.0 → 0.96.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 (181) hide show
  1. package/CHANGELOG.md +180 -0
  2. package/README.md +49 -25
  3. package/dist/adapt/arms.js +7 -1
  4. package/dist/adapt/toolCards.d.ts +1 -0
  5. package/dist/adapt/toolCards.js +16 -3
  6. package/dist/adapt/wireShapes.js +2 -16
  7. package/dist/adapter/activeRunSelfHeal.d.ts +4 -0
  8. package/dist/adapter/activeRunSelfHeal.js +30 -4
  9. package/dist/adapter/downstream/eventToSdkMessage.js +11 -3
  10. package/dist/adapter/downstream/terminalToSdkResult.js +8 -9
  11. package/dist/adapter/runStream.js +30 -47
  12. package/dist/agentSession/engineAgentRegistryRead.js +5 -4
  13. package/dist/agentSession/engineSessionBackgroundStop.js +22 -15
  14. package/dist/agentsWireCaps.js +13 -2
  15. package/dist/callerCwdCapability.d.ts +0 -4
  16. package/dist/callerCwdCapability.js +0 -6
  17. package/dist/centerWiringCapability.d.ts +0 -4
  18. package/dist/centerWiringCapability.js +0 -6
  19. package/dist/classifierVerdictWire.js +4 -16
  20. package/dist/clientSlice.js +1 -1
  21. package/dist/cloudConfigWireCaps.d.ts +3 -3
  22. package/dist/cloudConfigWireCaps.js +65 -45
  23. package/dist/coreValuePorts.d.ts +11 -7
  24. package/dist/coreValuePorts.js +5 -8
  25. package/dist/credentialProvenance.d.ts +28 -0
  26. package/dist/credentialProvenance.js +76 -0
  27. package/dist/decideFailureNote.js +3 -1
  28. package/dist/decideReceipt.js +7 -10
  29. package/dist/declared/supportFloorDeclared.js +3 -3
  30. package/dist/displayUntrusted.d.ts +7 -3
  31. package/dist/displayUntrusted.js +356 -60
  32. package/dist/engineCapsCache.d.ts +6 -0
  33. package/dist/engineCapsCache.js +226 -32
  34. package/dist/engineDirectory.d.ts +79 -0
  35. package/dist/engineDirectory.js +186 -0
  36. package/dist/engineErrorCodes.d.ts +14 -1
  37. package/dist/engineErrorCodes.js +37 -15
  38. package/dist/engineNoticeCodes.d.ts +17 -0
  39. package/dist/engineNoticeCodes.js +57 -3
  40. package/dist/engineWordRenames.d.ts +8 -0
  41. package/dist/engineWordRenames.js +13 -0
  42. package/dist/fileHistoryCaptureCapability.d.ts +14 -0
  43. package/dist/fileHistoryCaptureCapability.js +70 -0
  44. package/dist/fleet/bgSubagentRow.d.ts +15 -0
  45. package/dist/fleet/bgSubagentRow.js +67 -0
  46. package/dist/fleet/fleetLedger.d.ts +1 -0
  47. package/dist/fleet/fleetLedger.js +103 -89
  48. package/dist/fleet/fleetProjection.d.ts +1 -0
  49. package/dist/fleet/fleetProjection.js +10 -3
  50. package/dist/fleetTaskDesc.js +4 -17
  51. package/dist/gateOutcome.d.ts +12 -1
  52. package/dist/gateOutcome.js +58 -1
  53. package/dist/gateVocabulary.d.ts +7 -2
  54. package/dist/gateVocabulary.js +5 -1
  55. package/dist/generated/engineAskFaceTables.js +1 -1
  56. package/dist/generated/engineFactTables.d.ts +5 -3
  57. package/dist/generated/engineFactTables.js +17 -4
  58. package/dist/generated/engineNoticeTables.js +12 -3
  59. package/dist/generated/settingsSchemaFns.d.ts +3 -0
  60. package/dist/generated/settingsSchemaFns.js +53 -0
  61. package/dist/generated/toolNameTables.d.ts +1 -0
  62. package/dist/generated/toolNameTables.js +1 -0
  63. package/dist/hitl/approvalEndingCause.d.ts +2 -0
  64. package/dist/hitl/approvalEndingCause.js +31 -21
  65. package/dist/hitl/askParkRowRouting.js +1 -1
  66. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  67. package/dist/hitl/automaticAnswerVerdict.js +13 -8
  68. package/dist/hitl/decisionConflict.js +0 -2
  69. package/dist/hitl/decisionRefusal.d.ts +8 -0
  70. package/dist/hitl/decisionRefusal.js +48 -14
  71. package/dist/hitl/frameRouter.d.ts +0 -1
  72. package/dist/hitl/frameRouter.js +6 -14
  73. package/dist/hitl/hitlBridge.d.ts +6 -2
  74. package/dist/hitl/hitlBridge.js +28 -7
  75. package/dist/hitl/localAllowRule.d.ts +1 -0
  76. package/dist/hitl/localAllowRule.js +2 -2
  77. package/dist/hitl/noAllowCause.d.ts +2 -1
  78. package/dist/hitl/noAllowCause.js +3 -2
  79. package/dist/hitl/parkResolver.d.ts +1 -0
  80. package/dist/hitl/parkResolver.js +8 -54
  81. package/dist/hitl/parkRowBirthWait.d.ts +1 -0
  82. package/dist/hitl/parkRowBirthWait.js +2 -2
  83. package/dist/hitl/planReviewWire.d.ts +1 -0
  84. package/dist/hitl/planReviewWire.js +98 -20
  85. package/dist/hitl/replayedApproval.d.ts +1 -0
  86. package/dist/hitl/replayedApproval.js +14 -0
  87. package/dist/hitl/sessionPolicyDeliverable.js +8 -6
  88. package/dist/hitl/standingRows.d.ts +18 -0
  89. package/dist/hitl/standingRows.js +127 -0
  90. package/dist/hitl/toolApprovalWire.d.ts +15 -3
  91. package/dist/hitl/toolApprovalWire.js +238 -25
  92. package/dist/hookMatcherVerdict.d.ts +1 -9
  93. package/dist/hookMatcherVerdict.js +21 -61
  94. package/dist/hooksWireCaps.js +2 -2
  95. package/dist/hostCallbackGuard.d.ts +1 -0
  96. package/dist/hostCallbackGuard.js +6 -0
  97. package/dist/index.d.ts +21 -9
  98. package/dist/index.js +17 -8
  99. package/dist/mcpProbeCapability.d.ts +0 -4
  100. package/dist/mcpProbeCapability.js +0 -6
  101. package/dist/memoryComplianceCapability.d.ts +0 -4
  102. package/dist/memoryComplianceCapability.js +0 -6
  103. package/dist/memoryOriginCapability.d.ts +0 -4
  104. package/dist/memoryOriginCapability.js +0 -6
  105. package/dist/memorySpecWire.js +2 -2
  106. package/dist/modelIdentityResolvability.d.ts +2 -2
  107. package/dist/modelIdentityResolvability.js +12 -3
  108. package/dist/noticePresentation.d.ts +68 -0
  109. package/dist/noticePresentation.js +247 -0
  110. package/dist/outputStyleSeatCapability.d.ts +0 -1
  111. package/dist/outputStyleSeatCapability.js +0 -3
  112. package/dist/ownKey.d.ts +2 -0
  113. package/dist/ownKey.js +18 -0
  114. package/dist/peerFrames.js +13 -9
  115. package/dist/permissionModesCapability.d.ts +0 -4
  116. package/dist/permissionModesCapability.js +0 -6
  117. package/dist/permissionRuleIssue.js +0 -3
  118. package/dist/permissionsDeclaration.d.ts +2 -0
  119. package/dist/permissionsDeclaration.js +56 -41
  120. package/dist/printPermissionOutcome.d.ts +12 -0
  121. package/dist/printPermissionOutcome.js +50 -0
  122. package/dist/printToolResultFrame.d.ts +1 -0
  123. package/dist/printToolResultFrame.js +5 -9
  124. package/dist/promptBlockedCopy.d.ts +5 -0
  125. package/dist/promptBlockedCopy.js +35 -0
  126. package/dist/protocolSegment.d.ts +9 -6
  127. package/dist/protocolSegment.js +31 -21
  128. package/dist/providerRejection.d.ts +4 -0
  129. package/dist/providerRejection.js +75 -14
  130. package/dist/replayBody.d.ts +12 -0
  131. package/dist/replayBody.js +25 -0
  132. package/dist/resumeRefusalCopy.js +5 -21
  133. package/dist/retryStatus.d.ts +9 -1
  134. package/dist/retryStatus.js +9 -2
  135. package/dist/rewindArchiveCapability.d.ts +3 -13
  136. package/dist/rewindArchiveCapability.js +7 -58
  137. package/dist/rewindArchiveReading.d.ts +15 -0
  138. package/dist/rewindArchiveReading.js +56 -0
  139. package/dist/ruleCompileVerdict.d.ts +9 -1
  140. package/dist/ruleCompileVerdict.js +29 -4
  141. package/dist/runTerminal.d.ts +15 -1
  142. package/dist/runTerminal.js +56 -8
  143. package/dist/sandboxWire.js +13 -0
  144. package/dist/sealedKeyCapability.d.ts +0 -4
  145. package/dist/sealedKeyCapability.js +0 -6
  146. package/dist/seam.js +4 -2
  147. package/dist/seatContract.d.ts +73 -11
  148. package/dist/seatContract.js +195 -14
  149. package/dist/sessionReadRedactionCapability.d.ts +0 -4
  150. package/dist/sessionReadRedactionCapability.js +0 -6
  151. package/dist/sessionSyncFileHistory.d.ts +4 -0
  152. package/dist/sessionSyncFileHistory.js +66 -0
  153. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
  154. package/dist/sessionSyncFileHistoryCapability.js +0 -3
  155. package/dist/skillToolListsCapability.d.ts +0 -1
  156. package/dist/skillToolListsCapability.js +0 -3
  157. package/dist/steerPriorityCapability.d.ts +0 -1
  158. package/dist/steerPriorityCapability.js +0 -3
  159. package/dist/storePostureCapability.d.ts +0 -4
  160. package/dist/storePostureCapability.js +0 -6
  161. package/dist/subagent/engineSubagentSteer.js +7 -5
  162. package/dist/subagentContentStore.js +4 -15
  163. package/dist/supportFloor.d.ts +1 -0
  164. package/dist/supportFloor.js +13 -9
  165. package/dist/systemReminderTag.d.ts +1 -0
  166. package/dist/systemReminderTag.js +8 -0
  167. package/dist/toolHistoryMismatch.d.ts +0 -3
  168. package/dist/toolHistoryMismatch.js +3 -7
  169. package/dist/toolResult.d.ts +1 -1
  170. package/dist/toolResult.js +2 -1
  171. package/dist/toolResultContent.d.ts +2 -0
  172. package/dist/toolResultContent.js +63 -0
  173. package/dist/usageAnalytics.js +40 -16
  174. package/dist/userInvokedSkillsCapability.d.ts +0 -1
  175. package/dist/userInvokedSkillsCapability.js +0 -3
  176. package/dist/wireErrorTriage.d.ts +2 -0
  177. package/dist/wireErrorTriage.js +34 -5
  178. package/dist/wireFailureShape.d.ts +19 -2
  179. package/dist/wireFailureShape.js +55 -50
  180. package/docs/INTEGRATION-CLIENTS.md +1262 -17
  181. package/package.json +5 -5
@@ -12,7 +12,7 @@ import { recordWorkflowAgentTaskId } from '../workflow.js';
12
12
  import { isCoreTaskNotificationTerminal, isCoreTaskNotificationTerminalNotSuccess, isCoreTaskProgressTerminal, isCoreTaskProgressTerminalNotSuccess } from '../terminalStatuses.js';
13
13
  import { readToolHistoryMismatchKey } from '../toolHistoryMismatch.js';
14
14
  import { readProviderRejectionResendKey } from '../providerRejection.js';
15
- import { readFrameStringKey } from '../ownKey.js';
15
+ import { readFrameStringKey, readFrameTrueMark } from '../ownKey.js';
16
16
  import { washCredentials } from '../displayUntrusted.js';
17
17
  import { resolveEnginePanelTaskId } from '../engineAgentPanelStore.js';
18
18
  import { fleetRowAgentType } from '../fleet/fleetRowAgentType.js';
@@ -74,6 +74,7 @@ const assistantArm = function* (m, { ctx, idOf, text, cards, inst }) {
74
74
  uuid: idOf(m),
75
75
  session_id: ctx.sessionId,
76
76
  parent_tool_use_id: null,
77
+ ...(readFrameTrueMark(m, '_sema_tool_recovered') ? { _sema_tool_recovered: true } : {}),
77
78
  }, ctx.now());
78
79
  if (decision === 'reject' || decision === 'cancel') {
79
80
  cards.resetResponseId();
@@ -469,6 +470,7 @@ const textSegmentEndArm = function* (m, { text }) {
469
470
  if (content.length === 0)
470
471
  return;
471
472
  const r = text.replaceAnswerSegment(content, m);
473
+ yield* text.drainLive();
472
474
  yield chrome({
473
475
  kind: 'text_segment_end',
474
476
  laneProof: mainLane(),
@@ -491,6 +493,7 @@ const thinkingSegmentEndArm = function* (m, { text }) {
491
493
  if (content.length === 0)
492
494
  return;
493
495
  const r = text.replaceThinkingSegment(content, m);
496
+ yield* text.drainLive();
494
497
  yield chrome({
495
498
  kind: 'thinking_segment_end',
496
499
  laneProof: mainLane(),
@@ -542,6 +545,7 @@ const toolEndResultArm = function* (m, { idOf, cards, panel }) {
542
545
  eventId: closeEventId,
543
546
  parentToolCallId: closeParent,
544
547
  ...(typeof closeDenialKindRaw === 'string' ? { denialKind: closeDenialKindRaw } : {}),
548
+ ...(readFrameTrueMark(m, 'notExecuted') ? { notExecuted: true } : {}),
545
549
  });
546
550
  const s = structured !== undefined && structured !== null && typeof structured === 'object'
547
551
  ? structured
@@ -854,6 +858,8 @@ const retryStatusArm = function* (m, { ctx, flags }) {
854
858
  ...(typeof m.errorStatus === 'number' ? { errorStatus: m.errorStatus } : {}),
855
859
  ...(typeof m.elapsedMs === 'number' ? { elapsedMs: m.elapsedMs } : {}),
856
860
  ...(typeof m.timeoutMs === 'number' ? { timeoutMs: m.timeoutMs } : {}),
861
+ ...(typeof m.providerCondition === 'string' && m.providerCondition.length > 0 ? { providerCondition: m.providerCondition } : {}),
862
+ ...(typeof m.providerConditionSource === 'string' && m.providerConditionSource.length > 0 ? { providerConditionSource: m.providerConditionSource } : {}),
857
863
  }, ctx.now());
858
864
  if (status === null) {
859
865
  if (flags.takeRetryOverlay())
@@ -28,6 +28,7 @@ interface ToolEndPayload {
28
28
  eventId?: string | undefined;
29
29
  parentToolCallId?: string | undefined;
30
30
  denialKind?: string | undefined;
31
+ notExecuted?: boolean | undefined;
31
32
  }
32
33
  export interface OpenCardView {
33
34
  has(id: string): boolean;
@@ -2,6 +2,8 @@ import { deriveTranscriptId } from '../seam.js';
2
2
  import { degradedToolResultBody, detectEngineBgShellDetach, detectEngineBgShellReceipt, reportFindingsToolUseResult, structuredToToolUseResult, todoWriteToolUseResult, wireOutputToBody, } from '../toolResult.js';
3
3
  import { chrome, mainLane, transcript } from './ids.js';
4
4
  import { flattenWireOutput } from './wireShapes.js';
5
+ import { toolResultBlocksOf } from '../toolResultContent.js';
6
+ import { bashExitOf, bashExitReadingFailed } from '../bashExitReading.js';
5
7
  import { isCcToolDenialKind } from '../gateVocabulary.js';
6
8
  function toolUseResultParts(v) {
7
9
  return v !== undefined ? { tool_use_result: v } : {};
@@ -20,7 +22,17 @@ export function toolResultOutcomeOf(toolName, end, rawInput, owner, ledgerTier)
20
22
  if (rich === null && !isError && toolName === 'ReportFindings') {
21
23
  rich = reportFindingsToolUseResult(end?.structured, rawInput);
22
24
  }
23
- return { body, rich };
25
+ const failed = body.isError || rich?.isError === true || bashExitReadingFailed(bashExitOf(end?.structured, () => null));
26
+ const settled = failed && !body.isError ? { ...body, isError: true } : body;
27
+ return { body: withContentBlocks(settled, end), rich };
28
+ }
29
+ function withContentBlocks(body, end) {
30
+ if (body.isError || typeof body.content !== 'string' || end === undefined || end.output === undefined)
31
+ return body;
32
+ const blocks = toolResultBlocksOf(end.output, end.truncated === true);
33
+ if (blocks === undefined)
34
+ return body;
35
+ return { ...body, content: blocks, toolUseResult: body.toolUseResult !== undefined ? body.toolUseResult : body.content };
24
36
  }
25
37
  export function toolResultEnvelopeParts(o) {
26
38
  return {
@@ -52,7 +64,7 @@ export function createToolCardLedger(ctx, idOf) {
52
64
  lastLiveTodos = todo.newTodos;
53
65
  return { toolUseResult: todo.toolUseResult, isError: todo.isError };
54
66
  });
55
- const { body, rich } = outcome;
67
+ const { body } = outcome;
56
68
  const eventId = end?.eventId ?? p.eventId;
57
69
  yield transcript({
58
70
  type: 'user',
@@ -63,7 +75,7 @@ export function createToolCardLedger(ctx, idOf) {
63
75
  type: 'tool_result',
64
76
  tool_use_id: p.id,
65
77
  content: body.content,
66
- is_error: rich?.isError === true || body.isError,
78
+ is_error: body.isError,
67
79
  },
68
80
  ],
69
81
  },
@@ -72,6 +84,7 @@ export function createToolCardLedger(ctx, idOf) {
72
84
  ...(parentToolCallId !== undefined ? { parent_tool_use_id: parentToolCallId } : {}),
73
85
  ...toolResultEnvelopeParts(outcome),
74
86
  ...(isCcToolDenialKind(end?.denialKind) ? { _sema_denial_kind: end.denialKind } : {}),
87
+ ...(end?.notExecuted === true ? { _sema_not_executed: true } : {}),
75
88
  }, ctx.now());
76
89
  }
77
90
  function* closeCard(p, end) {
@@ -1,5 +1,6 @@
1
1
  import { frozenSet } from '../frozenSet.js';
2
2
  import { stripToolUseSideChannels } from '../adapter/types.js';
3
+ import { toolEndOutputText } from '../toolResultContent.js';
3
4
  export const FLUSH_INTERVAL_MS = 100;
4
5
  export const IDLE_FLUSH_MS = 1500;
5
6
  export const SUBAGENT_TOOL_NAMES = frozenSet(['Task', 'Agent', 'Fork']);
@@ -24,22 +25,7 @@ export function estimateCjkTokens(s) {
24
25
  return Math.round(t);
25
26
  }
26
27
  export function flattenWireOutput(output) {
27
- if (typeof output === 'string')
28
- return output;
29
- if (Array.isArray(output)) {
30
- const parts = [];
31
- for (const block of output) {
32
- if (block && typeof block === 'object') {
33
- const b = block;
34
- if (b.type === 'text' && typeof b.text === 'string')
35
- parts.push(b.text);
36
- else if (b.type === 'image')
37
- parts.push('[image]');
38
- }
39
- }
40
- return parts.join('');
41
- }
42
- return '';
28
+ return toolEndOutputText(output) ?? '';
43
29
  }
44
30
  export function shortTaskLabel(task) {
45
31
  const firstLine = (task.split('\n').find(l => l.trim()) ?? task).trim();
@@ -4,6 +4,10 @@ import { atMostOnceFailureClass } from '../atMostOnce.js';
4
4
  export declare const PLAN_REVIEW_GATE_KIND = "plan_review";
5
5
  export declare const PLAN_REVIEW_GATE_KINDS: readonly string[];
6
6
  export declare const ASK_PARK_GATE_KINDS: readonly string[];
7
+ export type DurableDecideLeg = 'approval' | 'plan_review' | 'other_gate' | 'unreadable' | 'absent';
8
+ export declare function durableDecideLegOf(row: {
9
+ readonly gateKind?: string | null;
10
+ } | null | undefined): DurableDecideLeg;
7
11
  export declare function askParkForeignGateKind(row: {
8
12
  gateKind?: string | null;
9
13
  }): string | null;
@@ -6,11 +6,37 @@ import { readSteerReceipt } from '../steerReceipt.js';
6
6
  import { resumeAttachReplayDisclosure, runningAttachOffered } from '../hitl/resumeRunningCard.js';
7
7
  import { isSdkRunTerminal, SDK_PARKED_RUN_STATUSES } from '../terminalStatuses.js';
8
8
  export const PLAN_REVIEW_GATE_KIND = 'plan_review';
9
- export const PLAN_REVIEW_GATE_KINDS = Object.freeze([PLAN_REVIEW_GATE_KIND, 'dry_run_review']);
10
- export const ASK_PARK_GATE_KINDS = Object.freeze(['human', 'irreversible_ask', 'policy_ask', 'tool_approval']);
9
+ const APPROVAL_LEG_GATE_KINDS = ['human', 'irreversible_ask'];
10
+ const PLAN_LEG_GATE_KINDS = ['plan_review'];
11
+ const CORE_GATE_KINDS = ['human', 'irreversible_ask', 'resource_limit', 'needs_review', 'plan_review', 'task_done'];
12
+ const _durableDecideLegPins = [true, true, true, true, true, true];
13
+ void _durableDecideLegPins;
14
+ export const PLAN_REVIEW_GATE_KINDS = Object.freeze([...PLAN_LEG_GATE_KINDS]);
15
+ export const ASK_PARK_GATE_KINDS = Object.freeze([...APPROVAL_LEG_GATE_KINDS]);
16
+ function gateKindReadingOf(row) {
17
+ let kind;
18
+ try {
19
+ kind = row !== null && typeof row === 'object' ? row.gateKind : undefined;
20
+ }
21
+ catch {
22
+ return { leg: 'unreadable', kind: null };
23
+ }
24
+ if (typeof kind !== 'string' || kind === '')
25
+ return { leg: 'absent', kind: null };
26
+ if (APPROVAL_LEG_GATE_KINDS.includes(kind))
27
+ return { leg: 'approval', kind };
28
+ if (PLAN_LEG_GATE_KINDS.includes(kind))
29
+ return { leg: 'plan_review', kind };
30
+ if (CORE_GATE_KINDS.includes(kind))
31
+ return { leg: 'other_gate', kind };
32
+ return { leg: 'unreadable', kind };
33
+ }
34
+ export function durableDecideLegOf(row) {
35
+ return gateKindReadingOf(row).leg;
36
+ }
11
37
  export function askParkForeignGateKind(row) {
12
- const kind = typeof row.gateKind === 'string' && row.gateKind.length > 0 ? row.gateKind : null;
13
- return kind !== null && !ASK_PARK_GATE_KINDS.includes(kind) ? kind : null;
38
+ const r = gateKindReadingOf(row);
39
+ return r.leg === 'approval' || r.leg === 'absent' ? null : (r.kind ?? '(unreadable)');
14
40
  }
15
41
  export const PLAN_REVIEW_STATES = Object.freeze(['needs_review']);
16
42
  export const ASK_PARK_STATES = Object.freeze(['suspended']);
@@ -5,7 +5,7 @@ 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 { markMcpSectionDroppedNamedRows } from '../../ownKey.js';
8
+ import { markMcpSectionDroppedNamedRows, readFrameTrueMark } from '../../ownKey.js';
9
9
  import { SEGMENT_END_IDENTITY_KEYS, stripToolUseSideChannels } from '../types.js';
10
10
  import { frozenSet } from '../../frozenSet.js';
11
11
  import { isCoreWorkflowRunTerminal } from '../../terminalStatuses.js';
@@ -40,7 +40,7 @@ export const INTERNAL_SDK_ARM_TYPES = frozenSet([
40
40
  'approval_revoke',
41
41
  'message_committed',
42
42
  ]);
43
- function assistantArm(ctx, content, eventId, parentToolCallId) {
43
+ function assistantArm(ctx, content, eventId, parentToolCallId, recovered) {
44
44
  const id = typeof eventId === 'string' && eventId.length > 0 ? eventId : undefined;
45
45
  const parent = typeof parentToolCallId === 'string' && parentToolCallId.length > 0 ? parentToolCallId : undefined;
46
46
  const model = parent === undefined && typeof ctx.model === 'string' && ctx.model.length > 0 ? ctx.model : undefined;
@@ -53,6 +53,7 @@ function assistantArm(ctx, content, eventId, parentToolCallId) {
53
53
  ...(model !== undefined ? { model } : {}),
54
54
  },
55
55
  parent_tool_use_id: parent ?? null,
56
+ ...(recovered === true ? { _sema_tool_recovered: true } : {}),
56
57
  }));
57
58
  }
58
59
  function streamEventArm(ctx, event) {
@@ -141,7 +142,7 @@ export function eventToSdkMessage(ev, ctx) {
141
142
  : {}),
142
143
  };
143
144
  const outBlock = ctx.lane === 'print' ? stripToolUseSideChannels(toolUse).block : toolUse;
144
- return projected(assistantArm(ctx, [outBlock], ev.eventId, ev.parentToolCallId));
145
+ return projected(assistantArm(ctx, [outBlock], ev.eventId, ev.parentToolCallId, readFrameTrueMark(ev, 'recovered')));
145
146
  }
146
147
  case 'compacted': {
147
148
  const raw = ev;
@@ -178,6 +179,7 @@ export function eventToSdkMessage(ev, ctx) {
178
179
  const collateralAbort = ev._sema_collateral_abort;
179
180
  const denialKind = ccToolDenialKindForToolEnd(ev);
180
181
  const denialUnclassified = denialKind === undefined && toolEndGate?.disposition.kind === 'denied';
182
+ const toolEndNotExecuted = readFrameTrueMark(ev, 'notExecuted');
181
183
  return projected(stamp(ctx, armBody({
182
184
  type: 'tool_end_result',
183
185
  toolCallId: ev.toolCallId,
@@ -200,6 +202,7 @@ export function eventToSdkMessage(ev, ctx) {
200
202
  ...(collateralAbort === true ? { _sema_collateral_abort: true } : {}),
201
203
  ...(denialKind !== undefined ? { _sema_denial_kind: denialKind } : {}),
202
204
  ...(denialUnclassified ? { _sema_denial_unclassified: true } : {}),
205
+ ...(toolEndNotExecuted ? { notExecuted: true } : {}),
203
206
  ...(ev.eventId !== undefined ? { eventId: ev.eventId } : {}),
204
207
  ...(ev.parentToolCallId !== undefined
205
208
  ? { parentToolCallId: ev.parentToolCallId }
@@ -217,6 +220,9 @@ export function eventToSdkMessage(ev, ctx) {
217
220
  const elapsedMs = num(st2.elapsedMs);
218
221
  const timeoutMs = num(st2.timeoutMs);
219
222
  const errClass = typeof ev.errClass === 'string' && ev.errClass.length > 0 ? ev.errClass : undefined;
223
+ const nonEmptyStr = (v) => (typeof v === 'string' && v.length > 0 ? v : undefined);
224
+ const providerCondition = nonEmptyStr(st2.providerCondition);
225
+ const providerConditionSource = nonEmptyStr(st2.providerConditionSource);
220
226
  return projected(stamp(ctx, armBody({
221
227
  type: 'retry_status',
222
228
  phase: ev.phase,
@@ -230,6 +236,8 @@ export function eventToSdkMessage(ev, ctx) {
230
236
  ...(errorStatus !== undefined ? { errorStatus } : {}),
231
237
  ...(elapsedMs !== undefined ? { elapsedMs } : {}),
232
238
  ...(timeoutMs !== undefined ? { timeoutMs } : {}),
239
+ ...(providerCondition !== undefined ? { providerCondition } : {}),
240
+ ...(providerConditionSource !== undefined ? { providerConditionSource } : {}),
233
241
  ...(typeof ev.eventId === 'string' ? { eventId: ev.eventId } : {}),
234
242
  ...(typeof ev.parentToolCallId === 'string' ? { parentToolCallId: ev.parentToolCallId } : {}),
235
243
  })));
@@ -4,9 +4,11 @@ import { putOwnKey, readFrameStringKey } from '../../ownKey.js';
4
4
  import { REDACTION_MARKER_PREFIX, washCredentials } from '../../displayUntrusted.js';
5
5
  import { readEffectiveReasoning, readEffectiveMemoryScopes } from '../../effectiveFacts.js';
6
6
  import { isReviewPark, readRunTerminal, runTerminalCode, runTerminalGateToolName, } from '../../runTerminal.js';
7
+ import { doneResultView } from '../../replayBody.js';
7
8
  import { toCcModelUsage } from './turnUsageToModelUsage.js';
8
9
  import { LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, OUTPUT_INVALID, isCorruptSessionCode, isRewindFamilyCode, } from '../../engineErrorCodes.js';
9
10
  import { corruptSessionContent } from '../../corruptSessionCopy.js';
11
+ import { runBlockedText } from '../../promptBlockedCopy.js';
10
12
  import { abortCauseNoteOf, readAbortCause } from '../../runCancelContext.js';
11
13
  function withTerminalNote(text, code, frame) {
12
14
  const withCorrupt = isCorruptSessionCode(code) ? `${text}\n${corruptSessionContent()}` : text;
@@ -519,14 +521,16 @@ function errorResult(ctx, parts) {
519
521
  });
520
522
  }
521
523
  export function doneToSdkResult(ev, ctx, observed) {
522
- const rRaw = ev.result;
524
+ const view = doneResultView(ev.result);
525
+ const rRaw = view.engine;
523
526
  const rec = typeof rRaw === 'object' && rRaw !== null ? rRaw : {};
524
527
  const r = rec;
525
528
  const stats = r.stats;
526
- const echoedSid = r.sessionId;
529
+ const nestedSid = r.sessionId;
530
+ const echoedSid = typeof nestedSid === 'string' && nestedSid.length > 0 ? nestedSid : view.row?.sessionId;
527
531
  if (typeof echoedSid === 'string' && echoedSid.length > 0)
528
532
  ctx.sessionId = echoedSid;
529
- const terminal = readRunTerminal(rRaw);
533
+ const terminal = readRunTerminal(ev.result);
530
534
  const durationMs = elapsedMs(ctx);
531
535
  const errorCode = runTerminalCode(terminal);
532
536
  const degraded = degradedOf(r);
@@ -556,15 +560,10 @@ export function doneToSdkResult(ev, ctx, observed) {
556
560
  });
557
561
  }
558
562
  if (terminal?.kind === 'blocked') {
559
- const blockedReason = terminal.reason;
560
563
  return errorResult(ctx, {
561
564
  ...errorBase,
562
565
  subtype: 'error_during_execution',
563
- errors: [
564
- blockedReason !== undefined
565
- ? `Run blocked: ${blockedReason}`
566
- : 'Run blocked (the agent reported it cannot proceed)',
567
- ],
566
+ errors: [runBlockedText(terminal)],
568
567
  });
569
568
  }
570
569
  if (terminal?.kind === 'paused') {
@@ -3,13 +3,15 @@ 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 { coerceOutput, publishSubagentContentEvent } from '../subagentContentStore.js';
6
- import { ACTIVE_RUN_BUSY_ERROR_CODE, OUTPUT_INVALID, isCorruptSessionCode, isLimitsExceededCode } from '../engineErrorCodes.js';
6
+ import { OUTPUT_INVALID, activeRunBusyCarrierOf, classifyActiveRunBusy, isCorruptSessionCode, isLimitsExceededCode } from '../engineErrorCodes.js';
7
+ import { doneResultView } from '../replayBody.js';
7
8
  import { corruptSessionContent } from '../corruptSessionCopy.js';
8
9
  import { abortCauseNoteOf } from '../runCancelContext.js';
9
10
  import { classifyToolHistoryMismatch, noteToolHistoryTerminal, openToolHistoryGeneration, TOOL_HISTORY_REWIND_SENTENCE, toolHistoryMismatchRowKey, toolHistoryRepeatSentence, toolHistoryRewindOffered, } from '../toolHistoryMismatch.js';
10
11
  import { isReviewPark, readRunTerminal, runTerminalCode } from '../runTerminal.js';
11
12
  import { providerRejectionResend } from '../providerRejection.js';
12
13
  import { washCredentials } from '../displayUntrusted.js';
14
+ import { PROMPT_BLOCKED_BY_HOOK_ROW_LEAD, runBlockedText } from '../promptBlockedCopy.js';
13
15
  import { ccToolDenialKindForToolEnd, gateDeniedBy, gateOutcomeOf } from '../gateOutcome.js';
14
16
  import { resumeReopenContent, resumeReopenFromError, suspendedReopenOf } from '../hitl/suspendedReopen.js';
15
17
  import { isCcToolDenialKind, isCcToolDenialKindADenial, isGateDeniedByWord } from '../gateVocabulary.js';
@@ -52,31 +54,10 @@ export function pendingGateIsProvablyDifferent(prev, next) {
52
54
  return a !== b;
53
55
  }
54
56
  export function activeRunBusySignal(ev) {
55
- if (typeof ev !== 'object' || ev === null || !('type' in ev))
56
- return null;
57
- const type = ev.type;
58
- let carrier;
59
- if (type === 'done') {
60
- const result = ev.result;
61
- if (typeof result !== 'object' || result === null)
62
- return null;
63
- const status = result.status;
64
- if (status !== 'failed' && (status !== undefined || Array.isArray(result)))
65
- return null;
66
- carrier = result;
67
- }
68
- else if (type === 'failed') {
69
- carrier = ev;
70
- }
71
- else {
72
- return null;
73
- }
74
- const cls = classifyActiveRunBusy({
75
- errorCode: typeof carrier.errorCode === 'string' ? carrier.errorCode : undefined,
76
- activeTaskId: carrier.activeTaskId,
77
- });
78
- if (!cls.busy)
57
+ const read = busyReadOfFrame(ev);
58
+ if (read === null || !read.cls.busy)
79
59
  return null;
60
+ const { carrier, cls } = read;
80
61
  const status = carrier.activeTaskStatus;
81
62
  const rawGate = carrier.pendingGate;
82
63
  let pendingGate = null;
@@ -100,19 +81,22 @@ export function activeRunBusySignal(ev) {
100
81
  ...(typeof msIdle === 'number' && Number.isFinite(msIdle) && msIdle >= 0 ? { msSinceLastActivity: msIdle } : {}),
101
82
  };
102
83
  }
103
- function classifyActiveRunBusy(input) {
104
- const handle = typeof input.activeTaskId === 'string' && input.activeTaskId.length > 0 ? input.activeTaskId : null;
105
- if (input.errorCode === ACTIVE_RUN_BUSY_ERROR_CODE)
106
- return { busy: true, handle };
107
- if (typeof input.activeTaskId === 'string')
108
- return { busy: true, handle };
109
- return { busy: false, handle };
84
+ function busyReadOfFrame(ev, doneTerminal, preReadActiveTaskId) {
85
+ const carrier = activeRunBusyCarrierOf(ev);
86
+ if (carrier === null)
87
+ return null;
88
+ const isDone = ev.type === 'done';
89
+ const terminal = isDone ? (doneTerminal !== undefined ? doneTerminal : readRunTerminal(ev.result)) : null;
90
+ const flatCode = typeof carrier.errorCode === 'string' ? carrier.errorCode : undefined;
91
+ const activeTaskId = preReadActiveTaskId !== undefined ? preReadActiveTaskId.value : carrier.activeTaskId;
92
+ const cls = classifyActiveRunBusy({ errorCode: (isDone ? runTerminalCode(terminal) : undefined) ?? flatCode, activeTaskId });
93
+ return { carrier, cls };
110
94
  }
111
95
  export const RUN_STOPPED_MESSAGE_PREFIX = 'Run stopped';
112
96
  export const RUN_BLOCKED_MESSAGE_PREFIX = 'Run blocked';
113
97
  export function isGovernanceStopRowText(text) {
114
98
  const t = text.trimStart();
115
- return t.startsWith(`${RUN_STOPPED_MESSAGE_PREFIX}:`) || t.startsWith(`${RUN_BLOCKED_MESSAGE_PREFIX}`);
99
+ return t.startsWith(`${RUN_STOPPED_MESSAGE_PREFIX}:`) || t.startsWith(`${RUN_BLOCKED_MESSAGE_PREFIX}`) || t.startsWith(PROMPT_BLOCKED_BY_HOOK_ROW_LEAD);
116
100
  }
117
101
  export const MODEL_OUTPUT_ERROR_PREFIX = 'Model output error';
118
102
  export function isModelOutputErrorText(text) {
@@ -133,13 +117,17 @@ function syntheticTerminalRow(ctx, text, historyKey, resend) {
133
117
  parent_tool_use_id: null,
134
118
  _sema_api_error_message: true,
135
119
  ...(historyKey !== undefined ? { _sema_tool_history_mismatch: historyKey } : {}),
136
- ...(resend !== undefined ? { _sema_provider_rejection_resend: { resend: resend.resend, text: resend.text } } : {}),
120
+ ...(resend !== undefined ? { _sema_provider_rejection_resend: { resend: resend.resend, text: resend.text, kind: resend.kind } } : {}),
137
121
  });
138
122
  }
139
123
  function engineRunIdOf(result) {
140
124
  const v = result?.runId;
141
125
  return typeof v === 'string' && v.length > 0 ? v : undefined;
142
126
  }
127
+ function engineResultOf(result) {
128
+ const v = doneResultView(result);
129
+ return v.replay ? (v.engine ?? result) : result;
130
+ }
143
131
  function engineSessionIdOf(result) {
144
132
  const v = result?.sessionId;
145
133
  return typeof v === 'string' && v.length > 0 ? v : undefined;
@@ -161,19 +149,14 @@ function terminalRowFacts(ev) {
161
149
  : doneTerminal?.kind === 'failed'
162
150
  ? (doneTerminal.message ?? doneTerminal.code ?? 'run failed')
163
151
  : doneTerminal?.kind === 'blocked'
164
- ? (doneTerminal.reason
165
- ? `Run blocked: ${doneTerminal.reason}`
166
- : 'Run blocked (the agent reported it cannot proceed)')
152
+ ? runBlockedText(doneTerminal)
167
153
  : null;
168
154
  const errText = errTextRaw === '' ? null : errTextRaw;
169
155
  if (errText === null)
170
156
  return { doneTerminal, errText, activeTaskId: undefined, busy: { busy: false, handle: null }, governance: false };
171
157
  const activeTaskId = (ev.type === 'done' ? ev.result?.activeTaskId : undefined) ??
172
158
  (ev.type === 'failed' ? ev.activeTaskId : undefined);
173
- const busy = classifyActiveRunBusy({
174
- errorCode: ev.type === 'failed' ? ev.errorCode : runTerminalCode(doneTerminal),
175
- activeTaskId,
176
- });
159
+ const busy = busyReadOfFrame(ev, doneTerminal, { value: activeTaskId })?.cls ?? { busy: false, handle: null };
177
160
  const governance = isGovernanceTerminal({
178
161
  status: ev.type === 'failed' ? undefined : doneTerminal?.kind === 'blocked' ? 'blocked' : undefined,
179
162
  errorCode: ev.type === 'failed' ? ev.errorCode : runTerminalCode(doneTerminal),
@@ -284,7 +267,7 @@ function apiErrorTerminalFromFacts(x, facts) {
284
267
  return none();
285
268
  if (type === 'failed')
286
269
  return { carrier: mintToolHistoryCarrier(nonEmptyStr(ownDataBit(x, 'errorCode')), undefined, nonEmptyStr(ownDataBit(x, 'errorMessage'))), detail: undefined };
287
- const result = type === 'done' ? plainObjectOf(ownDataBit(x, 'result')) : x;
270
+ const result = type === 'done' ? plainObjectOf(engineResultOf(ownDataBit(x, 'result'))) : x;
288
271
  if (result === undefined)
289
272
  return none();
290
273
  const snap = ownTerminalSnapshot(result);
@@ -667,12 +650,12 @@ async function* runStreamInner(events, ctx, handle = {}) {
667
650
  const abortNote = abortCauseNoteOf(ev);
668
651
  const historyTerminal = apiErrorTerminalOfRowFrame(ev, rowFacts);
669
652
  const historyMismatch = classifyToolHistoryMismatch(historyTerminal.carrier);
670
- const historyEchoedSid = ev.type === 'done' ? engineSessionIdOf(ev.result) : undefined;
653
+ const historyEchoedSid = ev.type === 'done' ? engineSessionIdOf(engineResultOf(ev.result)) : undefined;
671
654
  const historyRepeat = noteToolHistoryTerminal({
672
655
  sessionId: historyEchoedSid ?? ctx.sessionId,
673
656
  sessionEchoed: historyEchoedSid !== undefined,
674
657
  generation: historyGeneration,
675
- runId: ev.type === 'done' ? engineRunIdOf(ev.result) : undefined,
658
+ runId: ev.type === 'done' ? engineRunIdOf(engineResultOf(ev.result)) : undefined,
676
659
  replay: ev.type === 'done' && ev.replay === true,
677
660
  mismatch: historyMismatch,
678
661
  });
@@ -685,12 +668,12 @@ async function* runStreamInner(events, ctx, handle = {}) {
685
668
  yield syntheticTerminalRow(ctx, `${sessionUnreadable ? `${rowText}\n${corruptSessionContent()}` : rowText}${abortNote !== undefined ? `\n${abortNote}` : ''}${rewindLine}${resendLine}`, historyMismatch === null ? undefined : toolHistoryMismatchRowKey(historyMismatch, historyRepeat, rewindOffered), resend);
686
669
  }
687
670
  else {
688
- const echoedSid = ev.type === 'done' ? engineSessionIdOf(ev.result) : undefined;
671
+ const echoedSid = ev.type === 'done' ? engineSessionIdOf(engineResultOf(ev.result)) : undefined;
689
672
  noteToolHistoryTerminal({
690
673
  sessionId: echoedSid ?? ctx.sessionId,
691
674
  sessionEchoed: echoedSid !== undefined,
692
675
  generation: historyGeneration,
693
- runId: ev.type === 'done' ? engineRunIdOf(ev.result) : undefined,
676
+ runId: ev.type === 'done' ? engineRunIdOf(engineResultOf(ev.result)) : undefined,
694
677
  replay: ev.type === 'done' && ev.replay === true,
695
678
  mismatch: null,
696
679
  });
@@ -702,7 +685,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
702
685
  catch { }
703
686
  }
704
687
  if (ev.type === 'done' && ctx.emitChrome) {
705
- const doneStats = ev.result?.stats;
688
+ const doneStats = engineResultOf(ev.result)?.stats;
706
689
  const costFacts = readRunCostFacts(doneStats, { usageMissingObserved });
707
690
  if (costFacts !== undefined) {
708
691
  emitChromeFireAndForget(ctx, { kind: 'run_cost_reconciled', laneProof: mainLane(), ...costFacts.reconcile });
@@ -1,6 +1,7 @@
1
1
  import { errCodes } from '../controlRouter.js';
2
2
  import { hostLog } from '../host.js';
3
3
  import { isSessionIdPathSegment } from '../sessionIdSegment.js';
4
+ import { ownDataField } from '../ownKey.js';
4
5
  const unavailable = (why) => ({
5
6
  kind: 'unavailable',
6
7
  why,
@@ -58,12 +59,12 @@ export function isEngineAgentRegistryListingSuperseded(listing) {
58
59
  return registryListingProvenanceOf(listing)?.superseded === true;
59
60
  }
60
61
  function listFaceOn(caps) {
61
- if (typeof caps !== 'object' || caps === null || !Object.hasOwn(caps, 'background'))
62
+ if (typeof caps !== 'object' || caps === null)
62
63
  return false;
63
- const bg = caps.background;
64
- if (typeof bg !== 'object' || bg === null || !Object.hasOwn(bg, 'listFace'))
64
+ const bg = ownDataField(caps, 'background');
65
+ if (typeof bg !== 'object' || bg === null)
65
66
  return false;
66
- return bg.listFace === true;
67
+ return ownDataField(bg, 'listFace') === true;
67
68
  }
68
69
  function readRow(v) {
69
70
  if (typeof v !== 'object' || v === null || Array.isArray(v))
@@ -1,4 +1,4 @@
1
- import { engineCapValue } from '../engineCapsCache.js';
1
+ import { engineCapNestedValue } from '../engineCapsCache.js';
2
2
  import { isStatusDerivedCoarseCode } from '../engineErrorCodes.js';
3
3
  import { clientHasVerbs, engineWireFor, INJECTED_WIRE_SETTLE_MS, noAnswerDetailFrom, sendOnce, settleInjected } from '../engineWireFor.js';
4
4
  import { engineWireDebugEnabled } from '../engineWireTarget.js';
@@ -18,6 +18,8 @@ const DETAIL_NO_TARGET = `no engine connection is installed for this session${NO
18
18
  const DETAIL_NO_CLIENT = `an engine client could not be built from the installed connection${NOTHING_SENT}`;
19
19
  const DETAIL_CAPS_KEY_REQUIRED = `capability evidence for background.exitFaces is not available under the key the host named (capsBaseUrl)${NOTHING_SENT}`;
20
20
  const DETAIL_CAPS_UNOBSERVED = `the engine capabilities have not been read for this connection yet — wait for the capability probe to settle, then call again${NOTHING_SENT}`;
21
+ const DETAIL_CAPS_UNREADABLE = `the engine reported its capabilities in a form this client cannot read, so whether it offers the session background stop is unknown — calling again on this connection will not change that${NOTHING_SENT}`;
22
+ const DETAIL_CAPS_UNKNOWN_GENERIC = `whether the engine offers the session background stop is unknown${NOTHING_SENT}`;
21
23
  const DETAIL_NO_EXIT_FACE = `this engine does not offer the session background stop (capabilities.background.exitFaces is not true); background tasks may keep running${NOTHING_SENT}`;
22
24
  function refusedDetail(why) {
23
25
  switch (why) {
@@ -67,22 +69,27 @@ function unavailable(why, detail) {
67
69
  function usableStopClient(client) {
68
70
  return clientHasVerbs(client, [['sessions', 'backgroundStop']]);
69
71
  }
70
- function exitFaceGate(capsKey) {
71
- try {
72
- const v = engineCapValue(capsKey, 'background');
73
- if (v.kind === 'unobserved')
74
- return { why: 'capability_unknown', detail: DETAIL_CAPS_UNOBSERVED };
75
- if (v.kind !== 'value')
76
- return { why: 'no_exit_face', detail: DETAIL_NO_EXIT_FACE };
77
- const bg = v.value;
78
- if (typeof bg !== 'object' || bg === null || !Object.hasOwn(bg, 'exitFaces'))
79
- return { why: 'no_exit_face', detail: DETAIL_NO_EXIT_FACE };
80
- return bg.exitFaces === true ? null : { why: 'no_exit_face', detail: DETAIL_NO_EXIT_FACE };
81
- }
82
- catch {
83
- return { why: 'capability_unknown', detail: DETAIL_CAPS_UNOBSERVED };
72
+ function capsUnknownDetail(reason) {
73
+ switch (reason) {
74
+ case 'unobserved':
75
+ return DETAIL_CAPS_UNOBSERVED;
76
+ case 'unreadable':
77
+ return DETAIL_CAPS_UNREADABLE;
78
+ default: {
79
+ const unreachable = reason;
80
+ void unreachable;
81
+ return DETAIL_CAPS_UNKNOWN_GENERIC;
82
+ }
84
83
  }
85
84
  }
85
+ function exitFaceGate(capsKey) {
86
+ const v = engineCapNestedValue(capsKey, 'background', 'exitFaces');
87
+ if (v.kind === 'unobserved')
88
+ return { why: 'capability_unknown', detail: capsUnknownDetail('unobserved') };
89
+ if (v.kind === 'unreadable')
90
+ return { why: 'capability_unknown', detail: capsUnknownDetail('unreadable') };
91
+ return v.kind === 'value' && v.value === true ? null : { why: 'no_exit_face', detail: DETAIL_NO_EXIT_FACE };
92
+ }
86
93
  function readReceipt(v) {
87
94
  if (typeof v !== 'object' || v === null || Array.isArray(v))
88
95
  return undefined;
@@ -1,4 +1,5 @@
1
1
  import { hostEnv } from './hostEnv.js';
2
+ import { ownDataField } from './ownKey.js';
2
3
  import { makeEngineWireClient } from './engineWireSdk.js';
3
4
  import { frozenSet } from './frozenSet.js';
4
5
  import { settleWithinDeadline } from './abortableSleep.js';
@@ -289,7 +290,7 @@ export async function engineSupportsTaskAgents(baseUrl, opts) {
289
290
  if (typeof injected?.capabilities !== 'function')
290
291
  return undefined;
291
292
  const got = await settleWithinDeadline(opts.timeoutMs ?? 3000, (signal) => injected.capabilities({ signal }));
292
- return got.kind === 'value' ? got.value?.taskAgents === true : undefined;
293
+ return got.kind === 'value' ? taskAgentsOf(got.value) : undefined;
293
294
  }
294
295
  const client = makeEngineWireClient({
295
296
  baseUrl,
@@ -302,7 +303,17 @@ export async function engineSupportsTaskAgents(baseUrl, opts) {
302
303
  return undefined;
303
304
  try {
304
305
  const caps = await client.capabilities();
305
- return caps?.taskAgents === true;
306
+ return taskAgentsOf(caps);
307
+ }
308
+ catch {
309
+ return undefined;
310
+ }
311
+ }
312
+ function taskAgentsOf(caps) {
313
+ if (caps === null || typeof caps !== 'object')
314
+ return false;
315
+ try {
316
+ return ownDataField(caps, 'taskAgents') === true;
306
317
  }
307
318
  catch {
308
319
  return undefined;
@@ -7,9 +7,5 @@ export type CallerCwdReading = {
7
7
  value: boolean;
8
8
  };
9
9
  export declare function projectCallerCwdCapability(caps: unknown): CallerCwdReading | undefined;
10
- export declare function noteEngineCapsForCallerCwd(baseUrl: string, caps: unknown, opts?: {
11
- generation?: number;
12
- }): void;
13
10
  export declare function observedCallerCwd(baseUrl?: string | undefined): CallerCwdReading;
14
11
  export declare function callerCwdAdmitted(reading: CallerCwdReading | undefined): boolean;
15
- export declare function __resetCallerCwdReadingsForTests(): void;
@@ -19,9 +19,6 @@ const reader = createEngineCapReader({
19
19
  project: projectCallerCwdCapability,
20
20
  makeUnobserved: () => ({ kind: 'unobserved' }),
21
21
  });
22
- export function noteEngineCapsForCallerCwd(baseUrl, caps, opts) {
23
- reader.note(baseUrl, caps, opts);
24
- }
25
22
  export function observedCallerCwd(baseUrl = engineWireTarget()?.baseUrl) {
26
23
  return reader.observed(baseUrl);
27
24
  }
@@ -37,6 +34,3 @@ export function callerCwdAdmitted(reading) {
37
34
  return false;
38
35
  }
39
36
  }
40
- export function __resetCallerCwdReadingsForTests() {
41
- reader.__resetForTests();
42
- }
@@ -26,11 +26,7 @@ export type CenterWiringReading = {
26
26
  view: CenterWiringView;
27
27
  };
28
28
  export declare function projectCenterWiringCapability(caps: unknown): CenterWiringReading | undefined;
29
- export declare function noteEngineCapsForCenterWiring(baseUrl: string, caps: unknown, opts?: {
30
- generation?: number;
31
- }): void;
32
29
  export declare function observedCenterWiring(baseUrl?: string | undefined): CenterWiringReading;
33
30
  export type CallerQuotaLease = 'enforced' | 'not-enforced' | 'exhausted' | 'unobserved' | 'no-lease' | 'unknown';
34
31
  export declare function callerQuotaLease(reading: CenterWiringReading): CallerQuotaLease;
35
32
  export declare function centerWiringDoctorDetail(reading: CenterWiringReading): string;
36
- export declare function __resetCenterWiringReadingsForTests(): void;