@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
@@ -1,5 +1,4 @@
1
1
  import { frozenSet } from './frozenSet.js';
2
- import { CORE_TOOL_DECLARATION_CODES } from './generated/engineFactTables.js';
3
2
  import { SDK_DENY_REASON_ROUTING_FAILURE, SDK_RUN_DEATH_VERDICT_CODES, SDK_STATUS_DERIVED_COARSE_CODES } from './generated/sdkFactTables.js';
4
3
  export const LIMITS_MAX_TOKENS_EXCEEDED = 'limits.max_tokens_exceeded';
5
4
  export const LIMITS_MAX_COST_EXCEEDED = 'limits.max_cost_exceeded';
@@ -28,20 +27,6 @@ export function imageInvalidFailureNoteOf(code) {
28
27
  }
29
28
  export const CONFIG_AGENT_UNKNOWN_TOOL = 'config.agent.unknown_tool';
30
29
  export const CONFIG_OUTPUT_STYLE_INVALID = 'config.output_style_invalid';
31
- export const CONFIG_REFUSAL_CODES = frozenSet([
32
- CONFIG_LIMIT_INVALID,
33
- CONFIG_STRATEGY_FIND_LIMIT_INVALID,
34
- CONFIG_STRATEGY_MAX_SIZE_INVALID,
35
- CONFIG_LIMIT_UNKNOWN_KEY,
36
- CONFIG_DELEGATION_ENTRY_CAPS,
37
- CONFIG_MEMORY_PROJECT_KEY_SPELLING,
38
- CONFIG_MEMORY_WRITE_SCOPE_MISMATCH,
39
- CONFIG_LEGACY_TOOL_NAME,
40
- CONFIG_IMAGE_INVALID,
41
- CONFIG_AGENT_UNKNOWN_TOOL,
42
- CONFIG_OUTPUT_STYLE_INVALID,
43
- ...CORE_TOOL_DECLARATION_CODES,
44
- ]);
45
30
  export const RULES_LEGACY_TOOL_NAME = 'rules.legacy_tool_name';
46
31
  const RULES_ERROR_CODE_PREFIX = 'rules.';
47
32
  export function isRulesRefusalCode(code) {
@@ -77,8 +62,35 @@ export function isInterruptedToolEndCode(code) {
77
62
  return typeof code === 'string' && TOOL_END_INTERRUPTED_CODES.has(code);
78
63
  }
79
64
  export const CAPABILITY_SELF_ORCHESTRATION_REQUIRED = 'capability.self_orchestration_required';
65
+ export const CAPABILITY_IMAGE_INDEX_REQUIRED = 'capability.image_index_required';
80
66
  export const GATE_PARKED_ERROR_CODE = 'gate.parked';
81
67
  export const ACTIVE_RUN_BUSY_ERROR_CODE = 'conflict.session_active_run';
68
+ export function classifyActiveRunBusy(input) {
69
+ const handle = typeof input.activeTaskId === 'string' && input.activeTaskId.length > 0 ? input.activeTaskId : null;
70
+ if (input.errorCode === ACTIVE_RUN_BUSY_ERROR_CODE)
71
+ return { busy: true, handle };
72
+ if (typeof input.activeTaskId === 'string')
73
+ return { busy: true, handle };
74
+ return { busy: false, handle };
75
+ }
76
+ export function activeRunBusyCarrierOf(ev) {
77
+ if (typeof ev !== 'object' || ev === null || !('type' in ev))
78
+ return null;
79
+ const type = ev.type;
80
+ if (type === 'failed')
81
+ return ev;
82
+ if (type !== 'done')
83
+ return null;
84
+ const result = ev.result;
85
+ if (typeof result !== 'object' || result === null)
86
+ return null;
87
+ const status = result.status;
88
+ if (status === 'failed')
89
+ return result;
90
+ if (status === undefined && !Array.isArray(result) && Object.hasOwn(result, 'terminal'))
91
+ return result;
92
+ return null;
93
+ }
82
94
  export const CORRUPT_SESSION_ERROR_CODE = 'corrupt_session';
83
95
  export function isCorruptSessionCode(code) {
84
96
  return code === CORRUPT_SESSION_ERROR_CODE;
@@ -114,6 +126,14 @@ export const REQUEST_AUTONOMY_LANE_REFUSED = 'request.autonomy_lane_refused';
114
126
  export const CHECKPOINT_UNSUPPORTED_VERSION = 'checkpoint.unsupported_version';
115
127
  export const CHECKPOINT_WALLTIME_AXIS_RETIRED = 'checkpoint.walltime_axis_retired';
116
128
  export const CHECKPOINT_CONFIG_REFUSED = 'checkpoint.config_refused';
129
+ export const CHECKPOINT_REFUSED_PARK_CODES = Object.freeze([
130
+ CHECKPOINT_UNSUPPORTED_VERSION,
131
+ CHECKPOINT_WALLTIME_AXIS_RETIRED,
132
+ CHECKPOINT_CONFIG_REFUSED,
133
+ ]);
134
+ export function isRefusedParkCode(code) {
135
+ return typeof code === 'string' && CHECKPOINT_REFUSED_PARK_CODES.includes(code);
136
+ }
117
137
  export function refusalSaysStillPending(err) {
118
138
  return refusalRetriableReading(err) === true;
119
139
  }
@@ -167,6 +187,7 @@ export const RESUME_OUTCOME_INVALID = 'resume_outcome_invalid';
167
187
  export const CHECKPOINT_ALREADY_RESOLVED = 'checkpoint.already_resolved';
168
188
  export const NOT_FOUND_APPROVAL = 'not_found.approval';
169
189
  export const NOT_FOUND_CHECKPOINT = 'not_found.checkpoint';
190
+ export const NOT_FOUND_BLOB = 'not_found.blob';
170
191
  export const DECIDE_ALREADY_RESOLVED_CODES = Object.freeze([
171
192
  APPROVAL_STALE,
172
193
  CHECKPOINT_ALREADY_RESOLVED,
@@ -177,6 +198,7 @@ export function isDecideAlreadyResolvedCode(code) {
177
198
  return typeof code === 'string' && DECIDE_ALREADY_RESOLVED_CODES.includes(code);
178
199
  }
179
200
  export const ASK_GONE = 'gone.ask';
201
+ export const ASK_GONE_PARKED = 'gone.ask_parked';
180
202
  export const ASK_GONE_DENIED_WORD = SDK_DENY_REASON_ROUTING_FAILURE;
181
203
  export const RUN_DEATH_VERDICT_CODES = SDK_RUN_DEATH_VERDICT_CODES;
182
204
  const _runDeathVerdictCodePin = true;
@@ -171,6 +171,7 @@ export type ToolTurnIncompleteCause = (typeof CORE_TOOL_TURN_INCOMPLETE_CAUSES)[
171
171
  export interface ToolTurnIncompleteFactsView {
172
172
  cause: string;
173
173
  count: number;
174
+ outcome?: string;
174
175
  toolCallIds?: readonly string[];
175
176
  sessionId: string;
176
177
  runId: string;
@@ -201,6 +202,20 @@ export declare function readTurnInterrupted(notice: unknown): TurnInterruptedFac
201
202
  export declare function turnInterruptedNotice(facts: Pick<TurnInterruptedFactsView, 'lane'>): string | undefined;
202
203
  export type SteerCutVerdict = 'this_input' | 'other_input' | 'user_halt' | 'unattributed' | 'not_a_cut';
203
204
  export declare function steerCutVerdict(notice: unknown, messageId: string | undefined): SteerCutVerdict;
205
+ export interface FinishReasonUnknownFactsView {
206
+ finishReason: string;
207
+ sessionId: string;
208
+ runId: string;
209
+ }
210
+ export declare function readFinishReasonUnknown(notice: unknown): FinishReasonUnknownFactsView | undefined;
211
+ export interface StreamEndIgnoredFactsView {
212
+ statement: string;
213
+ word: string;
214
+ frames: number;
215
+ sessionId: string;
216
+ runId: string;
217
+ }
218
+ export declare function readStreamEndIgnored(notice: unknown): StreamEndIgnoredFactsView | undefined;
204
219
  export declare const ENGINE_NOTICE_FACT_READERS: Readonly<{
205
220
  readonly 'mcp.injection_dropped': typeof readMcpInjectionDrop;
206
221
  readonly 'delegation.ask_unresolvable': typeof readAskUnresolvable;
@@ -223,6 +238,8 @@ export declare const ENGINE_NOTICE_FACT_READERS: Readonly<{
223
238
  readonly 'task.user_steer_undrained': typeof readUserInputUndrained;
224
239
  readonly 'task.user_followup_undrained': typeof readUserInputUndrained;
225
240
  readonly 'task.turn_interrupted': typeof readTurnInterrupted;
241
+ readonly 'route.finish_reason_unknown': typeof readFinishReasonUnknown;
242
+ readonly 'route.stream_end_ignored': typeof readStreamEndIgnored;
226
243
  }>;
227
244
  type FactReaderTable = typeof ENGINE_NOTICE_FACT_READERS;
228
245
  export type EngineNoticeFactsCode = keyof FactReaderTable;
@@ -1,5 +1,6 @@
1
1
  import { AUTO_MODE_UNAVAILABLE_CAUSES } from './autoModeUnavailable.js';
2
2
  import { displayUntrusted } from './displayUntrusted.js';
3
+ import { currentEngineWord } from './engineWordRenames.js';
3
4
  import { CORE_ENGINE_NOTICE_CODES, CORE_MCP_INJECTION_DROP_REASONS, CORE_NOTICE_AUDIENCE, CORE_USER_INPUT_UNDRAINED_FAMILIES, } from './generated/engineNoticeTables.js';
4
5
  import { CORE_ASK_UNRESOLVABLE_CAUSES, CORE_DURABLE_MANDATE_SOURCES, CORE_PERMISSION_MODE_FOLD_REASONS, } from './generated/engineFactTables.js';
5
6
  export const ENGINE_NOTICE_CODES = CORE_ENGINE_NOTICE_CODES;
@@ -8,13 +9,13 @@ function audienceRow(table, code) {
8
9
  return Object.hasOwn(table, code) ? table[code] : undefined;
9
10
  }
10
11
  export function engineNoticeInCatalog(code) {
11
- return typeof code === 'string' && CATALOG.has(code);
12
+ return typeof code === 'string' && (CATALOG.has(code) || CATALOG.has(currentEngineWord(code)));
12
13
  }
13
14
  export const ENGINE_NOTICE_AUDIENCE = CORE_NOTICE_AUDIENCE;
14
15
  export function noticeAudienceOf(code) {
15
16
  if (typeof code !== 'string')
16
17
  return 'operator';
17
- return audienceRow(ENGINE_NOTICE_AUDIENCE, code) ?? 'operator';
18
+ return audienceRow(ENGINE_NOTICE_AUDIENCE, code) ?? audienceRow(ENGINE_NOTICE_AUDIENCE, currentEngineWord(code)) ?? 'operator';
18
19
  }
19
20
  export const MCP_INJECTION_DROP_REASONS = CORE_MCP_INJECTION_DROP_REASONS;
20
21
  const DROP_REASONS = new Set(MCP_INJECTION_DROP_REASONS);
@@ -602,12 +603,21 @@ function readToolTurnIncompleteOf(notice) {
602
603
  const o = d;
603
604
  const cause = nonEmpty(ownSeat(o, 'cause'));
604
605
  const count = positiveInt(ownSeat(o, 'count'));
606
+ const outcome = optionalNonEmpty(o, 'outcome');
605
607
  const toolCallIds = optionalNameList(o, 'toolCallIds');
606
608
  const sessionId = nonEmpty(ownSeat(o, 'sessionId'));
607
609
  const runId = nonEmpty(ownSeat(o, 'runId'));
608
610
  if (cause === undefined || count === undefined || sessionId === undefined || runId === undefined)
609
611
  return undefined;
610
- return { cause, count, ...(toolCallIds !== undefined ? { toolCallIds } : {}), sessionId, runId };
612
+ return { cause, count, ...(outcome !== undefined ? { outcome } : {}), ...(toolCallIds !== undefined ? { toolCallIds } : {}), sessionId, runId };
613
+ }
614
+ function optionalNonEmpty(o, key) {
615
+ try {
616
+ return nonEmpty(ownSeat(o, key));
617
+ }
618
+ catch {
619
+ return undefined;
620
+ }
611
621
  }
612
622
  export function readUserInputUndrained(notice) {
613
623
  return guardedRead(notice, readUserInputUndrainedOf);
@@ -779,6 +789,48 @@ export function steerCutVerdict(notice, messageId) {
779
789
  return 'unattributed';
780
790
  return facts.inputId === messageId ? 'this_input' : 'other_input';
781
791
  }
792
+ export function readFinishReasonUnknown(notice) {
793
+ return guardedRead(notice, readFinishReasonUnknownOf);
794
+ }
795
+ function readFinishReasonUnknownOf(notice) {
796
+ if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
797
+ return undefined;
798
+ const n = notice;
799
+ if (ownSeat(n, 'code') !== 'route.finish_reason_unknown')
800
+ return undefined;
801
+ const d = ownSeat(n, 'detail');
802
+ if (typeof d !== 'object' || d === null || Array.isArray(d))
803
+ return undefined;
804
+ const o = d;
805
+ const finishReason = nonEmpty(ownSeat(o, 'finishReason'));
806
+ const sessionId = nonEmpty(ownSeat(o, 'sessionId'));
807
+ const runId = nonEmpty(ownSeat(o, 'runId'));
808
+ if (finishReason === undefined || sessionId === undefined || runId === undefined)
809
+ return undefined;
810
+ return { finishReason, sessionId, runId };
811
+ }
812
+ export function readStreamEndIgnored(notice) {
813
+ return guardedRead(notice, readStreamEndIgnoredOf);
814
+ }
815
+ function readStreamEndIgnoredOf(notice) {
816
+ if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
817
+ return undefined;
818
+ const n = notice;
819
+ if (ownSeat(n, 'code') !== 'route.stream_end_ignored')
820
+ return undefined;
821
+ const d = ownSeat(n, 'detail');
822
+ if (typeof d !== 'object' || d === null || Array.isArray(d))
823
+ return undefined;
824
+ const o = d;
825
+ const statement = nonEmpty(ownSeat(o, 'statement'));
826
+ const word = nonEmpty(ownSeat(o, 'word'));
827
+ const frames = positiveInt(ownSeat(o, 'frames'));
828
+ const sessionId = nonEmpty(ownSeat(o, 'sessionId'));
829
+ const runId = nonEmpty(ownSeat(o, 'runId'));
830
+ if (statement === undefined || word === undefined || frames === undefined || sessionId === undefined || runId === undefined)
831
+ return undefined;
832
+ return { statement, word, frames, sessionId, runId };
833
+ }
782
834
  export const ENGINE_NOTICE_FACT_READERS = Object.freeze({
783
835
  'mcp.injection_dropped': readMcpInjectionDrop,
784
836
  'delegation.ask_unresolvable': readAskUnresolvable,
@@ -801,6 +853,8 @@ export const ENGINE_NOTICE_FACT_READERS = Object.freeze({
801
853
  'task.user_steer_undrained': readUserInputUndrained,
802
854
  'task.user_followup_undrained': readUserInputUndrained,
803
855
  'task.turn_interrupted': readTurnInterrupted,
856
+ 'route.finish_reason_unknown': readFinishReasonUnknown,
857
+ 'route.stream_end_ignored': readStreamEndIgnored,
804
858
  });
805
859
  const _factReaderTablePin = true;
806
860
  void _factReaderTablePin;
@@ -0,0 +1,8 @@
1
+ export declare const PRIOR_ENGINE_WORD_RENAMES: Readonly<{
2
+ readonly write_protection_unresolved: "target_unresolved";
3
+ }>;
4
+ export declare const PRIOR_ENGINE_NOTICE_CODE_RENAMES: Readonly<{
5
+ readonly 'config.write_protection_unresolved': "config.path_view_unresolved";
6
+ }>;
7
+ export type PriorEngineWord = keyof typeof PRIOR_ENGINE_WORD_RENAMES;
8
+ export declare function currentEngineWord(word: string): string;
@@ -0,0 +1,13 @@
1
+ export const PRIOR_ENGINE_WORD_RENAMES = Object.freeze({
2
+ write_protection_unresolved: 'target_unresolved',
3
+ });
4
+ export const PRIOR_ENGINE_NOTICE_CODE_RENAMES = Object.freeze({
5
+ 'config.write_protection_unresolved': 'config.path_view_unresolved',
6
+ });
7
+ export function currentEngineWord(word) {
8
+ if (Object.hasOwn(PRIOR_ENGINE_WORD_RENAMES, word))
9
+ return PRIOR_ENGINE_WORD_RENAMES[word];
10
+ if (Object.hasOwn(PRIOR_ENGINE_NOTICE_CODE_RENAMES, word))
11
+ return PRIOR_ENGINE_NOTICE_CODE_RENAMES[word];
12
+ return word;
13
+ }
@@ -16,5 +16,19 @@ export declare function fileHistoryCaptureMode(reading: FileHistoryCaptureReadin
16
16
  export declare function fileHistoryDeclarationField(reading: FileHistoryCaptureReading, captureOff: boolean): {
17
17
  fileHistory: 'disabled';
18
18
  } | Record<string, never>;
19
+ export declare const FILE_HISTORY_TIGHTEN_VERDICTS: readonly ["not_requested", "declare", "already_off", "unjudged"];
20
+ export type FileHistoryTightenVerdict = (typeof FILE_HISTORY_TIGHTEN_VERDICTS)[number];
21
+ export declare function fileHistoryTightenVerdict(reading: FileHistoryCaptureReading, captureOffByUser: boolean): FileHistoryTightenVerdict;
22
+ export declare function fileHistoryUnjudgedRefusal(reading: FileHistoryCaptureReading, captureOffByUser: boolean): string | undefined;
23
+ export interface FileHistoryTightenJudgement {
24
+ readonly verdict: FileHistoryTightenVerdict;
25
+ readonly reading: FileHistoryCaptureReading;
26
+ readonly refreshed: boolean;
27
+ readonly refusal: string | undefined;
28
+ }
29
+ export declare function judgeFileHistoryTighten(captureOffByUser: boolean, opts?: {
30
+ baseUrl?: string;
31
+ withinMs?: number;
32
+ }): Promise<FileHistoryTightenJudgement>;
19
33
  export declare function fileHistoryCaptureDoctorDetail(reading: FileHistoryCaptureReading): string;
20
34
  export declare function __resetFileHistoryCaptureReadingsForTests(): void;
@@ -1,6 +1,7 @@
1
1
  import { capForDisplay } from './fleetTaskDesc.js';
2
2
  import { engineWireTarget } from './engineWireTarget.js';
3
3
  import { createEngineCapReader } from './engineCapReader.js';
4
+ import { refreshEngineCapsOnce } from './engineCapsCache.js';
4
5
  import { ownDataField } from './ownKey.js';
5
6
  import { FILE_HISTORY_DISABLED } from './request/taskRequest.js';
6
7
  export function projectFileHistoryCaptureCapability(caps) {
@@ -52,6 +53,75 @@ export function fileHistoryCaptureMode(reading) {
52
53
  export function fileHistoryDeclarationField(reading, captureOff) {
53
54
  return captureOff === true && fileHistoryCaptureMode(reading) === 'on-optional' ? { fileHistory: FILE_HISTORY_DISABLED } : {};
54
55
  }
56
+ export const FILE_HISTORY_TIGHTEN_VERDICTS = Object.freeze(['not_requested', 'declare', 'already_off', 'unjudged']);
57
+ export function fileHistoryTightenVerdict(reading, captureOffByUser) {
58
+ if (captureOffByUser !== true)
59
+ return 'not_requested';
60
+ const mode = fileHistoryCaptureMode(reading);
61
+ if (mode === 'on-optional')
62
+ return 'declare';
63
+ if (mode === 'off')
64
+ return 'already_off';
65
+ return 'unjudged';
66
+ }
67
+ const FILE_HISTORY_UNJUDGED_REFUSAL = 'Nothing was sent: file checkpointing is turned off in your settings, but this engine did not report whether it can ' +
68
+ 'stop recording file history for a session, so sending now could record it anyway. Try again in a moment; to send ' +
69
+ 'regardless and let file history be recorded this time, turn file checkpointing back on in your settings.';
70
+ export function fileHistoryUnjudgedRefusal(reading, captureOffByUser) {
71
+ return fileHistoryTightenVerdict(reading, captureOffByUser) === 'unjudged' ? FILE_HISTORY_UNJUDGED_REFUSAL : undefined;
72
+ }
73
+ const FILE_HISTORY_REFRESH_WITHIN_MS = 3000;
74
+ export async function judgeFileHistoryTighten(captureOffByUser, opts) {
75
+ const closed = captureOffByUser === true;
76
+ const failClosed = () => {
77
+ const reading = { kind: 'unobserved' };
78
+ return closed
79
+ ? { verdict: 'unjudged', reading, refreshed: false, refusal: FILE_HISTORY_UNJUDGED_REFUSAL }
80
+ : { verdict: 'not_requested', reading, refreshed: false, refusal: undefined };
81
+ };
82
+ try {
83
+ let explicitBase;
84
+ let withinMs = FILE_HISTORY_REFRESH_WITHIN_MS;
85
+ if (typeof opts === 'object' && opts !== null) {
86
+ try {
87
+ const b = opts.baseUrl;
88
+ if (b !== undefined) {
89
+ if (typeof b !== 'string' || b === '')
90
+ return failClosed();
91
+ explicitBase = b;
92
+ }
93
+ }
94
+ catch {
95
+ return failClosed();
96
+ }
97
+ try {
98
+ const w = opts.withinMs;
99
+ if (w !== undefined)
100
+ withinMs = typeof w === 'number' ? w : 0;
101
+ }
102
+ catch {
103
+ withinMs = 0;
104
+ }
105
+ }
106
+ const baseUrl = explicitBase ?? engineWireTarget()?.baseUrl;
107
+ const first = observedFileHistoryCapture(baseUrl);
108
+ const v1 = fileHistoryTightenVerdict(first, captureOffByUser);
109
+ if (v1 !== 'unjudged')
110
+ return { verdict: v1, reading: first, refreshed: false, refusal: undefined };
111
+ const outcome = await refreshEngineCapsOnce(baseUrl, { withinMs });
112
+ const second = observedFileHistoryCapture(baseUrl);
113
+ const v2 = fileHistoryTightenVerdict(second, captureOffByUser);
114
+ return {
115
+ verdict: v2,
116
+ reading: second,
117
+ refreshed: outcome !== 'no_probe',
118
+ refusal: v2 === 'unjudged' ? FILE_HISTORY_UNJUDGED_REFUSAL : undefined,
119
+ };
120
+ }
121
+ catch {
122
+ return failClosed();
123
+ }
124
+ }
55
125
  const WORD_DETAIL_MAX = 40;
56
126
  export function fileHistoryCaptureDoctorDetail(reading) {
57
127
  const unobserved = 'file history capture not observed — the engine reports it on /v1/capabilities; this process has no usable capabilities reading cached for it, so whether this deployment captures file history is unknown';
@@ -0,0 +1,15 @@
1
+ import type { FleetTaskRow } from '@sema-agent/sdk';
2
+ export declare const DURABLE_AGENT_HANDLE_RE: RegExp;
3
+ export declare function isAgentHandle(rowId: string): boolean;
4
+ export type NonAgentHandleKind = 'background_bash' | 'monitor';
5
+ export declare function nonAgentHandleKind(rowId: string): NonAgentHandleKind | null;
6
+ export type BgSubagentRowFacts = Pick<FleetTaskRow, 'id' | 'parentId' | 'sourceLane'>;
7
+ export declare function isBackgroundSubagentRow(row: BgSubagentRowFacts): boolean;
8
+ export declare function isBackgroundWorkRow(row: BgSubagentRowFacts): boolean;
9
+ export interface BgRowOwnership {
10
+ readonly scoped: boolean;
11
+ readonly isOwnRun: (taskIdTail: string) => boolean;
12
+ }
13
+ export declare function liveBgRowOwnership(): BgRowOwnership;
14
+ export declare function liveBgRowOwnershipFor(sessionKey: string): BgRowOwnership;
15
+ export declare function isOwnBackgroundSubagentRow(row: BgSubagentRowFacts, own: BgRowOwnership): boolean;
@@ -0,0 +1,67 @@
1
+ import { CORE_DURABLE_AGENT_HANDLE_RE, CORE_TASK_HANDLE_PREFIXES } from '../generated/engineFactTables.js';
2
+ import { DEFAULT_SESSION_KEY } from '../sessionSlot.js';
3
+ import { isOwnEngineRun } from '../subagentContentStore.js';
4
+ import { isWorkflowAgentTaskId, rowIdTail } from '../workflow.js';
5
+ import { isFleetSessionScopedFor } from './fleetLedger.js';
6
+ import { wireParentId } from './fleetProjection.js';
7
+ const _taskTypePins = [true, true];
8
+ void _taskTypePins;
9
+ export const DURABLE_AGENT_HANDLE_RE = CORE_DURABLE_AGENT_HANDLE_RE;
10
+ export function isAgentHandle(rowId) {
11
+ if (typeof rowId !== 'string' || rowId.length === 0)
12
+ return false;
13
+ if (rowIdTail(rowId) !== rowId)
14
+ return false;
15
+ return DURABLE_AGENT_HANDLE_RE.test(rowId) || isWorkflowAgentTaskId(rowId);
16
+ }
17
+ const NON_AGENT_HANDLE_TYPES = ['background_bash', 'monitor'];
18
+ export function nonAgentHandleKind(rowId) {
19
+ if (typeof rowId !== 'string')
20
+ return null;
21
+ const prefix = /^([a-z])[0-9a-f]{16}$/.exec(rowIdTail(rowId))?.[1];
22
+ if (prefix === undefined)
23
+ return null;
24
+ for (const type of NON_AGENT_HANDLE_TYPES)
25
+ if (CORE_TASK_HANDLE_PREFIXES[type] === prefix)
26
+ return type;
27
+ return null;
28
+ }
29
+ const RUN_LEG_LANE = 'run-leg';
30
+ function isForegroundDelegationRow(row) {
31
+ return rowIdTail(row.id) !== row.id || row.sourceLane === RUN_LEG_LANE;
32
+ }
33
+ function hasRowId(row) {
34
+ return typeof row?.id === 'string' && row.id.length > 0;
35
+ }
36
+ export function isBackgroundSubagentRow(row) {
37
+ if (!hasRowId(row))
38
+ return false;
39
+ if (isForegroundDelegationRow(row))
40
+ return false;
41
+ if (nonAgentHandleKind(row.id) !== null)
42
+ return false;
43
+ if (wireParentId(row) !== undefined)
44
+ return true;
45
+ return isAgentHandle(row.id);
46
+ }
47
+ export function isBackgroundWorkRow(row) {
48
+ if (isBackgroundSubagentRow(row))
49
+ return true;
50
+ if (!hasRowId(row))
51
+ return false;
52
+ return !isForegroundDelegationRow(row) && nonAgentHandleKind(row.id) !== null;
53
+ }
54
+ export function liveBgRowOwnership() {
55
+ return liveBgRowOwnershipFor(DEFAULT_SESSION_KEY);
56
+ }
57
+ export function liveBgRowOwnershipFor(sessionKey) {
58
+ return { scoped: isFleetSessionScopedFor(sessionKey), isOwnRun: isOwnEngineRun };
59
+ }
60
+ export function isOwnBackgroundSubagentRow(row, own) {
61
+ if (!isBackgroundSubagentRow(row))
62
+ return false;
63
+ if (own.scoped)
64
+ return true;
65
+ const parentId = wireParentId(row);
66
+ return own.isOwnRun(rowIdTail(row.id)) || (parentId !== undefined && own.isOwnRun(rowIdTail(parentId)));
67
+ }
@@ -6,6 +6,7 @@ export interface EngineActiveBgTask {
6
6
  name?: string;
7
7
  status: string;
8
8
  parentId?: string;
9
+ sourceLane?: string;
9
10
  retiredByNotification?: boolean;
10
11
  }
11
12
  export interface EngineActiveBgReading {