| 1 | import type { SessionOperationAuthority } from "./useResourceOperations"; |
| 2 | import type { RemoteSessionApi } from "../lib/useRemoteSession"; |
| 3 | import type { RemoteTabRefView } from "../lib/types"; |
| 4 | import type { RemoteNavigationCommand } from "../lib/remoteNavigationCommands"; |
| 5 | import { CommandCancelled } from "../lib/commandOutcome"; |
| 6 | |
| 7 | type RemoteSendPorts = Pick<RemoteSessionApi, "compact" | "runManagementCommand" | "setModel" | "setEffort"> & { |
| 8 | send: (display: string, submit: string) => Promise<void>; |
| 9 | applyGoal: (tab: string, goal: string) => Promise<unknown>; |
| 10 | requestClear: () => void; |
| 11 | newSession: RemoteNavigationCommand; |
| 12 | }; |
| 13 | export type RemoteSendInput = { |
| 14 | tabId: string; |
| 15 | remote?: RemoteTabRefView; |
| 16 | activateGoal: boolean; |
| 17 | display: string; |
| 18 | submit: string; |
| 19 | commandText: string; |
| 20 | command: ReturnType<typeof import("../lib/useRemoteComposerIntegration").remoteRuntimeCommand>; |
| 21 | ports: RemoteSendPorts; |
| 22 | }; |
| 23 | |
| 24 | export async function executeRemoteSend(input: RemoteSendInput, authority: SessionOperationAuthority): Promise<void> { |
| 25 | const { command, ports } = input; |
| 26 | authority.checkpoint(); |
| 27 | if (command?.method === "clearSession") { if (authority.ownsUI()) ports.requestClear(); return; } |
| 28 | if (command?.method === "newSession") { |
| 29 | if (input.remote && authority.ownsUI()) { |
| 30 | const outcome = await ports.newSession(input.remote, { newSession: true }); |
| 31 | if (outcome.status === "failed") throw outcome.error; |
| 32 | if (outcome.status === "cancelled") throw new CommandCancelled(outcome.reason); |
| 33 | } |
| 34 | return; |
| 35 | } |
| 36 | if (command?.method === "compact") return ports.compact(command.value); |
| 37 | if (command?.method === "runManagementCommand") return ports.runManagementCommand(input.commandText, command.rehydrate); |
| 38 | if (command?.method === "setModel" || command?.method === "setEffort") return ports[command.method](command.value); |
| 39 | if (input.activateGoal) { |
| 40 | await ports.applyGoal(input.tabId, input.commandText); |
| 41 | authority.checkpoint(); |
| 42 | } |
| 43 | await ports.send(input.display, input.submit); |
| 44 | } |
| 45 | |
| 46 | export type ComposerRuntimeInput = { |
| 47 | tabId: string; |
| 48 | remote: boolean; |
| 49 | action: "pause" | "resume" | "effort"; |
| 50 | level?: string; |
| 51 | ports: Pick<RemoteSessionApi, "pauseGoal" | "resumeGoal" | "setEffort"> & { |
| 52 | pauseLocal: (tab: string) => Promise<unknown>; |
| 53 | resumeLocal: (tab: string) => Promise<unknown>; |
| 54 | effortLocal: (tab: string, level: string) => Promise<void>; |
| 55 | }; |
| 56 | }; |
| 57 | export async function executeComposerRuntime(input: ComposerRuntimeInput, authority: SessionOperationAuthority) { |
| 58 | authority.checkpoint(); |
| 59 | const { ports, tabId, remote } = input; |
| 60 | if (input.action === "pause") await (remote ? ports.pauseGoal() : ports.pauseLocal(tabId)); |
| 61 | else if (input.action === "resume") await (remote ? ports.resumeGoal() : ports.resumeLocal(tabId)); |
| 62 | else await (remote ? ports.setEffort(input.level ?? "") : ports.effortLocal(tabId, input.level ?? "")); |
| 63 | } |
| 64 |