@sema-agent/client-core 0.102.0 → 0.103.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 (95) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/README.md +8 -5
  3. package/dist/adapt/toolCards.d.ts +2 -1
  4. package/dist/adapt/toolCards.js +3 -1
  5. package/dist/adapter/downstream/eventToSdkMessage.d.ts +5 -1
  6. package/dist/adapter/downstream/eventToSdkMessage.js +21 -3
  7. package/dist/adapter/downstream/terminalToSdkResult.js +0 -1
  8. package/dist/adapter/downstream/wiringManifestView.js +4 -1
  9. package/dist/cloudConfigWireCaps.js +6 -3
  10. package/dist/credentialPlaneCapability.d.ts +22 -0
  11. package/dist/credentialPlaneCapability.js +75 -0
  12. package/dist/deviceExecutorManagementCapability.d.ts +1 -0
  13. package/dist/deviceExecutorManagementCapability.js +3 -1
  14. package/dist/engineErrorCodes.d.ts +1 -0
  15. package/dist/engineErrorCodes.js +3 -1
  16. package/dist/engineNoticeCodes.d.ts +26 -0
  17. package/dist/engineNoticeCodes.js +121 -12
  18. package/dist/engineRowRef.js +1 -0
  19. package/dist/errorSupplementRoles.js +1 -3
  20. package/dist/eventLeg.js +2 -1
  21. package/dist/fleet/fleetProjection.js +15 -9
  22. package/dist/gateOutcome.d.ts +20 -0
  23. package/dist/gateOutcome.js +89 -0
  24. package/dist/generated/engineAskFaceTables.js +2 -2
  25. package/dist/generated/engineFactTables.d.ts +6 -2
  26. package/dist/generated/engineFactTables.js +41 -1
  27. package/dist/generated/engineNoticeTables.js +18 -0
  28. package/dist/generated/settingsSchemaDefaultModel.d.ts +1 -1
  29. package/dist/generated/settingsSchemaDefaultModel.js +2 -2
  30. package/dist/generated/settingsSchemaFns.d.ts +15 -0
  31. package/dist/generated/settingsSchemaFns.js +25 -2
  32. package/dist/generated/settingsSchemaHooksClassifier.js +109 -29
  33. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -1
  34. package/dist/generated/settingsSchemaMcpRequestEntry.js +213 -93
  35. package/dist/generated/settingsSchemaMcpServerName.d.ts +1 -0
  36. package/dist/generated/settingsSchemaMcpServerName.js +8 -0
  37. package/dist/generated/settingsSchemaOwnKeyRead.d.ts +1 -0
  38. package/dist/generated/settingsSchemaOwnKeyRead.js +172 -0
  39. package/dist/generated/settingsSchemaPlainJsonObject.d.ts +1 -0
  40. package/dist/generated/settingsSchemaPlainJsonObject.js +28 -0
  41. package/dist/generated/settingsSchemaSafetyMergeSpec.js +10 -7
  42. package/dist/generated/settingsSchemaTierWords.d.ts +1 -0
  43. package/dist/generated/settingsSchemaTierWords.js +7 -0
  44. package/dist/generated/settingsSchemaTypes.d.ts +3 -1
  45. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  46. package/dist/hitl/decisionConflict.js +11 -11
  47. package/dist/hitl/decisionRefusal.d.ts +1 -0
  48. package/dist/hitl/decisionRefusal.js +4 -2
  49. package/dist/hitl/editedRuleTextPrecheck.d.ts +1 -0
  50. package/dist/hitl/editedRuleTextPrecheck.js +26 -1
  51. package/dist/hitl/persistedRulesWire.js +1 -0
  52. package/dist/hitl/planReviewWire.d.ts +2 -1
  53. package/dist/hitl/planReviewWire.js +8 -12
  54. package/dist/hitl/sessionPolicyDeliverable.d.ts +0 -1
  55. package/dist/hitl/sessionPolicyDeliverable.js +0 -5
  56. package/dist/hitl/sessionPolicyWire.js +1 -1
  57. package/dist/hitl/toolApprovalWire.d.ts +18 -6
  58. package/dist/hitl/toolApprovalWire.js +9 -4
  59. package/dist/i18n/messages.en.d.ts +5 -0
  60. package/dist/i18n/messages.en.js +6 -1
  61. package/dist/i18n/messages.zh.js +6 -1
  62. package/dist/index.d.ts +3 -2
  63. package/dist/index.js +2 -1
  64. package/dist/inheritEnvWire.d.ts +1 -0
  65. package/dist/inheritEnvWire.js +8 -5
  66. package/dist/mcpEngineLeg.d.ts +3 -0
  67. package/dist/mcpEngineLeg.js +4 -1
  68. package/dist/mcpLiveness.d.ts +18 -0
  69. package/dist/mcpLiveness.js +48 -1
  70. package/dist/mcpReconnect.d.ts +3 -0
  71. package/dist/mcpReconnect.js +6 -0
  72. package/dist/mcpStatusSupersetKeys.js +24 -1
  73. package/dist/mcpWireCaps.d.ts +2 -3
  74. package/dist/mcpWireCaps.js +9 -8
  75. package/dist/memoryEntriesWire.d.ts +35 -1
  76. package/dist/memoryEntriesWire.js +110 -14
  77. package/dist/modsFace.js +7 -3
  78. package/dist/postureKnob.js +1 -1
  79. package/dist/prepareRefusal.d.ts +0 -1
  80. package/dist/prepareRefusal.js +0 -3
  81. package/dist/promptProfileWireCaps.d.ts +1 -3
  82. package/dist/promptProfileWireCaps.js +2 -2
  83. package/dist/request/taskRequest.d.ts +1 -1
  84. package/dist/request/taskRequest.js +3 -3
  85. package/dist/retryStatus.d.ts +13 -1
  86. package/dist/retryStatus.js +20 -5
  87. package/dist/seatContract.js +10 -0
  88. package/dist/sessionMemoryErase.js +24 -2
  89. package/dist/turnFailurePresentation.js +8 -1
  90. package/dist/wireFailureShape.d.ts +12 -1
  91. package/dist/wireFailureShape.js +58 -24
  92. package/dist/wireRefusalCopy.d.ts +0 -3
  93. package/dist/wireRefusalCopy.js +0 -17
  94. package/docs/INTEGRATION-CLIENTS.md +155 -10
  95. package/package.json +5 -5
@@ -1,6 +1,6 @@
1
1
  import { mcpAllowToolsVerdict, mcpAssertionHeaderNotSentNotice, mcpElicitationVerdict, mcpToolAxesVerdict, mcpToolFacesVerdict, readMcpHttpIdentityHeaders } from './mcpWireCaps.js';
2
2
  import { skillToolListsVerdict, toCappedSpec } from './skillsWireCaps.js';
3
- import { SETTINGS_DESCRIBE_BAD_WIRE_NAME, SETTINGS_IS_USABLE_WIRE_NAME, SETTINGS_READ_REQUEST_MCP_TRANSPORT } from './generated/settingsSchemaFns.js';
3
+ import { SETTINGS_DESCRIBE_BAD_MCP_SERVER_NAME, SETTINGS_IS_USABLE_MCP_SERVER_NAME, SETTINGS_READ_REQUEST_MCP_TRANSPORT } from './generated/settingsSchemaFns.js';
4
4
  import { snapshotArgs, wireTransportOf } from './mcpWireTransport.js';
5
5
  import { msg, renderMessage } from './i18n/translate.js';
6
6
  import { TIER_ORDER } from './model/tierVocabulary.js';
@@ -66,7 +66,7 @@ export function cloudMcpToSpecs(servers, env) {
66
66
  recordDrop(name, 'missing-field');
67
67
  continue;
68
68
  }
69
- if (!SETTINGS_IS_USABLE_WIRE_NAME(name)) {
69
+ if (!SETTINGS_IS_USABLE_MCP_SERVER_NAME(name)) {
70
70
  recordDrop(name, 'name-unusable');
71
71
  continue;
72
72
  }
@@ -148,10 +148,12 @@ export function cloudMcpToSpecs(servers, env) {
148
148
  let axesDeclared;
149
149
  let elicitationDeclared;
150
150
  let allowDeclared;
151
+ let startupDeclared;
151
152
  try {
152
153
  axesDeclared = s.toolAxes;
153
154
  elicitationDeclared = s.elicitation;
154
155
  allowDeclared = s.allowTools;
156
+ startupDeclared = s.startupTimeoutMs;
155
157
  }
156
158
  catch {
157
159
  recordDrop(name, 'entry-unreadable');
@@ -199,6 +201,7 @@ export function cloudMcpToSpecs(servers, env) {
199
201
  ...(elVerdict.elicitation !== undefined ? { elicitation: elVerdict.elicitation } : {}),
200
202
  ...(facesShipped !== undefined ? { toolFaces: facesShipped } : {}),
201
203
  ...(axesShipped !== undefined ? { toolAxes: axesShipped } : {}),
204
+ ...(startupDeclared !== undefined ? { startupTimeoutMs: startupDeclared } : {}),
202
205
  });
203
206
  }
204
207
  return { specs, missingEnv: [...new Set(missingEnv)], droppedServers, degradedServers };
@@ -859,7 +862,7 @@ function droppedMcpNotices(carrier) {
859
862
  const label = name === undefined
860
863
  ? undefined
861
864
  : reason === 'name-unusable'
862
- ? SETTINGS_DESCRIBE_BAD_WIRE_NAME(name)
865
+ ? SETTINGS_DESCRIBE_BAD_MCP_SERVER_NAME(name)
863
866
  : reason === 'transport-invalid' || reason === 'allow-tools-invalid' || reason === 'entry-unreadable'
864
867
  ? `"${capForDisplay(name, DEGRADED_NAME_SHOWN)}"${pathLabel}`
865
868
  : `"${name}"${pathLabel}`;
@@ -0,0 +1,22 @@
1
+ export type SandboxGitCredentialOriginView = {
2
+ readonly origin: string;
3
+ readonly delivers: true;
4
+ } | {
5
+ readonly origin: string;
6
+ readonly delivers: false;
7
+ readonly reason: string;
8
+ };
9
+ export type SandboxGitCredentialPlaneReading = {
10
+ readonly kind: 'unobserved';
11
+ } | {
12
+ readonly kind: 'not_reported';
13
+ } | {
14
+ readonly kind: 'unreadable';
15
+ } | {
16
+ readonly kind: 'off';
17
+ readonly reason: string;
18
+ } | {
19
+ readonly kind: 'on';
20
+ readonly origins: readonly SandboxGitCredentialOriginView[];
21
+ };
22
+ export declare function observedSandboxGitCredentialPlane(baseUrl?: string | undefined): SandboxGitCredentialPlaneReading;
@@ -0,0 +1,75 @@
1
+ import { engineCapValue } from './engineCapsCache.js';
2
+ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
3
+ import { ownDataField } from './ownKey.js';
4
+ const UNOBSERVED = Object.freeze({ kind: 'unobserved' });
5
+ const NOT_REPORTED = Object.freeze({ kind: 'not_reported' });
6
+ const UNREADABLE = Object.freeze({ kind: 'unreadable' });
7
+ const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
8
+ const nonEmpty = (v) => typeof v === 'string' && v.length > 0;
9
+ function readOrigin(v) {
10
+ if (!isRecord(v))
11
+ return undefined;
12
+ const origin = ownDataField(v, 'origin');
13
+ const delivers = ownDataField(v, 'delivers');
14
+ if (!nonEmpty(origin))
15
+ return undefined;
16
+ if (delivers === true)
17
+ return Object.freeze({ origin, delivers: true });
18
+ if (delivers !== false)
19
+ return undefined;
20
+ const reason = ownDataField(v, 'reason');
21
+ return nonEmpty(reason) ? Object.freeze({ origin, delivers: false, reason }) : undefined;
22
+ }
23
+ function projectSandboxGit(plane) {
24
+ try {
25
+ if (!isRecord(plane))
26
+ return UNREADABLE;
27
+ const sg = ownDataField(plane, 'sandboxGit');
28
+ if (sg === undefined)
29
+ return NOT_REPORTED;
30
+ if (!isRecord(sg))
31
+ return UNREADABLE;
32
+ const state = ownDataField(sg, 'state');
33
+ if (state === 'off') {
34
+ const reason = ownDataField(sg, 'reason');
35
+ return nonEmpty(reason) ? Object.freeze({ kind: 'off', reason }) : UNREADABLE;
36
+ }
37
+ if (state !== 'on')
38
+ return UNREADABLE;
39
+ const list = ownDataField(sg, 'origins');
40
+ if (!Array.isArray(list))
41
+ return UNREADABLE;
42
+ const n = ownDataField(list, 'length');
43
+ if (typeof n !== 'number' || !Number.isInteger(n) || n < 0)
44
+ return UNREADABLE;
45
+ const origins = [];
46
+ for (let i = 0; i < n; i += 1) {
47
+ const row = readOrigin(ownDataField(list, String(i)));
48
+ if (row === undefined)
49
+ return UNREADABLE;
50
+ origins.push(row);
51
+ }
52
+ return Object.freeze({ kind: 'on', origins: Object.freeze(origins) });
53
+ }
54
+ catch {
55
+ return UNREADABLE;
56
+ }
57
+ }
58
+ export function observedSandboxGitCredentialPlane(baseUrl = engineWireTargetBaseUrl()) {
59
+ try {
60
+ const slot = engineCapValue(typeof baseUrl === 'string' && baseUrl.length > 0 ? baseUrl : undefined, 'credentialPlane');
61
+ switch (slot.kind) {
62
+ case 'unobserved':
63
+ return UNOBSERVED;
64
+ case 'not_reported':
65
+ return NOT_REPORTED;
66
+ case 'value':
67
+ return projectSandboxGit(slot.value);
68
+ default:
69
+ return UNREADABLE;
70
+ }
71
+ }
72
+ catch {
73
+ return UNOBSERVED;
74
+ }
75
+ }
@@ -13,6 +13,7 @@ export type DeviceExecutorManagementReading = {
13
13
  protocolVersion?: number;
14
14
  maxInflightPerDevice?: number;
15
15
  wsPath?: string;
16
+ relayUrl?: string;
16
17
  };
17
18
  export declare function projectDeviceExecutorManagementCapability(caps: unknown): DeviceExecutorManagementReading | undefined;
18
19
  export declare function observedDeviceExecutorManagement(baseUrl?: string | undefined): DeviceExecutorManagementReading;
@@ -1,6 +1,6 @@
1
1
  import { engineWireTargetBaseUrl } from './engineWireTarget.js';
2
2
  import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
3
- import { ownDataField } from './ownKey.js';
3
+ import { guardedRead, ownDataField } from './ownKey.js';
4
4
  import { capForDisplay } from './fleetTaskDesc.js';
5
5
  export function projectDeviceExecutorManagementCapability(caps) {
6
6
  try {
@@ -28,12 +28,14 @@ export function projectDeviceExecutorManagementCapability(caps) {
28
28
  const pv = ownDataField(d, 'protocolVersion');
29
29
  const mi = ownDataField(d, 'maxInflightPerDevice');
30
30
  const ws = ownDataField(d, 'wsPath');
31
+ const relay = guardedRead(() => ownDataField(d, 'relayUrl'));
31
32
  return {
32
33
  kind: 'present',
33
34
  management,
34
35
  ...(typeof pv === 'number' && Number.isFinite(pv) ? { protocolVersion: pv } : {}),
35
36
  ...(typeof mi === 'number' && Number.isFinite(mi) && mi >= 0 ? { maxInflightPerDevice: mi } : {}),
36
37
  ...(typeof ws === 'string' && ws.length > 0 ? { wsPath: ws } : {}),
38
+ ...(typeof relay === 'string' && relay.length > 0 ? { relayUrl: relay } : {}),
37
39
  };
38
40
  }
39
41
  catch {
@@ -59,6 +59,7 @@ export declare function activeRunBusyCarrierOf(ev: unknown): Record<string, unkn
59
59
  export declare const CORRUPT_SESSION_ERROR_CODE = "corrupt_session";
60
60
  export declare const CORRUPT_ROW_ERROR_CODE = "corrupt";
61
61
  export declare const MEMORY_CONTROL_PLANE_CORRUPT = "internal.memory_control_plane_corrupt";
62
+ export declare const RESUME_CONSTRAINT_REJECTED = "resume.constraint_rejected";
62
63
  export declare function isCorruptSessionCode(code: string | null | undefined): boolean;
63
64
  export declare const STOP_PARK_ARBITER_UNREACHABLE = "stop.park_arbiter_unreachable";
64
65
  export declare const STOP_PARK_RESUME_WON = "stop.park_resume_won";
@@ -104,8 +104,10 @@ export function activeRunBusyCarrierOf(ev) {
104
104
  export const CORRUPT_SESSION_ERROR_CODE = 'corrupt_session';
105
105
  export const CORRUPT_ROW_ERROR_CODE = 'corrupt';
106
106
  export const MEMORY_CONTROL_PLANE_CORRUPT = 'internal.memory_control_plane_corrupt';
107
+ const INVALID_SESSION_ERROR_CODE = 'invalid_session';
108
+ export const RESUME_CONSTRAINT_REJECTED = 'resume.constraint_rejected';
107
109
  export function isCorruptSessionCode(code) {
108
- return code === CORRUPT_SESSION_ERROR_CODE;
110
+ return code === CORRUPT_SESSION_ERROR_CODE || code === INVALID_SESSION_ERROR_CODE;
109
111
  }
110
112
  export const STOP_PARK_ARBITER_UNREACHABLE = 'stop.park_arbiter_unreachable';
111
113
  export const STOP_PARK_RESUME_WON = 'stop.park_resume_won';
@@ -1,5 +1,6 @@
1
1
  import type { FinishReasonUnknownDetail } from '@sema-agent/sdk';
2
2
  import { CORE_TOOL_TURN_INCOMPLETE_CAUSES, CORE_USER_INPUT_UNDRAINED_CAUSES, CORE_USER_INPUT_UNDRAINED_FAMILIES } from './generated/engineNoticeTables.js';
3
+ import type { UiLanguage } from './env/uiLanguage.js';
3
4
  export type NoticeAudience = 'user' | 'operator';
4
5
  export declare const ENGINE_NOTICE_CODES: readonly string[];
5
6
  export declare function engineNoticeInCatalog(code: unknown): boolean;
@@ -21,7 +22,16 @@ export interface AskUnresolvableFactsView {
21
22
  cause: string;
22
23
  parkLaneExisted?: boolean;
23
24
  remedy?: string;
25
+ remedies?: readonly AskUnresolvableRemedyView[];
24
26
  }
27
+ export type AskUnresolvableRemedyView = {
28
+ readonly kind: 'approver';
29
+ } | {
30
+ readonly kind: 'permission_mode';
31
+ readonly value: string;
32
+ readonly disclosedOn: string;
33
+ };
34
+ export declare function askUnresolvableRemedyContent(remedy: AskUnresolvableRemedyView, lang?: UiLanguage): string | undefined;
25
35
  export declare function readAskUnresolvable(notice: unknown): AskUnresolvableFactsView | undefined;
26
36
  export declare const DURABLE_MANDATE_SOURCES: readonly string[];
27
37
  export interface DurableGateUnavailableFactsView {
@@ -213,6 +223,20 @@ export interface StreamEndIgnoredFactsView {
213
223
  runId: string;
214
224
  }
215
225
  export declare function readStreamEndIgnored(notice: unknown): StreamEndIgnoredFactsView | undefined;
226
+ export interface ContextImageRemovedFactsView {
227
+ images: number;
228
+ sessionId: string;
229
+ runId: string;
230
+ }
231
+ export declare function readContextImageRemoved(notice: {} | null | undefined): ContextImageRemovedFactsView | undefined;
232
+ export interface McpAuthorizationRequiredFactsView {
233
+ server: string;
234
+ reason: string;
235
+ authorizeUrl?: string;
236
+ sessionId: string;
237
+ runId: string;
238
+ }
239
+ export declare function readMcpAuthorizationRequired(notice: {} | null | undefined): McpAuthorizationRequiredFactsView | undefined;
216
240
  export declare const ENGINE_NOTICE_FACT_READERS: Readonly<{
217
241
  readonly 'mcp.injection_dropped': typeof readMcpInjectionDrop;
218
242
  readonly 'delegation.ask_unresolvable': typeof readAskUnresolvable;
@@ -237,6 +261,8 @@ export declare const ENGINE_NOTICE_FACT_READERS: Readonly<{
237
261
  readonly 'task.turn_interrupted': typeof readTurnInterrupted;
238
262
  readonly 'route.finish_reason_unknown': typeof readFinishReasonUnknown;
239
263
  readonly 'route.stream_end_ignored': typeof readStreamEndIgnored;
264
+ readonly 'context.image_removed': typeof readContextImageRemoved;
265
+ readonly 'mcp.authorization_required': typeof readMcpAuthorizationRequired;
240
266
  }>;
241
267
  type FactReaderTable = typeof ENGINE_NOTICE_FACT_READERS;
242
268
  export type EngineNoticeFactsCode = keyof FactReaderTable;
@@ -1,7 +1,9 @@
1
1
  import { AUTO_MODE_UNAVAILABLE_CAUSES } from './autoModeUnavailable.js';
2
2
  import { displayUntrusted } from './displayUntrusted.js';
3
3
  import { CORE_ENGINE_NOTICE_CODES, CORE_MCP_INJECTION_DROP_REASONS, CORE_NOTICE_AUDIENCE, CORE_USER_INPUT_UNDRAINED_FAMILIES, } from './generated/engineNoticeTables.js';
4
- import { CORE_ASK_UNRESOLVABLE_CAUSES, CORE_DURABLE_MANDATE_SOURCES, CORE_PERMISSION_MODE_FOLD_REASONS, } from './generated/engineFactTables.js';
4
+ import { CORE_APPROVAL_REMEDY_KINDS, CORE_ASK_UNRESOLVABLE_CAUSES, CORE_DURABLE_MANDATE_SOURCES, CORE_PERMISSION_MODE_FOLD_REASONS, } from './generated/engineFactTables.js';
5
+ import { msg, renderMessage } from './i18n/translate.js';
6
+ import { readOwnDataValue } from './ownKey.js';
5
7
  export const ENGINE_NOTICE_CODES = CORE_ENGINE_NOTICE_CODES;
6
8
  const CATALOG = new Set(ENGINE_NOTICE_CODES);
7
9
  function audienceRow(table, code) {
@@ -50,6 +52,63 @@ function optionalSeat(o, key) {
50
52
  return undefined;
51
53
  }
52
54
  }
55
+ const _approvalRemedyKindPin = true;
56
+ void _approvalRemedyKindPin;
57
+ const APPROVAL_REMEDY_KIND_SET = new Set(CORE_APPROVAL_REMEDY_KINDS);
58
+ function readRemedyMember(v) {
59
+ try {
60
+ if (typeof v !== 'object' || v === null || Array.isArray(v))
61
+ return undefined;
62
+ const kind = readOwnDataValue(v, 'kind');
63
+ if (typeof kind !== 'string' || !APPROVAL_REMEDY_KIND_SET.has(kind))
64
+ return undefined;
65
+ if (kind === 'approver')
66
+ return Object.freeze({ kind: 'approver' });
67
+ const value = readOwnDataValue(v, 'value');
68
+ const disclosedOn = readOwnDataValue(v, 'disclosedOn');
69
+ if (typeof value !== 'string' || value.length === 0 || typeof disclosedOn !== 'string' || disclosedOn.length === 0)
70
+ return undefined;
71
+ return Object.freeze({ kind: 'permission_mode', value, disclosedOn });
72
+ }
73
+ catch {
74
+ return undefined;
75
+ }
76
+ }
77
+ function remedyAt(list, i) {
78
+ try {
79
+ return readOwnDataValue(list, String(i));
80
+ }
81
+ catch {
82
+ return undefined;
83
+ }
84
+ }
85
+ function readRemedyList(v) {
86
+ try {
87
+ if (!Array.isArray(v))
88
+ return undefined;
89
+ const n = readOwnDataValue(v, 'length');
90
+ if (typeof n !== 'number' || !Number.isInteger(n) || n <= 0)
91
+ return undefined;
92
+ const out = [];
93
+ for (let i = 0; i < n; i += 1) {
94
+ const r = readRemedyMember(remedyAt(v, i));
95
+ if (r !== undefined)
96
+ out.push(r);
97
+ }
98
+ return out.length > 0 ? Object.freeze(out) : undefined;
99
+ }
100
+ catch {
101
+ return undefined;
102
+ }
103
+ }
104
+ export function askUnresolvableRemedyContent(remedy, lang) {
105
+ const r = readRemedyMember(remedy);
106
+ if (r === undefined)
107
+ return undefined;
108
+ if (r.kind === 'approver')
109
+ return renderMessage(msg('notice.askUnresolvable.remedy.approver'), lang);
110
+ return renderMessage(msg('notice.askUnresolvable.remedy.permissionMode', { mode: displayUntrusted(r.value, { max: 64 }) }), lang);
111
+ }
53
112
  export function readAskUnresolvable(notice) {
54
113
  if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
55
114
  return undefined;
@@ -73,6 +132,13 @@ export function readAskUnresolvable(notice) {
73
132
  }
74
133
  const parkIn = o.parkLaneExisted;
75
134
  const remedyIn = optionalSeat(o, 'remedy');
135
+ let remedies;
136
+ try {
137
+ remedies = readRemedyList(readOwnDataValue(o, 'remedies'));
138
+ }
139
+ catch {
140
+ remedies = undefined;
141
+ }
76
142
  return {
77
143
  sessionId,
78
144
  toolName,
@@ -80,6 +146,7 @@ export function readAskUnresolvable(notice) {
80
146
  cause,
81
147
  ...(typeof parkIn === 'boolean' ? { parkLaneExisted: parkIn } : {}),
82
148
  ...(typeof remedyIn === 'string' && remedyIn.length > 0 ? { remedy: remedyIn } : {}),
149
+ ...(remedies !== undefined ? { remedies } : {}),
83
150
  };
84
151
  }
85
152
  export const DURABLE_MANDATE_SOURCES = CORE_DURABLE_MANDATE_SOURCES;
@@ -830,6 +897,48 @@ function readStreamEndIgnoredOf(notice) {
830
897
  return undefined;
831
898
  return { statement, word, frames, sessionId, runId };
832
899
  }
900
+ export function readContextImageRemoved(notice) {
901
+ return guardedRead(notice, readContextImageRemovedOf);
902
+ }
903
+ function readContextImageRemovedOf(notice) {
904
+ if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
905
+ return undefined;
906
+ const n = notice;
907
+ if (ownSeat(n, 'code') !== 'context.image_removed')
908
+ return undefined;
909
+ const d = ownSeat(n, 'detail');
910
+ if (typeof d !== 'object' || d === null || Array.isArray(d))
911
+ return undefined;
912
+ const o = d;
913
+ const images = ownSeat(o, 'images');
914
+ const sessionId = nonEmpty(ownSeat(o, 'sessionId'));
915
+ const runId = nonEmpty(ownSeat(o, 'runId'));
916
+ if (typeof images !== 'number' || !Number.isSafeInteger(images) || images < 1 || sessionId === undefined || runId === undefined)
917
+ return undefined;
918
+ return { images, sessionId, runId };
919
+ }
920
+ export function readMcpAuthorizationRequired(notice) {
921
+ return guardedRead(notice, readMcpAuthorizationRequiredOf);
922
+ }
923
+ function readMcpAuthorizationRequiredOf(notice) {
924
+ if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
925
+ return undefined;
926
+ const n = notice;
927
+ if (ownSeat(n, 'code') !== 'mcp.authorization_required')
928
+ return undefined;
929
+ const d = ownSeat(n, 'detail');
930
+ if (typeof d !== 'object' || d === null || Array.isArray(d))
931
+ return undefined;
932
+ const o = d;
933
+ const server = nonEmpty(ownSeat(o, 'server'));
934
+ const reason = nonEmpty(ownSeat(o, 'reason'));
935
+ const sessionId = nonEmpty(ownSeat(o, 'sessionId'));
936
+ const runId = nonEmpty(ownSeat(o, 'runId'));
937
+ if (server === undefined || reason === undefined || sessionId === undefined || runId === undefined)
938
+ return undefined;
939
+ const authorizeUrl = nonEmpty(optionalOwnSeat(o, 'authorizeUrl'));
940
+ return { server, reason, ...(authorizeUrl !== undefined ? { authorizeUrl } : {}), sessionId, runId };
941
+ }
833
942
  export const ENGINE_NOTICE_FACT_READERS = Object.freeze({
834
943
  'mcp.injection_dropped': readMcpInjectionDrop,
835
944
  'delegation.ask_unresolvable': readAskUnresolvable,
@@ -854,26 +963,26 @@ export const ENGINE_NOTICE_FACT_READERS = Object.freeze({
854
963
  'task.turn_interrupted': readTurnInterrupted,
855
964
  'route.finish_reason_unknown': readFinishReasonUnknown,
856
965
  'route.stream_end_ignored': readStreamEndIgnored,
966
+ 'context.image_removed': readContextImageRemoved,
967
+ 'mcp.authorization_required': readMcpAuthorizationRequired,
857
968
  });
858
969
  const _factReaderTablePin = true;
859
970
  void _factReaderTablePin;
860
971
  export function readEngineNoticeFacts(notice) {
861
- if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
862
- return undefined;
863
- let code;
864
- let detail;
865
972
  try {
866
- code = ownSeat(notice, 'code');
973
+ if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
974
+ return undefined;
975
+ const code = ownSeat(notice, 'code');
867
976
  if (typeof code !== 'string' || !Object.hasOwn(ENGINE_NOTICE_FACT_READERS, code))
868
977
  return undefined;
869
- detail = ownSeat(notice, 'detail');
978
+ const detail = ownSeat(notice, 'detail');
979
+ const k = code;
980
+ const facts = ENGINE_NOTICE_FACT_READERS[k]({ code: k, detail });
981
+ if (facts === undefined)
982
+ return undefined;
983
+ return { code: k, audience: noticeAudienceOf(k), facts };
870
984
  }
871
985
  catch {
872
986
  return undefined;
873
987
  }
874
- const k = code;
875
- const facts = ENGINE_NOTICE_FACT_READERS[k]({ code: k, detail });
876
- if (facts === undefined)
877
- return undefined;
878
- return { code: k, audience: noticeAudienceOf(k), facts };
879
988
  }
@@ -101,6 +101,7 @@ export const TRANSCRIPT_ROW_SIDECAR_KEYS = Object.freeze([
101
101
  '_sema_coded_detail',
102
102
  '_sema_task_notification',
103
103
  '_sema_answered_by',
104
+ '_sema_rewrite',
104
105
  ]);
105
106
  export function parkHeldCallIdOf(carrier) {
106
107
  return readFrameStringKey(carrier, 'toolCallId');
@@ -4,7 +4,7 @@ import { resumeRefusalContent, resumeContextUnavailableContent, requireExistingS
4
4
  import { resumeReopenContent } from './hitl/suspendedReopen.js';
5
5
  import { idempotencyPayloadMismatchContent } from './engineErrorCodes.js';
6
6
  import { inheritEnvRefusalContent } from './inheritEnvWire.js';
7
- import { usageWindowExhaustedContent, fleetLeaseUnavailableContent, settingsPermissionBucketRefusalContent, fieldLimitRefusalContent, autonomyLaneRefusalContent, userAttachmentRefusalContent, userInvokedSkillRefusalContent, unsupportedRuleRefusalContent, admissionWallRefusalContent, hostPostureRefusalContent, toolDeclarationRefusalContent, } from './wireRefusalCopy.js';
7
+ import { usageWindowExhaustedContent, fleetLeaseUnavailableContent, settingsPermissionBucketRefusalContent, fieldLimitRefusalContent, autonomyLaneRefusalContent, unsupportedRuleRefusalContent, admissionWallRefusalContent, hostPostureRefusalContent, toolDeclarationRefusalContent, } from './wireRefusalCopy.js';
8
8
  const ROLE_BY_READER = new Map([
9
9
  [corruptSessionContent, 'replacement'],
10
10
  [corruptStoredRowContent, 'replacement'],
@@ -19,8 +19,6 @@ const ROLE_BY_READER = new Map([
19
19
  [fieldLimitRefusalContent, 'replacement'],
20
20
  [autonomyLaneRefusalContent, 'replacement'],
21
21
  [idempotencyPayloadMismatchContent, 'replacement'],
22
- [userAttachmentRefusalContent, 'replacement'],
23
- [userInvokedSkillRefusalContent, 'replacement'],
24
22
  [unsupportedRuleRefusalContent, 'replacement'],
25
23
  [admissionWallRefusalContent, 'supplement'],
26
24
  [hostPostureRefusalContent, 'supplement'],
package/dist/eventLeg.js CHANGED
@@ -20,7 +20,7 @@ function makeFrameStageDomains(domains) {
20
20
  const FRAME_STAGE_DOMAINS = makeFrameStageDomains({
21
21
  bindRun: Object.freeze(['meta', 'done', 'failed']),
22
22
  stampOwner: Object.freeze(['task_progress']),
23
- hitlFrames: Object.freeze(['question', 'question_complete', 'elicitation', 'elicitation_complete', 'tool_approval', 'tool_approval_complete', 'approval_request', 'approval_revoke']),
23
+ hitlFrames: Object.freeze(['question', 'question_complete', 'elicitation', 'elicitation_complete', 'tool_approval', 'tool_approval_complete', 'approval_request', 'approval_complete', 'approval_revoke']),
24
24
  });
25
25
  const HITL_FRAMES_PROJECTED = Object.freeze(['human_input']);
26
26
  const _hitlFrameTypesPin = [true, true];
@@ -36,6 +36,7 @@ const HITL_PORT_OF = Object.freeze({
36
36
  tool_approval: 'toolApproval',
37
37
  tool_approval_complete: 'toolApproval',
38
38
  approval_request: 'register',
39
+ approval_complete: 'register',
39
40
  approval_revoke: 'register',
40
41
  });
41
42
  const inDomain = (stage, frameType) => FRAME_STAGE_DOMAINS[stage].includes(frameType);
@@ -295,7 +295,6 @@ const FLEET_TASK_ROW_WIRE_KEY_TUPLE = [
295
295
  'startedAt',
296
296
  'elapsedMs',
297
297
  'tokens',
298
- 'queuedCount',
299
298
  'awaitingPlanApproval',
300
299
  'currentAction',
301
300
  'currentTool',
@@ -321,6 +320,8 @@ const FLEET_WORKFLOW_ROW_WIRE_KEY_TUPLE = [
321
320
  'startedCount',
322
321
  'elapsedMs',
323
322
  'tokens',
323
+ 'errorCode',
324
+ 'parked',
324
325
  ];
325
326
  export const FLEET_WORKFLOW_ROW_WIRE_KEYS = FLEET_WORKFLOW_ROW_WIRE_KEY_TUPLE;
326
327
  export const FLEET_TASK_ROW_KEYS_NOT_PROJECTED = {
@@ -345,13 +346,6 @@ export const FLEET_TASK_ROW_KEYS_NOT_PROJECTED = {
345
346
  owner: 'client-core 规范重构轮',
346
347
  reason: '同 agentType:两位在本层合成一个身份 label,分开带出去等于把 187 的 tjl 规则推给每个消费端各写一遍。',
347
348
  },
348
- queuedCount: {
349
- kind: 'by-design',
350
- owner: 'client-core 0.95.0 CC-388',
351
- reason: '幻影键:sdk 行型仍声明它,但任何 server 版本都不发(生产侧已整只删除,零生产者,契约里也从没列过)。' +
352
- '投影一个永远缺席的可选位 = 假线索(读者以为「队列深度已经报了」),所以视图上不留位。' +
353
- 'sdk 在下一个 major 删掉这条声明的同批,本条与 `FLEET_TASK_ROW_WIRE_KEYS` 的 `queuedCount` 一起删;真要队列深度 = 带生产者的新键,不是复活这一个。',
354
- },
355
349
  workflowRunId: {
356
350
  kind: 'by-design',
357
351
  owner: 'client-core 规范重构轮',
@@ -364,6 +358,18 @@ export const FLEET_TASK_ROW_KEYS_NOT_PROJECTED = {
364
358
  reason: '结构化同源体 `currentTool` 已投影(SDK 注:currentAction 是它的**文本回落**)。🔴 诚实记账:旧端(server <1.288)只发 currentAction ⇒ 那一档上本视图今天确实拿不到活动文本,这是**已知缺口**不是设计取舍;补它 = 加 `currentAction?: string` 进本视图 + 端侧回落渲染。',
365
359
  },
366
360
  };
367
- export const FLEET_WORKFLOW_ROW_KEYS_NOT_PROJECTED = {};
361
+ export const FLEET_WORKFLOW_ROW_KEYS_NOT_PROJECTED = {
362
+ errorCode: {
363
+ kind: 'by-design',
364
+ owner: 'client-core 0.103.0 提货',
365
+ reason: '折进 status:只有停驻终态码 workflow.agent_parked 改显示状态(awaiting approval,停驻不是失败),读法唯一处 workflowRunDisplayStatusOf;' +
366
+ '0.95.0 CC-388 把它从视图退出时服务端还不铸,现在铸了也不回到视图 —— run 级别的其它码走 workflow 读面。',
367
+ },
368
+ parked: {
369
+ kind: 'by-design',
370
+ owner: 'client-core 0.103.0 提货',
371
+ reason: '折进 status:恒字面 true 的「有 agent 停在审批门上」位 ⇒ 显示状态 awaiting approval(workflowRunDisplayStatusOf 唯一读处);缺席不读作「没停」以外的任何事。',
372
+ },
373
+ };
368
374
  const _fleetViewKeyPins = [true, true, true, true, true, true, true, true];
369
375
  void _fleetViewKeyPins;
@@ -13,6 +13,7 @@ export type GateDispositionView = {
13
13
  classes?: readonly string[];
14
14
  deniedBy: DeniedBy | (string & {});
15
15
  cause?: string;
16
+ extension?: string;
16
17
  };
17
18
  export interface GateClassifierRoundView {
18
19
  modelRequested: string;
@@ -78,3 +79,22 @@ export declare function isApproverUnavailableGate(g: GateOutcomeView | undefined
78
79
  export declare function isHumanSettledGate(g: GateOutcomeView | undefined): boolean;
79
80
  export declare function isPolicyRefusedGate(g: GateOutcomeView | undefined): boolean;
80
81
  export declare function ccToolDenialKindForToolEnd(frame: unknown): CcToolDenialKind | undefined;
82
+ export type ToolInputRewriteAuthorView = {
83
+ readonly kind: 'extension';
84
+ readonly name: string;
85
+ } | {
86
+ readonly kind: 'policy';
87
+ } | {
88
+ readonly kind: 'approver';
89
+ } | {
90
+ readonly kind: string & {};
91
+ };
92
+ export type ToolInputRewriteValue = null | boolean | number | string | readonly ToolInputRewriteValue[] | {
93
+ readonly [key: string]: ToolInputRewriteValue;
94
+ };
95
+ export interface ToolInputRewriteView {
96
+ readonly by: readonly ToolInputRewriteAuthorView[];
97
+ readonly input?: ToolInputRewriteValue;
98
+ }
99
+ export declare function toolInputRewriteOf(frame: {} | null | undefined): ToolInputRewriteView | undefined;
100
+ export declare function rewriteExtensionNamesOf(rewrite: ToolInputRewriteView | undefined): readonly string[];
@@ -197,6 +197,7 @@ function readGateRecord(frame) {
197
197
  const mode = str(dr.mode);
198
198
  const askClass = str(dr.askClass);
199
199
  const classes = nonEmptyStringList(dr.classes);
200
+ const extension = str(dr.extension);
200
201
  disposition = {
201
202
  kind: 'denied',
202
203
  deniedBy,
@@ -205,6 +206,7 @@ function readGateRecord(frame) {
205
206
  ...(mode !== undefined ? { mode } : {}),
206
207
  ...(askClass !== undefined ? { askClass } : {}),
207
208
  ...(classes !== undefined ? { classes } : {}),
209
+ ...(extension !== undefined ? { extension } : {}),
208
210
  };
209
211
  }
210
212
  else {
@@ -328,3 +330,90 @@ const _settlementWordMirrorPin = SETTLEMENT_KIND_WORDS;
328
330
  void _settlementWordMirrorPin;
329
331
  const _settlementWordsCoveredPin = true;
330
332
  void _settlementWordsCoveredPin;
333
+ const REWRITE_INPUT_MAX_DEPTH = 256;
334
+ function ownDataSeat(o, key) {
335
+ const d = Object.getOwnPropertyDescriptor(o, key);
336
+ if (d === undefined || !Object.hasOwn(d, 'value'))
337
+ return { ok: false };
338
+ return { ok: true, value: d.value };
339
+ }
340
+ function isPlainJsonData(v, depth) {
341
+ if (v === null || typeof v === 'string' || typeof v === 'boolean')
342
+ return true;
343
+ if (typeof v === 'number')
344
+ return Number.isFinite(v);
345
+ if (typeof v !== 'object' || depth >= REWRITE_INPUT_MAX_DEPTH)
346
+ return false;
347
+ if (Array.isArray(v)) {
348
+ for (let i = 0; i < v.length; i++) {
349
+ const seat = ownDataSeat(v, String(i));
350
+ if (!seat.ok || !isPlainJsonData(seat.value, depth + 1))
351
+ return false;
352
+ }
353
+ return true;
354
+ }
355
+ const proto = Object.getPrototypeOf(v);
356
+ if (proto !== null && proto !== Object.prototype)
357
+ return false;
358
+ for (const key of Reflect.ownKeys(v)) {
359
+ if (typeof key !== 'string')
360
+ return false;
361
+ const seat = ownDataSeat(v, key);
362
+ if (!seat.ok || !isPlainJsonData(seat.value, depth + 1))
363
+ return false;
364
+ }
365
+ return true;
366
+ }
367
+ function readRewriteAuthor(v) {
368
+ if (typeof v !== 'object' || v === null || Array.isArray(v))
369
+ return undefined;
370
+ const kind = readOwnDataNonEmptyString(v, 'kind');
371
+ if (kind === undefined)
372
+ return undefined;
373
+ if (kind === 'extension') {
374
+ const name = readOwnDataNonEmptyString(v, 'name');
375
+ return name === undefined ? undefined : Object.freeze({ kind: 'extension', name });
376
+ }
377
+ return Object.freeze({ kind });
378
+ }
379
+ export function toolInputRewriteOf(frame) {
380
+ try {
381
+ if (typeof frame !== 'object' || frame === null || Array.isArray(frame))
382
+ return undefined;
383
+ const raw = readOwnDataValue(frame, 'rewrite');
384
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw))
385
+ return undefined;
386
+ const byRaw = readOwnDataValue(raw, 'by');
387
+ if (!Array.isArray(byRaw) || byRaw.length === 0)
388
+ return undefined;
389
+ const by = [];
390
+ for (let i = 0; i < byRaw.length; i++) {
391
+ const seat = ownDataSeat(byRaw, String(i));
392
+ const author = seat.ok ? readRewriteAuthor(seat.value) : undefined;
393
+ if (author === undefined)
394
+ return undefined;
395
+ by.push(author);
396
+ }
397
+ let input;
398
+ try {
399
+ const inputSeat = ownDataSeat(raw, 'input');
400
+ input = inputSeat.ok && isPlainJsonData(inputSeat.value, 0) ? inputSeat.value : undefined;
401
+ }
402
+ catch {
403
+ input = undefined;
404
+ }
405
+ return Object.freeze({ by: Object.freeze(by), ...(input !== undefined ? { input } : {}) });
406
+ }
407
+ catch {
408
+ return undefined;
409
+ }
410
+ }
411
+ export function rewriteExtensionNamesOf(rewrite) {
412
+ if (rewrite === undefined)
413
+ return Object.freeze([]);
414
+ const names = [];
415
+ for (const a of rewrite.by)
416
+ if (a.kind === 'extension' && 'name' in a && !names.includes(a.name))
417
+ names.push(a.name);
418
+ return Object.freeze(names);
419
+ }