@sema-agent/client-core 0.108.0 → 0.110.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 +294 -0
- package/README.md +77 -40
- package/dist/adapt/arms.js +41 -13
- package/dist/adapt/textStream.d.ts +2 -0
- package/dist/adapt/textStream.js +37 -16
- package/dist/adapter/activeRunSelfHeal.js +1 -1
- package/dist/adapter/downstream/eventToSdkMessage.js +11 -5
- package/dist/agentSession/engineAgentRegistryRead.js +2 -0
- package/dist/bashExitReading.d.ts +12 -0
- package/dist/bashExitReading.js +44 -0
- package/dist/checkpointRowVerdict.d.ts +1 -1
- package/dist/checkpointRowVerdict.js +4 -2
- package/dist/compensations.js +1 -1
- package/dist/declared/supportFloorDeclared.js +1 -1
- package/dist/displayUntrusted.js +132 -14
- package/dist/engineAgentAbsence.d.ts +2 -0
- package/dist/engineAgentAbsence.js +28 -0
- package/dist/engineErrorCodes.d.ts +7 -0
- package/dist/engineErrorCodes.js +7 -0
- package/dist/engineHealthFacts.d.ts +26 -0
- package/dist/engineHealthFacts.js +63 -4
- package/dist/engineInlineTaskStats.d.ts +4 -3
- package/dist/engineInlineTaskStats.js +18 -2
- package/dist/engineNoticeCodes.d.ts +138 -0
- package/dist/engineNoticeCodes.js +662 -55
- package/dist/engineRepoint.d.ts +140 -0
- package/dist/engineRepoint.js +285 -0
- package/dist/engineRowRef.js +2 -0
- package/dist/engineSessionMessages.d.ts +2 -1
- package/dist/engineSessionMessages.js +5 -0
- package/dist/errorSupplementRoles.js +5 -1
- package/dist/fleet/fleetProjection.js +3 -2
- package/dist/fleetTaskDesc.js +3 -3
- package/dist/generated/engineFactTables.d.ts +3 -0
- package/dist/generated/engineFactTables.js +18 -0
- package/dist/generated/engineNoticeTables.js +3 -0
- package/dist/generated/sdkFactTables.d.ts +1 -0
- package/dist/generated/sdkFactTables.js +4 -0
- package/dist/hitl/approvalAskers.d.ts +6 -0
- package/dist/hitl/approvalAskers.js +30 -0
- package/dist/hitl/approvalCardReasons.js +25 -4
- package/dist/hitl/approvalRequestFrameReading.d.ts +21 -0
- package/dist/hitl/approvalRequestFrameReading.js +90 -0
- package/dist/hitl/approvalResolution.d.ts +8 -1
- package/dist/hitl/approvalResolution.js +4 -0
- package/dist/hitl/approvalsFeed.js +1 -1
- package/dist/hitl/askGateWire.js +0 -2
- package/dist/hitl/askParkRowRouting.js +5 -2
- package/dist/hitl/automaticAnswerVerdict.d.ts +5 -2
- package/dist/hitl/automaticAnswerVerdict.js +18 -4
- package/dist/hitl/decisionConflict.d.ts +2 -1
- package/dist/hitl/decisionConflict.js +10 -4
- package/dist/hitl/decisionRefusal.js +1 -0
- package/dist/hitl/decisionSend.d.ts +3 -0
- package/dist/hitl/decisionSend.js +29 -11
- package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
- package/dist/hitl/editedApprovalAcceptance.js +26 -0
- package/dist/hitl/frameRouter.js +13 -19
- package/dist/hitl/gateLedger.d.ts +0 -4
- package/dist/hitl/gateLedger.js +0 -19
- package/dist/hitl/hitlBridge.d.ts +5 -0
- package/dist/hitl/hitlBridge.js +13 -9
- package/dist/hitl/hitlHostSurface.d.ts +1 -0
- package/dist/hitl/hitlHostSurface.js +7 -2
- package/dist/hitl/hostWithdrawal.d.ts +15 -0
- package/dist/hitl/hostWithdrawal.js +38 -0
- package/dist/hitl/livePendingAsk.js +17 -16
- package/dist/hitl/localAllowRule.js +2 -1
- package/dist/hitl/noAllowCause.d.ts +1 -1
- package/dist/hitl/noAllowCause.js +4 -2
- package/dist/hitl/parkExpiryJudgements.js +26 -1
- package/dist/hitl/parkOwnership.d.ts +2 -0
- package/dist/hitl/parkOwnership.js +48 -8
- package/dist/hitl/parkResolver.js +32 -16
- package/dist/hitl/parkedUnresumable.d.ts +13 -0
- package/dist/hitl/parkedUnresumable.js +80 -0
- package/dist/hitl/permissionRuleScope.d.ts +4 -0
- package/dist/hitl/permissionRuleScope.js +31 -0
- package/dist/hitl/persistedRulesWire.d.ts +2 -0
- package/dist/hitl/persistedRulesWire.js +13 -12
- package/dist/hitl/planReviewWire.js +14 -4
- package/dist/hitl/sessionAllowRoute.js +5 -4
- package/dist/hitl/sessionPolicyWire.js +6 -4
- package/dist/hitl/standingRows.d.ts +2 -5
- package/dist/hitl/standingRows.js +30 -15
- package/dist/hitl/toolApprovalWire.d.ts +42 -9
- package/dist/hitl/toolApprovalWire.js +267 -44
- package/dist/hooksWireCaps.js +35 -4
- package/dist/hostSettingsSource.js +2 -0
- package/dist/hostTurnSettings.d.ts +10 -4
- package/dist/hostTurnSettings.js +112 -5
- package/dist/i18n/messages.en.d.ts +251 -0
- package/dist/i18n/messages.en.js +254 -2
- package/dist/i18n/messages.zh.js +264 -2
- package/dist/index.d.ts +48 -12
- package/dist/index.js +29 -7
- package/dist/inheritEnvCapability.js +2 -0
- package/dist/inputAuthor.d.ts +16 -0
- package/dist/inputAuthor.js +44 -0
- package/dist/interruptRefusalNote.d.ts +2 -0
- package/dist/interruptRefusalNote.js +17 -0
- package/dist/liveModelCatalog.d.ts +2 -0
- package/dist/liveModelCatalog.js +21 -7
- package/dist/liveQuestionStore.d.ts +4 -1
- package/dist/liveQuestionStore.js +12 -3
- package/dist/localEngineJudge.d.ts +75 -0
- package/dist/localEngineJudge.js +242 -0
- package/dist/localEngineOccupancy.d.ts +88 -0
- package/dist/localEngineOccupancy.js +269 -0
- package/dist/localEngineSeatReading.d.ts +29 -0
- package/dist/localEngineSeatReading.js +294 -0
- package/dist/localEngineSpawn.d.ts +113 -0
- package/dist/localEngineSpawn.js +486 -0
- package/dist/localEngineStep.d.ts +286 -0
- package/dist/localEngineStep.js +1086 -0
- package/dist/localEngineStopLadder.d.ts +29 -0
- package/dist/localEngineStopLadder.js +139 -0
- package/dist/localEngineSwapCard.d.ts +43 -0
- package/dist/localEngineSwapCard.js +205 -0
- package/dist/localEngineTiming.d.ts +8 -0
- package/dist/localEngineTiming.js +8 -0
- package/dist/mcpEngineLeg.d.ts +3 -0
- package/dist/mcpEngineLeg.js +38 -1
- package/dist/mcpPanel.js +2 -0
- package/dist/mcpReconnect.d.ts +9 -1
- package/dist/mcpReconnect.js +132 -20
- package/dist/mcpWireCaps.js +2 -2
- package/dist/memoryEntriesWire.d.ts +1 -1
- package/dist/memoryEntriesWire.js +5 -0
- package/dist/modelCapabilityProbe.js +4 -3
- package/dist/modsFace.d.ts +8 -1
- package/dist/modsFace.js +27 -0
- package/dist/noticePresentation.d.ts +2 -0
- package/dist/noticePresentation.js +79 -1
- package/dist/notifications.d.ts +17 -6
- package/dist/notifications.js +67 -19
- package/dist/ownKey.d.ts +5 -0
- package/dist/ownKey.js +8 -1
- package/dist/peerFrames.d.ts +40 -2
- package/dist/peerFrames.js +158 -3
- package/dist/pluginHooksWire.d.ts +2 -1
- package/dist/pluginHooksWire.js +56 -1
- package/dist/replayBody.js +10 -2
- package/dist/request/taskRequest.d.ts +5 -0
- package/dist/request/taskRequest.js +138 -21
- package/dist/resumeRefusalCopy.d.ts +1 -3
- package/dist/resumeRefusalCopy.js +2 -1
- package/dist/retryStatus.d.ts +2 -2
- package/dist/retryStatus.js +2 -0
- package/dist/ruleReadings.js +1 -1
- package/dist/seam.d.ts +24 -2
- package/dist/seam.js +15 -2
- package/dist/seatContract.d.ts +125 -10
- package/dist/seatContract.js +373 -7
- package/dist/sessionBackground.js +4 -1
- package/dist/sessionBackgroundHandoff.js +2 -1
- package/dist/sessionEngine.d.ts +2 -0
- package/dist/sessionEngine.js +111 -0
- package/dist/sessionMemoryStatus.d.ts +2 -1
- package/dist/sessionSyncFileHistory.d.ts +4 -0
- package/dist/sessionSyncFileHistory.js +28 -0
- package/dist/sseIdleTriage.d.ts +13 -1
- package/dist/sseIdleTriage.js +24 -6
- package/dist/subagent/engineSubagentTail.js +6 -0
- package/dist/subagentContentStore.d.ts +12 -0
- package/dist/subagentContentStore.js +72 -11
- package/dist/terminalStatuses.d.ts +1 -0
- package/dist/terminalStatuses.js +4 -1
- package/dist/toolResult.js +18 -5
- package/dist/turnFailurePresentation.js +9 -2
- package/dist/typePins.d.ts +11 -0
- package/dist/usageAnalytics.d.ts +17 -0
- package/dist/usageAnalytics.js +44 -2
- package/dist/wireFailureShape.d.ts +22 -5
- package/dist/wireFailureShape.js +47 -26
- package/dist/wireRefusalCopy.d.ts +31 -1
- package/dist/wireRefusalCopy.js +167 -2
- package/docs/INTEGRATION-CLIENTS.md +3269 -21
- package/package.json +5 -5
package/dist/seatContract.js
CHANGED
|
@@ -10,6 +10,7 @@ import { MCP_LIVENESS_STATES } from "./mcpLiveness.js";
|
|
|
10
10
|
import { THINKING_LATCH_EVENTS, THINKING_LATCH_ROW_WORDS } from "./thinkingLatchWords.js";
|
|
11
11
|
import { EXECUTION_PLACEMENT_ROLES } from "./executionPlacementWords.js";
|
|
12
12
|
import { isSessionEngineView } from "./sessionEngine.js";
|
|
13
|
+
import { LOCAL_ENGINE_SWAP_CAUSES } from "./localEngineSwapCard.js";
|
|
13
14
|
const bad = (reason, field) => field === undefined ? { reason } : { reason, field };
|
|
14
15
|
const nested = (prefix, verdict) => {
|
|
15
16
|
const path = verdict.field === undefined
|
|
@@ -184,6 +185,21 @@ const R_INT0 = ruleOf("non-negative integer", (v) => typeof v === "number" && Nu
|
|
|
184
185
|
const R_INT1 = ruleOf("positive integer", (v) => typeof v === "number" && Number.isSafeInteger(v) && v > 0);
|
|
185
186
|
const SESSION_ENGINE_KIND_WORDS = Object.freeze(["local", "cloud"]);
|
|
186
187
|
const R_ENGINE_LANE = oneOfRule("engine lane", SESSION_ENGINE_KIND_WORDS);
|
|
188
|
+
const R_ROW_BAR = armsRule("row verdict", "kind", {
|
|
189
|
+
lacking: { code: reqF(R_NONEMPTY), reason: optF(R_NONEMPTY), requires: optF(arrayRule(R_NONEMPTY)), sentence: reqF(R_NONEMPTY) },
|
|
190
|
+
damaged: { code: reqF(R_NONEMPTY), reason: optF(R_NONEMPTY), requires: optF(arrayRule(R_NONEMPTY)), sentence: reqF(R_NONEMPTY) },
|
|
191
|
+
unknown: { word: reqF(R_NONEMPTY), sentence: optF(R_NONEMPTY) },
|
|
192
|
+
unreadable: {},
|
|
193
|
+
});
|
|
194
|
+
const PARKED_ROW_DEADLINE_WORDS = Object.freeze(["armed", "none"]);
|
|
195
|
+
const R_PARKED_ROW = shapeRule("parked row", {
|
|
196
|
+
rowVerdict: reqF(R_ROW_BAR),
|
|
197
|
+
rowKey: optF(R_NONEMPTY),
|
|
198
|
+
taskId: optF(R_NONEMPTY),
|
|
199
|
+
toolName: optF(R_NONEMPTY),
|
|
200
|
+
rowDeadline: optF(oneOfRule("deadline word", PARKED_ROW_DEADLINE_WORDS)),
|
|
201
|
+
});
|
|
202
|
+
const R_PARKED_UNRESUMABLE = arrayRule(R_PARKED_ROW, true);
|
|
187
203
|
const keyWords = (k) => k
|
|
188
204
|
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
189
205
|
.toLowerCase()
|
|
@@ -293,6 +309,8 @@ const CHROME_ARM_SEAT_ROUTE = {
|
|
|
293
309
|
compaction_started: "seat",
|
|
294
310
|
compaction_outcome: "seat",
|
|
295
311
|
engine_notice: "seat",
|
|
312
|
+
subagent_alias: "seat",
|
|
313
|
+
session_box_notice: "seat",
|
|
296
314
|
workflow_notification_enqueue: "host",
|
|
297
315
|
plan_review_park: "host",
|
|
298
316
|
approval_request: "host",
|
|
@@ -381,7 +399,7 @@ export function readSeatStreamDelta(message) {
|
|
|
381
399
|
return Object.freeze({ kind: "malformed" });
|
|
382
400
|
}
|
|
383
401
|
}
|
|
384
|
-
export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles", "thinkingLatch", "computerUseSwitch", "engineModeDefaultOnly", "seatActions"]);
|
|
402
|
+
export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles", "thinkingLatch", "computerUseSwitch", "engineModeDefaultOnly", "seatActions", "notificationLevels", "modsView"]);
|
|
385
403
|
const notReported = () => Object.freeze({ kind: "not_reported" });
|
|
386
404
|
const malformedReading = () => Object.freeze({ kind: "malformed" });
|
|
387
405
|
const reported = (available) => Object.freeze({ kind: "reported", available });
|
|
@@ -461,6 +479,8 @@ const SEAT_CAPABILITY_PHRASES = Object.freeze({
|
|
|
461
479
|
computerUseSwitch: Object.freeze({ action: "Computer use", ability: "be switched", support: "switch support" }),
|
|
462
480
|
engineModeDefaultOnly: Object.freeze({ action: "Default-only engine switching", ability: "keep existing sessions on their engine", support: "default-only engine switching" }),
|
|
463
481
|
seatActions: Object.freeze({ action: "App menu actions", ability: "send actions to this window", support: "app action support" }),
|
|
482
|
+
notificationLevels: Object.freeze({ action: "Choosing notification levels", ability: "keep notification levels", support: "notification-level support" }),
|
|
483
|
+
modsView: Object.freeze({ action: "Showing mods", ability: "show mods", support: "mods support" }),
|
|
464
484
|
});
|
|
465
485
|
export function seatCapabilityUnavailableDetail(name, reading) {
|
|
466
486
|
const phrase = Object.hasOwn(SEAT_CAPABILITY_PHRASES, name)
|
|
@@ -583,6 +603,7 @@ export const SEAT_TURN_SETTINGS_ORIGINS = Object.freeze({
|
|
|
583
603
|
hooks: Object.freeze({ hostSupplied: "settings.hooks" }),
|
|
584
604
|
resolved: Object.freeze({ hostSupplied: "settings.resolved" }),
|
|
585
605
|
outputStyle: Object.freeze({ hostSupplied: "settings.outputStyle" }),
|
|
606
|
+
env: Object.freeze({ hostSupplied: "settings.env" }),
|
|
586
607
|
});
|
|
587
608
|
export const SEAT_REWIND_INTENT_KEYS = ["mode", "targetMessageUuid"];
|
|
588
609
|
export const ATTACHMENT_UPLOAD_REQUEST_KEYS = ["name", "mimeType", "bytes"];
|
|
@@ -687,6 +708,18 @@ export const CLOUD_LOGIN_FAILURES = Object.freeze([
|
|
|
687
708
|
"no_tokens",
|
|
688
709
|
"other",
|
|
689
710
|
]);
|
|
711
|
+
export const LOCAL_ENGINE_DOWN_REASONS = Object.freeze([
|
|
712
|
+
"lock-unavailable",
|
|
713
|
+
"spawn-failed",
|
|
714
|
+
"spawn-refused",
|
|
715
|
+
"stop-failed",
|
|
716
|
+
"crash-loop",
|
|
717
|
+
"high-water-unreadable",
|
|
718
|
+
"principal-unknown",
|
|
719
|
+
]);
|
|
720
|
+
export const LOCAL_ENGINE_WAITING_REASONS = Object.freeze(["starting", "dormant", "draining", "unanswered", "peer"]);
|
|
721
|
+
export const ENGINE_SWAP_ANSWER_OUTCOMES = Object.freeze(["started", "stale-card", "nothing-pending"]);
|
|
722
|
+
export const SELF_UPGRADE_OUTCOMES = Object.freeze(["started", "unavailable"]);
|
|
690
723
|
const R_ISO = R_NONEMPTY;
|
|
691
724
|
const R_LOGIN_FAILURE = oneOfRule("login failure", CLOUD_LOGIN_FAILURES);
|
|
692
725
|
const R_DISPLAY_URL = ruleOf("display url", (v) => {
|
|
@@ -763,10 +796,80 @@ const ENGINE_TARGET_CLOUD = shapeRule("cloud", {
|
|
|
763
796
|
})),
|
|
764
797
|
orgEngine: optF(shapeRule("org engine", { url: reqF(R_DISPLAY_URL), required: reqF(R_BOOL) })),
|
|
765
798
|
});
|
|
766
|
-
const
|
|
799
|
+
const R_FINITE_TIME = ruleOf("non-negative integer", (v) => typeof v === "number" && Number.isSafeInteger(v) && v >= 0);
|
|
800
|
+
const SWAP_CARD_IDENTITY = shapeRule("engine identity", {
|
|
801
|
+
pid: optF(R_INT1),
|
|
802
|
+
instanceId: optF(R_NONEMPTY),
|
|
803
|
+
startedAt: optF(R_FINITE_TIME),
|
|
804
|
+
});
|
|
805
|
+
const SWAP_CARD_REF_SPEC = {
|
|
806
|
+
pid: reqF(R_INT1),
|
|
807
|
+
port: reqF(ruleOf("port", (v) => typeof v === "number" && Number.isInteger(v) && v >= 1 && v <= 65535)),
|
|
808
|
+
identity: reqF(SWAP_CARD_IDENTITY),
|
|
809
|
+
version: optF(R_NONEMPTY),
|
|
810
|
+
};
|
|
811
|
+
const SWAP_CARD_PROCESS_SPEC = { pid: reqF(R_INT1), startedAt: optF(R_INT1) };
|
|
812
|
+
const R_SWAP_CARD_TARGET = {
|
|
813
|
+
label: "card target",
|
|
814
|
+
test: (v, path) => {
|
|
815
|
+
if (!isPlainRecord(v))
|
|
816
|
+
return bad("not object", path === "" ? undefined : path);
|
|
817
|
+
return shapeVerdict(isAbsent(own(v, "identity")) ? SWAP_CARD_PROCESS_SPEC : SWAP_CARD_REF_SPEC, v, path);
|
|
818
|
+
},
|
|
819
|
+
};
|
|
820
|
+
const SWAP_CARD = shapeRule("swap card", {
|
|
821
|
+
cause: reqF(oneOfRule("swap cause", LOCAL_ENGINE_SWAP_CAUSES)),
|
|
822
|
+
target: reqF(R_SWAP_CARD_TARGET),
|
|
823
|
+
running: optF(R_NONEMPTY),
|
|
824
|
+
own: optF(R_NONEMPTY),
|
|
825
|
+
others: reqF(ruleOf("others count|null", (v) => {
|
|
826
|
+
if (v === null)
|
|
827
|
+
return true;
|
|
828
|
+
if (!isPlainRecord(v))
|
|
829
|
+
return false;
|
|
830
|
+
return shapeVerdict({ total: reqF(R_INT0), midTurn: reqF(R_INT0) }, v, "") === true;
|
|
831
|
+
})),
|
|
832
|
+
inflight: reqF(ruleOf("count|null", (v) => v === null || (typeof v === "number" && Number.isSafeInteger(v) && v >= 0))),
|
|
833
|
+
bgLive: reqF(ruleOf("count|null", (v) => v === null || (typeof v === "number" && Number.isSafeInteger(v) && v >= 0))),
|
|
834
|
+
unknown: reqF(arrayRule(oneOfRule("card unknown", ["others", "inflight", "bg", "self"]))),
|
|
835
|
+
forcedWithinMs: reqF(R_INT0),
|
|
836
|
+
fingerprint: reqF(R_NONEMPTY),
|
|
837
|
+
});
|
|
838
|
+
const LOCAL_ENGINE_SEAT_READING = armsRule("engine lifecycle", "phase", {
|
|
839
|
+
waiting: { why: reqF(oneOfRule("waiting reason", LOCAL_ENGINE_WAITING_REASONS)), unverifiable: optF(R_TRUE) },
|
|
840
|
+
attached: {},
|
|
841
|
+
pending: { serving: reqF(R_BOOL), card: optF(SWAP_CARD) },
|
|
842
|
+
swapping: { mode: reqF(oneOfRule("swap mode", ["idle", "forced"])) },
|
|
843
|
+
down: { reason: reqF(oneOfRule("down reason", LOCAL_ENGINE_DOWN_REASONS)) },
|
|
844
|
+
behind: { running: reqF(R_NONEMPTY), own: reqF(R_NONEMPTY), upgrade: reqF(oneOfRule("upgrade entry", ["available", "unavailable"])) },
|
|
845
|
+
});
|
|
846
|
+
const R_LIFECYCLE_DERIVED = ruleOf("lifecycle-derived", () => false);
|
|
847
|
+
const R_LIFECYCLE_WITHDRAWN = ruleOf("lifecycle-withdrawn", () => false);
|
|
848
|
+
const R_UNANSWERED_ONLY = ruleOf("unanswered-only", () => false);
|
|
849
|
+
const ENGINE_TARGET_LOCAL_SPEC = {
|
|
767
850
|
lastBootError: optF(R_STR),
|
|
768
851
|
mcp: optF(SEAT_LOCAL_MCP_READING),
|
|
769
|
-
|
|
852
|
+
lifecycle: reqF(LOCAL_ENGINE_SEAT_READING),
|
|
853
|
+
};
|
|
854
|
+
const ENGINE_TARGET_LOCAL = {
|
|
855
|
+
label: "local",
|
|
856
|
+
test: (v, path) => {
|
|
857
|
+
const verdict = shapeVerdict(ENGINE_TARGET_LOCAL_SPEC, v, path);
|
|
858
|
+
if (verdict !== true)
|
|
859
|
+
return verdict;
|
|
860
|
+
const rec = v;
|
|
861
|
+
const lifecycle = own(rec, "lifecycle");
|
|
862
|
+
const phase = own(lifecycle, "phase");
|
|
863
|
+
const bootError = !isAbsent(own(rec, "lastBootError"));
|
|
864
|
+
if (bootError !== (phase === "down"))
|
|
865
|
+
return R_LIFECYCLE_DERIVED.test(undefined, pathAt(path, "lastBootError"));
|
|
866
|
+
if (phase !== "attached" && phase !== "pending" && !isAbsent(own(rec, "mcp")))
|
|
867
|
+
return R_LIFECYCLE_WITHDRAWN.test(undefined, pathAt(path, "mcp"));
|
|
868
|
+
if (phase === "waiting" && own(lifecycle, "why") !== "unanswered" && !isAbsent(own(lifecycle, "unverifiable")))
|
|
869
|
+
return R_UNANSWERED_ONLY.test(undefined, pathAt(pathAt(path, "lifecycle"), "unverifiable"));
|
|
870
|
+
return true;
|
|
871
|
+
},
|
|
872
|
+
};
|
|
770
873
|
const ENGINE_TARGET_STATE = shapeRule("engine target", {
|
|
771
874
|
mode: reqF(R_ENGINE_LANE),
|
|
772
875
|
generation: reqF(R_INT0),
|
|
@@ -794,6 +897,8 @@ const ENGINE_TARGET_REFUSED_SPEC = {
|
|
|
794
897
|
detail: optF(R_STR),
|
|
795
898
|
};
|
|
796
899
|
const checkEngineTargetResult = seatShapeCheck(okArmsRule("engineTarget result", {}, ENGINE_TARGET_REFUSED_SPEC));
|
|
900
|
+
const checkEngineSwapAnswerOutcome = seatShapeCheck(oneOfRule("swap answer", ENGINE_SWAP_ANSWER_OUTCOMES));
|
|
901
|
+
const checkSelfUpgradeOutcome = seatShapeCheck(oneOfRule("self upgrade", SELF_UPGRADE_OUTCOMES));
|
|
797
902
|
const checkCancelCloudLogin = seatShapeCheck(shapeRule("cancel ack", { ok: reqF(R_BOOL) }));
|
|
798
903
|
const checkCloudLoginStart = seatShapeCheck(okArmsRule("startCloudLogin result", {
|
|
799
904
|
verificationUri: reqF(R_DISPLAY_URL),
|
|
@@ -971,6 +1076,46 @@ const checkSessionMcpPanelResult = seatCheck((v) => {
|
|
|
971
1076
|
return checkSessionMcpPanelFailure(v);
|
|
972
1077
|
return Object.hasOwn(v, "scenarioRefusal") ? checkSessionMcpPanelRefusalView(v) : checkSessionMcpPanelServersView(v);
|
|
973
1078
|
});
|
|
1079
|
+
const MOD_ROW_SKIP = shapeRule("mod skip", {
|
|
1080
|
+
registration: reqF(R_NONEMPTY),
|
|
1081
|
+
cause: reqF(R_NONEMPTY),
|
|
1082
|
+
reason: reqF(R_NONEMPTY),
|
|
1083
|
+
});
|
|
1084
|
+
const MOD_ROW_MOUNTED_SPEC = {
|
|
1085
|
+
name: reqF(R_NONEMPTY),
|
|
1086
|
+
seat: reqF(R_NONEMPTY),
|
|
1087
|
+
tier: reqF(R_NONEMPTY),
|
|
1088
|
+
provenance: optF(R_NONEMPTY),
|
|
1089
|
+
events: reqF(arrayRule(R_STR)),
|
|
1090
|
+
observe: optF(arrayRule(R_STR)),
|
|
1091
|
+
skipped: optF(arrayRule(MOD_ROW_SKIP, true)),
|
|
1092
|
+
};
|
|
1093
|
+
const MOD_ROW_REFUSED_SPEC = {
|
|
1094
|
+
name: reqF(R_NONEMPTY),
|
|
1095
|
+
seat: reqF(R_NONEMPTY),
|
|
1096
|
+
tier: reqF(R_NONEMPTY),
|
|
1097
|
+
provenance: optF(R_NONEMPTY),
|
|
1098
|
+
refusedBy: reqF(R_NONEMPTY),
|
|
1099
|
+
reason: reqF(R_NONEMPTY),
|
|
1100
|
+
};
|
|
1101
|
+
const MOD_ROW = {
|
|
1102
|
+
label: "mod row",
|
|
1103
|
+
test: (v, path) => {
|
|
1104
|
+
if (!isPlainRecord(v))
|
|
1105
|
+
return bad("not object", path);
|
|
1106
|
+
return Object.hasOwn(v, "refusedBy") || Object.hasOwn(v, "reason") ? shapeVerdict(MOD_ROW_REFUSED_SPEC, v, path) : shapeVerdict(MOD_ROW_MOUNTED_SPEC, v, path);
|
|
1107
|
+
},
|
|
1108
|
+
};
|
|
1109
|
+
const checkSessionModsFailure = seatShapeCheck(armsRule("readSessionMods failure", "kind", {
|
|
1110
|
+
unreadable: DEVICE_UNREADABLE_SPEC,
|
|
1111
|
+
unarmed: {},
|
|
1112
|
+
}));
|
|
1113
|
+
const checkSessionModsView = seatShapeCheck(shapeRule("mods view", { rows: reqF(arrayRule(MOD_ROW)) }));
|
|
1114
|
+
const checkSessionModsResult = seatCheck((v) => {
|
|
1115
|
+
if (!isPlainRecord(v))
|
|
1116
|
+
return bad("not object");
|
|
1117
|
+
return Object.hasOwn(v, "kind") ? checkSessionModsFailure(v) : checkSessionModsView(v);
|
|
1118
|
+
});
|
|
974
1119
|
const MCP_TOOL_TOGGLE_KEY = shapeRule("toggle key", {
|
|
975
1120
|
server: reqF(R_NONEMPTY),
|
|
976
1121
|
tool: reqF(R_NONEMPTY),
|
|
@@ -1066,6 +1211,75 @@ export function planSetComputerUse(request, lockedByEnv) {
|
|
|
1066
1211
|
return Object.freeze({ kind: "refused", reason: "confirmation-required" });
|
|
1067
1212
|
return Object.freeze({ kind: "apply", enabled: intent.kind === "enable" });
|
|
1068
1213
|
}
|
|
1214
|
+
export const NOTIFICATION_LEVEL_TYPES = Object.freeze(["permission", "question", "idle"]);
|
|
1215
|
+
export const NOTIFICATION_LEVELS = Object.freeze(["off", "badge", "banner"]);
|
|
1216
|
+
export const NOTIFICATION_LEVEL_REFUSAL_REASONS = Object.freeze(["invalid-request", "unsupported-level", "write-failed"]);
|
|
1217
|
+
const R_NOTIFICATION_LEVEL = oneOfRule("notification level", NOTIFICATION_LEVELS);
|
|
1218
|
+
const NOTIFICATION_SUPPORTED_ITEMS = arrayRule(R_NOTIFICATION_LEVEL, true);
|
|
1219
|
+
const NOTIFICATION_SUPPORTED_ORDER = "bad value (supported levels: off first, closed-set order, no repeats)";
|
|
1220
|
+
const R_NOTIFICATION_SUPPORTED = {
|
|
1221
|
+
label: "supported levels",
|
|
1222
|
+
test: (v, path) => {
|
|
1223
|
+
const verdict = NOTIFICATION_SUPPORTED_ITEMS.test(v, path);
|
|
1224
|
+
if (verdict !== true)
|
|
1225
|
+
return verdict;
|
|
1226
|
+
const rank = (x) => NOTIFICATION_LEVELS.indexOf(x);
|
|
1227
|
+
const rows = ownItems(v);
|
|
1228
|
+
if (rows[0] !== "off")
|
|
1229
|
+
return bad(NOTIFICATION_SUPPORTED_ORDER, path);
|
|
1230
|
+
for (let i = 1; i < rows.length; i += 1)
|
|
1231
|
+
if (rank(rows[i]) <= rank(rows[i - 1]))
|
|
1232
|
+
return bad(NOTIFICATION_SUPPORTED_ORDER, `${path}[${i}]`);
|
|
1233
|
+
return true;
|
|
1234
|
+
},
|
|
1235
|
+
};
|
|
1236
|
+
const NOTIFICATION_LEVELS_STATE_SHAPE = shapeRule("notification levels state", {
|
|
1237
|
+
levels: reqF(shapeRule("notification levels", {
|
|
1238
|
+
permission: reqF(R_NOTIFICATION_LEVEL),
|
|
1239
|
+
question: reqF(R_NOTIFICATION_LEVEL),
|
|
1240
|
+
idle: reqF(R_NOTIFICATION_LEVEL),
|
|
1241
|
+
})),
|
|
1242
|
+
supported: reqF(R_NOTIFICATION_SUPPORTED),
|
|
1243
|
+
});
|
|
1244
|
+
const NOTIFICATION_LEVELS_STATE = {
|
|
1245
|
+
label: NOTIFICATION_LEVELS_STATE_SHAPE.label,
|
|
1246
|
+
test: (v, path) => {
|
|
1247
|
+
const verdict = NOTIFICATION_LEVELS_STATE_SHAPE.test(v, path);
|
|
1248
|
+
if (verdict !== true)
|
|
1249
|
+
return verdict;
|
|
1250
|
+
const rec = v;
|
|
1251
|
+
const levels = own(rec, "levels");
|
|
1252
|
+
const supported = ownItems(own(rec, "supported"));
|
|
1253
|
+
for (const t of NOTIFICATION_LEVEL_TYPES)
|
|
1254
|
+
if (!supported.includes(own(levels, t)))
|
|
1255
|
+
return bad("unsupported level", pathAt(path, `levels.${t}`));
|
|
1256
|
+
return true;
|
|
1257
|
+
},
|
|
1258
|
+
};
|
|
1259
|
+
const checkNotificationLevelsState = seatShapeCheck(NOTIFICATION_LEVELS_STATE);
|
|
1260
|
+
const checkSetNotificationLevelResult = seatShapeCheck(okArmsRule("setNotificationLevel result", { state: reqF(NOTIFICATION_LEVELS_STATE) }, {
|
|
1261
|
+
reason: reqF(oneOfRule("notification level refusal", NOTIFICATION_LEVEL_REFUSAL_REASONS)),
|
|
1262
|
+
state: reqF(NOTIFICATION_LEVELS_STATE),
|
|
1263
|
+
}));
|
|
1264
|
+
export function planSetNotificationLevel(type, level, supported) {
|
|
1265
|
+
if (typeof type !== "string" || !inTuple(NOTIFICATION_LEVEL_TYPES, type) || typeof level !== "string" || !inTuple(NOTIFICATION_LEVELS, level)) {
|
|
1266
|
+
return Object.freeze({ kind: "refused", reason: "invalid-request" });
|
|
1267
|
+
}
|
|
1268
|
+
let delivers = false;
|
|
1269
|
+
try {
|
|
1270
|
+
const n = Array.isArray(supported) ? ownDataField(supported, "length") : undefined;
|
|
1271
|
+
if (typeof n === "number" && Number.isSafeInteger(n) && n <= NOTIFICATION_LEVELS.length) {
|
|
1272
|
+
for (let i = 0; i < n && !delivers; i += 1)
|
|
1273
|
+
delivers = own(supported, String(i)) === level;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
catch {
|
|
1277
|
+
delivers = false;
|
|
1278
|
+
}
|
|
1279
|
+
if (!delivers)
|
|
1280
|
+
return Object.freeze({ kind: "refused", reason: "unsupported-level" });
|
|
1281
|
+
return Object.freeze({ kind: "apply", type, level });
|
|
1282
|
+
}
|
|
1069
1283
|
export const SEAT_ACTION_NAMES = Object.freeze(["new-project", "prefill-composer"]);
|
|
1070
1284
|
const SEAT_PREFILL_TEXT_MAX = 14336;
|
|
1071
1285
|
const SEAT_PREFILL_CWD_MAX = 4096;
|
|
@@ -1240,11 +1454,77 @@ const checkLocalSessionRecord = seatCheck((s) => {
|
|
|
1240
1454
|
if (!isAbsent(lane) && (typeof lane !== "string" || lane.length === 0)) {
|
|
1241
1455
|
return bad("executionLane must be a non-empty string when present (absent = no writer lane reading)", "executionLane");
|
|
1242
1456
|
}
|
|
1457
|
+
const parkedRows = own(s, "parkedUnresumable");
|
|
1458
|
+
if (!isAbsent(parkedRows)) {
|
|
1459
|
+
const verdict = R_PARKED_UNRESUMABLE.test(parkedRows, "parkedUnresumable");
|
|
1460
|
+
if (verdict !== true)
|
|
1461
|
+
return verdict;
|
|
1462
|
+
if (parked === false)
|
|
1463
|
+
return bad("bad value (parked:false)", "parkedUnresumable");
|
|
1464
|
+
}
|
|
1243
1465
|
return true;
|
|
1244
1466
|
});
|
|
1245
1467
|
export function isLocalSessionRecord(s) {
|
|
1246
1468
|
return checkLocalSessionRecord(s) === true;
|
|
1247
1469
|
}
|
|
1470
|
+
const checkParkedUnresumableSlot = seatCheck((v) => R_PARKED_UNRESUMABLE.test(v, "parkedUnresumable"));
|
|
1471
|
+
const parkedVerdictCopy = (rv) => {
|
|
1472
|
+
const kind = own(rv, "kind");
|
|
1473
|
+
const str = (k) => {
|
|
1474
|
+
const x = own(rv, k);
|
|
1475
|
+
return typeof x === "string" ? x : undefined;
|
|
1476
|
+
};
|
|
1477
|
+
const sentence = str("sentence");
|
|
1478
|
+
if (kind === "lacking" || kind === "damaged") {
|
|
1479
|
+
const reason = str("reason");
|
|
1480
|
+
const requires = own(rv, "requires");
|
|
1481
|
+
return Object.freeze({
|
|
1482
|
+
kind,
|
|
1483
|
+
code: str("code") ?? "",
|
|
1484
|
+
...(reason !== undefined ? { reason } : {}),
|
|
1485
|
+
...(Array.isArray(requires) ? { requires: Object.freeze(ownItems(requires).filter((w) => typeof w === "string")) } : {}),
|
|
1486
|
+
sentence: sentence ?? "",
|
|
1487
|
+
});
|
|
1488
|
+
}
|
|
1489
|
+
if (kind === "unknown")
|
|
1490
|
+
return Object.freeze({ kind, word: str("word") ?? "", ...(sentence !== undefined ? { sentence } : {}) });
|
|
1491
|
+
return Object.freeze({ kind: "unreadable" });
|
|
1492
|
+
};
|
|
1493
|
+
const parkedRowCopy = (item) => {
|
|
1494
|
+
const str = (k) => {
|
|
1495
|
+
const x = own(item, k);
|
|
1496
|
+
return typeof x === "string" ? x : undefined;
|
|
1497
|
+
};
|
|
1498
|
+
const rv = own(item, "rowVerdict");
|
|
1499
|
+
const rowKey = str("rowKey");
|
|
1500
|
+
const taskId = str("taskId");
|
|
1501
|
+
const toolName = str("toolName");
|
|
1502
|
+
const rowDeadline = str("rowDeadline");
|
|
1503
|
+
return Object.freeze({
|
|
1504
|
+
rowVerdict: parkedVerdictCopy(typeof rv === "object" && rv !== null ? rv : {}),
|
|
1505
|
+
...(rowKey !== undefined ? { rowKey } : {}),
|
|
1506
|
+
...(taskId !== undefined ? { taskId } : {}),
|
|
1507
|
+
...(toolName !== undefined ? { toolName } : {}),
|
|
1508
|
+
...(rowDeadline === "armed" || rowDeadline === "none" ? { rowDeadline } : {}),
|
|
1509
|
+
});
|
|
1510
|
+
};
|
|
1511
|
+
export function readSeatParkedUnresumable(record) {
|
|
1512
|
+
try {
|
|
1513
|
+
if (typeof record !== "object" || record === null)
|
|
1514
|
+
return undefined;
|
|
1515
|
+
const v = own(record, "parkedUnresumable");
|
|
1516
|
+
if (isAbsent(v))
|
|
1517
|
+
return undefined;
|
|
1518
|
+
if (own(record, "parked") === false)
|
|
1519
|
+
return undefined;
|
|
1520
|
+
if (checkParkedUnresumableSlot(v) !== true)
|
|
1521
|
+
return undefined;
|
|
1522
|
+
return Object.freeze(ownItems(v).map((item) => parkedRowCopy(item)));
|
|
1523
|
+
}
|
|
1524
|
+
catch {
|
|
1525
|
+
return undefined;
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1248
1528
|
const checkToctouBinding = seatCheck((v) => {
|
|
1249
1529
|
if (!isPlainRecord(v))
|
|
1250
1530
|
return bad("toctouBinding must be a plain object", "toctouBinding");
|
|
@@ -1750,7 +2030,37 @@ export function isSendMessageAck(v) {
|
|
|
1750
2030
|
}
|
|
1751
2031
|
const checkInterruptAck = seatCheck((v) => isPlainRecord(v) && typeof own(v, "interrupted") === "boolean" ? true : bad("interrupt ack needs a plain object with boolean `interrupted`", "interrupted"));
|
|
1752
2032
|
const checkStopAck = seatCheck((v) => isPlainRecord(v) && typeof own(v, "stopped") === "boolean" ? true : bad("stop ack needs a plain object with boolean `stopped`", "stopped"));
|
|
1753
|
-
const
|
|
2033
|
+
const okAckVerdict = (v) => isPlainRecord(v) && typeof own(v, "ok") === "boolean" ? true : bad("ack needs a plain object with boolean `ok`", "ok");
|
|
2034
|
+
const checkOkAck = seatCheck(okAckVerdict);
|
|
2035
|
+
const TOOL_PERMISSION_SETTLED_WORDS = Object.freeze(["allow", "deny"]);
|
|
2036
|
+
const R_SETTLED_ELSEWHERE = shapeRule("settled elsewhere", {
|
|
2037
|
+
firstDecision: reqF(oneOfRule("decision word", TOOL_PERMISSION_SETTLED_WORDS)),
|
|
2038
|
+
contrary: reqF(R_BOOL),
|
|
2039
|
+
});
|
|
2040
|
+
const checkToolPermissionAck = seatCheck((v) => {
|
|
2041
|
+
const base = okAckVerdict(v);
|
|
2042
|
+
if (base !== true)
|
|
2043
|
+
return base;
|
|
2044
|
+
const slot = own(v, "settledElsewhere");
|
|
2045
|
+
return isAbsent(slot) ? true : R_SETTLED_ELSEWHERE.test(slot, "settledElsewhere");
|
|
2046
|
+
});
|
|
2047
|
+
const checkSettledElsewhereSlot = seatCheck((v) => R_SETTLED_ELSEWHERE.test(v, "settledElsewhere"));
|
|
2048
|
+
export function readToolPermissionSettledElsewhere(ack) {
|
|
2049
|
+
try {
|
|
2050
|
+
if (typeof ack !== "object" || ack === null)
|
|
2051
|
+
return undefined;
|
|
2052
|
+
const slot = own(ack, "settledElsewhere");
|
|
2053
|
+
if (isAbsent(slot))
|
|
2054
|
+
return undefined;
|
|
2055
|
+
if (checkSettledElsewhereSlot(slot) !== true)
|
|
2056
|
+
return undefined;
|
|
2057
|
+
const first = own(slot, "firstDecision");
|
|
2058
|
+
return Object.freeze({ firstDecision: first === "allow" ? "allow" : "deny", contrary: own(slot, "contrary") === true });
|
|
2059
|
+
}
|
|
2060
|
+
catch {
|
|
2061
|
+
return undefined;
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
1754
2064
|
const checkBooleanAck = (v) => typeof v === "boolean" ? true : bad("expected a bare boolean result");
|
|
1755
2065
|
const checkGetTranscriptResult = seatCheck((v) => {
|
|
1756
2066
|
if (!isPlainRecord(v))
|
|
@@ -1873,7 +2183,7 @@ export const LOCAL_SESSIONS_SPEC = {
|
|
|
1873
2183
|
sendMessage: { kind: "invoke", check: checkSendMessageAck },
|
|
1874
2184
|
interrupt: { kind: "invoke", check: checkInterruptAck },
|
|
1875
2185
|
stop: { kind: "invoke", check: checkStopAck },
|
|
1876
|
-
respondToToolPermission: { kind: "invoke", check:
|
|
2186
|
+
respondToToolPermission: { kind: "invoke", check: checkToolPermissionAck },
|
|
1877
2187
|
cancelQueuedMessage: { kind: "invoke", check: checkBooleanAck },
|
|
1878
2188
|
reorderQueuedMessage: { kind: "invoke", check: checkBooleanAck },
|
|
1879
2189
|
promoteQueuedMessage: { kind: "invoke", check: checkBooleanAck },
|
|
@@ -1898,6 +2208,8 @@ export const LOCAL_SESSIONS_SPEC = {
|
|
|
1898
2208
|
connectCloudEngine: { kind: "invoke", check: checkCloudConnectResult },
|
|
1899
2209
|
configureCloudEngine: { kind: "invoke", check: checkCloudConnectResult },
|
|
1900
2210
|
clearCloudEngine: { kind: "invoke", check: checkEngineTargetResult },
|
|
2211
|
+
answerEngineSwap: { kind: "invoke", check: checkEngineSwapAnswerOutcome },
|
|
2212
|
+
beginSelfUpgrade: { kind: "invoke", check: checkSelfUpgradeOutcome },
|
|
1901
2213
|
listOnboardProviders: { kind: "invoke", check: checkOnboardProvidersResult },
|
|
1902
2214
|
probeOnboardEntry: { kind: "invoke", check: checkOnboardProbeResult },
|
|
1903
2215
|
applyOnboardEntry: { kind: "invoke", check: checkOnboardApplyResult },
|
|
@@ -1907,7 +2219,10 @@ export const LOCAL_SESSIONS_SPEC = {
|
|
|
1907
2219
|
setThinkingLatch: { kind: "invoke", check: checkOkAck },
|
|
1908
2220
|
getComputerUse: { kind: "invoke", check: checkComputerUseState },
|
|
1909
2221
|
setComputerUse: { kind: "invoke", check: checkSetComputerUseResult },
|
|
2222
|
+
getNotificationLevels: { kind: "invoke", check: checkNotificationLevelsState },
|
|
2223
|
+
setNotificationLevel: { kind: "invoke", check: checkSetNotificationLevelResult },
|
|
1910
2224
|
claimSeatActions: { kind: "invoke", check: checkOkAck },
|
|
2225
|
+
readSessionMods: { kind: "invoke", check: checkSessionModsResult },
|
|
1911
2226
|
onEvent: { kind: "event", check: checkLocalSessionEvent },
|
|
1912
2227
|
onToolPermissionRequest: { kind: "event", check: checkToolPermissionRequest },
|
|
1913
2228
|
onSeatAction: { kind: "event", check: checkSeatAction },
|
|
@@ -1950,6 +2265,8 @@ export const SEAT_METHOD_NAMES = [
|
|
|
1950
2265
|
"connectCloudEngine",
|
|
1951
2266
|
"configureCloudEngine",
|
|
1952
2267
|
"clearCloudEngine",
|
|
2268
|
+
"answerEngineSwap",
|
|
2269
|
+
"beginSelfUpgrade",
|
|
1953
2270
|
"listOnboardProviders",
|
|
1954
2271
|
"probeOnboardEntry",
|
|
1955
2272
|
"applyOnboardEntry",
|
|
@@ -1959,7 +2276,10 @@ export const SEAT_METHOD_NAMES = [
|
|
|
1959
2276
|
"setThinkingLatch",
|
|
1960
2277
|
"getComputerUse",
|
|
1961
2278
|
"setComputerUse",
|
|
2279
|
+
"getNotificationLevels",
|
|
2280
|
+
"setNotificationLevel",
|
|
1962
2281
|
"claimSeatActions",
|
|
2282
|
+
"readSessionMods",
|
|
1963
2283
|
"onEvent",
|
|
1964
2284
|
"onToolPermissionRequest",
|
|
1965
2285
|
"onSeatAction",
|
|
@@ -2006,6 +2326,12 @@ export const TOOL_PERMISSION_REQUEST_KEYS = [
|
|
|
2006
2326
|
"askClass",
|
|
2007
2327
|
"classes",
|
|
2008
2328
|
"sessionRow",
|
|
2329
|
+
"probeReason",
|
|
2330
|
+
"probeCause",
|
|
2331
|
+
"feedbackCapable",
|
|
2332
|
+
"requestedBy",
|
|
2333
|
+
"frameReading",
|
|
2334
|
+
"inputSource",
|
|
2009
2335
|
];
|
|
2010
2336
|
export const LOCAL_SESSION_RECORD_KEYS = [
|
|
2011
2337
|
"sessionId",
|
|
@@ -2024,6 +2350,7 @@ export const LOCAL_SESSION_RECORD_KEYS = [
|
|
|
2024
2350
|
"thinkingLatch",
|
|
2025
2351
|
"engine",
|
|
2026
2352
|
"executionLane",
|
|
2353
|
+
"parkedUnresumable",
|
|
2027
2354
|
];
|
|
2028
2355
|
export const SEND_MESSAGE_REQUEST_KEYS = [
|
|
2029
2356
|
"sessionId",
|
|
@@ -2062,13 +2389,14 @@ export const TOOL_PERMISSION_DECISION_KEYS = [
|
|
|
2062
2389
|
"answer",
|
|
2063
2390
|
"updatedInput",
|
|
2064
2391
|
"remember",
|
|
2392
|
+
"feedback",
|
|
2065
2393
|
];
|
|
2066
2394
|
export const START_SESSION_OPTION_KEYS = ["model", "title", "cwd", "excludeTools", "engine"];
|
|
2067
2395
|
export const SEAT_VALIDATOR_KEY_COVERAGE = {
|
|
2068
2396
|
LocalSessionRecord: {
|
|
2069
2397
|
guard: "isLocalSessionRecord",
|
|
2070
2398
|
check: checkLocalSessionRecord,
|
|
2071
|
-
validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned", "rowTag", "unreadable", "thinkingLatch", "engine", "executionLane"],
|
|
2399
|
+
validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned", "rowTag", "unreadable", "thinkingLatch", "engine", "executionLane", "parkedUnresumable"],
|
|
2072
2400
|
unchecked: [],
|
|
2073
2401
|
},
|
|
2074
2402
|
ToolPermissionRequest: {
|
|
@@ -2112,10 +2440,34 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
|
|
|
2112
2440
|
key: "sessionRow",
|
|
2113
2441
|
why: "放宽方向的展示位(CC-699),判官在过境口 toolPermissionRequestAskBits(card, requestId):卡上「本会话放行」判官 standingRowsOf 的会话行同一前提 ∧ 本请求 requestId 的域带得走(live: / durable:),严格 true 才上座、永不铸 false;座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。消费端 `=== true` 才渲「本会话放行」,其余(缺席 / 坏形)一律不渲 —— 缺席是闭合失败,不是「没说就照渲」。不经过境口自铸座位请求的宿主拿不到这一位,座位卡就不给那一档。",
|
|
2114
2442
|
},
|
|
2443
|
+
{
|
|
2444
|
+
key: "feedbackCapable",
|
|
2445
|
+
why: "放宽方向的展示位(CC-585),判官在过境口 toolPermissionRequestAskBits(card, requestId):卡判官 answerCarriage(card) 答 model(卡带耐久待决行腿的正向事实 parkRow)∧ 本请求 requestId 的域恰是 durable:(只有 /decide 收放行反馈位),严格 true 才上座、永不铸 false;座位门不设第二判官,理由同 sessionRow(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。消费端 `=== true` 才渲「Yes + 告诉 agent 下一步」那一格输入,其余(缺席 / 坏形)一律不渲 —— 缺席是闭合失败。不经过境口自铸座位请求的宿主拿不到这一位,座位卡就不给那一格。",
|
|
2446
|
+
},
|
|
2115
2447
|
{
|
|
2116
2448
|
key: "ruleOffersAbsence",
|
|
2117
2449
|
why: "喂强制判据口 approvalIsMandated 的位(CC-203;寄存行那条腿的强制只以缺席词 mandated 表达),按开集读(非空串原文字节、词表不校);权威窄读在卡口与过境口,座位门不设第二判官,理由同 mandated。坏形读成缺席 ⇒ 这一路不判强制(放宽方向:寄存行上的强制就丢了;另两路 mandated / mandate 照判);表外串只是不等于 mandated。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
|
|
2118
2450
|
},
|
|
2451
|
+
{
|
|
2452
|
+
key: "probeReason",
|
|
2453
|
+
why: "展示位(CC-1316),权威窄读在过境口 toolPermissionRequestAskBits,与「为什么问」那一句的读口 askProbeReasonDetail 同一个读点(自有数据属性、取值器不执行;串且去两端空白后非空才在场,原文字节);座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。坏形读成缺席 ⇒ 卡上不显示这一句,不改决断;缺席不是「没有原因」。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
|
|
2454
|
+
},
|
|
2455
|
+
{
|
|
2456
|
+
key: "probeCause",
|
|
2457
|
+
why: "展示位(CC-1316),与 probeReason 同一对、同一个读点;载体层判(自有数据属性、非 null 非数组对象)才在场,同一引用原样搬运,内部成员不校(成员的窄读归 askProbeReasonDetail / probeCauseRowsOf);座位门不设第二判官,理由同 probeReason。坏形读成缺席 ⇒ 不显示因由行,不改决断。两位按键隔离:一位读不出不连坐另一位。",
|
|
2458
|
+
},
|
|
2459
|
+
{
|
|
2460
|
+
key: "requestedBy",
|
|
2461
|
+
why: "展示位(CC-1341),权威窄读在过境口 toolPermissionRequestAskBits,读点是卡口的唯一载体级读口 approvalRequestedByOf(载体顶层的自有数据属性、取值器不执行;kind 恰 extension 且 name 非空串才在场,出冻结的新铸副本);原始耐久待决行不读(上游不在行上铸这一位);座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。坏形读成缺席 ⇒ 卡上不显示发起者行,不改决断;缺席不是「模型发起」。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
|
|
2462
|
+
},
|
|
2463
|
+
{
|
|
2464
|
+
key: "frameReading",
|
|
2465
|
+
why: "展示位(CC-1345),权威窄读在过境口 toolPermissionRequestAskBits,读点是包内唯一读口 cardPayloadReadingOf(卡上 cardPayloadUnreadable 严格 true ∧ cardPayloadUnreadableWhy 是判因闭集三词之一才在场;卡面通用卡第一行按因选句同读它);座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。表外词 / 游离判因词 / 判因未知读成缺席 ⇒ 卡上回落不分因的原句,不改决断;缺席不是「帧读得出」。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
|
|
2466
|
+
},
|
|
2467
|
+
{
|
|
2468
|
+
key: "inputSource",
|
|
2469
|
+
why: "展示位(CC-1366),权威窄读在过境口 toolPermissionRequestAskBits,读点是包内唯一窄读 approvalInputSourceOf(载体顶层的自有数据属性、取值器不执行;闭集 record / stream 两词精确字节才在场);来源位本身只有一个铸点(卡入参读法的读数 → 位),过境口只抄卡上已铸的位、不拿 input 重判来源,原始帧 / 原始耐久待决行直交恒缺席;座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。表外词 / 近义词 / 非串读成缺席 ⇒ 壳按来源不明处置,不改决断;缺席不是 record。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
|
|
2470
|
+
},
|
|
2119
2471
|
],
|
|
2120
2472
|
},
|
|
2121
2473
|
LocalSessionEvent: {
|
|
@@ -2247,6 +2599,11 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
|
|
|
2247
2599
|
validated: ["ok"],
|
|
2248
2600
|
unchecked: [],
|
|
2249
2601
|
},
|
|
2602
|
+
ToolPermissionAck: {
|
|
2603
|
+
check: checkToolPermissionAck,
|
|
2604
|
+
validated: ["ok", "settledElsewhere"],
|
|
2605
|
+
unchecked: [],
|
|
2606
|
+
},
|
|
2250
2607
|
GetTranscriptResult: {
|
|
2251
2608
|
check: checkGetTranscriptResult,
|
|
2252
2609
|
validated: ["sessionId", "messages"],
|
|
@@ -2274,7 +2631,7 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
|
|
|
2274
2631
|
},
|
|
2275
2632
|
SeatCapabilitiesState: {
|
|
2276
2633
|
check: checkSeatCapabilitiesState,
|
|
2277
|
-
validated: ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles", "thinkingLatch", "computerUseSwitch", "engineModeDefaultOnly", "seatActions"],
|
|
2634
|
+
validated: ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles", "thinkingLatch", "computerUseSwitch", "engineModeDefaultOnly", "seatActions", "notificationLevels", "modsView"],
|
|
2278
2635
|
unchecked: [],
|
|
2279
2636
|
},
|
|
2280
2637
|
RecentFoldersResult: {
|
|
@@ -2340,7 +2697,12 @@ export const SEAT_VALIDATOR_COVERAGE_EXEMPT = [
|
|
|
2340
2697
|
["ComputerUseState", checkComputerUseState],
|
|
2341
2698
|
["SetComputerUseResult", checkSetComputerUseResult],
|
|
2342
2699
|
["SetComputerUseRequest", checkSetComputerUseRequest],
|
|
2700
|
+
["NotificationLevelsState", checkNotificationLevelsState],
|
|
2701
|
+
["SetNotificationLevelResult", checkSetNotificationLevelResult],
|
|
2343
2702
|
["SeatAction", checkSeatAction],
|
|
2703
|
+
["EngineSwapAnswerOutcome", checkEngineSwapAnswerOutcome],
|
|
2704
|
+
["SelfUpgradeOutcome", checkSelfUpgradeOutcome],
|
|
2705
|
+
["SessionModsResult", checkSessionModsResult],
|
|
2344
2706
|
].map(([label, check]) => ({
|
|
2345
2707
|
label,
|
|
2346
2708
|
check,
|
|
@@ -2404,5 +2766,9 @@ const _seatContractPins = [
|
|
|
2404
2766
|
true, true, true, true,
|
|
2405
2767
|
true, true,
|
|
2406
2768
|
true, true, true, true, true, true, true,
|
|
2769
|
+
true, true, true, true, true, true, true, true,
|
|
2770
|
+
true, true, true, true, true,
|
|
2771
|
+
true, true, true,
|
|
2772
|
+
true, true, true, true,
|
|
2407
2773
|
];
|
|
2408
2774
|
void _seatContractPins;
|
|
@@ -6,6 +6,7 @@ import { isLoopbackWireUrl } from './engineWireSdk.js';
|
|
|
6
6
|
import { hostEnv } from './hostEnv.js';
|
|
7
7
|
import { approvalDecisionHolds } from './hitl/approvalHolds.js';
|
|
8
8
|
import { readRunTerminal } from './runTerminal.js';
|
|
9
|
+
import { isReplayedTerminal } from './replayBody.js';
|
|
9
10
|
import { appendOwnElement, ownDataField, putOwnKey, readOwnDataFiniteNumber, readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
|
|
10
11
|
import { msg, renderMessage } from './i18n/translate.js';
|
|
11
12
|
export function projectSessionBackgroundable(caps) {
|
|
@@ -34,6 +35,8 @@ export function readSessionBackgroundable(baseUrl = engineWireTargetBaseUrl()) {
|
|
|
34
35
|
return Object.freeze({ kind: 'unobserved' });
|
|
35
36
|
}
|
|
36
37
|
}
|
|
38
|
+
const localEngineLanePin = true;
|
|
39
|
+
void localEngineLanePin;
|
|
37
40
|
export const OPENING_RECORD_CAP = 256;
|
|
38
41
|
const wireStates = new WeakMap();
|
|
39
42
|
const isObj = (v) => (typeof v === 'object' && v !== null) || typeof v === 'function';
|
|
@@ -416,7 +419,7 @@ function observeFrame(rec, ev) {
|
|
|
416
419
|
}
|
|
417
420
|
else {
|
|
418
421
|
rec.phase = 'ended-unstarted';
|
|
419
|
-
rec.replay = type === 'done' &&
|
|
422
|
+
rec.replay = type === 'done' && isReplayedTerminal(ev);
|
|
420
423
|
}
|
|
421
424
|
return;
|
|
422
425
|
}
|
|
@@ -4,6 +4,7 @@ import { REATTACH_WINDOW_MS, reattachBackoffMs } from './reattachWindow.js';
|
|
|
4
4
|
import { terminalEventFromRunRow } from './headlessReconnectWire.js';
|
|
5
5
|
import { RUN_CANCELLED_CODE } from './runCancelContext.js';
|
|
6
6
|
import { readRunTerminal } from './runTerminal.js';
|
|
7
|
+
import { isReplayedTerminal } from './replayBody.js';
|
|
7
8
|
import { readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
|
|
8
9
|
import { backgroundHandoffSentence, judgeHandoff, ownSlotOf, wireStateOf, } from './sessionBackground.js';
|
|
9
10
|
export const BACKGROUND_HANDOFF_ABORT_REASON = 'background';
|
|
@@ -34,7 +35,7 @@ function executionSettlementOf(ev) {
|
|
|
34
35
|
return { runEnded: true, kind: 'cancelled', status: 'failed' };
|
|
35
36
|
return { runEnded: true, kind: 'failed', status: 'failed', ...(code !== undefined ? { errorCode: code } : {}) };
|
|
36
37
|
}
|
|
37
|
-
if (type !== 'done' ||
|
|
38
|
+
if (type !== 'done' || isReplayedTerminal(ev))
|
|
38
39
|
return undefined;
|
|
39
40
|
const read = readRunTerminal(slot(ev, 'result'));
|
|
40
41
|
if (read === null)
|
package/dist/sessionEngine.d.ts
CHANGED
|
@@ -153,5 +153,7 @@ export declare function sessionEngineBindingFor(input: SessionEngineBindingInput
|
|
|
153
153
|
export declare function isSessionEngineView(v: {} | null | undefined): boolean;
|
|
154
154
|
export declare function readSessionEngine(record: SessionMapRecord | undefined): SessionEngineReading;
|
|
155
155
|
export declare function commitSessionEngine(store: SessionMapStorePort, session: SessionEngineSessionRef, request: SessionEngineCommitRequest): SessionEngineCommitResult;
|
|
156
|
+
export type SessionEngineRepointResult = 'moved' | 'unaffected' | 'conflict' | 'unreadable' | 'store-failed' | 'request-invalid';
|
|
157
|
+
export declare function repointSessionEngine(store: SessionMapStorePort, from: string, to: string): SessionEngineRepointResult;
|
|
156
158
|
export declare function sessionDispatchRefusedFor(refusal: SessionDispatchRefusal): SessionDispatchRefused;
|
|
157
159
|
export declare function sessionDispatchTarget(reading: SessionEngineReading, ctx: SessionEngineWiring): SessionDispatchDecision;
|