@sema-agent/client-core 0.95.0 → 0.97.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 (233) hide show
  1. package/CHANGELOG.md +269 -0
  2. package/README.md +61 -31
  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 -2
  8. package/dist/adapter/activeRunSelfHeal.js +32 -6
  9. package/dist/adapter/downstream/eventToSdkMessage.js +11 -3
  10. package/dist/adapter/downstream/terminalToSdkResult.js +14 -11
  11. package/dist/adapter/runStream.js +30 -47
  12. package/dist/agentSession/backgroundView.js +2 -15
  13. package/dist/agentSession/engineAgentRegistryRead.js +5 -4
  14. package/dist/agentSession/engineSessionBackgroundStop.js +22 -15
  15. package/dist/agentsWireCaps.d.ts +1 -1
  16. package/dist/agentsWireCaps.js +29 -12
  17. package/dist/approvalDecidedByCapability.d.ts +2 -0
  18. package/dist/approvalDecidedByCapability.js +0 -1
  19. package/dist/approvalsStreamLiveCapability.d.ts +2 -0
  20. package/dist/approvalsStreamLiveCapability.js +3 -2
  21. package/dist/attachmentSeatCapability.d.ts +2 -0
  22. package/dist/attachmentSeatCapability.js +0 -1
  23. package/dist/callerCwdCapability.d.ts +2 -4
  24. package/dist/callerCwdCapability.js +0 -7
  25. package/dist/centerWiringCapability.d.ts +2 -4
  26. package/dist/centerWiringCapability.js +4 -9
  27. package/dist/classifierVerdictWire.js +4 -16
  28. package/dist/clientSlice.js +1 -1
  29. package/dist/cloudConfigWireCaps.d.ts +4 -4
  30. package/dist/cloudConfigWireCaps.js +241 -85
  31. package/dist/coreValuePorts.d.ts +11 -7
  32. package/dist/coreValuePorts.js +5 -8
  33. package/dist/credentialProvenance.d.ts +28 -0
  34. package/dist/credentialProvenance.js +76 -0
  35. package/dist/decideFailureNote.js +3 -1
  36. package/dist/decideReceipt.js +7 -10
  37. package/dist/declared/supportFloorDeclared.js +3 -3
  38. package/dist/deviceExecutorManagementCapability.d.ts +2 -0
  39. package/dist/deviceExecutorManagementCapability.js +3 -2
  40. package/dist/displayUntrusted.d.ts +10 -3
  41. package/dist/displayUntrusted.js +371 -60
  42. package/dist/engineCapReader.d.ts +8 -2
  43. package/dist/engineCapReader.js +15 -7
  44. package/dist/engineCapsCache.d.ts +17 -3
  45. package/dist/engineCapsCache.js +268 -43
  46. package/dist/engineDirectory.d.ts +79 -0
  47. package/dist/engineDirectory.js +186 -0
  48. package/dist/engineErrorCodes.d.ts +17 -1
  49. package/dist/engineErrorCodes.js +46 -16
  50. package/dist/engineNoticeCodes.d.ts +17 -0
  51. package/dist/engineNoticeCodes.js +54 -1
  52. package/dist/executionLaneCapability.d.ts +2 -0
  53. package/dist/executionLaneCapability.js +3 -2
  54. package/dist/fileHistoryCaptureCapability.d.ts +16 -0
  55. package/dist/fileHistoryCaptureCapability.js +98 -2
  56. package/dist/fileHistoryLegNotice.js +4 -0
  57. package/dist/fleet/bgSubagentRow.d.ts +15 -0
  58. package/dist/fleet/bgSubagentRow.js +67 -0
  59. package/dist/fleet/fleetLedger.d.ts +1 -0
  60. package/dist/fleet/fleetLedger.js +164 -126
  61. package/dist/fleet/fleetProjection.d.ts +1 -0
  62. package/dist/fleet/fleetProjection.js +10 -3
  63. package/dist/fleetTaskDesc.js +4 -17
  64. package/dist/gateOutcome.d.ts +12 -1
  65. package/dist/gateOutcome.js +56 -1
  66. package/dist/gateVocabulary.d.ts +2 -2
  67. package/dist/gateVocabulary.js +4 -3
  68. package/dist/generated/engineAskFaceTables.js +1 -1
  69. package/dist/generated/engineFactTables.d.ts +5 -3
  70. package/dist/generated/engineFactTables.js +17 -4
  71. package/dist/generated/engineNoticeTables.js +12 -3
  72. package/dist/generated/sdkFactTables.d.ts +2 -0
  73. package/dist/generated/sdkFactTables.js +7 -0
  74. package/dist/generated/settingsSchemaFns.d.ts +3 -0
  75. package/dist/generated/settingsSchemaFns.js +53 -0
  76. package/dist/generated/toolNameTables.d.ts +1 -1
  77. package/dist/generated/toolNameTables.js +1 -42
  78. package/dist/hitl/approvalDecisionNoteAudit.js +2 -2
  79. package/dist/hitl/approvalEndingCause.d.ts +2 -0
  80. package/dist/hitl/approvalEndingCause.js +26 -21
  81. package/dist/hitl/approvalHolds.d.ts +16 -1
  82. package/dist/hitl/approvalHolds.js +52 -12
  83. package/dist/hitl/askGateWire.js +1 -0
  84. package/dist/hitl/askParkRowRouting.js +1 -1
  85. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  86. package/dist/hitl/automaticAnswerVerdict.js +13 -10
  87. package/dist/hitl/decisionConflict.js +4 -5
  88. package/dist/hitl/decisionRefusal.d.ts +8 -0
  89. package/dist/hitl/decisionRefusal.js +55 -14
  90. package/dist/hitl/frameRouter.d.ts +3 -1
  91. package/dist/hitl/frameRouter.js +58 -39
  92. package/dist/hitl/gateLedger.d.ts +0 -5
  93. package/dist/hitl/gateLedger.js +0 -21
  94. package/dist/hitl/hitlBridge.d.ts +6 -2
  95. package/dist/hitl/hitlBridge.js +46 -11
  96. package/dist/hitl/localAllowRule.d.ts +1 -0
  97. package/dist/hitl/localAllowRule.js +2 -2
  98. package/dist/hitl/noAllowCause.d.ts +2 -1
  99. package/dist/hitl/noAllowCause.js +3 -2
  100. package/dist/hitl/parkResolver.d.ts +1 -0
  101. package/dist/hitl/parkResolver.js +14 -56
  102. package/dist/hitl/parkRowBirthWait.d.ts +1 -0
  103. package/dist/hitl/parkRowBirthWait.js +2 -2
  104. package/dist/hitl/planReviewWire.d.ts +1 -0
  105. package/dist/hitl/planReviewWire.js +98 -20
  106. package/dist/hitl/replayedApproval.d.ts +3 -3
  107. package/dist/hitl/replayedApproval.js +21 -16
  108. package/dist/hitl/sessionPolicyDeliverable.d.ts +0 -1
  109. package/dist/hitl/sessionPolicyDeliverable.js +17 -17
  110. package/dist/hitl/sessionPolicyWire.d.ts +2 -0
  111. package/dist/hitl/sessionPolicyWire.js +15 -3
  112. package/dist/hitl/standingRows.d.ts +19 -0
  113. package/dist/hitl/standingRows.js +148 -0
  114. package/dist/hitl/suspendedReopen.js +2 -1
  115. package/dist/hitl/toolApprovalWire.d.ts +22 -10
  116. package/dist/hitl/toolApprovalWire.js +286 -47
  117. package/dist/hookMatcherVerdict.d.ts +1 -9
  118. package/dist/hookMatcherVerdict.js +21 -61
  119. package/dist/hooksWireCaps.js +2 -2
  120. package/dist/hostCallbackGuard.d.ts +1 -0
  121. package/dist/hostCallbackGuard.js +6 -0
  122. package/dist/index.d.ts +26 -12
  123. package/dist/index.js +20 -10
  124. package/dist/liveModelCatalog.d.ts +13 -0
  125. package/dist/liveModelCatalog.js +56 -0
  126. package/dist/mcpProbeCapability.d.ts +2 -4
  127. package/dist/mcpProbeCapability.js +3 -8
  128. package/dist/mcpWireCaps.d.ts +1 -0
  129. package/dist/mcpWireCaps.js +4 -1
  130. package/dist/memoryComplianceCapability.d.ts +2 -4
  131. package/dist/memoryComplianceCapability.js +3 -8
  132. package/dist/memoryOriginCapability.d.ts +2 -4
  133. package/dist/memoryOriginCapability.js +3 -8
  134. package/dist/memorySpecWire.js +2 -2
  135. package/dist/modelIdentityResolvability.d.ts +2 -2
  136. package/dist/modelIdentityResolvability.js +14 -5
  137. package/dist/noticePresentation.d.ts +68 -0
  138. package/dist/noticePresentation.js +247 -0
  139. package/dist/outputStyleSeatCapability.d.ts +2 -1
  140. package/dist/outputStyleSeatCapability.js +0 -4
  141. package/dist/ownKey.d.ts +2 -0
  142. package/dist/ownKey.js +18 -0
  143. package/dist/peerFrames.js +13 -9
  144. package/dist/peerLaneCapability.d.ts +2 -0
  145. package/dist/peerLaneCapability.js +3 -2
  146. package/dist/permissionModesCapability.d.ts +2 -4
  147. package/dist/permissionModesCapability.js +0 -7
  148. package/dist/permissionRuleIssue.js +0 -3
  149. package/dist/permissionRulesWriteCapability.d.ts +2 -0
  150. package/dist/permissionRulesWriteCapability.js +3 -2
  151. package/dist/permissionsAllowGrantCapability.d.ts +2 -0
  152. package/dist/permissionsAllowGrantCapability.js +4 -2
  153. package/dist/permissionsDeclaration.d.ts +2 -0
  154. package/dist/permissionsDeclaration.js +72 -59
  155. package/dist/printPermissionOutcome.d.ts +12 -0
  156. package/dist/printPermissionOutcome.js +50 -0
  157. package/dist/printToolResultFrame.d.ts +1 -0
  158. package/dist/printToolResultFrame.js +5 -9
  159. package/dist/promptBlockedCopy.d.ts +5 -0
  160. package/dist/promptBlockedCopy.js +35 -0
  161. package/dist/protocolSegment.d.ts +9 -6
  162. package/dist/protocolSegment.js +31 -21
  163. package/dist/providerRejection.d.ts +4 -0
  164. package/dist/providerRejection.js +75 -14
  165. package/dist/replayBody.d.ts +12 -0
  166. package/dist/replayBody.js +25 -0
  167. package/dist/request/taskRequest.d.ts +1 -4
  168. package/dist/request/taskRequest.js +74 -19
  169. package/dist/resumeRefusalCopy.js +9 -25
  170. package/dist/retryStatus.d.ts +9 -1
  171. package/dist/retryStatus.js +9 -2
  172. package/dist/rewindArchiveCapability.d.ts +3 -13
  173. package/dist/rewindArchiveCapability.js +12 -58
  174. package/dist/rewindArchiveReading.d.ts +17 -0
  175. package/dist/rewindArchiveReading.js +55 -0
  176. package/dist/ruleCompileVerdict.d.ts +9 -1
  177. package/dist/ruleCompileVerdict.js +29 -4
  178. package/dist/runTerminal.d.ts +48 -5
  179. package/dist/runTerminal.js +215 -12
  180. package/dist/sandboxWire.js +13 -0
  181. package/dist/sdkWireTransit.d.ts +2 -1
  182. package/dist/sdkWireTransit.js +1 -0
  183. package/dist/sealedKeyCapability.d.ts +2 -4
  184. package/dist/sealedKeyCapability.js +0 -7
  185. package/dist/seam.js +4 -2
  186. package/dist/seatContract.d.ts +76 -11
  187. package/dist/seatContract.js +222 -27
  188. package/dist/sessionPolicyCapability.d.ts +2 -0
  189. package/dist/sessionPolicyCapability.js +3 -2
  190. package/dist/sessionReadRedactionCapability.d.ts +2 -4
  191. package/dist/sessionReadRedactionCapability.js +0 -7
  192. package/dist/sessionSyncFileHistory.d.ts +4 -0
  193. package/dist/sessionSyncFileHistory.js +66 -0
  194. package/dist/sessionSyncFileHistoryCapability.d.ts +2 -1
  195. package/dist/sessionSyncFileHistoryCapability.js +3 -5
  196. package/dist/skillToolListsCapability.d.ts +2 -1
  197. package/dist/skillToolListsCapability.js +3 -5
  198. package/dist/sqlEngineCapability.d.ts +2 -0
  199. package/dist/sqlEngineCapability.js +4 -3
  200. package/dist/steerPriorityCapability.d.ts +2 -1
  201. package/dist/steerPriorityCapability.js +3 -5
  202. package/dist/storePostureCapability.d.ts +2 -4
  203. package/dist/storePostureCapability.js +4 -9
  204. package/dist/subagent/engineSubagentSteer.js +7 -5
  205. package/dist/subagentContentStore.js +4 -15
  206. package/dist/supportFloor.d.ts +1 -0
  207. package/dist/supportFloor.js +13 -9
  208. package/dist/systemReminderTag.d.ts +1 -0
  209. package/dist/systemReminderTag.js +8 -0
  210. package/dist/toolHistoryBadTurn.js +3 -2
  211. package/dist/toolHistoryMismatch.d.ts +0 -3
  212. package/dist/toolHistoryMismatch.js +3 -7
  213. package/dist/toolResult.d.ts +12 -1
  214. package/dist/toolResult.js +55 -1
  215. package/dist/toolResultContent.d.ts +2 -0
  216. package/dist/toolResultContent.js +63 -0
  217. package/dist/usageAnalytics.js +40 -16
  218. package/dist/userInvokedSkillsCapability.d.ts +2 -1
  219. package/dist/userInvokedSkillsCapability.js +3 -5
  220. package/dist/webSearchBackendCapability.d.ts +2 -0
  221. package/dist/webSearchBackendCapability.js +3 -2
  222. package/dist/wireErrorTriage.d.ts +2 -0
  223. package/dist/wireErrorTriage.js +91 -38
  224. package/dist/wireFailureShape.d.ts +20 -3
  225. package/dist/wireFailureShape.js +128 -72
  226. package/dist/workflowsJournalCapability.d.ts +2 -0
  227. package/dist/workflowsJournalCapability.js +3 -2
  228. package/dist/writeProtectionCapability.d.ts +2 -0
  229. package/dist/writeProtectionCapability.js +3 -2
  230. package/docs/INTEGRATION-CLIENTS.md +1784 -20
  231. package/package.json +5 -5
  232. package/dist/engineRefusedToolName.d.ts +0 -1
  233. package/dist/engineRefusedToolName.js +0 -8
@@ -0,0 +1,186 @@
1
+ import { guardedRead, readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
2
+ const KIND_WORDS = ['managed'];
3
+ const POSTURE_WORDS = ['single', 'multi'];
4
+ const RULE_WORDS = ['only-one', 'none', 'ambiguous'];
5
+ const UNREADABLE = Object.freeze({ kind: 'unreadable' });
6
+ function isCenterRelativePath(path) {
7
+ if (path.length === 0 || path.charCodeAt(0) !== 0x2f)
8
+ return false;
9
+ const second = path.charCodeAt(1);
10
+ if (second === 0x2f || second === 0x5c)
11
+ return false;
12
+ if (/[\s\u0000-\u001f\u007f-\u009f\\?#]/u.test(path))
13
+ return false;
14
+ return path.split('/').every((segment) => {
15
+ const decoded = segment.replace(/%2e/gi, '.');
16
+ return decoded !== '.' && decoded !== '..';
17
+ });
18
+ }
19
+ function isObj(v) {
20
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
21
+ }
22
+ function stringOf(holder, key) {
23
+ return guardedRead(() => readOwnDataNonEmptyString(holder, key));
24
+ }
25
+ function boolOf(holder, key) {
26
+ return guardedRead(() => {
27
+ const v = readOwnDataValue(holder, key);
28
+ return typeof v === 'boolean' ? v : undefined;
29
+ });
30
+ }
31
+ function wordOf(holder, key, listed) {
32
+ const word = stringOf(holder, key);
33
+ if (word === undefined)
34
+ return UNREADABLE;
35
+ const hit = listed.find((w) => w === word);
36
+ return hit !== undefined ? { kind: 'listed', word: hit } : { kind: 'unlisted', word };
37
+ }
38
+ function rowOf(raw) {
39
+ try {
40
+ if (!isObj(raw))
41
+ return undefined;
42
+ const name = stringOf(raw, 'name');
43
+ if (name === undefined)
44
+ return undefined;
45
+ const connect = guardedRead(() => readOwnDataValue(raw, 'connect'));
46
+ if (!isObj(connect))
47
+ return undefined;
48
+ const viaCenter = stringOf(connect, 'viaCenter');
49
+ if (viaCenter === undefined || !isCenterRelativePath(viaCenter))
50
+ return undefined;
51
+ return {
52
+ name,
53
+ kind: wordOf(raw, 'kind', KIND_WORDS),
54
+ scope: stringOf(raw, 'scope'),
55
+ online: boolOf(raw, 'online'),
56
+ posture: wordOf(raw, 'posture', POSTURE_WORDS),
57
+ viaCenter,
58
+ };
59
+ }
60
+ catch {
61
+ return undefined;
62
+ }
63
+ }
64
+ function rowSetOf(raw) {
65
+ try {
66
+ if (!Array.isArray(raw))
67
+ return undefined;
68
+ const length = readOwnDataValue(raw, 'length');
69
+ if (typeof length !== 'number' || !Number.isSafeInteger(length) || length < 0)
70
+ return undefined;
71
+ const rows = [];
72
+ const unreadableNames = [];
73
+ let unreadableRows = 0;
74
+ for (let i = 0; i < length; i += 1) {
75
+ const element = guardedRead(() => readOwnDataValue(raw, String(i)));
76
+ const row = rowOf(element);
77
+ if (row !== undefined) {
78
+ rows.push(row);
79
+ continue;
80
+ }
81
+ unreadableRows += 1;
82
+ const name = guardedRead(() => (isObj(element) ? stringOf(element, 'name') : undefined));
83
+ if (name !== undefined)
84
+ unreadableNames.push(name);
85
+ }
86
+ return { rows, unreadableRows, unreadableNames };
87
+ }
88
+ catch {
89
+ return undefined;
90
+ }
91
+ }
92
+ export function projectEngineDirectory(body) {
93
+ try {
94
+ if (!isObj(body))
95
+ return undefined;
96
+ return rowSetOf(readOwnDataValue(body, 'engines'));
97
+ }
98
+ catch {
99
+ return undefined;
100
+ }
101
+ }
102
+ export function projectMeEngine(body) {
103
+ try {
104
+ if (!isObj(body))
105
+ return undefined;
106
+ const rule = wordOf(body, 'rule', RULE_WORDS);
107
+ const rawTarget = guardedRead(() => readOwnDataValue(body, 'target'));
108
+ let target = UNREADABLE;
109
+ if (rawTarget === null) {
110
+ target = { kind: 'null' };
111
+ }
112
+ else {
113
+ const row = rowOf(rawTarget);
114
+ if (row !== undefined)
115
+ target = { kind: 'row', row };
116
+ }
117
+ const candidates = guardedRead(() => rowSetOf(readOwnDataValue(body, 'candidates')));
118
+ if (rule.kind === 'unreadable' && target.kind === 'unreadable' && candidates === undefined)
119
+ return undefined;
120
+ return { rule, target, candidates };
121
+ }
122
+ catch {
123
+ return undefined;
124
+ }
125
+ }
126
+ export function decideMeEngine(reading) {
127
+ try {
128
+ if (reading === undefined)
129
+ return { kind: 'unresolved', reason: 'body', rule: UNREADABLE, candidates: undefined };
130
+ const { rule, target, candidates } = reading;
131
+ const unresolved = (reason) => ({ kind: 'unresolved', reason, rule, candidates });
132
+ if (rule.kind === 'unreadable')
133
+ return unresolved('rule');
134
+ if (target.kind === 'unreadable')
135
+ return unresolved('target');
136
+ if (target.kind === 'row') {
137
+ if (rule.kind === 'listed' && (rule.word === 'none' || rule.word === 'ambiguous'))
138
+ return unresolved('conflict');
139
+ if (candidates === undefined)
140
+ return unresolved('candidates');
141
+ const picked = target.row;
142
+ if (!candidates.rows.some((row) => row.name === picked.name && row.viaCenter === picked.viaCenter))
143
+ return unresolved('conflict');
144
+ if (rule.kind === 'listed' && (candidates.rows.length !== 1 || candidates.unreadableRows !== 0))
145
+ return unresolved('conflict');
146
+ return { kind: 'connect', engine: picked, rule };
147
+ }
148
+ if (rule.kind === 'unlisted')
149
+ return unresolved('rule-unlisted');
150
+ if (rule.word === 'only-one')
151
+ return unresolved('conflict');
152
+ if (candidates === undefined)
153
+ return unresolved('candidates');
154
+ if (rule.word === 'none') {
155
+ if (candidates.rows.length === 0 && candidates.unreadableRows === 0)
156
+ return { kind: 'no-engine' };
157
+ return unresolved('conflict');
158
+ }
159
+ if (candidates.rows.length === 0)
160
+ return unresolved('candidates');
161
+ return candidates.rows.length + candidates.unreadableRows >= 2 ? { kind: 'choose', candidates } : unresolved('conflict');
162
+ }
163
+ catch {
164
+ return { kind: 'unresolved', reason: 'body', rule: UNREADABLE, candidates: undefined };
165
+ }
166
+ }
167
+ export function engineOverrideOf(set, requested) {
168
+ try {
169
+ if (typeof requested !== 'string' || requested === '')
170
+ return { kind: 'invalid' };
171
+ if (set === undefined)
172
+ return { kind: 'unreadable' };
173
+ const hits = set.rows.filter((row) => row.name === requested);
174
+ const hidden = set.unreadableNames.filter((name) => name === requested).length;
175
+ if (hits.length + hidden > 1)
176
+ return { kind: 'duplicate', name: requested };
177
+ if (hits.length === 1)
178
+ return { kind: 'select', engine: hits[0] };
179
+ if (hidden === 1)
180
+ return { kind: 'row-unreadable', name: requested };
181
+ return { kind: 'not-listed', candidates: set };
182
+ }
183
+ catch {
184
+ return { kind: 'unreadable' };
185
+ }
186
+ }
@@ -18,7 +18,6 @@ export declare const CONFIG_IMAGE_INVALID = "config.image_invalid";
18
18
  export declare function imageInvalidFailureNoteOf(code: string | undefined): string | undefined;
19
19
  export declare const CONFIG_AGENT_UNKNOWN_TOOL = "config.agent.unknown_tool";
20
20
  export declare const CONFIG_OUTPUT_STYLE_INVALID = "config.output_style_invalid";
21
- export declare const CONFIG_REFUSAL_CODES: ReadonlySet<string>;
22
21
  export declare const RULES_LEGACY_TOOL_NAME = "rules.legacy_tool_name";
23
22
  export declare function isRulesRefusalCode(code: string | undefined): boolean;
24
23
  export declare const DELEGATION_CONCURRENCY_CAP = "delegation.concurrency_cap";
@@ -33,8 +32,21 @@ export declare const TOOL_END_INTERRUPTED_NEVER_STARTED = "interrupted_never_sta
33
32
  export declare const TOOL_END_INTERRUPTED_OUTCOME_UNKNOWN = "interrupted_outcome_unknown";
34
33
  export declare function isInterruptedToolEndCode(code: string | undefined): boolean;
35
34
  export declare const CAPABILITY_SELF_ORCHESTRATION_REQUIRED = "capability.self_orchestration_required";
35
+ export declare const CAPABILITY_IMAGE_INDEX_REQUIRED = "capability.image_index_required";
36
36
  export declare const GATE_PARKED_ERROR_CODE = "gate.parked";
37
37
  export declare const ACTIVE_RUN_BUSY_ERROR_CODE = "conflict.session_active_run";
38
+ export declare const CONFLICT_IDEMPOTENCY_PAYLOAD_MISMATCH = "conflict.idempotency_payload_mismatch";
39
+ export declare function isIdempotencyPayloadMismatchCode(code: string | null | undefined): boolean;
40
+ export declare function idempotencyPayloadMismatchContent(): string;
41
+ export interface BusyClassification {
42
+ readonly busy: boolean;
43
+ readonly handle: string | null;
44
+ }
45
+ export declare function classifyActiveRunBusy(input: {
46
+ errorCode: string | undefined;
47
+ activeTaskId: unknown;
48
+ }): BusyClassification;
49
+ export declare function activeRunBusyCarrierOf(ev: unknown): Record<string, unknown> | null;
38
50
  export declare const CORRUPT_SESSION_ERROR_CODE = "corrupt_session";
39
51
  export declare function isCorruptSessionCode(code: string | null | undefined): boolean;
40
52
  export declare const STOP_PARK_ARBITER_UNREACHABLE = "stop.park_arbiter_unreachable";
@@ -58,6 +70,8 @@ export declare const REQUEST_AUTONOMY_LANE_REFUSED = "request.autonomy_lane_refu
58
70
  export declare const CHECKPOINT_UNSUPPORTED_VERSION = "checkpoint.unsupported_version";
59
71
  export declare const CHECKPOINT_WALLTIME_AXIS_RETIRED = "checkpoint.walltime_axis_retired";
60
72
  export declare const CHECKPOINT_CONFIG_REFUSED = "checkpoint.config_refused";
73
+ export declare const CHECKPOINT_REFUSED_PARK_CODES: readonly string[];
74
+ export declare function isRefusedParkCode(code: string | null | undefined): code is typeof CHECKPOINT_UNSUPPORTED_VERSION | typeof CHECKPOINT_WALLTIME_AXIS_RETIRED | typeof CHECKPOINT_CONFIG_REFUSED;
61
75
  export declare function refusalSaysStillPending(err: object): boolean;
62
76
  export declare function refusalRetriableReading(err: object): boolean | undefined;
63
77
  export type StatusDerivedCoarseCode = (typeof STATUS_DERIVED_COARSE_CODES)[number];
@@ -85,9 +99,11 @@ export declare const RESUME_OUTCOME_INVALID = "resume_outcome_invalid";
85
99
  export declare const CHECKPOINT_ALREADY_RESOLVED = "checkpoint.already_resolved";
86
100
  export declare const NOT_FOUND_APPROVAL = "not_found.approval";
87
101
  export declare const NOT_FOUND_CHECKPOINT = "not_found.checkpoint";
102
+ export declare const NOT_FOUND_BLOB = "not_found.blob";
88
103
  export declare const DECIDE_ALREADY_RESOLVED_CODES: readonly string[];
89
104
  export declare function isDecideAlreadyResolvedCode(code: string | null | undefined): boolean;
90
105
  export declare const ASK_GONE = "gone.ask";
106
+ export declare const ASK_GONE_PARKED = "gone.ask_parked";
91
107
  export declare const ASK_GONE_DENIED_WORD: "routing_failure_fail_closed";
92
108
  export declare const RUN_DEATH_VERDICT_CODES: readonly ["run.stalled", "run.orphaned", "approval.expired"];
93
109
  export type RunDeathVerdictCode = (typeof RUN_DEATH_VERDICT_CODES)[number];
@@ -1,5 +1,5 @@
1
1
  import { frozenSet } from './frozenSet.js';
2
- import { CORE_TOOL_DECLARATION_CODES } from './generated/engineFactTables.js';
2
+ import { ownDataField } from './ownKey.js';
3
3
  import { SDK_DENY_REASON_ROUTING_FAILURE, SDK_RUN_DEATH_VERDICT_CODES, SDK_STATUS_DERIVED_COARSE_CODES } from './generated/sdkFactTables.js';
4
4
  export const LIMITS_MAX_TOKENS_EXCEEDED = 'limits.max_tokens_exceeded';
5
5
  export const LIMITS_MAX_COST_EXCEEDED = 'limits.max_cost_exceeded';
@@ -28,20 +28,6 @@ export function imageInvalidFailureNoteOf(code) {
28
28
  }
29
29
  export const CONFIG_AGENT_UNKNOWN_TOOL = 'config.agent.unknown_tool';
30
30
  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
31
  export const RULES_LEGACY_TOOL_NAME = 'rules.legacy_tool_name';
46
32
  const RULES_ERROR_CODE_PREFIX = 'rules.';
47
33
  export function isRulesRefusalCode(code) {
@@ -77,8 +63,42 @@ export function isInterruptedToolEndCode(code) {
77
63
  return typeof code === 'string' && TOOL_END_INTERRUPTED_CODES.has(code);
78
64
  }
79
65
  export const CAPABILITY_SELF_ORCHESTRATION_REQUIRED = 'capability.self_orchestration_required';
66
+ export const CAPABILITY_IMAGE_INDEX_REQUIRED = 'capability.image_index_required';
80
67
  export const GATE_PARKED_ERROR_CODE = 'gate.parked';
81
68
  export const ACTIVE_RUN_BUSY_ERROR_CODE = 'conflict.session_active_run';
69
+ export const CONFLICT_IDEMPOTENCY_PAYLOAD_MISMATCH = 'conflict.idempotency_payload_mismatch';
70
+ export function isIdempotencyPayloadMismatchCode(code) {
71
+ return code === CONFLICT_IDEMPOTENCY_PAYLOAD_MISMATCH;
72
+ }
73
+ export function idempotencyPayloadMismatchContent() {
74
+ return 'This request reused an idempotency key that is already bound to a different request body, so the engine refused it and nothing ran · To retry, send exactly the same request again; to send a different request, use a new idempotency key';
75
+ }
76
+ export function classifyActiveRunBusy(input) {
77
+ const handle = typeof input.activeTaskId === 'string' && input.activeTaskId.length > 0 ? input.activeTaskId : null;
78
+ if (input.errorCode === ACTIVE_RUN_BUSY_ERROR_CODE)
79
+ return { busy: true, handle };
80
+ if (typeof input.activeTaskId === 'string')
81
+ return { busy: true, handle };
82
+ return { busy: false, handle };
83
+ }
84
+ export function activeRunBusyCarrierOf(ev) {
85
+ if (typeof ev !== 'object' || ev === null || !('type' in ev))
86
+ return null;
87
+ const type = ev.type;
88
+ if (type === 'failed')
89
+ return ev;
90
+ if (type !== 'done')
91
+ return null;
92
+ const result = ev.result;
93
+ if (typeof result !== 'object' || result === null)
94
+ return null;
95
+ const status = result.status;
96
+ if (status === 'failed')
97
+ return result;
98
+ if (status === undefined && !Array.isArray(result) && Object.hasOwn(result, 'terminal'))
99
+ return result;
100
+ return null;
101
+ }
82
102
  export const CORRUPT_SESSION_ERROR_CODE = 'corrupt_session';
83
103
  export function isCorruptSessionCode(code) {
84
104
  return code === CORRUPT_SESSION_ERROR_CODE;
@@ -114,12 +134,20 @@ export const REQUEST_AUTONOMY_LANE_REFUSED = 'request.autonomy_lane_refused';
114
134
  export const CHECKPOINT_UNSUPPORTED_VERSION = 'checkpoint.unsupported_version';
115
135
  export const CHECKPOINT_WALLTIME_AXIS_RETIRED = 'checkpoint.walltime_axis_retired';
116
136
  export const CHECKPOINT_CONFIG_REFUSED = 'checkpoint.config_refused';
137
+ export const CHECKPOINT_REFUSED_PARK_CODES = Object.freeze([
138
+ CHECKPOINT_UNSUPPORTED_VERSION,
139
+ CHECKPOINT_WALLTIME_AXIS_RETIRED,
140
+ CHECKPOINT_CONFIG_REFUSED,
141
+ ]);
142
+ export function isRefusedParkCode(code) {
143
+ return typeof code === 'string' && CHECKPOINT_REFUSED_PARK_CODES.includes(code);
144
+ }
117
145
  export function refusalSaysStillPending(err) {
118
146
  return refusalRetriableReading(err) === true;
119
147
  }
120
148
  export function refusalRetriableReading(err) {
121
149
  try {
122
- return Object.hasOwn(err, 'retriable') && err.retriable === true;
150
+ return ownDataField(err, 'retriable') === true;
123
151
  }
124
152
  catch {
125
153
  return undefined;
@@ -167,6 +195,7 @@ export const RESUME_OUTCOME_INVALID = 'resume_outcome_invalid';
167
195
  export const CHECKPOINT_ALREADY_RESOLVED = 'checkpoint.already_resolved';
168
196
  export const NOT_FOUND_APPROVAL = 'not_found.approval';
169
197
  export const NOT_FOUND_CHECKPOINT = 'not_found.checkpoint';
198
+ export const NOT_FOUND_BLOB = 'not_found.blob';
170
199
  export const DECIDE_ALREADY_RESOLVED_CODES = Object.freeze([
171
200
  APPROVAL_STALE,
172
201
  CHECKPOINT_ALREADY_RESOLVED,
@@ -177,6 +206,7 @@ export function isDecideAlreadyResolvedCode(code) {
177
206
  return typeof code === 'string' && DECIDE_ALREADY_RESOLVED_CODES.includes(code);
178
207
  }
179
208
  export const ASK_GONE = 'gone.ask';
209
+ export const ASK_GONE_PARKED = 'gone.ask_parked';
180
210
  export const ASK_GONE_DENIED_WORD = SDK_DENY_REASON_ROUTING_FAILURE;
181
211
  export const RUN_DEATH_VERDICT_CODES = SDK_RUN_DEATH_VERDICT_CODES;
182
212
  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;
@@ -602,12 +602,21 @@ function readToolTurnIncompleteOf(notice) {
602
602
  const o = d;
603
603
  const cause = nonEmpty(ownSeat(o, 'cause'));
604
604
  const count = positiveInt(ownSeat(o, 'count'));
605
+ const outcome = optionalNonEmpty(o, 'outcome');
605
606
  const toolCallIds = optionalNameList(o, 'toolCallIds');
606
607
  const sessionId = nonEmpty(ownSeat(o, 'sessionId'));
607
608
  const runId = nonEmpty(ownSeat(o, 'runId'));
608
609
  if (cause === undefined || count === undefined || sessionId === undefined || runId === undefined)
609
610
  return undefined;
610
- return { cause, count, ...(toolCallIds !== undefined ? { toolCallIds } : {}), sessionId, runId };
611
+ return { cause, count, ...(outcome !== undefined ? { outcome } : {}), ...(toolCallIds !== undefined ? { toolCallIds } : {}), sessionId, runId };
612
+ }
613
+ function optionalNonEmpty(o, key) {
614
+ try {
615
+ return nonEmpty(ownSeat(o, key));
616
+ }
617
+ catch {
618
+ return undefined;
619
+ }
611
620
  }
612
621
  export function readUserInputUndrained(notice) {
613
622
  return guardedRead(notice, readUserInputUndrainedOf);
@@ -779,6 +788,48 @@ export function steerCutVerdict(notice, messageId) {
779
788
  return 'unattributed';
780
789
  return facts.inputId === messageId ? 'this_input' : 'other_input';
781
790
  }
791
+ export function readFinishReasonUnknown(notice) {
792
+ return guardedRead(notice, readFinishReasonUnknownOf);
793
+ }
794
+ function readFinishReasonUnknownOf(notice) {
795
+ if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
796
+ return undefined;
797
+ const n = notice;
798
+ if (ownSeat(n, 'code') !== 'route.finish_reason_unknown')
799
+ return undefined;
800
+ const d = ownSeat(n, 'detail');
801
+ if (typeof d !== 'object' || d === null || Array.isArray(d))
802
+ return undefined;
803
+ const o = d;
804
+ const finishReason = nonEmpty(ownSeat(o, 'finishReason'));
805
+ const sessionId = nonEmpty(ownSeat(o, 'sessionId'));
806
+ const runId = nonEmpty(ownSeat(o, 'runId'));
807
+ if (finishReason === undefined || sessionId === undefined || runId === undefined)
808
+ return undefined;
809
+ return { finishReason, sessionId, runId };
810
+ }
811
+ export function readStreamEndIgnored(notice) {
812
+ return guardedRead(notice, readStreamEndIgnoredOf);
813
+ }
814
+ function readStreamEndIgnoredOf(notice) {
815
+ if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
816
+ return undefined;
817
+ const n = notice;
818
+ if (ownSeat(n, 'code') !== 'route.stream_end_ignored')
819
+ return undefined;
820
+ const d = ownSeat(n, 'detail');
821
+ if (typeof d !== 'object' || d === null || Array.isArray(d))
822
+ return undefined;
823
+ const o = d;
824
+ const statement = nonEmpty(ownSeat(o, 'statement'));
825
+ const word = nonEmpty(ownSeat(o, 'word'));
826
+ const frames = positiveInt(ownSeat(o, 'frames'));
827
+ const sessionId = nonEmpty(ownSeat(o, 'sessionId'));
828
+ const runId = nonEmpty(ownSeat(o, 'runId'));
829
+ if (statement === undefined || word === undefined || frames === undefined || sessionId === undefined || runId === undefined)
830
+ return undefined;
831
+ return { statement, word, frames, sessionId, runId };
832
+ }
782
833
  export const ENGINE_NOTICE_FACT_READERS = Object.freeze({
783
834
  'mcp.injection_dropped': readMcpInjectionDrop,
784
835
  'delegation.ask_unresolvable': readAskUnresolvable,
@@ -801,6 +852,8 @@ export const ENGINE_NOTICE_FACT_READERS = Object.freeze({
801
852
  'task.user_steer_undrained': readUserInputUndrained,
802
853
  'task.user_followup_undrained': readUserInputUndrained,
803
854
  'task.turn_interrupted': readTurnInterrupted,
855
+ 'route.finish_reason_unknown': readFinishReasonUnknown,
856
+ 'route.stream_end_ignored': readStreamEndIgnored,
804
857
  });
805
858
  const _factReaderTablePin = true;
806
859
  void _factReaderTablePin;
@@ -7,6 +7,8 @@ export interface ExecutionLaneCapabilityView {
7
7
  }
8
8
  export type ExecutionLaneReading = {
9
9
  kind: 'unobserved';
10
+ } | {
11
+ kind: 'unreadable';
10
12
  } | {
11
13
  kind: 'not_reported';
12
14
  } | {
@@ -1,6 +1,6 @@
1
1
  import { capForDisplay } from './fleetTaskDesc.js';
2
2
  import { engineWireTarget } from './engineWireTarget.js';
3
- import { createEngineCapReader } from './engineCapReader.js';
3
+ import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
4
4
  import { ownDataField } from './ownKey.js';
5
5
  export function projectExecutionLaneCapability(caps) {
6
6
  try {
@@ -55,7 +55,6 @@ export function projectExecutionLaneWiring(wiring) {
55
55
  const reader = createEngineCapReader({
56
56
  name: 'executionLane',
57
57
  project: projectExecutionLaneCapability,
58
- makeUnobserved: () => ({ kind: 'unobserved' }),
59
58
  });
60
59
  export function noteEngineCapsForExecutionLane(baseUrl, caps, opts) {
61
60
  reader.note(baseUrl, caps, opts);
@@ -98,6 +97,8 @@ export function noOsSandboxContent() {
98
97
  const LANE_DETAIL_MAX = 40;
99
98
  export function executionLaneDoctorDetail(reading) {
100
99
  switch (reading.kind) {
100
+ case 'unreadable':
101
+ return unreadableReadingDetail('execution lane');
101
102
  case 'unobserved':
102
103
  return ('execution lane not observed — the engine reports it on /v1/capabilities; ' +
103
104
  'this process has no usable capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)');
@@ -1,5 +1,7 @@
1
1
  export type FileHistoryCaptureReading = {
2
2
  kind: 'unobserved';
3
+ } | {
4
+ kind: 'unreadable';
3
5
  } | {
4
6
  kind: 'not_reported';
5
7
  } | {
@@ -16,5 +18,19 @@ export declare function fileHistoryCaptureMode(reading: FileHistoryCaptureReadin
16
18
  export declare function fileHistoryDeclarationField(reading: FileHistoryCaptureReading, captureOff: boolean): {
17
19
  fileHistory: 'disabled';
18
20
  } | Record<string, never>;
21
+ export declare const FILE_HISTORY_TIGHTEN_VERDICTS: readonly ["not_requested", "declare", "already_off", "unjudged"];
22
+ export type FileHistoryTightenVerdict = (typeof FILE_HISTORY_TIGHTEN_VERDICTS)[number];
23
+ export declare function fileHistoryTightenVerdict(reading: FileHistoryCaptureReading, captureOffByUser: boolean): FileHistoryTightenVerdict;
24
+ export declare function fileHistoryUnjudgedRefusal(reading: FileHistoryCaptureReading, captureOffByUser: boolean): string | undefined;
25
+ export interface FileHistoryTightenJudgement {
26
+ readonly verdict: FileHistoryTightenVerdict;
27
+ readonly reading: FileHistoryCaptureReading;
28
+ readonly refreshed: boolean;
29
+ readonly refusal: string | undefined;
30
+ }
31
+ export declare function judgeFileHistoryTighten(captureOffByUser: boolean, opts?: {
32
+ baseUrl?: string;
33
+ withinMs?: number;
34
+ }): Promise<FileHistoryTightenJudgement>;
19
35
  export declare function fileHistoryCaptureDoctorDetail(reading: FileHistoryCaptureReading): string;
20
36
  export declare function __resetFileHistoryCaptureReadingsForTests(): void;
@@ -1,6 +1,7 @@
1
1
  import { capForDisplay } from './fleetTaskDesc.js';
2
2
  import { engineWireTarget } from './engineWireTarget.js';
3
- import { createEngineCapReader } from './engineCapReader.js';
3
+ import { createEngineCapReader, unreadableReadingDetail } 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) {
@@ -21,7 +22,6 @@ export function projectFileHistoryCaptureCapability(caps) {
21
22
  const reader = createEngineCapReader({
22
23
  name: 'fileHistoryCapture',
23
24
  project: projectFileHistoryCaptureCapability,
24
- makeUnobserved: () => ({ kind: 'unobserved' }),
25
25
  });
26
26
  export function noteEngineCapsForFileHistoryCapture(baseUrl, caps, opts) {
27
27
  reader.note(baseUrl, caps, opts);
@@ -52,6 +52,100 @@ export function fileHistoryCaptureMode(reading) {
52
52
  export function fileHistoryDeclarationField(reading, captureOff) {
53
53
  return captureOff === true && fileHistoryCaptureMode(reading) === 'on-optional' ? { fileHistory: FILE_HISTORY_DISABLED } : {};
54
54
  }
55
+ export const FILE_HISTORY_TIGHTEN_VERDICTS = Object.freeze(['not_requested', 'declare', 'already_off', 'unjudged']);
56
+ export function fileHistoryTightenVerdict(reading, captureOffByUser) {
57
+ if (captureOffByUser !== true)
58
+ return 'not_requested';
59
+ const mode = fileHistoryCaptureMode(reading);
60
+ if (mode === 'on-optional')
61
+ return 'declare';
62
+ if (mode === 'off')
63
+ return 'already_off';
64
+ return 'unjudged';
65
+ }
66
+ const FILE_HISTORY_REFUSAL_NOT_YET = "Nothing was sent: file checkpointing is turned off in your settings, but this engine's capabilities have not been read " +
67
+ 'yet, so whether it can stop recording file history for a session is unknown and sending now could record it anyway. ' +
68
+ 'Try again in a moment; to send regardless and let file history be recorded this time, turn file checkpointing back on in your settings.';
69
+ const FILE_HISTORY_REFUSAL_NOT_SAID = 'Nothing was sent: file checkpointing is turned off in your settings, but this engine did not report whether it can ' +
70
+ 'stop recording file history for a session, so sending now could record it anyway. Trying again will not change that ' +
71
+ 'while this engine reports the same; to send and let file history be recorded this time, turn file checkpointing back on in your settings.';
72
+ const FILE_HISTORY_REFUSAL_UNREADABLE = "Nothing was sent: file checkpointing is turned off in your settings, but this engine's report on whether it can stop " +
73
+ 'recording file history for a session could not be read by this client, so sending now could record it anyway. Trying ' +
74
+ 'again will not change that while this engine reports the same; to send and let file history be recorded this time, ' +
75
+ 'turn file checkpointing back on in your settings.';
76
+ function unjudgedRefusalOf(reading) {
77
+ let kind;
78
+ let word;
79
+ try {
80
+ kind = typeof reading === 'object' && reading !== null ? reading.kind : undefined;
81
+ word = kind === 'present' ? reading.word : undefined;
82
+ }
83
+ catch {
84
+ return FILE_HISTORY_REFUSAL_NOT_YET;
85
+ }
86
+ if (kind === 'unreadable')
87
+ return FILE_HISTORY_REFUSAL_UNREADABLE;
88
+ if (kind === 'not_reported')
89
+ return FILE_HISTORY_REFUSAL_NOT_SAID;
90
+ if (kind === 'present' && typeof word === 'string' && word.length > 0)
91
+ return FILE_HISTORY_REFUSAL_NOT_SAID;
92
+ return FILE_HISTORY_REFUSAL_NOT_YET;
93
+ }
94
+ export function fileHistoryUnjudgedRefusal(reading, captureOffByUser) {
95
+ return fileHistoryTightenVerdict(reading, captureOffByUser) === 'unjudged' ? unjudgedRefusalOf(reading) : undefined;
96
+ }
97
+ const FILE_HISTORY_REFRESH_WITHIN_MS = 3000;
98
+ export async function judgeFileHistoryTighten(captureOffByUser, opts) {
99
+ const closed = captureOffByUser === true;
100
+ const failClosed = () => {
101
+ const reading = { kind: 'unobserved' };
102
+ return closed
103
+ ? { verdict: 'unjudged', reading, refreshed: false, refusal: FILE_HISTORY_REFUSAL_NOT_YET }
104
+ : { verdict: 'not_requested', reading, refreshed: false, refusal: undefined };
105
+ };
106
+ try {
107
+ let explicitBase;
108
+ let withinMs = FILE_HISTORY_REFRESH_WITHIN_MS;
109
+ if (typeof opts === 'object' && opts !== null) {
110
+ try {
111
+ const b = opts.baseUrl;
112
+ if (b !== undefined) {
113
+ if (typeof b !== 'string' || b === '')
114
+ return failClosed();
115
+ explicitBase = b;
116
+ }
117
+ }
118
+ catch {
119
+ return failClosed();
120
+ }
121
+ try {
122
+ const w = opts.withinMs;
123
+ if (w !== undefined)
124
+ withinMs = typeof w === 'number' ? w : 0;
125
+ }
126
+ catch {
127
+ withinMs = 0;
128
+ }
129
+ }
130
+ const baseUrl = explicitBase ?? engineWireTarget()?.baseUrl;
131
+ const first = observedFileHistoryCapture(baseUrl);
132
+ const v1 = fileHistoryTightenVerdict(first, captureOffByUser);
133
+ if (v1 !== 'unjudged')
134
+ return { verdict: v1, reading: first, refreshed: false, refusal: undefined };
135
+ const outcome = await refreshEngineCapsOnce(baseUrl, { withinMs });
136
+ const second = observedFileHistoryCapture(baseUrl);
137
+ const v2 = fileHistoryTightenVerdict(second, captureOffByUser);
138
+ return {
139
+ verdict: v2,
140
+ reading: second,
141
+ refreshed: outcome !== 'no_probe',
142
+ refusal: v2 === 'unjudged' ? unjudgedRefusalOf(second) : undefined,
143
+ };
144
+ }
145
+ catch {
146
+ return failClosed();
147
+ }
148
+ }
55
149
  const WORD_DETAIL_MAX = 40;
56
150
  export function fileHistoryCaptureDoctorDetail(reading) {
57
151
  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';
@@ -67,6 +161,8 @@ export function fileHistoryCaptureDoctorDetail(reading) {
67
161
  return unobserved;
68
162
  }
69
163
  switch (kind) {
164
+ case 'unreadable':
165
+ return unreadableReadingDetail('file history capture');
70
166
  case 'not_reported':
71
167
  return 'file history capture not reported by this engine; this does not say whether file history is captured here';
72
168
  case 'present':
@@ -89,6 +89,8 @@ function canonReading(r) {
89
89
  const kind = r.kind;
90
90
  if (kind === 'not_reported')
91
91
  return 'not_reported';
92
+ if (kind === 'unreadable')
93
+ return 'unreadable';
92
94
  if (kind === 'present') {
93
95
  const word = r.word;
94
96
  return typeof word === 'string' && word.length > 0 ? `present:${word}` : 'unobserved';
@@ -102,6 +104,8 @@ function canonReading(r) {
102
104
  function readingOfCanon(c) {
103
105
  if (c === 'not_reported')
104
106
  return { kind: 'not_reported' };
107
+ if (c === 'unreadable')
108
+ return { kind: 'unreadable' };
105
109
  if (c.startsWith('present:'))
106
110
  return { kind: 'present', word: c.slice('present:'.length) };
107
111
  return { kind: 'unobserved' };