@rivet-dev/agentos-runtime-core 0.0.0-codex-actor-plugin-contract-coverage.115ca8a → 0.0.0-fix-main-wasm-ownership.150c49a
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/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/correlation.d.ts +1 -4
- package/dist/correlation.js +7 -10
- package/dist/descriptors.d.ts +2 -12
- package/dist/descriptors.js +10 -6
- package/dist/frame-rpc.d.ts +9 -4
- package/dist/frame-rpc.js +19 -2
- 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 +11 -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 +5 -1
- package/dist/kernel-proxy.js +77 -39
- package/dist/native-client.d.ts +9 -5
- package/dist/native-client.js +41 -9
- 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 +3 -1
- package/dist/process.js +27 -8
- package/dist/protocol-client.d.ts +26 -4
- package/dist/protocol-client.js +164 -12
- 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 +23 -2
- package/dist/response-payloads.js +34 -2
- package/dist/sidecar-errors.d.ts +37 -0
- package/dist/sidecar-errors.js +27 -0
- package/dist/sidecar-process.d.ts +20 -6
- package/dist/sidecar-process.js +79 -15
- package/dist/state.d.ts +6 -6
- package/dist/state.js +10 -11
- package/dist/test-runtime.d.ts +21 -6
- package/dist/test-runtime.js +129 -65
- package/dist/vm-config.d.ts +5 -1
- package/package.json +5 -3
- 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
|
@@ -1,24 +1,36 @@
|
|
|
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;
|
|
11
|
-
|
|
14
|
+
control?: Readable & Writable;
|
|
12
15
|
eventBufferCapacity: number;
|
|
13
16
|
payloadCodec?: ProtocolFramePayloadCodec;
|
|
14
17
|
stderrText?: () => string;
|
|
15
18
|
frameError?: (error: Error) => Error;
|
|
16
19
|
streamEndedError?: () => Error;
|
|
20
|
+
/** Override the silence watchdog window. Tests only; production uses the default. */
|
|
21
|
+
silenceTimeoutMs?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Runs when the silence watchdog fires, before pending work is rejected.
|
|
24
|
+
* The stdio layer uses it to SIGKILL the sidecar child.
|
|
25
|
+
*/
|
|
26
|
+
onSilenceExpired?: () => void;
|
|
17
27
|
}
|
|
18
28
|
export declare class SidecarProtocolClient {
|
|
19
29
|
private readonly eventBuffer;
|
|
20
30
|
private readonly eventListeners;
|
|
21
|
-
private readonly
|
|
31
|
+
private readonly silenceTimeoutMs;
|
|
32
|
+
private silenceTimer;
|
|
33
|
+
private lastInboundAtMs;
|
|
22
34
|
private readonly payloadCodec;
|
|
23
35
|
private readonly stderrText;
|
|
24
36
|
private readonly hostFrameFactory;
|
|
@@ -27,12 +39,22 @@ export declare class SidecarProtocolClient {
|
|
|
27
39
|
private readonly eventWaiters;
|
|
28
40
|
private sidecarRequestHandler;
|
|
29
41
|
constructor(options: SidecarProtocolClientOptions);
|
|
42
|
+
/**
|
|
43
|
+
* Arm the silence watchdog: ANY inbound frame resets the clock (see the
|
|
44
|
+
* `onFrameActivity` tap above), and the sidecar heartbeats every 10s even
|
|
45
|
+
* while busy, so sustained silence for the full window means the process
|
|
46
|
+
* is dead or wedged — not slow. The check interval is unref'd so an idle
|
|
47
|
+
* host process can still exit naturally.
|
|
48
|
+
*/
|
|
49
|
+
private startSilenceWatchdog;
|
|
50
|
+
private stopSilenceWatchdog;
|
|
30
51
|
setSidecarRequestHandler(handler: LiveSidecarRequestHandler | null): void;
|
|
31
52
|
onEvent(handler: (event: LiveEventFrame) => void): () => void;
|
|
32
53
|
sendRequest(input: {
|
|
33
54
|
ownership: LiveOwnershipScope;
|
|
34
55
|
payload: LiveRequestPayload;
|
|
35
56
|
}): Promise<LiveResponseFrame>;
|
|
57
|
+
shutdown(reason: string): Promise<void>;
|
|
36
58
|
waitForEvent(matcher: LiveSidecarEventSelector | ((event: LiveEventFrame) => boolean), timeoutMs?: number, options?: {
|
|
37
59
|
signal?: AbortSignal;
|
|
38
60
|
}): Promise<LiveEventFrame>;
|
package/dist/protocol-client.js
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
import { SidecarEventBuffer, SidecarEventBufferOverflow,
|
|
1
|
+
import { normalizeSidecarEventMatcher, SidecarEventBuffer, SidecarEventBufferOverflow, sidecarEventWaitAbortError, } from "./event-buffer.js";
|
|
2
2
|
import { FrameRpcTransport } from "./frame-rpc.js";
|
|
3
|
-
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";
|
|
6
|
+
/**
|
|
7
|
+
* How long the host tolerates TOTAL inbound silence (no responses, events,
|
|
8
|
+
* sidecar requests, or heartbeats) before declaring the sidecar dead. The
|
|
9
|
+
* sidecar heartbeats every 10s from a dedicated thread, so this allows two
|
|
10
|
+
* missed beats plus margin; it bounds "sidecar is dead or wedged", never "this
|
|
11
|
+
* request is slow" — individual requests have no deadline of their own.
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_SIDECAR_SILENCE_TIMEOUT_MS = 30_000;
|
|
4
14
|
export class SidecarProtocolClient {
|
|
5
15
|
eventBuffer;
|
|
6
16
|
eventListeners = new Set();
|
|
7
|
-
|
|
17
|
+
silenceTimeoutMs;
|
|
18
|
+
silenceTimer = null;
|
|
19
|
+
lastInboundAtMs = 0;
|
|
8
20
|
payloadCodec;
|
|
9
21
|
stderrText;
|
|
10
22
|
hostFrameFactory = new HostProtocolFrameFactory();
|
|
@@ -13,14 +25,13 @@ export class SidecarProtocolClient {
|
|
|
13
25
|
eventWaiters = new Set();
|
|
14
26
|
sidecarRequestHandler = null;
|
|
15
27
|
constructor(options) {
|
|
16
|
-
this.
|
|
28
|
+
this.silenceTimeoutMs =
|
|
29
|
+
options.silenceTimeoutMs ?? DEFAULT_SIDECAR_SILENCE_TIMEOUT_MS;
|
|
17
30
|
this.eventBuffer = new SidecarEventBuffer(options.eventBufferCapacity);
|
|
18
31
|
this.payloadCodec = options.payloadCodec ?? "bare";
|
|
19
32
|
this.stderrText = options.stderrText ?? (() => "");
|
|
20
33
|
this.frameTransport = new FrameRpcTransport({
|
|
21
|
-
frameTransport: options.
|
|
22
|
-
stdin: options.stdin,
|
|
23
|
-
stdout: options.stdout,
|
|
34
|
+
frameTransport: resolveProtocolFrameTransport(options, this.payloadCodec),
|
|
24
35
|
encodeFrame: (frame) => encodeProtocolFramePayload(frame, this.payloadCodec),
|
|
25
36
|
decodeFrame: (payload) => decodeProtocolFramePayload(payload, this.payloadCodec),
|
|
26
37
|
classifyFrame: classifySidecarWrittenProtocolFrame,
|
|
@@ -38,6 +49,45 @@ export class SidecarProtocolClient {
|
|
|
38
49
|
this.failPermanently(options.streamEndedError?.() ??
|
|
39
50
|
new Error("sidecar protocol stream ended"));
|
|
40
51
|
});
|
|
52
|
+
this.frameTransport.onFrameActivity(() => {
|
|
53
|
+
this.lastInboundAtMs = performance.now();
|
|
54
|
+
});
|
|
55
|
+
this.startSilenceWatchdog(options.onSilenceExpired);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Arm the silence watchdog: ANY inbound frame resets the clock (see the
|
|
59
|
+
* `onFrameActivity` tap above), and the sidecar heartbeats every 10s even
|
|
60
|
+
* while busy, so sustained silence for the full window means the process
|
|
61
|
+
* is dead or wedged — not slow. The check interval is unref'd so an idle
|
|
62
|
+
* host process can still exit naturally.
|
|
63
|
+
*/
|
|
64
|
+
startSilenceWatchdog(onExpired) {
|
|
65
|
+
this.lastInboundAtMs = performance.now();
|
|
66
|
+
const checkIntervalMs = Math.max(Math.min(this.silenceTimeoutMs / 4, 1_000), 10);
|
|
67
|
+
this.silenceTimer = setInterval(() => {
|
|
68
|
+
const silenceMs = performance.now() - this.lastInboundAtMs;
|
|
69
|
+
if (silenceMs < this.silenceTimeoutMs) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
this.stopSilenceWatchdog();
|
|
73
|
+
const error = new SidecarSilenceTimeout({
|
|
74
|
+
silenceMs,
|
|
75
|
+
stderr: this.stderrText(),
|
|
76
|
+
});
|
|
77
|
+
try {
|
|
78
|
+
onExpired?.();
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
this.failPermanently(error);
|
|
82
|
+
}
|
|
83
|
+
}, checkIntervalMs);
|
|
84
|
+
this.silenceTimer.unref?.();
|
|
85
|
+
}
|
|
86
|
+
stopSilenceWatchdog() {
|
|
87
|
+
if (this.silenceTimer !== null) {
|
|
88
|
+
clearInterval(this.silenceTimer);
|
|
89
|
+
this.silenceTimer = null;
|
|
90
|
+
}
|
|
41
91
|
}
|
|
42
92
|
setSidecarRequestHandler(handler) {
|
|
43
93
|
this.sidecarRequestHandler = handler;
|
|
@@ -53,15 +103,21 @@ export class SidecarProtocolClient {
|
|
|
53
103
|
throw this.closedError;
|
|
54
104
|
}
|
|
55
105
|
const request = this.hostFrameFactory.createRequestFrame(input);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
106
|
+
// No per-request deadline: only the caller knows whether an operation is
|
|
107
|
+
// legitimately long (a whole agent turn is one request). A dead or
|
|
108
|
+
// wedged sidecar rejects this via the silence watchdog instead.
|
|
109
|
+
const response = await this.frameTransport.sendFrame(request.request_id, request);
|
|
60
110
|
if (response.payload.type === "rejected") {
|
|
61
|
-
throw new
|
|
111
|
+
throw new SidecarRejectedError(request.request_id, response.payload);
|
|
62
112
|
}
|
|
63
113
|
return response;
|
|
64
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
|
+
}
|
|
65
121
|
async waitForEvent(matcher, timeoutMs, options) {
|
|
66
122
|
if (this.closedError instanceof SidecarEventBufferOverflow) {
|
|
67
123
|
throw this.closedError;
|
|
@@ -126,9 +182,11 @@ export class SidecarProtocolClient {
|
|
|
126
182
|
}
|
|
127
183
|
}
|
|
128
184
|
this.closedError = error;
|
|
185
|
+
this.stopSilenceWatchdog();
|
|
129
186
|
this.rejectPending(error);
|
|
130
187
|
}
|
|
131
188
|
dispose() {
|
|
189
|
+
this.stopSilenceWatchdog();
|
|
132
190
|
this.frameTransport.dispose();
|
|
133
191
|
}
|
|
134
192
|
async writeFrame(frame) {
|
|
@@ -148,6 +206,14 @@ export class SidecarProtocolClient {
|
|
|
148
206
|
}
|
|
149
207
|
}
|
|
150
208
|
dispatchEvent(event) {
|
|
209
|
+
// Transport-level liveness beats from the sidecar. Their arrival already
|
|
210
|
+
// reset the silence watchdog at the frame layer; they carry no meaning
|
|
211
|
+
// for consumers and must never reach the bounded event buffer, where a
|
|
212
|
+
// long-idle VM would accumulate one every 10s until overflow.
|
|
213
|
+
if (event.payload.type === "structured" &&
|
|
214
|
+
event.payload.name === "heartbeat") {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
151
217
|
for (const listener of this.eventListeners) {
|
|
152
218
|
try {
|
|
153
219
|
listener(event);
|
|
@@ -179,3 +245,89 @@ export class SidecarProtocolClient {
|
|
|
179
245
|
this.eventWaiters.clear();
|
|
180
246
|
}
|
|
181
247
|
}
|
|
248
|
+
function resolveProtocolFrameTransport(options, payloadCodec) {
|
|
249
|
+
const hasSplitTransport = options.ordinaryFrameTransport !== undefined ||
|
|
250
|
+
options.controlFrameTransport !== undefined;
|
|
251
|
+
const hasStdio = options.stdin !== undefined ||
|
|
252
|
+
options.stdout !== undefined ||
|
|
253
|
+
options.control !== undefined;
|
|
254
|
+
if (options.frameTransport) {
|
|
255
|
+
if (hasSplitTransport || hasStdio) {
|
|
256
|
+
throw new Error("SidecarProtocolClient frameTransport cannot be combined with split-lane transports or streams");
|
|
257
|
+
}
|
|
258
|
+
return options.frameTransport;
|
|
259
|
+
}
|
|
260
|
+
let ordinary = options.ordinaryFrameTransport;
|
|
261
|
+
let control = options.controlFrameTransport;
|
|
262
|
+
if (hasSplitTransport) {
|
|
263
|
+
if (!ordinary || !control || hasStdio) {
|
|
264
|
+
throw new Error("SidecarProtocolClient requires both ordinaryFrameTransport and controlFrameTransport, without stdio streams");
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
if (!options.stdin || !options.stdout || !options.control) {
|
|
269
|
+
throw new Error("SidecarProtocolClient requires a combined frameTransport or stdin/stdout/control streams");
|
|
270
|
+
}
|
|
271
|
+
ordinary = new StdioFrameTransport({
|
|
272
|
+
stdin: options.stdin,
|
|
273
|
+
stdout: options.stdout,
|
|
274
|
+
encodeFrame: (frame) => encodeProtocolFramePayload(frame, payloadCodec),
|
|
275
|
+
decodeFrame: (payload) => {
|
|
276
|
+
const frame = decodeProtocolFramePayload(payload, payloadCodec);
|
|
277
|
+
validateOrdinaryInboundFrame(frame);
|
|
278
|
+
return frame;
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
control = new StdioFrameTransport({
|
|
282
|
+
stdin: options.control,
|
|
283
|
+
stdout: options.control,
|
|
284
|
+
encodeFrame: (frame) => encodeProtocolFramePayload(frame, payloadCodec),
|
|
285
|
+
decodeFrame: (payload) => {
|
|
286
|
+
const frame = decodeProtocolFramePayload(payload, payloadCodec);
|
|
287
|
+
validateControlInboundFrame(frame);
|
|
288
|
+
return frame;
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
return new SplitLaneFrameTransport({
|
|
293
|
+
ordinary,
|
|
294
|
+
control,
|
|
295
|
+
validateOrdinaryFrame: validateOrdinaryInboundFrame,
|
|
296
|
+
validateControlFrame: validateControlInboundFrame,
|
|
297
|
+
selectWriteLane: (frame) => {
|
|
298
|
+
switch (frame.frame_type) {
|
|
299
|
+
case "request":
|
|
300
|
+
return "ordinary";
|
|
301
|
+
case "sidecar_response":
|
|
302
|
+
case "control":
|
|
303
|
+
return "control";
|
|
304
|
+
default: {
|
|
305
|
+
const invalidFrame = frame;
|
|
306
|
+
throw new Error(`host frame ${invalidFrame.frame_type} is not valid on either writable protocol lane`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
function validateOrdinaryInboundFrame(frame) {
|
|
313
|
+
if (frame.frame_type !== "event") {
|
|
314
|
+
throw new Error(`sidecar frame ${frame.frame_type} is not valid on the ordinary protocol lane`);
|
|
315
|
+
}
|
|
316
|
+
if (isHeartbeatFrame(frame)) {
|
|
317
|
+
throw new Error("sidecar heartbeat event is not valid on the ordinary protocol lane");
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
function validateControlInboundFrame(frame) {
|
|
321
|
+
if (frame.frame_type === "response" ||
|
|
322
|
+
frame.frame_type === "sidecar_request") {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (frame.frame_type === "event" &&
|
|
326
|
+
isHeartbeatFrame(frame)) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
throw new Error(`sidecar frame ${frame.frame_type} is not valid on the control protocol lane`);
|
|
330
|
+
}
|
|
331
|
+
function isHeartbeatFrame(frame) {
|
|
332
|
+
return (frame.payload.type === "structured" && frame.payload.name === "heartbeat");
|
|
333
|
+
}
|
|
@@ -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
|
}
|
package/dist/protocol-schema.js
CHANGED
|
@@ -42,7 +42,7 @@ export type LiveRequestPayload = {
|
|
|
42
42
|
packages?: LivePackageDescriptor[];
|
|
43
43
|
packages_mount_at?: string;
|
|
44
44
|
bootstrap_commands?: string[];
|
|
45
|
-
|
|
45
|
+
binding_shim_commands?: string[];
|
|
46
46
|
} | {
|
|
47
47
|
type: "link_package";
|
|
48
48
|
package: LivePackageDescriptor;
|
|
@@ -79,6 +79,9 @@ export type LiveRequestPayload = {
|
|
|
79
79
|
lower_layer_ids: string[];
|
|
80
80
|
} | {
|
|
81
81
|
type: "snapshot_root_filesystem";
|
|
82
|
+
max_bytes: number;
|
|
83
|
+
} | {
|
|
84
|
+
type: "list_mounts";
|
|
82
85
|
} | {
|
|
83
86
|
type: "guest_kernel_call";
|
|
84
87
|
execution_id: string;
|
package/dist/request-payloads.js
CHANGED
|
@@ -58,7 +58,7 @@ export function toGeneratedRequestPayload(payload) {
|
|
|
58
58
|
packages: (payload.packages ?? []).map(toGeneratedPackageDescriptor),
|
|
59
59
|
packagesMountAt: payload.packages_mount_at ?? "",
|
|
60
60
|
bootstrapCommands: payload.bootstrap_commands ?? [],
|
|
61
|
-
|
|
61
|
+
bindingShimCommands: payload.binding_shim_commands ?? [],
|
|
62
62
|
},
|
|
63
63
|
};
|
|
64
64
|
case "link_package":
|
|
@@ -153,7 +153,12 @@ export function toGeneratedRequestPayload(payload) {
|
|
|
153
153
|
},
|
|
154
154
|
};
|
|
155
155
|
case "snapshot_root_filesystem":
|
|
156
|
-
return {
|
|
156
|
+
return {
|
|
157
|
+
tag: "SnapshotRootFilesystemRequest",
|
|
158
|
+
val: { maxBytes: BigInt(payload.max_bytes) },
|
|
159
|
+
};
|
|
160
|
+
case "list_mounts":
|
|
161
|
+
return { tag: "ListMountsRequest", val: null };
|
|
157
162
|
case "execute":
|
|
158
163
|
return {
|
|
159
164
|
tag: "ExecuteRequest",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type LiveRootFilesystemEntry, type LiveRootFilesystemEntryEncoding } from "./filesystem.js";
|
|
2
1
|
import { type LiveExtEnvelope } from "./ext.js";
|
|
2
|
+
import { type LiveRootFilesystemEntry, type LiveRootFilesystemEntryEncoding } from "./filesystem.js";
|
|
3
3
|
import type * as protocol from "./generated-protocol.js";
|
|
4
4
|
import { type LiveFilesystemOperation, type LiveGuestFilesystemOperation, type LiveSignalDispositionAction } from "./protocol-maps.js";
|
|
5
5
|
import { type LiveGuestFilesystemStat, type LiveProcessSnapshotEntry, type LiveSocketStateEntry } from "./state.js";
|
|
@@ -9,7 +9,7 @@ export interface LiveGuestDirEntry {
|
|
|
9
9
|
path: string;
|
|
10
10
|
isDirectory: boolean;
|
|
11
11
|
isSymbolicLink: boolean;
|
|
12
|
-
size:
|
|
12
|
+
size: bigint;
|
|
13
13
|
}
|
|
14
14
|
export interface LiveSignalHandlerRegistration {
|
|
15
15
|
action: LiveSignalDispositionAction;
|
|
@@ -49,6 +49,11 @@ export interface LivePackageCommands {
|
|
|
49
49
|
package_name: string;
|
|
50
50
|
commands: string[];
|
|
51
51
|
}
|
|
52
|
+
export interface LiveMountInfo {
|
|
53
|
+
path: string;
|
|
54
|
+
kind: string;
|
|
55
|
+
read_only: boolean;
|
|
56
|
+
}
|
|
52
57
|
export interface LiveAgentosProjectedAgent {
|
|
53
58
|
id: string;
|
|
54
59
|
acp_entrypoint: string;
|
|
@@ -79,6 +84,9 @@ export type LiveResponsePayload = {
|
|
|
79
84
|
} | {
|
|
80
85
|
type: "provided_commands_response";
|
|
81
86
|
packages: LivePackageCommands[];
|
|
87
|
+
} | {
|
|
88
|
+
type: "mounts_listed";
|
|
89
|
+
mounts: LiveMountInfo[];
|
|
82
90
|
} | {
|
|
83
91
|
type: "host_callbacks_registered";
|
|
84
92
|
registration: string;
|
|
@@ -179,6 +187,19 @@ export type LiveResponsePayload = {
|
|
|
179
187
|
type: "rejected";
|
|
180
188
|
code: string;
|
|
181
189
|
message: string;
|
|
190
|
+
limit_name: string | null;
|
|
191
|
+
configured_limit: number | null;
|
|
192
|
+
current_usage: number | null;
|
|
193
|
+
requested: number | null;
|
|
194
|
+
unit: string | null;
|
|
195
|
+
scope: string | null;
|
|
196
|
+
vm_id: string | null;
|
|
197
|
+
session_generation: number | null;
|
|
198
|
+
capability_id: number | null;
|
|
199
|
+
operation: string | null;
|
|
200
|
+
configuration_path: string | null;
|
|
201
|
+
retryable: boolean | null;
|
|
202
|
+
errno: string | null;
|
|
182
203
|
} | {
|
|
183
204
|
type: "ext_result";
|
|
184
205
|
envelope: LiveExtEnvelope;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fromGeneratedRootFilesystemEntry, } from "./filesystem.js";
|
|
2
1
|
import { fromGeneratedExtEnvelope } from "./ext.js";
|
|
2
|
+
import { fromGeneratedRootFilesystemEntry, } from "./filesystem.js";
|
|
3
3
|
import { bigIntToSafeNumber } from "./numbers.js";
|
|
4
4
|
import { fromGeneratedFilesystemOperation, fromGeneratedGuestFilesystemOperation, fromGeneratedRootFilesystemEntryEncoding, fromGeneratedSignalDispositionAction, } from "./protocol-maps.js";
|
|
5
5
|
import { fromGeneratedGuestFilesystemStat, fromGeneratedProcessSnapshotEntry, fromGeneratedSocketStateEntry, } from "./state.js";
|
|
@@ -55,6 +55,15 @@ export function fromGeneratedResponsePayload(payload) {
|
|
|
55
55
|
commands: [...pkg.commands],
|
|
56
56
|
})),
|
|
57
57
|
};
|
|
58
|
+
case "ListMountsResponse":
|
|
59
|
+
return {
|
|
60
|
+
type: "mounts_listed",
|
|
61
|
+
mounts: payload.val.mounts.map((mount) => ({
|
|
62
|
+
path: mount.path,
|
|
63
|
+
kind: mount.kind,
|
|
64
|
+
read_only: mount.readOnly,
|
|
65
|
+
})),
|
|
66
|
+
};
|
|
58
67
|
case "HostCallbacksRegisteredResponse":
|
|
59
68
|
return {
|
|
60
69
|
type: "host_callbacks_registered",
|
|
@@ -95,7 +104,7 @@ export function fromGeneratedResponsePayload(payload) {
|
|
|
95
104
|
path: entry.path,
|
|
96
105
|
isDirectory: entry.isDirectory,
|
|
97
106
|
isSymbolicLink: entry.isSymbolicLink,
|
|
98
|
-
size:
|
|
107
|
+
size: entry.size,
|
|
99
108
|
})),
|
|
100
109
|
}
|
|
101
110
|
: {}),
|
|
@@ -228,6 +237,29 @@ export function fromGeneratedResponsePayload(payload) {
|
|
|
228
237
|
type: "rejected",
|
|
229
238
|
code: payload.val.code,
|
|
230
239
|
message: payload.val.message,
|
|
240
|
+
limit_name: payload.val.limitName,
|
|
241
|
+
configured_limit: payload.val.configuredLimit === null
|
|
242
|
+
? null
|
|
243
|
+
: bigIntToSafeNumber(payload.val.configuredLimit, "rejected.configured_limit"),
|
|
244
|
+
current_usage: payload.val.currentUsage === null
|
|
245
|
+
? null
|
|
246
|
+
: bigIntToSafeNumber(payload.val.currentUsage, "rejected.current_usage"),
|
|
247
|
+
requested: payload.val.requested === null
|
|
248
|
+
? null
|
|
249
|
+
: bigIntToSafeNumber(payload.val.requested, "rejected.requested"),
|
|
250
|
+
unit: payload.val.unit,
|
|
251
|
+
scope: payload.val.scope,
|
|
252
|
+
vm_id: payload.val.vmId,
|
|
253
|
+
session_generation: payload.val.sessionGeneration === null
|
|
254
|
+
? null
|
|
255
|
+
: bigIntToSafeNumber(payload.val.sessionGeneration, "rejected.session_generation"),
|
|
256
|
+
capability_id: payload.val.capabilityId === null
|
|
257
|
+
? null
|
|
258
|
+
: bigIntToSafeNumber(payload.val.capabilityId, "rejected.capability_id"),
|
|
259
|
+
operation: payload.val.operation,
|
|
260
|
+
configuration_path: payload.val.configurationPath,
|
|
261
|
+
retryable: payload.val.retryable,
|
|
262
|
+
errno: payload.val.errno,
|
|
231
263
|
};
|
|
232
264
|
case "VmFetchResponse":
|
|
233
265
|
return {
|
package/dist/sidecar-errors.d.ts
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
export interface SidecarRejectionDetail {
|
|
2
|
+
code: string;
|
|
3
|
+
message: string;
|
|
4
|
+
limit_name: string | null;
|
|
5
|
+
configured_limit: number | null;
|
|
6
|
+
current_usage: number | null;
|
|
7
|
+
requested: number | null;
|
|
8
|
+
unit: string | null;
|
|
9
|
+
scope: string | null;
|
|
10
|
+
vm_id: string | null;
|
|
11
|
+
session_generation: number | null;
|
|
12
|
+
capability_id: number | null;
|
|
13
|
+
operation: string | null;
|
|
14
|
+
configuration_path: string | null;
|
|
15
|
+
retryable: boolean | null;
|
|
16
|
+
errno: string | null;
|
|
17
|
+
}
|
|
18
|
+
export declare class SidecarRejectedError extends Error {
|
|
19
|
+
readonly requestId: number;
|
|
20
|
+
readonly detail: SidecarRejectionDetail;
|
|
21
|
+
constructor(requestId: number, detail: SidecarRejectionDetail);
|
|
22
|
+
}
|
|
1
23
|
export declare class SidecarProcessExited extends Error {
|
|
2
24
|
readonly exitCode: number | null;
|
|
3
25
|
readonly signal: string | null;
|
|
@@ -8,6 +30,21 @@ export declare class SidecarProcessExited extends Error {
|
|
|
8
30
|
stderr: string;
|
|
9
31
|
});
|
|
10
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* The silence watchdog fired: the sidecar produced no protocol frames at all —
|
|
35
|
+
* not even its 10s liveness heartbeats — for the full silence window, so the
|
|
36
|
+
* process is dead or wedged (not merely busy: a busy sidecar still heartbeats
|
|
37
|
+
* from a dedicated thread). The host kills the sidecar and rejects every
|
|
38
|
+
* in-flight request with this error.
|
|
39
|
+
*/
|
|
40
|
+
export declare class SidecarSilenceTimeout extends Error {
|
|
41
|
+
readonly silenceMs: number;
|
|
42
|
+
readonly stderr: string;
|
|
43
|
+
constructor(options: {
|
|
44
|
+
silenceMs: number;
|
|
45
|
+
stderr: string;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
11
48
|
export declare class SidecarProcessError extends Error {
|
|
12
49
|
readonly childError: Error;
|
|
13
50
|
readonly stderr: string;
|
package/dist/sidecar-errors.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
function formatSidecarStderrSuffix(stderr) {
|
|
2
2
|
return stderr ? `\nstderr:\n${stderr}` : "";
|
|
3
3
|
}
|
|
4
|
+
export class SidecarRejectedError extends Error {
|
|
5
|
+
requestId;
|
|
6
|
+
detail;
|
|
7
|
+
constructor(requestId, detail) {
|
|
8
|
+
super(`sidecar rejected request ${requestId}: ${detail.code}: ${detail.message}`);
|
|
9
|
+
this.name = "SidecarRejectedError";
|
|
10
|
+
this.requestId = requestId;
|
|
11
|
+
this.detail = detail;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
4
14
|
export class SidecarProcessExited extends Error {
|
|
5
15
|
exitCode;
|
|
6
16
|
signal;
|
|
@@ -18,6 +28,23 @@ export class SidecarProcessExited extends Error {
|
|
|
18
28
|
this.stderr = options.stderr;
|
|
19
29
|
}
|
|
20
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* The silence watchdog fired: the sidecar produced no protocol frames at all —
|
|
33
|
+
* not even its 10s liveness heartbeats — for the full silence window, so the
|
|
34
|
+
* process is dead or wedged (not merely busy: a busy sidecar still heartbeats
|
|
35
|
+
* from a dedicated thread). The host kills the sidecar and rejects every
|
|
36
|
+
* in-flight request with this error.
|
|
37
|
+
*/
|
|
38
|
+
export class SidecarSilenceTimeout extends Error {
|
|
39
|
+
silenceMs;
|
|
40
|
+
stderr;
|
|
41
|
+
constructor(options) {
|
|
42
|
+
super(`sidecar unresponsive: no protocol frames or heartbeats for ${Math.round(options.silenceMs)}ms; killing sidecar${formatSidecarStderrSuffix(options.stderr)}`);
|
|
43
|
+
this.name = "SidecarSilenceTimeout";
|
|
44
|
+
this.silenceMs = options.silenceMs;
|
|
45
|
+
this.stderr = options.stderr;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
21
48
|
export class SidecarProcessError extends Error {
|
|
22
49
|
childError;
|
|
23
50
|
stderr;
|