@sema-agent/client-core 0.99.0 → 0.100.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 (128) hide show
  1. package/CHANGELOG.md +177 -0
  2. package/README.md +32 -19
  3. package/dist/adapt/arms.js +60 -36
  4. package/dist/adapt/panelTasks.d.ts +2 -1
  5. package/dist/adapt/panelTasks.js +32 -9
  6. package/dist/adapt/textStream.d.ts +1 -1
  7. package/dist/adapt/textStream.js +51 -28
  8. package/dist/adapter/activeRunSelfHeal.d.ts +7 -0
  9. package/dist/adapter/activeRunSelfHeal.js +58 -11
  10. package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
  11. package/dist/adapter/downstream/eventToSdkMessage.js +125 -9
  12. package/dist/adapter/downstream/terminalToSdkResult.js +10 -0
  13. package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
  14. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  15. package/dist/adapter/runStream.js +32 -5
  16. package/dist/adapter/types.d.ts +2 -0
  17. package/dist/agentsWireCaps.d.ts +7 -0
  18. package/dist/agentsWireCaps.js +100 -15
  19. package/dist/cloudConfigWireCaps.d.ts +10 -1
  20. package/dist/cloudConfigWireCaps.js +156 -62
  21. package/dist/compactionStatus.d.ts +34 -0
  22. package/dist/compactionStatus.js +196 -0
  23. package/dist/decideFailureNote.js +3 -3
  24. package/dist/displayUntrusted.js +150 -5
  25. package/dist/engineAgentPanelStore.d.ts +7 -4
  26. package/dist/engineErrorCodes.d.ts +9 -1
  27. package/dist/engineErrorCodes.js +9 -5
  28. package/dist/engineRowRef.js +1 -0
  29. package/dist/engineToolDirectory.d.ts +3 -0
  30. package/dist/engineToolDirectory.js +4 -2
  31. package/dist/eventLeg.d.ts +1 -7
  32. package/dist/eventLeg.js +7 -8
  33. package/dist/fileHistoryCaptureCapability.d.ts +0 -3
  34. package/dist/fileHistoryCaptureCapability.js +0 -4
  35. package/dist/generated/engineFactTables.d.ts +1 -0
  36. package/dist/generated/engineFactTables.js +27 -0
  37. package/dist/generated/engineNoticeTables.js +3 -0
  38. package/dist/generated/settingsSchemaFns.d.ts +12 -0
  39. package/dist/generated/settingsSchemaFns.js +13 -0
  40. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
  41. package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
  42. package/dist/generated/settingsSchemaTables.d.ts +1 -0
  43. package/dist/generated/settingsSchemaTables.js +5 -0
  44. package/dist/generated/settingsSchemaTypes.d.ts +28 -0
  45. package/dist/hitl/allowRuleShadow.js +2 -2
  46. package/dist/hitl/approvalCardReasons.js +2 -2
  47. package/dist/hitl/approvalHolds.d.ts +14 -0
  48. package/dist/hitl/approvalHolds.js +41 -0
  49. package/dist/hitl/askClassPair.d.ts +2 -2
  50. package/dist/hitl/askClassPair.js +2 -2
  51. package/dist/hitl/attributionLadder.d.ts +23 -0
  52. package/dist/hitl/attributionLadder.js +67 -0
  53. package/dist/hitl/decisionLedger.d.ts +55 -0
  54. package/dist/hitl/decisionLedger.js +156 -0
  55. package/dist/hitl/decisionRefusal.d.ts +1 -0
  56. package/dist/hitl/decisionRefusal.js +1 -1
  57. package/dist/hitl/decisionSend.d.ts +113 -0
  58. package/dist/hitl/decisionSend.js +579 -0
  59. package/dist/hitl/hitlBridge.js +18 -6
  60. package/dist/hitl/planReviewWire.js +45 -76
  61. package/dist/hitl/sessionPolicyDeliverable.js +3 -6
  62. package/dist/hitl/toolApprovalWire.js +43 -109
  63. package/dist/hostTurnSettings.d.ts +46 -7
  64. package/dist/hostTurnSettings.js +408 -7
  65. package/dist/humanTurn.d.ts +2 -1
  66. package/dist/humanTurn.js +3 -3
  67. package/dist/i18n/messages.en.d.ts +131 -0
  68. package/dist/i18n/messages.en.js +143 -12
  69. package/dist/i18n/messages.zh.js +148 -12
  70. package/dist/index.d.ts +18 -2
  71. package/dist/index.js +10 -1
  72. package/dist/inheritEnvCapability.d.ts +1 -0
  73. package/dist/inheritEnvCapability.js +9 -2
  74. package/dist/inheritEnvWire.js +2 -2
  75. package/dist/injectionLaneNotice.d.ts +5 -0
  76. package/dist/injectionLaneNotice.js +46 -0
  77. package/dist/mcpPanel.js +2 -0
  78. package/dist/mcpReconnect.js +2 -2
  79. package/dist/mcpToolToggles.d.ts +6 -0
  80. package/dist/mcpToolToggles.js +46 -0
  81. package/dist/mcpWireCaps.d.ts +10 -4
  82. package/dist/mcpWireCaps.js +106 -71
  83. package/dist/mcpWireTransport.d.ts +4 -0
  84. package/dist/mcpWireTransport.js +18 -0
  85. package/dist/modelCapabilityProbe.d.ts +2 -1
  86. package/dist/modelCapabilityProbe.js +10 -9
  87. package/dist/modelIdentityResolvability.d.ts +2 -0
  88. package/dist/modelIdentityResolvability.js +23 -5
  89. package/dist/ownKey.d.ts +26 -0
  90. package/dist/ownKey.js +75 -0
  91. package/dist/panelReduce.d.ts +5 -0
  92. package/dist/panelReduce.js +45 -13
  93. package/dist/panelStateHolder.d.ts +1 -0
  94. package/dist/panelStateHolder.js +10 -1
  95. package/dist/permissionRuleIssue.d.ts +2 -1
  96. package/dist/permissionRuleIssue.js +22 -21
  97. package/dist/pluginHooksWire.js +12 -10
  98. package/dist/prepareRefusal.d.ts +8 -0
  99. package/dist/prepareRefusal.js +72 -0
  100. package/dist/request/taskRequest.d.ts +10 -10
  101. package/dist/request/taskRequest.js +106 -65
  102. package/dist/resumeRefusalCopy.d.ts +3 -1
  103. package/dist/resumeRefusalCopy.js +22 -4
  104. package/dist/retryStatus.d.ts +18 -0
  105. package/dist/retryStatus.js +76 -19
  106. package/dist/ruleRefusalSentence.d.ts +4 -0
  107. package/dist/ruleRefusalSentence.js +58 -0
  108. package/dist/sandboxWire.d.ts +2 -1
  109. package/dist/sandboxWire.js +55 -21
  110. package/dist/scenarioRefusal.d.ts +2 -1
  111. package/dist/scenarioRefusal.js +5 -5
  112. package/dist/seam.d.ts +24 -9
  113. package/dist/seam.js +44 -4
  114. package/dist/seatContract.d.ts +16 -8
  115. package/dist/seatContract.js +21 -6
  116. package/dist/settingsCredentialKeyPaths.d.ts +8 -0
  117. package/dist/settingsCredentialKeyPaths.js +219 -0
  118. package/dist/skillsWireCaps.d.ts +0 -3
  119. package/dist/skillsWireCaps.js +1 -2
  120. package/dist/subagentContentStore.d.ts +1 -0
  121. package/dist/subagentContentStore.js +135 -27
  122. package/dist/toolsFlagNames.d.ts +8 -0
  123. package/dist/toolsFlagNames.js +110 -0
  124. package/dist/turnFailurePresentation.js +15 -7
  125. package/dist/wireRefusalCopy.d.ts +51 -17
  126. package/dist/wireRefusalCopy.js +298 -135
  127. package/docs/INTEGRATION-CLIENTS.md +423 -26
  128. package/package.json +4 -4
@@ -0,0 +1,58 @@
1
+ import { capForDisplay } from './fleetTaskDesc.js';
2
+ import { msg, renderMessage } from './i18n/translate.js';
3
+ import { permissionRuleIssueDetail } from './permissionRuleIssue.js';
4
+ const RULE_REFUSAL_NAMED_MAX = 5;
5
+ const RULE_NAME_MAX = 120;
6
+ const CLASS_OF_REASON = Object.freeze({
7
+ retired_tool_name: 'toolName',
8
+ unprefixed_namespaced_name: 'toolName',
9
+ incomplete_protocol_name: 'toolName',
10
+ home_relative_path: 'homePath',
11
+ compile_refused: 'compile',
12
+ paren_in_tool_name: 'compile',
13
+ });
14
+ function reasonOf(row, lang) {
15
+ const cls = typeof row.reason === 'string' && Object.hasOwn(CLASS_OF_REASON, row.reason) ? CLASS_OF_REASON[row.reason] : undefined;
16
+ if (cls === 'toolName')
17
+ return renderMessage(msg('rules.refusal.reason.toolName'), lang);
18
+ if (cls === 'homePath')
19
+ return renderMessage(msg('rules.refusal.reason.homePath'), lang);
20
+ if (cls === 'compile')
21
+ return permissionRuleIssueDetail(row.code, row.message, row.rule, lang);
22
+ return undefined;
23
+ }
24
+ function nameOf(rule) {
25
+ return `"${capForDisplay(rule, RULE_NAME_MAX)}"`;
26
+ }
27
+ export function ruleRefusalSentence(rows, lang) {
28
+ const seen = new Set();
29
+ const items = [];
30
+ try {
31
+ if (!Array.isArray(rows))
32
+ return undefined;
33
+ for (const row of rows) {
34
+ if (typeof row !== 'object' || row === null)
35
+ continue;
36
+ const rule = row.rule;
37
+ if (typeof rule !== 'string' || rule === '' || seen.has(rule))
38
+ continue;
39
+ const reason = reasonOf(row, lang);
40
+ if (reason === undefined)
41
+ continue;
42
+ seen.add(rule);
43
+ items.push({ rule, reason });
44
+ }
45
+ }
46
+ catch {
47
+ return undefined;
48
+ }
49
+ if (items.length === 0)
50
+ return undefined;
51
+ const shown = items.slice(0, RULE_REFUSAL_NAMED_MAX);
52
+ const separator = renderMessage(msg('rules.refusal.itemSeparator'), lang);
53
+ const named = shown.map((it) => renderMessage(msg('rules.refusal.item', { rule: nameOf(it.rule), reason: it.reason }), lang)).join(separator);
54
+ const rest = items.length - shown.length;
55
+ const list = rest > 0 ? msg('rules.refusal.list.more', { shown: named, count: rest }) : named;
56
+ const listText = typeof list === 'string' ? list : renderMessage(list, lang);
57
+ return renderMessage(items.length === 1 ? msg('rules.refusal.sentence.one', { list: listText }) : msg('rules.refusal.sentence.other', { count: items.length, list: listText }), lang);
58
+ }
@@ -1,3 +1,4 @@
1
+ import type { TaskRequestLike } from './request/taskRequest.js';
1
2
  export type SandboxSelection = {
2
3
  mode: 'default';
3
4
  } | {
@@ -25,4 +26,4 @@ export declare const SANDBOX_NO_PUBLISHED_IMAGE_404_ANCHOR = "no published sandb
25
26
  export declare const SANDBOX_CASCADE_CONFLICT_400_ANCHOR = "not supported together with cascade/verify";
26
27
  export type SandboxHintHost = 'terminal' | 'web' | 'desktop';
27
28
  export declare const SANDBOX_HINT_HOSTS: readonly SandboxHintHost[];
28
- export declare function sandboxDegradeHint(err: unknown, host?: SandboxHintHost): string | undefined;
29
+ export declare function sandboxDegradeHint(err: unknown, host?: SandboxHintHost, sentRequest?: TaskRequestLike): string | undefined;
@@ -1,5 +1,5 @@
1
1
  import { lastFlagValue } from './argvFlagValue.js';
2
- import { CAPABILITY_IMAGE_INDEX_REQUIRED } from './engineErrorCodes.js';
2
+ import { CAPABILITY_IMAGE_INDEX_REQUIRED, CAPABILITY_K8S_LANE_REQUIRED, isStatusDerivedCoarseCode, NOT_FOUND_IMAGE, REQUEST_FIELD_CONFLICT, REQUEST_PRECONDITION_UNMET } from './engineErrorCodes.js';
3
3
  import { THROWN_SLOT_UNREADABLE, readThrownSlot } from './wireFailureShape.js';
4
4
  const MAX_PROFILE_LEN = 128;
5
5
  const USAGE_HINT = "sema: --sandbox expects a profile name or 'auto'.\n" +
@@ -49,15 +49,15 @@ export const SANDBOX_NO_PUBLISHED_IMAGE_404_ANCHOR = 'no published sandbox image
49
49
  export const SANDBOX_CASCADE_CONFLICT_400_ANCHOR = 'not supported together with cascade/verify';
50
50
  export const SANDBOX_HINT_HOSTS = Object.freeze(['terminal', 'web', 'desktop']);
51
51
  const SANDBOX_HINT_ARMS = Object.freeze({
52
- imageIndexRequired501: {
53
- fact: 'Cloud sandbox images are not available on this engine: its storage backend keeps no image index, so profiles cannot be listed or selected here.',
52
+ imageIndexRequired: {
53
+ fact: 'Cloud sandbox images are not available on this engine: it has no sandbox image index (its store keeps none, or no image catalog is attached from the sema-web-admin config center), so profiles cannot be listed or selected here.',
54
54
  sep: '\n',
55
55
  outlet: {
56
- terminal: 'Use a worker backed by a SQL store (it has the image index), or re-run without --sandbox.',
57
- graphical: 'Use a worker backed by a SQL store (it has the image index), or keep the default environment.',
56
+ terminal: 'Use a worker that has the image index (a SQL-backed store with the image catalog attached), or re-run without --sandbox.',
57
+ graphical: 'Use a worker that has the image index (a SQL-backed store with the image catalog attached), or keep the default environment.',
58
58
  },
59
59
  },
60
- k8sLaneOnly400: {
60
+ k8sLaneOnly: {
61
61
  subject: { terminal: '--sandbox <profile>', graphical: 'The selected sandbox image profile' },
62
62
  fact: ' only applies on k8s-lane workers; this engine runs a host/e2b sandbox lane, so the request was honestly rejected.',
63
63
  sep: '\n',
@@ -66,12 +66,13 @@ const SANDBOX_HINT_ARMS = Object.freeze({
66
66
  graphical: 'Keep the default environment, or connect to a k8s-lane worker.',
67
67
  },
68
68
  },
69
- noImageIndex400: {
70
- fact: 'This worker has no sandbox image index configured (the sema-web-admin config center is not attached), so per-task profiles cannot resolve.',
69
+ sessionRequired: {
70
+ subject: { terminal: '--sandbox <profile>', graphical: 'The selected sandbox image profile' },
71
+ fact: ' is bound to a session, and this request resolved none, so the per-task image could not be registered.',
71
72
  sep: '\n',
72
73
  outlet: {
73
- terminal: 'Re-run without --sandbox, or use a worker with the image index enabled.',
74
- graphical: 'Keep the default environment, or use a worker with the image index enabled.',
74
+ terminal: 'Run it inside a session, or re-run without --sandbox.',
75
+ graphical: 'Start the work inside a session, or keep the default environment.',
75
76
  },
76
77
  },
77
78
  noPublishedImage404: {
@@ -104,21 +105,54 @@ function sandboxSlot(err, key) {
104
105
  const v = readThrownSlot(err, key, 'data');
105
106
  return v === THROWN_SLOT_UNREADABLE ? undefined : v;
106
107
  }
107
- export function sandboxDegradeHint(err, host) {
108
- const status = sandboxSlot(err, 'status');
109
- if (status === 501 && sandboxSlot(err, 'errorCode') === CAPABILITY_IMAGE_INDEX_REQUIRED)
110
- return sandboxHintOf(SANDBOX_HINT_ARMS.imageIndexRequired501, host);
111
- if (typeof err !== 'object' || err === null || typeof status !== 'number')
112
- return undefined;
108
+ function sentSandboxFacts(sentRequest) {
109
+ if (sentRequest === undefined || sentRequest === null || typeof sentRequest !== 'object')
110
+ return { profile: false, cascadeOrVerify: false, sessionOrDevice: false };
111
+ const profile = sandboxSlot(sentRequest, 'sandboxImageProfile');
112
+ const sent = (key) => {
113
+ const v = sandboxSlot(sentRequest, key);
114
+ return typeof v === 'string' && v.length > 0;
115
+ };
116
+ return {
117
+ profile: typeof profile === 'string' && profile.length > 0,
118
+ cascadeOrVerify: sandboxSlot(sentRequest, 'cascade') === true || sandboxSlot(sentRequest, 'verify') === true,
119
+ sessionOrDevice: sent('sessionId') || sent('deviceId'),
120
+ };
121
+ }
122
+ export function sandboxDegradeHint(err, host, sentRequest) {
113
123
  try {
124
+ if (typeof err !== 'object' || err === null)
125
+ return undefined;
126
+ const status = sandboxSlot(err, 'status');
127
+ const codeRaw = sandboxSlot(err, 'errorCode');
128
+ const code = typeof codeRaw === 'string' && codeRaw.length > 0 ? codeRaw : undefined;
129
+ if (status === 501 && code === CAPABILITY_K8S_LANE_REQUIRED)
130
+ return sandboxHintOf(SANDBOX_HINT_ARMS.k8sLaneOnly, host);
131
+ if (status === 501 && code === CAPABILITY_IMAGE_INDEX_REQUIRED)
132
+ return sandboxHintOf(SANDBOX_HINT_ARMS.imageIndexRequired, host);
133
+ if (status === 404 && code === NOT_FOUND_IMAGE)
134
+ return sandboxHintOf(SANDBOX_HINT_ARMS.noPublishedImage404, host);
135
+ if (status === 400 && code === REQUEST_PRECONDITION_UNMET) {
136
+ const sent = sentSandboxFacts(sentRequest);
137
+ return sent.profile && !sent.cascadeOrVerify && !sent.sessionOrDevice ? sandboxHintOf(SANDBOX_HINT_ARMS.sessionRequired, host) : undefined;
138
+ }
139
+ if (typeof status !== 'number')
140
+ return undefined;
141
+ const noCode = code === undefined || isStatusDerivedCoarseCode(code);
142
+ const cascadeCoded = code === REQUEST_FIELD_CONFLICT && (sentRequest === undefined || (() => {
143
+ const sent = sentSandboxFacts(sentRequest);
144
+ return sent.profile && sent.cascadeOrVerify;
145
+ })());
146
+ if (!noCode && !cascadeCoded)
147
+ return undefined;
114
148
  const msg = err.message;
115
149
  if (typeof msg !== 'string')
116
150
  return undefined;
117
- if (status === 400 && msg.includes(SANDBOX_K8S_ONLY_400_ANCHOR))
118
- return sandboxHintOf(SANDBOX_HINT_ARMS.k8sLaneOnly400, host);
119
- if (status === 400 && msg.includes(SANDBOX_NO_IMAGE_INDEX_400_ANCHOR))
120
- return sandboxHintOf(SANDBOX_HINT_ARMS.noImageIndex400, host);
121
- if (status === 404 && msg.includes(SANDBOX_NO_PUBLISHED_IMAGE_404_ANCHOR))
151
+ if (noCode && status === 400 && msg.includes(SANDBOX_K8S_ONLY_400_ANCHOR))
152
+ return sandboxHintOf(SANDBOX_HINT_ARMS.k8sLaneOnly, host);
153
+ if (noCode && status === 400 && msg.includes(SANDBOX_NO_IMAGE_INDEX_400_ANCHOR))
154
+ return sandboxHintOf(SANDBOX_HINT_ARMS.imageIndexRequired, host);
155
+ if (noCode && status === 404 && msg.includes(SANDBOX_NO_PUBLISHED_IMAGE_404_ANCHOR))
122
156
  return sandboxHintOf(SANDBOX_HINT_ARMS.noPublishedImage404, host);
123
157
  if (status === 400 && msg.includes(SANDBOX_CASCADE_CONFLICT_400_ANCHOR))
124
158
  return sandboxHintOf(SANDBOX_HINT_ARMS.cascadeConflict400, host);
@@ -1,3 +1,4 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
1
2
  export interface ScenarioRefusalReading {
2
3
  readonly errorCode?: string;
3
4
  readonly error?: string;
@@ -6,4 +7,4 @@ export interface ScenarioRefusalReading {
6
7
  }
7
8
  export declare function scenarioRefusalOf(body: object): ScenarioRefusalReading | undefined | null;
8
9
  export declare function scenarioRefusalFromError(err: {} | null | undefined): ScenarioRefusalReading | null;
9
- export declare function scenarioRefusalContent(reading: ScenarioRefusalReading): string;
10
+ export declare function scenarioRefusalContent(reading: ScenarioRefusalReading, lang?: UiLanguage): string;
@@ -3,6 +3,7 @@ import { readOwnDataValue } from './ownKey.js';
3
3
  import { SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE } from './engineErrorCodes.js';
4
4
  import { readErrorRecord, readErrorString } from './wireFailureShape.js';
5
5
  import { effectiveWireErrorCode } from './wireErrorTriage.js';
6
+ import { msg, renderMessage } from './i18n/translate.js';
6
7
  const SCENARIO_REFUSAL_ERROR_MAX = 200;
7
8
  function detailBits(detail) {
8
9
  if (detail === undefined)
@@ -86,7 +87,7 @@ export function scenarioRefusalFromError(err) {
86
87
  return null;
87
88
  }
88
89
  }
89
- export function scenarioRefusalContent(reading) {
90
+ export function scenarioRefusalContent(reading, lang) {
90
91
  let code;
91
92
  let scenario;
92
93
  let source;
@@ -102,10 +103,9 @@ export function scenarioRefusalContent(reading) {
102
103
  }
103
104
  if (code === SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE) {
104
105
  const name = typeof scenario === 'string' && scenario.length > 0 ? ` ("${capForDisplay(scenario, 80)}")` : '';
105
- const from = source === 'ruling' ? ', assigned to you by the configuration center,' : source === 'deployment' ? ", this deployment's default scenario," : '';
106
- return (`This deployment cannot resolve your scenario: the scenario${name}${from} does not exist here, so it refuses whatever depends on your scenario — ` +
107
- "new runs that do not name a scenario, and this session's list of MCP servers · Ask whoever operates the engine to fix the scenario assignment");
106
+ const from = source === 'ruling' ? msg('config.scenarioRefusal.source.ruling') : source === 'deployment' ? msg('config.scenarioRefusal.source.deployment') : '';
107
+ return renderMessage(msg('config.scenarioRefusal.dangling', { name, from }), lang);
108
108
  }
109
109
  const tail = typeof code === 'string' && code.length > 0 ? ` (${capForDisplay(code, 80)})` : '';
110
- return `This deployment's scenario check refused to resolve your scenario${tail}, so whatever depends on your scenario is not available — this session's list of MCP servers is unknown`;
110
+ return renderMessage(msg('config.scenarioRefusal.generic', { tail }), lang);
111
111
  }
package/dist/seam.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { ModelUsage, SDKMessage } from '@sema-agent/agent-types';
2
2
  import type { EngineTurnUsage } from './adapter/downstream/turnUsageToModelUsage.js';
3
3
  import type { RunCostReconcile } from './adapter/downstream/terminalToSdkResult.js';
4
- import type { WiringManifestAutoMode, WiringManifestModelGate, WiringManifestMcpEntryView, WiringManifestHookEntryView, WiringManifestLspSeamView, WiringManifestWriteProtectionView, WiringManifestAutoConsolidationView, WiringManifestReadDenyView, ContextUsageSectionView, PromptManifestSectionView, PromptManifestBlockView, PromptManifestToolView } from './adapter/downstream/eventToSdkMessage.js';
4
+ import type { WiringManifestAutoMode, WiringManifestModelGate, WiringManifestMcpEntryView, WiringManifestHookEntryView, WiringManifestLspSeamView, WiringManifestWriteProtectionView, WiringManifestAutoConsolidationView, WiringManifestReadDenyView, WiringManifestModView, ContextUsageSectionView, PromptManifestSectionView, PromptManifestBlockView, PromptManifestToolView, PromptManifestIdentityView } from './adapter/downstream/eventToSdkMessage.js';
5
5
  import type { ToolRosterView, ToolRosterDeltaView, WiringManifestHandsView } from './toolRoster.js';
6
6
  import type { WiringManifestFleetView } from './adapter/downstream/wiringManifestView.js';
7
7
  import type { SuspendedReopenReading } from './hitl/suspendedReopen.js';
@@ -34,13 +34,6 @@ export interface AdapterContext {
34
34
  readonly toolName: string;
35
35
  }): ToolKillCause | undefined;
36
36
  coalesceIntervalMs?: number;
37
- continuesPark?: ContinuesParkDeclaration;
38
- }
39
- export interface ContinuesParkDeclaration {
40
- readonly toolCallId: string;
41
- readonly checkpointId?: string;
42
- readonly parkedTaskId?: string;
43
- readonly continuationTaskId?: string;
44
37
  }
45
38
  export type ChromeEvent = {
46
39
  kind: 'retry_status';
@@ -167,7 +160,7 @@ export type ChromeEvent = {
167
160
  } | ({
168
161
  kind: 'run_cost_reconciled';
169
162
  laneProof: LaneProof;
170
- } & RunCostReconcile) | HumanInputChromeEvent | MessageCommittedChromeEvent | EngineNoticeChromeEvent | TextSegmentEndChromeEvent | ThinkingSegmentEndChromeEvent | ToolDisclosureChromeEvent | ToolProgressChromeEvent | ToolRosterDeltaChromeEvent | ContextUsageChromeEvent | CompactionOutcomeChromeEvent | SubagentStartedChromeEvent | PromptAssembledChromeEvent | MemorySavedChromeEvent | WiringManifestChromeEvent | ResultTextDivergedChromeEvent | ResultReplayedChromeEvent | ToolParkedChromeEvent | ApprovalRequestChromeEvent | ApprovalRevokeChromeEvent | {
163
+ } & RunCostReconcile) | HumanInputChromeEvent | MessageCommittedChromeEvent | EngineNoticeChromeEvent | TextSegmentEndChromeEvent | ThinkingSegmentEndChromeEvent | ToolDisclosureChromeEvent | ToolProgressChromeEvent | ToolRosterDeltaChromeEvent | ContextUsageChromeEvent | CompactionOutcomeChromeEvent | CompactionStartedChromeEvent | SubagentStartedChromeEvent | PromptAssembledChromeEvent | MemorySavedChromeEvent | WiringManifestChromeEvent | ResultTextDivergedChromeEvent | ResultReplayedChromeEvent | ToolParkedChromeEvent | ApprovalRequestChromeEvent | ApprovalRevokeChromeEvent | {
171
164
  kind: 'suspended_reopened';
172
165
  laneProof: LaneProof;
173
166
  reopen: Extract<SuspendedReopenReading, {
@@ -195,6 +188,7 @@ export interface WiringManifestChromeEvent {
195
188
  readonly selected: readonly string[];
196
189
  };
197
190
  fleet?: WiringManifestFleetView;
191
+ mods?: readonly WiringManifestModView[];
198
192
  eventId?: string;
199
193
  }
200
194
  export interface TextSegmentCommittedRow {
@@ -235,6 +229,15 @@ export interface CompactionOutcomeChromeEvent {
235
229
  outcome: string;
236
230
  trigger?: string;
237
231
  reason?: string;
232
+ pass?: string;
233
+ eventId?: string;
234
+ }
235
+ export interface CompactionStartedChromeEvent {
236
+ kind: 'compaction_started';
237
+ laneProof: LaneProof;
238
+ pass: string;
239
+ trigger: string;
240
+ startedAt?: number;
238
241
  eventId?: string;
239
242
  }
240
243
  export interface SubagentStartedChromeEvent {
@@ -269,6 +272,7 @@ export interface PromptAssembledChromeEvent {
269
272
  blocks?: readonly PromptManifestBlockView[];
270
273
  sections?: readonly PromptManifestSectionView[];
271
274
  tools?: readonly PromptManifestToolView[];
275
+ identity?: PromptManifestIdentityView;
272
276
  eventId?: string;
273
277
  }
274
278
  export interface ToolDisclosureChromeEvent {
@@ -401,3 +405,14 @@ export declare function deriveTranscriptId(frame: {
401
405
  id?: unknown;
402
406
  toolCallId?: unknown;
403
407
  }, ctx: Pick<AdapterContext, 'uuid'>, suffix?: string): string;
408
+ export declare const SEMA_TERMINAL_OWNER_KEY = "_sema_terminal_owner";
409
+ export type TerminalOwner = {
410
+ readonly kind: 'request-not-sent';
411
+ readonly requestId?: string;
412
+ readonly heldBy?: string;
413
+ } | {
414
+ readonly kind: 'followed-run';
415
+ readonly taskId: string;
416
+ readonly runId?: string;
417
+ };
418
+ export declare function terminalOwnerOf(row: {} | null | undefined): TerminalOwner | undefined;
package/dist/seam.js CHANGED
@@ -76,6 +76,12 @@ const CHROME_ARM_TABLE = {
76
76
  duty: 'CC-89(0.75.0):一次压缩的非 compacted 结局(作废 / 失败等),给用户一条可见提示。`outcome` / `trigger` 是引擎开集原词,按成员渲染必带 default 臂、认不得照原词显示;' +
77
77
  '🔴 不是终态 —— 任务还在跑,别据它收 spinner;`laneProof.lane` 为 subagent = 子代的压缩结局,别渲成主会话的;成功压缩不走本臂(权威是转录的 compact_boundary)。不接 = 压缩失败对用户不可见。',
78
78
  },
79
+ compaction_started: {
80
+ required: false,
81
+ duty: '可选:一次压缩 pass 宣告开始(服务端 ≥ 7.132.0)—— 要显示「正在压缩」的宿主接它。🔴 别自己配对开 / 收:把本臂、`compaction_outcome` 臂与转录 `compact_boundary` 行喂给' +
82
+ ' `createCompactionStatusTracker()`(按 `pass` 开收、子代车道不点亮主车道、流结束收口),交互车道读它的 `reading()`,print 车道把它的变化转成 CC 同形 `system/status` 帧;' +
83
+ '`trigger` 开集原词(按成员渲染带 default 臂);`startedAt` 缺席 = 没报;本臂不是终态,`laneProof.lane` 为 subagent = 子代的压缩,别渲成主会话的。',
84
+ },
79
85
  subagent_started: {
80
86
  required: false,
81
87
  duty: '可选:委派子代每周期一帧的起跑事实(sdk `task_started`,服务端 ≥ 7.127.0)—— 要「起跑时就开子代行」的宿主接它(不接 = 首个 task_progress 才开行,与 0.98.0 同)。' +
@@ -167,13 +173,13 @@ const CHROME_ARM_TABLE = {
167
173
  duty: '🔴 引擎明报的 assistant 散文段边界 + **该段权威全文**(#323/core #447;server ≥7.75.3 起 content 经脱敏器、' +
168
174
  'text_delta 仍逐字 ⇒ 两者**可以不相等**)。①`diverged` 在场(never false)⇒ 你按增量拼出来的那一段是过期的,' +
169
175
  '必须用 content **重渲该段**并以它为该段 committed 文本,不许保留增量拼文;②`committedPrefixDiverged` 在场' +
170
- '(never false)⇒ 这一段此前已 committed 上屏的正文**也**过期了,🔴 本包在这一形上**一个字节都不再交**' +
176
+ '(never false)⇒ 这一段此前已 committed 上屏的正文**也**过期了,🔴 本包在这一形上**一个字节都不再交**(唯一不同:本段已提交行的归属说不出 —— 上游两行同 uuid,`committedUuids` 整键缺席 —— 时本包一个字节不动,还押着的原始那截在本事件之后照旧作为本段末行交出)' +
171
177
  '(撤不回的那截拼不出 content)⇒ 把 committedPrefixLen 指的那一截换成 content,这一条**所有宿主都要做**;' +
172
178
  '缺席 ⇒ 本包交的是尾段,前缀+尾段=content,什么都不用丢;③`committedPrefixLen`(never 0)= 定位量,' +
173
179
  '🔴 **单位 = JS 字符串长度(UTF-16 代码单元),不是 UTF-8 字节、也不是几条消息**' +
174
- '(按 UTF-8 字节截会在非 ASCII 正文上截错位置把凭据留在屏上;按消息丢会连合并在同一条消息里的上一段定稿一起删掉),' +
175
- '照抄 `已committed正文.slice(0, 长度 - committedPrefixLen) + content`;按**增量拼文**计长、不是 content 上的偏移;④三键全缺席 ⇒ 照旧只当对账/定界,拿 content 再渲一行 = 同一段上屏两遍;⑤`segmentId`(恒在场)= 段身份,与本段已过境的 committed 文本行顶层 `_sema_segment_id` 同值 —— 换掉已提交那截时认行的钥匙是**两把**:行 uuid ∧ 段身份(按字节相等找行会被同后缀的独立行冒充)。' +
176
- '🔴 缺席只表示「没报」,绝不等于「段没结束」——要退回自家启发式必须按整条流判、不按单帧判;⑥`committedUuids[]`(0.71.0 起,在场 = 本窗口已提交行按序、`[]` = 零行、整键缺席 = 本包说不出):`committedPrefixDiverged` ⇒ **按 `committedRows[]` 逐行写回正文**(包已算好:首行 = 前段定稿前缀 + content、其余行空;别整行换首行,提交行可能带上一段定稿),端不再自己数窗口里过境的行,也不再对多行段整发放弃;`committedUuid` = 末条兼容位;' +
180
+ '(按 UTF-8 字节截会在非 ASCII 正文上截错位置把凭据留在屏上;按消息丢会连同一条消息里别的段的正文一起删掉),' +
181
+ '照抄 `已committed正文.slice(0, 长度 - committedPrefixLen) + content`;按**增量拼文**计长、不是 content 上的偏移;④三键全缺席 ⇒ 照旧只当对账/定界,拿 content 再渲一行 = 同一段上屏两遍;⑤`segmentId`(恒在场)= 段身份,与本段**全部** committed 文本行顶层 `_sema_segment_id` 同值(一行恰属一个段;本事件之后紧跟本段末行;段只按这一位认,不按消息界 / 相邻猜)—— 换掉已提交那截时认行的钥匙是**两把**:行 uuid ∧ 段身份(按字节相等找行会被同后缀的独立行冒充)。' +
182
+ '🔴 缺席只表示「没报」,绝不等于「段没结束」——要退回自家启发式必须按整条流判、不按单帧判;⑥`committedUuids[]`(0.71.0 起,在场 = 本窗口已提交行按序、`[]` = 零行、整键缺席 = 本包说不出):`committedPrefixDiverged` ⇒ **按 `committedRows[]` 逐行写回正文**(包已算好:首行 = content、其余行空),端不再自己数窗口里过境的行,也不再对多行段整发放弃;`committedUuid` = 末条兼容位;' +
177
183
  '⑦序:该段尾部的活体增量(`stream_delta`)一律先于本事件到达,本事件之后不再有同段增量(下一条增量属于下一段)。',
178
184
  },
179
185
  };
@@ -189,3 +195,37 @@ export function deriveTranscriptId(frame, ctx, suffix) {
189
195
  }
190
196
  return ctx.uuid();
191
197
  }
198
+ export const SEMA_TERMINAL_OWNER_KEY = '_sema_terminal_owner';
199
+ export function terminalOwnerOf(row) {
200
+ try {
201
+ if (typeof row !== 'object' || row === null)
202
+ return undefined;
203
+ const d = Object.getOwnPropertyDescriptor(row, SEMA_TERMINAL_OWNER_KEY);
204
+ if (d === undefined || !('value' in d))
205
+ return undefined;
206
+ const v = d.value;
207
+ if (typeof v !== 'object' || v === null)
208
+ return undefined;
209
+ const own = (k) => {
210
+ const pd = Object.getOwnPropertyDescriptor(v, k);
211
+ return pd !== undefined && 'value' in pd && typeof pd.value === 'string' && pd.value.length > 0 ? pd.value : undefined;
212
+ };
213
+ const kind = own('kind');
214
+ if (kind === 'request-not-sent') {
215
+ const requestId = own('requestId');
216
+ const heldBy = own('heldBy');
217
+ return { kind, ...(requestId !== undefined ? { requestId } : {}), ...(heldBy !== undefined ? { heldBy } : {}) };
218
+ }
219
+ if (kind === 'followed-run') {
220
+ const taskId = own('taskId');
221
+ if (taskId === undefined)
222
+ return undefined;
223
+ const runId = own('runId');
224
+ return { kind, taskId, ...(runId !== undefined ? { runId } : {}) };
225
+ }
226
+ return undefined;
227
+ }
228
+ catch {
229
+ return undefined;
230
+ }
231
+ }
@@ -12,6 +12,7 @@ import { type ProbeVerdictWord } from "./modelCapabilityProbe.js";
12
12
  import type { SubagentContentEvent } from "./subagentContentStore.js";
13
13
  import type { DeviceEnrollTokenOutcome, DeviceListOutcome, DeviceRebindOutcome, DeviceRevokeOutcome, DeviceSessionBindingOutcome, DeviceTransport, DeviceUnarmed, DeviceUnreadable } from "./deviceRebind.js";
14
14
  import type { McpPanelView } from "./mcpPanel.js";
15
+ import type { McpToolToggleKey } from "./mcpToolToggles.js";
15
16
  export interface SeatValidationFailure {
16
17
  reason: string;
17
18
  field?: string;
@@ -144,7 +145,7 @@ export type SeatStreamReading = {
144
145
  };
145
146
  export declare function seatStreamDeltaMessage(event: SeatStreamDeltaSource, ids: SeatStreamDeltaIds): SeatStreamEventMessage | undefined;
146
147
  export declare function readSeatStreamDelta(message: object): SeatStreamReading;
147
- export declare const SEAT_CAPABILITY_NAMES: readonly ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard"];
148
+ export declare const SEAT_CAPABILITY_NAMES: readonly ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles"];
148
149
  export type SeatCapabilityName = (typeof SEAT_CAPABILITY_NAMES)[number];
149
150
  export interface SeatCapabilitiesState {
150
151
  pickFolder?: boolean;
@@ -154,6 +155,7 @@ export interface SeatCapabilitiesState {
154
155
  devices?: boolean;
155
156
  engineTarget?: boolean;
156
157
  onboard?: boolean;
158
+ mcpToolToggles?: boolean;
157
159
  }
158
160
  export type SeatCapabilityReading = {
159
161
  readonly kind: "reported";
@@ -207,16 +209,16 @@ export declare const SEAT_TURN_SETTINGS_ORIGINS: Readonly<{
207
209
  carriedBy: "renderer";
208
210
  }>;
209
211
  webSearch: Readonly<{
210
- hostSupplied: "联网检索的每请求配置来自宿主的设置源(可能带检索服务的凭据与私网地址);渲染端没有设置文件,也不该持有凭据";
212
+ hostSupplied: "settings.webSearch";
211
213
  }>;
212
214
  hooks: Readonly<{
213
- hostSupplied: "hooks 表来自宿主的设置文件(宿主经设置端口与 hooksForWire 投影);渲染端没有设置文件、也不执行本机 hook";
215
+ hostSupplied: "settings.hooks";
214
216
  }>;
215
217
  resolved: Readonly<{
216
- hostSupplied: "设置解析器的生效快照(hooks / env / model / 已解析权限)由宿主跑解析器得出;渲染端没有设置源可解析";
218
+ hostSupplied: "settings.resolved";
217
219
  }>;
218
220
  outputStyle: Readonly<{
219
- hostSupplied: "输出风格正文由宿主的兜底层随请求带(风格文件在宿主);渲染端只选名字,不持正文";
221
+ hostSupplied: "settings.outputStyle";
220
222
  }>;
221
223
  }>;
222
224
  export interface SeatRewindIntent {
@@ -542,6 +544,10 @@ export interface OnboardProvidersResult {
542
544
  }
543
545
  export declare const checkOnboardEntryRequest: (v: unknown) => SeatValidation;
544
546
  export declare const checkOnboardApplyRequest: (v: unknown) => SeatValidation;
547
+ export declare const checkMcpToolToggleKey: (v: unknown) => SeatValidation;
548
+ export interface McpToolTogglesResult {
549
+ off: McpToolToggleKey[];
550
+ }
545
551
  export interface LocalSessionsApi {
546
552
  start(opts?: StartSessionOptions): Promise<LocalSessionRecord>;
547
553
  sendMessage(req: SendMessageRequest): Promise<SendMessageAck>;
@@ -577,6 +583,8 @@ export interface LocalSessionsApi {
577
583
  probeOnboardEntry(req: OnboardEntryRequest): Promise<OnboardProbeResult>;
578
584
  applyOnboardEntry(req: OnboardApplyRequest): Promise<OnboardApplyResult>;
579
585
  readSessionMcpPanel(sessionId: string): Promise<McpPanelView | DeviceUnreadable | DeviceTransport | DeviceUnarmed>;
586
+ listMcpToolToggles(): Promise<McpToolTogglesResult>;
587
+ setMcpToolToggle(key: McpToolToggleKey, enabled: boolean): Promise<OkAck>;
580
588
  onEvent(cb: (ev: LocalSessionEvent) => void): () => void;
581
589
  onToolPermissionRequest(cb: (req: ToolPermissionRequest) => void): () => void;
582
590
  sessionsStateStore: EipcStoreClient<SessionsState>;
@@ -620,7 +628,7 @@ export declare const checkSessionRowPatchRequest: (v: unknown) => SeatValidation
620
628
  export declare function isSessionRowPatchRequest(v: unknown): v is SessionRowPatchRequest;
621
629
  export declare function isSendMessageAck(v: unknown): v is SendMessageAck;
622
630
  export declare const LOCAL_SESSIONS_SPEC: EipcServiceSpec;
623
- export declare const SEAT_METHOD_NAMES: readonly ["start", "sendMessage", "interrupt", "stop", "respondToToolPermission", "cancelQueuedMessage", "reorderQueuedMessage", "promoteQueuedMessage", "setFocusedSession", "setModel", "getTranscript", "searchSessions", "uploadAttachment", "listModels", "applyModelConfig", "pickFolder", "listRecentFolders", "noteRecentFolder", "patchSession", "listDevices", "readSessionBinding", "rebindSession", "issueEnrollToken", "revokeDevice", "setEngineMode", "startCloudLogin", "cancelCloudLogin", "connectCloudEngine", "configureCloudEngine", "clearCloudEngine", "listOnboardProviders", "probeOnboardEntry", "applyOnboardEntry", "readSessionMcpPanel", "onEvent", "onToolPermissionRequest"];
631
+ export declare const SEAT_METHOD_NAMES: readonly ["start", "sendMessage", "interrupt", "stop", "respondToToolPermission", "cancelQueuedMessage", "reorderQueuedMessage", "promoteQueuedMessage", "setFocusedSession", "setModel", "getTranscript", "searchSessions", "uploadAttachment", "listModels", "applyModelConfig", "pickFolder", "listRecentFolders", "noteRecentFolder", "patchSession", "listDevices", "readSessionBinding", "rebindSession", "issueEnrollToken", "revokeDevice", "setEngineMode", "startCloudLogin", "cancelCloudLogin", "connectCloudEngine", "configureCloudEngine", "clearCloudEngine", "listOnboardProviders", "probeOnboardEntry", "applyOnboardEntry", "readSessionMcpPanel", "listMcpToolToggles", "setMcpToolToggle", "onEvent", "onToolPermissionRequest"];
624
632
  export declare const SEAT_STORE_PROPS: readonly ["sessionsStateStore", "focusedSessionStateStore", "settingsStateStore", "seatCapabilitiesStateStore", "engineTargetStateStore"];
625
633
  export declare const SEAT_EVENT_METHOD_NAMES: readonly ["onEvent", "onToolPermissionRequest"];
626
634
  export declare const LOCAL_SESSION_EVENT_KEYS: readonly ["type", "sessionId", "message", "error", "errorCategory", "code", "session", "userMessageUuid", "requestId", "outcome", "parked", "chrome", "_sema_turnFailure", "subagentContent"];
@@ -808,7 +816,7 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
808
816
  };
809
817
  readonly SeatCapabilitiesState: {
810
818
  readonly check: (v: unknown) => SeatValidation;
811
- readonly validated: readonly ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard"];
819
+ readonly validated: readonly ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles"];
812
820
  readonly unchecked: readonly [];
813
821
  };
814
822
  readonly RecentFoldersResult: {
@@ -848,7 +856,7 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
848
856
  };
849
857
  };
850
858
  export declare const SEAT_VALIDATOR_COVERAGE_EXEMPT: readonly [...{
851
- label: "DeviceListOutcome" | "DeviceSessionBindingOutcome" | "DeviceRebindOutcome" | "DeviceEnrollTokenOutcome" | "DeviceRevokeOutcome" | "SeatDeviceRebindRequest" | "SeatDeviceRevokeRequest" | "EngineTargetState" | "EngineTargetResult" | "CloudLoginStart" | "CloudLoginCancelAck" | "CloudConnectResult" | "CloudLoginRequest" | "CloudEngineConnectRequest" | "CloudEngineConfigureRequest" | "OnboardProvidersResult" | "OnboardProbeResult" | "OnboardApplyResult" | "OnboardEntryRequest" | "OnboardApplyRequest";
859
+ label: "DeviceListOutcome" | "DeviceSessionBindingOutcome" | "DeviceRebindOutcome" | "DeviceEnrollTokenOutcome" | "DeviceRevokeOutcome" | "SeatDeviceRebindRequest" | "SeatDeviceRevokeRequest" | "EngineTargetState" | "EngineTargetResult" | "CloudLoginStart" | "CloudLoginCancelAck" | "CloudConnectResult" | "CloudLoginRequest" | "CloudEngineConnectRequest" | "CloudEngineConfigureRequest" | "OnboardProvidersResult" | "OnboardProbeResult" | "OnboardApplyResult" | "OnboardEntryRequest" | "OnboardApplyRequest" | "McpToolTogglesResult" | "McpToolToggleKey";
852
860
  check: (v: unknown) => SeatValidation;
853
861
  why: string;
854
862
  }[], {
@@ -327,7 +327,7 @@ export function readSeatStreamDelta(message) {
327
327
  return Object.freeze({ kind: "malformed" });
328
328
  }
329
329
  }
330
- export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard"]);
330
+ export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles"]);
331
331
  const notReported = () => Object.freeze({ kind: "not_reported" });
332
332
  const malformedReading = () => Object.freeze({ kind: "malformed" });
333
333
  const reported = (available) => Object.freeze({ kind: "reported", available });
@@ -402,6 +402,7 @@ const SEAT_CAPABILITY_PHRASES = Object.freeze({
402
402
  devices: Object.freeze({ action: "Managing devices", ability: "manage devices", support: "device support" }),
403
403
  engineTarget: Object.freeze({ action: "Switching engines", ability: "switch engines", support: "engine-switching support" }),
404
404
  onboard: Object.freeze({ action: "Model setup", ability: "add models", support: "model-setup support" }),
405
+ mcpToolToggles: Object.freeze({ action: "Per-tool switching", ability: "toggle tools", support: "per-tool switches" }),
405
406
  });
406
407
  export function seatCapabilityUnavailableDetail(name, reading) {
407
408
  const phrase = Object.hasOwn(SEAT_CAPABILITY_PHRASES, name)
@@ -520,10 +521,10 @@ export const SEAT_REASONING_EFFORTS = [...REASONING_EFFORT_WORDS];
520
521
  export const SEAT_TURN_SETTINGS_KEYS = ["ultracode"];
521
522
  export const SEAT_TURN_SETTINGS_ORIGINS = Object.freeze({
522
523
  ultracode: Object.freeze({ carriedBy: "renderer" }),
523
- webSearch: Object.freeze({ hostSupplied: "联网检索的每请求配置来自宿主的设置源(可能带检索服务的凭据与私网地址);渲染端没有设置文件,也不该持有凭据" }),
524
- hooks: Object.freeze({ hostSupplied: "hooks 表来自宿主的设置文件(宿主经设置端口与 hooksForWire 投影);渲染端没有设置文件、也不执行本机 hook" }),
525
- resolved: Object.freeze({ hostSupplied: "设置解析器的生效快照(hooks / env / model / 已解析权限)由宿主跑解析器得出;渲染端没有设置源可解析" }),
526
- outputStyle: Object.freeze({ hostSupplied: "输出风格正文由宿主的兜底层随请求带(风格文件在宿主);渲染端只选名字,不持正文" }),
524
+ webSearch: Object.freeze({ hostSupplied: "settings.webSearch" }),
525
+ hooks: Object.freeze({ hostSupplied: "settings.hooks" }),
526
+ resolved: Object.freeze({ hostSupplied: "settings.resolved" }),
527
+ outputStyle: Object.freeze({ hostSupplied: "settings.outputStyle" }),
527
528
  });
528
529
  export const SEAT_REWIND_INTENT_KEYS = ["mode", "targetMessageUuid"];
529
530
  export const ATTACHMENT_UPLOAD_REQUEST_KEYS = ["name", "mimeType", "bytes"];
@@ -902,6 +903,12 @@ const checkSessionMcpPanelResult = seatCheck((v) => {
902
903
  return checkSessionMcpPanelFailure(v);
903
904
  return Object.hasOwn(v, "scenarioRefusal") ? checkSessionMcpPanelRefusalView(v) : checkSessionMcpPanelServersView(v);
904
905
  });
906
+ const MCP_TOOL_TOGGLE_KEY = shapeRule("toggle key", {
907
+ server: reqF(R_NONEMPTY),
908
+ tool: reqF(R_NONEMPTY),
909
+ });
910
+ export const checkMcpToolToggleKey = seatShapeCheck(MCP_TOOL_TOGGLE_KEY);
911
+ const checkMcpToolTogglesResult = seatShapeCheck(shapeRule("toggles result", { off: reqF(arrayRule(MCP_TOOL_TOGGLE_KEY)) }));
905
912
  const checkLocalSessionRecord = seatCheck((s) => {
906
913
  if (!isPlainRecord(s))
907
914
  return bad("session record is not a plain object");
@@ -1571,6 +1578,8 @@ export const LOCAL_SESSIONS_SPEC = {
1571
1578
  probeOnboardEntry: { kind: "invoke", check: checkOnboardProbeResult },
1572
1579
  applyOnboardEntry: { kind: "invoke", check: checkOnboardApplyResult },
1573
1580
  readSessionMcpPanel: { kind: "invoke", check: checkSessionMcpPanelResult },
1581
+ listMcpToolToggles: { kind: "invoke", check: checkMcpToolTogglesResult },
1582
+ setMcpToolToggle: { kind: "invoke", check: checkOkAck },
1574
1583
  onEvent: { kind: "event", check: checkLocalSessionEvent },
1575
1584
  onToolPermissionRequest: { kind: "event", check: checkToolPermissionRequest },
1576
1585
  },
@@ -1616,6 +1625,8 @@ export const SEAT_METHOD_NAMES = [
1616
1625
  "probeOnboardEntry",
1617
1626
  "applyOnboardEntry",
1618
1627
  "readSessionMcpPanel",
1628
+ "listMcpToolToggles",
1629
+ "setMcpToolToggle",
1619
1630
  "onEvent",
1620
1631
  "onToolPermissionRequest",
1621
1632
  ];
@@ -1895,7 +1906,7 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
1895
1906
  },
1896
1907
  SeatCapabilitiesState: {
1897
1908
  check: checkSeatCapabilitiesState,
1898
- validated: ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard"],
1909
+ validated: ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles"],
1899
1910
  unchecked: [],
1900
1911
  },
1901
1912
  RecentFoldersResult: {
@@ -1956,6 +1967,8 @@ export const SEAT_VALIDATOR_COVERAGE_EXEMPT = [
1956
1967
  ["OnboardApplyResult", checkOnboardApplyResult],
1957
1968
  ["OnboardEntryRequest", checkOnboardEntryRequest],
1958
1969
  ["OnboardApplyRequest", checkOnboardApplyRequest],
1970
+ ["McpToolTogglesResult", checkMcpToolTogglesResult],
1971
+ ["McpToolToggleKey", checkMcpToolToggleKey],
1959
1972
  ].map(([label, check]) => ({
1960
1973
  label,
1961
1974
  check,
@@ -2006,5 +2019,7 @@ const _seatContractPins = [
2006
2019
  true, true,
2007
2020
  true, true, true, true,
2008
2021
  true, true, true,
2022
+ true,
2023
+ true, true, true,
2009
2024
  ];
2010
2025
  void _seatContractPins;
@@ -0,0 +1,8 @@
1
+ export interface CredentialKeyFinding {
2
+ readonly path: string;
3
+ readonly numericByNameOnly?: true;
4
+ }
5
+ export declare function credentialNameWords(name: string): string[];
6
+ export declare function isCredentialEnvName(name: string): boolean;
7
+ export declare function isCredentialConfigKey(name: string): boolean;
8
+ export declare function settingsCredentialKeyPaths(doc: object | null | undefined): CredentialKeyFinding[];