Files
paseo/packages/server/src/shared/messages.stream-parsing.test.ts
T
Mohamed Boudra 65f8823e4e Merge remote-tracking branch 'origin/main' into merge/main-into-dev
# Conflicts:
#	CLAUDE.md
#	nix/package.nix
#	packages/app/src/components/combined-model-selector.tsx
#	packages/app/src/hooks/use-sidebar-workspaces-list.ts
#	packages/app/src/screens/workspace/workspace-screen.tsx
#	packages/app/src/stores/session-store.test.ts
#	packages/server/src/client/daemon-client.ts
#	packages/server/src/server/agent/agent-manager.ts
#	packages/server/src/server/session.ts
#	packages/server/src/server/session.workspace-git-watch.test.ts
#	packages/server/src/server/session.workspaces.test.ts
#	packages/server/src/shared/messages.ts
2026-04-08 11:38:17 +07:00

375 lines
11 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
AgentStreamMessageSchema,
FetchAgentTimelineRequestMessageSchema,
FetchAgentTimelineResponseMessageSchema,
SessionInboundMessageSchema,
SessionOutboundMessageSchema,
WSOutboundMessageSchema,
} from "./messages.js";
describe("shared messages stream parsing", () => {
it("parses representative fetch_agent_timeline_response payload", () => {
const parsed = FetchAgentTimelineResponseMessageSchema.parse({
type: "fetch_agent_timeline_response",
payload: {
requestId: "req-1",
agentId: "agent_live",
agent: null,
direction: "tail",
startSeq: 1,
endSeq: 2,
hasOlder: false,
hasNewer: false,
entries: [
{
provider: "codex",
item: { type: "assistant_message", text: "hello" },
timestamp: "2026-02-08T20:10:00.000Z",
seq: 2,
},
],
error: null,
},
});
expect(parsed.payload.entries).toHaveLength(1);
expect(parsed.payload.entries[0]?.item.type).toBe("assistant_message");
});
it("parses legacy fetch timeline request baggage at the parser boundary", () => {
const parsed = FetchAgentTimelineRequestMessageSchema.parse({
type: "fetch_agent_timeline_request",
agentId: "agent_live",
requestId: "req-legacy",
direction: "after",
cursor: {
seq: 12,
epoch: "legacy-epoch",
},
projection: "canonical",
});
expect(parsed.cursor?.epoch).toBe("legacy-epoch");
expect(parsed.projection).toBe("canonical");
});
it("parses legacy fetch timeline response baggage at the parser boundary", () => {
const parsed = FetchAgentTimelineResponseMessageSchema.parse({
type: "fetch_agent_timeline_response",
payload: {
requestId: "req-1",
agentId: "agent_live",
agent: null,
direction: "tail",
reset: false,
startCursor: { seq: 1, epoch: "legacy-epoch" },
endCursor: { seq: 2, epoch: "legacy-epoch" },
projection: "canonical",
entries: [
{
provider: "codex",
item: { type: "assistant_message", text: "hello" },
timestamp: "2026-02-08T20:10:00.000Z",
seqStart: 1,
seqEnd: 2,
sourceSeqRanges: [{ startSeq: 1, endSeq: 2 }],
collapsed: ["assistant_merge"],
},
],
error: null,
},
});
expect(parsed.payload.startSeq).toBe(1);
expect(parsed.payload.endSeq).toBe(2);
expect(parsed.payload.projection).toBe("canonical");
expect(parsed.payload.entries[0]?.seq).toBe(2);
});
it("parses explicit shutdown and restart lifecycle request payloads as distinct message types", () => {
const shutdownParsed = SessionInboundMessageSchema.safeParse({
type: "shutdown_server_request",
requestId: "req-shutdown-1",
});
expect(shutdownParsed.success).toBe(true);
const restartParsed = SessionInboundMessageSchema.safeParse({
type: "restart_server_request",
requestId: "req-restart-1",
reason: "settings_changed",
});
expect(restartParsed.success).toBe(true);
expect(shutdownParsed.success && shutdownParsed.data.type).toBe("shutdown_server_request");
expect(restartParsed.success && restartParsed.data.type).toBe("restart_server_request");
});
it("parses representative agent_stream tool_call event", () => {
const parsed = AgentStreamMessageSchema.parse({
type: "agent_stream",
payload: {
agentId: "agent_live",
timestamp: "2026-02-08T20:10:00.000Z",
seq: 12,
event: {
type: "timeline",
provider: "claude",
item: {
type: "tool_call",
callId: "call_live",
name: "shell",
status: "running",
detail: {
type: "shell",
command: "ls",
},
error: null,
},
},
},
});
expect(parsed.payload.event.type).toBe("timeline");
if (parsed.payload.event.type === "timeline") {
expect(parsed.payload.event.item.type).toBe("tool_call");
if (parsed.payload.event.item.type === "tool_call") {
expect(parsed.payload.event.item.status).toBe("running");
}
}
});
it("parses legacy agent_stream baggage at the parser boundary", () => {
const parsed = AgentStreamMessageSchema.parse({
type: "agent_stream",
payload: {
agentId: "agent_live",
timestamp: "2026-02-08T20:10:00.000Z",
epoch: "legacy-epoch",
event: {
type: "timeline",
provider: "claude",
item: {
type: "assistant_message",
text: "hello",
},
},
},
});
expect(parsed.payload.epoch).toBe("legacy-epoch");
});
it("parses representative sub_agent tool_call event", () => {
const parsed = AgentStreamMessageSchema.parse({
type: "agent_stream",
payload: {
agentId: "agent_live",
timestamp: "2026-02-08T20:10:00.000Z",
event: {
type: "timeline",
provider: "claude",
item: {
type: "tool_call",
callId: "call_sub_agent_live",
name: "Task",
status: "running",
detail: {
type: "sub_agent",
subAgentType: "Explore",
description: "Inspect repository structure",
log: "[Read] README.md",
actions: [
{
index: 1,
toolName: "Read",
summary: "README.md",
},
],
},
error: null,
},
},
},
});
expect(parsed.payload.event.type).toBe("timeline");
if (parsed.payload.event.type === "timeline") {
expect(parsed.payload.event.item.type).toBe("tool_call");
if (parsed.payload.event.item.type === "tool_call") {
expect(parsed.payload.event.item.detail.type).toBe("sub_agent");
}
}
});
it("parses optional permission actions and selectedActionId compatibly", () => {
const requestParsed = AgentStreamMessageSchema.parse({
type: "agent_stream",
payload: {
agentId: "agent_live",
timestamp: "2026-02-08T20:10:00.000Z",
event: {
type: "permission_requested",
provider: "codex",
request: {
id: "perm-1",
provider: "codex",
name: "CodexPlanApproval",
kind: "plan",
input: { plan: "- step 1" },
actions: [
{
id: "reject",
label: "Reject",
behavior: "deny",
variant: "danger",
intent: "dismiss",
},
{
id: "implement",
label: "Implement",
behavior: "allow",
variant: "primary",
intent: "implement",
},
],
},
},
},
});
expect(requestParsed.payload.event.type).toBe("permission_requested");
if (requestParsed.payload.event.type === "permission_requested") {
expect(requestParsed.payload.event.request.actions).toHaveLength(2);
expect(requestParsed.payload.event.request.actions?.[1]?.label).toBe("Implement");
}
const resolutionParsed = AgentStreamMessageSchema.parse({
type: "agent_stream",
payload: {
agentId: "agent_live",
timestamp: "2026-02-08T20:10:01.000Z",
event: {
type: "permission_resolved",
provider: "claude",
requestId: "perm-1",
resolution: {
behavior: "allow",
selectedActionId: "implement_resume",
},
},
},
});
expect(resolutionParsed.payload.event.type).toBe("permission_resolved");
if (resolutionParsed.payload.event.type === "permission_resolved") {
expect(resolutionParsed.payload.event.resolution).toEqual({
behavior: "allow",
selectedActionId: "implement_resume",
});
}
});
it("rejects removed initialize_agent_request inbound payload", () => {
const parsed = SessionInboundMessageSchema.safeParse({
type: "initialize_agent_request",
agentId: "agent-legacy",
requestId: "req-legacy-1",
});
expect(parsed.success).toBe(false);
});
it("rejects removed initialize_agent_request outbound payload", () => {
const parsed = SessionOutboundMessageSchema.safeParse({
type: "initialize_agent_request",
payload: {
requestId: "req-legacy-1",
agentId: "agent-legacy",
agentStatus: "running",
timelineSize: 12,
},
});
expect(parsed.success).toBe(false);
});
it("parses directory suggestions request and response payloads", () => {
const requestParsed = SessionInboundMessageSchema.safeParse({
type: "directory_suggestions_request",
query: "proj",
cwd: "/tmp/project",
includeFiles: true,
includeDirectories: true,
limit: 20,
requestId: "req-dir-1",
});
expect(requestParsed.success).toBe(true);
const responseParsed = SessionOutboundMessageSchema.safeParse({
type: "directory_suggestions_response",
payload: {
directories: ["/Users/test/projects/paseo"],
entries: [{ path: "/Users/test/projects/paseo", kind: "directory" }],
error: null,
requestId: "req-dir-1",
},
});
expect(responseParsed.success).toBe(true);
});
it("rejects websocket envelope for removed agent_stream_snapshot message type", () => {
const fixture = {
type: "agent_stream_snapshot",
payload: {
agentId: "agent-legacy",
events: [],
},
};
const wrapped = WSOutboundMessageSchema.safeParse({
type: "session",
message: fixture,
});
expect(wrapped.success).toBe(false);
});
it("rejects removed legacy git diff request messages", () => {
const gitDiffParsed = SessionInboundMessageSchema.safeParse({
type: "git_diff_request",
agentId: "agent-1",
requestId: "req-1",
});
expect(gitDiffParsed.success).toBe(false);
const highlightedParsed = SessionInboundMessageSchema.safeParse({
type: "highlighted_diff_request",
agentId: "agent-1",
requestId: "req-2",
});
expect(highlightedParsed.success).toBe(false);
});
it("rejects removed legacy git diff response messages", () => {
const gitDiffParsed = SessionOutboundMessageSchema.safeParse({
type: "git_diff_response",
payload: {
agentId: "agent-1",
diff: "",
error: null,
requestId: "req-1",
},
});
expect(gitDiffParsed.success).toBe(false);
const highlightedParsed = SessionOutboundMessageSchema.safeParse({
type: "highlighted_diff_response",
payload: {
agentId: "agent-1",
files: [],
error: null,
requestId: "req-2",
},
});
expect(highlightedParsed.success).toBe(false);
});
});