openlayer 0.0.1-alpha.0 → 0.0.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -6
- package/_shims/web-runtime.js +1 -1
- package/_shims/web-runtime.js.map +1 -1
- package/_shims/web-runtime.mjs +1 -1
- package/_shims/web-runtime.mjs.map +1 -1
- package/lib/core/cli.d.ts +15 -1
- package/lib/core/cli.d.ts.map +1 -1
- package/lib/core/cli.js +3 -4
- package/lib/core/cli.js.map +1 -1
- package/lib/core/cli.mjs +4 -3
- package/lib/core/cli.mjs.map +1 -1
- package/lib/core/openai-monitor.d.ts +54 -0
- package/lib/core/openai-monitor.d.ts.map +1 -0
- package/lib/core/openai-monitor.js +376 -0
- package/lib/core/openai-monitor.js.map +1 -0
- package/lib/core/openai-monitor.mjs +371 -0
- package/lib/core/openai-monitor.mjs.map +1 -0
- package/package.json +2 -2
- package/src/_shims/web-runtime.ts +1 -1
- package/src/lib/core/cli.ts +21 -5
- package/src/lib/core/index.d.ts +2 -0
- package/src/lib/core/openai-monitor.ts +470 -0
- package/src/lib/index.d.ts +1 -0
- package/src/version.ts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.js.map +1 -1
- package/version.mjs +1 -1
- package/version.mjs.map +1 -1
- package/lib/core/index.d.ts +0 -237
- package/lib/core/index.d.ts.map +0 -1
- package/lib/core/index.js +0 -635
- package/lib/core/index.js.map +0 -1
- package/lib/core/index.mjs +0 -627
- package/lib/core/index.mjs.map +0 -1
- package/lib/core/run.d.ts +0 -14
- package/lib/core/run.d.ts.map +0 -1
- package/lib/core/run.js +0 -3
- package/lib/core/run.js.map +0 -1
- package/lib/core/run.mjs +0 -2
- package/lib/core/run.mjs.map +0 -1
- package/src/lib/core/index.ts +0 -1067
- package/src/lib/core/run.ts +0 -14
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import { RequestOptions } from 'openai/core';
|
|
3
|
+
import {
|
|
4
|
+
ChatCompletion,
|
|
5
|
+
ChatCompletionChunk,
|
|
6
|
+
ChatCompletionCreateParams,
|
|
7
|
+
ChatCompletionMessageParam,
|
|
8
|
+
Completion,
|
|
9
|
+
CompletionCreateParams,
|
|
10
|
+
} from 'openai/resources';
|
|
11
|
+
import { Run } from 'openai/resources/beta/threads/runs/runs';
|
|
12
|
+
import { Threads } from 'openai/resources/beta/threads/threads';
|
|
13
|
+
import { Stream } from 'openai/streaming';
|
|
14
|
+
import Openlayer from '../../index';
|
|
15
|
+
|
|
16
|
+
type OpenAIMonitorConstructorProps = {
|
|
17
|
+
openAiApiKey: string;
|
|
18
|
+
openlayerClient: Openlayer;
|
|
19
|
+
openlayerInferencePipelineId: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type Pricing = {
|
|
23
|
+
input: number;
|
|
24
|
+
output: number;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const OpenAIPricing: { [key: string]: Pricing } = {
|
|
28
|
+
'babbage-002': {
|
|
29
|
+
input: 0.0004,
|
|
30
|
+
output: 0.0004,
|
|
31
|
+
},
|
|
32
|
+
'davinci-002': {
|
|
33
|
+
input: 0.002,
|
|
34
|
+
output: 0.002,
|
|
35
|
+
},
|
|
36
|
+
'gpt-3.5-turbo': {
|
|
37
|
+
input: 0.0005,
|
|
38
|
+
output: 0.0015,
|
|
39
|
+
},
|
|
40
|
+
'gpt-3.5-turbo-0125': {
|
|
41
|
+
input: 0.0005,
|
|
42
|
+
output: 0.0015,
|
|
43
|
+
},
|
|
44
|
+
'gpt-3.5-turbo-0301': {
|
|
45
|
+
input: 0.0015,
|
|
46
|
+
output: 0.002,
|
|
47
|
+
},
|
|
48
|
+
'gpt-3.5-turbo-0613': {
|
|
49
|
+
input: 0.0015,
|
|
50
|
+
output: 0.002,
|
|
51
|
+
},
|
|
52
|
+
'gpt-3.5-turbo-1106': {
|
|
53
|
+
input: 0.001,
|
|
54
|
+
output: 0.002,
|
|
55
|
+
},
|
|
56
|
+
'gpt-3.5-turbo-16k-0613': {
|
|
57
|
+
input: 0.003,
|
|
58
|
+
output: 0.004,
|
|
59
|
+
},
|
|
60
|
+
'gpt-3.5-turbo-instruct': {
|
|
61
|
+
input: 0.0015,
|
|
62
|
+
output: 0.002,
|
|
63
|
+
},
|
|
64
|
+
'gpt-4': {
|
|
65
|
+
input: 0.03,
|
|
66
|
+
output: 0.06,
|
|
67
|
+
},
|
|
68
|
+
'gpt-4-0125-preview': {
|
|
69
|
+
input: 0.01,
|
|
70
|
+
output: 0.03,
|
|
71
|
+
},
|
|
72
|
+
'gpt-4-0314': {
|
|
73
|
+
input: 0.03,
|
|
74
|
+
output: 0.06,
|
|
75
|
+
},
|
|
76
|
+
'gpt-4-0613': {
|
|
77
|
+
input: 0.03,
|
|
78
|
+
output: 0.06,
|
|
79
|
+
},
|
|
80
|
+
'gpt-4-1106-preview': {
|
|
81
|
+
input: 0.01,
|
|
82
|
+
output: 0.03,
|
|
83
|
+
},
|
|
84
|
+
'gpt-4-1106-vision-preview': {
|
|
85
|
+
input: 0.01,
|
|
86
|
+
output: 0.03,
|
|
87
|
+
},
|
|
88
|
+
'gpt-4-32k': {
|
|
89
|
+
input: 0.06,
|
|
90
|
+
output: 0.12,
|
|
91
|
+
},
|
|
92
|
+
'gpt-4-32k-0314': {
|
|
93
|
+
input: 0.06,
|
|
94
|
+
output: 0.12,
|
|
95
|
+
},
|
|
96
|
+
'gpt-4-32k-0613': {
|
|
97
|
+
input: 0.03,
|
|
98
|
+
output: 0.06,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
class OpenAIMonitor {
|
|
103
|
+
private openlayerClient: Openlayer;
|
|
104
|
+
|
|
105
|
+
private openAIClient: OpenAI;
|
|
106
|
+
|
|
107
|
+
private openlayerInferencePipelineId: string;
|
|
108
|
+
|
|
109
|
+
private defaultConfig: Openlayer.InferencePipelines.Data.DataStreamParams.LlmData = {
|
|
110
|
+
costColumnName: 'cost',
|
|
111
|
+
inferenceIdColumnName: 'id',
|
|
112
|
+
latencyColumnName: 'latency',
|
|
113
|
+
numOfTokenColumnName: 'tokens',
|
|
114
|
+
outputColumnName: 'output',
|
|
115
|
+
timestampColumnName: 'timestamp',
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Constructs an OpenAIMonitor instance.
|
|
120
|
+
* @param {OpenAIMonitorConstructorProps} props - The configuration properties for the OpenAI and Openlayer clients.
|
|
121
|
+
*/
|
|
122
|
+
constructor({
|
|
123
|
+
openAiApiKey,
|
|
124
|
+
openlayerClient,
|
|
125
|
+
openlayerInferencePipelineId,
|
|
126
|
+
}: OpenAIMonitorConstructorProps) {
|
|
127
|
+
this.openlayerInferencePipelineId = openlayerInferencePipelineId;
|
|
128
|
+
this.openlayerClient = openlayerClient;
|
|
129
|
+
|
|
130
|
+
this.openAIClient = new OpenAI({
|
|
131
|
+
apiKey: openAiApiKey,
|
|
132
|
+
dangerouslyAllowBrowser: true,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private cost = (model: string, inputTokens: number, outputTokens: number) => {
|
|
137
|
+
const pricing: Pricing | undefined = OpenAIPricing[model];
|
|
138
|
+
const inputCost = typeof pricing === 'undefined' ? undefined : (inputTokens / 1000) * pricing.input;
|
|
139
|
+
const outputCost = typeof pricing === 'undefined' ? undefined : (outputTokens / 1000) * pricing.output;
|
|
140
|
+
return typeof pricing === 'undefined' ? undefined : (inputCost ?? 0) + (outputCost ?? 0);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
private chatCompletionPrompt = (
|
|
144
|
+
fromMessages: ChatCompletionMessageParam[],
|
|
145
|
+
): Openlayer.InferencePipelines.Data.DataStreamParams.LlmData.Prompt[] =>
|
|
146
|
+
fromMessages.map(({ content, role }, i) => ({
|
|
147
|
+
content:
|
|
148
|
+
role === 'user' ? `{{ message_${i} }}`
|
|
149
|
+
: content === null || typeof content === 'undefined' ? ''
|
|
150
|
+
: content,
|
|
151
|
+
role,
|
|
152
|
+
}));
|
|
153
|
+
|
|
154
|
+
private threadPrompt = async (
|
|
155
|
+
fromMessages: Threads.MessagesPage,
|
|
156
|
+
): Promise<ChatCompletionMessageParam[]> => {
|
|
157
|
+
const messages: Threads.Messages.Message[] = [];
|
|
158
|
+
for await (const page of fromMessages.iterPages()) {
|
|
159
|
+
messages.push(...page.getPaginatedItems());
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return messages
|
|
163
|
+
.map(({ content, role }) =>
|
|
164
|
+
content.map((item) => ({
|
|
165
|
+
content: (() => {
|
|
166
|
+
switch (item.type) {
|
|
167
|
+
case 'image_file':
|
|
168
|
+
return item.image_file.file_id;
|
|
169
|
+
case 'text':
|
|
170
|
+
return item.text.value;
|
|
171
|
+
default:
|
|
172
|
+
return '';
|
|
173
|
+
}
|
|
174
|
+
})(),
|
|
175
|
+
role,
|
|
176
|
+
})),
|
|
177
|
+
)
|
|
178
|
+
.flat();
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
private inputVariables = (
|
|
182
|
+
fromPrompt: Openlayer.InferencePipelines.Data.DataStreamParams.LlmData.Prompt[],
|
|
183
|
+
andMessages: ChatCompletionMessageParam[],
|
|
184
|
+
) => {
|
|
185
|
+
const inputVariableNames = fromPrompt
|
|
186
|
+
.filter(({ role }) => role === 'user')
|
|
187
|
+
.map(({ content }) => String(content).replace(/{{\s*|\s*}}/g, '')) as string[];
|
|
188
|
+
const inputVariables = andMessages
|
|
189
|
+
.filter(({ role }) => role === 'user')
|
|
190
|
+
.map(({ content }) => content) as string[];
|
|
191
|
+
const inputVariablesMap = inputVariableNames.reduce(
|
|
192
|
+
(acc, name, i) => ({ ...acc, [name]: inputVariables[i] }),
|
|
193
|
+
{},
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
return { inputVariableNames, inputVariables, inputVariablesMap };
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Creates a chat completion using the OpenAI client and streams the result to Openlayer.
|
|
201
|
+
* @param {ChatCompletionCreateParams} body - The parameters for creating a chat completion.
|
|
202
|
+
* @param {RequestOptions} [options] - Optional request options.
|
|
203
|
+
* @param {Openlayer.RequestOptions<any> | undefined} [additionalLogs] - Optional metadata logs to include with the request sent to Openlayer.
|
|
204
|
+
* @returns {Promise<ChatCompletion | Stream<ChatCompletionChunk>>} Promise of a ChatCompletion or a Stream
|
|
205
|
+
* @throws {Error} Throws errors from the OpenAI client.
|
|
206
|
+
*/
|
|
207
|
+
public createChatCompletion = async (
|
|
208
|
+
body: ChatCompletionCreateParams,
|
|
209
|
+
options?: RequestOptions,
|
|
210
|
+
additionalLogs?: Openlayer.RequestOptions<any> | undefined,
|
|
211
|
+
): Promise<ChatCompletion | Stream<ChatCompletionChunk>> => {
|
|
212
|
+
// Start a timer to measure latency
|
|
213
|
+
const startTime = Date.now();
|
|
214
|
+
// Accumulate output for streamed responses
|
|
215
|
+
let streamedOutput = '';
|
|
216
|
+
|
|
217
|
+
const response = await this.openAIClient.chat.completions.create(body, options);
|
|
218
|
+
|
|
219
|
+
if (this.openlayerInferencePipelineId.length > 0) {
|
|
220
|
+
try {
|
|
221
|
+
const prompt = this.chatCompletionPrompt(body.messages);
|
|
222
|
+
const { inputVariableNames, inputVariablesMap } = this.inputVariables(prompt, body.messages);
|
|
223
|
+
|
|
224
|
+
const config: Openlayer.InferencePipelines.Data.DataStreamParams.LlmData = {
|
|
225
|
+
...this.defaultConfig,
|
|
226
|
+
inputVariableNames,
|
|
227
|
+
prompt,
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
if (body.stream) {
|
|
231
|
+
const streamedResponse = response as Stream<ChatCompletionChunk>;
|
|
232
|
+
|
|
233
|
+
for await (const chunk of streamedResponse) {
|
|
234
|
+
const [choice] = chunk.choices;
|
|
235
|
+
// Process each chunk - for example, accumulate input data
|
|
236
|
+
const chunkOutput = choice?.delta.content ?? '';
|
|
237
|
+
streamedOutput += chunkOutput;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const endTime = Date.now();
|
|
241
|
+
const latency = endTime - startTime;
|
|
242
|
+
|
|
243
|
+
this.openlayerClient.inferencePipelines.data.stream(this.openlayerInferencePipelineId, {
|
|
244
|
+
config,
|
|
245
|
+
rows: [
|
|
246
|
+
{
|
|
247
|
+
latency,
|
|
248
|
+
output: streamedOutput,
|
|
249
|
+
timestamp: startTime,
|
|
250
|
+
...inputVariablesMap,
|
|
251
|
+
...additionalLogs,
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
});
|
|
255
|
+
} else {
|
|
256
|
+
const nonStreamedResponse = response as ChatCompletion;
|
|
257
|
+
// Handle regular (non-streamed) response
|
|
258
|
+
const endTime = Date.now();
|
|
259
|
+
const latency = endTime - startTime;
|
|
260
|
+
const [choice] = nonStreamedResponse.choices;
|
|
261
|
+
const output = choice?.message.content;
|
|
262
|
+
const tokens = nonStreamedResponse.usage?.total_tokens ?? 0;
|
|
263
|
+
const inputTokens = nonStreamedResponse.usage?.prompt_tokens ?? 0;
|
|
264
|
+
const outputTokens = nonStreamedResponse.usage?.completion_tokens ?? 0;
|
|
265
|
+
const cost = this.cost(nonStreamedResponse.model, inputTokens, outputTokens);
|
|
266
|
+
|
|
267
|
+
if (typeof output === 'string') {
|
|
268
|
+
this.openlayerClient.inferencePipelines.data.stream(this.openlayerInferencePipelineId, {
|
|
269
|
+
config,
|
|
270
|
+
rows: [
|
|
271
|
+
{
|
|
272
|
+
cost,
|
|
273
|
+
latency,
|
|
274
|
+
model: nonStreamedResponse.model,
|
|
275
|
+
output,
|
|
276
|
+
timestamp: startTime,
|
|
277
|
+
tokens,
|
|
278
|
+
...inputVariablesMap,
|
|
279
|
+
...additionalLogs,
|
|
280
|
+
},
|
|
281
|
+
],
|
|
282
|
+
});
|
|
283
|
+
} else {
|
|
284
|
+
console.error('No output received from OpenAI.');
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
} catch (error) {
|
|
288
|
+
console.error(error);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return response;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Creates a completion using the OpenAI client and streams the result to Openlayer.
|
|
297
|
+
* @param {CompletionCreateParams} body - The parameters for creating a completion.
|
|
298
|
+
* @param {RequestOptions} [options] - Optional request options.
|
|
299
|
+
* @param {Openlayer.RequestOptions<any> | undefined} [additionalLogs] - Optional metadata logs to include with the request sent to Openlayer.
|
|
300
|
+
* @returns {Promise<Completion | Stream<Completion>>} Promise that resolves to a Completion or a Stream.
|
|
301
|
+
* @throws {Error} Throws errors from the OpenAI client.
|
|
302
|
+
*/
|
|
303
|
+
public createCompletion = async (
|
|
304
|
+
body: CompletionCreateParams,
|
|
305
|
+
options?: RequestOptions,
|
|
306
|
+
additionalLogs?: Openlayer.RequestOptions<any> | undefined,
|
|
307
|
+
): Promise<Completion | Stream<Completion>> => {
|
|
308
|
+
if (!body.prompt) {
|
|
309
|
+
console.error('No prompt provided.');
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Start a timer to measure latency
|
|
313
|
+
const startTime = Date.now();
|
|
314
|
+
|
|
315
|
+
// Accumulate output and tokens data for streamed responses
|
|
316
|
+
let streamedModel = body.model;
|
|
317
|
+
let streamedOutput = '';
|
|
318
|
+
let streamedTokens = 0;
|
|
319
|
+
let streamedInputTokens = 0;
|
|
320
|
+
let streamedOutputTokens = 0;
|
|
321
|
+
|
|
322
|
+
const response = await this.openAIClient.completions.create(body, options);
|
|
323
|
+
|
|
324
|
+
if (this.openlayerInferencePipelineId.length > 0) {
|
|
325
|
+
try {
|
|
326
|
+
const config: Openlayer.InferencePipelines.Data.DataStreamParams.LlmData = {
|
|
327
|
+
...this.defaultConfig,
|
|
328
|
+
inputVariableNames: ['input'],
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
if (body.stream) {
|
|
332
|
+
const streamedResponse = response as Stream<Completion>;
|
|
333
|
+
|
|
334
|
+
for await (const chunk of streamedResponse) {
|
|
335
|
+
const [choice] = chunk.choices;
|
|
336
|
+
// Process each chunk - for example, accumulate input data
|
|
337
|
+
streamedModel = chunk.model;
|
|
338
|
+
streamedOutput += choice?.text.trim();
|
|
339
|
+
streamedTokens += chunk.usage?.total_tokens ?? 0;
|
|
340
|
+
streamedInputTokens += chunk.usage?.prompt_tokens ?? 0;
|
|
341
|
+
streamedOutputTokens += chunk.usage?.completion_tokens ?? 0;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const endTime = Date.now();
|
|
345
|
+
const latency = endTime - startTime;
|
|
346
|
+
const cost = this.cost(streamedModel, streamedInputTokens, streamedOutputTokens);
|
|
347
|
+
|
|
348
|
+
this.openlayerClient.inferencePipelines.data.stream(this.openlayerInferencePipelineId, {
|
|
349
|
+
config,
|
|
350
|
+
rows: [
|
|
351
|
+
{
|
|
352
|
+
cost,
|
|
353
|
+
input: body.prompt,
|
|
354
|
+
latency,
|
|
355
|
+
output: streamedOutput,
|
|
356
|
+
timestamp: startTime,
|
|
357
|
+
tokens: streamedTokens,
|
|
358
|
+
...additionalLogs,
|
|
359
|
+
},
|
|
360
|
+
],
|
|
361
|
+
});
|
|
362
|
+
} else {
|
|
363
|
+
const nonStreamedResponse = response as Completion;
|
|
364
|
+
const [choice] = nonStreamedResponse.choices;
|
|
365
|
+
// Handle regular (non-streamed) response
|
|
366
|
+
const endTime = Date.now();
|
|
367
|
+
const latency = endTime - startTime;
|
|
368
|
+
const tokens = nonStreamedResponse.usage?.total_tokens ?? 0;
|
|
369
|
+
const inputTokens = nonStreamedResponse.usage?.prompt_tokens ?? 0;
|
|
370
|
+
const outputTokens = nonStreamedResponse.usage?.completion_tokens ?? 0;
|
|
371
|
+
const cost = this.cost(nonStreamedResponse.model, inputTokens, outputTokens);
|
|
372
|
+
|
|
373
|
+
this.openlayerClient.inferencePipelines.data.stream(this.openlayerInferencePipelineId, {
|
|
374
|
+
config,
|
|
375
|
+
rows: [
|
|
376
|
+
{
|
|
377
|
+
cost,
|
|
378
|
+
input: body.prompt,
|
|
379
|
+
latency,
|
|
380
|
+
output: choice?.text ?? '',
|
|
381
|
+
timestamp: startTime,
|
|
382
|
+
tokens,
|
|
383
|
+
...additionalLogs,
|
|
384
|
+
},
|
|
385
|
+
],
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
} catch (error) {
|
|
389
|
+
console.error(error);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return response;
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Monitor a run from an OpenAI assistant.
|
|
398
|
+
* Once the run is completed, the thread data is published to Openlayer,
|
|
399
|
+
* along with the latency, cost, and number of tokens used.
|
|
400
|
+
* @param {Run} run - The run created by the OpenAI assistant.
|
|
401
|
+
* @param {Openlayer.RequestOptions<any> | undefined} [additionalLogs] - Optional metadata logs to include with the request sent to Openlayer.
|
|
402
|
+
* @returns {Promise<void>} A promise that resolves when the run data has been successfully published to Openlayer.
|
|
403
|
+
*/
|
|
404
|
+
public async monitorThreadRun(run: Run, additionalLogs?: Openlayer.RequestOptions<any> | undefined) {
|
|
405
|
+
if (run.status !== 'completed' || this.openlayerInferencePipelineId.length === 0) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
try {
|
|
410
|
+
const {
|
|
411
|
+
assistant_id,
|
|
412
|
+
completed_at,
|
|
413
|
+
created_at,
|
|
414
|
+
model,
|
|
415
|
+
thread_id,
|
|
416
|
+
// @ts-ignore
|
|
417
|
+
usage,
|
|
418
|
+
} = run;
|
|
419
|
+
|
|
420
|
+
// @ts-ignore
|
|
421
|
+
const { completion_tokens, prompt_tokens, total_tokens } =
|
|
422
|
+
typeof usage === 'undefined' || typeof usage !== 'object' || usage === null ? {} : usage;
|
|
423
|
+
|
|
424
|
+
const cost = this.cost(model, prompt_tokens, completion_tokens);
|
|
425
|
+
const latency =
|
|
426
|
+
completed_at === null || created_at === null || isNaN(completed_at) || isNaN(created_at) ?
|
|
427
|
+
undefined
|
|
428
|
+
: (completed_at - created_at) * 1000;
|
|
429
|
+
|
|
430
|
+
const messages = await this.openAIClient.beta.threads.messages.list(thread_id, { order: 'asc' });
|
|
431
|
+
|
|
432
|
+
const populatedPrompt = await this.threadPrompt(messages);
|
|
433
|
+
const prompt = this.chatCompletionPrompt(populatedPrompt);
|
|
434
|
+
const { inputVariableNames, inputVariablesMap } = this.inputVariables(prompt, populatedPrompt);
|
|
435
|
+
|
|
436
|
+
const config: Openlayer.InferencePipelines.Data.DataStreamParams.LlmData = {
|
|
437
|
+
...this.defaultConfig,
|
|
438
|
+
inputVariableNames,
|
|
439
|
+
prompt: prompt.slice(0, prompt.length - 1),
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
const output = prompt[prompt.length - 1]?.content;
|
|
443
|
+
const resolvedOutput =
|
|
444
|
+
typeof output === 'string' ? output
|
|
445
|
+
: typeof output === 'undefined' || output === null ? ''
|
|
446
|
+
: `${output}`;
|
|
447
|
+
|
|
448
|
+
this.openlayerClient.inferencePipelines.data.stream(this.openlayerInferencePipelineId, {
|
|
449
|
+
config,
|
|
450
|
+
rows: [
|
|
451
|
+
{
|
|
452
|
+
cost,
|
|
453
|
+
latency,
|
|
454
|
+
openai_assistant_id: assistant_id,
|
|
455
|
+
openai_thread_id: thread_id,
|
|
456
|
+
output: resolvedOutput,
|
|
457
|
+
timestamp: run.created_at,
|
|
458
|
+
tokens: total_tokens,
|
|
459
|
+
...inputVariablesMap,
|
|
460
|
+
...additionalLogs,
|
|
461
|
+
},
|
|
462
|
+
],
|
|
463
|
+
});
|
|
464
|
+
} catch (error) {
|
|
465
|
+
console.error('Error logging thread run:', error);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
export default OpenAIMonitor;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as core from './core/index';
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.0.1-alpha.
|
|
1
|
+
export const VERSION = '0.0.1-alpha.1'; // x-release-please-version
|
package/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.0.1-alpha.
|
|
1
|
+
export declare const VERSION = "0.0.1-alpha.1";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/version.js
CHANGED
package/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["src/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,OAAO,GAAG,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["src/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,OAAO,GAAG,eAAe,CAAC,CAAC,2BAA2B"}
|
package/version.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '0.0.1-alpha.
|
|
1
|
+
export const VERSION = '0.0.1-alpha.1'; // x-release-please-version
|
|
2
2
|
//# sourceMappingURL=version.mjs.map
|
package/version.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.mjs","sourceRoot":"","sources":["src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"version.mjs","sourceRoot":"","sources":["src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,2BAA2B"}
|