@sema-agent/client-core 0.98.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.
- package/CHANGELOG.md +376 -0
- package/README.md +61 -35
- package/dist/adapt/arms.js +120 -55
- package/dist/adapt/panelTasks.d.ts +3 -2
- package/dist/adapt/panelTasks.js +34 -11
- package/dist/adapt/textStream.d.ts +1 -1
- package/dist/adapt/textStream.js +51 -28
- package/dist/adapter/activeRunSelfHeal.d.ts +11 -3
- package/dist/adapter/activeRunSelfHeal.js +210 -294
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +176 -12
- package/dist/adapter/downstream/terminalToSdkResult.js +10 -0
- package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
- package/dist/adapter/downstream/wiringManifestView.js +1 -0
- package/dist/adapter/runStream.js +82 -40
- package/dist/adapter/types.d.ts +2 -0
- package/dist/adapter/types.js +2 -1
- package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
- package/dist/agentsWireCaps.d.ts +7 -3
- package/dist/agentsWireCaps.js +133 -39
- package/dist/cloudConfigWireCaps.d.ts +10 -1
- package/dist/cloudConfigWireCaps.js +181 -65
- package/dist/compactionStatus.d.ts +34 -0
- package/dist/compactionStatus.js +196 -0
- package/dist/controlRouter.d.ts +4 -2
- package/dist/controlRouter.js +39 -51
- package/dist/coreValuePorts.d.ts +26 -1
- package/dist/coreValuePorts.js +10 -0
- package/dist/corruptSessionCopy.d.ts +2 -1
- package/dist/corruptSessionCopy.js +3 -3
- package/dist/decideFailureNote.js +3 -3
- package/dist/declared/supportFloorDeclared.js +1 -1
- package/dist/detachWire.js +3 -2
- package/dist/devicesFace.d.ts +34 -0
- package/dist/devicesFace.js +90 -0
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +153 -5
- package/dist/engineAgentPanelStore.d.ts +14 -4
- package/dist/engineAgentPanelStore.js +14 -0
- package/dist/engineCapReader.d.ts +2 -1
- package/dist/engineCapReader.js +7 -5
- package/dist/engineCapsCache.d.ts +8 -0
- package/dist/engineCapsCache.js +59 -6
- package/dist/engineCapsChange.d.ts +2 -0
- package/dist/engineCapsChange.js +9 -0
- package/dist/engineErrorCodes.d.ts +11 -2
- package/dist/engineErrorCodes.js +11 -12
- package/dist/engineRowRef.js +4 -0
- package/dist/engineSessionMessages.d.ts +1 -0
- package/dist/engineSessionMessages.js +7 -1
- package/dist/engineTargetSeat.d.ts +27 -0
- package/dist/engineTargetSeat.js +199 -0
- package/dist/engineToolDirectory.d.ts +3 -0
- package/dist/engineToolDirectory.js +4 -2
- package/dist/engineWireFor.js +3 -8
- package/dist/env/uiLanguage.d.ts +2 -1
- package/dist/env/uiLanguage.js +3 -2
- package/dist/eventLeg.d.ts +7 -5
- package/dist/eventLeg.js +68 -49
- package/dist/fileHistoryCaptureCapability.d.ts +2 -4
- package/dist/fileHistoryCaptureCapability.js +12 -22
- package/dist/fileHistoryLegNotice.d.ts +2 -1
- package/dist/fileHistoryLegNotice.js +3 -3
- package/dist/frameBinding.d.ts +3 -0
- package/dist/frameBinding.js +12 -0
- package/dist/gateOutcome.js +16 -2
- package/dist/gateVocabulary.d.ts +8 -7
- package/dist/gateVocabulary.js +71 -73
- package/dist/generated/engineFactTables.d.ts +18 -1
- package/dist/generated/engineFactTables.js +56 -0
- package/dist/generated/engineNoticeTables.js +12 -3
- package/dist/generated/settingsSchemaFns.d.ts +18 -0
- package/dist/generated/settingsSchemaFns.js +70 -0
- package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
- package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
- package/dist/generated/settingsSchemaTables.d.ts +2 -0
- package/dist/generated/settingsSchemaTables.js +9 -0
- package/dist/generated/settingsSchemaTypes.d.ts +133 -0
- package/dist/generated/settingsSchemaTypes.js +1 -0
- package/dist/hitl/allowRuleShadow.d.ts +2 -1
- package/dist/hitl/allowRuleShadow.js +18 -15
- package/dist/hitl/approvalCardReasons.d.ts +3 -2
- package/dist/hitl/approvalCardReasons.js +29 -30
- package/dist/hitl/approvalHolds.d.ts +17 -0
- package/dist/hitl/approvalHolds.js +114 -29
- package/dist/hitl/askClassPair.d.ts +2 -2
- package/dist/hitl/askClassPair.js +16 -0
- package/dist/hitl/askGateWire.js +2 -1
- package/dist/hitl/askSettlementLine.d.ts +14 -4
- package/dist/hitl/askSettlementLine.js +67 -47
- package/dist/hitl/attributionLadder.d.ts +23 -0
- package/dist/hitl/attributionLadder.js +67 -0
- package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
- package/dist/hitl/automaticAnswerVerdict.js +8 -8
- package/dist/hitl/crashConvergedNotice.d.ts +5 -4
- package/dist/hitl/crashConvergedNotice.js +28 -41
- package/dist/hitl/decisionLedger.d.ts +55 -0
- package/dist/hitl/decisionLedger.js +156 -0
- package/dist/hitl/decisionRefusal.d.ts +1 -0
- package/dist/hitl/decisionRefusal.js +1 -1
- package/dist/hitl/decisionSend.d.ts +113 -0
- package/dist/hitl/decisionSend.js +579 -0
- package/dist/hitl/frameRouter.js +7 -8
- package/dist/hitl/hitlBridge.d.ts +1 -0
- package/dist/hitl/hitlBridge.js +21 -9
- package/dist/hitl/persistedRulesWire.d.ts +6 -5
- package/dist/hitl/persistedRulesWire.js +55 -73
- package/dist/hitl/planReviewWire.d.ts +5 -0
- package/dist/hitl/planReviewWire.js +53 -76
- package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
- package/dist/hitl/sessionPolicyDeliverable.js +49 -9
- package/dist/hitl/sessionPolicyWire.d.ts +2 -1
- package/dist/hitl/sessionPolicyWire.js +23 -24
- package/dist/hitl/suspendedReopen.d.ts +2 -1
- package/dist/hitl/suspendedReopen.js +7 -10
- package/dist/hitl/toolApprovalWire.d.ts +17 -5
- package/dist/hitl/toolApprovalWire.js +120 -147
- package/dist/hooksWireCaps.js +145 -56
- package/dist/host.d.ts +21 -0
- package/dist/hostTurnSettings.d.ts +110 -0
- package/dist/hostTurnSettings.js +692 -0
- package/dist/humanTurn.d.ts +15 -1
- package/dist/humanTurn.js +100 -12
- package/dist/humanTurnRead.d.ts +2 -0
- package/dist/humanTurnRead.js +22 -1
- package/dist/i18n/messages.en.d.ts +713 -0
- package/dist/i18n/messages.en.js +713 -0
- package/dist/i18n/messages.zh.js +854 -1
- package/dist/index.d.ts +45 -13
- package/dist/index.js +27 -9
- package/dist/inheritEnvCapability.d.ts +4 -2
- package/dist/inheritEnvCapability.js +12 -5
- package/dist/inheritEnvWire.d.ts +3 -2
- package/dist/inheritEnvWire.js +14 -16
- package/dist/injectionLaneNotice.d.ts +5 -0
- package/dist/injectionLaneNotice.js +46 -0
- package/dist/interactiveHalt.js +17 -6
- package/dist/liveModelCatalog.d.ts +2 -1
- package/dist/liveModelCatalog.js +14 -8
- package/dist/mcpPanel.d.ts +10 -1
- package/dist/mcpPanel.js +42 -13
- package/dist/mcpProbeCapability.d.ts +2 -1
- package/dist/mcpProbeCapability.js +7 -11
- package/dist/mcpProbeWire.d.ts +3 -1
- package/dist/mcpProbeWire.js +5 -0
- package/dist/mcpReconnect.js +2 -2
- package/dist/mcpToolToggles.d.ts +6 -0
- package/dist/mcpToolToggles.js +46 -0
- package/dist/mcpWireCaps.d.ts +43 -3
- package/dist/mcpWireCaps.js +194 -59
- package/dist/mcpWireTransport.d.ts +4 -0
- package/dist/mcpWireTransport.js +18 -0
- package/dist/memoryEntriesWire.js +5 -10
- package/dist/model/onboardJudgement.d.ts +93 -0
- package/dist/model/onboardJudgement.js +415 -0
- package/dist/model/tierVocabulary.d.ts +2 -0
- package/dist/model/tierVocabulary.js +17 -5
- package/dist/modelCapabilityProbe.d.ts +65 -0
- package/dist/modelCapabilityProbe.js +601 -0
- package/dist/modelIdentityResolvability.d.ts +5 -0
- package/dist/modelIdentityResolvability.js +49 -22
- package/dist/ownKey.d.ts +33 -0
- package/dist/ownKey.js +109 -0
- package/dist/panelReduce.d.ts +11 -1
- package/dist/panelReduce.js +95 -16
- package/dist/panelStateHolder.d.ts +1 -0
- package/dist/panelStateHolder.js +10 -1
- package/dist/permissionRuleIssue.d.ts +2 -1
- package/dist/permissionRuleIssue.js +23 -20
- package/dist/permissionRulesWriteCapability.d.ts +2 -1
- package/dist/permissionRulesWriteCapability.js +8 -6
- package/dist/pluginHooksWire.d.ts +46 -3
- package/dist/pluginHooksWire.js +220 -12
- package/dist/prepareRefusal.d.ts +8 -0
- package/dist/prepareRefusal.js +72 -0
- package/dist/printModelStatus.d.ts +63 -0
- package/dist/printModelStatus.js +155 -0
- package/dist/request/taskRequest.d.ts +16 -10
- package/dist/request/taskRequest.js +195 -58
- package/dist/resumeRefusalCopy.d.ts +14 -9
- package/dist/resumeRefusalCopy.js +89 -144
- package/dist/retryStatus.d.ts +55 -0
- package/dist/retryStatus.js +155 -19
- package/dist/ruleRefusalSentence.d.ts +4 -0
- package/dist/ruleRefusalSentence.js +58 -0
- package/dist/sandboxWire.d.ts +2 -1
- package/dist/sandboxWire.js +55 -21
- package/dist/scenarioRefusal.d.ts +10 -0
- package/dist/scenarioRefusal.js +111 -0
- package/dist/seam.d.ts +48 -9
- package/dist/seam.js +54 -5
- package/dist/seatContract.d.ts +272 -14
- package/dist/seatContract.js +711 -23
- package/dist/selfOrchestrationDenial.js +7 -19
- package/dist/sessionIdSegment.d.ts +6 -0
- package/dist/sessionIdSegment.js +24 -0
- package/dist/sessionMemoryStatus.js +6 -11
- package/dist/sessionPolicyCapability.d.ts +2 -1
- package/dist/sessionPolicyCapability.js +8 -6
- package/dist/settingsCredentialKeyPaths.d.ts +8 -0
- package/dist/settingsCredentialKeyPaths.js +219 -0
- package/dist/settingsHooksSalvage.d.ts +44 -0
- package/dist/settingsHooksSalvage.js +211 -0
- package/dist/skillToolListsCapability.d.ts +2 -1
- package/dist/skillToolListsCapability.js +8 -6
- package/dist/skillsWireCaps.d.ts +0 -3
- package/dist/skillsWireCaps.js +1 -2
- package/dist/sseIdleTriage.js +3 -2
- package/dist/subagent/engineSubagentResume.js +15 -9
- package/dist/subagentContentStore.d.ts +4 -0
- package/dist/subagentContentStore.js +157 -27
- package/dist/toolHistoryMismatch.js +3 -2
- package/dist/toolRoster.d.ts +3 -2
- package/dist/toolRoster.js +21 -20
- package/dist/toolsFlagNames.d.ts +8 -0
- package/dist/toolsFlagNames.js +110 -0
- package/dist/turnFailurePresentation.d.ts +12 -1
- package/dist/turnFailurePresentation.js +220 -15
- package/dist/usageAnalytics.js +6 -11
- package/dist/userAttachmentEnvelope.d.ts +1 -0
- package/dist/userAttachmentEnvelope.js +37 -7
- package/dist/userAttachmentSeat.d.ts +21 -0
- package/dist/userAttachmentSeat.js +75 -0
- package/dist/userInvokedSkillsCapability.d.ts +11 -1
- package/dist/userInvokedSkillsCapability.js +31 -7
- package/dist/wireErrorTriage.d.ts +7 -0
- package/dist/wireErrorTriage.js +23 -1
- package/dist/wireFailureShape.js +2 -1
- package/dist/wireRefusalCopy.d.ts +62 -16
- package/dist/wireRefusalCopy.js +307 -148
- package/dist/workflowsJournalCapability.d.ts +2 -1
- package/dist/workflowsJournalCapability.js +8 -6
- package/docs/INTEGRATION-CLIENTS.md +951 -42
- package/package.json +5 -5
package/dist/seatContract.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { PERMISSION_MODE_WORDS, REASONING_EFFORT_WORDS } from "./taskRequestWords.js";
|
|
2
2
|
import { liveDefaultModelCopy, liveModelRowCopy } from "./model/liveCatalogShape.js";
|
|
3
3
|
import { REWIND_MODES } from "./rewindWireCaps.js";
|
|
4
|
+
import { SETTINGS_MODEL_API_WORDS } from "./generated/settingsSchemaTables.js";
|
|
5
|
+
import { PROBE_VERDICTS } from "./modelCapabilityProbe.js";
|
|
4
6
|
import { guardedRead, ownDataField, ownDataRefusalKeyOf, ownSendableField, readOwnDataValue } from "./ownKey.js";
|
|
7
|
+
import { MCP_LIVENESS_STATES } from "./mcpLiveness.js";
|
|
5
8
|
const bad = (reason, field) => field === undefined ? { reason } : { reason, field };
|
|
6
9
|
const nested = (prefix, verdict) => {
|
|
7
10
|
const path = verdict.field === undefined
|
|
@@ -89,6 +92,124 @@ const seatCheckAt = (fn) => (v, field) => {
|
|
|
89
92
|
return key !== undefined ? bad(NOT_PLAIN_DATA, `${field}.${key}`) : bad("payload could not be read", field);
|
|
90
93
|
}
|
|
91
94
|
};
|
|
95
|
+
const pathAt = (path, key) => (path === "" ? key : `${path}.${key}`);
|
|
96
|
+
const reqF = (rule) => ({ opt: false, rule });
|
|
97
|
+
const optF = (rule) => ({ opt: true, rule });
|
|
98
|
+
const ruleOf = (label, pred) => ({
|
|
99
|
+
label,
|
|
100
|
+
test: (v, path) => (pred(v) ? true : bad(`bad value (${label})`, path === "" ? undefined : path)),
|
|
101
|
+
});
|
|
102
|
+
function shapeVerdict(spec, v, path, disc) {
|
|
103
|
+
if (!isPlainRecord(v))
|
|
104
|
+
return bad("not object", path === "" ? undefined : path);
|
|
105
|
+
for (const k of sendableKeysOf(v)) {
|
|
106
|
+
if (k !== disc && !Object.hasOwn(spec, k))
|
|
107
|
+
return bad("unknown key", pathAt(path, k));
|
|
108
|
+
}
|
|
109
|
+
for (const k of Object.keys(spec)) {
|
|
110
|
+
const s = spec[k];
|
|
111
|
+
const val = own(v, k);
|
|
112
|
+
if (isAbsent(val)) {
|
|
113
|
+
if (!s.opt)
|
|
114
|
+
return bad("missing key", pathAt(path, k));
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const verdict = s.rule.test(val, pathAt(path, k));
|
|
118
|
+
if (verdict !== true)
|
|
119
|
+
return verdict;
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
const shapeRule = (label, spec) => ({ label, test: (v, path) => shapeVerdict(spec, v, path) });
|
|
124
|
+
const armsRule = (label, disc, arms) => ({
|
|
125
|
+
label,
|
|
126
|
+
test: (v, path) => {
|
|
127
|
+
if (!isPlainRecord(v))
|
|
128
|
+
return bad("not object", path === "" ? undefined : path);
|
|
129
|
+
const d = own(v, disc);
|
|
130
|
+
if (typeof d !== "string" || !Object.hasOwn(arms, d))
|
|
131
|
+
return bad("unknown arm", pathAt(path, disc));
|
|
132
|
+
return shapeVerdict(arms[d], v, path, disc);
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
const isArraySlotKey = (k, n) => k === "length" || (/^(0|[1-9][0-9]*)$/.test(k) && Number(k) < n);
|
|
136
|
+
const arrayRule = (item, nonEmpty = false) => ({
|
|
137
|
+
label: `${item.label}[]`,
|
|
138
|
+
test: (v, path) => {
|
|
139
|
+
if (!Array.isArray(v))
|
|
140
|
+
return bad(`bad value (${item.label}[])`, path === "" ? undefined : path);
|
|
141
|
+
const n = ownDataField(v, "length");
|
|
142
|
+
for (const k of Reflect.ownKeys(v)) {
|
|
143
|
+
if (typeof k === "string" && !isArraySlotKey(k, typeof n === "number" ? n : 0))
|
|
144
|
+
return bad("unknown key", pathAt(path, k));
|
|
145
|
+
}
|
|
146
|
+
const rows = ownItems(v);
|
|
147
|
+
if (nonEmpty && rows.length === 0)
|
|
148
|
+
return bad(`bad value (${item.label}[])`, path === "" ? undefined : path);
|
|
149
|
+
for (let i = 0; i < rows.length; i += 1) {
|
|
150
|
+
const verdict = item.test(rows[i], `${path}[${i}]`);
|
|
151
|
+
if (verdict !== true)
|
|
152
|
+
return verdict;
|
|
153
|
+
}
|
|
154
|
+
return true;
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
const oneOfRule = (label, words) => ruleOf(label, (v) => typeof v === "string" && words.includes(v));
|
|
158
|
+
const R_STR = ruleOf("string", (v) => typeof v === "string");
|
|
159
|
+
const R_NONEMPTY = ruleOf("non-empty string", (v) => typeof v === "string" && v.length > 0);
|
|
160
|
+
const R_BOOL = ruleOf("boolean", (v) => typeof v === "boolean");
|
|
161
|
+
const R_TRUE = ruleOf("true", (v) => v === true);
|
|
162
|
+
const R_NUM = ruleOf("finite number", (v) => typeof v === "number" && Number.isFinite(v));
|
|
163
|
+
const R_INT0 = ruleOf("non-negative integer", (v) => typeof v === "number" && Number.isSafeInteger(v) && v >= 0);
|
|
164
|
+
const R_INT1 = ruleOf("positive integer", (v) => typeof v === "number" && Number.isSafeInteger(v) && v > 0);
|
|
165
|
+
const keyWords = (k) => k
|
|
166
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
167
|
+
.toLowerCase()
|
|
168
|
+
.split(/[^a-z0-9]+/)
|
|
169
|
+
.filter((w) => w.length > 0);
|
|
170
|
+
const SECRET_KEY_WORDS = new Set(["token", "secret", "password", "passwd", "authorization", "bearer", "sealed"]);
|
|
171
|
+
const SECRET_KEY_PAIRS = new Set(["api key", "device code", "access key", "private key"]);
|
|
172
|
+
const isSecretKeyName = (k) => {
|
|
173
|
+
const words = keyWords(k);
|
|
174
|
+
for (let i = 0; i < words.length; i += 1) {
|
|
175
|
+
if (SECRET_KEY_WORDS.has(words[i]))
|
|
176
|
+
return true;
|
|
177
|
+
if (i + 1 < words.length && SECRET_KEY_PAIRS.has(`${words[i]} ${words[i + 1]}`))
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
return false;
|
|
181
|
+
};
|
|
182
|
+
const firstSecretKeyPath = (root, allow) => {
|
|
183
|
+
const seen = new Set();
|
|
184
|
+
const stack = [[root, ""]];
|
|
185
|
+
while (stack.length > 0) {
|
|
186
|
+
const [v, path] = stack.pop();
|
|
187
|
+
if (typeof v !== "object" || v === null || seen.has(v))
|
|
188
|
+
continue;
|
|
189
|
+
seen.add(v);
|
|
190
|
+
const isArr = Array.isArray(v);
|
|
191
|
+
for (const k of Reflect.ownKeys(v)) {
|
|
192
|
+
if (typeof k !== "string" || (isArr && k === "length"))
|
|
193
|
+
continue;
|
|
194
|
+
const d = Reflect.getOwnPropertyDescriptor(v, k);
|
|
195
|
+
if (d === undefined || !Object.hasOwn(d, "value"))
|
|
196
|
+
continue;
|
|
197
|
+
const at = isArr && /^[0-9]+$/.test(k) ? `${path}[${k}]` : pathAt(path, k);
|
|
198
|
+
if (isSecretKeyName(k) && !allow.has(at))
|
|
199
|
+
return at;
|
|
200
|
+
stack.push([d.value, at]);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return undefined;
|
|
204
|
+
};
|
|
205
|
+
const NO_SECRET_ALLOW = new Set();
|
|
206
|
+
const seatShapeCheck = (rule, allow = NO_SECRET_ALLOW) => seatCheck((v) => {
|
|
207
|
+
const verdict = rule.test(v, "");
|
|
208
|
+
if (verdict !== true)
|
|
209
|
+
return verdict;
|
|
210
|
+
const secret = firstSecretKeyPath(v, allow);
|
|
211
|
+
return secret === undefined ? true : bad("secret key", secret);
|
|
212
|
+
});
|
|
92
213
|
export const TOOL_PERMISSION_REQUEST_ID_DOMAINS = Object.freeze([
|
|
93
214
|
"live:",
|
|
94
215
|
"durable:",
|
|
@@ -127,6 +248,7 @@ const SEAT_EVENT_TYPE_TUPLE = [
|
|
|
127
248
|
"chrome_event",
|
|
128
249
|
"error",
|
|
129
250
|
"tool_permission_resolved",
|
|
251
|
+
"subagent_content",
|
|
130
252
|
];
|
|
131
253
|
export const SEAT_EVENT_TYPES = Object.freeze(SEAT_EVENT_TYPE_TUPLE);
|
|
132
254
|
const CHROME_EVENT_KIND_TUPLE = [
|
|
@@ -205,7 +327,7 @@ export function readSeatStreamDelta(message) {
|
|
|
205
327
|
return Object.freeze({ kind: "malformed" });
|
|
206
328
|
}
|
|
207
329
|
}
|
|
208
|
-
export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession"]);
|
|
330
|
+
export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles"]);
|
|
209
331
|
const notReported = () => Object.freeze({ kind: "not_reported" });
|
|
210
332
|
const malformedReading = () => Object.freeze({ kind: "malformed" });
|
|
211
333
|
const reported = (available) => Object.freeze({ kind: "reported", available });
|
|
@@ -277,6 +399,10 @@ const SEAT_CAPABILITY_PHRASES = Object.freeze({
|
|
|
277
399
|
pickFolder: Object.freeze({ action: "Opening a folder", ability: "show a folder picker", support: "folder picker support" }),
|
|
278
400
|
rewind: Object.freeze({ action: "Rewinding to an earlier message", ability: "rewind this session", support: "rewind support" }),
|
|
279
401
|
recents: Object.freeze({ action: "Remembering recent folders", ability: "remember recent folders", support: "recent folders support" }), patchSession: Object.freeze({ action: "Renaming or pinning a conversation", ability: "rename or pin conversations", support: "rename and pin support" }),
|
|
402
|
+
devices: Object.freeze({ action: "Managing devices", ability: "manage devices", support: "device support" }),
|
|
403
|
+
engineTarget: Object.freeze({ action: "Switching engines", ability: "switch engines", support: "engine-switching support" }),
|
|
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" }),
|
|
280
406
|
});
|
|
281
407
|
export function seatCapabilityUnavailableDetail(name, reading) {
|
|
282
408
|
const phrase = Object.hasOwn(SEAT_CAPABILITY_PHRASES, name)
|
|
@@ -395,16 +521,394 @@ export const SEAT_REASONING_EFFORTS = [...REASONING_EFFORT_WORDS];
|
|
|
395
521
|
export const SEAT_TURN_SETTINGS_KEYS = ["ultracode"];
|
|
396
522
|
export const SEAT_TURN_SETTINGS_ORIGINS = Object.freeze({
|
|
397
523
|
ultracode: Object.freeze({ carriedBy: "renderer" }),
|
|
398
|
-
webSearch: Object.freeze({ hostSupplied: "
|
|
399
|
-
hooks: Object.freeze({ hostSupplied: "hooks
|
|
400
|
-
resolved: Object.freeze({ hostSupplied: "
|
|
401
|
-
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" }),
|
|
402
528
|
});
|
|
403
529
|
export const SEAT_REWIND_INTENT_KEYS = ["mode", "targetMessageUuid"];
|
|
404
530
|
export const ATTACHMENT_UPLOAD_REQUEST_KEYS = ["name", "mimeType", "bytes"];
|
|
405
531
|
export const SESSION_ROW_PATCH_REQUEST_KEYS = Object.freeze(["sessionId", "title", "pinned"]);
|
|
406
532
|
export const SESSION_SEARCH_RESULT_KEYS = ["sessionId", "title", "matches"];
|
|
407
533
|
export const GET_TRANSCRIPT_RESULT_KEYS = ["sessionId", "messages"];
|
|
534
|
+
const DEVICE_REFUSED_SPEC = { status: reqF(R_INT0), errorCode: optF(R_STR), message: optF(R_STR) };
|
|
535
|
+
const DEVICE_LANE_ABSENT_SPEC = { runStoreOnly: optF(R_TRUE) };
|
|
536
|
+
const DEVICE_TRANSPORT_SPEC = { detail: optF(R_STR) };
|
|
537
|
+
const DEVICE_UNREADABLE_SPEC = { why: reqF(R_STR) };
|
|
538
|
+
const DEVICE_UNCONFIRMED_SPEC = {
|
|
539
|
+
why: reqF(oneOfRule("unconfirmed why", ["accepted-unreadable", "transport", "server-error"])),
|
|
540
|
+
detail: optF(R_STR),
|
|
541
|
+
mayStillBeRunning: reqF(R_BOOL),
|
|
542
|
+
};
|
|
543
|
+
const DEVICE_RATE_LIMITED_SPEC = { retryAfterSec: optF(R_NUM) };
|
|
544
|
+
const DEVICE_ROSTER_ROW = shapeRule("device row", {
|
|
545
|
+
deviceId: reqF(R_NONEMPTY),
|
|
546
|
+
name: optF(R_STR),
|
|
547
|
+
status: reqF(oneOfRule("device status", ["online", "offline", "unknown"])),
|
|
548
|
+
lastSeenAt: optF(R_STR),
|
|
549
|
+
});
|
|
550
|
+
const DEVICE_BINDING = shapeRule("device binding", {
|
|
551
|
+
deviceId: reqF(R_NONEMPTY),
|
|
552
|
+
rev: reqF(R_INT0),
|
|
553
|
+
boundAt: optF(R_STR),
|
|
554
|
+
});
|
|
555
|
+
const checkDeviceListOutcome = seatShapeCheck(armsRule("listDevices outcome", "kind", {
|
|
556
|
+
ok: { devices: reqF(arrayRule(DEVICE_ROSTER_ROW)), dropped: reqF(R_INT0) },
|
|
557
|
+
unreadable: DEVICE_UNREADABLE_SPEC,
|
|
558
|
+
"lane-absent": DEVICE_LANE_ABSENT_SPEC,
|
|
559
|
+
refused: DEVICE_REFUSED_SPEC,
|
|
560
|
+
transport: DEVICE_TRANSPORT_SPEC,
|
|
561
|
+
unarmed: {},
|
|
562
|
+
}));
|
|
563
|
+
const checkDeviceSessionBindingOutcome = seatShapeCheck(armsRule("readSessionBinding outcome", "kind", {
|
|
564
|
+
ok: { rootSessionId: reqF(R_NONEMPTY), boundDevice: reqF(DEVICE_BINDING) },
|
|
565
|
+
"not-found": {},
|
|
566
|
+
unreadable: DEVICE_UNREADABLE_SPEC,
|
|
567
|
+
"lane-absent": DEVICE_LANE_ABSENT_SPEC,
|
|
568
|
+
refused: DEVICE_REFUSED_SPEC,
|
|
569
|
+
transport: DEVICE_TRANSPORT_SPEC,
|
|
570
|
+
unarmed: {},
|
|
571
|
+
}));
|
|
572
|
+
const checkDeviceRebindOutcome = seatShapeCheck(armsRule("rebindSession outcome", "kind", {
|
|
573
|
+
ok: { deviceId: reqF(R_NONEMPTY), rev: reqF(R_INT0), workspaceCarryover: optF(oneOfRule("carryover", ["none"])) },
|
|
574
|
+
"active-run": { activeTaskId: optF(R_STR) },
|
|
575
|
+
"rev-conflict": { currentRev: optF(R_INT0) },
|
|
576
|
+
"not-found": {},
|
|
577
|
+
unconfirmed: DEVICE_UNCONFIRMED_SPEC,
|
|
578
|
+
"lane-absent": DEVICE_LANE_ABSENT_SPEC,
|
|
579
|
+
refused: DEVICE_REFUSED_SPEC,
|
|
580
|
+
unarmed: {},
|
|
581
|
+
}));
|
|
582
|
+
const ENROLL_TOKEN_ALLOW = new Set(["token"]);
|
|
583
|
+
const checkDeviceEnrollTokenOutcome = seatShapeCheck(armsRule("issueEnrollToken outcome", "kind", {
|
|
584
|
+
ok: { token: reqF(R_NONEMPTY), expiresAt: optF(R_STR), ttlSec: optF(R_INT1) },
|
|
585
|
+
"rate-limited": DEVICE_RATE_LIMITED_SPEC,
|
|
586
|
+
unreadable: DEVICE_UNREADABLE_SPEC,
|
|
587
|
+
"lane-absent": DEVICE_LANE_ABSENT_SPEC,
|
|
588
|
+
refused: DEVICE_REFUSED_SPEC,
|
|
589
|
+
transport: DEVICE_TRANSPORT_SPEC,
|
|
590
|
+
unarmed: {},
|
|
591
|
+
}), ENROLL_TOKEN_ALLOW);
|
|
592
|
+
const checkDeviceRevokeOutcome = seatShapeCheck(armsRule("revokeDevice outcome", "kind", {
|
|
593
|
+
ok: { deviceId: reqF(R_NONEMPTY), revokedAt: optF(R_STR) },
|
|
594
|
+
"not-found": {},
|
|
595
|
+
unconfirmed: DEVICE_UNCONFIRMED_SPEC,
|
|
596
|
+
"lane-absent": DEVICE_LANE_ABSENT_SPEC,
|
|
597
|
+
refused: DEVICE_REFUSED_SPEC,
|
|
598
|
+
unarmed: {},
|
|
599
|
+
}));
|
|
600
|
+
export const checkSeatDeviceRebindRequest = seatShapeCheck(shapeRule("rebindSession request", {
|
|
601
|
+
sessionId: reqF(R_NONEMPTY),
|
|
602
|
+
toDeviceId: reqF(R_NONEMPTY),
|
|
603
|
+
expectedRev: reqF(R_INT0),
|
|
604
|
+
fromDeviceId: reqF(R_NONEMPTY),
|
|
605
|
+
}));
|
|
606
|
+
export const checkSeatDeviceRevokeRequest = seatShapeCheck(shapeRule("revokeDevice request", { deviceId: reqF(R_NONEMPTY), reason: optF(R_STR) }));
|
|
607
|
+
export const ENGINE_TARGET_REFUSALS = Object.freeze([
|
|
608
|
+
"busy",
|
|
609
|
+
"switching",
|
|
610
|
+
"not_configured",
|
|
611
|
+
"not_signed_in",
|
|
612
|
+
"probe_failed",
|
|
613
|
+
"org_policy",
|
|
614
|
+
"url_refused",
|
|
615
|
+
"login_failed",
|
|
616
|
+
"storage_unavailable",
|
|
617
|
+
"no_local_runtime",
|
|
618
|
+
"input",
|
|
619
|
+
]);
|
|
620
|
+
export const CLOUD_LOGIN_FAILURES = Object.freeze([
|
|
621
|
+
"access_denied",
|
|
622
|
+
"expired_token",
|
|
623
|
+
"invalid_grant",
|
|
624
|
+
"cancelled",
|
|
625
|
+
"transport",
|
|
626
|
+
"refused",
|
|
627
|
+
"no_tokens",
|
|
628
|
+
"other",
|
|
629
|
+
]);
|
|
630
|
+
const R_ISO = R_NONEMPTY;
|
|
631
|
+
const R_LOGIN_FAILURE = oneOfRule("login failure", CLOUD_LOGIN_FAILURES);
|
|
632
|
+
const R_DISPLAY_URL = ruleOf("display url", (v) => {
|
|
633
|
+
if (typeof v !== "string" || v.length === 0)
|
|
634
|
+
return false;
|
|
635
|
+
let u;
|
|
636
|
+
try {
|
|
637
|
+
u = new URL(v);
|
|
638
|
+
}
|
|
639
|
+
catch {
|
|
640
|
+
return false;
|
|
641
|
+
}
|
|
642
|
+
return (u.protocol === "https:" || u.protocol === "http:") && u.username === "" && u.password === "" && u.search === "" && u.hash === "";
|
|
643
|
+
});
|
|
644
|
+
const R_VERIFICATION_URI_COMPLETE = ruleOf("verification uri", (v) => {
|
|
645
|
+
if (typeof v !== "string" || v.length === 0)
|
|
646
|
+
return false;
|
|
647
|
+
let text = v;
|
|
648
|
+
for (let i = 0; i < 4; i += 1) {
|
|
649
|
+
let next;
|
|
650
|
+
try {
|
|
651
|
+
next = decodeURIComponent(text);
|
|
652
|
+
}
|
|
653
|
+
catch {
|
|
654
|
+
return false;
|
|
655
|
+
}
|
|
656
|
+
if (next === text)
|
|
657
|
+
break;
|
|
658
|
+
text = next;
|
|
659
|
+
}
|
|
660
|
+
return !/device[_-]?code/i.test(text);
|
|
661
|
+
});
|
|
662
|
+
const ENGINE_PROBE_READING = shapeRule("engine probe", {
|
|
663
|
+
ok: reqF(R_BOOL),
|
|
664
|
+
version: optF(R_STR),
|
|
665
|
+
detail: optF(R_STR),
|
|
666
|
+
at: reqF(R_ISO),
|
|
667
|
+
});
|
|
668
|
+
const SEAT_LOCAL_MCP_ROW = shapeRule("mcp row", {
|
|
669
|
+
name: reqF(R_NONEMPTY),
|
|
670
|
+
status: reqF(R_STR),
|
|
671
|
+
toolCount: optF(R_INT0),
|
|
672
|
+
liveness: optF(R_STR),
|
|
673
|
+
errorCode: optF(R_STR),
|
|
674
|
+
forcedAsk: optF(arrayRule(R_NONEMPTY, true)),
|
|
675
|
+
});
|
|
676
|
+
const SEAT_LOCAL_MCP_READING = armsRule("mcp reading", "status", {
|
|
677
|
+
listed: { servers: reqF(arrayRule(SEAT_LOCAL_MCP_ROW)), readAt: reqF(R_ISO), restartRequired: optF(R_TRUE) },
|
|
678
|
+
unreadable: { cause: reqF(R_NONEMPTY), detail: optF(R_STR), readAt: reqF(R_ISO), restartRequired: optF(R_TRUE) },
|
|
679
|
+
});
|
|
680
|
+
const ENGINE_TARGET_CLOUD = shapeRule("cloud", {
|
|
681
|
+
configured: reqF(R_BOOL),
|
|
682
|
+
url: optF(R_DISPLAY_URL),
|
|
683
|
+
label: optF(R_STR),
|
|
684
|
+
auth: optF(armsRule("cloud auth", "kind", {
|
|
685
|
+
registry: { registryUrl: reqF(R_DISPLAY_URL), principal: optF(R_STR), role: optF(R_STR), scope: optF(R_STR) },
|
|
686
|
+
token: {},
|
|
687
|
+
})),
|
|
688
|
+
login: optF(armsRule("cloud login", "state", {
|
|
689
|
+
pending: {
|
|
690
|
+
registryUrl: reqF(R_DISPLAY_URL),
|
|
691
|
+
userCode: reqF(R_NONEMPTY),
|
|
692
|
+
verificationUri: reqF(R_DISPLAY_URL),
|
|
693
|
+
verificationUriComplete: optF(R_VERIFICATION_URI_COMPLETE),
|
|
694
|
+
expiresAt: reqF(R_ISO),
|
|
695
|
+
},
|
|
696
|
+
failed: { failure: reqF(R_LOGIN_FAILURE), status: optF(R_INT0), at: reqF(R_ISO) },
|
|
697
|
+
})),
|
|
698
|
+
lastProbe: optF(ENGINE_PROBE_READING),
|
|
699
|
+
authError: optF(shapeRule("auth error", {
|
|
700
|
+
failure: reqF(R_LOGIN_FAILURE),
|
|
701
|
+
status: optF(R_INT0),
|
|
702
|
+
at: reqF(R_ISO),
|
|
703
|
+
})),
|
|
704
|
+
orgEngine: optF(shapeRule("org engine", { url: reqF(R_DISPLAY_URL), required: reqF(R_BOOL) })),
|
|
705
|
+
});
|
|
706
|
+
const ENGINE_TARGET_LOCAL = shapeRule("local", {
|
|
707
|
+
lastBootError: optF(R_STR),
|
|
708
|
+
mcp: optF(SEAT_LOCAL_MCP_READING),
|
|
709
|
+
});
|
|
710
|
+
const ENGINE_TARGET_STATE = shapeRule("engine target", {
|
|
711
|
+
mode: reqF(oneOfRule("engine mode", ["local", "cloud"])),
|
|
712
|
+
generation: reqF(R_INT0),
|
|
713
|
+
cloud: reqF(ENGINE_TARGET_CLOUD),
|
|
714
|
+
local: reqF(ENGINE_TARGET_LOCAL),
|
|
715
|
+
});
|
|
716
|
+
const checkEngineTargetState = seatShapeCheck(ENGINE_TARGET_STATE);
|
|
717
|
+
const okArmsRule = (label, okSpec, refusedSpec) => ({
|
|
718
|
+
label,
|
|
719
|
+
test: (v, path) => {
|
|
720
|
+
if (!isPlainRecord(v))
|
|
721
|
+
return bad("not object", path === "" ? undefined : path);
|
|
722
|
+
const ok = own(v, "ok");
|
|
723
|
+
if (ok === true)
|
|
724
|
+
return shapeVerdict(okSpec, v, path, "ok");
|
|
725
|
+
if (ok === false)
|
|
726
|
+
return shapeVerdict(refusedSpec, v, path, "ok");
|
|
727
|
+
return bad("unknown arm", pathAt(path, "ok"));
|
|
728
|
+
},
|
|
729
|
+
});
|
|
730
|
+
const ENGINE_TARGET_REFUSED_SPEC = {
|
|
731
|
+
refusal: reqF(oneOfRule("engineTarget refusal", ENGINE_TARGET_REFUSALS)),
|
|
732
|
+
failure: optF(R_LOGIN_FAILURE),
|
|
733
|
+
status: optF(R_INT0),
|
|
734
|
+
detail: optF(R_STR),
|
|
735
|
+
};
|
|
736
|
+
const checkEngineTargetResult = seatShapeCheck(okArmsRule("engineTarget result", {}, ENGINE_TARGET_REFUSED_SPEC));
|
|
737
|
+
const checkCancelCloudLogin = seatShapeCheck(shapeRule("cancel ack", { ok: reqF(R_BOOL) }));
|
|
738
|
+
const checkCloudLoginStart = seatShapeCheck(okArmsRule("startCloudLogin result", {
|
|
739
|
+
verificationUri: reqF(R_DISPLAY_URL),
|
|
740
|
+
verificationUriComplete: optF(R_VERIFICATION_URI_COMPLETE),
|
|
741
|
+
userCode: reqF(R_NONEMPTY),
|
|
742
|
+
expiresAt: reqF(R_ISO),
|
|
743
|
+
}, ENGINE_TARGET_REFUSED_SPEC));
|
|
744
|
+
const checkCloudConnectResult = seatShapeCheck(okArmsRule("connect result", {
|
|
745
|
+
probe: reqF(shapeRule("probe", { version: optF(R_STR) })),
|
|
746
|
+
}, ENGINE_TARGET_REFUSED_SPEC));
|
|
747
|
+
export const checkCloudLoginRequest = seatShapeCheck(shapeRule("startCloudLogin request", { registryUrl: reqF(R_DISPLAY_URL) }));
|
|
748
|
+
export const checkCloudEngineConnectRequest = seatShapeCheck(shapeRule("connectCloudEngine request", { url: reqF(R_DISPLAY_URL) }));
|
|
749
|
+
const CONFIGURE_TOKEN_ALLOW = new Set(["token"]);
|
|
750
|
+
export const checkCloudEngineConfigureRequest = seatShapeCheck(shapeRule("configureCloudEngine request", { url: reqF(R_DISPLAY_URL), token: reqF(R_NONEMPTY) }), CONFIGURE_TOKEN_ALLOW);
|
|
751
|
+
export const ONBOARD_REFUSALS = Object.freeze([
|
|
752
|
+
"input",
|
|
753
|
+
"probe_failed",
|
|
754
|
+
"probe_unverified",
|
|
755
|
+
"credential_unpaired",
|
|
756
|
+
"catalog_unreadable",
|
|
757
|
+
"write_conflict",
|
|
758
|
+
"write_failed",
|
|
759
|
+
"engine_is_remote",
|
|
760
|
+
"env_catalog_present",
|
|
761
|
+
]);
|
|
762
|
+
const R_API_WORD = oneOfRule("api", SETTINGS_MODEL_API_WORDS);
|
|
763
|
+
const ONBOARD_PROBE_RESULT = shapeRule("probe result", {
|
|
764
|
+
verdict: reqF(oneOfRule("probe verdict", PROBE_VERDICTS)),
|
|
765
|
+
detail: reqF(R_STR),
|
|
766
|
+
thinking: optF(R_NONEMPTY),
|
|
767
|
+
});
|
|
768
|
+
const ENGINE_UP_SPEC = { model: reqF(ruleOf("string|null", (x) => x === null || typeof x === "string")) };
|
|
769
|
+
const ENGINE_NOT_UP_SPEC = { reason: reqF(R_STR) };
|
|
770
|
+
const ENGINE_RESTART_OUTCOME = armsRule("engine restart", "state", {
|
|
771
|
+
started: ENGINE_UP_SPEC,
|
|
772
|
+
restarted: ENGINE_UP_SPEC,
|
|
773
|
+
pending: ENGINE_NOT_UP_SPEC,
|
|
774
|
+
failed: ENGINE_NOT_UP_SPEC,
|
|
775
|
+
skipped: ENGINE_NOT_UP_SPEC,
|
|
776
|
+
});
|
|
777
|
+
const ONBOARD_SOURCE = armsRule("onboard source", "kind", {
|
|
778
|
+
preset: { providerId: reqF(R_NONEMPTY) },
|
|
779
|
+
custom: {},
|
|
780
|
+
imported: { profileId: reqF(R_NONEMPTY) },
|
|
781
|
+
});
|
|
782
|
+
const ONBOARD_ENTRY_SPEC = {
|
|
783
|
+
source: reqF(ONBOARD_SOURCE),
|
|
784
|
+
modelId: reqF(R_NONEMPTY),
|
|
785
|
+
baseUrl: optF(R_NONEMPTY),
|
|
786
|
+
api: optF(R_API_WORD),
|
|
787
|
+
apiKey: optF(R_NONEMPTY),
|
|
788
|
+
contextWindow: optF(R_INT1),
|
|
789
|
+
maxTokens: optF(R_INT1),
|
|
790
|
+
};
|
|
791
|
+
const ONBOARD_KEY_ALLOW = new Set(["apiKey"]);
|
|
792
|
+
export const checkOnboardEntryRequest = seatShapeCheck(shapeRule("probeOnboardEntry request", ONBOARD_ENTRY_SPEC), ONBOARD_KEY_ALLOW);
|
|
793
|
+
export const checkOnboardApplyRequest = seatShapeCheck(shapeRule("applyOnboardEntry request", {
|
|
794
|
+
...ONBOARD_ENTRY_SPEC,
|
|
795
|
+
makeDefault: optF(R_BOOL),
|
|
796
|
+
acceptUnverified: optF(R_BOOL),
|
|
797
|
+
}), ONBOARD_KEY_ALLOW);
|
|
798
|
+
const checkOnboardProbeResult = seatShapeCheck(ONBOARD_PROBE_RESULT);
|
|
799
|
+
const checkOnboardApplyResult = seatShapeCheck(okArmsRule("applyOnboardEntry result", {
|
|
800
|
+
entryName: reqF(R_NONEMPTY),
|
|
801
|
+
modelId: reqF(R_NONEMPTY),
|
|
802
|
+
keyEnv: reqF(R_NONEMPTY),
|
|
803
|
+
updatedExisting: reqF(R_BOOL),
|
|
804
|
+
probe: reqF(ONBOARD_PROBE_RESULT),
|
|
805
|
+
otherIssues: reqF(arrayRule(shapeRule("catalog issue", {
|
|
806
|
+
name: reqF(R_NONEMPTY),
|
|
807
|
+
modelId: reqF(R_STR),
|
|
808
|
+
issue: reqF(R_NONEMPTY),
|
|
809
|
+
}))),
|
|
810
|
+
engine: reqF(ENGINE_RESTART_OUTCOME),
|
|
811
|
+
}, {
|
|
812
|
+
refusal: reqF(oneOfRule("onboard refusal", ONBOARD_REFUSALS)),
|
|
813
|
+
detail: optF(R_STR),
|
|
814
|
+
probe: optF(ONBOARD_PROBE_RESULT),
|
|
815
|
+
}));
|
|
816
|
+
const checkOnboardProvidersResult = seatShapeCheck(shapeRule("onboard providers", {
|
|
817
|
+
providers: reqF(arrayRule(shapeRule("provider row", {
|
|
818
|
+
id: reqF(R_NONEMPTY),
|
|
819
|
+
name: reqF(R_NONEMPTY),
|
|
820
|
+
baseUrl: reqF(R_NONEMPTY),
|
|
821
|
+
api: reqF(R_API_WORD),
|
|
822
|
+
keyAuth: reqF(R_BOOL),
|
|
823
|
+
authEnv: reqF(R_STR),
|
|
824
|
+
models: reqF(arrayRule(shapeRule("provider model", {
|
|
825
|
+
id: reqF(R_NONEMPTY),
|
|
826
|
+
contextWindow: reqF(R_INT1),
|
|
827
|
+
maxTokens: reqF(R_INT1),
|
|
828
|
+
}))),
|
|
829
|
+
consoleUrl: optF(R_STR),
|
|
830
|
+
}))),
|
|
831
|
+
importable: optF(arrayRule(shapeRule("importable profile", {
|
|
832
|
+
id: reqF(R_NONEMPTY),
|
|
833
|
+
name: reqF(R_STR),
|
|
834
|
+
baseUrl: reqF(R_NONEMPTY),
|
|
835
|
+
api: reqF(R_API_WORD),
|
|
836
|
+
hasKey: reqF(R_BOOL),
|
|
837
|
+
models: reqF(arrayRule(R_NONEMPTY)),
|
|
838
|
+
}))),
|
|
839
|
+
}));
|
|
840
|
+
const checkSessionMcpPanelFailure = seatShapeCheck(armsRule("readSessionMcpPanel failure", "kind", {
|
|
841
|
+
unreadable: DEVICE_UNREADABLE_SPEC,
|
|
842
|
+
transport: DEVICE_TRANSPORT_SPEC,
|
|
843
|
+
unarmed: {},
|
|
844
|
+
}));
|
|
845
|
+
function mcpPanelLivenessArms() {
|
|
846
|
+
const arms = {};
|
|
847
|
+
for (const state of MCP_LIVENESS_STATES)
|
|
848
|
+
arms[state] = state === "unreachable" ? { observedAt: reqF(R_NUM), errorCode: optF(R_NONEMPTY) } : { observedAt: reqF(R_NUM) };
|
|
849
|
+
const keysPin = [true, true];
|
|
850
|
+
void keysPin;
|
|
851
|
+
return arms;
|
|
852
|
+
}
|
|
853
|
+
const MCP_PANEL_LIVENESS_VIEW = armsRule("mcp liveness", "state", mcpPanelLivenessArms());
|
|
854
|
+
const MCP_PANEL_LEG_ENTRY = shapeRule("leg entry", {
|
|
855
|
+
name: reqF(R_NONEMPTY),
|
|
856
|
+
status: reqF(R_NONEMPTY),
|
|
857
|
+
source: optF(R_NONEMPTY),
|
|
858
|
+
errorCode: optF(R_NONEMPTY),
|
|
859
|
+
toolCount: optF(R_NUM),
|
|
860
|
+
delivered: optF(R_NONEMPTY),
|
|
861
|
+
httpStatus: optF(R_NUM),
|
|
862
|
+
liveness: optF(MCP_PANEL_LIVENESS_VIEW),
|
|
863
|
+
livenessUnreadable: optF(R_TRUE),
|
|
864
|
+
});
|
|
865
|
+
const MCP_PANEL_LAST_LEG = shapeRule("last leg", {
|
|
866
|
+
runId: reqF(R_NONEMPTY),
|
|
867
|
+
at: reqF(R_NONEMPTY),
|
|
868
|
+
mcp: reqF(arrayRule(MCP_PANEL_LEG_ENTRY)),
|
|
869
|
+
});
|
|
870
|
+
const MCP_PANEL_SERVER_ROW = shapeRule("panel server", {
|
|
871
|
+
name: reqF(R_NONEMPTY),
|
|
872
|
+
status: reqF(R_NONEMPTY),
|
|
873
|
+
serverInfo: optF(shapeRule("server info", {
|
|
874
|
+
name: reqF(R_STR),
|
|
875
|
+
version: reqF(R_STR),
|
|
876
|
+
})),
|
|
877
|
+
toolNames: optF(arrayRule(R_STR)),
|
|
878
|
+
error: optF(R_STR),
|
|
879
|
+
});
|
|
880
|
+
const MCP_PANEL_SCENARIO_REFUSAL = shapeRule("scenario refusal", {
|
|
881
|
+
errorCode: optF(R_NONEMPTY),
|
|
882
|
+
error: optF(R_STR),
|
|
883
|
+
scenario: optF(R_NONEMPTY),
|
|
884
|
+
source: optF(oneOfRule("refusal source", ["ruling", "deployment"])),
|
|
885
|
+
});
|
|
886
|
+
const checkSessionMcpPanelServersView = seatShapeCheck(shapeRule("servers view", {
|
|
887
|
+
asOf: reqF(R_NONEMPTY),
|
|
888
|
+
lastLegMcp: optF(MCP_PANEL_LAST_LEG),
|
|
889
|
+
lastLegMcpUnreadable: optF(R_TRUE),
|
|
890
|
+
servers: reqF(arrayRule(MCP_PANEL_SERVER_ROW)),
|
|
891
|
+
degraded: optF(R_TRUE),
|
|
892
|
+
}));
|
|
893
|
+
const checkSessionMcpPanelRefusalView = seatShapeCheck(shapeRule("refusal view", {
|
|
894
|
+
asOf: reqF(R_NONEMPTY),
|
|
895
|
+
lastLegMcp: optF(MCP_PANEL_LAST_LEG),
|
|
896
|
+
lastLegMcpUnreadable: optF(R_TRUE),
|
|
897
|
+
scenarioRefusal: reqF(MCP_PANEL_SCENARIO_REFUSAL),
|
|
898
|
+
}));
|
|
899
|
+
const checkSessionMcpPanelResult = seatCheck((v) => {
|
|
900
|
+
if (!isPlainRecord(v))
|
|
901
|
+
return bad("mcp panel result is not a plain object");
|
|
902
|
+
if (Object.hasOwn(v, "kind"))
|
|
903
|
+
return checkSessionMcpPanelFailure(v);
|
|
904
|
+
return Object.hasOwn(v, "scenarioRefusal") ? checkSessionMcpPanelRefusalView(v) : checkSessionMcpPanelServersView(v);
|
|
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)) }));
|
|
408
912
|
const checkLocalSessionRecord = seatCheck((s) => {
|
|
409
913
|
if (!isPlainRecord(s))
|
|
410
914
|
return bad("session record is not a plain object");
|
|
@@ -505,6 +1009,91 @@ const checkLaneProof = seatCheckAt((v, field) => {
|
|
|
505
1009
|
}
|
|
506
1010
|
return true;
|
|
507
1011
|
});
|
|
1012
|
+
const R_NEVER = ruleOf("absent", () => false);
|
|
1013
|
+
const RETRY_ERROR_PAYLOAD = shapeRule("retry error", {
|
|
1014
|
+
formatted: reqF(R_STR),
|
|
1015
|
+
isNetworkDown: optF(R_BOOL),
|
|
1016
|
+
connection: optF(shapeRule("connection", { isSSLError: optF(R_BOOL) })),
|
|
1017
|
+
rateLimits: optF({
|
|
1018
|
+
label: "rate limits",
|
|
1019
|
+
test: (v, path) => v === null
|
|
1020
|
+
? true
|
|
1021
|
+
: shapeVerdict({ resetsAt: optF(R_NUM), rateLimitType: optF(R_STR) }, v, path),
|
|
1022
|
+
}),
|
|
1023
|
+
});
|
|
1024
|
+
const RETRY_COMMON_SPEC = {
|
|
1025
|
+
deadline: reqF(R_NUM),
|
|
1026
|
+
attempt: optF(R_NUM),
|
|
1027
|
+
maxRetries: optF(R_NUM),
|
|
1028
|
+
errClass: optF(R_STR),
|
|
1029
|
+
retryAtMs: optF(R_NUM),
|
|
1030
|
+
errorStatus: optF(R_NUM),
|
|
1031
|
+
providerCondition: optF(R_STR),
|
|
1032
|
+
providerConditionSource: optF(R_STR),
|
|
1033
|
+
elapsedMs: optF(R_NUM),
|
|
1034
|
+
timeoutMs: optF(R_NUM),
|
|
1035
|
+
};
|
|
1036
|
+
const RETRY_STATUS = armsRule("retry status", "kind", {
|
|
1037
|
+
stalled: { ...RETRY_COMMON_SPEC, detail: optF(R_STR) },
|
|
1038
|
+
error: { ...RETRY_COMMON_SPEC, terminal: optF(R_TRUE), error: reqF(RETRY_ERROR_PAYLOAD) },
|
|
1039
|
+
waiting: { ...RETRY_COMMON_SPEC, terminal: optF(R_NEVER), error: reqF(RETRY_ERROR_PAYLOAD) },
|
|
1040
|
+
});
|
|
1041
|
+
const ENGINE_TURN_USAGE = shapeRule("engine usage", {
|
|
1042
|
+
inputTokens: reqF(R_NUM),
|
|
1043
|
+
totalInputTokens: reqF(R_NUM),
|
|
1044
|
+
outputTokens: reqF(R_NUM),
|
|
1045
|
+
cacheReadTokens: reqF(R_NUM),
|
|
1046
|
+
cacheWriteTokens: reqF(R_NUM),
|
|
1047
|
+
costMicroUsd: reqF(R_NUM),
|
|
1048
|
+
});
|
|
1049
|
+
const SEMA_MODEL_USAGE = shapeRule("model usage", {
|
|
1050
|
+
inputTokens: reqF(R_NUM),
|
|
1051
|
+
outputTokens: reqF(R_NUM),
|
|
1052
|
+
cacheReadInputTokens: reqF(R_NUM),
|
|
1053
|
+
cacheCreationInputTokens: reqF(R_NUM),
|
|
1054
|
+
webSearchRequests: reqF(R_NUM),
|
|
1055
|
+
costUSD: reqF(R_NUM),
|
|
1056
|
+
contextWindow: reqF(R_NUM),
|
|
1057
|
+
maxOutputTokens: reqF(R_NUM),
|
|
1058
|
+
canonicalModel: optF(R_STR),
|
|
1059
|
+
provider: optF(R_STR),
|
|
1060
|
+
_sema_cost_absent: optF(R_TRUE),
|
|
1061
|
+
_sema_web_search_requests_absent: optF(R_TRUE),
|
|
1062
|
+
_sema_context_window_absent: optF(R_TRUE),
|
|
1063
|
+
_sema_max_output_tokens_absent: optF(R_TRUE),
|
|
1064
|
+
});
|
|
1065
|
+
const SEAT_CHROME_PAYLOAD_SPECS = {
|
|
1066
|
+
retry_status: { status: reqF({ label: "retry status", test: (v, path) => (v === null ? true : RETRY_STATUS.test(v, path)) }) },
|
|
1067
|
+
context_usage: {
|
|
1068
|
+
usedTokens: optF(R_NUM),
|
|
1069
|
+
windowTokens: optF(R_NUM),
|
|
1070
|
+
compactAtTokens: optF(R_NUM),
|
|
1071
|
+
sections: optF(arrayRule(shapeRule("section", { id: reqF(R_STR), tokens: reqF(R_NUM), kind: optF(R_STR) }))),
|
|
1072
|
+
eventId: optF(R_NONEMPTY),
|
|
1073
|
+
},
|
|
1074
|
+
last_turn_usage: {
|
|
1075
|
+
usage: reqF(SEMA_MODEL_USAGE),
|
|
1076
|
+
engineUsage: optF(ENGINE_TURN_USAGE),
|
|
1077
|
+
engineUsageUnknownKeys: optF(R_INT1),
|
|
1078
|
+
usageMissing: optF(R_TRUE),
|
|
1079
|
+
stopReason: optF(R_STR),
|
|
1080
|
+
responseModel: optF(R_NONEMPTY),
|
|
1081
|
+
},
|
|
1082
|
+
bgshell_register: {
|
|
1083
|
+
taskId: reqF(R_NONEMPTY),
|
|
1084
|
+
registration: reqF(shapeRule("registration", {
|
|
1085
|
+
kind: reqF(oneOfRule("registration kind", ["register"])),
|
|
1086
|
+
taskId: reqF(R_NONEMPTY),
|
|
1087
|
+
command: reqF(R_STR),
|
|
1088
|
+
description: optF(R_STR),
|
|
1089
|
+
receipt: reqF(R_STR),
|
|
1090
|
+
source: reqF(oneOfRule("registration source", ["bash", "monitor"])),
|
|
1091
|
+
})),
|
|
1092
|
+
},
|
|
1093
|
+
bgshell_settle: { taskId: reqF(R_NONEMPTY), status: reqF(R_STR), outputPath: optF(R_STR) },
|
|
1094
|
+
memory_saved: { id: reqF(R_NONEMPTY), notes: reqF(arrayRule(R_NONEMPTY, true)) },
|
|
1095
|
+
};
|
|
1096
|
+
const ENVELOPE_ROWS = { kind: reqF({ label: "kind", test: () => true }), laneProof: reqF({ label: "laneProof", test: () => true }) };
|
|
508
1097
|
const checkSeatChromeEnvelope = seatCheckAt((v, field) => {
|
|
509
1098
|
if (!isPlainRecord(v))
|
|
510
1099
|
return bad("chrome must be a plain object", field);
|
|
@@ -514,7 +1103,13 @@ const checkSeatChromeEnvelope = seatCheckAt((v, field) => {
|
|
|
514
1103
|
if (!inTuple(CHROME_EVENT_KIND_TUPLE, kind)) {
|
|
515
1104
|
return bad(`chrome.kind is not a renderer-wired arm (${CHROME_EVENT_KIND_TUPLE.join("|")})`, `${field}.kind`);
|
|
516
1105
|
}
|
|
517
|
-
|
|
1106
|
+
const lane = checkLaneProof(own(v, "laneProof"), `${field}.laneProof`);
|
|
1107
|
+
if (lane !== true)
|
|
1108
|
+
return lane;
|
|
1109
|
+
if (Object.hasOwn(SEAT_CHROME_PAYLOAD_SPECS, kind)) {
|
|
1110
|
+
return shapeVerdict({ ...ENVELOPE_ROWS, ...SEAT_CHROME_PAYLOAD_SPECS[kind] }, v, field);
|
|
1111
|
+
}
|
|
1112
|
+
return true;
|
|
518
1113
|
});
|
|
519
1114
|
const checkLocalSessionEvent = seatCheck((v) => {
|
|
520
1115
|
if (!isPlainRecord(v))
|
|
@@ -534,18 +1129,6 @@ const checkLocalSessionEvent = seatCheck((v) => {
|
|
|
534
1129
|
const code = own(v, "code");
|
|
535
1130
|
if (!isAbsent(code) && typeof code !== "number")
|
|
536
1131
|
return bad("code must be a number when present", "code");
|
|
537
|
-
const request = own(v, "request");
|
|
538
|
-
if (!isAbsent(request)) {
|
|
539
|
-
const verdict = checkToolPermissionRequest(request);
|
|
540
|
-
if (verdict !== true)
|
|
541
|
-
return nested("request", verdict);
|
|
542
|
-
}
|
|
543
|
-
const sources = own(v, "sources");
|
|
544
|
-
if (!isAbsent(sources)) {
|
|
545
|
-
const okSources = Array.isArray(sources) && ownItems(sources).every((t) => typeof t === "string");
|
|
546
|
-
if (!okSources)
|
|
547
|
-
return bad("sources must be a string[]", "sources");
|
|
548
|
-
}
|
|
549
1132
|
const session = own(v, "session");
|
|
550
1133
|
if (!isAbsent(session)) {
|
|
551
1134
|
const verdict = checkLocalSessionRecord(session);
|
|
@@ -573,8 +1156,43 @@ const checkLocalSessionEvent = seatCheck((v) => {
|
|
|
573
1156
|
if (verdict !== true)
|
|
574
1157
|
return nested("chrome", verdict);
|
|
575
1158
|
}
|
|
1159
|
+
const sub = own(v, "subagentContent");
|
|
1160
|
+
if (type === "subagent_content") {
|
|
1161
|
+
if (isAbsent(sub))
|
|
1162
|
+
return bad("missing key", "subagentContent");
|
|
1163
|
+
const verdict = SUBAGENT_CONTENT_SHAPE.test(sub, "subagentContent");
|
|
1164
|
+
if (verdict !== true)
|
|
1165
|
+
return verdict;
|
|
1166
|
+
}
|
|
1167
|
+
else if (!isAbsent(sub)) {
|
|
1168
|
+
return bad("unexpected key", "subagentContent");
|
|
1169
|
+
}
|
|
576
1170
|
return true;
|
|
577
1171
|
});
|
|
1172
|
+
const SUBAGENT_CONTENT_SHAPE = shapeRule("subagent content", {
|
|
1173
|
+
type: reqF(oneOfRule("content type", ["text_delta", "reasoning_delta", "text", "reasoning", "tool_start", "tool_end"])),
|
|
1174
|
+
taskId: reqF(R_NONEMPTY),
|
|
1175
|
+
parentToolCallId: reqF(R_NONEMPTY),
|
|
1176
|
+
delta: optF(R_STR),
|
|
1177
|
+
text: optF(R_STR),
|
|
1178
|
+
eventId: optF(R_STR),
|
|
1179
|
+
toolCallId: optF(R_STR),
|
|
1180
|
+
toolName: optF(R_STR),
|
|
1181
|
+
args: optF({ label: "passthrough", test: () => true }),
|
|
1182
|
+
output: optF(R_STR),
|
|
1183
|
+
isError: optF(R_BOOL),
|
|
1184
|
+
});
|
|
1185
|
+
export function readSeatSubagentContent(event) {
|
|
1186
|
+
try {
|
|
1187
|
+
if (checkLocalSessionEvent(event) !== true || own(event, "type") !== "subagent_content")
|
|
1188
|
+
return undefined;
|
|
1189
|
+
const sub = own(event, "subagentContent");
|
|
1190
|
+
return { ...sub };
|
|
1191
|
+
}
|
|
1192
|
+
catch {
|
|
1193
|
+
return undefined;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
578
1196
|
export function isLocalSessionEvent(v) {
|
|
579
1197
|
return checkLocalSessionEvent(v) === true;
|
|
580
1198
|
}
|
|
@@ -945,6 +1563,23 @@ export const LOCAL_SESSIONS_SPEC = {
|
|
|
945
1563
|
pickFolder: { kind: "invoke", check: checkPickFolderResult },
|
|
946
1564
|
listRecentFolders: { kind: "invoke", check: checkRecentFoldersResult },
|
|
947
1565
|
noteRecentFolder: { kind: "invoke", check: checkOkAck }, patchSession: { kind: "invoke", check: checkLocalSessionRecord },
|
|
1566
|
+
listDevices: { kind: "invoke", check: checkDeviceListOutcome },
|
|
1567
|
+
readSessionBinding: { kind: "invoke", check: checkDeviceSessionBindingOutcome },
|
|
1568
|
+
rebindSession: { kind: "invoke", check: checkDeviceRebindOutcome },
|
|
1569
|
+
issueEnrollToken: { kind: "invoke", check: checkDeviceEnrollTokenOutcome },
|
|
1570
|
+
revokeDevice: { kind: "invoke", check: checkDeviceRevokeOutcome },
|
|
1571
|
+
setEngineMode: { kind: "invoke", check: checkEngineTargetResult },
|
|
1572
|
+
startCloudLogin: { kind: "invoke", check: checkCloudLoginStart },
|
|
1573
|
+
cancelCloudLogin: { kind: "invoke", check: checkCancelCloudLogin },
|
|
1574
|
+
connectCloudEngine: { kind: "invoke", check: checkCloudConnectResult },
|
|
1575
|
+
configureCloudEngine: { kind: "invoke", check: checkCloudConnectResult },
|
|
1576
|
+
clearCloudEngine: { kind: "invoke", check: checkEngineTargetResult },
|
|
1577
|
+
listOnboardProviders: { kind: "invoke", check: checkOnboardProvidersResult },
|
|
1578
|
+
probeOnboardEntry: { kind: "invoke", check: checkOnboardProbeResult },
|
|
1579
|
+
applyOnboardEntry: { kind: "invoke", check: checkOnboardApplyResult },
|
|
1580
|
+
readSessionMcpPanel: { kind: "invoke", check: checkSessionMcpPanelResult },
|
|
1581
|
+
listMcpToolToggles: { kind: "invoke", check: checkMcpToolTogglesResult },
|
|
1582
|
+
setMcpToolToggle: { kind: "invoke", check: checkOkAck },
|
|
948
1583
|
onEvent: { kind: "event", check: checkLocalSessionEvent },
|
|
949
1584
|
onToolPermissionRequest: { kind: "event", check: checkToolPermissionRequest },
|
|
950
1585
|
},
|
|
@@ -953,6 +1588,7 @@ export const LOCAL_SESSIONS_SPEC = {
|
|
|
953
1588
|
focusedSessionState: { check: checkFocusedSessionState },
|
|
954
1589
|
settingsState: { check: checkSettingsState },
|
|
955
1590
|
seatCapabilitiesState: { check: checkSeatCapabilitiesState },
|
|
1591
|
+
engineTargetState: { check: checkEngineTargetState },
|
|
956
1592
|
},
|
|
957
1593
|
};
|
|
958
1594
|
export const SEAT_METHOD_NAMES = [
|
|
@@ -974,6 +1610,23 @@ export const SEAT_METHOD_NAMES = [
|
|
|
974
1610
|
"pickFolder",
|
|
975
1611
|
"listRecentFolders",
|
|
976
1612
|
"noteRecentFolder", "patchSession",
|
|
1613
|
+
"listDevices",
|
|
1614
|
+
"readSessionBinding",
|
|
1615
|
+
"rebindSession",
|
|
1616
|
+
"issueEnrollToken",
|
|
1617
|
+
"revokeDevice",
|
|
1618
|
+
"setEngineMode",
|
|
1619
|
+
"startCloudLogin",
|
|
1620
|
+
"cancelCloudLogin",
|
|
1621
|
+
"connectCloudEngine",
|
|
1622
|
+
"configureCloudEngine",
|
|
1623
|
+
"clearCloudEngine",
|
|
1624
|
+
"listOnboardProviders",
|
|
1625
|
+
"probeOnboardEntry",
|
|
1626
|
+
"applyOnboardEntry",
|
|
1627
|
+
"readSessionMcpPanel",
|
|
1628
|
+
"listMcpToolToggles",
|
|
1629
|
+
"setMcpToolToggle",
|
|
977
1630
|
"onEvent",
|
|
978
1631
|
"onToolPermissionRequest",
|
|
979
1632
|
];
|
|
@@ -982,6 +1635,7 @@ export const SEAT_STORE_PROPS = [
|
|
|
982
1635
|
"focusedSessionStateStore",
|
|
983
1636
|
"settingsStateStore",
|
|
984
1637
|
"seatCapabilitiesStateStore",
|
|
1638
|
+
"engineTargetStateStore",
|
|
985
1639
|
];
|
|
986
1640
|
export const SEAT_EVENT_METHOD_NAMES = ["onEvent", "onToolPermissionRequest"];
|
|
987
1641
|
export const LOCAL_SESSION_EVENT_KEYS = [
|
|
@@ -991,8 +1645,6 @@ export const LOCAL_SESSION_EVENT_KEYS = [
|
|
|
991
1645
|
"error",
|
|
992
1646
|
"errorCategory",
|
|
993
1647
|
"code",
|
|
994
|
-
"request",
|
|
995
|
-
"sources",
|
|
996
1648
|
"session",
|
|
997
1649
|
"userMessageUuid",
|
|
998
1650
|
"requestId",
|
|
@@ -1000,6 +1652,7 @@ export const LOCAL_SESSION_EVENT_KEYS = [
|
|
|
1000
1652
|
"parked",
|
|
1001
1653
|
"chrome",
|
|
1002
1654
|
"_sema_turnFailure",
|
|
1655
|
+
"subagentContent",
|
|
1003
1656
|
];
|
|
1004
1657
|
export const TOOL_PERMISSION_REQUEST_KEYS = [
|
|
1005
1658
|
"requestId",
|
|
@@ -1135,14 +1788,13 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
|
|
|
1135
1788
|
"error",
|
|
1136
1789
|
"errorCategory",
|
|
1137
1790
|
"code",
|
|
1138
|
-
"request",
|
|
1139
|
-
"sources",
|
|
1140
1791
|
"session",
|
|
1141
1792
|
"userMessageUuid",
|
|
1142
1793
|
"requestId",
|
|
1143
1794
|
"outcome",
|
|
1144
1795
|
"parked",
|
|
1145
1796
|
"chrome",
|
|
1797
|
+
"subagentContent",
|
|
1146
1798
|
],
|
|
1147
1799
|
unchecked: [
|
|
1148
1800
|
{
|
|
@@ -1254,7 +1906,7 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
|
|
|
1254
1906
|
},
|
|
1255
1907
|
SeatCapabilitiesState: {
|
|
1256
1908
|
check: checkSeatCapabilitiesState,
|
|
1257
|
-
validated: ["pickFolder", "rewind", "recents", "patchSession"],
|
|
1909
|
+
validated: ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles"],
|
|
1258
1910
|
unchecked: [],
|
|
1259
1911
|
},
|
|
1260
1912
|
RecentFoldersResult: {
|
|
@@ -1287,8 +1939,41 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
|
|
|
1287
1939
|
validated: ["kind", "laneProof"],
|
|
1288
1940
|
unchecked: [],
|
|
1289
1941
|
},
|
|
1942
|
+
SessionMcpPanelResult: {
|
|
1943
|
+
check: checkSessionMcpPanelResult,
|
|
1944
|
+
validated: ["kind", "why", "detail", "asOf", "servers", "lastLegMcp", "lastLegMcpUnreadable", "degraded", "scenarioRefusal"],
|
|
1945
|
+
unchecked: [],
|
|
1946
|
+
},
|
|
1290
1947
|
};
|
|
1291
1948
|
export const SEAT_VALIDATOR_COVERAGE_EXEMPT = [
|
|
1949
|
+
...[
|
|
1950
|
+
["DeviceListOutcome", checkDeviceListOutcome],
|
|
1951
|
+
["DeviceSessionBindingOutcome", checkDeviceSessionBindingOutcome],
|
|
1952
|
+
["DeviceRebindOutcome", checkDeviceRebindOutcome],
|
|
1953
|
+
["DeviceEnrollTokenOutcome", checkDeviceEnrollTokenOutcome],
|
|
1954
|
+
["DeviceRevokeOutcome", checkDeviceRevokeOutcome],
|
|
1955
|
+
["SeatDeviceRebindRequest", checkSeatDeviceRebindRequest],
|
|
1956
|
+
["SeatDeviceRevokeRequest", checkSeatDeviceRevokeRequest],
|
|
1957
|
+
["EngineTargetState", checkEngineTargetState],
|
|
1958
|
+
["EngineTargetResult", checkEngineTargetResult],
|
|
1959
|
+
["CloudLoginStart", checkCloudLoginStart],
|
|
1960
|
+
["CloudLoginCancelAck", checkCancelCloudLogin],
|
|
1961
|
+
["CloudConnectResult", checkCloudConnectResult],
|
|
1962
|
+
["CloudLoginRequest", checkCloudLoginRequest],
|
|
1963
|
+
["CloudEngineConnectRequest", checkCloudEngineConnectRequest],
|
|
1964
|
+
["CloudEngineConfigureRequest", checkCloudEngineConfigureRequest],
|
|
1965
|
+
["OnboardProvidersResult", checkOnboardProvidersResult],
|
|
1966
|
+
["OnboardProbeResult", checkOnboardProbeResult],
|
|
1967
|
+
["OnboardApplyResult", checkOnboardApplyResult],
|
|
1968
|
+
["OnboardEntryRequest", checkOnboardEntryRequest],
|
|
1969
|
+
["OnboardApplyRequest", checkOnboardApplyRequest],
|
|
1970
|
+
["McpToolTogglesResult", checkMcpToolTogglesResult],
|
|
1971
|
+
["McpToolToggleKey", checkMcpToolToggleKey],
|
|
1972
|
+
].map(([label, check]) => ({
|
|
1973
|
+
label,
|
|
1974
|
+
check,
|
|
1975
|
+
why: "座位闭形规则铸的判官(规格表型由对象型派生,键集与必选性编译期两向钉);逐臂逐键投毒在三只席位门(见上方注)。",
|
|
1976
|
+
})),
|
|
1292
1977
|
{
|
|
1293
1978
|
label: "PickFolderResult",
|
|
1294
1979
|
check: checkPickFolderResult,
|
|
@@ -1333,5 +2018,8 @@ const _seatContractPins = [
|
|
|
1333
2018
|
true, true, true, true, true, true,
|
|
1334
2019
|
true, true,
|
|
1335
2020
|
true, true, true, true,
|
|
2021
|
+
true, true, true,
|
|
2022
|
+
true,
|
|
2023
|
+
true, true, true,
|
|
1336
2024
|
];
|
|
1337
2025
|
void _seatContractPins;
|