@opengeni/runtime 0.14.1 → 0.14.15

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.
Files changed (79) hide show
  1. package/dist/{chunk-4YJ5Z52Z.js → chunk-7E2ZSCZK.js} +6 -6
  2. package/dist/{chunk-4YJ5Z52Z.js.map → chunk-7E2ZSCZK.js.map} +1 -1
  3. package/dist/{chunk-HHWIZHQM.js → chunk-GNEGANUF.js} +942 -300
  4. package/dist/chunk-GNEGANUF.js.map +1 -0
  5. package/dist/codex-tool-search.d.ts +100 -0
  6. package/dist/context-compaction.d.ts +236 -0
  7. package/dist/history-sanitizer.d.ts +320 -0
  8. package/dist/index.d.ts +186 -718
  9. package/dist/index.js +612 -126
  10. package/dist/index.js.map +1 -1
  11. package/dist/{localSources-T3HZ6KY4.js → localSources-BXHBKGF4.js} +2 -2
  12. package/dist/mcp-network.d.ts +32 -35
  13. package/dist/metrics.d.ts +33 -0
  14. package/dist/sandbox/capabilities.d.ts +11 -0
  15. package/dist/sandbox/channel-a.d.ts +226 -0
  16. package/dist/sandbox/display-stack.d.ts +99 -0
  17. package/dist/sandbox/errors.d.ts +16 -0
  18. package/dist/sandbox/exec-banner.d.ts +19 -0
  19. package/dist/sandbox/index.d.ts +190 -6
  20. package/dist/sandbox/index.js +20 -4
  21. package/dist/sandbox/op-correlation.d.ts +24 -0
  22. package/dist/sandbox/provider-errors.d.ts +32 -0
  23. package/dist/sandbox/provider-operation-gate.d.ts +12 -0
  24. package/dist/sandbox/providers/blaxel.d.ts +2 -0
  25. package/dist/sandbox/providers/cloudflare.d.ts +2 -0
  26. package/dist/sandbox/providers/daytona.d.ts +2 -0
  27. package/dist/sandbox/providers/docker.d.ts +2 -0
  28. package/dist/sandbox/providers/e2b.d.ts +2 -0
  29. package/dist/sandbox/providers/index.d.ts +11 -0
  30. package/dist/sandbox/providers/local.d.ts +2 -0
  31. package/dist/sandbox/providers/modal.d.ts +132 -0
  32. package/dist/sandbox/providers/none.d.ts +2 -0
  33. package/dist/sandbox/providers/runloop.d.ts +2 -0
  34. package/dist/sandbox/providers/selfhosted.d.ts +2 -0
  35. package/dist/sandbox/providers/types.d.ts +30 -0
  36. package/dist/sandbox/providers/vercel.d.ts +2 -0
  37. package/dist/sandbox/recording.d.ts +80 -0
  38. package/dist/sandbox/routing/backend-resolver.d.ts +173 -0
  39. package/dist/sandbox/routing/routing-session.d.ts +401 -0
  40. package/dist/sandbox/run-credentials.d.ts +65 -0
  41. package/dist/sandbox/select.d.ts +120 -0
  42. package/dist/sandbox/selfhosted/capabilities.d.ts +91 -0
  43. package/dist/sandbox/selfhosted/control-rpc.d.ts +175 -0
  44. package/dist/sandbox/selfhosted/fault-rendering.d.ts +40 -0
  45. package/dist/sandbox/selfhosted/op-observer.d.ts +40 -0
  46. package/dist/sandbox/selfhosted/op-stream.d.ts +104 -0
  47. package/dist/sandbox/selfhosted/op-testing.d.ts +108 -0
  48. package/dist/sandbox/selfhosted/op-transport.d.ts +60 -0
  49. package/dist/sandbox/selfhosted/retry-policy.d.ts +106 -0
  50. package/dist/sandbox/selfhosted/session.d.ts +552 -0
  51. package/dist/sandbox/selfhosted/testing.d.ts +48 -0
  52. package/dist/sandbox/stream-port.d.ts +80 -0
  53. package/dist/sandbox/stream-token.d.ts +44 -0
  54. package/dist/sandbox/terminal-server.d.ts +67 -0
  55. package/dist/sandbox/toolspace-token.d.ts +23 -0
  56. package/dist/sandbox/turn-tool-cancellation.d.ts +72 -0
  57. package/dist/sandbox/workspace-archive.d.ts +39 -0
  58. package/dist/sandbox-computer.d.ts +227 -0
  59. package/dist/screenshot-error-card.d.ts +1 -0
  60. package/dist/skill-library.d.ts +10 -12
  61. package/dist/usage-telemetry.d.ts +45 -0
  62. package/dist/workspace-skills.d.ts +31 -0
  63. package/package.json +7 -7
  64. package/src/context-compaction.ts +600 -6
  65. package/src/history-sanitizer.ts +10 -92
  66. package/src/index.ts +301 -62
  67. package/src/sandbox/channel-a.ts +267 -81
  68. package/src/sandbox/index.ts +56 -94
  69. package/src/sandbox/provider-operation-gate.ts +110 -0
  70. package/src/sandbox/providers/docker.ts +13 -1
  71. package/src/sandbox/providers/modal.ts +433 -3
  72. package/src/sandbox/routing/routing-session.ts +84 -8
  73. package/src/sandbox/selfhosted/session.ts +7 -6
  74. package/src/sandbox/turn-tool-cancellation.ts +47 -7
  75. package/src/sandbox/workspace-archive.ts +176 -73
  76. package/src/sandbox-computer.ts +25 -75
  77. package/dist/chunk-HHWIZHQM.js.map +0 -1
  78. package/dist/index-BraazrAO.d.ts +0 -2931
  79. /package/dist/{localSources-T3HZ6KY4.js.map → localSources-BXHBKGF4.js.map} +0 -0
@@ -0,0 +1,80 @@
1
+ /** The provider-resolved endpoint for an exposed port. Mirrors the SDK's
2
+ * `ExposedPortEndpoint` (host/port/tls/query/...) WITHOUT importing the
3
+ * agent-loop barrel — the leaf stays agent-loop-free. */
4
+ export type ExposedPortEndpoint = {
5
+ host: string;
6
+ port: number;
7
+ tls?: boolean;
8
+ query?: string;
9
+ protocol?: string;
10
+ url?: string;
11
+ /** The URL path the socket connects on. Modal/Daytona/Blaxel serve the edge at
12
+ * the root (`/`, the default); the selfhosted relay serves it at `/stream`
13
+ * (M8b). When set, buildStreamUrl uses it instead of the root. */
14
+ path?: string;
15
+ [key: string]: unknown;
16
+ };
17
+ /** Thrown when the provider cannot expose the stream port (no resolveExposedPort,
18
+ * or the provider tunnel lookup failed). The caller degrades the desktop cell to
19
+ * `transport:null` (a value, never a crash) — a headless-only provider or a
20
+ * transient tunnel failure must not fail the whole handshake. */
21
+ export declare class StreamPortUnavailableError extends Error {
22
+ readonly cause?: unknown;
23
+ constructor(message: string, cause?: unknown);
24
+ }
25
+ export type ExposeStreamPortInput = {
26
+ workspaceId: string;
27
+ sessionId: string;
28
+ /** The sandbox_lease_holders viewer row id the token is scoped to. */
29
+ viewerId: string;
30
+ /** The live lease epoch — the fence the token is pinned to. */
31
+ leaseEpoch: number;
32
+ /** The HMAC secret for the scoped stream token (resolveStreamTokenSecret). */
33
+ streamTokenSecret: string;
34
+ /** The exposed stream port; defaults to 6080. */
35
+ port?: number;
36
+ /** Token TTL in seconds; defaults to STREAM_TOKEN_DEFAULT_TTL_SECONDS. */
37
+ ttlSeconds?: number;
38
+ /** The framebuffer geometry to echo back to the client. */
39
+ resolution?: [number, number];
40
+ /** Override the issue clock (tests). Seconds since the epoch. */
41
+ nowSeconds?: number;
42
+ };
43
+ export type ExposeStreamPortResult = {
44
+ /** The direct-to-provider WS URL the viewer connects to (provider-scoped; the
45
+ * OpenGeni token is NOT appended). */
46
+ url: string;
47
+ /** The scoped OpenGeni stream token — recorded against the holder, NEVER a URL
48
+ * query param. */
49
+ token: string;
50
+ /** ISO absolute expiry of the token (the rotation hot-swap window backstop). */
51
+ expiresAt: string;
52
+ /** The pixel transport the client speaks. */
53
+ transport: "vnc-ws";
54
+ /** The reference noVNC client the SDK helper mounts. */
55
+ client: "novnc";
56
+ resolution: [number, number];
57
+ leaseEpoch: number;
58
+ };
59
+ /**
60
+ * Assemble the direct-to-provider WS URL from a resolved endpoint. The SDK's
61
+ * `urlForExposedPort(endpoint,'ws')` is the canonical tls-aware, IPv6-bracketing,
62
+ * provider-query-preserving assembler — we reimplement its exact logic here so
63
+ * the leaf stays agent-loop-free (the helper lives behind the bare
64
+ * `@openai/agents-core` root, which the import-discipline test forbids). The
65
+ * provider's own `endpoint.query` (Blaxel `bl_preview_token`, Daytona signed
66
+ * token) is preserved; the OpenGeni token is NOT appended (it is recorded against
67
+ * the holder + validated at the in-box websockify edge).
68
+ */
69
+ export declare function buildStreamUrl(endpoint: ExposedPortEndpoint): string;
70
+ /**
71
+ * Resolve the provider's scoped tunnel for the stream port and mint the scoped
72
+ * OpenGeni stream token. Returns a coherent `{url, token, expiresAt, transport,
73
+ * client, resolution}` cell the caller records on the lease (data_plane_url) and
74
+ * returns in the DesktopStream handshake.
75
+ *
76
+ * Throws `StreamPortUnavailableError` when the provider session cannot resolve
77
+ * the port (no `resolveExposedPort`, or the tunnel lookup failed) — the caller
78
+ * maps this to a `transport:null` degradation (a value, never a crash).
79
+ */
80
+ export declare function exposeStreamPort(session: unknown, input: ExposeStreamPortInput): Promise<ExposeStreamPortResult>;
@@ -0,0 +1,44 @@
1
+ import { type StreamTokenPayload as StreamTokenPayloadType } from "@opengeni/contracts";
2
+ export declare const STREAM_TOKEN_DEFAULT_TTL_SECONDS = 120;
3
+ export type MintStreamTokenInput = {
4
+ workspaceId: string;
5
+ sessionId: string;
6
+ /** The sandbox_lease_holders viewer row id. */
7
+ viewerId: string;
8
+ /** The epoch the token is fenced to. For a Modal box this is the live LEASE
9
+ * epoch (re-minted on box rollover). For a SELFHOSTED relay stream (M8b) this is
10
+ * the session's swap `active_epoch`: the relay tracks the highest epoch any
11
+ * viewer presented per channel and REJECTS a token with a lower epoch, so a
12
+ * viewer whose token predates a swap-away cannot reach the machine the session
13
+ * swapped off of. One field, two fences — the relay/in-box edge reads it as the
14
+ * stale-viewer floor either way. */
15
+ leaseEpoch: number;
16
+ /** v1 is always "view"; "control" is the never-granted raw-input plane. */
17
+ mode?: "view" | "control";
18
+ /** The exposed stream port (noVNC); defaults to 6080. */
19
+ port?: number;
20
+ /** TTL in seconds; defaults to STREAM_TOKEN_DEFAULT_TTL_SECONDS. */
21
+ ttlSeconds?: number;
22
+ /** Override the issue clock (tests). Seconds since the epoch. */
23
+ nowSeconds?: number;
24
+ };
25
+ /**
26
+ * Mint a scoped stream token for one viewer holder. Builds the hard-narrow
27
+ * StreamTokenPayload (the claim set the in-box edge / control plane validates)
28
+ * and signs it with the resolved stream-token secret via the contracts HMAC
29
+ * envelope (`ogs_` prefix). The token is RECORDED against the holder row by the
30
+ * caller and is NEVER appended to the data-plane URL as a query param.
31
+ */
32
+ export declare function mintStreamToken(secret: string, input: MintStreamTokenInput): Promise<string>;
33
+ /**
34
+ * Verify a scoped stream token. Returns the parsed claims on success, or null on
35
+ * a bad prefix / malformed envelope / bad HMAC signature / schema-invalid claims
36
+ * / expiry. Re-exports the contracts verify; the leaf is the agent-loop-free
37
+ * import surface the API uses.
38
+ *
39
+ * The epoch fence (claim.leaseEpoch vs the LIVE lease epoch) and the
40
+ * workspace+session scope are enforced at USE by the caller against the live
41
+ * lease + route params — verify proves authenticity + freshness only.
42
+ */
43
+ export declare function verifyStreamToken(secret: string, token: string, nowSeconds?: number): Promise<StreamTokenPayloadType | null>;
44
+ export { StreamTokenPayload, type StreamTokenPayload as StreamTokenPayloadType, } from "@opengeni/contracts";
@@ -0,0 +1,67 @@
1
+ import { TERMINAL_STREAM_PORT } from "@opengeni/contracts";
2
+ export { TERMINAL_STREAM_PORT };
3
+ export declare const TERMINAL_SERVER_TIMEOUT_MS = 60000;
4
+ /** Thrown when the ttyd launch failed inside the box. exitCode 14 maps to the
5
+ * up-script's "ttyd failed to come up" stage; any other non-zero is unknown.
6
+ * Degradation is surfaced as a value to clients by the caller (Terminal
7
+ * transport falls back to sse-events / null); this error is for diagnostics. */
8
+ export declare class TerminalServerError extends Error {
9
+ readonly exitCode: number;
10
+ readonly stage: "ttyd" | "unknown";
11
+ constructor(exitCode: number, output: string);
12
+ }
13
+ /** Thrown when the provider session cannot run commands (a headless-only backend
14
+ * with neither `exec` nor `execCommand`). The terminal tier degrades to the
15
+ * Channel-A sse-events firehose — the caller maps this to a `transport:null`
16
+ * pty-ws (the read-only firehose still works). */
17
+ export declare class TerminalServerUnsupportedError extends Error {
18
+ constructor(message: string);
19
+ }
20
+ export type EnsureTerminalServerOptions = {
21
+ /** The exposed terminal port; defaults to 7681 (ttyd default). */
22
+ port?: number;
23
+ /** Per-exec timeout; defaults to TERMINAL_SERVER_TIMEOUT_MS. */
24
+ timeoutMs?: number;
25
+ };
26
+ export type EnsureTerminalServerResult = {
27
+ /** The exposed port ttyd listens on (PTY-over-websocket). */
28
+ port: number;
29
+ /** The raw `OPENGENI_TERMINAL_UP …` marker line, for diagnostics. Never
30
+ * surfaced to clients. */
31
+ marker: string;
32
+ };
33
+ /**
34
+ * Build the shell command that runs the idempotent up-script under an in-box
35
+ * `flock`. The script is shipped in the image at /usr/local/bin/opengeni-terminal-up
36
+ * (the canonical desktop image, alongside opengeni-desktop-up); we set the port
37
+ * env and wrap the call in `flock` so two concurrent ensureTerminalServer callers
38
+ * (the API viewer op + the agent turn, both racing after a rollover) serialize
39
+ * without a double launch. The up-script's own curl readiness probe makes the
40
+ * second call a no-op.
41
+ *
42
+ * Exported (pure, side-effect-free) so the ensureTerminalServer unit test can
43
+ * assert the exact command sequence without a live box. Mirrors
44
+ * buildDisplayStackScript. A ttyd process is sandbox-group-global, not
45
+ * OpenGeni-session-specific, so it must never inherit the box-global legacy
46
+ * Toolspace pointer. Session-scoped interactive exec/PTY uses Channel A; the
47
+ * shared ttyd shell fails closed for Toolspace until that stream plane itself is
48
+ * session-isolated.
49
+ */
50
+ export declare function buildTerminalServerScript(options?: EnsureTerminalServerOptions): string;
51
+ /**
52
+ * Idempotently bring up the ttyd PTY-over-websocket server on the live box. Safe
53
+ * to call N times (the in-box flock + the up-script's curl readiness probe make a
54
+ * second call a no-op). Resolves with the exposed port on success; throws
55
+ * `TerminalServerError` on a launch failure and `TerminalServerUnsupportedError`
56
+ * when the session cannot run commands.
57
+ *
58
+ * `session` is the externally-owned provider session (the `established.session`
59
+ * from establishSandboxSessionFromEnvelope, or any SandboxSessionLike). We prefer
60
+ * `session.exec` (structured `{exitCode}`) and fall back to `session.execCommand`
61
+ * (bare string), inferring success from the up-script's marker line in the
62
+ * fallback case. Mirrors ensureDisplayStack exactly.
63
+ */
64
+ export declare function ensureTerminalServer(session: unknown, options?: EnsureTerminalServerOptions): Promise<EnsureTerminalServerResult>;
65
+ /** Tear the terminal server down (down-script). Best-effort; never throws on a
66
+ * missing process. Mirrors tearDownDisplayStack. */
67
+ export declare function tearDownTerminalServer(session: unknown): Promise<void>;
@@ -0,0 +1,23 @@
1
+ import type { SandboxClient } from "@openai/agents/sandbox";
2
+ export declare class ToolspaceTokenPathError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export declare function shellToolspacePath(value: string): string;
6
+ /**
7
+ * Derive the per-session token file beside the legacy manifest pointer.
8
+ *
9
+ * The manifest pointer stays box-global so an already-warm shared sandbox does
10
+ * not receive an illegal environment delta. Every OpenGeni command overrides
11
+ * that pointer with this deterministic path. The hash is path hygiene and
12
+ * avoids disclosing host/session ids in filenames; filesystem paths are not an
13
+ * authorization boundary. The delegated bearer's session claim remains the
14
+ * authority boundary for Toolspace calls.
15
+ */
16
+ export declare function toolspaceTokenFileForSession(manifestTokenFile: string, sessionId: string): string;
17
+ export declare function toolspaceTokenFileFromEnvironment(environment: Readonly<Record<string, string>>, sessionId: string): string;
18
+ /** Prefix one sandbox command with its session-specific Toolspace pointer. */
19
+ export declare function withToolspaceTokenEnvironment(cmd: string, tokenFile: string): string;
20
+ /** Preserve provider identity/capabilities while decorating command creation. */
21
+ export declare function withToolspaceTokenSession<T extends object>(session: T, tokenFile: string): T;
22
+ /** Decorate every client-created/resumed session with one session pointer. */
23
+ export declare function withToolspaceTokenClient(client: SandboxClient, tokenFile: string): SandboxClient;
@@ -0,0 +1,72 @@
1
+ type CommandCancellationSession = {
2
+ cancelExecCommand?(opId: string): Promise<boolean>;
3
+ supportsPty?(): boolean;
4
+ hasRetainedProcess?(providerSessionId: number): boolean;
5
+ writeStdinForProcessMutation?(args: {
6
+ sessionId: number;
7
+ chars?: string;
8
+ yieldTimeMs?: number;
9
+ maxOutputTokens?: number;
10
+ }): Promise<string>;
11
+ writeStdinForProcessControl?(args: {
12
+ sessionId: number;
13
+ chars?: string;
14
+ yieldTimeMs?: number;
15
+ maxOutputTokens?: number;
16
+ }): Promise<string>;
17
+ execCommandForProcessControl?(providerSessionId: number, args: TurnSandboxCommandArgs): Promise<string>;
18
+ };
19
+ export type TurnSandboxCommandArgs = {
20
+ cmd: string;
21
+ workdir?: string;
22
+ shell?: string;
23
+ login?: boolean;
24
+ tty?: boolean;
25
+ yieldTimeMs?: number;
26
+ maxOutputTokens?: number;
27
+ runAs?: string;
28
+ };
29
+ export type TurnSandboxCommandResult = {
30
+ stdout: string;
31
+ stderr: string;
32
+ exitCode: number;
33
+ wallTimeSeconds: number;
34
+ };
35
+ export type TurnSandboxCommandSession = CommandCancellationSession & {
36
+ exec?(args: TurnSandboxCommandArgs): Promise<unknown>;
37
+ execCommand?(args: TurnSandboxCommandArgs): Promise<string>;
38
+ writeStdin?(args: {
39
+ sessionId: number;
40
+ chars?: string;
41
+ yieldTimeMs?: number;
42
+ maxOutputTokens?: number;
43
+ }): Promise<string>;
44
+ };
45
+ /**
46
+ * The worker may publish an attempt-quiesced receipt only after this fence
47
+ * resolves. `cancel()` prevents new turn-owned sandbox calls, actively stops
48
+ * shell processes, and `waitForQuiescence()` drains every capability call that
49
+ * was already in flight. Cleanup/telemetry outside the sandbox capability set
50
+ * remains independently attempt-fenced.
51
+ */
52
+ export type TurnToolCancellationFence = {
53
+ cancel(reason?: unknown): void;
54
+ waitForQuiescence(): Promise<void>;
55
+ runSandboxCommand(session: TurnSandboxCommandSession, args: TurnSandboxCommandArgs): Promise<unknown>;
56
+ runSandboxCommandStructured(session: TurnSandboxCommandSession, args: TurnSandboxCommandArgs): Promise<TurnSandboxCommandResult>;
57
+ };
58
+ export type TurnToolCancellationController = TurnToolCancellationFence & {
59
+ wrapTools<T>(tools: T[], session?: CommandCancellationSession): T[];
60
+ };
61
+ export declare class TurnSandboxCommandCancelledError extends Error {
62
+ readonly name = "TurnSandboxCommandCancelledError";
63
+ constructor(reason: unknown);
64
+ }
65
+ export declare function cancellableShellCommand(command: string, markerPath: string): string;
66
+ export declare function createTurnToolCancellationController(signal?: AbortSignal): TurnToolCancellationController;
67
+ /** Wrap a capability instance without depending on SDK-private subclasses. */
68
+ export declare function wrapCapabilityToolsForTurnCancellation(capability: {
69
+ tools(): unknown[];
70
+ _session?: CommandCancellationSession;
71
+ }, controller: TurnToolCancellationController): void;
72
+ export {};
@@ -0,0 +1,39 @@
1
+ import { type NativeSnapshotDescriptor, type NativeSnapshotRef, type WorkspaceArchiveDescriptor, type WorkspaceTreeFingerprint } from "@opengeni/contracts";
2
+ export { WORKSPACE_ARCHIVE_DESCRIPTOR_VERSION, decodeNativeSnapshotRef, parseWorkspaceArchiveDescriptor, type NativeSnapshotDescriptor, type NativeSnapshotProvider, type NativeSnapshotRef, type TarWorkspaceArchiveDescriptor, type WorkspaceArchiveDescriptor, type WorkspaceTreeFingerprint, } from "@opengeni/contracts";
3
+ export type VerifiedWorkspaceArchive = {
4
+ bytes: Uint8Array;
5
+ base64: string;
6
+ descriptor: WorkspaceArchiveDescriptor;
7
+ kind: "tar" | "provider_snapshot";
8
+ nativeSnapshot?: NativeSnapshotRef;
9
+ };
10
+ export type WorkspaceArchiveIntegrityCode = "archive_metadata_missing" | "archive_metadata_invalid" | "archive_base64_invalid" | "archive_hash_mismatch" | "archive_hydration_failed" | "workspace_fingerprint_unavailable" | "workspace_changed_during_capture" | "workspace_fingerprint_mismatch" | "native_snapshot_reference_invalid" | "native_snapshot_fallback_unverified";
11
+ export declare class WorkspaceArchiveIntegrityError extends Error {
12
+ readonly code: WorkspaceArchiveIntegrityCode;
13
+ readonly name = "WorkspaceArchiveIntegrityError";
14
+ readonly retryable: boolean;
15
+ constructor(code: WorkspaceArchiveIntegrityCode, message: string, options?: {
16
+ retryable?: boolean;
17
+ });
18
+ }
19
+ export declare function describeNativeSnapshotArchive(bytes: Uint8Array, capturedAtMs?: number): NativeSnapshotDescriptor | null;
20
+ export declare function describeLegacyNativeSnapshotArchive(base64: unknown, observedAtMs?: number): {
21
+ archiveBase64: string;
22
+ descriptor: NativeSnapshotDescriptor;
23
+ } | null;
24
+ export declare function readVerifiedWorkspaceArchive(base64: unknown, metadata: unknown): VerifiedWorkspaceArchive | null;
25
+ /** Hashes names, kinds, modes, symlink targets and all file bytes through one
26
+ * deterministic GNU tar stream. Hardlinks are dereferenced deliberately:
27
+ * content-preserving providers may restore them as independent files, and inode
28
+ * topology is not part of OpenGeni's workspace contract. Manifest paths that
29
+ * the provider's tar persistence deliberately excludes are pruned from both the
30
+ * digest and counters, so verification covers the exact persistent projection.
31
+ * Only the aggregate is returned; paths and file contents never enter logs or
32
+ * durable metadata. */
33
+ export declare function fingerprintSandboxWorkspace(session: unknown): Promise<WorkspaceTreeFingerprint>;
34
+ /** Provider-native persistence returns an opaque receipt and is accepted under
35
+ * the provider/artifact publication fence. A real tar capture is accepted only
36
+ * when the complete persistent tree is byte-identical immediately before and
37
+ * after serialization; a concurrent mutation makes that candidate unusable. */
38
+ export declare function captureVerifiedWorkspaceArchive(session: unknown, capturedAtMs?: number): Promise<VerifiedWorkspaceArchive>;
39
+ export declare function verifyRestoredWorkspace(session: unknown, descriptor: WorkspaceArchiveDescriptor): Promise<WorkspaceTreeFingerprint | null>;
@@ -0,0 +1,227 @@
1
+ import { type Computer, type Tool } from "@openai/agents";
2
+ import { Capability, type SandboxSessionLike } from "@openai/agents/sandbox";
3
+ import { type DesktopInputRequest } from "@opengeni/agent-proto";
4
+ type ComputerButton = "left" | "right" | "wheel" | "back" | "forward";
5
+ export type SandboxComputerOptions = {
6
+ display?: string;
7
+ dimensions?: [number, number];
8
+ runAs?: string;
9
+ typeDelayMs?: number;
10
+ readOnly?: boolean;
11
+ screenshotTmpDir?: string;
12
+ screenshotWarmupBudgetMs?: number;
13
+ screenshotRetryDelayMs?: number;
14
+ /**
15
+ * One turn-scoped preparation hook, invoked by the first real computer action.
16
+ * The agent may advertise computer-use on every turn, but merely advertising the
17
+ * tool must not boot Xvfb/XFCE or start a recording. The runtime capability owns
18
+ * this hook and uses it to bring up :0 (and optionally notify the worker) only
19
+ * after the model actually chooses a computer tool.
20
+ */
21
+ prepare?: (session: SandboxSessionLike) => Promise<void>;
22
+ };
23
+ /** No exec/execCommand on the session, or the display is not up. */
24
+ export declare class ComputerUnavailableError extends Error {
25
+ constructor(message: string);
26
+ }
27
+ /** The screenshot file read back SHORT of its on-box byte size — a chunk was truncated
28
+ * by the provider's exec-output cap. This is deterministic, NOT a warm-up transient, so
29
+ * it fails LOUD immediately with the byte counts (never a silent blank the model would
30
+ * read as a real empty screen) and is not retried. */
31
+ export declare class ScreenshotReadError extends Error {
32
+ constructor(message: string);
33
+ }
34
+ /** A write action attempted while readOnly. */
35
+ export declare class ComputerReadOnlyError extends Error {
36
+ constructor();
37
+ }
38
+ /** A nonzero xdotool/scrot exit, OR a command that did not finish before the
39
+ * yield window (F3 — "still running" is a failure, not a silent success). */
40
+ export declare class ComputerActionError extends Error {
41
+ cmd: string;
42
+ exitCode: number;
43
+ stderr: string;
44
+ constructor(cmd: string, exitCode: number, stderr: string);
45
+ }
46
+ /**
47
+ * The Computer the agent drives. Every action issues ONE shell line through the
48
+ * externally-owned session (exec ?? execCommand, F1), prefixed with the display.
49
+ * screenshot() scrots to a /tmp file and reads the RAW bytes by running
50
+ * `base64 <path>` over the SAME command primitive and stripping the banner — NOT
51
+ * `session.readFile` (Modal's readFile path-validates against /workspace and rejects
52
+ * /tmp with "escapes the workspace root", which would yield an empty frame and 400
53
+ * the model). The base64-over-exec path is /tmp-readable and binary-safe.
54
+ */
55
+ export declare class SandboxComputer implements Computer {
56
+ readonly environment: "ubuntu";
57
+ readonly dimensions: [number, number];
58
+ private session;
59
+ private readonly display;
60
+ private readonly runAs?;
61
+ private readonly typeDelayMs;
62
+ private readonly readOnly;
63
+ private readonly tmp;
64
+ private readonly screenshotWarmupBudgetMs;
65
+ private readonly screenshotRetryDelayMs;
66
+ private readonly prepare;
67
+ private prepared;
68
+ private preparation;
69
+ constructor(session: SandboxSessionLike, opts?: SandboxComputerOptions);
70
+ /** Rebind to a freshly resumed-by-id session after a box rollover / re-establish. */
71
+ rebind(session: SandboxSessionLike): void;
72
+ private prepareOnce;
73
+ private x;
74
+ private guardWrite;
75
+ private shq;
76
+ screenshot(): Promise<string>;
77
+ private readCmdRaw;
78
+ private readScreenshotBytes;
79
+ click(xp: number, yp: number, button: ComputerButton): Promise<void>;
80
+ doubleClick(xp: number, yp: number): Promise<void>;
81
+ move(xp: number, yp: number): Promise<void>;
82
+ scroll(xp: number, yp: number, sx: number, sy: number): Promise<void>;
83
+ type(text: string): Promise<void>;
84
+ keypress(keys: string[]): Promise<void>;
85
+ drag(path: [number, number][]): Promise<void>;
86
+ wait(): Promise<void>;
87
+ }
88
+ /** The structural slice of a self-hosted session the native computer drives — the
89
+ * two control-plane ops added in session.ts. Kept structural (NOT an import of
90
+ * `SelfhostedSession`) so this agent-loop file never hard-couples to the sandbox
91
+ * leaf; the duck-typed `isNativeDesktopSession` probe (below) selects on it. */
92
+ export type NativeDesktopSession = {
93
+ desktopInput(event: DesktopInputRequest["event"]): Promise<void>;
94
+ screenshot(): Promise<{
95
+ png: Uint8Array;
96
+ width: number;
97
+ height: number;
98
+ nativeWidth: number;
99
+ nativeHeight: number;
100
+ }>;
101
+ };
102
+ export type NativeDesktopComputerOptions = {
103
+ dimensions?: [number, number];
104
+ environment?: NonNullable<Computer["environment"]>;
105
+ readOnly?: boolean;
106
+ screenshotWarmupBudgetMs?: number;
107
+ screenshotRetryDelayMs?: number;
108
+ };
109
+ /**
110
+ * A `Computer` that drives a SELF-HOSTED machine's OWN desktop NATIVELY over the
111
+ * control plane (`desktopInput` inject + `screenshot` capture on the bound
112
+ * `SelfhostedSession`) instead of xdotool/scrot over `exec`. Consent + epoch are
113
+ * enforced AGENT-side, so an unconsented inject surfaces the session's mapped
114
+ * control error.
115
+ *
116
+ * screenshot() returns raw base64 with NO data-URL prefix — the EXACT contract of
117
+ * `SandboxComputer.screenshot`: the Agents SDK wraps it as
118
+ * `data:image/png;base64,${output}`, so an empty string would become
119
+ * `image_url: ''` and 400 the model turn. An empty PNG therefore THROWS
120
+ * `ComputerUnavailableError` (mirroring SandboxComputer's empty-guard) — the model
121
+ * never receives an empty image_url.
122
+ */
123
+ export declare class NativeDesktopComputer implements Computer {
124
+ readonly environment: NonNullable<Computer["environment"]>;
125
+ readonly dimensions: [number, number];
126
+ private session;
127
+ private readonly readOnly;
128
+ private readonly screenshotWarmupBudgetMs;
129
+ private readonly screenshotRetryDelayMs;
130
+ private lastEncoded;
131
+ private lastNative;
132
+ constructor(session: NativeDesktopSession, opts?: NativeDesktopComputerOptions);
133
+ /** Rebind to a freshly resumed-by-id session after a box rollover / re-establish. */
134
+ rebind(session: NativeDesktopSession): void;
135
+ private guardWrite;
136
+ /** Scale a coordinate the model expressed in the MOST RECENT screenshot's
137
+ * ENCODED pixel space back to NATIVE pixels. When the last frame was not
138
+ * downscaled (encoded == native), or no screenshot has been taken yet, this is a
139
+ * 1:1 identity — the byte-identical current behavior. The agent then applies its
140
+ * own platform mapping (macOS divides native pixels by the backing scale to reach
141
+ * CGEvent points; Linux XTEST is 1:1) exactly as it did pre-downscale. */
142
+ private toNative;
143
+ private pointer;
144
+ screenshot(): Promise<string>;
145
+ click(x: number, y: number, button: ComputerButton): Promise<void>;
146
+ doubleClick(x: number, y: number): Promise<void>;
147
+ move(x: number, y: number): Promise<void>;
148
+ scroll(x: number, y: number, sx: number, sy: number): Promise<void>;
149
+ type(text: string): Promise<void>;
150
+ keypress(keys: string[]): Promise<void>;
151
+ drag(path: [number, number][]): Promise<void>;
152
+ wait(): Promise<void>;
153
+ }
154
+ /**
155
+ * Backend-aware SELECTION discriminator: a SELF-HOSTED session exposes the two
156
+ * native control-plane ops (`desktopInput` + `screenshot`); a MODAL session does
157
+ * not (it drives the desktop via xdotool/scrot over `exec`). Duck-typing on those
158
+ * two methods keeps this file from hard-importing `SelfhostedSession` (avoiding an
159
+ * agent-loop ↔ sandbox-leaf import coupling) and is future-proof: any backend that
160
+ * grows native inject/capture is picked up automatically.
161
+ */
162
+ export declare function isNativeDesktopSession(session: SandboxSessionLike): session is SandboxSessionLike & NativeDesktopSession;
163
+ /**
164
+ * The FUNCTION-transport computer tools for the codex / text backend, each routing
165
+ * to the SAME bound `Computer` the hosted `computer_use_preview` tool would drive.
166
+ * `computer_screenshot` hands the model the desktop two ways, selected by
167
+ * `imageFunctionResults`:
168
+ * • false (chat-completions providers, the default) → the text-transport
169
+ * `data:image/png;base64,…` URL (imageOutputFromBytes → renderImageForTextTransport,
170
+ * the SDK's text `view_image` path) — those backends can't read structured image
171
+ * tool results.
172
+ * • true (the codex/ChatGPT backend) → the structured `{type:'image'}` tool output,
173
+ * which agents-core normalizes into an `input_image` content item inside the
174
+ * function_call_output — the codex /responses backend accepts and SEES it (a text
175
+ * data-URL there is just unreadable text). See index.ts for why it's on there.
176
+ * Write tools return a concise confirmation; when read-only they return
177
+ * {@link COMPUTER_READ_ONLY_MESSAGE} instead of throwing, and any action error is
178
+ * returned as a string so a failed action never kills the turn. Exported so it can be
179
+ * unit-tested against a fake `Computer`.
180
+ */
181
+ export declare function computerFunctionTools(computer: Computer, readOnly: boolean, needsApproval?: ComputerUseArgs["needsApproval"], imageFunctionResults?: boolean): Tool<unknown>[];
182
+ /**
183
+ * EXPLICIT tool-transport selection, decided by the caller that knows the
184
+ * provider's true wire identity (the worker's model resolution — see agent-turn.ts),
185
+ * never inferred from the bound model instance's constructor name:
186
+ * • "hosted" → the single hosted `computer_use_preview` tool (Responses backends).
187
+ * • "function-image" → the FUNCTION `computer_*` tools with screenshots delivered as a
188
+ * structured `{type:'image'}` output (the codex/ChatGPT backend,
189
+ * which rejects hosted tool types but SEES structured image results).
190
+ * • "disabled" → no computer tools. Providers without a proven visual image
191
+ * transport fail closed instead of receiving base64 as text.
192
+ * • "function-text" → deprecated fail-closed alias retained for source compatibility.
193
+ * • omitted → fail closed exactly like "disabled"; public runtime callers must
194
+ * prove the transport explicitly before computer tools are exposed.
195
+ */
196
+ export type ComputerToolMode = "hosted" | "function-image" | "disabled" | "function-text";
197
+ export type ComputerUseArgs = {
198
+ dimensions?: [number, number];
199
+ readOnly?: boolean;
200
+ display?: string;
201
+ needsApproval?: boolean | ((ctx: unknown, action: unknown) => boolean | Promise<boolean>);
202
+ /** @deprecated Use `toolMode: "function-image"`. Omitted transport now fails closed. */
203
+ imageFunctionResults?: boolean;
204
+ toolMode?: ComputerToolMode;
205
+ /** Called after the display is ready on the first actual computer action. */
206
+ onReady?: (session: SandboxSessionLike) => Promise<void>;
207
+ };
208
+ export declare function computerUse(args?: ComputerUseArgs): ComputerUseCapability;
209
+ /**
210
+ * A `Capability` subclass merged into the agent's tool set by SandboxAgent
211
+ * (`tools = [...agent.tools, ...capability.tools()]`). `bind(session)` hands it
212
+ * the LIVE externally-owned session, so the agent's actions and the viewers'
213
+ * pixels are one display.
214
+ *
215
+ * `tools()` is transport-aware only through `ComputerUseArgs.toolMode`. The bound
216
+ * model instance is intentionally ignored: a constructor name cannot prove whether
217
+ * screenshots travel as hosted computer output or structured function images.
218
+ */
219
+ export declare class ComputerUseCapability extends Capability {
220
+ private args;
221
+ readonly type = "computer-use";
222
+ constructor(args?: ComputerUseArgs);
223
+ tools(): Tool<unknown>[];
224
+ /** The single HOSTED `computer_use_preview` tool bound to `computer`. */
225
+ private hostedComputerTool;
226
+ }
227
+ export {};
@@ -0,0 +1 @@
1
+ export declare const SCREENSHOT_FAILURE_CARD_IMAGE_URL = "data:image/png;base64,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";
@@ -6,7 +6,7 @@
6
6
  * Entries are immutable in the runtime. A new artifact gets a new version and
7
7
  * content hash; callers must not mutate the returned records.
8
8
  */
9
- type SkillLibraryEntry = Readonly<{
9
+ export type SkillLibraryEntry = Readonly<{
10
10
  id: string;
11
11
  name: string;
12
12
  version: string;
@@ -30,32 +30,32 @@ type SkillLibraryEntry = Readonly<{
30
30
  }>;
31
31
  relativePath: string;
32
32
  }>;
33
- type SkillLibraryFile = Readonly<{
33
+ export type SkillLibraryFile = Readonly<{
34
34
  path: string;
35
35
  content: string;
36
36
  }>;
37
- type SkillLibraryArtifact = Readonly<{
37
+ export type SkillLibraryArtifact = Readonly<{
38
38
  files: readonly SkillLibraryFile[];
39
39
  /** SHA-256 over the complete canonical artifact manifest, not just SKILL.md. */
40
40
  contentSha256: string;
41
41
  }>;
42
- type SkillLibrarySkill = Readonly<{
42
+ export type SkillLibrarySkill = Readonly<{
43
43
  name: string;
44
44
  description: string;
45
45
  files: readonly SkillLibraryFile[];
46
46
  }>;
47
47
  /** Return only entries whose reviewed artifact is present in this deployment. */
48
- declare function listSkillLibraryEntries(): readonly SkillLibraryEntry[];
48
+ export declare function listSkillLibraryEntries(): readonly SkillLibraryEntry[];
49
49
  /** Return whether an id belongs to the immutable library, even if its artifact is unavailable. */
50
- declare function isSkillLibraryEntryId(id: string): boolean;
50
+ export declare function isSkillLibraryEntryId(id: string): boolean;
51
51
  /** Resolve an exact immutable library entry by id and version. */
52
- declare function getSkillLibraryEntry(id: string, version?: string): SkillLibraryEntry | null;
52
+ export declare function getSkillLibraryEntry(id: string, version?: string): SkillLibraryEntry | null;
53
53
  /**
54
54
  * Load a selected curated entry into the SDK's in-memory skill shape.
55
55
  * Selection is guidance-only: this function has no access to settings,
56
56
  * credentials, MCP declarations, or model-provider configuration.
57
57
  */
58
- declare function loadSkillLibrarySkill(id: string, version?: string): {
58
+ export declare function loadSkillLibrarySkill(id: string, version?: string): {
59
59
  entry: SkillLibraryEntry;
60
60
  skill: SkillLibrarySkill;
61
61
  };
@@ -67,8 +67,6 @@ declare function loadSkillLibrarySkill(id: string, version?: string): {
67
67
  * a lossy UTF-8 string round-trip. Files are decoded only after the digest
68
68
  * input has been captured because the SDK skill surface is text-based.
69
69
  */
70
- declare function readSkillLibraryArtifact(root: string): SkillLibraryArtifact;
70
+ export declare function readSkillLibraryArtifact(root: string): SkillLibraryArtifact;
71
71
  /** Verify a reviewed artifact against its immutable catalog digest. */
72
- declare function verifySkillLibraryArtifact(root: string, expectedSha256: string, entry?: Pick<SkillLibraryEntry, "id" | "version">): SkillLibraryArtifact;
73
-
74
- export { type SkillLibraryArtifact, type SkillLibraryEntry, type SkillLibraryFile, type SkillLibrarySkill, getSkillLibraryEntry, isSkillLibraryEntryId, listSkillLibraryEntries, loadSkillLibrarySkill, readSkillLibraryArtifact, verifySkillLibraryArtifact };
72
+ export declare function verifySkillLibraryArtifact(root: string, expectedSha256: string, entry?: Pick<SkillLibraryEntry, "id" | "version">): SkillLibraryArtifact;