openlayer 0.1.20 → 0.1.22
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/dist/index.js +50 -51
- package/examples/langchain.mjs +23 -18
- package/examples/openai_monitor.mjs +55 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -95,7 +95,7 @@ class OpenlayerClient {
|
|
|
95
95
|
timestampColumnName: 'timestamp',
|
|
96
96
|
};
|
|
97
97
|
this.openlayerServerUrl = 'https://api.openlayer.com/v1';
|
|
98
|
-
this.version = '0.1.
|
|
98
|
+
this.version = '0.1.0a21';
|
|
99
99
|
this.resolvedQuery = (endpoint, args = {}) => (0, request_1.resolvedQuery)(this.openlayerServerUrl, endpoint, args);
|
|
100
100
|
/**
|
|
101
101
|
* Creates a new inference pipeline in Openlayer or loads an existing one.
|
|
@@ -108,26 +108,25 @@ class OpenlayerClient {
|
|
|
108
108
|
try {
|
|
109
109
|
return yield this.loadInferencePipeline(projectId, name);
|
|
110
110
|
}
|
|
111
|
-
catch (_a) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
return inferencePipeline;
|
|
111
|
+
catch (_a) { }
|
|
112
|
+
const createInferencePipelineEndpoint = `/projects/${projectId}/inference-pipelines`;
|
|
113
|
+
const createInferencePipelineQuery = this.resolvedQuery(createInferencePipelineEndpoint, { version: this.version });
|
|
114
|
+
const createInferencePipelineResponse = yield fetch(createInferencePipelineQuery, {
|
|
115
|
+
body: JSON.stringify({
|
|
116
|
+
description: '',
|
|
117
|
+
name,
|
|
118
|
+
}),
|
|
119
|
+
headers: {
|
|
120
|
+
Authorization: `Bearer ${this.openlayerApiKey}`,
|
|
121
|
+
'Content-Type': 'application/json',
|
|
122
|
+
},
|
|
123
|
+
method: 'POST',
|
|
124
|
+
});
|
|
125
|
+
const inferencePipeline = yield createInferencePipelineResponse.json();
|
|
126
|
+
if (!(inferencePipeline === null || inferencePipeline === void 0 ? void 0 : inferencePipeline.id)) {
|
|
127
|
+
throw new Error('Error creating inference pipeline');
|
|
130
128
|
}
|
|
129
|
+
return inferencePipeline;
|
|
131
130
|
});
|
|
132
131
|
/**
|
|
133
132
|
* Creates a new project in Openlayer or loads an existing one.
|
|
@@ -141,32 +140,31 @@ class OpenlayerClient {
|
|
|
141
140
|
try {
|
|
142
141
|
return yield this.loadProject(name);
|
|
143
142
|
}
|
|
144
|
-
catch (_b) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
return project;
|
|
143
|
+
catch (_b) { }
|
|
144
|
+
const projectsEndpoint = '/projects';
|
|
145
|
+
const projectsQuery = this.resolvedQuery(projectsEndpoint);
|
|
146
|
+
const response = yield fetch(projectsQuery, {
|
|
147
|
+
body: JSON.stringify({
|
|
148
|
+
description,
|
|
149
|
+
name,
|
|
150
|
+
taskType,
|
|
151
|
+
}),
|
|
152
|
+
headers: {
|
|
153
|
+
Authorization: `Bearer ${this.openlayerApiKey}`,
|
|
154
|
+
'Content-Type': 'application/json',
|
|
155
|
+
},
|
|
156
|
+
method: 'POST',
|
|
157
|
+
});
|
|
158
|
+
const data = yield response.json();
|
|
159
|
+
const { items: projects, error } = data;
|
|
160
|
+
if (!Array.isArray(projects)) {
|
|
161
|
+
throw new Error(typeof error === 'string' ? error : 'Invalid response from Openlayer');
|
|
162
|
+
}
|
|
163
|
+
const project = projects.find((p) => p.name === name);
|
|
164
|
+
if (!(project === null || project === void 0 ? void 0 : project.id)) {
|
|
165
|
+
throw new Error('Project not found');
|
|
169
166
|
}
|
|
167
|
+
return project;
|
|
170
168
|
});
|
|
171
169
|
/**
|
|
172
170
|
* Loads an existing inference pipeline from Openlayer based on its name and project ID.
|
|
@@ -189,12 +187,12 @@ class OpenlayerClient {
|
|
|
189
187
|
},
|
|
190
188
|
method: 'GET',
|
|
191
189
|
});
|
|
192
|
-
const { items: inferencePipelines } = yield inferencePipelineResponse.json();
|
|
190
|
+
const { items: inferencePipelines, error } = yield inferencePipelineResponse.json();
|
|
193
191
|
const inferencePipeline = Array.isArray(inferencePipelines)
|
|
194
192
|
? inferencePipelines.find((p) => p.name === name)
|
|
195
193
|
: undefined;
|
|
196
194
|
if (!(inferencePipeline === null || inferencePipeline === void 0 ? void 0 : inferencePipeline.id)) {
|
|
197
|
-
throw new Error('Inference pipeline not found');
|
|
195
|
+
throw new Error(typeof error === 'string' ? error : 'Inference pipeline not found');
|
|
198
196
|
}
|
|
199
197
|
return inferencePipeline;
|
|
200
198
|
});
|
|
@@ -298,9 +296,10 @@ class OpenAIMonitor {
|
|
|
298
296
|
? undefined
|
|
299
297
|
: (inputCost !== null && inputCost !== void 0 ? inputCost : 0) + (outputCost !== null && outputCost !== void 0 ? outputCost : 0);
|
|
300
298
|
};
|
|
301
|
-
this.formatChatCompletionInput = (messages) => messages.map(({ content, role }, i) => (
|
|
302
|
-
? `{{ message_${i} }}`
|
|
303
|
-
|
|
299
|
+
this.formatChatCompletionInput = (messages) => messages.map(({ content, role }, i) => ({
|
|
300
|
+
content: role === 'user' ? `{{ message_${i} }}` : content,
|
|
301
|
+
role,
|
|
302
|
+
}));
|
|
304
303
|
/**
|
|
305
304
|
* Creates a chat completion using the OpenAI client and streams the result to Openlayer.
|
|
306
305
|
* @param {ChatCompletionCreateParams} body - The parameters for creating a chat completion.
|
|
@@ -324,7 +323,7 @@ class OpenAIMonitor {
|
|
|
324
323
|
const prompt = this.formatChatCompletionInput(body.messages);
|
|
325
324
|
const inputVariableNames = prompt
|
|
326
325
|
.filter(({ role }) => role === 'user')
|
|
327
|
-
.map(({ content }) => content);
|
|
326
|
+
.map(({ content }) => String(content).replace(/{{\s*|\s*}}/g, ''));
|
|
328
327
|
const inputVariables = body.messages
|
|
329
328
|
.filter(({ role }) => role === 'user')
|
|
330
329
|
.map(({ content }) => content);
|
package/examples/langchain.mjs
CHANGED
|
@@ -24,22 +24,27 @@ const inputs = [
|
|
|
24
24
|
'What would be a good name for a company that makes colorful socks?',
|
|
25
25
|
];
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
28
|
+
const input = inputs[i];
|
|
29
|
+
// Call the LLM
|
|
30
|
+
const output = await chatModel.predict(input);
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
32
|
+
// Stream the results to Openlayer
|
|
33
|
+
await openlayer.streamData(
|
|
34
|
+
{
|
|
35
|
+
input,
|
|
36
|
+
output,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
...openlayer.defaultConfig,
|
|
40
|
+
inputVariableNames: ['input'],
|
|
41
|
+
prompt: [
|
|
42
|
+
{
|
|
43
|
+
content: '{{ input }}',
|
|
44
|
+
role: 'user',
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
inferencePipeline.id
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This example shows how to use Openlayer to monitor your OpenAI workflows.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { OpenAIMonitor } from 'openlayer';
|
|
6
|
+
|
|
7
|
+
const monitor = new OpenAIMonitor({
|
|
8
|
+
openAiApiKey: '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',
|
|
9
|
+
openlayerApiKey: 'UyKge0qbzrnAg_vehsTtw_e_mArrHHyT',
|
|
10
|
+
openlayerInferencePipelineName: 'production',
|
|
11
|
+
openlayerProjectName: 'test6',
|
|
12
|
+
openlayerServerUrl: 'http://localhost:8080/v1',
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
monitor.startMonitoring();
|
|
16
|
+
|
|
17
|
+
const inputs = [
|
|
18
|
+
{
|
|
19
|
+
promptVersion: 'v1',
|
|
20
|
+
systemMessage:
|
|
21
|
+
'You are an all-knowing assistant. Answer questions thoughtfully.',
|
|
22
|
+
userMessage: 'What is the meaning of life?',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
promptVersion: 'v2',
|
|
26
|
+
systemMessage: 'Be as creative as you can!',
|
|
27
|
+
userMessage:
|
|
28
|
+
'What would be a good name for a company that makes colorful socks?',
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
33
|
+
const { promptVersion, systemMessage, userMessage } = inputs[i];
|
|
34
|
+
// Stream the results to Openlayer
|
|
35
|
+
await monitor.createChatCompletion(
|
|
36
|
+
{
|
|
37
|
+
messages: [
|
|
38
|
+
{
|
|
39
|
+
content: systemMessage,
|
|
40
|
+
role: 'assistant',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
content: userMessage,
|
|
44
|
+
role: 'user',
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
model: 'gpt-3.5-turbo',
|
|
48
|
+
},
|
|
49
|
+
undefined,
|
|
50
|
+
{
|
|
51
|
+
// Add any additional columns you want to track here
|
|
52
|
+
promptVersion,
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
}
|