Skip to content

Commit 7959629

Browse files
committed
remove getFinalAssistantMessage from nodejs test harness
1 parent d46feaa commit 7959629

2 files changed

Lines changed: 20 additions & 87 deletions

File tree

nodejs/test/e2e/harness/sdkTestHelper.ts

Lines changed: 1 addition & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2,78 +2,7 @@
22
* Copyright (c) Microsoft Corporation. All rights reserved.
33
*--------------------------------------------------------------------------------------------*/
44

5-
import { AssistantMessageEvent, CopilotSession, SessionEvent } from "../../../src";
6-
7-
export async function getFinalAssistantMessage(
8-
session: CopilotSession
9-
): Promise<AssistantMessageEvent> {
10-
// We don't know whether the answer has already arrived or not, so race both possibilities
11-
return new Promise<AssistantMessageEvent>(async (resolve, reject) => {
12-
getFutureFinalResponse(session).then(resolve).catch(reject);
13-
getExistingFinalResponse(session)
14-
.then((msg) => {
15-
if (msg) {
16-
resolve(msg);
17-
}
18-
})
19-
.catch(reject);
20-
});
21-
}
22-
23-
function getExistingFinalResponse(
24-
session: CopilotSession
25-
): Promise<AssistantMessageEvent | undefined> {
26-
return new Promise<AssistantMessageEvent | undefined>(async (resolve, reject) => {
27-
const messages = await session.getMessages();
28-
const finalUserMessageIndex = messages.findLastIndex((m) => m.type === "user.message");
29-
const currentTurnMessages =
30-
finalUserMessageIndex < 0 ? messages : messages.slice(finalUserMessageIndex);
31-
32-
const currentTurnError = currentTurnMessages.find((m) => m.type === "session.error");
33-
if (currentTurnError) {
34-
const error = new Error(currentTurnError.data.message);
35-
error.stack = currentTurnError.data.stack;
36-
reject(error);
37-
return;
38-
}
39-
40-
const sessionIdleMessageIndex = currentTurnMessages.findIndex(
41-
(m) => m.type === "session.idle"
42-
);
43-
if (sessionIdleMessageIndex !== -1) {
44-
const lastAssistantMessage = currentTurnMessages
45-
.slice(0, sessionIdleMessageIndex)
46-
.findLast((m) => m.type === "assistant.message");
47-
resolve(lastAssistantMessage as AssistantMessageEvent | undefined);
48-
return;
49-
}
50-
51-
resolve(undefined);
52-
});
53-
}
54-
55-
function getFutureFinalResponse(session: CopilotSession): Promise<AssistantMessageEvent> {
56-
return new Promise<AssistantMessageEvent>((resolve, reject) => {
57-
let finalAssistantMessage: AssistantMessageEvent | undefined;
58-
session.on((event) => {
59-
if (event.type === "assistant.message") {
60-
finalAssistantMessage = event;
61-
} else if (event.type === "session.idle") {
62-
if (!finalAssistantMessage) {
63-
reject(
64-
new Error("Received session.idle without a preceding assistant.message")
65-
);
66-
} else {
67-
resolve(finalAssistantMessage);
68-
}
69-
} else if (event.type === "session.error") {
70-
const error = new Error(event.data.message);
71-
error.stack = event.data.stack;
72-
reject(error);
73-
}
74-
});
75-
});
76-
}
5+
import { CopilotSession, SessionEvent } from "../../../src";
776

787
export async function retry(
798
message: string,

nodejs/test/e2e/session.test.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { describe, expect, it, onTestFinished } from "vitest";
22
import { ParsedHttpExchange } from "../../../test/harness/replayingCapiProxy.js";
3-
import { CopilotClient } from "../../src/index.js";
3+
import { CopilotClient, SessionEvent } from "../../src/index.js";
44
import { CLI_PATH, createSdkTestContext } from "./harness/sdkTestContext.js";
5-
import { getFinalAssistantMessage, getNextEventOfType } from "./harness/sdkTestHelper.js";
5+
import { getNextEventOfType } from "./harness/sdkTestHelper.js";
66

77
describe("Sessions", async () => {
88
const { copilotClient: client, openAiEndpoint, homeDir, env } = await createSdkTestContext();
@@ -167,7 +167,7 @@ describe("Sessions", async () => {
167167
expect(session2.sessionId).toBe(sessionId);
168168

169169
// TODO: There's an inconsistency here. When resuming with a new client, we don't see
170-
// the session.idle message in the history, which means we can't use getFinalAssistantMessage.
170+
// the session.idle message in the history, so we can't easily identify when a turn completed.
171171

172172
const messages = await session2.getMessages();
173173
expect(messages).toContainEqual(expect.objectContaining({ type: "user.message" }));
@@ -328,9 +328,8 @@ describe("Sessions", async () => {
328328
expect(session.sessionId).toMatch(/^[a-f0-9-]+$/);
329329

330330
// Session should work normally with custom config dir
331-
await session.send({ prompt: "What is 1+1?" });
332-
const assistantMessage = await getFinalAssistantMessage(session);
333-
expect(assistantMessage.data.content).toContain("2");
331+
const assistantMessage = await session.sendAndWait({ prompt: "What is 1+1?" });
332+
expect(assistantMessage?.data.content).toContain("2");
334333
});
335334
});
336335

@@ -348,23 +347,28 @@ describe("Send Blocking Behavior", async () => {
348347
it("send returns immediately while events stream in background", async () => {
349348
const session = await client.createSession();
350349

351-
const events: string[] = [];
352-
session.on((event) => {
353-
events.push(event.type);
354-
});
350+
const events: Array<SessionEvent> = [];
351+
session.on((event) => events.push(event));
352+
353+
// Set up promise to wait for idle BEFORE sending
354+
const idlePromise = getNextEventOfType(session, "session.idle");
355355

356356
// Use a slow command so we can verify send() returns before completion
357357
await session.send({ prompt: "Run 'sleep 2 && echo done'" });
358358

359359
// send() should return before turn completes (no session.idle yet)
360-
expect(events).not.toContain("session.idle");
360+
expect(events.some((e) => e.type === "session.idle")).toBe(false);
361361

362362
// Wait for turn to complete
363-
const message = await getFinalAssistantMessage(session);
363+
await idlePromise;
364364

365-
expect(message.data.content).toContain("done");
366-
expect(events).toContain("session.idle");
367-
expect(events).toContain("assistant.message");
365+
// Find the last assistant message from collected events
366+
const assistantMessages = events.filter((e) => e.type === "assistant.message");
367+
const message = assistantMessages[assistantMessages.length - 1];
368+
369+
expect(message.data?.content).toContain("done");
370+
expect(events.some((e) => e.type === "session.idle")).toBe(true);
371+
expect(events.some((e) => e.type === "assistant.message")).toBe(true);
368372
});
369373

370374
it("sendAndWait blocks until session.idle and returns final assistant message", async () => {

0 commit comments

Comments
 (0)