@rynx-ai/server 0.1.11-beta.30 → 0.1.11-beta.32
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/dist/control-api.js +37 -0
- package/dist/control-web/assets/{abnfDiagram-VRR7QNED-COu02MlJ.js → abnfDiagram-VRR7QNED-8c99_3I5.js} +1 -1
- package/dist/control-web/assets/{arc-DqiFeYAM.js → arc-FWW96Tzo.js} +1 -1
- package/dist/control-web/assets/{architectureDiagram-ZJ3FMSHR-BWFGgUV4.js → architectureDiagram-ZJ3FMSHR-B5FrqoRB.js} +1 -1
- package/dist/control-web/assets/{blockDiagram-677ZJIJ3-ZC0bXDzB.js → blockDiagram-677ZJIJ3-DJRwOGMa.js} +1 -1
- package/dist/control-web/assets/{c4Diagram-LMCZKHZV-Uupq5I-s.js → c4Diagram-LMCZKHZV-B8FCUurl.js} +1 -1
- package/dist/control-web/assets/channel-Bnyhn1Qs.js +1 -0
- package/dist/control-web/assets/{chunk-2Q5K7J3B-C77vwuDM.js → chunk-2Q5K7J3B-DC5xexY2.js} +1 -1
- package/dist/control-web/assets/{chunk-32BRIVSS-BkfLE_TX.js → chunk-32BRIVSS-DAzT69zb.js} +1 -1
- package/dist/control-web/assets/{chunk-5VM5RSS4-By6zfDWW.js → chunk-5VM5RSS4-CXKpL77L.js} +1 -1
- package/dist/control-web/assets/{chunk-EX3LRPZG-CO439p_3.js → chunk-EX3LRPZG-DQKQvoPv.js} +1 -1
- package/dist/control-web/assets/{chunk-JWPE2WC7-B9BPEwug.js → chunk-JWPE2WC7-CWMqpJoT.js} +1 -1
- package/dist/control-web/assets/{chunk-MOJQB5TN-CYKygWZz.js → chunk-MOJQB5TN-Bd8jn7RZ.js} +1 -1
- package/dist/control-web/assets/{chunk-RYQCIY6F-ug-An4HG.js → chunk-RYQCIY6F-DKXEMFO6.js} +1 -1
- package/dist/control-web/assets/{chunk-V7JOEXUC-3UFQGnKX.js → chunk-V7JOEXUC-BUDLq5nU.js} +1 -1
- package/dist/control-web/assets/{chunk-VR4S4FIN-DjspjYUb.js → chunk-VR4S4FIN-C65l7VIz.js} +1 -1
- package/dist/control-web/assets/{chunk-XXDRQBXY-3znnutie.js → chunk-XXDRQBXY-Y2498HkC.js} +1 -1
- package/dist/control-web/assets/classDiagram-OUVF2IWQ-CBtXSdwW.js +1 -0
- package/dist/control-web/assets/classDiagram-v2-EOCWNBFH-CBtXSdwW.js +1 -0
- package/dist/control-web/assets/{cose-bilkent-JH36ORCC-Dr28goCd.js → cose-bilkent-JH36ORCC-C9aVXb8E.js} +1 -1
- package/dist/control-web/assets/{cynefin-VYW2F7L2-Be5uJhnw.js → cynefin-VYW2F7L2-BsyMhvG0.js} +1 -1
- package/dist/control-web/assets/{cynefinDiagram-TSTJHNR4-BLxtSvL6.js → cynefinDiagram-TSTJHNR4-DwY43f3-.js} +1 -1
- package/dist/control-web/assets/{dagre-VKFMJZFB-DPRuDV5p.js → dagre-VKFMJZFB-CP1xk7Ox.js} +1 -1
- package/dist/control-web/assets/{diagram-FQU43EPY-Cybg22U0.js → diagram-FQU43EPY-D_yRnH1b.js} +1 -1
- package/dist/control-web/assets/{diagram-G47NLZAW-CGeIKUfW.js → diagram-G47NLZAW-DpTmLmbm.js} +1 -1
- package/dist/control-web/assets/{diagram-NH7WQ7WH-BJq5MBRm.js → diagram-NH7WQ7WH-Wh_P26Dr.js} +1 -1
- package/dist/control-web/assets/{diagram-OA4YK3LP-DquOQGwg.js → diagram-OA4YK3LP-BMMaO78f.js} +1 -1
- package/dist/control-web/assets/{diagram-WEI45ONY-Cblb4xP2.js → diagram-WEI45ONY-D8smty9F.js} +1 -1
- package/dist/control-web/assets/{ebnfDiagram-CCIWWBDH-CQjHiOqj.js → ebnfDiagram-CCIWWBDH-BqVsmEYh.js} +1 -1
- package/dist/control-web/assets/{erDiagram-Q63AITRT-Bspr3uKJ.js → erDiagram-Q63AITRT-CxaumIzW.js} +1 -1
- package/dist/control-web/assets/{flowDiagram-23GEKE2U-CxcZyBA-.js → flowDiagram-23GEKE2U-DZhUBne-.js} +1 -1
- package/dist/control-web/assets/{ganttDiagram-NO4QXBWP-qBdh7A-P.js → ganttDiagram-NO4QXBWP-B20dY8SF.js} +1 -1
- package/dist/control-web/assets/{gitGraphDiagram-IHSO6WYX-BTYub2KT.js → gitGraphDiagram-IHSO6WYX-CAlnqFfW.js} +1 -1
- package/dist/control-web/assets/{highlighted-body-OFNGDK62-DyksUrwu.js → highlighted-body-OFNGDK62-vBlGjC8F.js} +1 -1
- package/dist/control-web/assets/{index-BDaSctIT.js → index-B3g4Kfko.js} +1 -1
- package/dist/control-web/assets/index-BKqZNg1a.js +718 -0
- package/dist/control-web/assets/index-CZrE_F_i.css +32 -0
- package/dist/control-web/assets/{infoDiagram-FWYZ7A6U-ChbQR3Zo.js → infoDiagram-FWYZ7A6U-PaEyeSke.js} +1 -1
- package/dist/control-web/assets/{ishikawaDiagram-FXEZZL3T-C-4_qGzn.js → ishikawaDiagram-FXEZZL3T-BwsgPXGC.js} +1 -1
- package/dist/control-web/assets/{journeyDiagram-5HDEW3XC-B090zN18.js → journeyDiagram-5HDEW3XC-BUEf1NEq.js} +1 -1
- package/dist/control-web/assets/{kanban-definition-HUTT4EX6-RlTcRbPs.js → kanban-definition-HUTT4EX6-CiTCwnJ7.js} +1 -1
- package/dist/control-web/assets/{linear-DTuNxDqu.js → linear-Cs4GSPvX.js} +1 -1
- package/dist/control-web/assets/{mermaid-GHXKKRXX-BkcV3dgg.js → mermaid-GHXKKRXX-C_lUqoOB.js} +6 -6
- package/dist/control-web/assets/{mindmap-definition-LN4V7U3C-DYby41E9.js → mindmap-definition-LN4V7U3C-B8TkylOR.js} +1 -1
- package/dist/control-web/assets/{pegDiagram-2B236MQR-CPK6GaEv.js → pegDiagram-2B236MQR-Bnge_jzz.js} +1 -1
- package/dist/control-web/assets/{pieDiagram-ENE6RG2P-DLCmXuji.js → pieDiagram-ENE6RG2P-DOP7FAKG.js} +1 -1
- package/dist/control-web/assets/{quadrantDiagram-ABIIQ3AL-RIS8r7CA.js → quadrantDiagram-ABIIQ3AL-Cqqu5uu-.js} +1 -1
- package/dist/control-web/assets/{railroadDiagram-RFXS5EU6-B1HB7xsg.js → railroadDiagram-RFXS5EU6-1bk56BMW.js} +1 -1
- package/dist/control-web/assets/{requirementDiagram-TGXJPOKE-Inh_4hU0.js → requirementDiagram-TGXJPOKE-BHVwG79A.js} +1 -1
- package/dist/control-web/assets/{sankeyDiagram-HTMAVEWB-DPF33kPB.js → sankeyDiagram-HTMAVEWB-ghjBFqfs.js} +1 -1
- package/dist/control-web/assets/{sequenceDiagram-DBY2YBRQ-iywKWoYc.js → sequenceDiagram-DBY2YBRQ-DChtyqq5.js} +1 -1
- package/dist/control-web/assets/{sizeCapture-X5ZJPWSS-DlnHubz9.js → sizeCapture-X5ZJPWSS-BNp94nCS.js} +1 -1
- package/dist/control-web/assets/{stateDiagram-2N3HPSRC-CShzll2N.js → stateDiagram-2N3HPSRC-CaFYkZZ2.js} +1 -1
- package/dist/control-web/assets/stateDiagram-v2-6OUMAXLB-CCvEZFYI.js +1 -0
- package/dist/control-web/assets/{swimlanes-5IMT3BWC-CxlQpFBv.js → swimlanes-5IMT3BWC-CV2YWeYv.js} +2 -2
- package/dist/control-web/assets/swimlanesDiagram-G3AALYLV-BFAdJHEB.js +8 -0
- package/dist/control-web/assets/{timeline-definition-FHXFAJF6-Dlx59Xc3.js → timeline-definition-FHXFAJF6-Cq32UWLH.js} +1 -1
- package/dist/control-web/assets/{vennDiagram-L72KCM5P-DLsv4i_t.js → vennDiagram-L72KCM5P-BgBoqPth.js} +1 -1
- package/dist/control-web/assets/{wardleyDiagram-EHGQE667-BazV8fpH.js → wardleyDiagram-EHGQE667-VsC2Gfpu.js} +1 -1
- package/dist/control-web/assets/{xychartDiagram-FW5EYKEG-Bx9uDlYu.js → xychartDiagram-FW5EYKEG-CyFiAunt.js} +1 -1
- package/dist/control-web/index.html +2 -2
- package/dist/desktop-browser-host.d.ts +3 -1
- package/dist/desktop-browser-host.js +39 -4
- package/dist/machine-session-service.d.ts +12 -0
- package/dist/machine-session-service.js +31 -7
- package/dist/remote-runtime-dispatcher.d.ts +1 -1
- package/dist/remote-runtime-dispatcher.js +26 -1
- package/dist/remote-runtime-session-projection.d.ts +1 -0
- package/dist/remote-runtime-session-projection.js +1 -0
- package/dist/server.d.ts +23 -1
- package/dist/server.js +94 -11
- package/dist/session-browser-service.d.ts +24 -4
- package/dist/session-browser-service.js +127 -1
- package/dist/session-pending-inputs.d.ts +40 -0
- package/dist/session-pending-inputs.js +84 -0
- package/dist/session-portal.d.ts +14 -2
- package/dist/session-portal.js +268 -31
- package/package.json +7 -7
- package/dist/control-web/assets/channel-3HG15wfa.js +0 -1
- package/dist/control-web/assets/classDiagram-OUVF2IWQ-WmU4L9YT.js +0 -1
- package/dist/control-web/assets/classDiagram-v2-EOCWNBFH-WmU4L9YT.js +0 -1
- package/dist/control-web/assets/index-B9SAq_63.js +0 -718
- package/dist/control-web/assets/index-CtaYRNgJ.css +0 -32
- package/dist/control-web/assets/stateDiagram-v2-6OUMAXLB-Cdx0fWna.js +0 -1
- package/dist/control-web/assets/swimlanesDiagram-G3AALYLV-CoX0jnUu.js +0 -8
|
@@ -115,7 +115,8 @@ export class MachineSessionService {
|
|
|
115
115
|
limit: limit + 1,
|
|
116
116
|
})).slice(0, limit + 1).map((item) => structuredClone(item));
|
|
117
117
|
const runtime = cloneRuntimeSnapshot(this.ports.runtimeState.snapshot(sessionId));
|
|
118
|
-
const
|
|
118
|
+
const pendingInputs = this.ports.pendingInputs?.snapshotFor(sessionId) ?? [];
|
|
119
|
+
const empty = snapshotPage(sessionId, [], pendingInputs, runtime, false);
|
|
119
120
|
const items = [];
|
|
120
121
|
let itemsJsonBytes = 0;
|
|
121
122
|
for (const item of candidates.slice(0, limit)) {
|
|
@@ -123,14 +124,14 @@ export class MachineSessionService {
|
|
|
123
124
|
const nextCount = items.length + 1;
|
|
124
125
|
const hasMore = candidates.length > nextCount;
|
|
125
126
|
if (items.length > 0 &&
|
|
126
|
-
snapshotPageJsonByteLength(sessionId, nextItemsJsonBytes, item.id, runtime, hasMore) > this.snapshotPageMaxBytes) {
|
|
127
|
+
snapshotPageJsonByteLength(sessionId, nextItemsJsonBytes, item.id, pendingInputs, runtime, hasMore) > this.snapshotPageMaxBytes) {
|
|
127
128
|
break;
|
|
128
129
|
}
|
|
129
130
|
items.push(item);
|
|
130
131
|
itemsJsonBytes = nextItemsJsonBytes;
|
|
131
132
|
}
|
|
132
133
|
return items.length > 0
|
|
133
|
-
? snapshotPage(sessionId, items, runtime, candidates.length > items.length)
|
|
134
|
+
? snapshotPage(sessionId, items, pendingInputs, runtime, candidates.length > items.length)
|
|
134
135
|
: empty;
|
|
135
136
|
}
|
|
136
137
|
/**
|
|
@@ -264,7 +265,7 @@ export class MachineSessionService {
|
|
|
264
265
|
statusCode: 409,
|
|
265
266
|
});
|
|
266
267
|
}
|
|
267
|
-
//
|
|
268
|
+
// Native state is authoritative. Do not make a failed
|
|
268
269
|
// toggle survive reload when the loaded thread rejected it.
|
|
269
270
|
try {
|
|
270
271
|
await updateMode.call(executionPort.runner, sessionId, collaborationMode);
|
|
@@ -670,9 +671,14 @@ export class MachineSessionService {
|
|
|
670
671
|
}
|
|
671
672
|
if (prepared.operationState === "injected" ||
|
|
672
673
|
prepared.operationState === "mirrored") {
|
|
674
|
+
const replayPendingId = prepared.operationState === "injected" && request.clientMessageId
|
|
675
|
+
? this.ports.pendingInputs
|
|
676
|
+
?.findByClientMessageId(sessionId, request.clientMessageId)?.pendingId
|
|
677
|
+
: undefined;
|
|
673
678
|
return {
|
|
674
679
|
ok: true,
|
|
675
680
|
injected: true,
|
|
681
|
+
...(replayPendingId ? { pendingId: replayPendingId } : {}),
|
|
676
682
|
...(includeResponseId && prepared.responseId
|
|
677
683
|
? { responseId: prepared.responseId }
|
|
678
684
|
: {}),
|
|
@@ -732,6 +738,18 @@ export class MachineSessionService {
|
|
|
732
738
|
throw abortReason(signal);
|
|
733
739
|
}
|
|
734
740
|
let result;
|
|
741
|
+
const pendingId = this.ports.pendingInputs && request.clientMessageId
|
|
742
|
+
? this.ports.pendingInputs.record(sessionId, {
|
|
743
|
+
clientMessageId: request.clientMessageId,
|
|
744
|
+
content: (hasContent
|
|
745
|
+
? request.content
|
|
746
|
+
: [{ type: "input_text", text: request.message }]).map((part) => ({ ...part })),
|
|
747
|
+
})
|
|
748
|
+
: undefined;
|
|
749
|
+
const rollbackPendingInput = () => {
|
|
750
|
+
if (pendingId)
|
|
751
|
+
this.ports.pendingInputs?.resolve(sessionId, pendingId);
|
|
752
|
+
};
|
|
735
753
|
try {
|
|
736
754
|
const injectionInput = needsPreparedOperation ? prepared.input : request.message;
|
|
737
755
|
result = turnOptions
|
|
@@ -739,6 +757,7 @@ export class MachineSessionService {
|
|
|
739
757
|
: await execution.runner.injectMessage(sessionId, injectionInput);
|
|
740
758
|
}
|
|
741
759
|
catch (error) {
|
|
760
|
+
rollbackPendingInput();
|
|
742
761
|
const failure = execution.runner.lastLiveSessionFailure?.(sessionId)
|
|
743
762
|
?? liveSessionFailureFrom(error);
|
|
744
763
|
const reason = failure?.message
|
|
@@ -750,6 +769,7 @@ export class MachineSessionService {
|
|
|
750
769
|
}
|
|
751
770
|
const outcome = result.outcome;
|
|
752
771
|
if (outcome === "failed") {
|
|
772
|
+
rollbackPendingInput();
|
|
753
773
|
const failure = execution.runner.lastLiveSessionFailure?.(sessionId);
|
|
754
774
|
const reason = failure?.message
|
|
755
775
|
?? execution.runner.lastLiveSessionError?.(sessionId)
|
|
@@ -760,6 +780,7 @@ export class MachineSessionService {
|
|
|
760
780
|
throw new MachineSessionServiceFailure("outcome_unknown", `live injection ${outcome}`, reason, failure);
|
|
761
781
|
}
|
|
762
782
|
if (outcome !== "injected" && outcome !== "steered") {
|
|
783
|
+
rollbackPendingInput();
|
|
763
784
|
const failure = execution.runner.lastLiveSessionFailure?.(sessionId);
|
|
764
785
|
const reason = failure?.message
|
|
765
786
|
?? execution.runner.lastLiveSessionError?.(sessionId)
|
|
@@ -789,6 +810,7 @@ export class MachineSessionService {
|
|
|
789
810
|
return {
|
|
790
811
|
ok: true,
|
|
791
812
|
injected: true,
|
|
813
|
+
...(pendingId ? { pendingId } : {}),
|
|
792
814
|
...(includeResponseId && result.responseId ? { responseId: result.responseId } : {}),
|
|
793
815
|
...(operationExecution ? { operationExecution } : {}),
|
|
794
816
|
};
|
|
@@ -987,6 +1009,7 @@ export class MachineSessionService {
|
|
|
987
1009
|
this.ports.execution?.runner.stopRunner(sessionId);
|
|
988
1010
|
this.ports.events.close?.(sessionId);
|
|
989
1011
|
await this.ports.pendingMessages?.delete(sessionId);
|
|
1012
|
+
this.ports.pendingInputs?.deleteSession(sessionId);
|
|
990
1013
|
await this.ports.resources?.deleteSession(sessionId);
|
|
991
1014
|
this.ports.registry.remove(sessionId);
|
|
992
1015
|
await this.ports.log.deleteSession(sessionId);
|
|
@@ -1372,10 +1395,11 @@ function decodeListCursor(value) {
|
|
|
1372
1395
|
throw new MachineSessionServiceInputError("cursor is invalid");
|
|
1373
1396
|
}
|
|
1374
1397
|
}
|
|
1375
|
-
function snapshotPage(sessionId, items, runtime, hasMore) {
|
|
1398
|
+
function snapshotPage(sessionId, items, pendingInputs, runtime, hasMore) {
|
|
1376
1399
|
return {
|
|
1377
1400
|
sessionId,
|
|
1378
1401
|
items,
|
|
1402
|
+
pendingInputs,
|
|
1379
1403
|
runtime,
|
|
1380
1404
|
hasMore,
|
|
1381
1405
|
...(hasMore && items.length > 0 ? { nextAfterId: items.at(-1).id } : {}),
|
|
@@ -1383,10 +1407,10 @@ function snapshotPage(sessionId, items, runtime, hasMore) {
|
|
|
1383
1407
|
}
|
|
1384
1408
|
/** Exact UTF-8 size of {@link snapshotPage} without repeatedly serializing the
|
|
1385
1409
|
* complete item array while searching for a page boundary. */
|
|
1386
|
-
function snapshotPageJsonByteLength(sessionId, itemsJsonBytes, finalItemId, runtime, hasMore) {
|
|
1410
|
+
function snapshotPageJsonByteLength(sessionId, itemsJsonBytes, finalItemId, pendingInputs, runtime, hasMore) {
|
|
1387
1411
|
return Buffer.byteLength(`{"sessionId":${JSON.stringify(sessionId)},"items":[`, "utf8")
|
|
1388
1412
|
+ itemsJsonBytes
|
|
1389
|
-
+ Buffer.byteLength(`],"runtime":${JSON.stringify(runtime)},"hasMore":${hasMore}${hasMore ? `,"nextAfterId":${JSON.stringify(finalItemId)}` : ""}}`, "utf8");
|
|
1413
|
+
+ Buffer.byteLength(`],"pendingInputs":${JSON.stringify(pendingInputs)},"runtime":${JSON.stringify(runtime)},"hasMore":${hasMore}${hasMore ? `,"nextAfterId":${JSON.stringify(finalItemId)}` : ""}}`, "utf8");
|
|
1390
1414
|
}
|
|
1391
1415
|
function sessionSummary(id, meta, log, runtimeState, pendingState) {
|
|
1392
1416
|
const createdAt = meta?.createdAt ?? timestampFromEpoch(log?.createdAt, "createdAt");
|
|
@@ -35,7 +35,7 @@ export interface RemoteRuntimeProjectHost {
|
|
|
35
35
|
remove(projectId: string): boolean | Promise<boolean>;
|
|
36
36
|
}
|
|
37
37
|
export type RemoteRuntimeSessionHost = Pick<MachineSessionService, "list" | "snapshot" | "watch" | "interrupt" | "agentOptions" | "launchOptions" | "executionSettings" | "updateExecutionSettings" | "create" | "fork" | "sendMessage" | "resourcePolicy" | "beginResourceUpload" | "writeResourceUploadChunk" | "commitResourceUpload" | "getResource" | "readResource" | "deleteResource" | "getFile" | "readFile" | "getWorkspaceFile" | "readWorkspaceFile" | "enqueueMessage" | "startTerminal" | "delete" | "resolveInteraction">;
|
|
38
|
-
export type RemoteRuntimeBrowserHost = Pick<SessionBrowserService, "getState" | "open" | "close" | "createPage" | "closePage" | "activatePage" | "navigatePage" | "goBack" | "goForward" | "reload">;
|
|
38
|
+
export type RemoteRuntimeBrowserHost = Pick<SessionBrowserService, "getState" | "getRequestHeaders" | "setRequestHeaders" | "open" | "close" | "createPage" | "closePage" | "activatePage" | "navigatePage" | "goBack" | "goForward" | "reload">;
|
|
39
39
|
export type RemoteRuntimeSessionEmulatorHost = Pick<SessionEmulatorService, "getState" | "listDevices" | "attach" | "detach" | "tap" | "type" | "button" | "rotate" | "launch" | "gesture" | "releaseDevice" | "stopDevice">;
|
|
40
40
|
export interface OpenRemoteRuntimeSessionEvents {
|
|
41
41
|
sessionId: string;
|
|
@@ -176,6 +176,10 @@ export class RemoteRuntimeDispatcher {
|
|
|
176
176
|
return await this.withSessions(request, (sessions) => sessions.resolveInteraction(request.params.sessionId, request.params.interactionId, request.params.resolution));
|
|
177
177
|
case "browser.state.get":
|
|
178
178
|
return await this.withBrowsers(request, (browsers) => browsers.getState(request.params));
|
|
179
|
+
case "browser.request-headers.get":
|
|
180
|
+
return await this.withBrowsers(request, (browsers) => browsers.getRequestHeaders(request.params));
|
|
181
|
+
case "browser.request-headers.set":
|
|
182
|
+
return await this.withBrowsers(request, (browsers) => browsers.setRequestHeaders(request.params));
|
|
179
183
|
case "browser.open":
|
|
180
184
|
return await this.withBrowsers(request, (browsers) => browsers.open(request.params));
|
|
181
185
|
case "browser.close":
|
|
@@ -198,7 +202,7 @@ export class RemoteRuntimeDispatcher {
|
|
|
198
202
|
return rpcError(request.id, "method_not_found", "Remote Runtime method is not supported");
|
|
199
203
|
}
|
|
200
204
|
catch (error) {
|
|
201
|
-
this.options.onError?.(error, request);
|
|
205
|
+
this.options.onError?.(error, diagnosticRequest(request));
|
|
202
206
|
const mapped = mapHostError(request, error);
|
|
203
207
|
return rpcError(request.id, mapped.code, mapped.message);
|
|
204
208
|
}
|
|
@@ -302,6 +306,20 @@ export class RemoteRuntimeDispatcher {
|
|
|
302
306
|
return rpcResult(request, await invoke(browsers));
|
|
303
307
|
}
|
|
304
308
|
}
|
|
309
|
+
function diagnosticRequest(request) {
|
|
310
|
+
if (request.method !== "browser.request-headers.set")
|
|
311
|
+
return request;
|
|
312
|
+
return {
|
|
313
|
+
...request,
|
|
314
|
+
params: {
|
|
315
|
+
...request.params,
|
|
316
|
+
headers: request.params.headers.map((header) => ({
|
|
317
|
+
...header,
|
|
318
|
+
value: "[redacted]",
|
|
319
|
+
})),
|
|
320
|
+
},
|
|
321
|
+
};
|
|
322
|
+
}
|
|
305
323
|
function mapHostError(request, error) {
|
|
306
324
|
if (error instanceof ProjectNotFoundError) {
|
|
307
325
|
return { code: "not_found", message: "Runtime Project was not found" };
|
|
@@ -322,6 +340,13 @@ function mapHostError(request, error) {
|
|
|
322
340
|
return { code: "not_found", message: "Browser resource was not found" };
|
|
323
341
|
case "generation_mismatch":
|
|
324
342
|
return { code: "conflict", message: "Browser generation is stale" };
|
|
343
|
+
case "revision_mismatch":
|
|
344
|
+
return { code: "conflict", message: "Browser request headers revision is stale" };
|
|
345
|
+
case "unsupported":
|
|
346
|
+
return {
|
|
347
|
+
code: "failed_precondition",
|
|
348
|
+
message: "Browser request headers are unsupported by the active Browser Host",
|
|
349
|
+
};
|
|
325
350
|
case "unavailable":
|
|
326
351
|
case "capacity":
|
|
327
352
|
case "shutting_down":
|
|
@@ -9,6 +9,7 @@ export declare function projectRemoteRuntimeSessionListResult(value: unknown): R
|
|
|
9
9
|
export declare function projectRemoteRuntimeSessionSnapshotResult(value: {
|
|
10
10
|
sessionId: string;
|
|
11
11
|
items: SessionItem[];
|
|
12
|
+
pendingInputs: NonNullable<RemoteRuntimeSessionSnapshotResult["pendingInputs"]>;
|
|
12
13
|
runtime: unknown;
|
|
13
14
|
hasMore: boolean;
|
|
14
15
|
nextAfterId?: string;
|
|
@@ -27,6 +27,7 @@ export function projectRemoteRuntimeSessionSnapshotResult(value) {
|
|
|
27
27
|
const candidate = {
|
|
28
28
|
sessionId: value.sessionId,
|
|
29
29
|
items,
|
|
30
|
+
pendingInputs: structuredClone(value.pendingInputs),
|
|
30
31
|
runtime,
|
|
31
32
|
hasMore: value.hasMore,
|
|
32
33
|
...(value.nextAfterId === undefined ? {} : { nextAfterId: value.nextAfterId }),
|
package/dist/server.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ import type { RemoteRuntimeRpcMethod, RemoteRuntimeRpcParams, RemoteRuntimeRpcRe
|
|
|
15
15
|
import { RunnerManager, type CodexSessionStore, type RunnerSessionContextProvider } from "@rynx-ai/runtime";
|
|
16
16
|
import { type ControlPlaneDeps, type LocalSessionResourceHost, type SessionResourceLifecycle } from "./control-api.js";
|
|
17
17
|
import type { MachineSessionService } from "./machine-session-service.js";
|
|
18
|
+
import type { MachineSessionPendingInputPort } from "./session-pending-inputs.js";
|
|
18
19
|
import type { DaemonRuntimeHost } from "./remote-runtime.js";
|
|
19
20
|
import { type AttachDesktopBrowserHostServerOptions } from "./desktop-browser-host.js";
|
|
20
21
|
import { type SessionPortalAuthorizationPorts } from "./session-portal.js";
|
|
@@ -25,11 +26,14 @@ import type { SessionEmulatorService } from "./session-emulator-service.js";
|
|
|
25
26
|
import { type SessionTerminalHost } from "./session-terminal-host.js";
|
|
26
27
|
import type { ProviderCliManagementHost } from "./provider-cli-host.js";
|
|
27
28
|
import { type RuntimeWebAccessPolicy } from "./runtime-web-auth.js";
|
|
29
|
+
import type { SessionBrowserRequestHeadersPort } from "./session-browser-service.js";
|
|
28
30
|
export type { ProviderCliManagementHost, ProviderCliStatusHost, } from "./provider-cli-host.js";
|
|
29
31
|
export { MachineSessionService, MachineSessionServiceFailure, MachineSessionServiceInputError, synthesizeSessionTitle, } from "./machine-session-service.js";
|
|
32
|
+
export { SessionPendingInputIndex } from "./session-pending-inputs.js";
|
|
30
33
|
export type { MachineSessionAgentCatalogPort, MachineSessionCreateInput, MachineSessionCreateResult, MachineSessionDeleteResult, MachineSessionForkInput, MachineSessionForkOperationRecord, MachineSessionForkOperationState, MachineSessionForkResult, MachineSessionForkStorePort, MachineSessionNativeRotationInput, MachineSessionInterruptPort, MachineSessionInterruptResult, MachineSessionInteractionResult, MachineSessionListInput, MachineSessionListPage, MachineSessionMessageResult, MachineSessionMessageEnqueueResult, MachineSessionMessageInput, MachineSessionMessageOperationState, MachineSessionPendingMessage, MachineSessionPendingMessagePort, MachineSessionPreparedInput, MachineSessionResourcePort, MachineSessionRunExecutionSelection, MachineSessionRunExecutionSnapshot, MachineSessionRunnerPort, MachineSessionRuntimeStatePort, MachineSessionServiceFailureCode, MachineSessionServiceOptions, MachineSessionServicePorts, MachineSessionSnapshotInput, MachineSessionSnapshotPage, MachineSessionWatch, StartedMachineSessionRun, } from "./machine-session-service.js";
|
|
34
|
+
export type { MachineSessionPendingInput, MachineSessionPendingInputPort, } from "./session-pending-inputs.js";
|
|
31
35
|
export { SessionBrowserHostError, SessionBrowserService, SessionBrowserServiceError, SessionBrowserSurfaceUnsupportedError, } from "./session-browser-service.js";
|
|
32
|
-
export type { SessionBrowserHost, SessionBrowserHostCreateInput, SessionBrowserHostErrorCode, SessionBrowserHostEvent, SessionBrowserHostHandle, SessionBrowserHostPage, SessionBrowserHostSurfaceFrame, SessionBrowserHostSurfaceOpenInput, SessionBrowserHostSurfaceSource, SessionBrowserHostSurfaceTrustedInput, SessionBrowserHostSurfaceViewport, SessionBrowserHostSnapshot, SessionBrowserInspectionEndpoint, SessionBrowserInspectionTarget, SessionBrowserRegistryPort, SessionBrowserServiceErrorCode, SessionBrowserServiceOptions, SessionBrowserServicePorts, SessionBrowserSurfaceOpenInput, SessionBrowserSurfaceSource, } from "./session-browser-service.js";
|
|
36
|
+
export type { SessionBrowserHost, SessionBrowserHostCreateInput, SessionBrowserHostErrorCode, SessionBrowserHostEvent, SessionBrowserHostHandle, SessionBrowserHostPage, SessionBrowserHostSurfaceFrame, SessionBrowserHostSurfaceOpenInput, SessionBrowserHostSurfaceSource, SessionBrowserHostSurfaceTrustedInput, SessionBrowserHostSurfaceViewport, SessionBrowserHostSnapshot, SessionBrowserInspectionEndpoint, SessionBrowserInspectionTarget, SessionBrowserRegistryPort, SessionBrowserRequestHeadersPort, SessionBrowserServiceErrorCode, SessionBrowserServiceOptions, SessionBrowserServicePorts, SessionBrowserSurfaceOpenInput, SessionBrowserSurfaceSource, } from "./session-browser-service.js";
|
|
33
37
|
export { SessionEmulatorBindingConflictError, SessionEmulatorService, SessionEmulatorServiceError, } from "./session-emulator-service.js";
|
|
34
38
|
export type { SessionEmulatorBindingRecord, SessionEmulatorBindingStore, SessionEmulatorServiceErrorCode, SessionEmulatorServiceOptions, SessionEmulatorSurface, } from "./session-emulator-service.js";
|
|
35
39
|
export { SessionBrowserSurfaceCoordinator } from "./session-browser-surface-coordinator.js";
|
|
@@ -152,6 +156,7 @@ export interface PluginRuntimeHostServices {
|
|
|
152
156
|
sessionRegistry: SessionRegistry;
|
|
153
157
|
sessionRuns: Pick<MachineSessionService, "startRun">;
|
|
154
158
|
sessionFiles: Pick<MachineSessionService, "resolveResourcePath">;
|
|
159
|
+
sessionBrowserRequestHeaders?: SessionBrowserRequestHeadersPort;
|
|
155
160
|
agentCatalog: {
|
|
156
161
|
list(): Promise<PluginAgentSummary[]>;
|
|
157
162
|
get(id: string): Promise<PluginAgentSummary | null>;
|
|
@@ -163,6 +168,15 @@ export interface PluginRuntimeHostServices {
|
|
|
163
168
|
sessionActivity(sessionId: string): PluginSessionActivitySnapshot;
|
|
164
169
|
interruptSession(sessionId: string): Promise<boolean>;
|
|
165
170
|
terminateSession?(sessionId: string): Promise<boolean>;
|
|
171
|
+
sessionTimeline?: {
|
|
172
|
+
hasItem(sessionId: string, itemId: string): Promise<boolean>;
|
|
173
|
+
projectText(input: {
|
|
174
|
+
sessionId: string;
|
|
175
|
+
responseId: string;
|
|
176
|
+
itemId: string;
|
|
177
|
+
text: string;
|
|
178
|
+
}): Promise<void>;
|
|
179
|
+
};
|
|
166
180
|
resolveSessionInteraction(sessionId: string, interactionId: string, resolution: SessionInteractionResolution): Promise<{
|
|
167
181
|
disposition: "applied" | "already_resolved" | "not_found" | "invalid";
|
|
168
182
|
}>;
|
|
@@ -434,6 +448,14 @@ export declare class SessionMirrorQueue {
|
|
|
434
448
|
export declare function createSessionRuntimeServices(input: {
|
|
435
449
|
config: AppConfig;
|
|
436
450
|
sessionLog?: SessionLogStore;
|
|
451
|
+
pendingInputs?: MachineSessionPendingInputPort;
|
|
452
|
+
onPendingInputPersisted?: (input: {
|
|
453
|
+
sessionId: string;
|
|
454
|
+
pendingId: string;
|
|
455
|
+
clientMessageId: string;
|
|
456
|
+
responseId: string;
|
|
457
|
+
messageItemId: string;
|
|
458
|
+
}) => void | Promise<void>;
|
|
437
459
|
onMirrorError?: (error: unknown, sessionId: string) => void;
|
|
438
460
|
sessionContextProvider?: RunnerSessionContextProvider;
|
|
439
461
|
admissionOpen?: () => boolean;
|
package/dist/server.js
CHANGED
|
@@ -17,6 +17,7 @@ import { SessionRuntimeIndex } from "./session-runtime-index.js";
|
|
|
17
17
|
import { createRunnerSessionTerminalHost, } from "./session-terminal-host.js";
|
|
18
18
|
import { runtimeWebAccessPolicyForBindHost, } from "./runtime-web-auth.js";
|
|
19
19
|
export { MachineSessionService, MachineSessionServiceFailure, MachineSessionServiceInputError, synthesizeSessionTitle, } from "./machine-session-service.js";
|
|
20
|
+
export { SessionPendingInputIndex } from "./session-pending-inputs.js";
|
|
20
21
|
export { SessionBrowserHostError, SessionBrowserService, SessionBrowserServiceError, SessionBrowserSurfaceUnsupportedError, } from "./session-browser-service.js";
|
|
21
22
|
export { SessionEmulatorBindingConflictError, SessionEmulatorService, SessionEmulatorServiceError, } from "./session-emulator-service.js";
|
|
22
23
|
export { SessionBrowserSurfaceCoordinator } from "./session-browser-surface-coordinator.js";
|
|
@@ -68,11 +69,28 @@ export function createSessionRuntimeServices(input) {
|
|
|
68
69
|
const sessionBus = new InMemorySessionBus();
|
|
69
70
|
const sessionRuntimeIndex = new SessionRuntimeIndex();
|
|
70
71
|
const sessionMirrorQueue = new SessionMirrorQueue(async (sessionId, event) => {
|
|
71
|
-
const
|
|
72
|
+
const generatedImageFinalized = await finalizeGeneratedImageEvent(sessionId, event, input);
|
|
73
|
+
const pendingFinalized = resolvePendingInputEvent(sessionId, generatedImageFinalized, input.pendingInputs);
|
|
74
|
+
const finalized = pendingFinalized.event;
|
|
72
75
|
sessionRuntimeIndex.observe(sessionId, finalized);
|
|
73
76
|
await persistSessionEvent(sessionId, finalized, {
|
|
74
77
|
sessionLog: input.sessionLog,
|
|
75
78
|
sessionBus,
|
|
79
|
+
...(input.onPendingInputPersisted
|
|
80
|
+
? {
|
|
81
|
+
onInputPersisted: async (persistedEvent) => {
|
|
82
|
+
if (!persistedEvent.clearedPendingId || !pendingFinalized.clientMessageId)
|
|
83
|
+
return;
|
|
84
|
+
await input.onPendingInputPersisted({
|
|
85
|
+
sessionId,
|
|
86
|
+
pendingId: persistedEvent.clearedPendingId,
|
|
87
|
+
clientMessageId: pendingFinalized.clientMessageId,
|
|
88
|
+
responseId: persistedEvent.item.responseId,
|
|
89
|
+
messageItemId: persistedEvent.item.id,
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
: {}),
|
|
76
94
|
});
|
|
77
95
|
});
|
|
78
96
|
const mirrorSessionEvent = (sessionId, event) => {
|
|
@@ -97,6 +115,47 @@ export function createSessionRuntimeServices(input) {
|
|
|
97
115
|
publishSessionEvent: mirrorSessionEvent,
|
|
98
116
|
};
|
|
99
117
|
}
|
|
118
|
+
/** Drain the oldest pending web input when the Provider transcript produces a
|
|
119
|
+
* real user record. The transcript is the only durable writer; the returned id
|
|
120
|
+
* lets clients replace the exact temporary bubble. */
|
|
121
|
+
function resolvePendingInputEvent(sessionId, event, pendingInputs) {
|
|
122
|
+
if (event.type !== "session.input.consumed" ||
|
|
123
|
+
event.item.type !== "message" ||
|
|
124
|
+
event.item.data.role !== "user" ||
|
|
125
|
+
event.item.data.isMeta) {
|
|
126
|
+
return { event };
|
|
127
|
+
}
|
|
128
|
+
const pending = pendingInputs?.resolveOldest(sessionId);
|
|
129
|
+
if (!pending)
|
|
130
|
+
return { event };
|
|
131
|
+
const fileParts = pending.content.filter((part) => part.type === "input_image" || part.type === "input_file");
|
|
132
|
+
const alreadyHasFiles = event.item.data.content.some((part) => part.type === "input_image" || part.type === "input_file");
|
|
133
|
+
const containsInternalResourceMarker = event.item.data.content.some((part) => part.type === "input_text" &&
|
|
134
|
+
/\[\[RYNX_(?:IMAGE|FILE)_RESOURCE\s/.test(part.text));
|
|
135
|
+
const content = containsInternalResourceMarker
|
|
136
|
+
? pending.content
|
|
137
|
+
: fileParts.length > 0 && !alreadyHasFiles
|
|
138
|
+
? [...fileParts, ...event.item.data.content]
|
|
139
|
+
: event.item.data.content;
|
|
140
|
+
return {
|
|
141
|
+
clientMessageId: pending.clientMessageId,
|
|
142
|
+
event: {
|
|
143
|
+
...event,
|
|
144
|
+
clearedPendingId: pending.pendingId,
|
|
145
|
+
...(content !== event.item.data.content
|
|
146
|
+
? {
|
|
147
|
+
item: {
|
|
148
|
+
...event.item,
|
|
149
|
+
data: {
|
|
150
|
+
...event.item.data,
|
|
151
|
+
content,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
}
|
|
155
|
+
: {}),
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
100
159
|
async function finalizeGeneratedImageEvent(sessionId, event, input) {
|
|
101
160
|
if (event.type !== "response.output_item.done" ||
|
|
102
161
|
event.item.type !== "function_call_output") {
|
|
@@ -309,6 +368,36 @@ export async function startServer({ config = loadConfig(), control, sessionLog,
|
|
|
309
368
|
},
|
|
310
369
|
interruptSession: (sessionId) => runnerManager.interruptLiveSession(sessionId),
|
|
311
370
|
terminateSession: (sessionId) => runnerManager.terminateLiveSession(sessionId),
|
|
371
|
+
...(sessionLog
|
|
372
|
+
? {
|
|
373
|
+
sessionTimeline: {
|
|
374
|
+
hasItem: async (sessionId, itemId) => Boolean(await sessionLog.get(sessionId, itemId)),
|
|
375
|
+
projectText: async ({ sessionId, responseId, itemId, text }) => {
|
|
376
|
+
const event = {
|
|
377
|
+
type: "response.output_item.done",
|
|
378
|
+
responseId,
|
|
379
|
+
item: {
|
|
380
|
+
id: itemId,
|
|
381
|
+
sessionId,
|
|
382
|
+
position: -1,
|
|
383
|
+
responseId,
|
|
384
|
+
status: "completed",
|
|
385
|
+
createdAt: Date.now(),
|
|
386
|
+
createdBy: "plugin_projection",
|
|
387
|
+
type: "message",
|
|
388
|
+
data: { role: "assistant", content: [{ type: "output_text", text }] },
|
|
389
|
+
},
|
|
390
|
+
};
|
|
391
|
+
// Projection is an acknowledged durable operation, unlike the
|
|
392
|
+
// provider mirror's deliberately best-effort live fan-out.
|
|
393
|
+
// Append first and only then publish; a failed append leaves the
|
|
394
|
+
// projection ledger pending so the Plugin can retry safely.
|
|
395
|
+
await sessionLog.append(sessionId, [event.item]);
|
|
396
|
+
sessionServices.sessionBus.publish(sessionId, event);
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
}
|
|
400
|
+
: {}),
|
|
312
401
|
resolveSessionInteraction: (sessionId, interactionId, resolution) => runnerManager.resolveInteraction(sessionId, interactionId, resolution),
|
|
313
402
|
...(sessionPortalConfig
|
|
314
403
|
? {
|
|
@@ -392,6 +481,10 @@ export async function startServer({ config = loadConfig(), control, sessionLog,
|
|
|
392
481
|
webSocketServers.push(attachEmulatorTouchWs(server, { emulator: control.emulator }));
|
|
393
482
|
}
|
|
394
483
|
startupWebSocketServers = webSocketServers;
|
|
484
|
+
// Plugin recovery fences and revokes any product-owned Portal authority.
|
|
485
|
+
// Do not expose the listener until every enabled Plugin got its serialized
|
|
486
|
+
// startup attempt; startPluginRuntimes absorbs individual failures.
|
|
487
|
+
await (pluginRuntime?.startPluginRuntimes() ?? Promise.resolve());
|
|
395
488
|
if (sessionPortalConfig) {
|
|
396
489
|
sessionPortalServer = await startSessionPortal({
|
|
397
490
|
host: config.RYNX_SESSION_PORTAL_HOST,
|
|
@@ -403,15 +496,6 @@ export async function startServer({ config = loadConfig(), control, sessionLog,
|
|
|
403
496
|
shutdownSignal: controlShutdown.signal,
|
|
404
497
|
});
|
|
405
498
|
}
|
|
406
|
-
const startup = pluginRuntime?.startPluginRuntimes() ?? Promise.resolve();
|
|
407
|
-
void startup.catch((error) => {
|
|
408
|
-
console.error(JSON.stringify({
|
|
409
|
-
level: "error",
|
|
410
|
-
type: "plugin-runtime",
|
|
411
|
-
event: "startup_failed",
|
|
412
|
-
error: error instanceof Error ? error.message : String(error),
|
|
413
|
-
}));
|
|
414
|
-
});
|
|
415
499
|
resolve(bindServerLifecycle(server, {
|
|
416
500
|
fence: () => {
|
|
417
501
|
controlShutdown.abort(new Error("Rynx server is shutting down"));
|
|
@@ -422,7 +506,6 @@ export async function startServer({ config = loadConfig(), control, sessionLog,
|
|
|
422
506
|
sessionPortalServer?.shutdown() ?? Promise.resolve(),
|
|
423
507
|
]).then(() => undefined),
|
|
424
508
|
cleanup: async () => runCleanupSteps([
|
|
425
|
-
() => startup.catch(() => undefined),
|
|
426
509
|
() => Promise.resolve(daemonManagement?.pluginManagement?.dispose?.()),
|
|
427
510
|
() => pluginRuntime?.dispose() ?? Promise.resolve(),
|
|
428
511
|
() => runnerManager.stop(),
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import type { AdmissionReservation } from "@rynx-ai/core";
|
|
2
|
-
import { type RuntimeBrowserCloseParams, type RuntimeBrowserCloseResult, type RuntimeBrowserExecutionBackend, type RuntimeBrowserOpenParams, type RuntimeBrowserPageCreateParams, type RuntimeBrowserPageMutationParams, type RuntimeBrowserPageNavigateParams, type RuntimeBrowserState, type RuntimeBrowserStateGetParams } from "@rynx-ai/protocol/runtime-browser";
|
|
2
|
+
import { type RuntimeBrowserCloseParams, type RuntimeBrowserCloseResult, type RuntimeBrowserExecutionBackend, type RuntimeBrowserOpenParams, type RuntimeBrowserPageCreateParams, type RuntimeBrowserPageMutationParams, type RuntimeBrowserPageNavigateParams, type RuntimeBrowserRequestHeadersConfig, type RuntimeBrowserRequestHeadersGetParams, type RuntimeBrowserRequestHeadersPolicy, type RuntimeBrowserRequestHeadersSetParams, type RuntimeBrowserState, type RuntimeBrowserStateGetParams } from "@rynx-ai/protocol/runtime-browser";
|
|
3
3
|
import type { RuntimeBrowserSurfaceFormat, RuntimeBrowserSurfaceInputEvent } from "@rynx-ai/protocol/runtime-browser-surface";
|
|
4
4
|
import { type RuntimeBrowserEndpointDescriptor } from "@rynx-ai/protocol/runtime-browser-bootstrap";
|
|
5
5
|
export interface SessionBrowserHostCreateInput {
|
|
6
6
|
sessionId: string;
|
|
7
7
|
browserGeneration: number;
|
|
8
|
+
/** Required at this internal boundary so every Host installs the policy
|
|
9
|
+
* before it permits the first navigation. Wire-version compatibility stays
|
|
10
|
+
* inside the concrete Host adapter. */
|
|
11
|
+
requestHeaders: RuntimeBrowserRequestHeadersConfig;
|
|
8
12
|
url?: string;
|
|
9
13
|
}
|
|
10
14
|
/** Generation-scoped physical page state. `hostPageId` never leaves the service. */
|
|
@@ -136,6 +140,8 @@ export interface SessionBrowserHostHandle {
|
|
|
136
140
|
goBack(hostPageId: string): Promise<void>;
|
|
137
141
|
goForward(hostPageId: string): Promise<void>;
|
|
138
142
|
reload(hostPageId: string): Promise<void>;
|
|
143
|
+
/** Replaces the Session-wide desired request Header projection for this generation. */
|
|
144
|
+
setRequestHeaders(config: RuntimeBrowserRequestHeadersConfig): Promise<void>;
|
|
139
145
|
close(): Promise<void>;
|
|
140
146
|
}
|
|
141
147
|
/** Physical Browser factory selected by the Runtime composition root. */
|
|
@@ -156,19 +162,26 @@ export interface SessionBrowserServiceOptions {
|
|
|
156
162
|
pageIdFactory?: () => string;
|
|
157
163
|
/** Injectable boot nonce; production randomization fences stale pre-restart mutations. */
|
|
158
164
|
bootGenerationSeed?: number;
|
|
165
|
+
/** Injectable only for deterministic CAS tests; production uses 128 random bits. */
|
|
166
|
+
requestHeaderRevisionSeed?: string;
|
|
159
167
|
/**
|
|
160
168
|
* Synchronous daemon admission fence. A successful reservation is held until
|
|
161
169
|
* Browser open has either failed or registered the physical Host handle.
|
|
162
170
|
*/
|
|
163
171
|
admissionReserve?: () => AdmissionReservation | undefined;
|
|
164
172
|
}
|
|
165
|
-
export type SessionBrowserHostErrorCode = "unavailable" | "page_not_found" | "capacity" | "outcome_unknown";
|
|
173
|
+
export type SessionBrowserHostErrorCode = "unavailable" | "unsupported" | "page_not_found" | "capacity" | "outcome_unknown";
|
|
166
174
|
/** Expected failure reported by a Browser Host implementation. */
|
|
167
175
|
export declare class SessionBrowserHostError extends Error {
|
|
168
176
|
readonly code: SessionBrowserHostErrorCode;
|
|
169
177
|
constructor(code: SessionBrowserHostErrorCode, message: string, options?: ErrorOptions);
|
|
170
178
|
}
|
|
171
|
-
|
|
179
|
+
/** Narrow Session-owned policy port used by transports and Plugin hosting. */
|
|
180
|
+
export interface SessionBrowserRequestHeadersPort {
|
|
181
|
+
getRequestHeaders(input: RuntimeBrowserRequestHeadersGetParams): Promise<RuntimeBrowserRequestHeadersPolicy>;
|
|
182
|
+
setRequestHeaders(input: RuntimeBrowserRequestHeadersSetParams): Promise<RuntimeBrowserRequestHeadersPolicy>;
|
|
183
|
+
}
|
|
184
|
+
export type SessionBrowserServiceErrorCode = "invalid_request" | "not_found" | "generation_mismatch" | "revision_mismatch" | "unsupported" | "unavailable" | "capacity" | "host_failure" | "outcome_unknown" | "shutting_down";
|
|
172
185
|
/** Stable application error; transports map the code without exposing Host diagnostics. */
|
|
173
186
|
export declare class SessionBrowserServiceError extends Error {
|
|
174
187
|
readonly code: SessionBrowserServiceErrorCode;
|
|
@@ -178,15 +191,18 @@ export declare class SessionBrowserServiceError extends Error {
|
|
|
178
191
|
* Transport-neutral owner of the Runtime -> Session -> Browser -> Page model.
|
|
179
192
|
* Every operation for one Session shares one queue; different Sessions remain independent.
|
|
180
193
|
*/
|
|
181
|
-
export declare class SessionBrowserService {
|
|
194
|
+
export declare class SessionBrowserService implements SessionBrowserRequestHeadersPort {
|
|
182
195
|
private readonly ports;
|
|
183
196
|
private readonly records;
|
|
184
197
|
private readonly generations;
|
|
198
|
+
private readonly requestHeaderPolicies;
|
|
185
199
|
private readonly queues;
|
|
186
200
|
private readonly deletingSessions;
|
|
187
201
|
private readonly observers;
|
|
188
202
|
private readonly pageIdFactory;
|
|
189
203
|
private readonly bootGenerationSeed;
|
|
204
|
+
private readonly requestHeaderRevisionSeed;
|
|
205
|
+
private requestHeaderRevision;
|
|
190
206
|
private readonly admissionReserve?;
|
|
191
207
|
private shuttingDown;
|
|
192
208
|
private closeAllPromise?;
|
|
@@ -205,6 +221,8 @@ export declare class SessionBrowserService {
|
|
|
205
221
|
*/
|
|
206
222
|
getInspectionPageEndpoint(input: RuntimeBrowserPageMutationParams): Promise<SessionBrowserInspectionEndpoint>;
|
|
207
223
|
getState(input: RuntimeBrowserStateGetParams): Promise<RuntimeBrowserState | null>;
|
|
224
|
+
getRequestHeaders(input: RuntimeBrowserRequestHeadersGetParams): Promise<RuntimeBrowserRequestHeadersPolicy>;
|
|
225
|
+
setRequestHeaders(input: RuntimeBrowserRequestHeadersSetParams): Promise<RuntimeBrowserRequestHeadersPolicy>;
|
|
208
226
|
/**
|
|
209
227
|
* Runtime-local automation handoff. This method is deliberately absent from
|
|
210
228
|
* RemoteRuntimeBrowserHost and Direct RPC so a CDP endpoint cannot cross a
|
|
@@ -233,6 +251,8 @@ export declare class SessionBrowserService {
|
|
|
233
251
|
private closeEveryRecord;
|
|
234
252
|
private createBrowser;
|
|
235
253
|
private reserveOpenAdmission;
|
|
254
|
+
private currentRequestHeaders;
|
|
255
|
+
private nextRequestHeadersRevision;
|
|
236
256
|
private closeUnavailableForRecreate;
|
|
237
257
|
private pageMutation;
|
|
238
258
|
private pageMutationParsed;
|