@opengeni/runtime 0.11.0 → 0.13.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.
@@ -0,0 +1,67 @@
1
+ // The SDK's execCommand/writeStdin fallback returns a formatted response with
2
+ // provider metadata followed by an `Output:` delimiter and command-controlled
3
+ // output. Terminal status is authoritative only in the metadata header; the
4
+ // output body is untrusted and may contain exact copies of SDK banner lines.
5
+
6
+ const EXEC_BANNER_HEADER_MAX_CHARS = 16 * 1024;
7
+ const OUTPUT_DELIMITER = /\r?\nOutput:\r?\n/u;
8
+ const SDK_METADATA_LINE =
9
+ /^(?:Chunk ID:|Wall time:|Original token count:|Output:|Process (?:running with session ID|exited with code))/mu;
10
+ const RUNNING_LINE = /^Process running with session ID (\d+)$/u;
11
+ const EXITED_LINE = /^Process exited with code (-?\d+)$/u;
12
+ const PROCESS_STATUS_PREFIX = /^Process (?:running with session ID|exited with code)/u;
13
+
14
+ export type ExecResponseBanner =
15
+ | { kind: "absent" }
16
+ | { kind: "invalid" }
17
+ | { kind: "running"; sessionId: number }
18
+ | { kind: "exited"; exitCode: number };
19
+
20
+ /** Parse exactly one terminal status from the SDK metadata header. Responses
21
+ * that resemble SDK output but lack a complete delimiter/header are invalid,
22
+ * while raw provider output without SDK metadata remains `absent` so callers
23
+ * may use their provider-specific body markers. */
24
+ export function parseExecResponseBanner(raw: string): ExecResponseBanner {
25
+ const delimiter = OUTPUT_DELIMITER.exec(raw);
26
+ if (!delimiter) {
27
+ return SDK_METADATA_LINE.test(raw) ? { kind: "invalid" } : { kind: "absent" };
28
+ }
29
+ if (delimiter.index > EXEC_BANNER_HEADER_MAX_CHARS) return { kind: "invalid" };
30
+
31
+ const header = raw.slice(0, delimiter.index);
32
+ const status: Array<{ kind: "running"; value: string } | { kind: "exited"; value: string }> = [];
33
+ for (const line of header.split(/\r?\n/u)) {
34
+ const running = RUNNING_LINE.exec(line);
35
+ if (running) {
36
+ status.push({ kind: "running", value: running[1]! });
37
+ continue;
38
+ }
39
+ const exited = EXITED_LINE.exec(line);
40
+ if (exited) {
41
+ status.push({ kind: "exited", value: exited[1]! });
42
+ continue;
43
+ }
44
+ // A status-looking metadata line that is malformed is ambiguous and must
45
+ // not be normalized into another process identity or terminal result.
46
+ if (PROCESS_STATUS_PREFIX.test(line)) return { kind: "invalid" };
47
+ }
48
+ if (status.length !== 1) return { kind: "invalid" };
49
+
50
+ const terminal = status[0]!;
51
+ const value = Number(terminal.value);
52
+ if (!Number.isSafeInteger(value)) return { kind: "invalid" };
53
+ if (terminal.kind === "running") {
54
+ return value >= 0 ? { kind: "running", sessionId: value } : { kind: "invalid" };
55
+ }
56
+ return { kind: "exited", exitCode: value };
57
+ }
58
+
59
+ export function parseExecBannerSessionId(raw: string): number | null {
60
+ const banner = parseExecResponseBanner(raw);
61
+ return banner.kind === "running" ? banner.sessionId : null;
62
+ }
63
+
64
+ export function parseExecBannerExitCode(raw: string): number | null {
65
+ const banner = parseExecResponseBanner(raw);
66
+ return banner.kind === "exited" ? banner.exitCode : null;
67
+ }
@@ -72,7 +72,9 @@ export {
72
72
  type LiveModalSandboxLeaseAttribution,
73
73
  type ModalModuleLoader,
74
74
  type ModalOrphanSweepResult,
75
+ type ModalOrphanSweepTermination,
75
76
  type ModalSandboxAttribution,
77
+ type RevalidateModalOrphanTermination,
76
78
  } from "./providers/modal";
77
79
  export {
78
80
  selectBackend,
@@ -106,6 +108,11 @@ export {
106
108
  ensureDisplayStack,
107
109
  tearDownDisplayStack,
108
110
  type DesktopGeometry,
111
+ type DisplayStackCallerKind,
112
+ type DisplayStackClassification,
113
+ type DisplayStackTelemetryContext,
114
+ type DisplayStackTelemetryEvent,
115
+ type DisplayStackTelemetryStatus,
109
116
  type EnsureDisplayStackOptions,
110
117
  type EnsureDisplayStackResult,
111
118
  } from "./display-stack";
@@ -38,6 +38,10 @@ export type ModalOrphanSweepResult = {
38
38
  skipped: number;
39
39
  };
40
40
 
41
+ export type RevalidateModalOrphanTermination = (
42
+ candidate: ModalOrphanSweepTermination,
43
+ ) => Promise<boolean>;
44
+
41
45
  export function modalSandboxAttributionEnvironment(
42
46
  input: ModalSandboxAttribution,
43
47
  ): Record<string, string> {
@@ -337,6 +341,9 @@ export async function sweepModalOrphanSandboxes(
337
341
  maxTerminations?: number;
338
342
  unattributedGraceMs?: number;
339
343
  client?: ModalClientLike;
344
+ /** Re-read durable ownership immediately before provider termination. A
345
+ * false result or callback failure skips the destructive action. */
346
+ revalidateTermination?: RevalidateModalOrphanTermination;
340
347
  } = {},
341
348
  ): Promise<ModalOrphanSweepResult> {
342
349
  const nowMs = options.now?.getTime() ?? Date.now();
@@ -437,10 +444,30 @@ export async function sweepModalOrphanSandboxes(
437
444
  skipped += 1;
438
445
  continue;
439
446
  }
447
+ const candidate = { sandboxId: info.id, reason, tags };
448
+ let sandbox: Awaited<ReturnType<typeof modal.sandboxes.fromId>>;
449
+ try {
450
+ sandbox = await modal.sandboxes.fromId(info.id);
451
+ } catch {
452
+ skipped += 1;
453
+ continue;
454
+ }
455
+ if (options.revalidateTermination) {
456
+ try {
457
+ if (!(await options.revalidateTermination(candidate))) {
458
+ skipped += 1;
459
+ continue;
460
+ }
461
+ } catch {
462
+ // Destructive provider cleanup fails closed when the fresh durable
463
+ // ownership read is unavailable or otherwise inconclusive.
464
+ skipped += 1;
465
+ continue;
466
+ }
467
+ }
440
468
  try {
441
- const sandbox = await modal.sandboxes.fromId(info.id);
442
469
  await sandbox.terminate();
443
- terminated.push({ sandboxId: info.id, reason, tags });
470
+ terminated.push(candidate);
444
471
  } catch {
445
472
  skipped += 1;
446
473
  }
@@ -1279,7 +1279,9 @@ export class ComputerUseCapability extends Capability {
1279
1279
  // any computer-use-only recording. One SandboxComputer instance caches
1280
1280
  // this for the rest of the turn.
1281
1281
  prepare: async (preparedSession) => {
1282
- await ensureDisplayStack(preparedSession);
1282
+ await ensureDisplayStack(preparedSession, {
1283
+ telemetryContext: { callerKind: "computer" },
1284
+ });
1283
1285
  await this.args.onReady?.(preparedSession);
1284
1286
  },
1285
1287
  });