-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathopenai.ts
109 lines (92 loc) · 3.28 KB
/
openai.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
import { OpenAIApi, CreateCompletionRequest, CreateChatCompletionRequest } from "openai";
import { AxiosRequestConfig } from "axios";
import { AxiomClient, BatchedAxiomClient, ImmediateAxiomClient } from './shared';
export interface WithAxiomOptions {
token?: string;
dataset?: string;
excludePromptOrMessages?: boolean;
excludeChoices?: boolean;
sendType?: "batch"|"immediate";
}
export function withAxiom(openai: OpenAIApi, opts?: WithAxiomOptions): { openai: OpenAIApi, flush: Function } {
const dataset = opts?.dataset || process.env.AXIOM_DATASET;
let axiom: AxiomClient;
if (opts?.sendType === "immediate") {
axiom = new ImmediateAxiomClient(opts?.token, dataset!);
} else {
axiom = new BatchedAxiomClient(opts?.token, dataset!);
}
const createCompletion = openai.createCompletion;
openai.createCompletion = async (request: CreateCompletionRequest, options?: AxiosRequestConfig<any>) => {
const start = new Date();
const transformedRequest = structuredClone(request) as any;
if (opts?.excludePromptOrMessages) {
delete transformedRequest.prompt;
}
let response = null;
let duration = null;
try {
response = await createCompletion.apply(openai, [request, options]);
duration = new Date().getTime() - start.getTime();
} catch (e: any) {
await axiom.ingestEvents({
_time: start.toISOString(),
type: "completion",
duration_ms: duration,
request: transformedRequest,
error: e.message,
})
throw e;
}
const transformedResponse = structuredClone(response.data) as any;
if (opts?.excludeChoices) {
delete transformedResponse.choices;
}
transformedResponse.created = new Date(transformedResponse.created * 1000).toISOString();
await axiom.ingestEvents({
_time: start.toISOString(),
type: "completion",
duration_ms: duration,
request: transformedRequest,
response: transformedResponse
});
return response;
}
const createChatCompletion = openai.createChatCompletion;
openai.createChatCompletion = async (request: CreateChatCompletionRequest, options?: AxiosRequestConfig) => {
const start = new Date();
const transformedRequest = structuredClone(request) as any;
if (opts?.excludePromptOrMessages) {
delete transformedRequest.messages;
}
let response = null;
let duration = null;
try {
response = await createChatCompletion.apply(openai, [request, options]);
duration = new Date().getTime() - start.getTime();
} catch (e: any) {
await axiom.ingestEvents({
_time: start.toISOString(),
type: "chatCompletion",
duration_ms: duration,
request: transformedRequest,
error: e.message,
})
throw e;
}
const transformedResponse = structuredClone(response.data) as any;
if (opts?.excludeChoices) {
delete transformedResponse.choices;
}
transformedResponse.created = new Date(transformedResponse.created * 1000).toISOString();
await axiom.ingestEvents({
_time: start.toISOString(),
type: "chatCompletion",
duration_ms: duration,
request: transformedRequest,
response: transformedResponse
});
return response;
}
return { openai, flush: axiom.flush.bind(axiom) };
}