Files
orca/src/shared/remote-runtime-client.ts
T
Neil 4882eeb8ac rm git shim: neutralize stale wrappers without a host gate (#14255)
* Revert "fix terminal attribution shim removal edge cases (#14187)"

This reverts 585dd6d3a9. Re-landed in the next commit without the host capability gate. Nothing shipped with it, so no migration constraint.

* rm git shim: neutralize stale wrappers without a host gate

Re-lands the cleanup half of #14187: pass-through tombstones for retained wrapper paths, env/PATH scrubbing at every spawn owner, and the retired setting drop.

Only writes tombstones when the legacy directory already exists, so a clean install no longer has it created. Leaves out the terminal.attribution-removed.v1 capability gate: the tombstone neutralizes each host locally, so refusing terminal create/split against older hosts denied service without adding cleanup.

* rm git shim: surface neutralization failures and fix rollback marker

Readiness review follow-ups: warn on each failed attempt and on give-up (was silent and undiagnosable); write a VERSION marker distinct from the retired shim's '7' so a rolled-back build rewrites its own wrappers; clear a captured ORCA_REAL_* path that no longer exists so the cmd wrapper's where.exe fallback can run; stop a locked temp file masking the real error. Adds retry-exhaustion coverage.

* rm git shim: pin the cmd fallback order and correct the give-up count

Round-2 review follow-ups: string-pin that a stale ORCA_REAL_* is cleared before the where.exe fallback, and count the initial attempt in the give-up warning so it agrees with the per-attempt line.

* rm git shim: keep the split-failure toast

The revert took a toast that #14187 added alongside the gate but which stands on its own: without it a failed remote split only reaches the console and the pane silently never appears. Also pins attempt ordinals in the retry-exhaustion test.
2026-08-13 03:01:45 -07:00

868 lines
26 KiB
TypeScript

/* oxlint-disable max-lines -- Why: one-shot and streaming remote clients share the
* same E2EE handshake and response validation state; keep them together until
* the terminal transport is fully migrated and a stable shared connection
* abstraction emerges. */
import { randomUUID } from 'node:crypto'
import WebSocket from 'ws'
import type { PairingOffer } from './pairing'
import {
decrypt,
decryptBytes,
deriveSharedKey,
encrypt,
encryptBytes,
generateKeyPair,
publicKeyFromBase64,
publicKeyToBase64
} from './e2ee-crypto'
import {
isKeepaliveFrame,
RuntimeRpcEnvelopeSchema,
type RuntimeOrchestrationEnvelope,
type RuntimeRpcResponse
} from './runtime-rpc-envelope'
import type { RuntimeStatus } from './runtime-types'
import {
AGENT_SESSION_BOUNDARY_RUNTIME_CAPABILITY,
SESSION_TAB_CLOSE_INTENT_RUNTIME_CAPABILITY
} from './protocol-version'
// Re-export so existing value importers of `RemoteRuntimeClientError` are
// unaffected; the class lives in a ws-free module so type-only consumers
// (and mobile's typecheck) don't compile this file's Node-only deps.
import { RemoteRuntimeClientError } from './remote-runtime-client-error'
import {
isRemoteRuntimeBinaryFrameWithinLimit,
REMOTE_RUNTIME_MAX_WEBSOCKET_FRAME_BYTES,
serializeRemoteRuntimePayload,
serializeRemoteRuntimeRpcRequest
} from './remote-runtime-memory-limits'
import {
prepareRemoteRuntimeRequest,
releaseRemoteRuntimePreparedRequest,
takeRemoteRuntimePreparedRequest
} from './remote-runtime-prepared-request-admission'
import { parseRemoteRuntimeJsonText } from './remote-runtime-request-frames'
import {
startRemoteRuntimeSocketLiveness,
type RemoteRuntimeSocketLivenessMonitor,
type RemoteRuntimeSocketLivenessOptions
} from './remote-runtime-socket-liveness'
import { createWsOutboundBackpressureQueue } from './ws-outbound-backpressure-queue'
import { MAX_TIMER_DELAY_MS, isSafeTimerDelayMs } from './timer-delay'
export { RemoteRuntimeClientError } from './remote-runtime-client-error'
type HandshakeState = 'awaiting_ready' | 'awaiting_authenticated' | 'ready'
function ignoreSettledRemoteRuntimeSocketError(): void {}
function formatRemoteRuntimeCloseMessage(code: number, reason: Buffer): string {
const suffixParts: string[] = []
if (code !== 1005 && code !== 1006) {
suffixParts.push(String(code))
}
const reasonText = reason.toString().trim()
if (reasonText) {
suffixParts.push(reasonText)
}
return suffixParts.length > 0
? `Remote Orca runtime closed the connection (${suffixParts.join(': ')}).`
: 'Remote Orca runtime closed the connection.'
}
export type RemoteRuntimeSubscription = {
requestId: string
close: () => void
sendBinary: (bytes: Uint8Array<ArrayBufferLike>) => boolean
}
export type RemoteRuntimeSubscriptionCallbacks<TResult = unknown> = {
onResponse: (response: RuntimeRpcResponse<TResult>) => void
onBinary?: (bytes: Uint8Array<ArrayBufferLike>) => void
onError: (error: RemoteRuntimeClientError) => void
onClose?: () => void
}
export function sendRemoteRuntimeRequest<TResult>(
pairing: PairingOffer,
method: string,
params: unknown,
timeoutMs: number,
envelope?: RuntimeOrchestrationEnvelope
): Promise<RuntimeRpcResponse<TResult>> {
return sendRemoteRuntimeRequestOnSocket(pairing, method, params, timeoutMs, envelope)
}
export function sendRemoteRuntimeRequestWithStatusPreflight<TResult>(
pairing: PairingOffer,
method: string,
params: unknown,
timeoutMs: number,
validateStatus: (response: RuntimeRpcResponse<RuntimeStatus>) => void,
envelope?: RuntimeOrchestrationEnvelope
): Promise<RuntimeRpcResponse<TResult>> {
return sendRemoteRuntimeRequestOnSocket(
pairing,
method,
params,
timeoutMs,
envelope,
validateStatus
)
}
async function sendRemoteRuntimeRequestOnSocket<TResult>(
pairing: PairingOffer,
method: string,
params: unknown,
timeoutMs: number,
envelope?: RuntimeOrchestrationEnvelope,
validateStatus?: (response: RuntimeRpcResponse<RuntimeStatus>) => void
): Promise<RuntimeRpcResponse<TResult>> {
if (!isSafeTimerDelayMs(timeoutMs)) {
throw new RemoteRuntimeClientError(
'invalid_argument',
`Runtime request timeout must be an integer between 0 and ${MAX_TIMER_DELAY_MS}ms.`
)
}
const requestId = randomUUID()
const statusRequestId = validateStatus ? randomUUID() : null
const serializedStatusRequest = statusRequestId
? serializeRemoteRuntimePayload({
id: statusRequestId,
deviceToken: pairing.deviceToken,
method: 'status.get'
})
: null
const serializedAuth = serializeRemoteRuntimePayload({
type: 'e2ee_auth',
deviceToken: pairing.deviceToken,
clientCapabilities: [
SESSION_TAB_CLOSE_INTENT_RUNTIME_CAPABILITY,
AGENT_SESSION_BOUNDARY_RUNTIME_CAPABILITY
]
})
const pendingRequest = {
preparedRequest: prepareRemoteRuntimeRequest(new Map(), () =>
serializeRemoteRuntimeRpcRequest({
requestId,
deviceToken: pairing.deviceToken,
method,
params,
envelope
})
)
}
let serializedRequest = takeRemoteRuntimePreparedRequest(pendingRequest)
let awaitingRequestId = statusRequestId ?? requestId
let awaitingStatus = statusRequestId !== null
return await new Promise<RuntimeRpcResponse<TResult>>((resolve, reject) => {
const keyPair = generateKeyPair()
const serverPublicKey = publicKeyFromBase64(pairing.publicKeyB64)
const sharedKey = deriveSharedKey(keyPair.secretKey, serverPublicKey)
let state: HandshakeState = 'awaiting_ready'
let settled = false
let ws: WebSocket | null = null
const getPairingStage = (): 'connect' | 'host-identity' | 'runtime' =>
state === 'awaiting_ready'
? 'connect'
: state === 'awaiting_authenticated'
? 'host-identity'
: 'runtime'
const cleanupSocketListeners = (): void => {
const socket = ws
if (!socket) {
return
}
socket.off('open', onOpen)
socket.off('error', onError)
socket.off('close', onClose)
socket.off('message', onMessage)
// Why: the settled one-shot no longer needs Orca callbacks, but a ws
// can still report a late transport error after close is requested.
if (socket.readyState !== WebSocket.CLOSED) {
socket.on('error', ignoreSettledRemoteRuntimeSocketError)
}
}
let timeout = setTimeout(onTimeout, timeoutMs)
function onTimeout(): void {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'runtime_timeout',
'Timed out waiting for the remote Orca runtime to respond.',
{ pairingStage: getPairingStage() }
)
})
}
function refreshTimeout(): void {
const refreshableTimeout = timeout as { refresh?: () => void }
if (typeof refreshableTimeout.refresh === 'function') {
refreshableTimeout.refresh()
return
}
// Mobile's DOM timer type has no refresh().
clearTimeout(timeout)
timeout = setTimeout(onTimeout, timeoutMs)
}
const finish = (
result: { ok: true; response: RuntimeRpcResponse<TResult> } | { ok: false; error: Error }
): void => {
if (settled) {
return
}
settled = true
clearTimeout(timeout)
try {
cleanupSocketListeners()
ws?.close()
} catch {
// ignore best-effort close
}
if (result.ok === false) {
reject(result.error)
} else {
resolve(result.response)
}
}
try {
ws = new WebSocket(pairing.endpoint, { maxPayload: REMOTE_RUNTIME_MAX_WEBSOCKET_FRAME_BYTES })
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
finish({
ok: false,
error: new RemoteRuntimeClientError(
'invalid_argument',
`Invalid remote endpoint: ${message}`
)
})
return
}
function onOpen(): void {
ws?.send(
JSON.stringify({
type: 'e2ee_hello',
publicKeyB64: publicKeyToBase64(keyPair.publicKey)
})
)
}
function onError(): void {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'remote_runtime_unavailable',
'Could not connect to the remote Orca runtime.',
{ pairingStage: getPairingStage() }
)
})
}
function onClose(code: number, reason: Buffer): void {
if (!settled) {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'remote_runtime_unavailable',
formatRemoteRuntimeCloseMessage(code, reason),
{
pairingStage: getPairingStage(),
closeCode: code
}
)
})
}
}
function onMessage(data: WebSocket.RawData, isBinary: boolean): void {
if (settled) {
return
}
if (isBinary) {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an unexpected binary frame.',
{
pairingStage: state === 'awaiting_ready' ? 'host-identity' : getPairingStage()
}
)
})
return
}
const frame = data.toString()
if (state === 'awaiting_ready') {
handleReadyFrame(frame)
return
}
const plaintext = decrypt(frame, sharedKey)
if (plaintext === null) {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an undecryptable frame.',
{
pairingStage: state === 'awaiting_authenticated' ? 'host-identity' : getPairingStage()
}
)
})
return
}
if (state === 'awaiting_authenticated') {
handleAuthenticatedFrame(plaintext)
return
}
handleRpcFrame(plaintext)
}
ws.once('open', onOpen)
ws.once('error', onError)
ws.on('close', onClose)
ws.on('message', onMessage)
function handleReadyFrame(frame: string): void {
let ready: unknown
try {
ready = parseRemoteRuntimeJsonText(frame)
} catch {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an invalid E2EE handshake frame.',
{ pairingStage: 'host-identity' }
)
})
return
}
if (
typeof ready !== 'object' ||
ready === null ||
(ready as { type?: unknown }).type !== 'e2ee_ready'
) {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an unexpected E2EE handshake frame.',
{ pairingStage: 'host-identity' }
)
})
return
}
state = 'awaiting_authenticated'
ws?.send(encrypt(serializedAuth, sharedKey))
}
function handleAuthenticatedFrame(plaintext: string): void {
let authenticated: unknown
try {
authenticated = parseRemoteRuntimeJsonText(plaintext)
} catch {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an invalid E2EE auth frame.',
{ pairingStage: 'host-identity' }
)
})
return
}
const type = (authenticated as { type?: unknown }).type
if (type !== 'e2ee_authenticated') {
const code =
typeof authenticated === 'object' &&
authenticated !== null &&
(authenticated as { error?: { code?: unknown } }).error?.code === 'unauthorized'
? 'unauthorized'
: 'invalid_runtime_response'
finish({
ok: false,
error: new RemoteRuntimeClientError(
code,
'Remote Orca runtime rejected the pairing token.',
{ pairingStage: code === 'unauthorized' ? 'access-grant' : 'host-identity' }
)
})
return
}
state = 'ready'
if (serializedStatusRequest) {
ws?.send(encrypt(serializedStatusRequest, sharedKey))
return
}
sendRequestedRpc()
}
function sendRequestedRpc(): void {
const request = serializedRequest
serializedRequest = null
if (request === null) {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'remote_runtime_unavailable',
'Remote Orca runtime request was released before it could be sent.'
)
})
return
}
ws?.send(encrypt(request, sharedKey))
}
function handleRpcFrame(plaintext: string): void {
let raw: unknown
try {
raw = parseRemoteRuntimeJsonText(plaintext)
} catch {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an invalid response frame.',
{ pairingStage: 'runtime' }
)
})
return
}
if (isKeepaliveFrame(raw)) {
refreshTimeout()
return
}
const parsed = RuntimeRpcEnvelopeSchema.safeParse(raw)
if (!parsed.success || '_keepalive' in parsed.data) {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an invalid response frame.',
{ pairingStage: 'runtime' }
)
})
return
}
if (parsed.data.id !== awaitingRequestId) {
finish({
ok: false,
error: new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned a mismatched response id.',
{ pairingStage: 'runtime' }
)
})
return
}
if (awaitingStatus && validateStatus) {
try {
validateStatus(parsed.data as RuntimeRpcResponse<RuntimeStatus>)
} catch (error) {
finish({
ok: false,
error:
error instanceof Error
? error
: new RemoteRuntimeClientError('runtime_error', String(error))
})
return
}
awaitingStatus = false
awaitingRequestId = requestId
refreshTimeout()
sendRequestedRpc()
return
}
const response = parsed.data as RuntimeRpcResponse<TResult>
finish({ ok: true, response })
}
}).finally(() => releaseRemoteRuntimePreparedRequest(pendingRequest))
}
export async function subscribeRemoteRuntimeRequest<TResult>(
pairing: PairingOffer,
method: string,
params: unknown,
timeoutMs: number,
callbacks: RemoteRuntimeSubscriptionCallbacks<TResult>,
livenessOptions?: RemoteRuntimeSocketLivenessOptions
): Promise<RemoteRuntimeSubscription> {
const requestId = randomUUID()
const serializedRequest = serializeRemoteRuntimeRpcRequest({
requestId,
deviceToken: pairing.deviceToken,
method,
params
})
const serializedAuth = serializeRemoteRuntimePayload({
type: 'e2ee_auth',
deviceToken: pairing.deviceToken,
clientCapabilities: [
SESSION_TAB_CLOSE_INTENT_RUNTIME_CAPABILITY,
AGENT_SESSION_BOUNDARY_RUNTIME_CAPABILITY
]
})
return await new Promise((resolve, reject) => {
const keyPair = generateKeyPair()
const serverPublicKey = publicKeyFromBase64(pairing.publicKeyB64)
const sharedKey = deriveSharedKey(keyPair.secretKey, serverPublicKey)
let state: HandshakeState = 'awaiting_ready'
let settled = false
let ws: WebSocket | null = null
let liveness: RemoteRuntimeSocketLivenessMonitor | null = null
const cleanupSocketListeners = (): WebSocket | null => {
liveness?.stop()
liveness = null
sendQueue?.dispose()
sendQueue = null
const socket = ws
if (!socket) {
return null
}
socket.off('open', onOpen)
socket.off('error', onError)
socket.off('close', onClose)
socket.off('message', onMessage)
socket.off('pong', onLivenessSignal)
socket.off('ping', onLivenessSignal)
ws = null
// Why: startup failures detach Orca callbacks before closing the ws,
// but ws can still emit a late transport error while close is in flight.
if (socket.readyState !== WebSocket.CLOSED) {
socket.on('error', ignoreSettledRemoteRuntimeSocketError)
}
return socket
}
const closeSocketAfterCleanup = (): void => {
const socket = cleanupSocketListeners()
try {
socket?.close()
} catch {
// ignore best-effort close
}
}
const timeout = setTimeout(() => {
fail(
new RemoteRuntimeClientError(
'runtime_timeout',
'Timed out waiting for the remote Orca runtime subscription to start.'
)
)
}, timeoutMs)
const close = (): void => {
try {
ws?.close()
} catch {
// ignore best-effort close
}
}
// Why: client input (keystrokes) must never be dropped under backpressure.
// Hold encrypted frames in order while bufferedAmount is over the cap and
// drain as it clears; a wedged link (hard cap) fails the socket so the
// renderer resubscribes and replays a fresh snapshot.
let sendQueue: ReturnType<typeof createWsOutboundBackpressureQueue<Buffer>> | null = null
const ensureSendQueue = (
socket: WebSocket
): ReturnType<typeof createWsOutboundBackpressureQueue<Buffer>> => {
if (!sendQueue) {
sendQueue = createWsOutboundBackpressureQueue<Buffer>({
send: (frame) => socket.send(frame, { binary: true }),
byteLengthOf: (frame) => frame.byteLength,
getBufferedAmount: () => socket.bufferedAmount,
isWritable: () => socket.readyState === WebSocket.OPEN,
onOverflow: () =>
fail(
new RemoteRuntimeClientError(
'remote_runtime_unavailable',
'Remote Orca runtime send buffer overflow; reconnecting.'
)
)
})
}
return sendQueue
}
const sendBinary = (bytes: Uint8Array<ArrayBufferLike>): boolean => {
if (
!isRemoteRuntimeBinaryFrameWithinLimit(bytes) ||
state !== 'ready' ||
!ws ||
ws.readyState !== WebSocket.OPEN
) {
return false
}
ensureSendQueue(ws).enqueue(Buffer.from(encryptBytes(bytes, sharedKey)))
return true
}
const succeed = (): void => {
if (settled) {
return
}
settled = true
clearTimeout(timeout)
resolve({ requestId, close, sendBinary })
}
const fail = (error: RemoteRuntimeClientError): void => {
if (!settled) {
settled = true
clearTimeout(timeout)
closeSocketAfterCleanup()
reject(error)
return
}
callbacks.onError(error)
// Why: after a subscription is established, protocol failures are
// terminal for this socket. Closing here releases the WebSocket listeners
// and lets the IPC subscription registry drop its retained callbacks.
closeSocketAfterCleanup()
callbacks.onClose?.()
}
try {
ws = new WebSocket(pairing.endpoint, { maxPayload: REMOTE_RUNTIME_MAX_WEBSOCKET_FRAME_BYTES })
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
fail(new RemoteRuntimeClientError('invalid_argument', `Invalid remote endpoint: ${message}`))
return
}
function onOpen(): void {
ws?.send(
JSON.stringify({
type: 'e2ee_hello',
publicKeyB64: publicKeyToBase64(keyPair.publicKey)
})
)
}
function onError(): void {
fail(
new RemoteRuntimeClientError(
'remote_runtime_unavailable',
'Could not connect to the remote Orca runtime.'
)
)
}
function onClose(code: number, reason: Buffer): void {
clearTimeout(timeout)
cleanupSocketListeners()
if (!settled) {
settled = true
reject(
new RemoteRuntimeClientError(
'remote_runtime_unavailable',
formatRemoteRuntimeCloseMessage(code, reason)
)
)
return
}
callbacks.onClose?.()
}
function onMessage(data: WebSocket.RawData, isBinary: boolean): void {
liveness?.noteActivity()
if (isBinary) {
handleBinaryFrame(new Uint8Array(data as Buffer))
return
}
const frame = data.toString()
if (state === 'awaiting_ready') {
handleReadyFrame(frame)
return
}
const plaintext = decrypt(frame, sharedKey)
if (plaintext === null) {
fail(
new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an undecryptable frame.'
)
)
return
}
if (state === 'awaiting_authenticated') {
handleAuthenticatedFrame(plaintext)
return
}
handleRpcFrame(plaintext)
}
function onLivenessSignal(): void {
liveness?.noteActivity()
}
ws.once('open', onOpen)
ws.once('error', onError)
ws.on('close', onClose)
ws.on('message', onMessage)
ws.on('pong', onLivenessSignal)
ws.on('ping', onLivenessSignal)
// Why: dedicated stream sockets (terminal.multiplex, browser.screencast)
// ride the same tunnels as shared control; a half-open drop must surface
// as a close so the renderer's onTransportClose resubscribe path runs
// instead of freezing the stream forever (#7718/#7489).
const monitoredWs = ws
liveness = startRemoteRuntimeSocketLiveness({
ping: () => {
if (monitoredWs.readyState === WebSocket.OPEN) {
monitoredWs.ping()
}
},
onDead: () => {
// Why: fail() first so listeners detach before terminate's close event;
// otherwise the close handler would emit a second onClose to callers.
fail(
new RemoteRuntimeClientError(
'remote_runtime_unavailable',
'Remote Orca runtime stopped responding; the stream connection was reset.'
)
)
try {
// Why: close() on a half-open socket can hang for the OS TCP timeout.
monitoredWs.terminate()
} catch {
// Best-effort terminate; the subscription is already settled.
}
},
options: livenessOptions
})
function handleReadyFrame(frame: string): void {
let ready: unknown
try {
ready = parseRemoteRuntimeJsonText(frame)
} catch {
fail(
new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an invalid E2EE handshake frame.'
)
)
return
}
if (
typeof ready !== 'object' ||
ready === null ||
(ready as { type?: unknown }).type !== 'e2ee_ready'
) {
fail(
new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an unexpected E2EE handshake frame.'
)
)
return
}
state = 'awaiting_authenticated'
ws?.send(encrypt(serializedAuth, sharedKey))
}
function handleAuthenticatedFrame(plaintext: string): void {
let authenticated: unknown
try {
authenticated = parseRemoteRuntimeJsonText(plaintext)
} catch {
fail(
new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an invalid E2EE auth frame.'
)
)
return
}
const type = (authenticated as { type?: unknown }).type
if (type !== 'e2ee_authenticated') {
const code =
typeof authenticated === 'object' &&
authenticated !== null &&
(authenticated as { error?: { code?: unknown } }).error?.code === 'unauthorized'
? 'unauthorized'
: 'invalid_runtime_response'
fail(new RemoteRuntimeClientError(code, 'Remote Orca runtime rejected the pairing token.'))
return
}
state = 'ready'
ws?.send(encrypt(serializedRequest, sharedKey))
succeed()
}
function handleRpcFrame(plaintext: string): void {
let raw: unknown
try {
raw = parseRemoteRuntimeJsonText(plaintext)
} catch {
fail(
new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an invalid response frame.'
)
)
return
}
const parsed = RuntimeRpcEnvelopeSchema.safeParse(raw)
if (!parsed.success || '_keepalive' in parsed.data) {
return
}
const response = parsed.data as RuntimeRpcResponse<TResult>
if (response.id !== requestId) {
fail(
new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned a mismatched response id.'
)
)
return
}
callbacks.onResponse(response)
}
function handleBinaryFrame(frame: Uint8Array<ArrayBufferLike>): void {
if (state !== 'ready') {
fail(
new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned binary data before authentication.'
)
)
return
}
const plaintext = decryptBytes(frame, sharedKey)
if (plaintext === null) {
fail(
new RemoteRuntimeClientError(
'invalid_runtime_response',
'Remote Orca runtime returned an undecryptable binary frame.'
)
)
return
}
callbacks.onBinary?.(plaintext)
}
})
}