@sema-agent/client-core 0.95.0 → 0.96.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +180 -0
- package/README.md +49 -25
- package/dist/adapt/arms.js +7 -1
- package/dist/adapt/toolCards.d.ts +1 -0
- package/dist/adapt/toolCards.js +16 -3
- package/dist/adapt/wireShapes.js +2 -16
- package/dist/adapter/activeRunSelfHeal.d.ts +4 -0
- package/dist/adapter/activeRunSelfHeal.js +30 -4
- package/dist/adapter/downstream/eventToSdkMessage.js +11 -3
- package/dist/adapter/downstream/terminalToSdkResult.js +8 -9
- package/dist/adapter/runStream.js +30 -47
- package/dist/agentSession/engineAgentRegistryRead.js +5 -4
- package/dist/agentSession/engineSessionBackgroundStop.js +22 -15
- package/dist/agentsWireCaps.js +13 -2
- package/dist/callerCwdCapability.d.ts +0 -4
- package/dist/callerCwdCapability.js +0 -6
- package/dist/centerWiringCapability.d.ts +0 -4
- package/dist/centerWiringCapability.js +0 -6
- package/dist/classifierVerdictWire.js +4 -16
- package/dist/clientSlice.js +1 -1
- package/dist/cloudConfigWireCaps.d.ts +3 -3
- package/dist/cloudConfigWireCaps.js +65 -45
- package/dist/coreValuePorts.d.ts +11 -7
- package/dist/coreValuePorts.js +5 -8
- package/dist/credentialProvenance.d.ts +28 -0
- package/dist/credentialProvenance.js +76 -0
- package/dist/decideFailureNote.js +3 -1
- package/dist/decideReceipt.js +7 -10
- package/dist/declared/supportFloorDeclared.js +3 -3
- package/dist/displayUntrusted.d.ts +7 -3
- package/dist/displayUntrusted.js +356 -60
- package/dist/engineCapsCache.d.ts +6 -0
- package/dist/engineCapsCache.js +226 -32
- package/dist/engineDirectory.d.ts +79 -0
- package/dist/engineDirectory.js +186 -0
- package/dist/engineErrorCodes.d.ts +14 -1
- package/dist/engineErrorCodes.js +37 -15
- package/dist/engineNoticeCodes.d.ts +17 -0
- package/dist/engineNoticeCodes.js +57 -3
- package/dist/engineWordRenames.d.ts +8 -0
- package/dist/engineWordRenames.js +13 -0
- package/dist/fileHistoryCaptureCapability.d.ts +14 -0
- package/dist/fileHistoryCaptureCapability.js +70 -0
- package/dist/fleet/bgSubagentRow.d.ts +15 -0
- package/dist/fleet/bgSubagentRow.js +67 -0
- package/dist/fleet/fleetLedger.d.ts +1 -0
- package/dist/fleet/fleetLedger.js +103 -89
- package/dist/fleet/fleetProjection.d.ts +1 -0
- package/dist/fleet/fleetProjection.js +10 -3
- package/dist/fleetTaskDesc.js +4 -17
- package/dist/gateOutcome.d.ts +12 -1
- package/dist/gateOutcome.js +58 -1
- package/dist/gateVocabulary.d.ts +7 -2
- package/dist/gateVocabulary.js +5 -1
- package/dist/generated/engineAskFaceTables.js +1 -1
- package/dist/generated/engineFactTables.d.ts +5 -3
- package/dist/generated/engineFactTables.js +17 -4
- package/dist/generated/engineNoticeTables.js +12 -3
- package/dist/generated/settingsSchemaFns.d.ts +3 -0
- package/dist/generated/settingsSchemaFns.js +53 -0
- package/dist/generated/toolNameTables.d.ts +1 -0
- package/dist/generated/toolNameTables.js +1 -0
- package/dist/hitl/approvalEndingCause.d.ts +2 -0
- package/dist/hitl/approvalEndingCause.js +31 -21
- package/dist/hitl/askParkRowRouting.js +1 -1
- package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
- package/dist/hitl/automaticAnswerVerdict.js +13 -8
- package/dist/hitl/decisionConflict.js +0 -2
- package/dist/hitl/decisionRefusal.d.ts +8 -0
- package/dist/hitl/decisionRefusal.js +48 -14
- package/dist/hitl/frameRouter.d.ts +0 -1
- package/dist/hitl/frameRouter.js +6 -14
- package/dist/hitl/hitlBridge.d.ts +6 -2
- package/dist/hitl/hitlBridge.js +28 -7
- package/dist/hitl/localAllowRule.d.ts +1 -0
- package/dist/hitl/localAllowRule.js +2 -2
- package/dist/hitl/noAllowCause.d.ts +2 -1
- package/dist/hitl/noAllowCause.js +3 -2
- package/dist/hitl/parkResolver.d.ts +1 -0
- package/dist/hitl/parkResolver.js +8 -54
- package/dist/hitl/parkRowBirthWait.d.ts +1 -0
- package/dist/hitl/parkRowBirthWait.js +2 -2
- package/dist/hitl/planReviewWire.d.ts +1 -0
- package/dist/hitl/planReviewWire.js +98 -20
- package/dist/hitl/replayedApproval.d.ts +1 -0
- package/dist/hitl/replayedApproval.js +14 -0
- package/dist/hitl/sessionPolicyDeliverable.js +8 -6
- package/dist/hitl/standingRows.d.ts +18 -0
- package/dist/hitl/standingRows.js +127 -0
- package/dist/hitl/toolApprovalWire.d.ts +15 -3
- package/dist/hitl/toolApprovalWire.js +238 -25
- package/dist/hookMatcherVerdict.d.ts +1 -9
- package/dist/hookMatcherVerdict.js +21 -61
- package/dist/hooksWireCaps.js +2 -2
- package/dist/hostCallbackGuard.d.ts +1 -0
- package/dist/hostCallbackGuard.js +6 -0
- package/dist/index.d.ts +21 -9
- package/dist/index.js +17 -8
- package/dist/mcpProbeCapability.d.ts +0 -4
- package/dist/mcpProbeCapability.js +0 -6
- package/dist/memoryComplianceCapability.d.ts +0 -4
- package/dist/memoryComplianceCapability.js +0 -6
- package/dist/memoryOriginCapability.d.ts +0 -4
- package/dist/memoryOriginCapability.js +0 -6
- package/dist/memorySpecWire.js +2 -2
- package/dist/modelIdentityResolvability.d.ts +2 -2
- package/dist/modelIdentityResolvability.js +12 -3
- package/dist/noticePresentation.d.ts +68 -0
- package/dist/noticePresentation.js +247 -0
- package/dist/outputStyleSeatCapability.d.ts +0 -1
- package/dist/outputStyleSeatCapability.js +0 -3
- package/dist/ownKey.d.ts +2 -0
- package/dist/ownKey.js +18 -0
- package/dist/peerFrames.js +13 -9
- package/dist/permissionModesCapability.d.ts +0 -4
- package/dist/permissionModesCapability.js +0 -6
- package/dist/permissionRuleIssue.js +0 -3
- package/dist/permissionsDeclaration.d.ts +2 -0
- package/dist/permissionsDeclaration.js +56 -41
- package/dist/printPermissionOutcome.d.ts +12 -0
- package/dist/printPermissionOutcome.js +50 -0
- package/dist/printToolResultFrame.d.ts +1 -0
- package/dist/printToolResultFrame.js +5 -9
- package/dist/promptBlockedCopy.d.ts +5 -0
- package/dist/promptBlockedCopy.js +35 -0
- package/dist/protocolSegment.d.ts +9 -6
- package/dist/protocolSegment.js +31 -21
- package/dist/providerRejection.d.ts +4 -0
- package/dist/providerRejection.js +75 -14
- package/dist/replayBody.d.ts +12 -0
- package/dist/replayBody.js +25 -0
- package/dist/resumeRefusalCopy.js +5 -21
- package/dist/retryStatus.d.ts +9 -1
- package/dist/retryStatus.js +9 -2
- package/dist/rewindArchiveCapability.d.ts +3 -13
- package/dist/rewindArchiveCapability.js +7 -58
- package/dist/rewindArchiveReading.d.ts +15 -0
- package/dist/rewindArchiveReading.js +56 -0
- package/dist/ruleCompileVerdict.d.ts +9 -1
- package/dist/ruleCompileVerdict.js +29 -4
- package/dist/runTerminal.d.ts +15 -1
- package/dist/runTerminal.js +56 -8
- package/dist/sandboxWire.js +13 -0
- package/dist/sealedKeyCapability.d.ts +0 -4
- package/dist/sealedKeyCapability.js +0 -6
- package/dist/seam.js +4 -2
- package/dist/seatContract.d.ts +73 -11
- package/dist/seatContract.js +195 -14
- package/dist/sessionReadRedactionCapability.d.ts +0 -4
- package/dist/sessionReadRedactionCapability.js +0 -6
- package/dist/sessionSyncFileHistory.d.ts +4 -0
- package/dist/sessionSyncFileHistory.js +66 -0
- package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
- package/dist/sessionSyncFileHistoryCapability.js +0 -3
- package/dist/skillToolListsCapability.d.ts +0 -1
- package/dist/skillToolListsCapability.js +0 -3
- package/dist/steerPriorityCapability.d.ts +0 -1
- package/dist/steerPriorityCapability.js +0 -3
- package/dist/storePostureCapability.d.ts +0 -4
- package/dist/storePostureCapability.js +0 -6
- package/dist/subagent/engineSubagentSteer.js +7 -5
- package/dist/subagentContentStore.js +4 -15
- package/dist/supportFloor.d.ts +1 -0
- package/dist/supportFloor.js +13 -9
- package/dist/systemReminderTag.d.ts +1 -0
- package/dist/systemReminderTag.js +8 -0
- package/dist/toolHistoryMismatch.d.ts +0 -3
- package/dist/toolHistoryMismatch.js +3 -7
- package/dist/toolResult.d.ts +1 -1
- package/dist/toolResult.js +2 -1
- package/dist/toolResultContent.d.ts +2 -0
- package/dist/toolResultContent.js +63 -0
- package/dist/usageAnalytics.js +40 -16
- package/dist/userInvokedSkillsCapability.d.ts +0 -1
- package/dist/userInvokedSkillsCapability.js +0 -3
- package/dist/wireErrorTriage.d.ts +2 -0
- package/dist/wireErrorTriage.js +34 -5
- package/dist/wireFailureShape.d.ts +19 -2
- package/dist/wireFailureShape.js +55 -50
- package/docs/INTEGRATION-CLIENTS.md +1262 -17
- package/package.json +5 -5
package/dist/seatContract.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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 { ownDataField, ownDataRefusalKeyOf, ownSendableField } from "./ownKey.js";
|
|
4
|
+
import { guardedRead, ownDataField, ownDataRefusalKeyOf, ownSendableField, readOwnDataValue } from "./ownKey.js";
|
|
5
5
|
const bad = (reason, field) => field === undefined ? { reason } : { reason, field };
|
|
6
6
|
const nested = (prefix, verdict) => {
|
|
7
7
|
const path = verdict.field === undefined
|
|
@@ -13,8 +13,15 @@ const nested = (prefix, verdict) => {
|
|
|
13
13
|
return bad(reason, path);
|
|
14
14
|
};
|
|
15
15
|
const isObject = (v) => typeof v === "object" && v !== null;
|
|
16
|
+
const isPlainRecord = (v) => {
|
|
17
|
+
if (!isObject(v) || Array.isArray(v))
|
|
18
|
+
return false;
|
|
19
|
+
const proto = Object.getPrototypeOf(v);
|
|
20
|
+
return proto === Object.prototype || proto === null;
|
|
21
|
+
};
|
|
16
22
|
const isAbsent = (v) => typeof v === "undefined";
|
|
17
23
|
const optionalString = (v) => isAbsent(v) || typeof v === "string";
|
|
24
|
+
const isFolderPath = (v) => typeof v === "string" && v.length > 0;
|
|
18
25
|
const inTuple = (tuple, v) => tuple.includes(v);
|
|
19
26
|
const own = (o, k) => ownSendableField(o, k);
|
|
20
27
|
const ownItems = (a) => {
|
|
@@ -112,14 +119,16 @@ const SEAT_EVENT_TYPE_TUPLE = [
|
|
|
112
119
|
"error",
|
|
113
120
|
"tool_permission_resolved",
|
|
114
121
|
];
|
|
115
|
-
export const SEAT_EVENT_TYPES = SEAT_EVENT_TYPE_TUPLE;
|
|
122
|
+
export const SEAT_EVENT_TYPES = Object.freeze(SEAT_EVENT_TYPE_TUPLE);
|
|
116
123
|
const CHROME_EVENT_KIND_TUPLE = [
|
|
117
124
|
"panel_task",
|
|
118
125
|
"notification_terminal",
|
|
119
126
|
"prompt_suggestions",
|
|
120
127
|
"subagent_lifecycle",
|
|
128
|
+
"text_segment_end",
|
|
129
|
+
"thinking_segment_end",
|
|
121
130
|
];
|
|
122
|
-
export const CHROME_EVENT_KINDS = CHROME_EVENT_KIND_TUPLE;
|
|
131
|
+
export const CHROME_EVENT_KINDS = Object.freeze(CHROME_EVENT_KIND_TUPLE);
|
|
123
132
|
const LANE_PROOF_LANE_TUPLE = ["main", "subagent", "workflow"];
|
|
124
133
|
export const SEAT_CHROME_ENVELOPE_KEYS = ["kind", "laneProof"];
|
|
125
134
|
export const HITL_RESOLUTION_OUTCOMES = [
|
|
@@ -132,7 +141,7 @@ export const HITL_RESOLUTION_OUTCOMES = [
|
|
|
132
141
|
"decline",
|
|
133
142
|
"cancel",
|
|
134
143
|
];
|
|
135
|
-
export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind"]);
|
|
144
|
+
export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession"]);
|
|
136
145
|
const notReported = () => Object.freeze({ kind: "not_reported" });
|
|
137
146
|
const malformedReading = () => Object.freeze({ kind: "malformed" });
|
|
138
147
|
const reported = (available) => Object.freeze({ kind: "reported", available });
|
|
@@ -206,6 +215,7 @@ export function watchSeatCapability(store, name, onReading) {
|
|
|
206
215
|
const SEAT_CAPABILITY_PHRASES = Object.freeze({
|
|
207
216
|
pickFolder: Object.freeze({ action: "Opening a folder", ability: "show a folder picker", support: "folder picker support" }),
|
|
208
217
|
rewind: Object.freeze({ action: "Rewinding to an earlier message", ability: "rewind this session", support: "rewind support" }),
|
|
218
|
+
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" }),
|
|
209
219
|
});
|
|
210
220
|
export function seatCapabilityUnavailableDetail(name, reading) {
|
|
211
221
|
const phrase = Object.hasOwn(SEAT_CAPABILITY_PHRASES, name)
|
|
@@ -228,6 +238,96 @@ export function seatCapabilityUnavailableDetail(name, reading) {
|
|
|
228
238
|
return `${phrase.action} isn't available: this app hasn't reported ${phrase.support}.`;
|
|
229
239
|
return `${phrase.action} isn't available: this app's support report couldn't be read.`;
|
|
230
240
|
}
|
|
241
|
+
const NO_TIME = Number.NEGATIVE_INFINITY;
|
|
242
|
+
const stampMs = (v) => {
|
|
243
|
+
if (typeof v !== "string")
|
|
244
|
+
return NO_TIME;
|
|
245
|
+
const t = Date.parse(v);
|
|
246
|
+
return Number.isFinite(t) ? t : NO_TIME;
|
|
247
|
+
};
|
|
248
|
+
const softField = (o, key) => typeof o === "object" && o !== null ? guardedRead(() => readOwnDataValue(o, key)) : undefined;
|
|
249
|
+
const softItems = (a) => {
|
|
250
|
+
const isArray = guardedRead(() => Array.isArray(a));
|
|
251
|
+
if (isArray !== true)
|
|
252
|
+
return undefined;
|
|
253
|
+
const n = softField(a, "length");
|
|
254
|
+
if (typeof n !== "number" || !Number.isSafeInteger(n) || n < 0)
|
|
255
|
+
return undefined;
|
|
256
|
+
const out = [];
|
|
257
|
+
for (let i = 0; i < n; i += 1)
|
|
258
|
+
out.push(softField(a, String(i)));
|
|
259
|
+
return out;
|
|
260
|
+
};
|
|
261
|
+
export function recentFoldersOf(input) {
|
|
262
|
+
const sessions = softItems(softField(input, "sessions"));
|
|
263
|
+
const registered = softItems(softField(input, "registered"));
|
|
264
|
+
if (sessions === undefined && registered === undefined)
|
|
265
|
+
return null;
|
|
266
|
+
const byPath = new Map();
|
|
267
|
+
let order = 0;
|
|
268
|
+
const place = (path, at) => {
|
|
269
|
+
const cur = byPath.get(path);
|
|
270
|
+
order += 1;
|
|
271
|
+
if (cur === undefined)
|
|
272
|
+
byPath.set(path, { at, order });
|
|
273
|
+
else if (at > cur.at)
|
|
274
|
+
cur.at = at;
|
|
275
|
+
};
|
|
276
|
+
for (const row of registered ?? []) {
|
|
277
|
+
const path = softField(row, "path");
|
|
278
|
+
if (isFolderPath(path))
|
|
279
|
+
place(path, stampMs(softField(row, "lastUsedAt")));
|
|
280
|
+
}
|
|
281
|
+
for (const rec of sessions ?? []) {
|
|
282
|
+
const cwd = softField(rec, "cwd");
|
|
283
|
+
if (!isFolderPath(cwd))
|
|
284
|
+
continue;
|
|
285
|
+
const active = stampMs(softField(rec, "lastActivityAt"));
|
|
286
|
+
place(cwd, active !== NO_TIME ? active : stampMs(softField(rec, "createdAt")));
|
|
287
|
+
}
|
|
288
|
+
return [...byPath.entries()]
|
|
289
|
+
.sort(([, x], [, y]) => (x.at === y.at ? x.order - y.order : x.at > y.at ? -1 : 1))
|
|
290
|
+
.map(([path]) => path);
|
|
291
|
+
}
|
|
292
|
+
export async function readRecentFolders(input) {
|
|
293
|
+
const capability = guardedRead(() => input.capability);
|
|
294
|
+
const list = guardedRead(() => input.list);
|
|
295
|
+
const sessions = guardedRead(() => input.sessions);
|
|
296
|
+
let registered;
|
|
297
|
+
let host = "skipped";
|
|
298
|
+
let unreadableRows = 0;
|
|
299
|
+
if (capability !== undefined && seatCapabilityUnavailableDetail("recents", capability) === undefined) {
|
|
300
|
+
try {
|
|
301
|
+
const items = softItems(softField(await list(), "folders"));
|
|
302
|
+
if (items === undefined) {
|
|
303
|
+
host = "unreadable";
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
const rows = [];
|
|
307
|
+
for (const item of items) {
|
|
308
|
+
const path = softField(item, "path");
|
|
309
|
+
if (!isFolderPath(path)) {
|
|
310
|
+
unreadableRows += 1;
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
const lastUsedAt = softField(item, "lastUsedAt");
|
|
314
|
+
rows.push(typeof lastUsedAt === "string" ? { path, lastUsedAt } : { path });
|
|
315
|
+
}
|
|
316
|
+
if (items.length > 0 && rows.length === 0) {
|
|
317
|
+
host = "unreadable";
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
registered = rows;
|
|
321
|
+
host = "listed";
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
host = "unreadable";
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return Object.freeze({ folders: recentFoldersOf({ sessions, registered }), host, unreadableRows });
|
|
330
|
+
}
|
|
231
331
|
export const PERMISSION_MODE_INTENTS = [...PERMISSION_MODE_WORDS];
|
|
232
332
|
export const ATTACHMENT_IDS_PER_TASK_CAP = 16;
|
|
233
333
|
export const SEAT_REASONING_EFFORTS = [...REASONING_EFFORT_WORDS];
|
|
@@ -241,6 +341,7 @@ export const SEAT_TURN_SETTINGS_ORIGINS = Object.freeze({
|
|
|
241
341
|
});
|
|
242
342
|
export const SEAT_REWIND_INTENT_KEYS = ["mode", "targetMessageUuid"];
|
|
243
343
|
export const ATTACHMENT_UPLOAD_REQUEST_KEYS = ["name", "mimeType", "bytes"];
|
|
344
|
+
export const SESSION_ROW_PATCH_REQUEST_KEYS = Object.freeze(["sessionId", "title", "pinned"]);
|
|
244
345
|
export const SESSION_SEARCH_RESULT_KEYS = ["sessionId", "title", "matches"];
|
|
245
346
|
export const GET_TRANSCRIPT_RESULT_KEYS = ["sessionId", "messages"];
|
|
246
347
|
const checkLocalSessionRecord = seatCheck((s) => {
|
|
@@ -255,7 +356,7 @@ const checkLocalSessionRecord = seatCheck((s) => {
|
|
|
255
356
|
if (!optionalString(own(s, "title")))
|
|
256
357
|
return bad("title must be a string when present", "title");
|
|
257
358
|
const cwd = own(s, "cwd");
|
|
258
|
-
if (!isAbsent(cwd) && (
|
|
359
|
+
if (!isAbsent(cwd) && !isFolderPath(cwd)) {
|
|
259
360
|
return bad("cwd must be a non-empty path string when present (absent = no folder chosen)", "cwd");
|
|
260
361
|
}
|
|
261
362
|
if (typeof own(s, "isRunning") !== "boolean")
|
|
@@ -274,6 +375,10 @@ const checkLocalSessionRecord = seatCheck((s) => {
|
|
|
274
375
|
if (!isAbsent(parked) && typeof parked !== "boolean") {
|
|
275
376
|
return bad("parked must be a boolean when present", "parked");
|
|
276
377
|
}
|
|
378
|
+
const pinned = own(s, "pinned");
|
|
379
|
+
if (!isAbsent(pinned) && typeof pinned !== "boolean") {
|
|
380
|
+
return bad("pinned must be a boolean when present (absent = not pinned or unknown)", "pinned");
|
|
381
|
+
}
|
|
277
382
|
return true;
|
|
278
383
|
});
|
|
279
384
|
export function isLocalSessionRecord(s) {
|
|
@@ -597,6 +702,30 @@ export function checkSendMessageRequest(v) {
|
|
|
597
702
|
export function isSendMessageRequest(v) {
|
|
598
703
|
return checkSendMessageRequest(v) === true;
|
|
599
704
|
}
|
|
705
|
+
export const checkSessionRowPatchRequest = seatCheck((v) => {
|
|
706
|
+
if (!isObject(v) || Array.isArray(v))
|
|
707
|
+
return bad("patchSession request is not an object");
|
|
708
|
+
const body = {};
|
|
709
|
+
for (const k of Object.keys(v)) {
|
|
710
|
+
if (!inTuple(SESSION_ROW_PATCH_REQUEST_KEYS, k))
|
|
711
|
+
return bad(`unknown key (closed shape: ${SESSION_ROW_PATCH_REQUEST_KEYS.join(", ")})`, k);
|
|
712
|
+
body[k] = own(v, k);
|
|
713
|
+
}
|
|
714
|
+
if (typeof body.sessionId !== "string" || body.sessionId.length === 0)
|
|
715
|
+
return bad("sessionId must be a non-empty string", "sessionId");
|
|
716
|
+
const { title, pinned } = body;
|
|
717
|
+
if (!isAbsent(title) && title !== null && (typeof title !== "string" || title.length === 0)) {
|
|
718
|
+
return bad('title must be a non-empty string, or null to clear it back to the automatic title (an empty string is not a way to clear)', "title");
|
|
719
|
+
}
|
|
720
|
+
if (!isAbsent(pinned) && typeof pinned !== "boolean")
|
|
721
|
+
return bad("pinned must be a boolean when present", "pinned");
|
|
722
|
+
if (isAbsent(title) && isAbsent(pinned))
|
|
723
|
+
return bad("nothing to change: carry at least one of title / pinned");
|
|
724
|
+
return true;
|
|
725
|
+
});
|
|
726
|
+
export function isSessionRowPatchRequest(v) {
|
|
727
|
+
return checkSessionRowPatchRequest(v) === true;
|
|
728
|
+
}
|
|
600
729
|
const checkSendMessageAck = seatCheck((v) => {
|
|
601
730
|
if (!isObject(v))
|
|
602
731
|
return bad("sendMessage ack is not an object");
|
|
@@ -678,11 +807,10 @@ const checkFocusedSessionState = seatCheck((v) => {
|
|
|
678
807
|
return true;
|
|
679
808
|
});
|
|
680
809
|
const checkSettingsState = seatCheck((v) => {
|
|
681
|
-
if (!
|
|
682
|
-
return bad("settings state is not
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
return bad("defaultModel must be a string or null", "defaultModel");
|
|
810
|
+
if (!isPlainRecord(v))
|
|
811
|
+
return bad("settings state is not a plain object");
|
|
812
|
+
if (Object.hasOwn(v, "defaultModel")) {
|
|
813
|
+
return bad("defaultModel is not carried in settings state: read the deployment default model from the model catalog (liveDefaultModelOf over the listModels() result)", "defaultModel");
|
|
686
814
|
}
|
|
687
815
|
if (!optionalString(own(v, "engineVersion")))
|
|
688
816
|
return bad("engineVersion must be a string when present", "engineVersion");
|
|
@@ -690,9 +818,32 @@ const checkSettingsState = seatCheck((v) => {
|
|
|
690
818
|
return bad("dataRoot must be a string when present", "dataRoot");
|
|
691
819
|
return true;
|
|
692
820
|
});
|
|
693
|
-
const checkPickFolderResult = (v) => v === null || (
|
|
821
|
+
const checkPickFolderResult = (v) => v === null || isFolderPath(v)
|
|
694
822
|
? true
|
|
695
823
|
: bad("pickFolder result must be null (cancelled) or a non-empty path string");
|
|
824
|
+
const checkRecentFolderRow = seatCheck((v) => {
|
|
825
|
+
if (!isPlainRecord(v))
|
|
826
|
+
return bad("recent folder row is not a plain object");
|
|
827
|
+
if (!isFolderPath(own(v, "path")))
|
|
828
|
+
return bad("path must be a non-empty path string", "path");
|
|
829
|
+
if (!optionalString(own(v, "lastUsedAt")))
|
|
830
|
+
return bad("lastUsedAt must be a string when present", "lastUsedAt");
|
|
831
|
+
return true;
|
|
832
|
+
});
|
|
833
|
+
const checkRecentFoldersResult = seatCheck((v) => {
|
|
834
|
+
if (!isPlainRecord(v))
|
|
835
|
+
return bad("recent folders result is not a plain object");
|
|
836
|
+
const folders = own(v, "folders");
|
|
837
|
+
if (!Array.isArray(folders))
|
|
838
|
+
return bad("folders must be an array", "folders");
|
|
839
|
+
const rows = ownItems(folders);
|
|
840
|
+
for (let i = 0; i < rows.length; i += 1) {
|
|
841
|
+
const verdict = checkRecentFolderRow(rows[i]);
|
|
842
|
+
if (verdict !== true)
|
|
843
|
+
return nested(`folders[${i}]`, verdict);
|
|
844
|
+
}
|
|
845
|
+
return true;
|
|
846
|
+
});
|
|
696
847
|
const checkSeatCapabilitiesState = seatCheck((v) => {
|
|
697
848
|
if (!isObject(v) || Array.isArray(v))
|
|
698
849
|
return bad("seat capabilities state is not an object");
|
|
@@ -730,6 +881,8 @@ export const LOCAL_SESSIONS_SPEC = {
|
|
|
730
881
|
listModels: { kind: "invoke", check: checkLiveModelCatalog },
|
|
731
882
|
applyModelConfig: { kind: "invoke", check: checkApplyModelConfigResult },
|
|
732
883
|
pickFolder: { kind: "invoke", check: checkPickFolderResult },
|
|
884
|
+
listRecentFolders: { kind: "invoke", check: checkRecentFoldersResult },
|
|
885
|
+
noteRecentFolder: { kind: "invoke", check: checkOkAck }, patchSession: { kind: "invoke", check: checkLocalSessionRecord },
|
|
733
886
|
onEvent: { kind: "event", check: checkLocalSessionEvent },
|
|
734
887
|
onToolPermissionRequest: { kind: "event", check: checkToolPermissionRequest },
|
|
735
888
|
},
|
|
@@ -757,6 +910,8 @@ export const SEAT_METHOD_NAMES = [
|
|
|
757
910
|
"listModels",
|
|
758
911
|
"applyModelConfig",
|
|
759
912
|
"pickFolder",
|
|
913
|
+
"listRecentFolders",
|
|
914
|
+
"noteRecentFolder", "patchSession",
|
|
760
915
|
"onEvent",
|
|
761
916
|
"onToolPermissionRequest",
|
|
762
917
|
];
|
|
@@ -804,6 +959,7 @@ export const TOOL_PERMISSION_REQUEST_KEYS = [
|
|
|
804
959
|
"ruleOffersAbsence",
|
|
805
960
|
"askClass",
|
|
806
961
|
"classes",
|
|
962
|
+
"rememberRefused",
|
|
807
963
|
];
|
|
808
964
|
export const LOCAL_SESSION_RECORD_KEYS = [
|
|
809
965
|
"sessionId",
|
|
@@ -816,6 +972,7 @@ export const LOCAL_SESSION_RECORD_KEYS = [
|
|
|
816
972
|
"lastActivityAt",
|
|
817
973
|
"queuedMessages",
|
|
818
974
|
"parked",
|
|
975
|
+
"pinned",
|
|
819
976
|
];
|
|
820
977
|
export const SEND_MESSAGE_REQUEST_KEYS = [
|
|
821
978
|
"sessionId",
|
|
@@ -860,7 +1017,7 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
|
|
|
860
1017
|
LocalSessionRecord: {
|
|
861
1018
|
guard: "isLocalSessionRecord",
|
|
862
1019
|
check: checkLocalSessionRecord,
|
|
863
|
-
validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked"],
|
|
1020
|
+
validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned"],
|
|
864
1021
|
unchecked: [],
|
|
865
1022
|
},
|
|
866
1023
|
ToolPermissionRequest: {
|
|
@@ -900,6 +1057,10 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
|
|
|
900
1057
|
key: "classes",
|
|
901
1058
|
why: "与 askClass 同一对(CC-284),同在同缺、同一只成对窄读(非空、每员非空串、无重复、首员等于 askClass;开集、原样顺序);座位门不设第二判官,理由同 askClass。",
|
|
902
1059
|
},
|
|
1060
|
+
{
|
|
1061
|
+
key: "rememberRefused",
|
|
1062
|
+
why: "展示增强位(CC-642),权威窄读在卡口两条腿与过境口 toolPermissionRequestAskBits(同一只 readApprovalRememberRefused:自有键 ∧ 严格 true 才上座,永不铸 false);座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。消费端 `=== true` 读,其余(缺席 / 坏形)一律当缺席 ⇒ 照旧渲「本会话放行」。缺席 = 服务端没说(记得住或老服务端),不是 false。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
|
|
1063
|
+
},
|
|
903
1064
|
{
|
|
904
1065
|
key: "ruleOffersAbsence",
|
|
905
1066
|
why: "喂强制判据口 approvalIsMandated 的位(CC-203;寄存行那条腿的强制只以缺席词 mandated 表达),按开集读(非空串原文字节、词表不校);权威窄读在卡口与过境口,座位门不设第二判官,理由同 mandated。坏形读成缺席 ⇒ 这一路不判强制(放宽方向:寄存行上的强制就丢了;另两路 mandated / mandate 照判);表外串只是不等于 mandated。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
|
|
@@ -971,6 +1132,12 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
|
|
|
971
1132
|
],
|
|
972
1133
|
unchecked: [],
|
|
973
1134
|
},
|
|
1135
|
+
SessionRowPatchRequest: {
|
|
1136
|
+
guard: "isSessionRowPatchRequest",
|
|
1137
|
+
check: checkSessionRowPatchRequest,
|
|
1138
|
+
validated: ["sessionId", "title", "pinned"],
|
|
1139
|
+
unchecked: [],
|
|
1140
|
+
},
|
|
974
1141
|
ApplyModelConfigResult: {
|
|
975
1142
|
check: checkApplyModelConfigResult,
|
|
976
1143
|
validated: ["ok", "requiresRestart", "reason"],
|
|
@@ -1019,12 +1186,22 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
|
|
|
1019
1186
|
},
|
|
1020
1187
|
SettingsState: {
|
|
1021
1188
|
check: checkSettingsState,
|
|
1022
|
-
validated: ["
|
|
1189
|
+
validated: ["engineVersion", "dataRoot"],
|
|
1023
1190
|
unchecked: [],
|
|
1024
1191
|
},
|
|
1025
1192
|
SeatCapabilitiesState: {
|
|
1026
1193
|
check: checkSeatCapabilitiesState,
|
|
1027
|
-
validated: ["pickFolder", "rewind"],
|
|
1194
|
+
validated: ["pickFolder", "rewind", "recents", "patchSession"],
|
|
1195
|
+
unchecked: [],
|
|
1196
|
+
},
|
|
1197
|
+
RecentFoldersResult: {
|
|
1198
|
+
check: checkRecentFoldersResult,
|
|
1199
|
+
validated: ["folders"],
|
|
1200
|
+
unchecked: [],
|
|
1201
|
+
},
|
|
1202
|
+
RecentFolderRow: {
|
|
1203
|
+
check: checkRecentFolderRow,
|
|
1204
|
+
validated: ["path", "lastUsedAt"],
|
|
1028
1205
|
unchecked: [],
|
|
1029
1206
|
},
|
|
1030
1207
|
SeatRewindIntent: {
|
|
@@ -1087,5 +1264,9 @@ const _seatContractPins = [
|
|
|
1087
1264
|
true, true, true, true, true, true, true, true,
|
|
1088
1265
|
true, true, true, true, true,
|
|
1089
1266
|
true, true, true, true, true, true, true, true,
|
|
1267
|
+
true, true,
|
|
1268
|
+
true, true,
|
|
1269
|
+
true, true, true, true,
|
|
1270
|
+
true, true, true, true, true, true,
|
|
1090
1271
|
];
|
|
1091
1272
|
void _seatContractPins;
|
|
@@ -7,9 +7,5 @@ export type SessionReadRedactionReading = {
|
|
|
7
7
|
value: true;
|
|
8
8
|
};
|
|
9
9
|
export declare function projectSessionReadRedactionCapability(caps: unknown): SessionReadRedactionReading | undefined;
|
|
10
|
-
export declare function noteEngineCapsForSessionReadRedaction(baseUrl: string, caps: unknown, opts?: {
|
|
11
|
-
generation?: number;
|
|
12
|
-
}): void;
|
|
13
10
|
export declare function observedSessionReadRedaction(baseUrl?: string | undefined): SessionReadRedactionReading;
|
|
14
11
|
export declare function sessionReadRedactionAdmitted(reading: SessionReadRedactionReading | undefined): boolean;
|
|
15
|
-
export declare function __resetSessionReadRedactionReadingsForTests(): void;
|
|
@@ -19,9 +19,6 @@ const reader = createEngineCapReader({
|
|
|
19
19
|
project: projectSessionReadRedactionCapability,
|
|
20
20
|
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
21
21
|
});
|
|
22
|
-
export function noteEngineCapsForSessionReadRedaction(baseUrl, caps, opts) {
|
|
23
|
-
reader.note(baseUrl, caps, opts);
|
|
24
|
-
}
|
|
25
22
|
export function observedSessionReadRedaction(baseUrl = engineWireTarget()?.baseUrl) {
|
|
26
23
|
return reader.observed(baseUrl);
|
|
27
24
|
}
|
|
@@ -37,6 +34,3 @@ export function sessionReadRedactionAdmitted(reading) {
|
|
|
37
34
|
return false;
|
|
38
35
|
}
|
|
39
36
|
}
|
|
40
|
-
export function __resetSessionReadRedactionReadingsForTests() {
|
|
41
|
-
reader.__resetForTests();
|
|
42
|
-
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const FILE_HISTORY_SKIPPED_NOTICE: string;
|
|
2
|
+
export declare function fileHistorySyncNotice(result: unknown): string | undefined;
|
|
3
|
+
export declare function fileHistorySyncNoticeIdentity(result: unknown): string | undefined;
|
|
4
|
+
export declare function isFileHistoryBlobMissing(err: unknown): boolean;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { NOT_FOUND_BLOB } from './engineErrorCodes.js';
|
|
2
|
+
import { effectiveWireErrorCode } from './wireErrorTriage.js';
|
|
3
|
+
import { readThrownSlot } from './wireFailureShape.js';
|
|
4
|
+
export const FILE_HISTORY_SKIPPED_NOTICE = 'File history was not copied: only the conversation was synced, because one of the two engines does not confirm that it can ' +
|
|
5
|
+
'transfer file history (the record /rewind uses to restore files). Syncing this session again will not add it until ' +
|
|
6
|
+
'the conversation has new turns and both engines can transfer file history.';
|
|
7
|
+
function getOwn(o, key) {
|
|
8
|
+
return Object.hasOwn(o, key) ? o[key] : undefined;
|
|
9
|
+
}
|
|
10
|
+
function envelopeSaidEmpty(result) {
|
|
11
|
+
try {
|
|
12
|
+
const manifest = getOwn(result, 'manifest');
|
|
13
|
+
if (manifest === null || typeof manifest !== 'object')
|
|
14
|
+
return false;
|
|
15
|
+
const fh = getOwn(manifest, 'fileHistory');
|
|
16
|
+
if (fh === null || typeof fh !== 'object')
|
|
17
|
+
return false;
|
|
18
|
+
const tracked = getOwn(fh, 'tracked');
|
|
19
|
+
const boundaries = getOwn(fh, 'boundaries');
|
|
20
|
+
return Array.isArray(tracked) && tracked.length === 0 && Array.isArray(boundaries) && boundaries.length === 0;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function fileHistorySyncNotice(result) {
|
|
27
|
+
if (result === null || typeof result !== 'object')
|
|
28
|
+
return undefined;
|
|
29
|
+
try {
|
|
30
|
+
if (getOwn(result, 'fileHistory') !== 'skipped')
|
|
31
|
+
return undefined;
|
|
32
|
+
return envelopeSaidEmpty(result) ? undefined : FILE_HISTORY_SKIPPED_NOTICE;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function fileHistorySyncNoticeIdentity(result) {
|
|
39
|
+
if (fileHistorySyncNotice(result) === undefined)
|
|
40
|
+
return undefined;
|
|
41
|
+
try {
|
|
42
|
+
const manifest = getOwn(result, 'manifest');
|
|
43
|
+
if (manifest === null || typeof manifest !== 'object')
|
|
44
|
+
return undefined;
|
|
45
|
+
const sessionId = getOwn(manifest, 'sessionId');
|
|
46
|
+
const leafId = getOwn(manifest, 'leafId');
|
|
47
|
+
if (typeof sessionId !== 'string' || sessionId === '' || typeof leafId !== 'string' || leafId === '')
|
|
48
|
+
return undefined;
|
|
49
|
+
return JSON.stringify([sessionId, leafId]);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export function isFileHistoryBlobMissing(err) {
|
|
56
|
+
if (typeof err !== 'object' || err === null)
|
|
57
|
+
return false;
|
|
58
|
+
try {
|
|
59
|
+
if (readThrownSlot(err, 'status') !== 404)
|
|
60
|
+
return false;
|
|
61
|
+
return effectiveWireErrorCode(err) === NOT_FOUND_BLOB;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -14,4 +14,3 @@ export declare function noteEngineCapsForSessionSyncFileHistory(baseUrl: string,
|
|
|
14
14
|
export declare function observedSessionSyncFileHistory(baseUrl?: string | undefined): SessionSyncFileHistoryReading;
|
|
15
15
|
export declare function sessionSyncFileHistoryAvailable(reading: SessionSyncFileHistoryReading): 'yes' | 'no' | 'unknown';
|
|
16
16
|
export declare function sessionSyncFileHistoryDoctorDetail(reading: SessionSyncFileHistoryReading): string;
|
|
17
|
-
export declare function __resetSessionSyncFileHistoryReadingsForTests(): void;
|
|
@@ -46,6 +46,3 @@ export function sessionSyncFileHistoryDoctorDetail(reading) {
|
|
|
46
46
|
return 'session-sync file history on — syncing a session can also move its edited-file history';
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
export function __resetSessionSyncFileHistoryReadingsForTests() {
|
|
50
|
-
reader.__resetForTests();
|
|
51
|
-
}
|
|
@@ -14,4 +14,3 @@ export declare function noteEngineCapsForSkillToolLists(baseUrl: string, caps: u
|
|
|
14
14
|
export declare function observedSkillToolLists(baseUrl?: string | undefined): SkillToolListsReading;
|
|
15
15
|
export declare function skillToolListsAvailable(reading: SkillToolListsReading): 'yes' | 'no' | 'unknown';
|
|
16
16
|
export declare function skillToolListsDoctorDetail(reading: SkillToolListsReading): string;
|
|
17
|
-
export declare function __resetSkillToolListsReadingsForTests(): void;
|
|
@@ -46,6 +46,3 @@ export function skillToolListsDoctorDetail(reading) {
|
|
|
46
46
|
return 'skill tool lists on — a request skill’s allowed and disallowed tool lists are read as this run’s rules';
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
export function __resetSkillToolListsReadingsForTests() {
|
|
50
|
-
reader.__resetForTests();
|
|
51
|
-
}
|
|
@@ -14,4 +14,3 @@ export declare function noteEngineCapsForSteerPriority(baseUrl: string, caps: un
|
|
|
14
14
|
export declare function observedSteerPriority(baseUrl?: string | undefined): SteerPriorityReading;
|
|
15
15
|
export declare function steerPriorityMode(reading: SteerPriorityReading): SteerPriorityMode;
|
|
16
16
|
export declare function steerPriorityDoctorDetail(reading: SteerPriorityReading): string;
|
|
17
|
-
export declare function __resetSteerPriorityReadingsForTests(): void;
|
|
@@ -74,6 +74,3 @@ export function steerPriorityDoctorDetail(reading) {
|
|
|
74
74
|
}
|
|
75
75
|
return `steer priority reported as "${capForDisplay(word, WORD_DETAIL_MAX)}" — a value this client does not know yet, so whether it is applied is unknown and a "now" or "later" steer is not sent`;
|
|
76
76
|
}
|
|
77
|
-
export function __resetSteerPriorityReadingsForTests() {
|
|
78
|
-
reader.__resetForTests();
|
|
79
|
-
}
|
|
@@ -15,11 +15,7 @@ export type StorePostureReading = {
|
|
|
15
15
|
view: StorePostureView;
|
|
16
16
|
};
|
|
17
17
|
export declare function projectStorePostureCapability(caps: unknown): StorePostureReading | undefined;
|
|
18
|
-
export declare function noteEngineCapsForStorePosture(baseUrl: string, caps: unknown, opts?: {
|
|
19
|
-
generation?: number;
|
|
20
|
-
}): void;
|
|
21
18
|
export declare function observedStorePosture(baseUrl?: string | undefined): StorePostureReading;
|
|
22
19
|
export declare function storePersistence(reading: StorePostureReading): 'durable' | 'not_durable' | 'unknown';
|
|
23
20
|
export declare function storePostureHeadWord(reading: StorePostureReading): string | undefined;
|
|
24
21
|
export declare function storePostureDoctorDetail(reading: StorePostureReading): string;
|
|
25
|
-
export declare function __resetStorePostureReadingsForTests(): void;
|
|
@@ -46,9 +46,6 @@ const reader = createEngineCapReader({
|
|
|
46
46
|
project: projectStorePostureCapability,
|
|
47
47
|
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
48
48
|
});
|
|
49
|
-
export function noteEngineCapsForStorePosture(baseUrl, caps, opts) {
|
|
50
|
-
reader.note(baseUrl, caps, opts);
|
|
51
|
-
}
|
|
52
49
|
export function observedStorePosture(baseUrl = engineWireTarget()?.baseUrl) {
|
|
53
50
|
return reader.observed(baseUrl);
|
|
54
51
|
}
|
|
@@ -127,6 +124,3 @@ export function storePostureDoctorDetail(reading) {
|
|
|
127
124
|
}
|
|
128
125
|
return `${assembled} — ${lost} (degraded for a reason this client does not know yet: "${word(reason)}")`;
|
|
129
126
|
}
|
|
130
|
-
export function __resetStorePostureReadingsForTests() {
|
|
131
|
-
reader.__resetForTests();
|
|
132
|
-
}
|
|
@@ -5,6 +5,7 @@ import { resolveOwnerContext, resolveOwnerRunId } from './engineSubagentResume.j
|
|
|
5
5
|
import { noteBgOwnerAbsence } from './subagentOwnerAbsence.js';
|
|
6
6
|
import { errCodes, steeringRefusedBeforeEngine } from '../controlRouter.js';
|
|
7
7
|
import { ownNonEmptyStringOf } from '../steerReceipt.js';
|
|
8
|
+
import { wireFailureTextsOf } from '../wireFailureShape.js';
|
|
8
9
|
function usableSteerClient(client) {
|
|
9
10
|
return clientHasVerbs(client, [['runs', 'steerSubagent']]);
|
|
10
11
|
}
|
|
@@ -53,14 +54,14 @@ export async function steerEngineSubagent(target, text, childTaskId, opts) {
|
|
|
53
54
|
status = undefined;
|
|
54
55
|
}
|
|
55
56
|
if (status !== undefined) {
|
|
56
|
-
const
|
|
57
|
-
hostLog('debug', `engineSubagentSteer: ${status} ${
|
|
57
|
+
const texts = wireFailureTextsOf(e);
|
|
58
|
+
hostLog('debug', `engineSubagentSteer: ${status} ${texts.log.slice(0, 200)}`);
|
|
58
59
|
const refused = typeof e === 'object' && e !== null ? steeringRefusedBeforeEngine(e) : undefined;
|
|
59
60
|
if (refused !== undefined && refused.safety === 'ledger_unavailable') {
|
|
60
61
|
return { ok: false, reason: 'not-delivered', safety: refused.safety, detail: refused.advice };
|
|
61
62
|
}
|
|
62
63
|
if (status === 409 || status === 404) {
|
|
63
|
-
return { ok: false, reason: 'not-running', detail };
|
|
64
|
+
return { ok: false, reason: 'not-running', detail: texts.reason };
|
|
64
65
|
}
|
|
65
66
|
return { ok: false, reason: 'error', detail: `${status}` };
|
|
66
67
|
}
|
|
@@ -69,7 +70,8 @@ export async function steerEngineSubagent(target, text, childTaskId, opts) {
|
|
|
69
70
|
hostLog('debug', `engineSubagentSteer: may have been received, no answer — ${noAnswer}`);
|
|
70
71
|
return { ok: false, reason: 'error', detail: noAnswer, unconfirmed: true };
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
const texts = wireFailureTextsOf(e);
|
|
74
|
+
hostLog('debug', `engineSubagentSteer: fetch failed ${texts.log}`);
|
|
75
|
+
return { ok: false, reason: 'error', detail: texts.reason };
|
|
74
76
|
}
|
|
75
77
|
}
|
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
import { DEFAULT_SESSION_KEY } from './sessionSlot.js';
|
|
2
|
+
import { toolEndOutputText } from './toolResultContent.js';
|
|
2
3
|
export function coerceOutput(v) {
|
|
3
4
|
if (v === undefined || v === null)
|
|
4
5
|
return undefined;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const parts = [];
|
|
9
|
-
for (const block of v) {
|
|
10
|
-
if (block && typeof block === 'object') {
|
|
11
|
-
const b = block;
|
|
12
|
-
if (b.type === 'text' && typeof b.text === 'string')
|
|
13
|
-
parts.push(b.text);
|
|
14
|
-
else if (b.type === 'image')
|
|
15
|
-
parts.push('[image]');
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return parts.join('');
|
|
19
|
-
}
|
|
6
|
+
const text = toolEndOutputText(v);
|
|
7
|
+
if (text !== undefined)
|
|
8
|
+
return text;
|
|
20
9
|
try {
|
|
21
10
|
return JSON.stringify(v);
|
|
22
11
|
}
|
package/dist/supportFloor.d.ts
CHANGED
|
@@ -8,4 +8,5 @@ export declare const SUPPORT_FLOOR: Readonly<SupportFloor>;
|
|
|
8
8
|
export declare function supportFloorOf(component: unknown): string | undefined;
|
|
9
9
|
export type EngineVersionTier = 'engine' | 'legacy' | 'unknown';
|
|
10
10
|
export declare function engineVersionTier(version: unknown, floor?: string): EngineVersionTier;
|
|
11
|
+
export declare function engineSupportFloorEffective(floor?: string): string;
|
|
11
12
|
export declare function coreVersionTier(version: unknown, floor?: string): EngineVersionTier;
|