384 lines · 9.1 KB · TypeScript
RawDownload
import { describe, expect, it } from "vitest";import * as protocol from "../src/generated-protocol.js";import {	classifySidecarWrittenProtocolFrame,	decodeBareProtocolFrame,	decodeProtocolFramePayload,	encodeBareProtocolFrame,	encodeProtocolFramePayload,	fromGeneratedSidecarWrittenProtocolFrame,	HostProtocolFrameFactory,	resolveSidecarRequestFramePayload,	toGeneratedProtocolFrame,} from "../src/protocol-frames.js";import { SIDECAR_PROTOCOL_SCHEMA } from "../src/protocol-schema.js"; const textDecoder = new TextDecoder(); const ownership = {	scope: "connection" as const,	connection_id: "conn",}; const generatedAuthOwnership = {	scope: "connection" as const,	connection_id: "conn-1",}; const GENERATED_AUTH_FRAME_HEX =	"00166167656e746f732d6e61746976652d73696465636172080007000000000000000006636f6e6e2d31000e67656e6572617465642d7465737405746f6b656e080001000000"; const hostCallbackRequest = {	frame_type: "sidecar_request" as const,	schema: SIDECAR_PROTOCOL_SCHEMA,	request_id: 7,	ownership,	payload: {		type: "host_callback" as const,		invocation_id: "invocation",		callback_key: "tool",		input: {},		timeout_ms: 1000,	},}; describe("protocol frame conversion", () => {	it("creates host-written request, response, and control frames", () => {		const factory = new HostProtocolFrameFactory(); 		const first = factory.createRequestFrame({			ownership,			payload: {				type: "authenticate",				client_name: "agentos",				auth_token: "token",				protocol_version: 8,				bridge_version: 1,			},		});		const second = factory.createRequestFrame({			ownership,			payload: {				type: "create_layer",			},		}); 		expect(first).toMatchObject({			frame_type: "request",			schema: SIDECAR_PROTOCOL_SCHEMA,			request_id: 1,			ownership,		});		expect(second.request_id).toBe(2);		expect(			factory.createSidecarResponseFrame({				request: hostCallbackRequest,				payload: {					type: "host_callback_result",					invocation_id: "invocation",					result: { ok: true },				},			}),		).toEqual({			frame_type: "sidecar_response",			schema: SIDECAR_PROTOCOL_SCHEMA,			request_id: 7,			ownership,			payload: {				type: "host_callback_result",				invocation_id: "invocation",				result: { ok: true },			},		});		expect(			factory.createControlFrame({ type: "shutdown", reason: "test complete" }),		).toEqual({			frame_type: "control",			schema: SIDECAR_PROTOCOL_SCHEMA,			payload: { type: "shutdown", reason: "test complete" },		});	}); 	it("resolves sidecar request frame handlers", async () => {		await expect(			resolveSidecarRequestFramePayload(hostCallbackRequest, async () => ({				type: "host_callback_result",				invocation_id: "invocation",				result: { ok: true },			})),		).resolves.toEqual({			type: "host_callback_result",			invocation_id: "invocation",			result: { ok: true },		});	}); 	it("returns error payloads for missing or mismatched sidecar handlers", async () => {		await expect(			resolveSidecarRequestFramePayload(hostCallbackRequest, null),		).resolves.toMatchObject({			type: "host_callback_result",			invocation_id: "invocation",			error: "no sidecar request handler registered for host_callback",		}); 		await expect(			resolveSidecarRequestFramePayload(hostCallbackRequest, async () => ({				type: "js_bridge_result",				call_id: "call",				result: {},			})),		).resolves.toMatchObject({			type: "host_callback_result",			invocation_id: "invocation",			error: "sidecar handler returned js_bridge_result for host_callback",		});	}); 	it("maps host-written request frames to generated protocol frames", () => {		expect(			toGeneratedProtocolFrame({				frame_type: "request",				schema: SIDECAR_PROTOCOL_SCHEMA,				request_id: 7,				ownership,				payload: {					type: "authenticate",					client_name: "agentos",					auth_token: "token",					protocol_version: 8,					bridge_version: 1,				},			}),		).toMatchObject({			tag: "RequestFrame",			val: {				requestId: 7n,				payload: {					tag: "AuthenticateRequest",				},			},		});	}); 	it("encodes host-written frames as BARE protocol bytes", () => {		const encoded = encodeBareProtocolFrame({			frame_type: "sidecar_response",			schema: SIDECAR_PROTOCOL_SCHEMA,			request_id: 8,			ownership,			payload: {				type: "host_callback_result",				invocation_id: "invocation",				result: { ok: true },			},		}); 		expect(protocol.decodeProtocolFrame(new Uint8Array(encoded)).tag).toBe(			"SidecarResponseFrame",		); 		const control = encodeBareProtocolFrame({			frame_type: "control",			schema: SIDECAR_PROTOCOL_SCHEMA,			payload: { type: "shutdown", reason: "test complete" },		});		expect(protocol.decodeProtocolFrame(new Uint8Array(control))).toMatchObject(			{				tag: "ControlFrame",				val: {					payload: {						tag: "ShutdownControl",						val: { reason: "test complete" },					},				},			},		);	}); 	it("matches native generated auth frame BARE bytes", () => {		const encoded = encodeBareProtocolFrame({			frame_type: "request",			schema: SIDECAR_PROTOCOL_SCHEMA,			request_id: 7,			ownership: generatedAuthOwnership,			payload: {				type: "authenticate",				client_name: "generated-test",				auth_token: "token",				protocol_version: SIDECAR_PROTOCOL_SCHEMA.version,				bridge_version: 1,			},		}); 		expect(Buffer.from(encoded).toString("hex")).toBe(GENERATED_AUTH_FRAME_HEX);		expect(protocol.decodeProtocolFrame(new Uint8Array(encoded))).toMatchObject(			{				tag: "RequestFrame",				val: {					requestId: 7n,					payload: { tag: "AuthenticateRequest" },				},			},		);	}); 	it("decodes sidecar-written response frames from generated protocol frames", () => {		expect(			fromGeneratedSidecarWrittenProtocolFrame({				tag: "ResponseFrame",				val: {					schema: SIDECAR_PROTOCOL_SCHEMA,					requestId: 9n,					ownership: {						tag: "ConnectionOwnership",						val: { connectionId: "conn" },					},					payload: {						tag: "VmCreatedResponse",						val: { vmId: "vm" },					},				},			}),		).toEqual({			frame_type: "response",			schema: SIDECAR_PROTOCOL_SCHEMA,			request_id: 9,			ownership,			payload: { type: "vm_created", vm_id: "vm" },		});	}); 	it("decodes sidecar-written event frames from BARE bytes", () => {		const bytes = protocol.encodeProtocolFrame({			tag: "EventFrame",			val: {				schema: SIDECAR_PROTOCOL_SCHEMA,				ownership: {					tag: "ConnectionOwnership",					val: { connectionId: "conn" },				},				payload: {					tag: "StructuredEvent",					val: {						name: "ready",						detail: new Map([["ok", "true"]]),					},				},			},		}); 		expect(decodeBareProtocolFrame(bytes)).toEqual({			frame_type: "event",			schema: SIDECAR_PROTOCOL_SCHEMA,			ownership,			payload: {				type: "structured",				name: "ready",				detail: { ok: "true" },			},		});	}); 	it("encodes and decodes JSON compatibility protocol frames", () => {		const encoded = encodeProtocolFramePayload(			{				frame_type: "event",				schema: SIDECAR_PROTOCOL_SCHEMA,				ownership,				payload: {					type: "process_output",					process_id: "proc",					channel: "stdout",					chunk: new Uint8Array([1, 2, 3]),				},			},			"json",		); 		expect(JSON.parse(textDecoder.decode(encoded)).payload.chunk).toEqual([			1, 2, 3,		]); 		const decoded = decodeProtocolFramePayload(encoded, "json");		if (			decoded.frame_type !== "event" ||			decoded.payload.type !== "process_output"		) {			throw new Error("expected process_output event");		}		expect(decoded.payload.chunk).toBeInstanceOf(Uint8Array);		expect(Array.from(decoded.payload.chunk)).toEqual([1, 2, 3]);	}); 	it("classifies sidecar-written protocol frames for RPC dispatch", () => {		expect(			classifySidecarWrittenProtocolFrame({				frame_type: "response",				schema: SIDECAR_PROTOCOL_SCHEMA,				request_id: 10,				ownership,				payload: { type: "vm_created", vm_id: "vm" },			}),		).toMatchObject({			kind: "response",			requestId: 10,			frame: { frame_type: "response" },		}); 		expect(			classifySidecarWrittenProtocolFrame({				frame_type: "event",				schema: SIDECAR_PROTOCOL_SCHEMA,				ownership,				payload: {					type: "structured",					name: "ready",					detail: {},				},			}),		).toMatchObject({			kind: "event",			frame: { frame_type: "event" },		}); 		expect(			classifySidecarWrittenProtocolFrame({				frame_type: "sidecar_request",				schema: SIDECAR_PROTOCOL_SCHEMA,				request_id: 11,				ownership,				payload: {					type: "host_callback",					invocation_id: "invocation",					callback_key: "tool",					input: { ok: true },					timeout_ms: 1_000,				},			}),		).toMatchObject({			kind: "sidecarRequest",			frame: { frame_type: "sidecar_request" },		});	}); 	it("rejects host-written generated frames on the sidecar-written decode path", () => {		expect(() =>			fromGeneratedSidecarWrittenProtocolFrame({				tag: "RequestFrame",				val: {					schema: SIDECAR_PROTOCOL_SCHEMA,					requestId: 1n,					ownership: {						tag: "ConnectionOwnership",						val: { connectionId: "conn" },					},					payload: {						tag: "CreateLayerRequest",						val: null,					},				},			}),		).toThrow("unsupported BARE protocol frame tag: RequestFrame");	});});