openlayer 0.0.1 → 0.0.2

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/.eslintrc.json CHANGED
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "extends": [
3
- "next/core-web-vitals",
4
3
  "plugin:typescript-sort-keys/recommended",
5
4
  "plugin:prettier/recommended"
6
5
  ],
@@ -22,7 +21,6 @@
22
21
  "multiline-comment-style": ["error", "starred-block"],
23
22
  "new-cap": "error",
24
23
  "no-alert": "error",
25
- "no-console": "error",
26
24
  "no-duplicate-imports": "error",
27
25
  "no-else-return": "error",
28
26
  "no-empty-function": "error",
@@ -121,56 +119,6 @@
121
119
  "switch-colon-spacing": "error",
122
120
  "template-curly-spacing": "error",
123
121
  "template-tag-spacing": "error",
124
- "yield-star-spacing": "error",
125
-
126
- // React
127
- "react/boolean-prop-naming": "error",
128
- "react/button-has-type": "error",
129
- "react/destructuring-assignment": "error",
130
- // FIXME: This fails to load
131
- // "react/hook-use-state": "error",
132
- "react/no-array-index-key": "error",
133
- "react/no-arrow-function-lifecycle": "error",
134
- "react/no-danger": "error",
135
- "react/no-invalid-html-attribute": "error",
136
- "react/no-multi-comp": "warn",
137
- "react/no-this-in-sfc": "error",
138
- "react/no-typos": "warn",
139
- "react/no-unsafe": "error",
140
- "react/no-unstable-nested-components": "warn",
141
- "react/no-unused-class-component-methods": "error",
142
- "react/no-unused-prop-types": "error",
143
- "react/no-unused-state": "error",
144
- "react/prefer-es6-class": "error",
145
- "react/prefer-stateless-function": "error",
146
- "react/self-closing-comp": "error",
147
- "react/sort-comp": "error",
148
- "react/sort-prop-types": "error",
149
- "react/static-property-placement": "error",
150
- "react/style-prop-object": "error",
151
- "react/void-dom-elements-no-children": "error",
152
-
153
- // JSX
154
- "react/jsx-boolean-value": "error",
155
- "react/jsx-child-element-spacing": "error",
156
- "react/jsx-closing-tag-location": "error",
157
- "react/jsx-curly-brace-presence": "error",
158
- "react/jsx-curly-spacing": "error",
159
- "react/jsx-equals-spacing": "error",
160
- "react/jsx-filename-extension": [
161
- 2,
162
- { "extensions": [".js", ".jsx", ".ts", ".tsx"] }
163
- ],
164
- "react/jsx-first-prop-new-line": "error",
165
- "react/jsx-handler-names": "error",
166
- // "react/jsx-indent": ["error", 2, { "checkAttributes": true }],
167
- // "react/jsx-indent-props": ["error", 2],
168
- "react/jsx-newline": "warn",
169
- "react/jsx-pascal-case": "error",
170
- "react/jsx-props-no-multi-spaces": "error",
171
- "react/jsx-sort-default-props": "error",
172
- "react/jsx-sort-props": "error",
173
- "react/jsx-tag-spacing": ["error", { "beforeSelfClosing": "always" }],
174
- "react/jsx-wrap-multilines": "error"
122
+ "yield-star-spacing": "error"
175
123
  }
176
124
  }
package/dist/index.d.ts CHANGED
@@ -1,16 +1,24 @@
1
1
  import { RequestOptions } from 'openai/core';
2
2
  import { ChatCompletion, ChatCompletionChunk, ChatCompletionCreateParams, Completion, CompletionCreateParams } from 'openai/resources';
3
3
  import { Stream } from 'openai/streaming';
4
+ type ConstructorProps = {
5
+ openAiApiKey: string;
6
+ openlayerApiKey?: string;
7
+ openlayerInferencePipelineName?: string;
8
+ openlayerProjectName?: string;
9
+ openlayerServerUrl?: string;
10
+ };
4
11
  declare class OpenAIMonitor {
12
+ private OpenAIClient;
13
+ private monitoringOn;
5
14
  private openlayerApiKey?;
6
15
  private openlayerProjectName?;
7
16
  private openlayerInferencePipelineName?;
8
17
  private openlayerServerUrl;
9
- private OpenAIClient;
10
- private monitoringOn;
11
18
  private version;
12
- constructor(openAiApiKey: string, openlayerApiKey?: string | undefined, openlayerProjectName?: string | undefined, openlayerInferencePipelineName?: string | undefined, openlayerServerUrl?: string);
19
+ constructor({ openAiApiKey, openlayerApiKey, openlayerInferencePipelineName, openlayerProjectName, openlayerServerUrl, }: ConstructorProps);
13
20
  private formatChatCompletionInput;
21
+ private resolvedQuery;
14
22
  private uploadDataToOpenlayer;
15
23
  startMonitoring(): void;
16
24
  stopMonitoring(): void;
package/dist/index.js CHANGED
@@ -28,39 +28,41 @@ var __asyncValues = (this && this.__asyncValues) || function (o) {
28
28
  };
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  const openai_1 = require("openai");
31
+ const request_1 = require("./utils/request");
31
32
  class OpenAIMonitor {
32
- constructor(openAiApiKey, openlayerApiKey, openlayerProjectName, openlayerInferencePipelineName, openlayerServerUrl = 'https://api.openlayer.com/v1') {
33
- this.openlayerApiKey = openlayerApiKey;
34
- this.openlayerProjectName = openlayerProjectName;
35
- this.openlayerInferencePipelineName = openlayerInferencePipelineName;
36
- this.openlayerServerUrl = openlayerServerUrl;
33
+ constructor({ openAiApiKey, openlayerApiKey, openlayerInferencePipelineName, openlayerProjectName, openlayerServerUrl, }) {
37
34
  this.monitoringOn = false;
35
+ this.openlayerServerUrl = 'https://api.openlayer.com/v1';
38
36
  this.version = '0.1.0a16';
39
37
  this.formatChatCompletionInput = (messages) => messages
40
38
  .filter(({ role }) => role === 'user')
41
39
  .map(({ content }) => content)
42
40
  .join('\n')
43
41
  .trim();
42
+ this.resolvedQuery = (endpoint, args = {}) => (0, request_1.resolvedQuery)(this.openlayerServerUrl, endpoint, Object.assign({ version: this.version }, args));
44
43
  this.uploadDataToOpenlayer = (data) => __awaiter(this, void 0, void 0, function* () {
45
44
  const uploadToInferencePipeline = (id) => __awaiter(this, void 0, void 0, function* () {
46
- const dataStreamEndpoint = `/inference-pipelines/${id}/data-stream?version=${this.version}`;
47
- const dataStreamUrl = `${this.openlayerServerUrl}${dataStreamEndpoint}`;
48
- console.log('boy', dataStreamUrl, JSON.stringify({
49
- dataset: [data],
50
- datasetConfig: {},
51
- }));
52
- const response = yield fetch(dataStreamUrl, {
53
- method: 'POST',
45
+ const dataStreamEndpoint = `/inference-pipelines/${id}/data-stream`;
46
+ const dataStreamQuery = this.resolvedQuery(dataStreamEndpoint);
47
+ const response = yield fetch(dataStreamQuery, {
48
+ body: JSON.stringify({
49
+ config: {
50
+ inferenceIdColumnName: 'inference_id',
51
+ inputVariableNames: ['input'],
52
+ latencyColumnName: 'latency',
53
+ outputColumnName: 'output',
54
+ timestampColumnName: 'timestamp',
55
+ tokensColumnName: 'tokens',
56
+ },
57
+ rows: [data],
58
+ }),
54
59
  headers: {
55
- 'Content-Type': 'application/json',
56
60
  Authorization: `Bearer ${this.openlayerApiKey}`,
61
+ 'Content-Type': 'application/json',
57
62
  },
58
- body: JSON.stringify({
59
- dataset: [data],
60
- datasetConfig: {},
61
- }),
63
+ method: 'POST',
62
64
  });
63
- console.log('uhh', response);
65
+ console.log('bruh', response, dataStreamQuery);
64
66
  if (!response.ok) {
65
67
  console.error('Error making POST request:', response.status);
66
68
  throw new Error(`Error: ${response.status}`);
@@ -71,16 +73,19 @@ class OpenAIMonitor {
71
73
  throw new Error('Openlayer API key and project name are required for publishing.');
72
74
  }
73
75
  try {
74
- const projectsEndpoint = `/projects?perPage=100&name=${this.openlayerProjectName}&version=${this.version}`;
75
- const projectsUrl = `${this.openlayerServerUrl}${projectsEndpoint}`;
76
- const projectsResponse = yield fetch(projectsUrl, {
77
- method: 'GET',
76
+ const projectsEndpoint = '/projects';
77
+ const projectsQueryParameters = {
78
+ name: this.openlayerProjectName,
79
+ };
80
+ const projectsQuery = this.resolvedQuery(projectsEndpoint, projectsQueryParameters);
81
+ const projectsResponse = yield fetch(projectsQuery, {
78
82
  headers: {
79
- 'Content-Type': 'application/json',
80
83
  Authorization: `Bearer ${this.openlayerApiKey}`,
84
+ 'Content-Type': 'application/json',
81
85
  },
86
+ method: 'GET',
82
87
  });
83
- const _a = yield projectsResponse.json(), { items: projects } = _a, data = __rest(_a, ["items"]);
88
+ const { items: projects } = yield projectsResponse.json();
84
89
  if (!Array.isArray(projects)) {
85
90
  throw new Error('Invalid response from Openlayer');
86
91
  }
@@ -88,46 +93,50 @@ class OpenAIMonitor {
88
93
  if (!(project === null || project === void 0 ? void 0 : project.id)) {
89
94
  throw new Error('Project not found');
90
95
  }
91
- const inferencePipelineEndpoint = `/projects/${project.id}/inference-pipelines?perPage=100&name=${this.openlayerInferencePipelineName}&version=${this.version}`;
92
- const inferencePipelineUrl = `${this.openlayerServerUrl}${inferencePipelineEndpoint}`;
93
- const inferencePipelineResponse = yield fetch(inferencePipelineUrl, {
94
- method: 'GET',
96
+ const inferencePipelineEndpoint = `/projects/${project.id}/inference-pipelines`;
97
+ const inferencePipelineQueryParameters = {
98
+ name: this.openlayerInferencePipelineName,
99
+ };
100
+ const inferencePipelineQuery = this.resolvedQuery(inferencePipelineEndpoint, inferencePipelineQueryParameters);
101
+ const inferencePipelineResponse = yield fetch(inferencePipelineQuery, {
95
102
  headers: {
96
- 'Content-Type': 'application/json',
97
103
  Authorization: `Bearer ${this.openlayerApiKey}`,
104
+ 'Content-Type': 'application/json',
98
105
  },
106
+ method: 'GET',
99
107
  });
100
108
  const { items: inferencePipelines } = yield inferencePipelineResponse.json();
101
109
  const inferencePipeline = Array.isArray(inferencePipelines)
102
110
  ? inferencePipelines.find(({ name }) => typeof this.openlayerInferencePipelineName === 'undefined' ||
103
111
  name === this.openlayerInferencePipelineName)
104
112
  : undefined;
105
- if (!(inferencePipeline === null || inferencePipeline === void 0 ? void 0 : inferencePipeline.id)) {
106
- const createInferencePipelineEndpoint = `/projects/${project.id}/inference-pipelines?version=${this.version}`;
107
- const createInferencePipelineUrl = `${this.openlayerServerUrl}${createInferencePipelineEndpoint}`;
108
- const createInferencePipelineResponse = yield fetch(createInferencePipelineUrl, {
109
- method: 'POST',
110
- headers: {
111
- 'Content-Type': 'application/json',
112
- Authorization: `Bearer ${this.openlayerApiKey}`,
113
- },
113
+ if (inferencePipeline === null || inferencePipeline === void 0 ? void 0 : inferencePipeline.id) {
114
+ const { id: inferencePipelineId } = inferencePipeline;
115
+ yield uploadToInferencePipeline(inferencePipelineId);
116
+ }
117
+ else {
118
+ const createInferencePipelineEndpoint = `/projects/${project.id}/inference-pipelines`;
119
+ const createInferencePipelineQuery = this.resolvedQuery(createInferencePipelineEndpoint);
120
+ const createInferencePipelineResponse = yield fetch(createInferencePipelineQuery, {
114
121
  body: JSON.stringify({
115
122
  description: '',
116
123
  name: typeof this.openlayerInferencePipelineName === 'undefined'
117
124
  ? 'production'
118
125
  : this.openlayerInferencePipelineName,
119
126
  }),
127
+ headers: {
128
+ Authorization: `Bearer ${this.openlayerApiKey}`,
129
+ 'Content-Type': 'application/json',
130
+ },
131
+ method: 'POST',
120
132
  });
121
- const _b = yield createInferencePipelineResponse.json(), { id: inferencePipelineId } = _b, response = __rest(_b, ["id"]);
133
+ const _a = yield createInferencePipelineResponse.json(), { id: inferencePipelineId } = _a, response = __rest(_a, ["id"]);
134
+ console.log(createInferencePipelineResponse, response, inferencePipelineId);
122
135
  if (!inferencePipelineId) {
123
136
  throw new Error('Error creating inference pipeline');
124
137
  }
125
138
  yield uploadToInferencePipeline(inferencePipelineId);
126
139
  }
127
- else {
128
- const { id: inferencePipelineId } = inferencePipeline;
129
- yield uploadToInferencePipeline(inferencePipelineId);
130
- }
131
140
  }
132
141
  catch (error) {
133
142
  console.error('Error publishing data to Openlayer:', error);
@@ -135,8 +144,8 @@ class OpenAIMonitor {
135
144
  }
136
145
  });
137
146
  this.createChatCompletion = (body, options) => __awaiter(this, void 0, void 0, function* () {
138
- var _c, e_1, _d, _e;
139
- var _f, _g;
147
+ var _b, e_1, _c, _d;
148
+ var _e, _f;
140
149
  if (!this.monitoringOn) {
141
150
  throw new Error('Monitoring is not active.');
142
151
  }
@@ -148,10 +157,10 @@ class OpenAIMonitor {
148
157
  if (body.stream) {
149
158
  const streamedResponse = response;
150
159
  try {
151
- for (var _h = true, streamedResponse_1 = __asyncValues(streamedResponse), streamedResponse_1_1; streamedResponse_1_1 = yield streamedResponse_1.next(), _c = streamedResponse_1_1.done, !_c; _h = true) {
152
- _e = streamedResponse_1_1.value;
153
- _h = false;
154
- const chunk = _e;
160
+ for (var _g = true, streamedResponse_1 = __asyncValues(streamedResponse), streamedResponse_1_1; streamedResponse_1_1 = yield streamedResponse_1.next(), _b = streamedResponse_1_1.done, !_b; _g = true) {
161
+ _d = streamedResponse_1_1.value;
162
+ _g = false;
163
+ const chunk = _d;
155
164
  // Process each chunk - for example, accumulate input data
156
165
  outputData += chunk.choices[0].delta.content;
157
166
  }
@@ -159,7 +168,7 @@ class OpenAIMonitor {
159
168
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
160
169
  finally {
161
170
  try {
162
- if (!_h && !_c && (_d = streamedResponse_1.return)) yield _d.call(streamedResponse_1);
171
+ if (!_g && !_b && (_c = streamedResponse_1.return)) yield _c.call(streamedResponse_1);
163
172
  }
164
173
  finally { if (e_1) throw e_1.error; }
165
174
  }
@@ -167,7 +176,7 @@ class OpenAIMonitor {
167
176
  const latency = endTime - startTime;
168
177
  this.uploadDataToOpenlayer({
169
178
  input: this.formatChatCompletionInput(body.messages),
170
- latency: latency,
179
+ latency,
171
180
  output: outputData,
172
181
  });
173
182
  }
@@ -178,16 +187,16 @@ class OpenAIMonitor {
178
187
  const latency = endTime - startTime;
179
188
  this.uploadDataToOpenlayer({
180
189
  input: this.formatChatCompletionInput(body.messages),
190
+ latency,
181
191
  output: nonStreamedResponse.choices[0].message.content,
182
- latency: latency,
183
- tokens: (_g = (_f = nonStreamedResponse.usage) === null || _f === void 0 ? void 0 : _f.total_tokens) !== null && _g !== void 0 ? _g : 0,
192
+ tokens: (_f = (_e = nonStreamedResponse.usage) === null || _e === void 0 ? void 0 : _e.total_tokens) !== null && _f !== void 0 ? _f : 0,
184
193
  });
185
194
  }
186
195
  return response;
187
196
  });
188
197
  this.createCompletion = (body, options) => __awaiter(this, void 0, void 0, function* () {
189
- var _j, e_2, _k, _l;
190
- var _m, _o, _p, _q;
198
+ var _h, e_2, _j, _k;
199
+ var _l, _m, _o, _p;
191
200
  if (!this.monitoringOn) {
192
201
  throw new Error('Monitoring is not active.');
193
202
  }
@@ -200,19 +209,19 @@ class OpenAIMonitor {
200
209
  if (body.stream) {
201
210
  const streamedResponse = response;
202
211
  try {
203
- for (var _r = true, streamedResponse_2 = __asyncValues(streamedResponse), streamedResponse_2_1; streamedResponse_2_1 = yield streamedResponse_2.next(), _j = streamedResponse_2_1.done, !_j; _r = true) {
204
- _l = streamedResponse_2_1.value;
205
- _r = false;
206
- const chunk = _l;
212
+ for (var _q = true, streamedResponse_2 = __asyncValues(streamedResponse), streamedResponse_2_1; streamedResponse_2_1 = yield streamedResponse_2.next(), _h = streamedResponse_2_1.done, !_h; _q = true) {
213
+ _k = streamedResponse_2_1.value;
214
+ _q = false;
215
+ const chunk = _k;
207
216
  // Process each chunk - for example, accumulate input data
208
217
  outputData += chunk.choices[0].text.trim();
209
- tokensData += (_o = (_m = chunk.usage) === null || _m === void 0 ? void 0 : _m.total_tokens) !== null && _o !== void 0 ? _o : 0;
218
+ tokensData += (_m = (_l = chunk.usage) === null || _l === void 0 ? void 0 : _l.total_tokens) !== null && _m !== void 0 ? _m : 0;
210
219
  }
211
220
  }
212
221
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
213
222
  finally {
214
223
  try {
215
- if (!_r && !_j && (_k = streamedResponse_2.return)) yield _k.call(streamedResponse_2);
224
+ if (!_q && !_h && (_j = streamedResponse_2.return)) yield _j.call(streamedResponse_2);
216
225
  }
217
226
  finally { if (e_2) throw e_2.error; }
218
227
  }
@@ -220,7 +229,7 @@ class OpenAIMonitor {
220
229
  const latency = endTime - startTime;
221
230
  this.uploadDataToOpenlayer({
222
231
  input: body.prompt,
223
- latency: latency,
232
+ latency,
224
233
  output: outputData,
225
234
  tokens: tokensData,
226
235
  });
@@ -232,17 +241,20 @@ class OpenAIMonitor {
232
241
  const latency = endTime - startTime;
233
242
  this.uploadDataToOpenlayer({
234
243
  input: body.prompt,
244
+ latency,
235
245
  output: nonStreamedResponse.choices[0].text,
236
- latency: latency,
237
- tokens: (_q = (_p = nonStreamedResponse.usage) === null || _p === void 0 ? void 0 : _p.total_tokens) !== null && _q !== void 0 ? _q : 0,
246
+ tokens: (_p = (_o = nonStreamedResponse.usage) === null || _o === void 0 ? void 0 : _o.total_tokens) !== null && _p !== void 0 ? _p : 0,
238
247
  });
239
248
  }
240
249
  return response;
241
250
  });
242
251
  this.OpenAIClient = new openai_1.default({ apiKey: openAiApiKey });
243
252
  this.openlayerApiKey = openlayerApiKey;
253
+ this.openlayerInferencePipelineName = openlayerInferencePipelineName;
244
254
  this.openlayerProjectName = openlayerProjectName;
245
- this.openlayerServerUrl = this.openlayerServerUrl;
255
+ if (openlayerServerUrl) {
256
+ this.openlayerServerUrl = openlayerServerUrl;
257
+ }
246
258
  if (!this.openlayerApiKey || !this.openlayerProjectName) {
247
259
  throw new Error('Openlayer API key and project name are required for publishing.');
248
260
  }
@@ -264,20 +276,4 @@ class OpenAIMonitor {
264
276
  console.info('Monitoring stopped.');
265
277
  }
266
278
  }
267
- // Usage Example
268
- (() => __awaiter(void 0, void 0, void 0, function* () {
269
- const monitor = new OpenAIMonitor('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', 'UyKge0qbzrnAg_vehsTtw_e_mArrHHyT', 'aoeuaoeuaoeu', 'production', 'http://127.0.0.1:8080/v1');
270
- monitor.startMonitoring();
271
- const chatCompletion = yield monitor.createChatCompletion({
272
- messages: [{ role: 'user', content: 'Say this is a test' }],
273
- model: 'gpt-3.5-turbo',
274
- });
275
- const completion = yield monitor.createCompletion({
276
- model: 'gpt-3.5-turbo-instruct',
277
- prompt: 'Say this is a test',
278
- });
279
- console.log('Client chat completion:', chatCompletion);
280
- console.log('Client completion:', completion);
281
- monitor.stopMonitoring();
282
- }))();
283
279
  exports.default = OpenAIMonitor;
@@ -0,0 +1,5 @@
1
+ export type RequestParameters = {
2
+ [key: string]: any;
3
+ };
4
+ export declare const resolvedQuery: (baseUrl: string, endpoint: string, args?: RequestParameters) => string;
5
+ export declare const queryParameters: (args: RequestParameters) => string;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queryParameters = exports.resolvedQuery = void 0;
4
+ const resolvedQuery = (baseUrl, endpoint, args = {}) => `${baseUrl}${endpoint}${(0, exports.queryParameters)(args)}`;
5
+ exports.resolvedQuery = resolvedQuery;
6
+ const queryParameters = (args) => {
7
+ const filteredArgs = Object.keys(args)
8
+ .filter((key) => typeof args[key] !== 'undefined')
9
+ .reduce((acc, arg) => {
10
+ if (Array.isArray(args[arg])) {
11
+ if (args[arg].length === 0) {
12
+ return acc;
13
+ }
14
+ acc[arg] = args[arg].join(`&${arg}=`);
15
+ }
16
+ else {
17
+ if ((typeof args[arg] === 'string' && args[arg].length === 0) ||
18
+ (typeof args[arg] === 'object' &&
19
+ Object.values(args[arg]).length === 0)) {
20
+ return acc;
21
+ }
22
+ acc[arg] = args[arg];
23
+ }
24
+ return acc;
25
+ }, {});
26
+ if (Object.keys(filteredArgs).length === 0) {
27
+ return '';
28
+ }
29
+ const resolvedArgs = Object.keys(filteredArgs)
30
+ .map((key) => `${key}=${filteredArgs[key]}`)
31
+ .join('&');
32
+ return `?${resolvedArgs}`;
33
+ };
34
+ exports.queryParameters = queryParameters;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openlayer",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "The Openlayer TypeScript client",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -16,7 +16,7 @@
16
16
  "@typescript-eslint/parser": "^6.11.0",
17
17
  "eslint": "^8.54.0",
18
18
  "eslint-config-prettier": "^9.0.0",
19
- "eslint-plugin-react-hooks": "^4.6.0",
19
+ "eslint-plugin-prettier": "^5.0.1",
20
20
  "eslint-plugin-typescript-sort-keys": "^3.1.0",
21
21
  "openai": "^4.19.0"
22
22
  },