forked from github/copilot-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhooks_extended.test.ts
More file actions
125 lines (102 loc) · 4.53 KB
/
Copy pathhooks_extended.test.ts
File metadata and controls
125 lines (102 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/
import { describe, expect, it } from "vitest";
import { approveAll } from "../../src/index.js";
import type {
ErrorOccurredHookInput,
SessionEndHookInput,
SessionStartHookInput,
UserPromptSubmittedHookInput,
} from "../../src/types.js";
import { createSdkTestContext } from "./harness/sdkTestContext.js";
describe("Extended session hooks", async () => {
const { copilotClient: client } = await createSdkTestContext();
it("should invoke onSessionStart hook on new session", async () => {
const sessionStartInputs: SessionStartHookInput[] = [];
const session = await client.createSession({
onPermissionRequest: approveAll,
hooks: {
onSessionStart: async (input, invocation) => {
sessionStartInputs.push(input);
expect(invocation.sessionId).toBe(session.sessionId);
},
},
});
await session.sendAndWait({
prompt: "Say hi",
});
expect(sessionStartInputs.length).toBeGreaterThan(0);
expect(sessionStartInputs[0].source).toBe("new");
expect(sessionStartInputs[0].timestamp).toBeGreaterThan(0);
expect(sessionStartInputs[0].cwd).toBeDefined();
await session.destroy();
});
it("should invoke onUserPromptSubmitted hook when sending a message", async () => {
const userPromptInputs: UserPromptSubmittedHookInput[] = [];
const session = await client.createSession({
onPermissionRequest: approveAll,
hooks: {
onUserPromptSubmitted: async (input, invocation) => {
userPromptInputs.push(input);
expect(invocation.sessionId).toBe(session.sessionId);
},
},
});
await session.sendAndWait({
prompt: "Say hello",
});
expect(userPromptInputs.length).toBeGreaterThan(0);
expect(userPromptInputs[0].prompt).toContain("Say hello");
expect(userPromptInputs[0].timestamp).toBeGreaterThan(0);
expect(userPromptInputs[0].cwd).toBeDefined();
await session.destroy();
});
it("should invoke onSessionEnd hook when session is destroyed", async () => {
const sessionEndInputs: SessionEndHookInput[] = [];
const session = await client.createSession({
onPermissionRequest: approveAll,
hooks: {
onSessionEnd: async (input, invocation) => {
sessionEndInputs.push(input);
expect(invocation.sessionId).toBe(session.sessionId);
},
},
});
await session.sendAndWait({
prompt: "Say hi",
});
await session.destroy();
// Wait briefly for async hook
await new Promise((resolve) => setTimeout(resolve, 100));
expect(sessionEndInputs.length).toBeGreaterThan(0);
});
it("should invoke onErrorOccurred hook when error occurs", async () => {
const errorInputs: ErrorOccurredHookInput[] = [];
const session = await client.createSession({
onPermissionRequest: approveAll,
hooks: {
onErrorOccurred: async (input, invocation) => {
errorInputs.push(input);
expect(invocation.sessionId).toBe(session.sessionId);
expect(input.timestamp).toBeGreaterThan(0);
expect(input.cwd).toBeDefined();
expect(input.error).toBeDefined();
expect(["model_call", "tool_execution", "system", "user_input"]).toContain(
input.errorContext
);
expect(typeof input.recoverable).toBe("boolean");
},
},
});
await session.sendAndWait({
prompt: "Say hi",
});
// onErrorOccurred is dispatched by the runtime for actual errors (model failures, system errors).
// In a normal session it may not fire. Verify the hook is properly wired by checking
// that the session works correctly with the hook registered.
// If the hook did fire, the assertions inside it would have run.
expect(session.sessionId).toBeDefined();
await session.destroy();
});
});