@rivet-dev/agentos-runtime-core 0.2.8-rc.2 → 0.2.8-rc.4
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/README.md +1 -1
- package/commands/[ +0 -0
- package/commands/_stubs +0 -0
- package/commands/acl_tools +0 -0
- package/commands/arch +0 -0
- package/commands/attr +0 -0
- package/commands/awk +0 -0
- package/commands/b2sum +0 -0
- package/commands/base32 +0 -0
- package/commands/base64 +0 -0
- package/commands/basename +0 -0
- package/commands/basenc +0 -0
- package/commands/bash +0 -0
- package/commands/bc +0 -0
- package/commands/cat +0 -0
- package/commands/chacl +0 -0
- package/commands/chcon +0 -0
- package/commands/chgrp +0 -0
- package/commands/chmod +0 -0
- package/commands/chown +0 -0
- package/commands/chroot +0 -0
- package/commands/cksum +0 -0
- package/commands/cmp +0 -0
- package/commands/column +0 -0
- package/commands/comm +0 -0
- package/commands/cp +0 -0
- package/commands/curl +0 -0
- package/commands/cut +0 -0
- package/commands/date +0 -0
- package/commands/dd +0 -0
- package/commands/df +0 -0
- package/commands/diff +0 -0
- package/commands/dir +0 -0
- package/commands/dircolors +0 -0
- package/commands/dirname +0 -0
- package/commands/du +0 -0
- package/commands/echo +0 -0
- package/commands/egrep +0 -0
- package/commands/env +0 -0
- package/commands/envsubst +0 -0
- package/commands/expand +0 -0
- package/commands/expr +0 -0
- package/commands/factor +0 -0
- package/commands/false +0 -0
- package/commands/fd +0 -0
- package/commands/fgrep +0 -0
- package/commands/file +0 -0
- package/commands/find +0 -0
- package/commands/findmnt +0 -0
- package/commands/fmt +0 -0
- package/commands/fold +0 -0
- package/commands/getent +0 -0
- package/commands/getfacl +0 -0
- package/commands/getfattr +0 -0
- package/commands/git +0 -0
- package/commands/git-receive-pack +0 -0
- package/commands/git-remote-http +0 -0
- package/commands/git-remote-https +0 -0
- package/commands/git-upload-archive +0 -0
- package/commands/git-upload-pack +0 -0
- package/commands/grep +0 -0
- package/commands/groups +0 -0
- package/commands/gunzip +0 -0
- package/commands/gzip +0 -0
- package/commands/head +0 -0
- package/commands/hostid +0 -0
- package/commands/hostname +0 -0
- package/commands/http-test +0 -0
- package/commands/id +0 -0
- package/commands/install +0 -0
- package/commands/join +0 -0
- package/commands/jq +0 -0
- package/commands/kill +0 -0
- package/commands/link +0 -0
- package/commands/ln +0 -0
- package/commands/logname +0 -0
- package/commands/ls +0 -0
- package/commands/md5sum +0 -0
- package/commands/mkdir +0 -0
- package/commands/mkfifo +0 -0
- package/commands/mknod +0 -0
- package/commands/mktemp +0 -0
- package/commands/more +0 -0
- package/commands/mount +0 -0
- package/commands/mv +0 -0
- package/commands/nice +0 -0
- package/commands/nl +0 -0
- package/commands/nohup +0 -0
- package/commands/nproc +0 -0
- package/commands/numfmt +0 -0
- package/commands/od +0 -0
- package/commands/paste +0 -0
- package/commands/pathchk +0 -0
- package/commands/pinky +0 -0
- package/commands/printenv +0 -0
- package/commands/printf +0 -0
- package/commands/ptx +0 -0
- package/commands/pwd +0 -0
- package/commands/readlink +0 -0
- package/commands/realpath +0 -0
- package/commands/rev +0 -0
- package/commands/rg +0 -0
- package/commands/rm +0 -0
- package/commands/rmdir +0 -0
- package/commands/runas +0 -0
- package/commands/runcon +0 -0
- package/commands/sed +0 -0
- package/commands/seq +0 -0
- package/commands/setfacl +0 -0
- package/commands/setfattr +0 -0
- package/commands/sh +0 -0
- package/commands/sha1sum +0 -0
- package/commands/sha224sum +0 -0
- package/commands/sha256sum +0 -0
- package/commands/sha384sum +0 -0
- package/commands/sha512sum +0 -0
- package/commands/shred +0 -0
- package/commands/shuf +0 -0
- package/commands/sleep +0 -0
- package/commands/sort +0 -0
- package/commands/spawn-test-host +0 -0
- package/commands/split +0 -0
- package/commands/sqlite3 +0 -0
- package/commands/ssh +0 -0
- package/commands/ssh-keysign +0 -0
- package/commands/ssh-sk-helper +0 -0
- package/commands/stat +0 -0
- package/commands/stdbuf +0 -0
- package/commands/strings +0 -0
- package/commands/stty +0 -0
- package/commands/su +0 -0
- package/commands/sum +0 -0
- package/commands/sync +0 -0
- package/commands/tac +0 -0
- package/commands/tail +0 -0
- package/commands/tar +0 -0
- package/commands/tee +0 -0
- package/commands/test +0 -0
- package/commands/timeout +0 -0
- package/commands/touch +0 -0
- package/commands/tr +0 -0
- package/commands/tree +0 -0
- package/commands/true +0 -0
- package/commands/truncate +0 -0
- package/commands/tsort +0 -0
- package/commands/tty +0 -0
- package/commands/uname +0 -0
- package/commands/unexpand +0 -0
- package/commands/uniq +0 -0
- package/commands/unlink +0 -0
- package/commands/unzip +0 -0
- package/commands/uptime +0 -0
- package/commands/users +0 -0
- package/commands/vdir +0 -0
- package/commands/wc +0 -0
- package/commands/wget +0 -0
- package/commands/which +0 -0
- package/commands/who +0 -0
- package/commands/whoami +0 -0
- package/commands/xargs +0 -0
- package/commands/xattr_tools +0 -0
- package/commands/xfs_io +0 -0
- package/commands/xu +0 -0
- package/commands/yes +0 -0
- package/commands/yq +0 -0
- package/commands/zcat +0 -0
- package/commands/zip +0 -0
- package/dist/binary.js +4 -3
- package/dist/descriptors.d.ts +2 -12
- package/dist/descriptors.js +10 -6
- package/dist/frame-stream.d.ts +33 -0
- package/dist/frame-stream.js +113 -0
- package/dist/generated/AcpLimitsConfig.d.ts +16 -0
- package/dist/generated/BindingLimitsConfig.d.ts +10 -0
- package/dist/generated/CreateVmConfig.d.ts +4 -0
- package/dist/generated/Http2LimitsConfig.d.ts +12 -0
- package/dist/generated/Http2LimitsConfig.js +2 -0
- package/dist/generated/JsRuntimeLimitsConfig.d.ts +1 -0
- package/dist/generated/MountPluginDescriptor.d.ts +1 -1
- package/dist/generated/ProcessLimitsConfig.d.ts +7 -0
- package/dist/generated/ProcessLimitsConfig.js +2 -0
- package/dist/generated/ReactorLimitsConfig.d.ts +23 -0
- package/dist/generated/ReactorLimitsConfig.js +2 -0
- package/dist/generated/SqliteLimitsConfig.d.ts +3 -0
- package/dist/generated/SqliteLimitsConfig.js +2 -0
- package/dist/generated/TlsLimitsConfig.d.ts +3 -0
- package/dist/generated/TlsLimitsConfig.js +2 -0
- package/dist/generated/UdpLimitsConfig.d.ts +4 -0
- package/dist/generated/UdpLimitsConfig.js +2 -0
- package/dist/generated/VmGroupConfig.d.ts +5 -0
- package/dist/generated/VmGroupConfig.js +2 -0
- package/dist/generated/VmLimitsConfig.d.ts +14 -2
- package/dist/generated/VmSqliteDescriptor.d.ts +10 -0
- package/dist/generated/VmSqliteDescriptor.js +2 -0
- package/dist/generated/VmUserAccountConfig.d.ts +9 -0
- package/dist/generated/VmUserAccountConfig.js +2 -0
- package/dist/generated/VmUserConfig.d.ts +19 -0
- package/dist/generated/VmUserConfig.js +1 -0
- package/dist/generated/WasmLimitsConfig.d.ts +1 -0
- package/dist/generated-protocol.d.ts +60 -2
- package/dist/generated-protocol.js +166 -31
- package/dist/kernel-proxy.d.ts +4 -0
- package/dist/kernel-proxy.js +53 -20
- package/dist/native-client.d.ts +3 -3
- package/dist/native-client.js +43 -8
- package/dist/node-runtime-options-schema.d.ts +1 -1
- package/dist/node-runtime-options-schema.js +43 -1
- package/dist/node-runtime.d.ts +12 -3
- package/dist/node-runtime.js +8 -7
- package/dist/process.d.ts +5 -1
- package/dist/process.js +35 -8
- package/dist/protocol-client.d.ts +9 -2
- package/dist/protocol-client.js +127 -7
- package/dist/protocol-frames.d.ts +14 -3
- package/dist/protocol-frames.js +26 -1
- package/dist/protocol-schema.d.ts +1 -1
- package/dist/protocol-schema.js +1 -1
- package/dist/request-payloads.d.ts +4 -1
- package/dist/request-payloads.js +7 -2
- package/dist/response-payloads.d.ts +22 -1
- package/dist/response-payloads.js +33 -1
- package/dist/sidecar-errors.d.ts +22 -0
- package/dist/sidecar-errors.js +10 -0
- package/dist/sidecar-process.d.ts +12 -2
- package/dist/sidecar-process.js +77 -12
- package/dist/test-runtime.d.ts +19 -7
- package/dist/test-runtime.js +213 -66
- package/dist/vm-config.d.ts +5 -1
- package/package.json +11 -6
- package/commands/codex +0 -0
- package/commands/codex-exec +0 -0
- package/commands/http_get +0 -0
- package/dist/generated/ToolLimitsConfig.d.ts +0 -10
- /package/dist/generated/{ToolLimitsConfig.js → BindingLimitsConfig.js} +0 -0
package/dist/native-client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolvePublishedSidecarBinary } from "./binary.js";
|
|
2
|
-
import { SidecarProcessExited, StdioSidecarProcess
|
|
2
|
+
import { SidecarProcessExited, StdioSidecarProcess } from "./process.js";
|
|
3
3
|
import { SidecarProtocolClient } from "./protocol-client.js";
|
|
4
4
|
import { registerSidecarProcessSpawnFactory } from "./sidecar-process.js";
|
|
5
5
|
export const DEFAULT_SIDECAR_EVENT_BUFFER_CAPACITY = 4_096;
|
|
@@ -18,9 +18,19 @@ export class StdioSidecarProtocolClient {
|
|
|
18
18
|
this.gracefulExitMs = options.gracefulExitMs;
|
|
19
19
|
this.forceExitMs = options.forceExitMs;
|
|
20
20
|
this.disposedErrorMessage = options.disposedErrorMessage;
|
|
21
|
+
const transportOptions = this.sidecarProcess.combinedStdio
|
|
22
|
+
? {
|
|
23
|
+
stdin: this.child.stdin,
|
|
24
|
+
stdout: this.child.stdout,
|
|
25
|
+
combinedStdio: true,
|
|
26
|
+
}
|
|
27
|
+
: {
|
|
28
|
+
stdin: this.child.stdin,
|
|
29
|
+
stdout: this.child.stdout,
|
|
30
|
+
control: this.sidecarProcess.control,
|
|
31
|
+
};
|
|
21
32
|
this.protocolClient = new SidecarProtocolClient({
|
|
22
|
-
|
|
23
|
-
stdout: this.child.stdout,
|
|
33
|
+
...transportOptions,
|
|
24
34
|
eventBufferCapacity: options.eventBufferCapacity,
|
|
25
35
|
payloadCodec: options.payloadCodec,
|
|
26
36
|
silenceTimeoutMs: options.silenceTimeoutMs,
|
|
@@ -52,14 +62,15 @@ export class StdioSidecarProtocolClient {
|
|
|
52
62
|
});
|
|
53
63
|
}
|
|
54
64
|
static spawn(options = {}) {
|
|
65
|
+
const combinedStdio = typeof globalThis._childProcessSpawnStart !== "undefined";
|
|
55
66
|
return new StdioSidecarProtocolClient(StdioSidecarProcess.spawn({
|
|
56
67
|
command: options.command ?? resolvePublishedSidecarBinary(),
|
|
57
68
|
args: options.args ?? [],
|
|
58
69
|
cwd: options.cwd,
|
|
70
|
+
combinedStdio,
|
|
59
71
|
}), {
|
|
60
72
|
silenceTimeoutMs: options.silenceTimeoutMs,
|
|
61
|
-
eventBufferCapacity: options.eventBufferCapacity ??
|
|
62
|
-
DEFAULT_SIDECAR_EVENT_BUFFER_CAPACITY,
|
|
73
|
+
eventBufferCapacity: options.eventBufferCapacity ?? DEFAULT_SIDECAR_EVENT_BUFFER_CAPACITY,
|
|
63
74
|
gracefulExitMs: options.gracefulExitMs ?? DEFAULT_SIDECAR_GRACEFUL_EXIT_MS,
|
|
64
75
|
forceExitMs: options.forceExitMs ?? DEFAULT_SIDECAR_FORCE_EXIT_MS,
|
|
65
76
|
disposedErrorMessage: options.disposedErrorMessage ?? "sidecar client disposed",
|
|
@@ -79,6 +90,13 @@ export class StdioSidecarProtocolClient {
|
|
|
79
90
|
return await this.protocolClient.waitForEvent(matcher, timeoutMs, options);
|
|
80
91
|
}
|
|
81
92
|
async dispose() {
|
|
93
|
+
let shutdownError = null;
|
|
94
|
+
try {
|
|
95
|
+
await this.protocolClient.shutdown(this.disposedErrorMessage);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
shutdownError = error instanceof Error ? error : new Error(String(error));
|
|
99
|
+
}
|
|
82
100
|
this.protocolClient.failPermanently(new Error(this.disposedErrorMessage));
|
|
83
101
|
if (!this.child.stdin.destroyed) {
|
|
84
102
|
try {
|
|
@@ -88,6 +106,14 @@ export class StdioSidecarProtocolClient {
|
|
|
88
106
|
// Stdin may already be closing. The child exit watcher will catch up.
|
|
89
107
|
}
|
|
90
108
|
}
|
|
109
|
+
if (this.sidecarProcess.control && !this.sidecarProcess.control.destroyed) {
|
|
110
|
+
try {
|
|
111
|
+
this.sidecarProcess.control.end();
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// The control socket may already be closing with the child.
|
|
115
|
+
}
|
|
116
|
+
}
|
|
91
117
|
const exitCode = await this.sidecarProcess.waitForExit(this.gracefulExitMs);
|
|
92
118
|
if (exitCode === null) {
|
|
93
119
|
try {
|
|
@@ -117,11 +143,20 @@ export class StdioSidecarProtocolClient {
|
|
|
117
143
|
catch {
|
|
118
144
|
// Best effort. The child is gone so the descriptor will close on its own.
|
|
119
145
|
}
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
|
|
146
|
+
if (this.sidecarProcess.control) {
|
|
147
|
+
try {
|
|
148
|
+
this.sidecarProcess.control.destroy();
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// Best effort. The child is gone so the descriptor will close on its own.
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (exitCode !== null && exitCode !== 0 && this.child.signalCode === null) {
|
|
123
155
|
throw new Error(`sidecar exited with code ${exitCode}\nstderr:\n${this.sidecarProcess.stderrText()}`);
|
|
124
156
|
}
|
|
157
|
+
if (shutdownError && this.child.exitCode !== 0) {
|
|
158
|
+
throw shutdownError;
|
|
159
|
+
}
|
|
125
160
|
}
|
|
126
161
|
failPermanently(error) {
|
|
127
162
|
this.protocolClient.failPermanently(error, {
|
|
@@ -114,4 +114,4 @@ export declare const nodeRuntimePermissionsSchema: z.ZodObject<{
|
|
|
114
114
|
* the Rust VM config.
|
|
115
115
|
*/
|
|
116
116
|
export declare const nodeRuntimeCreateOptionsSchema: z.ZodType<NodeRuntimeCreateOptions>;
|
|
117
|
-
export declare function parseNodeRuntimeCreateOptions(options
|
|
117
|
+
export declare function parseNodeRuntimeCreateOptions(options: NodeRuntimeCreateOptions): NodeRuntimeCreateOptions;
|
|
@@ -1,6 +1,46 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
const permissionModeSchema = z.enum(["allow", "deny"]);
|
|
3
3
|
const stringArray = z.array(z.string());
|
|
4
|
+
const vmIdSchema = z.number().int().min(0).max(0xffffffff);
|
|
5
|
+
const vmAccountNameSchema = z
|
|
6
|
+
.string()
|
|
7
|
+
.min(1)
|
|
8
|
+
.refine((value) => !/[:\s\0]/u.test(value), "Invalid account name");
|
|
9
|
+
const vmGuestPathSchema = z.string().startsWith("/");
|
|
10
|
+
const vmUserAccountSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
uid: vmIdSchema,
|
|
13
|
+
gid: vmIdSchema,
|
|
14
|
+
username: vmAccountNameSchema,
|
|
15
|
+
homedir: vmGuestPathSchema,
|
|
16
|
+
shell: vmGuestPathSchema,
|
|
17
|
+
gecos: z.string().optional(),
|
|
18
|
+
supplementaryGids: z.array(vmIdSchema).max(64),
|
|
19
|
+
})
|
|
20
|
+
.strict();
|
|
21
|
+
const vmGroupSchema = z
|
|
22
|
+
.object({
|
|
23
|
+
gid: vmIdSchema,
|
|
24
|
+
name: vmAccountNameSchema,
|
|
25
|
+
members: z.array(vmAccountNameSchema),
|
|
26
|
+
})
|
|
27
|
+
.strict();
|
|
28
|
+
const vmUserConfigSchema = z
|
|
29
|
+
.object({
|
|
30
|
+
uid: vmIdSchema.optional(),
|
|
31
|
+
gid: vmIdSchema.optional(),
|
|
32
|
+
euid: vmIdSchema.optional(),
|
|
33
|
+
egid: vmIdSchema.optional(),
|
|
34
|
+
username: z.string().optional(),
|
|
35
|
+
homedir: z.string().optional(),
|
|
36
|
+
shell: z.string().optional(),
|
|
37
|
+
gecos: z.string().optional(),
|
|
38
|
+
groupName: z.string().optional(),
|
|
39
|
+
supplementaryGids: z.array(vmIdSchema).max(64).optional(),
|
|
40
|
+
accounts: z.array(vmUserAccountSchema).max(64).optional(),
|
|
41
|
+
groups: z.array(vmGroupSchema).max(128).optional(),
|
|
42
|
+
})
|
|
43
|
+
.strict();
|
|
4
44
|
const fsPermissionRuleSchema = z
|
|
5
45
|
.object({
|
|
6
46
|
mode: permissionModeSchema,
|
|
@@ -91,8 +131,10 @@ const bindingDefinitionSchema = z
|
|
|
91
131
|
*/
|
|
92
132
|
export const nodeRuntimeCreateOptionsSchema = z
|
|
93
133
|
.object({
|
|
134
|
+
filesystem: z.custom((value) => typeof value === "object" && value !== null, { message: "Expected caller-owned VirtualFileSystem object" }),
|
|
94
135
|
env: z.record(z.string(), z.string()).optional(),
|
|
95
136
|
cwd: z.string().optional(),
|
|
137
|
+
user: vmUserConfigSchema.optional(),
|
|
96
138
|
permissions: nodeRuntimePermissionsSchema.optional(),
|
|
97
139
|
commandsDir: z.string().optional(),
|
|
98
140
|
wasmCommandDirs: stringArray.optional(),
|
|
@@ -116,6 +158,6 @@ export const nodeRuntimeCreateOptionsSchema = z
|
|
|
116
158
|
jsRuntime: jsRuntimeSchema.optional(),
|
|
117
159
|
})
|
|
118
160
|
.strict();
|
|
119
|
-
export function parseNodeRuntimeCreateOptions(options
|
|
161
|
+
export function parseNodeRuntimeCreateOptions(options) {
|
|
120
162
|
return nodeRuntimeCreateOptionsSchema.parse(options);
|
|
121
163
|
}
|
package/dist/node-runtime.d.ts
CHANGED
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
* isolation boundary — no host escapes, no real Node.js builtins for guest
|
|
18
18
|
* work.
|
|
19
19
|
*/
|
|
20
|
-
import type { BindingDefinition, KernelBootTiming, Permissions, VirtualDirEntry } from "./test-runtime.js";
|
|
20
|
+
import type { BindingDefinition, KernelBootTiming, Permissions, VirtualDirEntry, VirtualFileSystem } from "./test-runtime.js";
|
|
21
21
|
import type { JsRuntimeConfig } from "./generated/JsRuntimeConfig.js";
|
|
22
|
+
import type { VmUserConfig } from "./generated/VmUserConfig.js";
|
|
22
23
|
import type { SidecarProcess } from "./sidecar-process.js";
|
|
23
|
-
export type { BindingDefinition,
|
|
24
|
+
export type { BindingDefinition, BindingExample, VirtualDirEntry, } from "./test-runtime.js";
|
|
24
25
|
export { resolveNodeRuntimeSidecarBinary } from "./test-runtime.js";
|
|
25
26
|
export type NodeRuntimeBootTimingPhase = KernelBootTiming["phase"] | "runtime_mount_wasm" | "runtime_mount_node" | "bindings";
|
|
26
27
|
export interface NodeRuntimeBootTiming {
|
|
@@ -50,10 +51,18 @@ export declare function resolveNodeRuntimeCommandsDir(explicit?: string): string
|
|
|
50
51
|
* `crates/vm-config/src/lib.rs::CreateVmConfig`.
|
|
51
52
|
*/
|
|
52
53
|
export interface NodeRuntimeCreateOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Caller-owned filesystem used only by this low-level compatibility runtime.
|
|
56
|
+
* AgentOS clients do not create a TypeScript filesystem implicitly; normal
|
|
57
|
+
* product code should use the sidecar-owned VFS through `AgentOs`.
|
|
58
|
+
*/
|
|
59
|
+
filesystem: VirtualFileSystem;
|
|
53
60
|
/** Environment variables visible to guest processes. */
|
|
54
61
|
env?: Record<string, string>;
|
|
55
62
|
/** Initial working directory for guest processes. Defaults to `/workspace`. */
|
|
56
63
|
cwd?: string;
|
|
64
|
+
/** Initial virtual Linux credentials and account record. Defaults to `1000:1000` (`agentos`). */
|
|
65
|
+
user?: VmUserConfig;
|
|
57
66
|
/**
|
|
58
67
|
* Permission policy for the VM. Merged over a secure default that **denies
|
|
59
68
|
* network access** (guest code cannot reach the network until you opt in);
|
|
@@ -440,7 +449,7 @@ export declare class NodeRuntime {
|
|
|
440
449
|
* session, creates the VM with a bootstrapped root filesystem, mounts the
|
|
441
450
|
* shell and Node runtimes, and waits for the VM to report ready.
|
|
442
451
|
*/
|
|
443
|
-
static create(options
|
|
452
|
+
static create(options: NodeRuntimeCreateOptions): Promise<NodeRuntime>;
|
|
444
453
|
createResidentRunner(_options?: NodeRuntimeResidentRunnerOptions): Promise<NodeRuntimeResidentRunner>;
|
|
445
454
|
/**
|
|
446
455
|
* Run `code` as a guest Node program and capture its output.
|
package/dist/node-runtime.js
CHANGED
|
@@ -20,18 +20,18 @@
|
|
|
20
20
|
import { existsSync } from "node:fs";
|
|
21
21
|
import path from "node:path";
|
|
22
22
|
import { fileURLToPath } from "node:url";
|
|
23
|
-
import {
|
|
23
|
+
import { createKernel, createNodeRuntime, createWasmVmRuntime, NodeFileSystem, } from "./test-runtime.js";
|
|
24
24
|
import { parseNodeRuntimeCreateOptions } from "./node-runtime-options-schema.js";
|
|
25
25
|
export { resolveNodeRuntimeSidecarBinary } from "./test-runtime.js";
|
|
26
26
|
/** Repository root, used to locate the in-repo WASM command build output. */
|
|
27
27
|
const REPO_ROOT = fileURLToPath(new URL("../../..", import.meta.url));
|
|
28
28
|
/**
|
|
29
29
|
* In-repo build output for the WASM coreutils/shell command binaries, produced
|
|
30
|
-
* by the Rust command build (`make -C
|
|
30
|
+
* by the Rust command build (`make -C toolchain wasm`). Only present in a
|
|
31
31
|
* developer checkout; preferred when it exists so local edits are picked up
|
|
32
32
|
* without re-vendoring.
|
|
33
33
|
*/
|
|
34
|
-
const REPO_COMMANDS_DIR = path.join(REPO_ROOT, "
|
|
34
|
+
const REPO_COMMANDS_DIR = path.join(REPO_ROOT, "toolchain/target/wasm32-wasip1/release/commands");
|
|
35
35
|
/**
|
|
36
36
|
* Commands vendored into the published `@rivet-dev/agentos-runtime-core` package by
|
|
37
37
|
* `scripts/copy-wasm-commands.mjs` (listed in `files` as `commands`). This is
|
|
@@ -128,14 +128,14 @@ export class NodeRuntime {
|
|
|
128
128
|
* session, creates the VM with a bootstrapped root filesystem, mounts the
|
|
129
129
|
* shell and Node runtimes, and waits for the VM to report ready.
|
|
130
130
|
*/
|
|
131
|
-
static async create(options
|
|
131
|
+
static async create(options) {
|
|
132
132
|
options = parseNodeRuntimeCreateOptions(options);
|
|
133
133
|
const commandsDir = resolveNodeRuntimeCommandsDir(options.commandsDir);
|
|
134
134
|
// Seed caller-provided files into the VM's in-memory filesystem before
|
|
135
135
|
// boot so they are part of the root filesystem snapshot the guest sees
|
|
136
136
|
// (e.g. projected npm packages or fixtures). The host filesystem is
|
|
137
137
|
// never exposed; only these bytes are copied in.
|
|
138
|
-
const filesystem =
|
|
138
|
+
const filesystem = options.filesystem;
|
|
139
139
|
if (options.files) {
|
|
140
140
|
for (const [filePath, content] of Object.entries(options.files)) {
|
|
141
141
|
await filesystem.writeFile(filePath, content);
|
|
@@ -183,6 +183,7 @@ export class NodeRuntime {
|
|
|
183
183
|
},
|
|
184
184
|
env: options.env,
|
|
185
185
|
cwd: options.cwd,
|
|
186
|
+
user: options.user,
|
|
186
187
|
sidecar: options.sidecar,
|
|
187
188
|
onBootTiming: (timing) => options.onBootTiming?.(timing),
|
|
188
189
|
loopbackExemptPorts: options.loopbackExemptPorts,
|
|
@@ -202,7 +203,7 @@ export class NodeRuntime {
|
|
|
202
203
|
// installed as guest commands the moment the VM is ready.
|
|
203
204
|
const bindings = options.bindings;
|
|
204
205
|
if (bindings && Object.keys(bindings).length > 0) {
|
|
205
|
-
await measureBootTiming("bindings", options.onBootTiming, () => kernel.
|
|
206
|
+
await measureBootTiming("bindings", options.onBootTiming, () => kernel.registerBindings(bindings));
|
|
206
207
|
}
|
|
207
208
|
}
|
|
208
209
|
catch (error) {
|
|
@@ -588,7 +589,7 @@ export class NodeRuntime {
|
|
|
588
589
|
* {@link NodeRuntime.create}) so the bindings are invocable.
|
|
589
590
|
*/
|
|
590
591
|
async registerBindings(bindings) {
|
|
591
|
-
await this.kernel.
|
|
592
|
+
await this.kernel.registerBindings(bindings);
|
|
592
593
|
}
|
|
593
594
|
/**
|
|
594
595
|
* Write a file into the VM's virtual filesystem, creating parent
|
package/dist/process.d.ts
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import { type ChildProcessWithoutNullStreams } from "node:child_process";
|
|
2
|
+
import type { Duplex } from "node:stream";
|
|
2
3
|
export { SidecarProcessError, SidecarProcessExited, } from "./sidecar-errors.js";
|
|
3
4
|
import { SidecarProcessError, SidecarProcessExited } from "./sidecar-errors.js";
|
|
4
5
|
export interface StdioSidecarProcessSpawnOptions {
|
|
5
6
|
command: string;
|
|
6
7
|
args?: string[];
|
|
7
8
|
cwd?: string;
|
|
9
|
+
combinedStdio?: boolean;
|
|
8
10
|
}
|
|
9
11
|
export declare class StdioSidecarProcess {
|
|
10
12
|
readonly child: ChildProcessWithoutNullStreams;
|
|
13
|
+
readonly control: Duplex | null;
|
|
14
|
+
readonly combinedStdio: boolean;
|
|
11
15
|
private readonly stderrChunks;
|
|
12
16
|
private readonly exitListeners;
|
|
13
17
|
private readonly errorListeners;
|
|
14
18
|
private constructor();
|
|
15
19
|
static spawn(options: StdioSidecarProcessSpawnOptions): StdioSidecarProcess;
|
|
16
|
-
static fromChild(child: ChildProcessWithoutNullStreams): StdioSidecarProcess;
|
|
20
|
+
static fromChild(child: ChildProcessWithoutNullStreams, control?: Duplex | null): StdioSidecarProcess;
|
|
17
21
|
onExit(handler: (error: SidecarProcessExited) => void): () => void;
|
|
18
22
|
onError(handler: (error: SidecarProcessError) => void): () => void;
|
|
19
23
|
stderrText(): string;
|
package/dist/process.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { spawn
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
2
|
export { SidecarProcessError, SidecarProcessExited, } from "./sidecar-errors.js";
|
|
3
|
-
import { SidecarProcessError, SidecarProcessExited
|
|
3
|
+
import { SidecarProcessError, SidecarProcessExited } from "./sidecar-errors.js";
|
|
4
4
|
export class StdioSidecarProcess {
|
|
5
5
|
child;
|
|
6
|
+
control;
|
|
7
|
+
combinedStdio;
|
|
6
8
|
stderrChunks = [];
|
|
7
9
|
exitListeners = new Set();
|
|
8
10
|
errorListeners = new Set();
|
|
9
|
-
constructor(child) {
|
|
11
|
+
constructor(child, control) {
|
|
10
12
|
this.child = child;
|
|
13
|
+
this.control = control;
|
|
14
|
+
this.combinedStdio = control === null;
|
|
11
15
|
this.child.stderr.on("data", (chunk) => {
|
|
12
16
|
this.stderrChunks.push(typeof chunk === "string" ? Buffer.from(chunk) : Buffer.from(chunk));
|
|
13
17
|
});
|
|
@@ -30,13 +34,26 @@ export class StdioSidecarProcess {
|
|
|
30
34
|
});
|
|
31
35
|
}
|
|
32
36
|
static spawn(options) {
|
|
33
|
-
|
|
37
|
+
const combinedStdio = options.combinedStdio === true;
|
|
38
|
+
const child = spawn(options.command, options.args ?? [], {
|
|
34
39
|
cwd: options.cwd,
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
env: combinedStdio
|
|
41
|
+
? { ...process.env, AGENTOS_SIDECAR_COMBINED_STDIO: "1" }
|
|
42
|
+
: process.env,
|
|
43
|
+
stdio: combinedStdio
|
|
44
|
+
? ["pipe", "pipe", "pipe"]
|
|
45
|
+
: ["pipe", "pipe", "pipe", "pipe"],
|
|
46
|
+
});
|
|
47
|
+
try {
|
|
48
|
+
return new StdioSidecarProcess(child, combinedStdio ? null : requireControlStream(child));
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
child.kill("SIGKILL");
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
37
54
|
}
|
|
38
|
-
static fromChild(child) {
|
|
39
|
-
return new StdioSidecarProcess(child);
|
|
55
|
+
static fromChild(child, control) {
|
|
56
|
+
return new StdioSidecarProcess(child, control === null ? null : (control ?? requireControlStream(child)));
|
|
40
57
|
}
|
|
41
58
|
onExit(handler) {
|
|
42
59
|
this.exitListeners.add(handler);
|
|
@@ -95,3 +112,13 @@ export class StdioSidecarProcess {
|
|
|
95
112
|
});
|
|
96
113
|
}
|
|
97
114
|
}
|
|
115
|
+
function requireControlStream(child) {
|
|
116
|
+
const stream = child.stdio[3];
|
|
117
|
+
if (!stream ||
|
|
118
|
+
typeof stream.write !== "function" ||
|
|
119
|
+
typeof stream.on !== "function" ||
|
|
120
|
+
typeof stream.read !== "function") {
|
|
121
|
+
throw new Error("sidecar process did not expose a full-duplex fd 3");
|
|
122
|
+
}
|
|
123
|
+
return stream;
|
|
124
|
+
}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import type { Readable, Writable } from "node:stream";
|
|
2
2
|
import { type LiveSidecarEventSelector } from "./event-buffer.js";
|
|
3
|
-
import type
|
|
4
|
-
import { type LiveEventFrame, type LiveProtocolFrame, type LiveResponseFrame, type LiveSidecarRequestFrame, type LiveSidecarRequestHandler, type ProtocolFramePayloadCodec } from "./protocol-frames.js";
|
|
3
|
+
import { type FrameTransport } from "./frame-stream.js";
|
|
5
4
|
import type { LiveOwnershipScope } from "./ownership.js";
|
|
5
|
+
import { type LiveControlFrame, type LiveEventFrame, type LiveProtocolFrame, type LiveRequestFrame, type LiveResponseFrame, type LiveSidecarRequestFrame, type LiveSidecarRequestHandler, type LiveSidecarResponseFrame, type ProtocolFramePayloadCodec } from "./protocol-frames.js";
|
|
6
6
|
import type { LiveRequestPayload } from "./request-payloads.js";
|
|
7
7
|
export interface SidecarProtocolClientOptions {
|
|
8
|
+
/** A combined transport remains supported for embedders and focused tests. */
|
|
8
9
|
frameTransport?: FrameTransport<LiveResponseFrame | LiveEventFrame | LiveSidecarRequestFrame, LiveProtocolFrame>;
|
|
10
|
+
ordinaryFrameTransport?: FrameTransport<LiveEventFrame, LiveRequestFrame>;
|
|
11
|
+
controlFrameTransport?: FrameTransport<LiveResponseFrame | LiveSidecarRequestFrame | LiveEventFrame, LiveSidecarResponseFrame | LiveControlFrame>;
|
|
9
12
|
stdin?: Writable;
|
|
10
13
|
stdout?: Readable;
|
|
14
|
+
control?: Readable & Writable;
|
|
15
|
+
/** Use one bidirectional stdin/stdout transport when the host cannot inherit fd 3. */
|
|
16
|
+
combinedStdio?: boolean;
|
|
11
17
|
eventBufferCapacity: number;
|
|
12
18
|
payloadCodec?: ProtocolFramePayloadCodec;
|
|
13
19
|
stderrText?: () => string;
|
|
@@ -50,6 +56,7 @@ export declare class SidecarProtocolClient {
|
|
|
50
56
|
ownership: LiveOwnershipScope;
|
|
51
57
|
payload: LiveRequestPayload;
|
|
52
58
|
}): Promise<LiveResponseFrame>;
|
|
59
|
+
shutdown(reason: string): Promise<void>;
|
|
53
60
|
waitForEvent(matcher: LiveSidecarEventSelector | ((event: LiveEventFrame) => boolean), timeoutMs?: number, options?: {
|
|
54
61
|
signal?: AbortSignal;
|
|
55
62
|
}): Promise<LiveEventFrame>;
|
package/dist/protocol-client.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { SidecarEventBuffer, SidecarEventBufferOverflow,
|
|
1
|
+
import { normalizeSidecarEventMatcher, SidecarEventBuffer, SidecarEventBufferOverflow, sidecarEventWaitAbortError, } from "./event-buffer.js";
|
|
2
2
|
import { FrameRpcTransport } from "./frame-rpc.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { SplitLaneFrameTransport, StdioFrameTransport, } from "./frame-stream.js";
|
|
4
|
+
import { classifySidecarWrittenProtocolFrame, decodeProtocolFramePayload, encodeProtocolFramePayload, HostProtocolFrameFactory, resolveSidecarRequestFramePayload, } from "./protocol-frames.js";
|
|
5
|
+
import { SidecarRejectedError, SidecarSilenceTimeout, } from "./sidecar-errors.js";
|
|
5
6
|
/**
|
|
6
7
|
* How long the host tolerates TOTAL inbound silence (no responses, events,
|
|
7
8
|
* sidecar requests, or heartbeats) before declaring the sidecar dead. The
|
|
@@ -30,9 +31,7 @@ export class SidecarProtocolClient {
|
|
|
30
31
|
this.payloadCodec = options.payloadCodec ?? "bare";
|
|
31
32
|
this.stderrText = options.stderrText ?? (() => "");
|
|
32
33
|
this.frameTransport = new FrameRpcTransport({
|
|
33
|
-
frameTransport: options.
|
|
34
|
-
stdin: options.stdin,
|
|
35
|
-
stdout: options.stdout,
|
|
34
|
+
frameTransport: resolveProtocolFrameTransport(options, this.payloadCodec),
|
|
36
35
|
encodeFrame: (frame) => encodeProtocolFramePayload(frame, this.payloadCodec),
|
|
37
36
|
decodeFrame: (payload) => decodeProtocolFramePayload(payload, this.payloadCodec),
|
|
38
37
|
classifyFrame: classifySidecarWrittenProtocolFrame,
|
|
@@ -109,10 +108,16 @@ export class SidecarProtocolClient {
|
|
|
109
108
|
// wedged sidecar rejects this via the silence watchdog instead.
|
|
110
109
|
const response = await this.frameTransport.sendFrame(request.request_id, request);
|
|
111
110
|
if (response.payload.type === "rejected") {
|
|
112
|
-
throw new
|
|
111
|
+
throw new SidecarRejectedError(request.request_id, response.payload);
|
|
113
112
|
}
|
|
114
113
|
return response;
|
|
115
114
|
}
|
|
115
|
+
async shutdown(reason) {
|
|
116
|
+
if (this.closedError) {
|
|
117
|
+
throw this.closedError;
|
|
118
|
+
}
|
|
119
|
+
await this.frameTransport.writeFrame(this.hostFrameFactory.createControlFrame({ type: "shutdown", reason }));
|
|
120
|
+
}
|
|
116
121
|
async waitForEvent(matcher, timeoutMs, options) {
|
|
117
122
|
if (this.closedError instanceof SidecarEventBufferOverflow) {
|
|
118
123
|
throw this.closedError;
|
|
@@ -188,6 +193,20 @@ export class SidecarProtocolClient {
|
|
|
188
193
|
await this.frameTransport.writeFrame(frame);
|
|
189
194
|
}
|
|
190
195
|
async dispatchSidecarRequest(request) {
|
|
196
|
+
// A callback can arrive immediately before the response that acknowledges
|
|
197
|
+
// the command which created it. Let the inbound decoder finish that turn
|
|
198
|
+
// before writing a callback response; otherwise a very fast host callback
|
|
199
|
+
// can complete and reap the guest process while its execute request is
|
|
200
|
+
// still being admitted, leaving the host waiting for an exit it missed.
|
|
201
|
+
await new Promise((resolve) => {
|
|
202
|
+
const scheduleImmediate = globalThis.setImmediate;
|
|
203
|
+
if (scheduleImmediate) {
|
|
204
|
+
scheduleImmediate(resolve);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
setTimeout(resolve, 0);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
191
210
|
const payload = await resolveSidecarRequestFramePayload(request, this.sidecarRequestHandler);
|
|
192
211
|
try {
|
|
193
212
|
await this.writeFrame(this.hostFrameFactory.createSidecarResponseFrame({
|
|
@@ -240,3 +259,104 @@ export class SidecarProtocolClient {
|
|
|
240
259
|
this.eventWaiters.clear();
|
|
241
260
|
}
|
|
242
261
|
}
|
|
262
|
+
function resolveProtocolFrameTransport(options, payloadCodec) {
|
|
263
|
+
const hasSplitTransport = options.ordinaryFrameTransport !== undefined ||
|
|
264
|
+
options.controlFrameTransport !== undefined;
|
|
265
|
+
const hasStdio = options.stdin !== undefined ||
|
|
266
|
+
options.stdout !== undefined ||
|
|
267
|
+
options.control !== undefined;
|
|
268
|
+
if (options.combinedStdio) {
|
|
269
|
+
if (options.frameTransport ||
|
|
270
|
+
hasSplitTransport ||
|
|
271
|
+
options.control !== undefined ||
|
|
272
|
+
!options.stdin ||
|
|
273
|
+
!options.stdout) {
|
|
274
|
+
throw new Error("SidecarProtocolClient combinedStdio requires only stdin and stdout streams");
|
|
275
|
+
}
|
|
276
|
+
return new StdioFrameTransport({
|
|
277
|
+
stdin: options.stdin,
|
|
278
|
+
stdout: options.stdout,
|
|
279
|
+
encodeFrame: (frame) => encodeProtocolFramePayload(frame, payloadCodec),
|
|
280
|
+
decodeFrame: (payload) => decodeProtocolFramePayload(payload, payloadCodec),
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
if (options.frameTransport) {
|
|
284
|
+
if (hasSplitTransport || hasStdio) {
|
|
285
|
+
throw new Error("SidecarProtocolClient frameTransport cannot be combined with split-lane transports or streams");
|
|
286
|
+
}
|
|
287
|
+
return options.frameTransport;
|
|
288
|
+
}
|
|
289
|
+
let ordinary = options.ordinaryFrameTransport;
|
|
290
|
+
let control = options.controlFrameTransport;
|
|
291
|
+
if (hasSplitTransport) {
|
|
292
|
+
if (!ordinary || !control || hasStdio) {
|
|
293
|
+
throw new Error("SidecarProtocolClient requires both ordinaryFrameTransport and controlFrameTransport, without stdio streams");
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
if (!options.stdin || !options.stdout || !options.control) {
|
|
298
|
+
throw new Error("SidecarProtocolClient requires a combined frameTransport or stdin/stdout/control streams");
|
|
299
|
+
}
|
|
300
|
+
ordinary = new StdioFrameTransport({
|
|
301
|
+
stdin: options.stdin,
|
|
302
|
+
stdout: options.stdout,
|
|
303
|
+
encodeFrame: (frame) => encodeProtocolFramePayload(frame, payloadCodec),
|
|
304
|
+
decodeFrame: (payload) => {
|
|
305
|
+
const frame = decodeProtocolFramePayload(payload, payloadCodec);
|
|
306
|
+
validateOrdinaryInboundFrame(frame);
|
|
307
|
+
return frame;
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
control = new StdioFrameTransport({
|
|
311
|
+
stdin: options.control,
|
|
312
|
+
stdout: options.control,
|
|
313
|
+
encodeFrame: (frame) => encodeProtocolFramePayload(frame, payloadCodec),
|
|
314
|
+
decodeFrame: (payload) => {
|
|
315
|
+
const frame = decodeProtocolFramePayload(payload, payloadCodec);
|
|
316
|
+
validateControlInboundFrame(frame);
|
|
317
|
+
return frame;
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
return new SplitLaneFrameTransport({
|
|
322
|
+
ordinary,
|
|
323
|
+
control,
|
|
324
|
+
validateOrdinaryFrame: validateOrdinaryInboundFrame,
|
|
325
|
+
validateControlFrame: validateControlInboundFrame,
|
|
326
|
+
selectWriteLane: (frame) => {
|
|
327
|
+
switch (frame.frame_type) {
|
|
328
|
+
case "request":
|
|
329
|
+
return "ordinary";
|
|
330
|
+
case "sidecar_response":
|
|
331
|
+
case "control":
|
|
332
|
+
return "control";
|
|
333
|
+
default: {
|
|
334
|
+
const invalidFrame = frame;
|
|
335
|
+
throw new Error(`host frame ${invalidFrame.frame_type} is not valid on either writable protocol lane`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
function validateOrdinaryInboundFrame(frame) {
|
|
342
|
+
if (frame.frame_type !== "event") {
|
|
343
|
+
throw new Error(`sidecar frame ${frame.frame_type} is not valid on the ordinary protocol lane`);
|
|
344
|
+
}
|
|
345
|
+
if (isHeartbeatFrame(frame)) {
|
|
346
|
+
throw new Error("sidecar heartbeat event is not valid on the ordinary protocol lane");
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function validateControlInboundFrame(frame) {
|
|
350
|
+
if (frame.frame_type === "response" ||
|
|
351
|
+
frame.frame_type === "sidecar_request") {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (frame.frame_type === "event" &&
|
|
355
|
+
isHeartbeatFrame(frame)) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
throw new Error(`sidecar frame ${frame.frame_type} is not valid on the control protocol lane`);
|
|
359
|
+
}
|
|
360
|
+
function isHeartbeatFrame(frame) {
|
|
361
|
+
return (frame.payload.type === "structured" && frame.payload.name === "heartbeat");
|
|
362
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type TransportPayloadCodec } from "./frame-payload-codec.js";
|
|
2
|
-
import type { ClassifiedFrame } from "./frame-rpc.js";
|
|
3
1
|
import { type LiveSidecarRequestPayload, type LiveSidecarResponsePayload } from "./callbacks.js";
|
|
4
2
|
import { type LiveSidecarEventPayload } from "./event-buffer.js";
|
|
3
|
+
import { type TransportPayloadCodec } from "./frame-payload-codec.js";
|
|
4
|
+
import type { ClassifiedFrame } from "./frame-rpc.js";
|
|
5
5
|
import * as protocol from "./generated-protocol.js";
|
|
6
6
|
import { type LiveOwnershipScope } from "./ownership.js";
|
|
7
7
|
import { SIDECAR_PROTOCOL_SCHEMA } from "./protocol-schema.js";
|
|
@@ -41,7 +41,16 @@ export interface LiveSidecarResponseFrame {
|
|
|
41
41
|
ownership: LiveOwnershipScope;
|
|
42
42
|
payload: LiveSidecarResponsePayload;
|
|
43
43
|
}
|
|
44
|
-
export type
|
|
44
|
+
export type LiveControlPayload = {
|
|
45
|
+
type: "shutdown";
|
|
46
|
+
reason: string;
|
|
47
|
+
};
|
|
48
|
+
export interface LiveControlFrame {
|
|
49
|
+
frame_type: "control";
|
|
50
|
+
schema: typeof SIDECAR_PROTOCOL_SCHEMA;
|
|
51
|
+
payload: LiveControlPayload;
|
|
52
|
+
}
|
|
53
|
+
export type LiveProtocolFrame = LiveRequestFrame | LiveResponseFrame | LiveEventFrame | LiveSidecarRequestFrame | LiveSidecarResponseFrame | LiveControlFrame;
|
|
45
54
|
export type LiveSidecarWrittenProtocolFrame = LiveResponseFrame | LiveEventFrame | LiveSidecarRequestFrame;
|
|
46
55
|
export type ProtocolFramePayloadCodec = TransportPayloadCodec;
|
|
47
56
|
export type ClassifiedSidecarWrittenProtocolFrame = ClassifiedFrame<LiveResponseFrame, LiveEventFrame, LiveSidecarRequestFrame>;
|
|
@@ -56,6 +65,7 @@ export declare class HostProtocolFrameFactory {
|
|
|
56
65
|
request: LiveSidecarRequestFrame;
|
|
57
66
|
payload: LiveSidecarResponsePayload;
|
|
58
67
|
}): LiveSidecarResponseFrame;
|
|
68
|
+
createControlFrame(payload: LiveControlPayload): LiveControlFrame;
|
|
59
69
|
}
|
|
60
70
|
export declare function resolveSidecarRequestFramePayload(request: LiveSidecarRequestFrame, handler: LiveSidecarRequestHandler | null): Promise<LiveSidecarResponsePayload>;
|
|
61
71
|
export declare function toGeneratedProtocolFrame(frame: LiveProtocolFrame): protocol.ProtocolFrame;
|
|
@@ -65,4 +75,5 @@ export declare function encodeProtocolFramePayload(frame: LiveProtocolFrame, cod
|
|
|
65
75
|
export declare function decodeProtocolFramePayload(payload: Uint8Array, codec: ProtocolFramePayloadCodec): LiveSidecarWrittenProtocolFrame;
|
|
66
76
|
export declare function classifySidecarWrittenProtocolFrame(frame: LiveSidecarWrittenProtocolFrame): ClassifiedSidecarWrittenProtocolFrame;
|
|
67
77
|
export declare function fromGeneratedSidecarWrittenProtocolFrame(frame: protocol.ProtocolFrame): LiveSidecarWrittenProtocolFrame;
|
|
78
|
+
export declare function toGeneratedControlPayload(payload: LiveControlPayload): protocol.ControlPayload;
|
|
68
79
|
export declare function toLiveProtocolSchema(schema: protocol.ProtocolSchema): typeof SIDECAR_PROTOCOL_SCHEMA;
|
package/dist/protocol-frames.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { toExactUint8Array } from "./bytes.js";
|
|
2
|
-
import { decodeJsonFramePayload, encodeJsonFramePayload, } from "./frame-payload-codec.js";
|
|
3
2
|
import { errorSidecarResponsePayload, fromGeneratedSidecarRequestPayload, isMatchingSidecarResponsePayload, toGeneratedSidecarResponsePayload, } from "./callbacks.js";
|
|
4
3
|
import { fromGeneratedEventPayload, } from "./event-buffer.js";
|
|
4
|
+
import { decodeJsonFramePayload, encodeJsonFramePayload, } from "./frame-payload-codec.js";
|
|
5
5
|
import * as protocol from "./generated-protocol.js";
|
|
6
6
|
import { bigIntToSafeNumber } from "./numbers.js";
|
|
7
7
|
import { fromGeneratedOwnershipScope, toGeneratedOwnershipScope, } from "./ownership.js";
|
|
@@ -28,6 +28,13 @@ export class HostProtocolFrameFactory {
|
|
|
28
28
|
payload: input.payload,
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
+
createControlFrame(payload) {
|
|
32
|
+
return {
|
|
33
|
+
frame_type: "control",
|
|
34
|
+
schema: SIDECAR_PROTOCOL_SCHEMA,
|
|
35
|
+
payload,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
31
38
|
}
|
|
32
39
|
export async function resolveSidecarRequestFramePayload(request, handler) {
|
|
33
40
|
try {
|
|
@@ -66,6 +73,14 @@ export function toGeneratedProtocolFrame(frame) {
|
|
|
66
73
|
payload: toGeneratedSidecarResponsePayload(frame.payload),
|
|
67
74
|
},
|
|
68
75
|
};
|
|
76
|
+
case "control":
|
|
77
|
+
return {
|
|
78
|
+
tag: "ControlFrame",
|
|
79
|
+
val: {
|
|
80
|
+
schema: frame.schema,
|
|
81
|
+
payload: toGeneratedControlPayload(frame.payload),
|
|
82
|
+
},
|
|
83
|
+
};
|
|
69
84
|
case "response":
|
|
70
85
|
case "event":
|
|
71
86
|
case "sidecar_request":
|
|
@@ -131,9 +146,19 @@ export function fromGeneratedSidecarWrittenProtocolFrame(frame) {
|
|
|
131
146
|
};
|
|
132
147
|
case "RequestFrame":
|
|
133
148
|
case "SidecarResponseFrame":
|
|
149
|
+
case "ControlFrame":
|
|
134
150
|
throw new Error(`unsupported BARE protocol frame tag: ${frame.tag}`);
|
|
135
151
|
}
|
|
136
152
|
}
|
|
153
|
+
export function toGeneratedControlPayload(payload) {
|
|
154
|
+
switch (payload.type) {
|
|
155
|
+
case "shutdown":
|
|
156
|
+
return {
|
|
157
|
+
tag: "ShutdownControl",
|
|
158
|
+
val: { reason: payload.reason },
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
137
162
|
export function toLiveProtocolSchema(schema) {
|
|
138
163
|
return validateSidecarProtocolSchema(schema);
|
|
139
164
|
}
|