@rynx-ai/server 0.1.0 → 0.1.9
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/browser-surface-control-queue.d.ts +42 -0
- package/dist/browser-surface-control-queue.js +187 -0
- package/dist/browser-surface-ws.d.ts +14 -0
- package/dist/browser-surface-ws.js +355 -0
- package/dist/control-api.d.ts +59 -4
- package/dist/control-api.js +2213 -132
- package/dist/control-web/assets/highlighted-body-OFNGDK62-e-w61YLy.js +1 -0
- package/dist/control-web/assets/index-BQ7XVBKO.css +32 -0
- package/dist/control-web/assets/index-ClpzuBJx.js +606 -0
- package/dist/control-web/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/control-web/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/control-web/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/control-web/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/control-web/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/control-web/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/control-web/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/control-web/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/dist/control-web/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/dist/control-web/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/dist/control-web/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/dist/control-web/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/dist/control-web/assets/mermaid-GHXKKRXX-DZn7Hbr2.js +131 -0
- package/dist/control-web/assets/rynx-wordmark-LL1QRYHD.png +0 -0
- package/dist/control-web/favicon.png +0 -0
- package/dist/control-web/favicon.svg +38 -0
- package/dist/control-web/index.html +16 -0
- package/dist/control-web-dist.d.ts +1 -1
- package/dist/control-web-dist.js +19 -14
- package/dist/desktop-browser-host.d.ts +153 -0
- package/dist/desktop-browser-host.js +936 -0
- package/dist/direct-runtime-browser-surface-server.d.ts +74 -0
- package/dist/direct-runtime-browser-surface-server.js +821 -0
- package/dist/direct-runtime-server.d.ts +137 -0
- package/dist/direct-runtime-server.js +1931 -0
- package/dist/emulator-surface-ws.d.ts +6 -0
- package/dist/emulator-surface-ws.js +197 -0
- package/dist/machine-session-service.d.ts +182 -0
- package/dist/machine-session-service.js +559 -0
- package/dist/provider-cli-host.d.ts +10 -0
- package/dist/provider-cli-host.js +1 -0
- package/dist/remote-runtime-dispatcher.d.ts +94 -0
- package/dist/remote-runtime-dispatcher.js +380 -0
- package/dist/remote-runtime-session-projection.d.ts +19 -0
- package/dist/remote-runtime-session-projection.js +556 -0
- package/dist/remote-runtime.d.ts +22 -0
- package/dist/remote-runtime.js +32 -0
- package/dist/runtime-web-auth.d.ts +21 -0
- package/dist/runtime-web-auth.js +92 -0
- package/dist/server.d.ts +292 -10
- package/dist/server.js +314 -98
- package/dist/session-browser-service.d.ts +218 -0
- package/dist/session-browser-service.js +686 -0
- package/dist/session-browser-surface-coordinator.d.ts +23 -0
- package/dist/session-browser-surface-coordinator.js +563 -0
- package/dist/session-emulator-service.d.ts +167 -0
- package/dist/session-emulator-service.js +464 -0
- package/dist/session-runtime-index.d.ts +17 -0
- package/dist/session-runtime-index.js +86 -0
- package/dist/session-terminal-host.d.ts +46 -0
- package/dist/session-terminal-host.js +252 -0
- package/dist/terminal-ws.d.ts +9 -20
- package/dist/terminal-ws.js +420 -97
- package/package.json +9 -7
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Server } from "node:http";
|
|
2
|
+
import { WebSocketServer } from "ws";
|
|
3
|
+
import type { RuntimeConnectionResolverHost } from "./server.js";
|
|
4
|
+
export declare function attachEmulatorSurfaceWs(server: Server, deps: {
|
|
5
|
+
runtimeConnectionResolver?: RuntimeConnectionResolverHost;
|
|
6
|
+
}): WebSocketServer;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { WebSocket, WebSocketServer } from "ws";
|
|
2
|
+
import { parseRuntimeEmulatorSurfaceClientFrame, RUNTIME_EMULATOR_SURFACE_MAX_FRAME_RATE, } from "@rynx-ai/protocol/runtime-emulator-surface";
|
|
3
|
+
import { authorizeRuntimeWebRequest, RUNTIME_WEB_CAPABILITY_QUERY, } from "./runtime-web-auth.js";
|
|
4
|
+
const SURFACE_PATH = /^\/api\/runtimes\/([^/]+)\/sessions\/([^/]+)\/emulator\/surface$/;
|
|
5
|
+
const SELECTOR_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._~-]{0,255}$/;
|
|
6
|
+
const MAX_ID_BYTES = 512;
|
|
7
|
+
const MAX_BUFFERED_BYTES = 24 * 1024 * 1024;
|
|
8
|
+
const OPEN_TIMEOUT_MS = 10_000;
|
|
9
|
+
const KEEPALIVE_MS = 15_000;
|
|
10
|
+
const MAX_QUEUED_INPUTS = 64;
|
|
11
|
+
export function attachEmulatorSurfaceWs(server, deps) {
|
|
12
|
+
const wss = new WebSocketServer({ noServer: true, perMessageDeflate: false, maxPayload: 4 * 1024 });
|
|
13
|
+
server.on("upgrade", (request, socket, head) => {
|
|
14
|
+
const parsed = parseUpgrade(request);
|
|
15
|
+
if (!parsed)
|
|
16
|
+
return;
|
|
17
|
+
if ("failure" in parsed)
|
|
18
|
+
return rejectUpgrade(socket, 400, parsed.failure);
|
|
19
|
+
const authorization = authorizeRuntimeWebRequest(request, {
|
|
20
|
+
mutation: true,
|
|
21
|
+
capability: parsed.url.searchParams.get(RUNTIME_WEB_CAPABILITY_QUERY) ?? "",
|
|
22
|
+
});
|
|
23
|
+
if (authorization)
|
|
24
|
+
return rejectUpgrade(socket, authorization.status, authorization.error);
|
|
25
|
+
try {
|
|
26
|
+
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
27
|
+
void handleConnection(ws, parsed.url, parsed.route, deps);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
rejectUpgrade(socket, 400, "invalid Emulator Surface WebSocket upgrade");
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return wss;
|
|
35
|
+
}
|
|
36
|
+
async function handleConnection(ws, url, route, deps) {
|
|
37
|
+
const bindingId = url.searchParams.get("bindingId");
|
|
38
|
+
const maximumFrameRate = Number(url.searchParams.get("maximumFrameRate") ?? "3");
|
|
39
|
+
if (!validId(bindingId) ||
|
|
40
|
+
!Number.isSafeInteger(maximumFrameRate) ||
|
|
41
|
+
maximumFrameRate < 1 ||
|
|
42
|
+
maximumFrameRate > RUNTIME_EMULATOR_SURFACE_MAX_FRAME_RATE) {
|
|
43
|
+
ws.close(4400, "invalid Emulator Surface options");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (!deps.runtimeConnectionResolver) {
|
|
47
|
+
ws.close(4406, "Emulator Surface is unavailable");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const controller = new AbortController();
|
|
51
|
+
let lease;
|
|
52
|
+
let surface;
|
|
53
|
+
let cleaned = false;
|
|
54
|
+
let cleanupPromise;
|
|
55
|
+
let queuedInputs = 0;
|
|
56
|
+
let inputTail = Promise.resolve();
|
|
57
|
+
const cleanup = () => {
|
|
58
|
+
if (cleanupPromise)
|
|
59
|
+
return cleanupPromise;
|
|
60
|
+
cleaned = true;
|
|
61
|
+
cleanupPromise = (async () => {
|
|
62
|
+
controller.abort(new Error("Emulator Surface browser disconnected"));
|
|
63
|
+
try {
|
|
64
|
+
await surface?.close();
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
lease?.release();
|
|
68
|
+
}
|
|
69
|
+
})();
|
|
70
|
+
return cleanupPromise;
|
|
71
|
+
};
|
|
72
|
+
const keepalive = setInterval(() => {
|
|
73
|
+
if (ws.readyState === WebSocket.OPEN)
|
|
74
|
+
ws.ping();
|
|
75
|
+
}, KEEPALIVE_MS);
|
|
76
|
+
keepalive.unref?.();
|
|
77
|
+
ws.on("message", (data, isBinary) => {
|
|
78
|
+
if (isBinary || !surface) {
|
|
79
|
+
ws.close(4400, "invalid Emulator Surface browser input");
|
|
80
|
+
void cleanup().catch(() => undefined);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
let frame;
|
|
84
|
+
try {
|
|
85
|
+
frame = parseRuntimeEmulatorSurfaceClientFrame(JSON.parse(data.toString()));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
ws.close(4400, "invalid Emulator Surface browser input");
|
|
89
|
+
void cleanup().catch(() => undefined);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (frame.type !== "emulator.surface.touch" || frame.surfaceId !== surface.ready.surfaceId) {
|
|
93
|
+
ws.close(4400, "Emulator Surface browser input does not match the active Surface");
|
|
94
|
+
void cleanup().catch(() => undefined);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (queuedInputs >= MAX_QUEUED_INPUTS) {
|
|
98
|
+
ws.close(4408, "Emulator Surface browser input queue is full");
|
|
99
|
+
void cleanup().catch(() => undefined);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
queuedInputs += 1;
|
|
103
|
+
inputTail = inputTail
|
|
104
|
+
.then(async () => {
|
|
105
|
+
if (cleaned || !surface)
|
|
106
|
+
return;
|
|
107
|
+
await surface.sendTouch({
|
|
108
|
+
phase: frame.phase,
|
|
109
|
+
x: frame.x,
|
|
110
|
+
y: frame.y,
|
|
111
|
+
});
|
|
112
|
+
})
|
|
113
|
+
.catch(() => {
|
|
114
|
+
if (!cleaned)
|
|
115
|
+
ws.close(4500, "Emulator Surface input failed");
|
|
116
|
+
void cleanup().catch(() => undefined);
|
|
117
|
+
})
|
|
118
|
+
.finally(() => { queuedInputs -= 1; });
|
|
119
|
+
});
|
|
120
|
+
ws.on("close", () => void cleanup().catch(() => undefined));
|
|
121
|
+
ws.on("error", () => void cleanup().catch(() => undefined));
|
|
122
|
+
try {
|
|
123
|
+
lease = await deps.runtimeConnectionResolver.acquire(route.selector, { signal: controller.signal });
|
|
124
|
+
if (lease.target.selector !== route.selector)
|
|
125
|
+
throw new Error("Runtime resolver returned a mismatched target");
|
|
126
|
+
surface = await lease.openEmulatorSurface(route.sessionId, bindingId, {
|
|
127
|
+
signal: controller.signal,
|
|
128
|
+
timeoutMs: OPEN_TIMEOUT_MS,
|
|
129
|
+
maximumFrameRate,
|
|
130
|
+
});
|
|
131
|
+
if (cleaned)
|
|
132
|
+
return;
|
|
133
|
+
await send(ws, JSON.stringify(surface.ready));
|
|
134
|
+
for await (const frame of surface) {
|
|
135
|
+
if (cleaned)
|
|
136
|
+
return;
|
|
137
|
+
if (ws.bufferedAmount + frame.encodedBytes.byteLength > MAX_BUFFERED_BYTES) {
|
|
138
|
+
ws.close(4408, "Emulator Surface browser is too slow");
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
await send(ws, frame.encodedBytes, true);
|
|
142
|
+
}
|
|
143
|
+
if (!cleaned)
|
|
144
|
+
ws.close(1000, "Emulator Surface ended");
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
if (!cleaned && ws.readyState === WebSocket.OPEN) {
|
|
148
|
+
const message = error instanceof Error ? error.message : "Emulator Surface failed";
|
|
149
|
+
// 4406 is an actionable daemon-upgrade state. A temporarily offline
|
|
150
|
+
// Runtime can also report "unavailable" and must stay on the ordinary
|
|
151
|
+
// reconnect path instead of flashing a false upgrade error.
|
|
152
|
+
ws.close(message.includes("semantic capability") ? 4406 : 4500, message.slice(0, 120));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
clearInterval(keepalive);
|
|
157
|
+
await cleanup().catch(() => undefined);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function parseUpgrade(request) {
|
|
161
|
+
let url;
|
|
162
|
+
try {
|
|
163
|
+
url = new URL(request.url ?? "", "http://localhost");
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
const match = SURFACE_PATH.exec(url.pathname);
|
|
169
|
+
if (!match)
|
|
170
|
+
return undefined;
|
|
171
|
+
try {
|
|
172
|
+
const selector = decodeURIComponent(match[1]);
|
|
173
|
+
const sessionId = decodeURIComponent(match[2]);
|
|
174
|
+
if (!SELECTOR_PATTERN.test(selector) || !validId(sessionId))
|
|
175
|
+
return { failure: "invalid Emulator Surface route" };
|
|
176
|
+
return { url, route: { selector, sessionId } };
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return { failure: "invalid Emulator Surface route encoding" };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function validId(value) {
|
|
183
|
+
return typeof value === "string" && value.length > 0 && Buffer.byteLength(value, "utf8") <= MAX_ID_BYTES && /^[\x21-\x7e]+$/.test(value);
|
|
184
|
+
}
|
|
185
|
+
function send(ws, data, binary = false) {
|
|
186
|
+
return new Promise((resolve, reject) => {
|
|
187
|
+
if (ws.readyState !== WebSocket.OPEN)
|
|
188
|
+
return reject(new Error("Emulator Surface WebSocket is closed"));
|
|
189
|
+
ws.send(data, { binary }, (error) => error ? reject(error) : resolve());
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function rejectUpgrade(socket, status, message) {
|
|
193
|
+
if (socket.destroyed)
|
|
194
|
+
return;
|
|
195
|
+
const label = status === 401 ? "Unauthorized" : status === 403 ? "Forbidden" : "Bad Request";
|
|
196
|
+
socket.end(`HTTP/1.1 ${status} ${label}\r\nConnection: close\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: ${Buffer.byteLength(message)}\r\n\r\n${message}`);
|
|
197
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daemon-owned application service for the first Remote Runtime Session slice.
|
|
3
|
+
*
|
|
4
|
+
* This service deliberately has no HTTP, Koa, WebSocket, or Direct-binding
|
|
5
|
+
* knowledge. Durable records, live state, events, and interruption remain owned
|
|
6
|
+
* by the daemon process and arrive through narrow injected ports. Local and
|
|
7
|
+
* Direct adapters can therefore expose the same behavior without copying state
|
|
8
|
+
* into a Control Plane database.
|
|
9
|
+
*/
|
|
10
|
+
import { type AgentRuntimeId, type AgentSpec, type ConversationRuntime, type SessionProviderId, type ReasoningEffort, type SessionBus, type SessionLogStore, type SessionRegistry } from "@rynx-ai/core";
|
|
11
|
+
import type { SequencedSessionEvent, SessionInteractionResolution, SessionItem } from "@rynx-ai/protocol";
|
|
12
|
+
import type { ControlAgentSummary, ControlSessionInteractionResolveDisposition, ControlSessionRuntimeSnapshot } from "@rynx-ai/protocol/control";
|
|
13
|
+
import { type RemoteRuntimeSessionInterruptResult, type RemoteRuntimeSessionLaunchOptionsListResult, type RemoteRuntimeSessionListParams, type RemoteRuntimeSessionListResult, type RemoteRuntimeSessionSnapshotParams } from "@rynx-ai/protocol/remote-runtime-rpc";
|
|
14
|
+
import { type CodexRuntimeStatus, type CodexSessionStore, type InjectOutcome } from "@rynx-ai/runtime";
|
|
15
|
+
export interface MachineSessionRuntimeStatePort {
|
|
16
|
+
snapshot(sessionId: string): ControlSessionRuntimeSnapshot;
|
|
17
|
+
remove?(sessionId: string): void;
|
|
18
|
+
}
|
|
19
|
+
export interface MachineSessionInterruptPort {
|
|
20
|
+
interrupt(sessionId: string): Promise<boolean>;
|
|
21
|
+
}
|
|
22
|
+
export interface MachineSessionAgentCatalogPort {
|
|
23
|
+
list(): Promise<ControlAgentSummary[]>;
|
|
24
|
+
}
|
|
25
|
+
export interface MachineSessionRunnerPort {
|
|
26
|
+
ensureLiveSession(sessionId: string, options?: {
|
|
27
|
+
cwd?: string;
|
|
28
|
+
cols?: number;
|
|
29
|
+
rows?: number;
|
|
30
|
+
runtime?: AgentRuntimeId;
|
|
31
|
+
reasoningEffort?: ReasoningEffort;
|
|
32
|
+
agentName?: string;
|
|
33
|
+
agentSpec?: AgentSpec;
|
|
34
|
+
}): Promise<boolean>;
|
|
35
|
+
lastLiveSessionError?(sessionId: string): string | undefined;
|
|
36
|
+
injectMessage(sessionId: string, text: string): Promise<InjectOutcome>;
|
|
37
|
+
stopRunner(sessionId: string): void;
|
|
38
|
+
resolveInteraction(sessionId: string, interactionId: string, resolution: SessionInteractionResolution): Promise<{
|
|
39
|
+
disposition: ControlSessionInteractionResolveDisposition;
|
|
40
|
+
}>;
|
|
41
|
+
/** Backend-free readiness probe for launch options and direct Provider creation. */
|
|
42
|
+
getStatus?(options: {
|
|
43
|
+
runtime: AgentRuntimeId;
|
|
44
|
+
}): Promise<CodexRuntimeStatus>;
|
|
45
|
+
}
|
|
46
|
+
export interface MachineSessionServicePorts {
|
|
47
|
+
registry: Pick<SessionRegistry, "create" | "get" | "list" | "setTitle" | "remove">;
|
|
48
|
+
log: Pick<SessionLogStore, "list" | "listSessions" | "snapshot" | "deleteSession">;
|
|
49
|
+
events: Pick<SessionBus, "subscribe"> & Partial<Pick<SessionBus, "close">>;
|
|
50
|
+
runtimeState: MachineSessionRuntimeStatePort;
|
|
51
|
+
interruption: MachineSessionInterruptPort;
|
|
52
|
+
/** External Session-owned resources fenced before and finalized after deletion. */
|
|
53
|
+
lifecycle?: {
|
|
54
|
+
beforeDelete?(sessionId: string): void | Promise<void>;
|
|
55
|
+
afterDelete?(sessionId: string): void | Promise<void>;
|
|
56
|
+
};
|
|
57
|
+
/** Target-daemon catalog. Exposed only as bounded Session creation options. */
|
|
58
|
+
agents?: MachineSessionAgentCatalogPort;
|
|
59
|
+
/** Native Session execution belongs to the target daemon, never the caller. */
|
|
60
|
+
execution?: {
|
|
61
|
+
runtime: Pick<ConversationRuntime, "resolveRuntime">;
|
|
62
|
+
runner: MachineSessionRunnerPort;
|
|
63
|
+
sessionStore?: Pick<CodexSessionStore, "get">;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export interface MachineSessionServiceOptions {
|
|
67
|
+
/** Maximum summaries returned in one list page. */
|
|
68
|
+
maxListLimit?: number;
|
|
69
|
+
/** JSON byte budget for one complete list page. */
|
|
70
|
+
listPageMaxBytes?: number;
|
|
71
|
+
/** Maximum items returned in one transcript page. */
|
|
72
|
+
maxSnapshotItemLimit?: number;
|
|
73
|
+
/** JSON byte budget for one complete transcript page. */
|
|
74
|
+
snapshotPageMaxBytes?: number;
|
|
75
|
+
/** Bound for the current registry/log merge until storage offers keyset paging. */
|
|
76
|
+
directoryScanLimit?: number;
|
|
77
|
+
}
|
|
78
|
+
export type MachineSessionListInput = RemoteRuntimeSessionListParams;
|
|
79
|
+
export interface MachineSessionListPage extends RemoteRuntimeSessionListResult {
|
|
80
|
+
/** True when the storage-side directory exceeded the bounded merge window. */
|
|
81
|
+
directoryTruncated: boolean;
|
|
82
|
+
}
|
|
83
|
+
export type MachineSessionSnapshotInput = RemoteRuntimeSessionSnapshotParams;
|
|
84
|
+
export interface MachineSessionSnapshotPage {
|
|
85
|
+
sessionId: string;
|
|
86
|
+
/** Canonical daemon-owned items; the Direct adapter projects payloads later. */
|
|
87
|
+
items: SessionItem[];
|
|
88
|
+
runtime: ControlSessionRuntimeSnapshot;
|
|
89
|
+
hasMore: boolean;
|
|
90
|
+
nextAfterId?: string;
|
|
91
|
+
}
|
|
92
|
+
export type MachineSessionInterruptResult = RemoteRuntimeSessionInterruptResult;
|
|
93
|
+
interface MachineSessionCreateOptions {
|
|
94
|
+
model?: string;
|
|
95
|
+
reasoningEffort?: ReasoningEffort;
|
|
96
|
+
title?: string;
|
|
97
|
+
}
|
|
98
|
+
export type MachineSessionCreateInput = MachineSessionCreateOptions & ({
|
|
99
|
+
agent: string;
|
|
100
|
+
provider?: never;
|
|
101
|
+
} | {
|
|
102
|
+
provider: SessionProviderId;
|
|
103
|
+
agent?: never;
|
|
104
|
+
});
|
|
105
|
+
export interface MachineSessionCreateResult {
|
|
106
|
+
sessionId: string;
|
|
107
|
+
}
|
|
108
|
+
export interface MachineSessionMessageResult {
|
|
109
|
+
ok: true;
|
|
110
|
+
injected: true;
|
|
111
|
+
}
|
|
112
|
+
export interface MachineSessionTerminalStartResult {
|
|
113
|
+
ok: true;
|
|
114
|
+
}
|
|
115
|
+
export interface MachineSessionDeleteResult {
|
|
116
|
+
ok: true;
|
|
117
|
+
}
|
|
118
|
+
export interface MachineSessionInteractionResult {
|
|
119
|
+
disposition: ControlSessionInteractionResolveDisposition;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* A process-live event tail. `cancel` is idempotent and settles a pending
|
|
123
|
+
* consumer read even when the underlying bus iterator does not settle its own
|
|
124
|
+
* pending `next()` on `return()`.
|
|
125
|
+
*/
|
|
126
|
+
export interface MachineSessionWatch extends AsyncIterable<SequencedSessionEvent> {
|
|
127
|
+
readonly sessionId: string;
|
|
128
|
+
cancel(): Promise<void>;
|
|
129
|
+
}
|
|
130
|
+
export declare class MachineSessionServiceInputError extends Error {
|
|
131
|
+
constructor(message: string);
|
|
132
|
+
}
|
|
133
|
+
export type MachineSessionServiceFailureCode = "not_found" | "failed_precondition" | "outcome_unknown";
|
|
134
|
+
/** Expected application failure; adapters decide how to represent it on the wire. */
|
|
135
|
+
export declare class MachineSessionServiceFailure extends Error {
|
|
136
|
+
readonly code: MachineSessionServiceFailureCode;
|
|
137
|
+
readonly detail?: string | undefined;
|
|
138
|
+
constructor(code: MachineSessionServiceFailureCode, message: string, detail?: string | undefined);
|
|
139
|
+
}
|
|
140
|
+
/** Application boundary shared by an in-process Local adapter and Direct RPC. */
|
|
141
|
+
export declare class MachineSessionService {
|
|
142
|
+
private readonly ports;
|
|
143
|
+
private readonly maxListLimit;
|
|
144
|
+
private readonly listPageMaxBytes;
|
|
145
|
+
private readonly maxSnapshotItemLimit;
|
|
146
|
+
private readonly snapshotPageMaxBytes;
|
|
147
|
+
private readonly directoryScanLimit;
|
|
148
|
+
constructor(ports: MachineSessionServicePorts, options?: MachineSessionServiceOptions);
|
|
149
|
+
list(input?: MachineSessionListInput): Promise<MachineSessionListPage>;
|
|
150
|
+
snapshot(input: MachineSessionSnapshotInput): Promise<MachineSessionSnapshotPage>;
|
|
151
|
+
/**
|
|
152
|
+
* Install a live subscriber synchronously, before returning control to an
|
|
153
|
+
* adapter. The adapter may now acknowledge readiness and request snapshot
|
|
154
|
+
* pages while buffering this tail, closing the subscribe/snapshot race.
|
|
155
|
+
*/
|
|
156
|
+
watch(sessionIdInput: string, options?: {
|
|
157
|
+
signal?: AbortSignal;
|
|
158
|
+
}): MachineSessionWatch;
|
|
159
|
+
interrupt(sessionIdInput: string): Promise<MachineSessionInterruptResult>;
|
|
160
|
+
/** Session-scoped projection of the target daemon's own Agent catalog. */
|
|
161
|
+
agentOptions(): Promise<{
|
|
162
|
+
agents: ControlAgentSummary[];
|
|
163
|
+
}>;
|
|
164
|
+
/** Target-owned Provider readiness plus the existing Agent preset catalog. */
|
|
165
|
+
launchOptions(): Promise<RemoteRuntimeSessionLaunchOptionsListResult>;
|
|
166
|
+
/** Create target-owned Session identity from one Agent preset or direct Provider. */
|
|
167
|
+
create(input: MachineSessionCreateInput): Promise<MachineSessionCreateResult>;
|
|
168
|
+
/** Inject one turn through the target daemon's native single-writer runner. */
|
|
169
|
+
sendMessage(sessionIdInput: string, messageInput: string): Promise<MachineSessionMessageResult>;
|
|
170
|
+
/** Explicitly restore the target daemon's live runner without starting a turn. */
|
|
171
|
+
startTerminal(sessionIdInput: string): Promise<MachineSessionTerminalStartResult>;
|
|
172
|
+
private ensureLiveSession;
|
|
173
|
+
resolveInteraction(sessionIdInput: string, interactionIdInput: string, resolution: SessionInteractionResolution): Promise<MachineSessionInteractionResult>;
|
|
174
|
+
delete(sessionIdInput: string): Promise<MachineSessionDeleteResult>;
|
|
175
|
+
private requireAgents;
|
|
176
|
+
private runtimeReadiness;
|
|
177
|
+
private probeRuntimeReadiness;
|
|
178
|
+
private requireExecution;
|
|
179
|
+
}
|
|
180
|
+
/** One-line title derived from the first user message; no model call. */
|
|
181
|
+
export declare function synthesizeSessionTitle(message: string, limit?: number): string;
|
|
182
|
+
export {};
|