53c8d33758
- Added multi-session support to ACP mode enabling session forking, resumption, and closure operations. - Added session model state reporting and unstable_setSessionModel RPC command for direct model configuration. - Added turn-level usage tracking and stable message ID tracking for assistant chunks in ACP responses. - Added Settings.cloneForCwd() method and ExtensionRunner.getFlagValues() for configuration isolation across sessions. - Fixed ACP session cleanup to properly cancel in-flight prompts and dispose resources on disconnect. - Refactored AcpAgent to manage multiple concurrent sessions with per-session lifecycle instead of single session.
65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
import { describe, expect, it } from "bun:test";
|
|
import { mapAgentSessionEventToAcpSessionUpdates } from "../src/modes/acp/acp-event-mapper";
|
|
import type { AgentSessionEvent } from "../src/session/agent-session";
|
|
|
|
function makeAssistantMessage(text: string) {
|
|
return {
|
|
role: "assistant" as const,
|
|
content: [{ type: "text" as const, text }],
|
|
api: "anthropic-messages" as const,
|
|
provider: "anthropic" as const,
|
|
model: "claude-sonnet-4-20250514",
|
|
usage: {
|
|
input: 10,
|
|
output: 5,
|
|
cacheRead: 0,
|
|
cacheWrite: 0,
|
|
totalTokens: 15,
|
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
},
|
|
stopReason: "stop" as const,
|
|
timestamp: Date.now(),
|
|
};
|
|
}
|
|
|
|
function getChunkMessageId(event: { update: object }): string | undefined {
|
|
const update = event.update as { messageId?: string | null };
|
|
return typeof update.messageId === "string" ? update.messageId : undefined;
|
|
}
|
|
|
|
describe("ACP event mapper", () => {
|
|
it("attaches a stable messageId to live assistant chunks", () => {
|
|
const assistantMessage = makeAssistantMessage("chunk");
|
|
const getMessageId = (message: unknown): string | undefined =>
|
|
message === assistantMessage ? "a80f1ff7-4f0a-4e6b-9f09-c94857b62a4a" : undefined;
|
|
|
|
const textUpdates = mapAgentSessionEventToAcpSessionUpdates(
|
|
{
|
|
type: "message_update",
|
|
message: assistantMessage,
|
|
assistantMessageEvent: { type: "text_delta", delta: "chunk" },
|
|
} as AgentSessionEvent,
|
|
"session-1",
|
|
{ getMessageId },
|
|
);
|
|
const thoughtUpdates = mapAgentSessionEventToAcpSessionUpdates(
|
|
{
|
|
type: "message_update",
|
|
message: assistantMessage,
|
|
assistantMessageEvent: { type: "thinking_delta", delta: "plan" },
|
|
} as AgentSessionEvent,
|
|
"session-1",
|
|
{ getMessageId },
|
|
);
|
|
|
|
expect(textUpdates).toHaveLength(1);
|
|
expect(thoughtUpdates).toHaveLength(1);
|
|
expect(textUpdates[0] ? getChunkMessageId(textUpdates[0]) : undefined).toBe(
|
|
"a80f1ff7-4f0a-4e6b-9f09-c94857b62a4a",
|
|
);
|
|
expect(thoughtUpdates[0] ? getChunkMessageId(thoughtUpdates[0]) : undefined).toBe(
|
|
"a80f1ff7-4f0a-4e6b-9f09-c94857b62a4a",
|
|
);
|
|
});
|
|
});
|