@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,14 +1,8 @@
1
1
  import { isCcToolDenialKind } from './gateVocabulary.js';
2
2
  export { flattenWireOutput as flattenToolOutput } from './adapt/wireShapes.js';
3
3
  import { flattenWireOutput } from './adapt/wireShapes.js';
4
- import { parseModelFacingBash } from './toolResult.js';
5
- import { bashExitOf, bashExitReadingFailed } from './bashExitReading.js';
6
4
  import { toolResultEnvelopeParts, toolResultOutcomeOf } from './adapt/toolCards.js';
7
- function bashExitCodeFailed(toolName, text, structured) {
8
- if (typeof toolName !== 'string' || toolName.toLowerCase() !== 'bash')
9
- return false;
10
- return bashExitReadingFailed(bashExitOf(structured, () => parseModelFacingBash(text)));
11
- }
5
+ import { readFrameTrueMark } from './ownKey.js';
12
6
  export function toolEndResultToUserFrame(arm) {
13
7
  if (typeof arm.toolCallId !== 'string' || arm.toolCallId.length === 0)
14
8
  return null;
@@ -21,6 +15,7 @@ export function toolEndResultToUserFrame(arm) {
21
15
  isError: arm.isError === true,
22
16
  }, undefined, parent === null ? 'leader' : 'subagent');
23
17
  const envelope = toolResultEnvelopeParts(outcome);
18
+ const content = Array.isArray(outcome.body.content) ? outcome.body.content : arm.truncated === true ? `${text}\n…(truncated)` : text;
24
19
  return {
25
20
  type: 'user',
26
21
  message: {
@@ -29,13 +24,14 @@ export function toolEndResultToUserFrame(arm) {
29
24
  {
30
25
  type: 'tool_result',
31
26
  tool_use_id: arm.toolCallId,
32
- content: arm.truncated === true ? `${text}\n…(truncated)` : text,
33
- is_error: arm.isError === true || bashExitCodeFailed(arm.toolName, text, arm.structured),
27
+ content,
28
+ is_error: outcome.body.isError,
34
29
  },
35
30
  ],
36
31
  },
37
32
  parent_tool_use_id: parent,
38
33
  ...(isCcToolDenialKind(arm._sema_denial_kind) ? { _sema_denial_kind: arm._sema_denial_kind } : {}),
34
+ ...(readFrameTrueMark(arm, 'notExecuted') ? { _sema_not_executed: true } : {}),
39
35
  ...(Object.hasOwn(envelope, 'tool_use_result') ? { tool_use_result: envelope.tool_use_result } : {}),
40
36
  ...(Object.hasOwn(envelope, '_sema_degraded') ? { _sema_degraded: envelope._sema_degraded } : {}),
41
37
  uuid: arm.uuid,
@@ -0,0 +1,5 @@
1
+ import type { RunTerminalRead } from './runTerminal.js';
2
+ export declare const PROMPT_BLOCKED_BY_HOOK_ROW_LEAD = "UserPromptSubmit operation blocked by hook";
3
+ export declare function runBlockedText(blocked: Extract<RunTerminalRead, {
4
+ kind: 'blocked';
5
+ }>): string;
@@ -0,0 +1,35 @@
1
+ import { displayUntrusted } from './displayUntrusted.js';
2
+ import { stripSystemReminderTagTokens, unwrapSystemReminder } from './systemReminderTag.js';
3
+ export const PROMPT_BLOCKED_BY_HOOK_ROW_LEAD = 'UserPromptSubmit operation blocked by hook';
4
+ const RUN_BLOCKED_REASONED = 'Run blocked';
5
+ const RUN_BLOCKED_NO_REASON = 'Run blocked (the agent reported it cannot proceed)';
6
+ const HOOK_WORDS_SHOWN_MAX = 1000;
7
+ const CAUSE_CLAUSE = Object.freeze({
8
+ crashed: 'the hook failed before it answered; the prompt was not submitted',
9
+ timeout: 'the hook did not answer in time; the prompt was not submitted',
10
+ cancelled: 'the run was cancelled while the hook was checking the prompt; the prompt was not submitted',
11
+ });
12
+ function shownHookWords(words) {
13
+ if (words === undefined)
14
+ return undefined;
15
+ const shown = stripSystemReminderTagTokens(displayUntrusted(stripSystemReminderTagTokens(words), { max: HOOK_WORDS_SHOWN_MAX })).trim();
16
+ return shown === '' ? undefined : shown;
17
+ }
18
+ export function runBlockedText(blocked) {
19
+ const detail = blocked.detail;
20
+ if (detail !== undefined && detail.kind === 'prompt_blocked_by_hook') {
21
+ const clause = detail.cause !== 'unrecognized' && Object.hasOwn(CAUSE_CLAUSE, detail.cause) ? CAUSE_CLAUSE[detail.cause] : undefined;
22
+ const words = shownHookWords(detail.hookReason);
23
+ if (clause !== undefined)
24
+ return `${PROMPT_BLOCKED_BY_HOOK_ROW_LEAD}: ${clause}${words !== undefined ? `\n${words}` : ''}`;
25
+ return words !== undefined ? `${PROMPT_BLOCKED_BY_HOOK_ROW_LEAD}:\n${words}` : PROMPT_BLOCKED_BY_HOOK_ROW_LEAD;
26
+ }
27
+ const reason = blocked.reason;
28
+ if (reason === undefined)
29
+ return RUN_BLOCKED_NO_REASON;
30
+ const unwrapped = unwrapSystemReminder(reason);
31
+ if (unwrapped === reason)
32
+ return `${RUN_BLOCKED_REASONED}: ${reason}`;
33
+ const body = stripSystemReminderTagTokens(unwrapped).trim();
34
+ return body === '' ? RUN_BLOCKED_NO_REASON : `${RUN_BLOCKED_REASONED}: ${body}`;
35
+ }
@@ -1,12 +1,15 @@
1
- export type ProtocolSegment = {
2
- readonly kind: 'ok';
1
+ export type RuleToolNameReading = {
2
+ readonly kind: 'current';
3
3
  } | {
4
- readonly kind: 'empty';
4
+ readonly kind: 'retired';
5
+ readonly currentName?: string;
5
6
  } | {
6
- readonly kind: 'unminted';
7
- readonly minted?: string;
7
+ readonly kind: 'unprefixed_namespace';
8
+ } | {
9
+ readonly kind: 'unmintable_segment';
8
10
  } | {
9
11
  readonly kind: 'unknown';
10
12
  };
11
- export declare function protocolSegmentOf(name: string): ProtocolSegment;
13
+ export declare function ruleToolNameVerdictOf(name: string): RuleToolNameReading;
14
+ export declare function mintedPrefixOf(name: string): string | undefined;
12
15
  export declare function clientOwnedServerPrefix(server: string): string | undefined;
@@ -1,33 +1,43 @@
1
- import { hasCoreValuePort, mcpNamespace, mintNamespacePrefix, protocolOf } from './coreValuePorts.js';
2
- import { CORE_PROTOCOL_PREFIXES } from './generated/toolNameTables.js';
3
- export function protocolSegmentOf(name) {
4
- if (CORE_PROTOCOL_PREFIXES.some((prefix) => name.startsWith(prefix) && name.slice(prefix.length).split('__')[0] === ''))
5
- return { kind: 'empty' };
6
- const ns = protocolOf(name);
7
- if (ns === undefined)
8
- return hasCoreValuePort('protocolOf') ? { kind: 'ok' } : { kind: 'unknown' };
9
- let parsed;
1
+ import { mcpNamespace, mintNamespacePrefix, protocolOf, ruleToolNameJudgement } from './coreValuePorts.js';
2
+ export function ruleToolNameVerdictOf(name) {
3
+ let kind;
4
+ let currentName;
10
5
  try {
11
- parsed = ns.parse(name);
6
+ const v = ruleToolNameJudgement(name, new Set());
7
+ if (v === null || typeof v !== 'object')
8
+ return { kind: 'unknown' };
9
+ kind = v.kind;
10
+ if (kind === 'retired')
11
+ currentName = v.currentName;
12
12
  }
13
13
  catch {
14
14
  return { kind: 'unknown' };
15
15
  }
16
- const peer = parsed?.peer;
17
- if (typeof peer !== 'string')
18
- return { kind: 'ok' };
19
- if (peer.includes('*'))
20
- return { kind: 'unminted' };
21
- let minted;
16
+ switch (kind) {
17
+ case 'current':
18
+ case 'unprefixed_namespace':
19
+ case 'unmintable_segment':
20
+ return { kind };
21
+ case 'retired':
22
+ return typeof currentName === 'string' && currentName !== '' ? { kind, currentName } : { kind };
23
+ default:
24
+ return { kind: 'unknown' };
25
+ }
26
+ }
27
+ export function mintedPrefixOf(name) {
22
28
  try {
23
- minted = mintNamespacePrefix(ns, peer);
29
+ const ns = protocolOf(name);
30
+ if (ns === undefined)
31
+ return undefined;
32
+ const peer = ns.parse(name)?.peer;
33
+ if (typeof peer !== 'string' || peer.includes('*'))
34
+ return undefined;
35
+ const minted = mintNamespacePrefix(ns, peer);
36
+ return typeof minted === 'string' ? minted : undefined;
24
37
  }
25
38
  catch {
26
- return { kind: 'unknown' };
39
+ return undefined;
27
40
  }
28
- if (typeof minted !== 'string')
29
- return { kind: 'unknown' };
30
- return minted === `${ns.prefix}${peer}__` ? { kind: 'ok' } : { kind: 'unminted', minted };
31
41
  }
32
42
  export function clientOwnedServerPrefix(server) {
33
43
  try {
@@ -1,8 +1,12 @@
1
1
  import { type RunTerminalFailureDetail } from './runTerminal.js';
2
2
  import { type ToolHistoryErrorCarrier } from './toolHistoryMismatch.js';
3
+ export declare const PROVIDER_REJECTION_KINDS: readonly ["schema_invalid", "auth", "rate_limited", "resend_eligible", "unknown"];
4
+ export type ProviderRejectionKind = (typeof PROVIDER_REJECTION_KINDS)[number];
3
5
  export interface ProviderRejectionResend {
4
6
  resend: 'edit_and_resend' | 'not_by_editing';
5
7
  text: string;
8
+ kind: ProviderRejectionKind;
6
9
  }
7
10
  export declare function readProviderRejectionResendKey(v: object | null | undefined): ProviderRejectionResend | undefined;
8
11
  export declare function providerRejectionResend(detail: RunTerminalFailureDetail | null | undefined, carrier?: ToolHistoryErrorCarrier | null): ProviderRejectionResend | undefined;
12
+ export declare function providerRejectionKind(detail: RunTerminalFailureDetail | null | undefined): ProviderRejectionKind;
@@ -18,6 +18,28 @@ function providerStatusTier(status) {
18
18
  return UNTIERED;
19
19
  }
20
20
  const EDITABLE_TIER = 'invalid_request';
21
+ export const PROVIDER_REJECTION_KINDS = Object.freeze(['schema_invalid', 'auth', 'rate_limited', 'resend_eligible', 'unknown']);
22
+ const SCHEMA_INVALID_CODES = new Set([
23
+ 'invalid_type',
24
+ 'missing_required_parameter',
25
+ 'unknown_parameter',
26
+ 'unsupported_parameter',
27
+ 'invalid_function_parameters',
28
+ 'invalid_json_schema',
29
+ ]);
30
+ function schemaTierStatus(status) {
31
+ return status === 400 || status === 422;
32
+ }
33
+ function kindOfStatus(status, code) {
34
+ const tier = providerStatusTier(status);
35
+ if (tier === 'authentication_failed')
36
+ return 'auth';
37
+ if (tier === 'rate_limit')
38
+ return 'rate_limited';
39
+ if (tier === EDITABLE_TIER)
40
+ return code !== undefined && schemaTierStatus(status) && SCHEMA_INVALID_CODES.has(code) ? 'schema_invalid' : 'resend_eligible';
41
+ return 'unknown';
42
+ }
21
43
  const NOT_BY_EDITING_TAIL = new Map([
22
44
  ['authentication_failed', ': check the provider credentials or access for this account.'],
23
45
  ['model_not_found', ': the model is not available from this provider — choose another model.'],
@@ -30,26 +52,40 @@ function toolHistoryMismatchCarrier(carrier) {
30
52
  }
31
53
  const PROVIDER_REJECTED = 'provider_rejected';
32
54
  const RESEND_TEXT_STATUS = /\(HTTP (\d{3})\)/;
55
+ function ownDataOf(o, key) {
56
+ const d = Object.getOwnPropertyDescriptor(o, key);
57
+ return d !== undefined && Object.hasOwn(d, 'value') ? d.value : undefined;
58
+ }
33
59
  export function readProviderRejectionResendKey(v) {
34
60
  try {
35
61
  if (typeof v !== 'object' || v === null || Array.isArray(v))
36
62
  return undefined;
37
- const got = v;
38
- const resend = got.resend;
39
- const text = got.text;
63
+ const resend = ownDataOf(v, 'resend');
64
+ const text = ownDataOf(v, 'text');
65
+ const kind = ownDataOf(v, 'kind');
40
66
  if (typeof text !== 'string' || (resend !== 'edit_and_resend' && resend !== 'not_by_editing'))
41
67
  return undefined;
42
68
  const hit = RESEND_TEXT_STATUS.exec(text);
43
69
  if (hit === null || hit[1] === undefined)
44
70
  return undefined;
45
- const again = providerRejectionResend({ kind: PROVIDER_REJECTED, status: Number(hit[1]) });
46
- return again !== undefined && again.resend === resend && again.text === text ? { resend: again.resend, text: again.text } : undefined;
71
+ const rej = readRejection({ kind: PROVIDER_REJECTED, status: Number(hit[1]) });
72
+ if (rej === undefined)
73
+ return undefined;
74
+ let wanted;
75
+ if (kind === undefined)
76
+ wanted = kindOfStatus(rej.status, undefined);
77
+ else if (typeof kind === 'string' && PROVIDER_REJECTION_KINDS.includes(kind))
78
+ wanted = kind;
79
+ else
80
+ return undefined;
81
+ const again = verdictOf(rej.status, wanted);
82
+ return again !== undefined && again.resend === resend && again.text === text ? { resend: again.resend, text: again.text, kind: again.kind } : undefined;
47
83
  }
48
84
  catch {
49
85
  return undefined;
50
86
  }
51
87
  }
52
- export function providerRejectionResend(detail, carrier) {
88
+ function readRejection(detail) {
53
89
  let read;
54
90
  try {
55
91
  const r = readRunTerminal({ terminal: { kind: 'failed', detail } });
@@ -63,16 +99,41 @@ export function providerRejectionResend(detail, carrier) {
63
99
  const status = Object.hasOwn(read, 'status') ? read.status : undefined;
64
100
  if (status === undefined)
65
101
  return undefined;
66
- if (toolHistoryMismatchCarrier(carrier))
102
+ return { status, code: Object.hasOwn(read, 'code') ? read.code : undefined };
103
+ }
104
+ function schemaInvalidText(status) {
105
+ return `The model provider rejected the structure of this request (HTTP ${status}) — rewording the message will not fix this. Check that the configured model and endpoint accept this kind of request, or report the problem to whoever runs the engine.`;
106
+ }
107
+ function verdictOf(status, kind) {
108
+ if (kind === 'schema_invalid') {
109
+ if (providerStatusTier(status) !== EDITABLE_TIER || !schemaTierStatus(status))
110
+ return undefined;
111
+ return { resend: 'not_by_editing', text: schemaInvalidText(status), kind };
112
+ }
113
+ if (kind !== kindOfStatus(status, undefined))
67
114
  return undefined;
68
- const tier = providerStatusTier(status);
69
- return tier === EDITABLE_TIER
70
- ? {
115
+ if (kind === 'resend_eligible') {
116
+ return {
71
117
  resend: 'edit_and_resend',
72
118
  text: `The model provider rejected this request as sent (HTTP ${status}). Change it — for example shorten it or remove an attachment — and send it again.`,
73
- }
74
- : {
75
- resend: 'not_by_editing',
76
- text: `The model provider refused this request (HTTP ${status})${NOT_BY_EDITING_TAIL.get(tier) ?? NOT_BY_EDITING_TAIL.get(UNTIERED) ?? ''}`,
119
+ kind,
77
120
  };
121
+ }
122
+ return {
123
+ resend: 'not_by_editing',
124
+ text: `The model provider refused this request (HTTP ${status})${NOT_BY_EDITING_TAIL.get(providerStatusTier(status)) ?? NOT_BY_EDITING_TAIL.get(UNTIERED) ?? ''}`,
125
+ kind,
126
+ };
127
+ }
128
+ export function providerRejectionResend(detail, carrier) {
129
+ const r = readRejection(detail);
130
+ if (r === undefined)
131
+ return undefined;
132
+ if (toolHistoryMismatchCarrier(carrier))
133
+ return undefined;
134
+ return verdictOf(r.status, kindOfStatus(r.status, r.code));
135
+ }
136
+ export function providerRejectionKind(detail) {
137
+ const r = readRejection(detail);
138
+ return r === undefined ? 'unknown' : kindOfStatus(r.status, r.code);
78
139
  }
@@ -0,0 +1,12 @@
1
+ export interface ReplayRowView {
2
+ readonly status?: string;
3
+ readonly errorCode?: string;
4
+ readonly error?: string;
5
+ readonly sessionId?: string;
6
+ }
7
+ export interface DoneResultView {
8
+ readonly replay: boolean;
9
+ readonly engine: unknown;
10
+ readonly row?: ReplayRowView;
11
+ }
12
+ export declare function doneResultView(result: unknown): DoneResultView;
@@ -0,0 +1,25 @@
1
+ function guarded(o, k) {
2
+ try {
3
+ return o[k];
4
+ }
5
+ catch {
6
+ return undefined;
7
+ }
8
+ }
9
+ function guardedString(o, k) {
10
+ const v = guarded(o, k);
11
+ return typeof v === 'string' && v.length > 0 ? v : undefined;
12
+ }
13
+ export function doneResultView(result) {
14
+ if (typeof result !== 'object' || result === null || Array.isArray(result))
15
+ return { replay: false, engine: result };
16
+ if (guarded(result, 'replay') !== true)
17
+ return { replay: false, engine: result };
18
+ const row = {};
19
+ for (const k of ['status', 'errorCode', 'error', 'sessionId']) {
20
+ const v = guardedString(result, k);
21
+ if (v !== undefined)
22
+ row[k] = v;
23
+ }
24
+ return { replay: true, engine: guarded(result, 'result'), row };
25
+ }
@@ -1,6 +1,6 @@
1
- import { readErrorNumber, readErrorString } from './wireFailureShape.js';
1
+ import { readBlockedBy, readErrorNumber, readErrorString } from './wireFailureShape.js';
2
2
  import { readOwnDataNonEmptyString } from './ownKey.js';
3
- import { RESUME_CONTEXT_UNAVAILABLE, RESUME_PLACEMENT_MISMATCH, RESUME_PREFLIGHT_REJECTED, RESUME_POLICY_FOLD_CODE, PARKED_RESUME_STARTUP_FAILED, isStatusDerivedCoarseCode, RESUME_SESSION_NOT_FOUND, REQUEST_FIELD_CONFLICT, CHECKPOINT_UNSUPPORTED_VERSION, CHECKPOINT_WALLTIME_AXIS_RETIRED, CHECKPOINT_CONFIG_REFUSED, refusalSaysStillPending, refusalRetriableReading, } from './engineErrorCodes.js';
3
+ import { RESUME_CONTEXT_UNAVAILABLE, RESUME_PLACEMENT_MISMATCH, RESUME_PREFLIGHT_REJECTED, RESUME_POLICY_FOLD_CODE, PARKED_RESUME_STARTUP_FAILED, isStatusDerivedCoarseCode, RESUME_SESSION_NOT_FOUND, REQUEST_FIELD_CONFLICT, CHECKPOINT_UNSUPPORTED_VERSION, CHECKPOINT_WALLTIME_AXIS_RETIRED, CHECKPOINT_CONFIG_REFUSED, isRefusedParkCode, refusalSaysStillPending, refusalRetriableReading, } from './engineErrorCodes.js';
4
4
  import { capForDisplay } from './fleetTaskDesc.js';
5
5
  import { engineVersionTier } from './supportFloor.js';
6
6
  import { resumeRetryLaterFromError } from './wireErrorTriage.js';
@@ -55,22 +55,7 @@ export function resumePolicyBlockFromError(err) {
55
55
  }
56
56
  if (outer !== RESUME_POLICY_FOLD_CODE)
57
57
  return null;
58
- const judge = (v) => ({
59
- blockedBy: typeof v === 'string' && v.length > 0 ? { kind: 'named', code: v } : { kind: 'unreadable' },
60
- });
61
- try {
62
- const top = o['blockedBy'];
63
- if (top !== undefined)
64
- return judge(top);
65
- const extra = o['extra'];
66
- if (typeof extra === 'object' && extra !== null && !Array.isArray(extra) && Object.hasOwn(extra, 'blockedBy')) {
67
- return judge(extra['blockedBy']);
68
- }
69
- return { blockedBy: { kind: 'absent' } };
70
- }
71
- catch {
72
- return { blockedBy: { kind: 'unreadable' } };
73
- }
58
+ return { blockedBy: readBlockedBy(o) };
74
59
  }
75
60
  export function resumePolicyBlockContent(detail) {
76
61
  const b = detail.blockedBy;
@@ -282,7 +267,6 @@ export function checkpointUnsupportedVersionContent(detail, ctx) {
282
267
  }
283
268
  return [CHECKPOINT_UNSUPPORTED_WHAT, CHECKPOINT_UNSUPPORTED_STILL_WAITING, outlet + CHECKPOINT_UNSUPPORTED_DRAIN].join(' · ');
284
269
  }
285
- const REFUSED_PARK_CODES = new Set([CHECKPOINT_UNSUPPORTED_VERSION, CHECKPOINT_WALLTIME_AXIS_RETIRED, CHECKPOINT_CONFIG_REFUSED]);
286
270
  const REFUSED_PARK_FIELD_TOKEN = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;
287
271
  export function refusedParkFromError(failure) {
288
272
  if (typeof failure !== 'object' || failure === null)
@@ -296,7 +280,7 @@ export function refusedParkFromError(failure) {
296
280
  catch {
297
281
  return null;
298
282
  }
299
- if (typeof code !== 'string' || !REFUSED_PARK_CODES.has(code))
283
+ if (typeof code !== 'string' || !isRefusedParkCode(code))
300
284
  return null;
301
285
  if (status !== undefined && status !== 409)
302
286
  return null;
@@ -305,7 +289,7 @@ export function refusedParkFromError(failure) {
305
289
  const rawField = code === CHECKPOINT_CONFIG_REFUSED ? readErrorString(failure, 'field') : undefined;
306
290
  const field = rawField !== undefined && REFUSED_PARK_FIELD_TOKEN.test(rawField) ? rawField : undefined;
307
291
  return Object.freeze({
308
- code: code,
292
+ code,
309
293
  ...(field !== undefined ? { field } : {}),
310
294
  ...(stillPending !== undefined ? { stillPending } : {}),
311
295
  });
@@ -6,6 +6,8 @@ export type RetryStatus = {
6
6
  errClass?: BrainRetryErrClass | (string & {});
7
7
  retryAtMs?: number;
8
8
  errorStatus?: number;
9
+ providerCondition?: string;
10
+ providerConditionSource?: string;
9
11
  elapsedMs?: number;
10
12
  timeoutMs?: number;
11
13
  detail?: string;
@@ -17,6 +19,8 @@ export type RetryStatus = {
17
19
  errClass?: BrainRetryErrClass | (string & {});
18
20
  retryAtMs?: number;
19
21
  errorStatus?: number;
22
+ providerCondition?: string;
23
+ providerConditionSource?: string;
20
24
  terminal?: true;
21
25
  error: RetryStatusErrorPayload;
22
26
  elapsedMs?: number;
@@ -29,6 +33,8 @@ export type RetryStatus = {
29
33
  errClass?: BrainRetryErrClass | (string & {});
30
34
  retryAtMs?: number;
31
35
  errorStatus?: number;
36
+ providerCondition?: string;
37
+ providerConditionSource?: string;
32
38
  elapsedMs?: number;
33
39
  timeoutMs?: number;
34
40
  terminal?: never;
@@ -60,7 +66,9 @@ export interface BrainStatusPayload {
60
66
  errClass?: BrainRetryErrClass | (string & {});
61
67
  elapsedMs?: number;
62
68
  timeoutMs?: number;
69
+ providerCondition?: string;
70
+ providerConditionSource?: string;
63
71
  }
64
- export declare const BRAIN_STATUS_PAYLOAD_KEYS: readonly ["phase", "detail", "retryInSec", "retryInMs", "attempt", "maxRetries", "errClass", "retryAtMs", "errorStatus", "elapsedMs", "timeoutMs"];
72
+ export declare const BRAIN_STATUS_PAYLOAD_KEYS: readonly ["phase", "detail", "retryInSec", "retryInMs", "attempt", "maxRetries", "errClass", "retryAtMs", "errorStatus", "elapsedMs", "timeoutMs", "providerCondition", "providerConditionSource"];
65
73
  export declare function mapBrainStatusToRetry(p: BrainStatusPayload, nowMs: number): RetryStatus | null;
66
74
  export {};
@@ -20,6 +20,8 @@ export const BRAIN_STATUS_PAYLOAD_KEYS = [
20
20
  'errorStatus',
21
21
  'elapsedMs',
22
22
  'timeoutMs',
23
+ 'providerCondition',
24
+ 'providerConditionSource',
23
25
  ];
24
26
  const _brainStatusKeyPin = [true, true];
25
27
  void _brainStatusKeyPin;
@@ -33,6 +35,10 @@ export function mapBrainStatusToRetry(p, nowMs) {
33
35
  const cause = typeof p.errClass === 'string' && p.errClass.length > 0 ? { errClass: p.errClass } : {};
34
36
  const producerTiming = typeof p.retryAtMs === 'number' ? { retryAtMs: p.retryAtMs } : {};
35
37
  const failureStatus = typeof p.errorStatus === 'number' ? { errorStatus: p.errorStatus } : {};
38
+ const providerJudged = {
39
+ ...(typeof p.providerCondition === 'string' && p.providerCondition.length > 0 ? { providerCondition: p.providerCondition } : {}),
40
+ ...(typeof p.providerConditionSource === 'string' && p.providerConditionSource.length > 0 ? { providerConditionSource: p.providerConditionSource } : {}),
41
+ };
36
42
  const saneMs = (v) => typeof v === 'number' && Number.isFinite(v) && v >= 0 ? v : undefined;
37
43
  const elapsedMs = saneMs(p.elapsedMs);
38
44
  const timeoutMs = saneMs(p.timeoutMs);
@@ -40,9 +46,10 @@ export function mapBrainStatusToRetry(p, nowMs) {
40
46
  ...(elapsedMs !== undefined ? { elapsedMs } : {}),
41
47
  ...(timeoutMs !== undefined ? { timeoutMs } : {}),
42
48
  };
43
- const stalledDetail = typeof p.detail === 'string' && p.detail.length > 0 ? { detail: p.detail } : {};
49
+ const stalledShown = typeof p.detail === 'string' && p.detail.length > 0 ? displayUntrusted(p.detail) : '';
50
+ const stalledDetail = stalledShown.length > 0 ? { detail: stalledShown } : {};
44
51
  const shown = (absent) => (typeof p.detail === 'string' ? displayUntrusted(p.detail) : absent);
45
- const extra = { ...counts, ...cause, ...producerTiming, ...failureStatus, ...waitProgress };
52
+ const extra = { ...counts, ...cause, ...producerTiming, ...failureStatus, ...providerJudged, ...waitProgress };
46
53
  switch (p.phase) {
47
54
  case 'recovered':
48
55
  return null;
@@ -1,24 +1,14 @@
1
+ import { type RewindArchiveReading, type RewindCodeArchive } from './rewindArchiveReading.js';
1
2
  import type { RewindMode } from './rewindWireCaps.js';
2
- export type RewindArchiveBit = 'on' | 'off' | 'not_reported' | 'malformed';
3
- export type RewindArchiveReading = {
4
- kind: 'unobserved';
5
- } | {
6
- kind: 'present';
7
- conversationAnchor: RewindArchiveBit;
8
- forkRestore: RewindArchiveBit;
9
- codeOnly: RewindArchiveBit;
10
- restoreFilesEpoch: RewindArchiveBit;
11
- };
3
+ export { projectRewindArchiveCapability, rewindConversationAvailability } from './rewindArchiveReading.js';
4
+ export type { RewindArchiveBit, RewindArchiveReading, RewindCodeArchive } from './rewindArchiveReading.js';
12
5
  export type RewindArchiveMode = 'both' | 'code';
13
- export type RewindCodeArchive = 'available' | 'unavailable' | 'unknown';
14
- export declare function projectRewindArchiveCapability(caps: unknown): RewindArchiveReading | undefined;
15
6
  export declare function noteEngineCapsForRewindArchive(baseUrl: string, caps: unknown, opts?: {
16
7
  generation?: number;
17
8
  }): void;
18
9
  export declare function observedRewindArchive(baseUrl?: string | undefined): RewindArchiveReading;
19
10
  export declare function rewindCodeArchiveAvailability(reading: RewindArchiveReading, mode: RewindArchiveMode): RewindCodeArchive;
20
11
  export declare function rewindArchiveDoctorDetail(reading: RewindArchiveReading, mode: RewindArchiveMode): string;
21
- export declare function rewindConversationAvailability(reading: RewindArchiveReading): RewindCodeArchive;
22
12
  export declare function engineRewindRefusedNow(option: RewindMode, reading?: RewindArchiveReading): boolean;
23
13
  export declare function rewindConversationDoctorDetail(reading: RewindArchiveReading): string;
24
14
  export declare function rewindRestoreFilesEpochDetail(reading: RewindArchiveReading): string;
@@ -1,55 +1,13 @@
1
1
  import { engineWireTarget } from './engineWireTarget.js';
2
- import { createEngineCapReader } from './engineCapReader.js';
3
- import { ownDataField } from './ownKey.js';
4
- import { _wireConversationRewindJudge } from './toolHistoryMismatch.js';
5
- const CAPS_KEYS = {
6
- conversationAnchor: 'resumeAt',
7
- forkRestore: 'rewindFiles',
8
- codeOnly: 'rewindFilesTo',
9
- restoreFilesEpoch: 'restoreFiles',
10
- };
11
- const _capsKeyPin = true;
12
- void _capsKeyPin;
13
- function bitOf(caps, key) {
14
- const v = ownDataField(caps, key);
15
- if (v === undefined)
16
- return 'not_reported';
17
- if (v === true)
18
- return 'on';
19
- if (v === false)
20
- return 'off';
21
- return 'malformed';
22
- }
23
- export function projectRewindArchiveCapability(caps) {
24
- try {
25
- if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
26
- return undefined;
27
- return {
28
- kind: 'present',
29
- conversationAnchor: bitOf(caps, CAPS_KEYS.conversationAnchor),
30
- forkRestore: bitOf(caps, CAPS_KEYS.forkRestore),
31
- codeOnly: bitOf(caps, CAPS_KEYS.codeOnly),
32
- restoreFilesEpoch: bitOf(caps, CAPS_KEYS.restoreFilesEpoch),
33
- };
34
- }
35
- catch {
36
- return undefined;
37
- }
38
- }
39
- const reader = createEngineCapReader({
40
- name: 'rewindArchive',
41
- project: projectRewindArchiveCapability,
42
- makeUnobserved: () => ({ kind: 'unobserved' }),
43
- });
2
+ import { resetRewindArchiveReader, rewindArchiveReadingAt, rewindConversationAvailability, } from './rewindArchiveReading.js';
3
+ export { projectRewindArchiveCapability, rewindConversationAvailability } from './rewindArchiveReading.js';
44
4
  export function noteEngineCapsForRewindArchive(baseUrl, caps, opts) {
45
- reader.note(baseUrl, caps, opts);
46
- }
47
- function conversationRewindJudge(engineBaseUrl) {
48
- return rewindConversationAvailability(observedRewindArchive(engineBaseUrl));
5
+ void baseUrl;
6
+ void caps;
7
+ void opts;
49
8
  }
50
- _wireConversationRewindJudge(conversationRewindJudge);
51
9
  export function observedRewindArchive(baseUrl = engineWireTarget()?.baseUrl) {
52
- return reader.observed(baseUrl);
10
+ return rewindArchiveReadingAt(baseUrl);
53
11
  }
54
12
  export function rewindCodeArchiveAvailability(reading, mode) {
55
13
  if (reading.kind !== 'present')
@@ -86,15 +44,6 @@ export function rewindArchiveDoctorDetail(reading, mode) {
86
44
  return `${lane} reported in a shape this reader cannot read — the value is neither true nor false, so the answer is unknown, not "no"`;
87
45
  }
88
46
  }
89
- export function rewindConversationAvailability(reading) {
90
- if (reading.kind !== 'present')
91
- return 'unknown';
92
- if (reading.conversationAnchor === 'on')
93
- return 'available';
94
- if (reading.conversationAnchor === 'off')
95
- return 'unavailable';
96
- return 'unknown';
97
- }
98
47
  export function engineRewindRefusedNow(option, reading = observedRewindArchive()) {
99
48
  switch (option) {
100
49
  case 'both':
@@ -139,5 +88,5 @@ export function rewindRestoreFilesEpochDetail(reading) {
139
88
  }
140
89
  }
141
90
  export function __resetRewindArchiveReadingsForTests() {
142
- reader.__resetForTests();
91
+ resetRewindArchiveReader();
143
92
  }
@@ -0,0 +1,15 @@
1
+ export type RewindArchiveBit = 'on' | 'off' | 'not_reported' | 'malformed';
2
+ export type RewindArchiveReading = {
3
+ kind: 'unobserved';
4
+ } | {
5
+ kind: 'present';
6
+ conversationAnchor: RewindArchiveBit;
7
+ forkRestore: RewindArchiveBit;
8
+ codeOnly: RewindArchiveBit;
9
+ restoreFilesEpoch: RewindArchiveBit;
10
+ };
11
+ export type RewindCodeArchive = 'available' | 'unavailable' | 'unknown';
12
+ export declare function projectRewindArchiveCapability(caps: unknown): RewindArchiveReading | undefined;
13
+ export declare function rewindArchiveReadingAt(baseUrl: string | undefined): RewindArchiveReading;
14
+ export declare function resetRewindArchiveReader(): void;
15
+ export declare function rewindConversationAvailability(reading: RewindArchiveReading): RewindCodeArchive;