generated from ellisonleao/nvim-plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmock.ts
116 lines (105 loc) · 2.64 KB
/
mock.ts
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
import { type ToolRequest } from "../tools/toolManager.ts";
import { type Result } from "../utils/result.ts";
import { Defer, pollUntil } from "../utils/async.ts";
import {
setClient,
type Provider,
type ProviderMessage,
type StopReason,
type Usage,
} from "./provider.ts";
type MockRequest = {
messages: Array<ProviderMessage>;
onText: (text: string) => void;
onError: (error: Error) => void;
defer: Defer<{
toolRequests: Result<ToolRequest, { rawRequest: unknown }>[];
stopReason: StopReason;
usage: Usage;
}>;
};
export class MockProvider implements Provider {
public requests: MockRequest[] = [];
abort() {
if (this.requests.length) {
const lastRequest = this.requests[this.requests.length - 1];
if (!lastRequest.defer.resolved) {
lastRequest.defer.resolve({
toolRequests: [],
stopReason: "end_turn",
usage: {
inputTokens: 0,
outputTokens: 0,
},
});
}
}
}
createStreamParameters(messages: Array<ProviderMessage>): unknown {
return messages;
}
// eslint-disable-next-line @typescript-eslint/require-await
async countTokens(messages: Array<ProviderMessage>): Promise<number> {
return messages.length;
}
async sendMessage(
messages: Array<ProviderMessage>,
onText: (text: string) => void,
onError: (error: Error) => void,
): Promise<{
toolRequests: Result<ToolRequest, { rawRequest: unknown }>[];
stopReason: StopReason;
usage: Usage;
}> {
const request: MockRequest = {
messages,
onText,
onError,
defer: new Defer(),
};
this.requests.push(request);
return request.defer.promise;
}
async awaitPendingRequest() {
return pollUntil(() => {
const lastRequest = this.requests[this.requests.length - 1];
if (lastRequest && !lastRequest.defer.resolved) {
return lastRequest;
}
throw new Error(`no pending requests`);
});
}
async respond({
text,
toolRequests,
stopReason,
}: {
text?: string;
toolRequests: Result<ToolRequest, { rawRequest: unknown }>[];
stopReason: StopReason;
}) {
const lastRequest = await this.awaitPendingRequest();
if (text) {
lastRequest.onText(text);
}
lastRequest.defer.resolve({
toolRequests,
stopReason,
usage: {
inputTokens: 0,
outputTokens: 0,
},
});
}
}
export async function withMockClient(
fn: (mock: MockProvider) => Promise<void>,
) {
const mock = new MockProvider();
setClient("anthropic", mock);
try {
await fn(mock);
} finally {
setClient("anthropic", undefined);
}
}