openlayer 0.1.3 → 0.1.5

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +176 -3
  2. package/dist/index.js +220 -117
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -1,6 +1,66 @@
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
+ /**
5
+ * Represents the data structure for a chat completion.
6
+ */
7
+ export interface ChatCompletionData {
8
+ [key: string]: any;
9
+ /**
10
+ * The input data for the chat completion. It can be a string, an array of strings,
11
+ * or a nested array of numbers.
12
+ */
13
+ input: string | string[] | number[] | number[][];
14
+ /**
15
+ * The latency of the chat completion in milliseconds. Optional.
16
+ */
17
+ latency?: number;
18
+ /**
19
+ * The output string generated by the chat completion.
20
+ */
21
+ output: string;
22
+ /**
23
+ * A timestamp representing when the chat completion occurred. Optional.
24
+ */
25
+ timestamp?: number;
26
+ /**
27
+ * The number of tokens used in the chat completion. Optional.
28
+ */
29
+ tokens?: number;
30
+ }
31
+ /**
32
+ * Configuration settings for uploading chat completion data to Openlayer.
33
+ */
34
+ export interface ChatCompletionConfig {
35
+ /**
36
+ * The name of the column that stores the ground truth data. Can be null.
37
+ */
38
+ groundTruthColumnName: string | null;
39
+ /**
40
+ * The name of the column that stores inference IDs. Can be null.
41
+ */
42
+ inferenceIdColumnName: string | null;
43
+ /**
44
+ * An array of names for input variable columns. Can be null.
45
+ */
46
+ inputVariableNames: string[] | null;
47
+ /**
48
+ * The name of the column that stores latency data. Can be null.
49
+ */
50
+ latencyColumnName: string | null;
51
+ /**
52
+ * The name of the column that stores the number of tokens. Can be null.
53
+ */
54
+ numOfTokenColumnName: string | null;
55
+ /**
56
+ * The name of the column that stores output data. Can be null.
57
+ */
58
+ outputColumnName: string | null;
59
+ /**
60
+ * The name of the column that stores timestamp data. Can be null.
61
+ */
62
+ timestampColumnName: string | null;
63
+ }
4
64
  type ConstructorProps = {
5
65
  openAiApiKey: string;
6
66
  openlayerApiKey?: string;
@@ -8,10 +68,66 @@ type ConstructorProps = {
8
68
  openlayerProjectName?: string;
9
69
  openlayerServerUrl?: string;
10
70
  };
71
+ type OpenlayerInferencePipeline = {
72
+ dataVolumeGraphs?: OpenlayerSampleVolumeGraph;
73
+ dateCreated: string;
74
+ dateLastEvaluated?: string;
75
+ dateLastSampleReceived?: string;
76
+ dateOfNextEvaluation?: string;
77
+ dateUpdated: string;
78
+ description?: string;
79
+ failingGoalCount: number;
80
+ id: string;
81
+ name: string;
82
+ passingGoalCount: number;
83
+ projectId: string;
84
+ status: OpenlayerInferencePipelineStatus;
85
+ statusMessage?: string;
86
+ totalGoalCount: number;
87
+ };
88
+ type OpenlayerInferencePipelineStatus = 'completed' | 'failed' | 'paused' | 'queued' | 'running' | 'unknown';
89
+ type OpenlayerProject = {
90
+ dateCreated: string;
91
+ dateUpdated: string;
92
+ description?: string;
93
+ developmentGoalCount: number;
94
+ goalCount: number;
95
+ id: string;
96
+ inferencePipelineCount: number;
97
+ memberIds: string[];
98
+ monitoringGoalCount: number;
99
+ name: string;
100
+ sample?: boolean;
101
+ slackChannelId?: string;
102
+ slackChannelName?: string;
103
+ slackChannelNotificationsEnabled: boolean;
104
+ taskType: OpenlayerTaskType;
105
+ unreadNotificationCount: number;
106
+ versionCount: number;
107
+ };
108
+ type OpenlayerSampleVolumeGraphBucket = {
109
+ title: string;
110
+ xAxis: {
111
+ data: string[];
112
+ title: string;
113
+ };
114
+ yAxis: {
115
+ data: number[];
116
+ title: string;
117
+ };
118
+ };
119
+ type OpenlayerSampleVolumeGraph = {
120
+ daily: OpenlayerSampleVolumeGraphBucket;
121
+ hourly: OpenlayerSampleVolumeGraphBucket;
122
+ monthly: OpenlayerSampleVolumeGraphBucket;
123
+ weekly: OpenlayerSampleVolumeGraphBucket;
124
+ };
125
+ type OpenlayerTaskType = 'llm-base' | 'tabular-classification' | 'tabular-regression' | 'text-classification';
11
126
  declare class OpenAIMonitor {
12
127
  private OpenAIClient;
13
128
  private monitoringOn;
14
129
  private openlayerApiKey?;
130
+ private openlayerDefaultDataConfig;
15
131
  private openlayerProjectName?;
16
132
  private openlayerInferencePipelineName?;
17
133
  private openlayerServerUrl;
@@ -19,10 +135,67 @@ declare class OpenAIMonitor {
19
135
  constructor({ openAiApiKey, openlayerApiKey, openlayerInferencePipelineName, openlayerProjectName, openlayerServerUrl, }: ConstructorProps);
20
136
  private formatChatCompletionInput;
21
137
  private resolvedQuery;
22
- private uploadDataToOpenlayer;
23
- startMonitoring(): void;
24
- stopMonitoring(): void;
138
+ private uploadToInferencePipeline;
139
+ /**
140
+ * Uploads data to Openlayer. This function takes ChatCompletionData and an optional
141
+ * ChatCompletionConfig, then uploads the data to the specified Openlayer Inference Pipeline.
142
+ * @param data The ChatCompletionData to be uploaded.
143
+ * @param config Configuration for the data upload.
144
+ * @throws Throws an error if Openlayer API key or project name are not set.
145
+ * @returns A promise that resolves when the data has been successfully uploaded.
146
+ */
147
+ uploadDataToOpenlayer: (data: ChatCompletionData, config: ChatCompletionConfig) => Promise<void>;
148
+ /**
149
+ * Creates a new ChatCompletion instance. If monitoring is not active, an error is thrown.
150
+ * This function also measures latency and uploads data to Openlayer.
151
+ * @param body The parameters for creating a chat completion.
152
+ * @param options Optional request options.
153
+ * @throws Throws an error if monitoring is not active or if there is no output received from OpenAI.
154
+ * @returns A promise that resolves to a ChatCompletion or a Stream of ChatCompletionChunks.
155
+ */
25
156
  createChatCompletion: (body: ChatCompletionCreateParams, options?: RequestOptions) => Promise<ChatCompletion | Stream<ChatCompletionChunk>>;
157
+ /**
158
+ * Creates a new Completion instance. If monitoring is not active, an error is thrown.
159
+ * This function also measures latency and uploads data to Openlayer.
160
+ * @param body The parameters for creating a completion.
161
+ * @param options Optional request options.
162
+ * @throws Throws an error if monitoring is not active or if no prompt is provided.
163
+ * @returns A promise that resolves to a Completion or a Stream of Completions.
164
+ */
26
165
  createCompletion: (body: CompletionCreateParams, options?: RequestOptions) => Promise<Completion | Stream<Completion>>;
166
+ /**
167
+ * Creates a new inference pipeline in Openlayer, or loads an existing one if it already exists.
168
+ * @param name The name of the inference pipeline.
169
+ * @param projectId The project ID containing the inference pipeline.
170
+ * @throws Throws an error if the inference pipeline cannot be created or found.
171
+ * @returns A promise that resolves to an OpenlayerInferencePipeline object.
172
+ */
173
+ createInferencePipeline: (name: string, projectId: string) => Promise<OpenlayerInferencePipeline>;
174
+ /**
175
+ * Creates a new project in Openlayer, or loads an existing one if it already exists.
176
+ * @param name The name of the project.
177
+ * @param taskType The type of task associated with the project.
178
+ * @param description Optional description of the project.
179
+ * @throws Throws an error if the project cannot be created or found.
180
+ * @returns A promise that resolves to an OpenlayerProject object.
181
+ */
182
+ createProject: (name: string, taskType: OpenlayerTaskType, description?: string) => Promise<OpenlayerProject>;
183
+ /**
184
+ * Loads an existing inference pipeline from Openlayer based on its name and project ID.
185
+ * @param name The name of the inference pipeline.
186
+ * @param projectId The project ID containing the inference pipeline.
187
+ * @throws Throws an error if the inference pipeline is not found.
188
+ * @returns A promise that resolves to an OpenlayerInferencePipeline object.
189
+ */
190
+ loadInferencePipeline: (name: string, projectId: string) => Promise<OpenlayerInferencePipeline>;
191
+ loadProject: (name: string) => Promise<OpenlayerProject>;
192
+ /**
193
+ * Starts monitoring for the OpenAI Monitor instance. If monitoring is already active, a warning is logged.
194
+ */
195
+ startMonitoring(): void;
196
+ /**
197
+ * Stops monitoring for the OpenAI Monitor instance. If monitoring is not active, a warning is logged.
198
+ */
199
+ stopMonitoring(): void;
27
200
  }
28
201
  export default OpenAIMonitor;
package/dist/index.js CHANGED
@@ -22,6 +22,15 @@ const request_1 = require("./utils/request");
22
22
  class OpenAIMonitor {
23
23
  constructor({ openAiApiKey, openlayerApiKey, openlayerInferencePipelineName, openlayerProjectName, openlayerServerUrl, }) {
24
24
  this.monitoringOn = false;
25
+ this.openlayerDefaultDataConfig = {
26
+ groundTruthColumnName: null,
27
+ inferenceIdColumnName: 'id',
28
+ inputVariableNames: ['input'],
29
+ latencyColumnName: 'latency',
30
+ numOfTokenColumnName: 'tokens',
31
+ outputColumnName: 'output',
32
+ timestampColumnName: 'timestamp',
33
+ };
25
34
  this.openlayerServerUrl = 'https://api.openlayer.com/v1';
26
35
  this.version = '0.1.0a16';
27
36
  this.formatChatCompletionInput = (messages) => messages
@@ -30,115 +39,62 @@ class OpenAIMonitor {
30
39
  .join('\n')
31
40
  .trim();
32
41
  this.resolvedQuery = (endpoint, args = {}) => (0, request_1.resolvedQuery)(this.openlayerServerUrl, endpoint, args);
33
- this.uploadDataToOpenlayer = (data) => __awaiter(this, void 0, void 0, function* () {
34
- const uploadToInferencePipeline = (id) => __awaiter(this, void 0, void 0, function* () {
35
- const dataStreamEndpoint = `/inference-pipelines/${id}/data-stream`;
36
- const dataStreamQuery = this.resolvedQuery(dataStreamEndpoint);
37
- const response = yield fetch(dataStreamQuery, {
38
- body: JSON.stringify({
39
- config: {
40
- groundTruthColumnName: null,
41
- inferenceIdColumnName: 'id',
42
- inputVariableNames: ['input'],
43
- latencyColumnName: 'latency',
44
- numOfTokenColumnName: 'tokens',
45
- outputColumnName: 'output',
46
- timestampColumnName: 'timestamp',
47
- },
48
- rows: [
49
- Object.assign(Object.assign({}, data), { id: (0, uuid_1.v4)(), timestamp: data.timestamp / 1000 }),
50
- ],
51
- }),
52
- headers: {
53
- Authorization: `Bearer ${this.openlayerApiKey}`,
54
- 'Content-Type': 'application/json',
55
- },
56
- method: 'POST',
57
- });
58
- if (!response.ok) {
59
- console.error('Error making POST request:', response.status);
60
- throw new Error(`Error: ${response.status}`);
61
- }
62
- return yield response.json();
42
+ this.uploadToInferencePipeline = (inferencePipelineId, data, config) => __awaiter(this, void 0, void 0, function* () {
43
+ var _a;
44
+ const dataStreamEndpoint = `/inference-pipelines/${inferencePipelineId}/data-stream`;
45
+ const dataStreamQuery = this.resolvedQuery(dataStreamEndpoint);
46
+ const response = yield fetch(dataStreamQuery, {
47
+ body: JSON.stringify({
48
+ config,
49
+ rows: [
50
+ Object.assign(Object.assign({}, data), { id: (0, uuid_1.v4)(), timestamp: Math.round(((_a = data.timestamp) !== null && _a !== void 0 ? _a : Date.now()) / 1000) }),
51
+ ],
52
+ }),
53
+ headers: {
54
+ Authorization: `Bearer ${this.openlayerApiKey}`,
55
+ 'Content-Type': 'application/json',
56
+ },
57
+ method: 'POST',
63
58
  });
59
+ if (!response.ok) {
60
+ console.error('Error making POST request:', response.status);
61
+ throw new Error(`Error: ${response.status}`);
62
+ }
63
+ return yield response.json();
64
+ });
65
+ /**
66
+ * Uploads data to Openlayer. This function takes ChatCompletionData and an optional
67
+ * ChatCompletionConfig, then uploads the data to the specified Openlayer Inference Pipeline.
68
+ * @param data The ChatCompletionData to be uploaded.
69
+ * @param config Configuration for the data upload.
70
+ * @throws Throws an error if Openlayer API key or project name are not set.
71
+ * @returns A promise that resolves when the data has been successfully uploaded.
72
+ */
73
+ this.uploadDataToOpenlayer = (data, config) => __awaiter(this, void 0, void 0, function* () {
64
74
  if (!this.openlayerApiKey || !this.openlayerProjectName) {
65
75
  throw new Error('Openlayer API key and project name are required for publishing.');
66
76
  }
67
77
  try {
68
- const projectsEndpoint = '/projects';
69
- const projectsQueryParameters = {
70
- name: this.openlayerProjectName,
71
- version: this.version,
72
- };
73
- const projectsQuery = this.resolvedQuery(projectsEndpoint, projectsQueryParameters);
74
- const projectsResponse = yield fetch(projectsQuery, {
75
- headers: {
76
- Authorization: `Bearer ${this.openlayerApiKey}`,
77
- 'Content-Type': 'application/json',
78
- },
79
- method: 'GET',
80
- });
81
- const { items: projects } = yield projectsResponse.json();
82
- if (!Array.isArray(projects)) {
83
- throw new Error('Invalid response from Openlayer');
84
- }
85
- const project = projects.find(({ name }) => name === this.openlayerProjectName);
86
- if (!(project === null || project === void 0 ? void 0 : project.id)) {
87
- throw new Error('Project not found');
88
- }
89
- const inferencePipelineEndpoint = `/projects/${project.id}/inference-pipelines`;
90
- const inferencePipelineQueryParameters = {
91
- name: this.openlayerInferencePipelineName,
92
- version: this.version,
93
- };
94
- const inferencePipelineQuery = this.resolvedQuery(inferencePipelineEndpoint, inferencePipelineQueryParameters);
95
- const inferencePipelineResponse = yield fetch(inferencePipelineQuery, {
96
- headers: {
97
- Authorization: `Bearer ${this.openlayerApiKey}`,
98
- 'Content-Type': 'application/json',
99
- },
100
- method: 'GET',
101
- });
102
- const { items: inferencePipelines } = yield inferencePipelineResponse.json();
103
- const inferencePipeline = Array.isArray(inferencePipelines)
104
- ? inferencePipelines.find(({ name }) => typeof this.openlayerInferencePipelineName === 'undefined' ||
105
- name === this.openlayerInferencePipelineName)
106
- : undefined;
107
- if (inferencePipeline === null || inferencePipeline === void 0 ? void 0 : inferencePipeline.id) {
108
- const { id: inferencePipelineId } = inferencePipeline;
109
- yield uploadToInferencePipeline(inferencePipelineId);
110
- }
111
- else {
112
- const createInferencePipelineEndpoint = `/projects/${project.id}/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: typeof this.openlayerInferencePipelineName === 'undefined'
118
- ? 'production'
119
- : this.openlayerInferencePipelineName,
120
- }),
121
- headers: {
122
- Authorization: `Bearer ${this.openlayerApiKey}`,
123
- 'Content-Type': 'application/json',
124
- },
125
- method: 'POST',
126
- });
127
- const { id: inferencePipelineId } = yield createInferencePipelineResponse.json();
128
- if (!inferencePipelineId) {
129
- throw new Error('Error creating inference pipeline');
130
- }
131
- yield uploadToInferencePipeline(inferencePipelineId);
132
- }
78
+ const project = yield this.createProject(this.openlayerProjectName, 'llm-base');
79
+ const inferencePipeline = yield this.createInferencePipeline(this.openlayerProjectName, project.id);
80
+ yield this.uploadToInferencePipeline(inferencePipeline.id, data, config);
133
81
  }
134
82
  catch (error) {
135
83
  console.error('Error publishing data to Openlayer:', error);
136
84
  throw error;
137
85
  }
138
86
  });
87
+ /**
88
+ * Creates a new ChatCompletion instance. If monitoring is not active, an error is thrown.
89
+ * This function also measures latency and uploads data to Openlayer.
90
+ * @param body The parameters for creating a chat completion.
91
+ * @param options Optional request options.
92
+ * @throws Throws an error if monitoring is not active or if there is no output received from OpenAI.
93
+ * @returns A promise that resolves to a ChatCompletion or a Stream of ChatCompletionChunks.
94
+ */
139
95
  this.createChatCompletion = (body, options) => __awaiter(this, void 0, void 0, function* () {
140
- var _a, e_1, _b, _c;
141
- var _d, _e;
96
+ var _b, e_1, _c, _d;
97
+ var _e, _f;
142
98
  if (!this.monitoringOn) {
143
99
  throw new Error('Monitoring is not active.');
144
100
  }
@@ -150,10 +106,10 @@ class OpenAIMonitor {
150
106
  if (body.stream) {
151
107
  const streamedResponse = response;
152
108
  try {
153
- for (var _f = true, streamedResponse_1 = __asyncValues(streamedResponse), streamedResponse_1_1; streamedResponse_1_1 = yield streamedResponse_1.next(), _a = streamedResponse_1_1.done, !_a; _f = true) {
154
- _c = streamedResponse_1_1.value;
155
- _f = false;
156
- const chunk = _c;
109
+ 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) {
110
+ _d = streamedResponse_1_1.value;
111
+ _g = false;
112
+ const chunk = _d;
157
113
  // Process each chunk - for example, accumulate input data
158
114
  outputData += chunk.choices[0].delta.content;
159
115
  }
@@ -161,7 +117,7 @@ class OpenAIMonitor {
161
117
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
162
118
  finally {
163
119
  try {
164
- if (!_f && !_a && (_b = streamedResponse_1.return)) yield _b.call(streamedResponse_1);
120
+ if (!_g && !_b && (_c = streamedResponse_1.return)) yield _c.call(streamedResponse_1);
165
121
  }
166
122
  finally { if (e_1) throw e_1.error; }
167
123
  }
@@ -172,29 +128,44 @@ class OpenAIMonitor {
172
128
  latency,
173
129
  output: outputData,
174
130
  timestamp: startTime,
175
- });
131
+ }, this.openlayerDefaultDataConfig);
176
132
  }
177
133
  else {
178
134
  const nonStreamedResponse = response;
179
135
  // Handle regular (non-streamed) response
180
136
  const endTime = Date.now();
181
137
  const latency = endTime - startTime;
138
+ const output = nonStreamedResponse.choices[0].message.content;
139
+ if (typeof output !== 'string') {
140
+ throw new Error('No output received from OpenAI.');
141
+ }
182
142
  this.uploadDataToOpenlayer({
183
143
  input: this.formatChatCompletionInput(body.messages),
184
144
  latency,
185
- output: nonStreamedResponse.choices[0].message.content,
145
+ output,
186
146
  timestamp: startTime,
187
- tokens: (_e = (_d = nonStreamedResponse.usage) === null || _d === void 0 ? void 0 : _d.total_tokens) !== null && _e !== void 0 ? _e : 0,
188
- });
147
+ tokens: (_f = (_e = nonStreamedResponse.usage) === null || _e === void 0 ? void 0 : _e.total_tokens) !== null && _f !== void 0 ? _f : 0,
148
+ }, this.openlayerDefaultDataConfig);
189
149
  }
190
150
  return response;
191
151
  });
152
+ /**
153
+ * Creates a new Completion instance. If monitoring is not active, an error is thrown.
154
+ * This function also measures latency and uploads data to Openlayer.
155
+ * @param body The parameters for creating a completion.
156
+ * @param options Optional request options.
157
+ * @throws Throws an error if monitoring is not active or if no prompt is provided.
158
+ * @returns A promise that resolves to a Completion or a Stream of Completions.
159
+ */
192
160
  this.createCompletion = (body, options) => __awaiter(this, void 0, void 0, function* () {
193
- var _g, e_2, _h, _j;
194
- var _k, _l, _m, _o;
161
+ var _h, e_2, _j, _k;
162
+ var _l, _m, _o, _p;
195
163
  if (!this.monitoringOn) {
196
164
  throw new Error('Monitoring is not active.');
197
165
  }
166
+ if (!body.prompt) {
167
+ throw new Error('No prompt provided.');
168
+ }
198
169
  // Start a timer to measure latency
199
170
  const startTime = Date.now();
200
171
  // Accumulate output and tokens data for streamed responses
@@ -204,19 +175,19 @@ class OpenAIMonitor {
204
175
  if (body.stream) {
205
176
  const streamedResponse = response;
206
177
  try {
207
- for (var _p = true, streamedResponse_2 = __asyncValues(streamedResponse), streamedResponse_2_1; streamedResponse_2_1 = yield streamedResponse_2.next(), _g = streamedResponse_2_1.done, !_g; _p = true) {
208
- _j = streamedResponse_2_1.value;
209
- _p = false;
210
- const chunk = _j;
178
+ 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) {
179
+ _k = streamedResponse_2_1.value;
180
+ _q = false;
181
+ const chunk = _k;
211
182
  // Process each chunk - for example, accumulate input data
212
183
  outputData += chunk.choices[0].text.trim();
213
- tokensData += (_l = (_k = chunk.usage) === null || _k === void 0 ? void 0 : _k.total_tokens) !== null && _l !== void 0 ? _l : 0;
184
+ tokensData += (_m = (_l = chunk.usage) === null || _l === void 0 ? void 0 : _l.total_tokens) !== null && _m !== void 0 ? _m : 0;
214
185
  }
215
186
  }
216
187
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
217
188
  finally {
218
189
  try {
219
- if (!_p && !_g && (_h = streamedResponse_2.return)) yield _h.call(streamedResponse_2);
190
+ if (!_q && !_h && (_j = streamedResponse_2.return)) yield _j.call(streamedResponse_2);
220
191
  }
221
192
  finally { if (e_2) throw e_2.error; }
222
193
  }
@@ -228,7 +199,7 @@ class OpenAIMonitor {
228
199
  output: outputData,
229
200
  timestamp: startTime,
230
201
  tokens: tokensData,
231
- });
202
+ }, this.openlayerDefaultDataConfig);
232
203
  }
233
204
  else {
234
205
  const nonStreamedResponse = response;
@@ -240,11 +211,137 @@ class OpenAIMonitor {
240
211
  latency,
241
212
  output: nonStreamedResponse.choices[0].text,
242
213
  timestamp: startTime,
243
- tokens: (_o = (_m = nonStreamedResponse.usage) === null || _m === void 0 ? void 0 : _m.total_tokens) !== null && _o !== void 0 ? _o : 0,
244
- });
214
+ tokens: (_p = (_o = nonStreamedResponse.usage) === null || _o === void 0 ? void 0 : _o.total_tokens) !== null && _p !== void 0 ? _p : 0,
215
+ }, this.openlayerDefaultDataConfig);
245
216
  }
246
217
  return response;
247
218
  });
219
+ /**
220
+ * Creates a new inference pipeline in Openlayer, or loads an existing one if it already exists.
221
+ * @param name The name of the inference pipeline.
222
+ * @param projectId The project ID containing the inference pipeline.
223
+ * @throws Throws an error if the inference pipeline cannot be created or found.
224
+ * @returns A promise that resolves to an OpenlayerInferencePipeline object.
225
+ */
226
+ this.createInferencePipeline = (name, projectId) => __awaiter(this, void 0, void 0, function* () {
227
+ try {
228
+ return yield this.loadInferencePipeline(name, projectId);
229
+ }
230
+ catch (_r) {
231
+ const createInferencePipelineEndpoint = `/projects/${projectId}/inference-pipelines`;
232
+ const createInferencePipelineQuery = this.resolvedQuery(createInferencePipelineEndpoint, { version: this.version });
233
+ const createInferencePipelineResponse = yield fetch(createInferencePipelineQuery, {
234
+ body: JSON.stringify({
235
+ description: '',
236
+ name: typeof this.openlayerInferencePipelineName === 'undefined'
237
+ ? 'production'
238
+ : this.openlayerInferencePipelineName,
239
+ }),
240
+ headers: {
241
+ Authorization: `Bearer ${this.openlayerApiKey}`,
242
+ 'Content-Type': 'application/json',
243
+ },
244
+ method: 'POST',
245
+ });
246
+ const inferencePipeline = yield createInferencePipelineResponse.json();
247
+ if (!(inferencePipeline === null || inferencePipeline === void 0 ? void 0 : inferencePipeline.id)) {
248
+ throw new Error('Error creating inference pipeline');
249
+ }
250
+ return inferencePipeline;
251
+ }
252
+ });
253
+ /**
254
+ * Creates a new project in Openlayer, or loads an existing one if it already exists.
255
+ * @param name The name of the project.
256
+ * @param taskType The type of task associated with the project.
257
+ * @param description Optional description of the project.
258
+ * @throws Throws an error if the project cannot be created or found.
259
+ * @returns A promise that resolves to an OpenlayerProject object.
260
+ */
261
+ this.createProject = (name, taskType, description) => __awaiter(this, void 0, void 0, function* () {
262
+ try {
263
+ return yield this.loadProject(name);
264
+ }
265
+ catch (_s) {
266
+ const projectsEndpoint = '/projects';
267
+ const projectsQuery = this.resolvedQuery(projectsEndpoint);
268
+ const projectsResponse = yield fetch(projectsQuery, {
269
+ body: JSON.stringify({
270
+ description,
271
+ name,
272
+ taskType,
273
+ }),
274
+ headers: {
275
+ Authorization: `Bearer ${this.openlayerApiKey}`,
276
+ 'Content-Type': 'application/json',
277
+ },
278
+ method: 'POST',
279
+ });
280
+ const { items: projects } = yield projectsResponse.json();
281
+ if (!Array.isArray(projects)) {
282
+ throw new Error('Invalid response from Openlayer');
283
+ }
284
+ const project = projects.find((p) => p.name === name);
285
+ if (!(project === null || project === void 0 ? void 0 : project.id)) {
286
+ throw new Error('Project not found');
287
+ }
288
+ return project;
289
+ }
290
+ });
291
+ /**
292
+ * Loads an existing inference pipeline from Openlayer based on its name and project ID.
293
+ * @param name The name of the inference pipeline.
294
+ * @param projectId The project ID containing the inference pipeline.
295
+ * @throws Throws an error if the inference pipeline is not found.
296
+ * @returns A promise that resolves to an OpenlayerInferencePipeline object.
297
+ */
298
+ this.loadInferencePipeline = (name, projectId) => __awaiter(this, void 0, void 0, function* () {
299
+ const inferencePipelineEndpoint = `/projects/${projectId}/inference-pipelines`;
300
+ const inferencePipelineQueryParameters = {
301
+ name: this.openlayerInferencePipelineName,
302
+ version: this.version,
303
+ };
304
+ const inferencePipelineQuery = this.resolvedQuery(inferencePipelineEndpoint, inferencePipelineQueryParameters);
305
+ const inferencePipelineResponse = yield fetch(inferencePipelineQuery, {
306
+ headers: {
307
+ Authorization: `Bearer ${this.openlayerApiKey}`,
308
+ 'Content-Type': 'application/json',
309
+ },
310
+ method: 'GET',
311
+ });
312
+ const { items: inferencePipelines } = yield inferencePipelineResponse.json();
313
+ const inferencePipeline = Array.isArray(inferencePipelines)
314
+ ? inferencePipelines.find((p) => p.name === name)
315
+ : undefined;
316
+ if (!(inferencePipeline === null || inferencePipeline === void 0 ? void 0 : inferencePipeline.id)) {
317
+ throw new Error('Inference pipeline not found');
318
+ }
319
+ return inferencePipeline;
320
+ });
321
+ this.loadProject = (name) => __awaiter(this, void 0, void 0, function* () {
322
+ const projectsEndpoint = '/projects';
323
+ const projectsQueryParameters = {
324
+ name,
325
+ version: this.version,
326
+ };
327
+ const projectsQuery = this.resolvedQuery(projectsEndpoint, projectsQueryParameters);
328
+ const projectsResponse = yield fetch(projectsQuery, {
329
+ headers: {
330
+ Authorization: `Bearer ${this.openlayerApiKey}`,
331
+ 'Content-Type': 'application/json',
332
+ },
333
+ method: 'GET',
334
+ });
335
+ const { items: projects } = yield projectsResponse.json();
336
+ if (!Array.isArray(projects)) {
337
+ throw new Error('Invalid response from Openlayer');
338
+ }
339
+ const project = projects.find((p) => p.name === name);
340
+ if (!(project === null || project === void 0 ? void 0 : project.id)) {
341
+ throw new Error('Project not found');
342
+ }
343
+ return project;
344
+ });
248
345
  this.OpenAIClient = new openai_1.default({
249
346
  apiKey: openAiApiKey,
250
347
  dangerouslyAllowBrowser: true,
@@ -259,6 +356,9 @@ class OpenAIMonitor {
259
356
  throw new Error('Openlayer API key and project name are required for publishing.');
260
357
  }
261
358
  }
359
+ /**
360
+ * Starts monitoring for the OpenAI Monitor instance. If monitoring is already active, a warning is logged.
361
+ */
262
362
  startMonitoring() {
263
363
  if (this.monitoringOn) {
264
364
  console.warn('Monitoring is already on!');
@@ -267,6 +367,9 @@ class OpenAIMonitor {
267
367
  this.monitoringOn = true;
268
368
  console.info('Monitoring started.');
269
369
  }
370
+ /**
371
+ * Stops monitoring for the OpenAI Monitor instance. If monitoring is not active, a warning is logged.
372
+ */
270
373
  stopMonitoring() {
271
374
  if (!this.monitoringOn) {
272
375
  console.warn('Monitoring is not active.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openlayer",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "The Openlayer TypeScript client",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",