@proteinjs/conversation 1.7.5 → 2.0.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/src/OpenAi.ts CHANGED
@@ -15,75 +15,95 @@ import { ChatCompletionMessageParamFactory } from './ChatCompletionMessageParamF
15
15
  import { Stream } from 'openai/streaming';
16
16
  import { Readable } from 'stream';
17
17
  import { OpenAiStreamProcessor } from './OpenAiStreamProcessor';
18
+ import { UsageData, UsageDataAccumulator } from './UsageData';
18
19
 
19
20
  function delay(ms: number) {
20
21
  return new Promise((resolve) => setTimeout(resolve, ms));
21
22
  }
22
23
 
24
+ export type GenerateResponseParams = {
25
+ messages: (string | ChatCompletionMessageParam)[];
26
+ model?: TiktokenModel;
27
+ };
28
+
29
+ export type GenerateResponseReturn = {
30
+ message: string;
31
+ usagedata: UsageData;
32
+ };
33
+
34
+ export type GenerateStreamingResponseParams = GenerateResponseParams & {
35
+ abortSignal?: AbortSignal;
36
+ onUsageData?: (usageData: UsageData) => Promise<void>;
37
+ };
38
+
39
+ type GenerateResponseHelperParams = GenerateStreamingResponseParams & {
40
+ model: TiktokenModel;
41
+ stream: boolean;
42
+ currentFunctionCalls?: number;
43
+ usageDataAccumulator?: UsageDataAccumulator;
44
+ };
45
+
46
+ export type OpenAiParams = {
47
+ model?: TiktokenModel;
48
+ history?: MessageHistory;
49
+ functions?: Omit<Function, 'instructions'>[];
50
+ messageModerators?: MessageModerator[];
51
+ maxFunctionCalls?: number;
52
+ logLevel?: LogLevel;
53
+ };
54
+
23
55
  export const DEFAULT_MODEL: TiktokenModel = 'gpt-3.5-turbo';
56
+ export const DEFAULT_MAX_FUNCTION_CALLS = 50;
57
+
24
58
  export class OpenAi {
25
- static async generateResponse(
26
- messages: (string | ChatCompletionMessageParam)[],
27
- model?: string,
28
- history?: MessageHistory,
29
- functions?: Omit<Function, 'instructions'>[],
30
- messageModerators?: MessageModerator[],
31
- logLevel: LogLevel = 'info',
32
- maxFunctionCalls: number = 50
33
- ): Promise<string> {
34
- return (await this.generateResponseHelper(
35
- messages,
36
- false,
37
- 0,
38
- model,
39
- history,
40
- functions,
41
- messageModerators,
42
- undefined,
43
- logLevel,
44
- maxFunctionCalls
45
- )) as string;
59
+ private model: TiktokenModel;
60
+ private history: MessageHistory;
61
+ private functions?: Omit<Function, 'instructions'>[];
62
+ private messageModerators?: MessageModerator[];
63
+ private maxFunctionCalls: number;
64
+ private logLevel?: LogLevel;
65
+
66
+ constructor({
67
+ model = DEFAULT_MODEL,
68
+ history = new MessageHistory(),
69
+ functions,
70
+ messageModerators,
71
+ maxFunctionCalls = DEFAULT_MAX_FUNCTION_CALLS,
72
+ logLevel,
73
+ }: OpenAiParams = {}) {
74
+ this.model = model;
75
+ this.history = history;
76
+ this.functions = functions;
77
+ this.messageModerators = messageModerators;
78
+ this.maxFunctionCalls = maxFunctionCalls;
79
+ this.logLevel = logLevel;
46
80
  }
47
81
 
48
- static async generateStreamingResponse(
49
- messages: (string | ChatCompletionMessageParam)[],
50
- model?: string,
51
- history?: MessageHistory,
52
- functions?: Omit<Function, 'instructions'>[],
53
- messageModerators?: MessageModerator[],
54
- abortSignal?: AbortSignal,
55
- logLevel: LogLevel = 'info',
56
- maxFunctionCalls: number = 50
57
- ): Promise<Readable> {
58
- return (await this.generateResponseHelper(
59
- messages,
60
- true,
61
- 0,
62
- model,
63
- history,
64
- functions,
65
- messageModerators,
66
- abortSignal,
67
- logLevel,
68
- maxFunctionCalls
69
- )) as Readable;
82
+ async generateResponse({ model, ...rest }: GenerateResponseParams): Promise<GenerateResponseReturn> {
83
+ return (await this.generateResponseHelper({
84
+ model: model ?? this.model,
85
+ stream: false,
86
+ ...rest,
87
+ })) as GenerateResponseReturn;
70
88
  }
71
89
 
72
- static async generateResponseHelper(
73
- messages: (string | ChatCompletionMessageParam)[],
74
- stream: boolean,
75
- currentFunctionCalls: number,
76
- model?: string,
77
- history?: MessageHistory,
78
- functions?: Omit<Function, 'instructions'>[],
79
- messageModerators?: MessageModerator[],
80
- abortSignal?: AbortSignal,
81
- logLevel: LogLevel = 'info',
82
- maxFunctionCalls: number = 50
83
- ): Promise<string | Readable> {
84
- const logger = new Logger({ name: 'OpenAi.generateResponseHelper', logLevel });
85
- const updatedHistory = OpenAi.getUpdatedMessageHistory(messages, history, messageModerators);
86
- const response = await OpenAi.executeRequest(updatedHistory, stream, logLevel, functions, model, abortSignal);
90
+ async generateStreamingResponse({ model, ...rest }: GenerateStreamingResponseParams): Promise<Readable> {
91
+ return (await this.generateResponseHelper({ model: model ?? this.model, stream: true, ...rest })) as Readable;
92
+ }
93
+
94
+ private async generateResponseHelper({
95
+ messages,
96
+ model,
97
+ stream,
98
+ abortSignal,
99
+ onUsageData,
100
+ usageDataAccumulator,
101
+ currentFunctionCalls = 0,
102
+ }: GenerateResponseHelperParams): Promise<GenerateResponseReturn | Readable> {
103
+ const logger = new Logger({ name: 'OpenAi.generateResponseHelper', logLevel: this.logLevel });
104
+ this.updateMessageHistory(messages);
105
+ const resolvedUsageDataAccumulator = usageDataAccumulator ?? new UsageDataAccumulator({ model });
106
+ const response = await this.executeRequest(model, stream, resolvedUsageDataAccumulator, abortSignal);
87
107
  if (stream) {
88
108
  logger.info({ message: `Processing response stream` });
89
109
  const inputStream = response as Stream<ChatCompletionChunk>;
@@ -95,35 +115,36 @@ export class OpenAi {
95
115
 
96
116
  // For the initial call to `generateResponseHelper`, return the `OpenAiStreamProcessor` output stream
97
117
  const onToolCalls = ((toolCalls, currentFunctionCalls) =>
98
- OpenAi.handleToolCalls(
118
+ this.handleToolCalls(
99
119
  toolCalls,
100
- true,
101
- currentFunctionCalls,
102
- updatedHistory,
103
120
  model,
104
- functions,
105
- messageModerators,
121
+ stream,
122
+ currentFunctionCalls,
123
+ resolvedUsageDataAccumulator,
106
124
  abortSignal,
107
- logLevel,
108
- maxFunctionCalls
125
+ onUsageData
109
126
  )) as (toolCalls: ChatCompletionMessageToolCall[], currentFunctionCalls: number) => Promise<Readable>;
110
- const streamProcessor = new OpenAiStreamProcessor(inputStream, onToolCalls, logLevel, abortSignal);
127
+ const streamProcessor = new OpenAiStreamProcessor(
128
+ inputStream,
129
+ onToolCalls,
130
+ resolvedUsageDataAccumulator,
131
+ this.logLevel,
132
+ abortSignal,
133
+ onUsageData
134
+ );
111
135
  return streamProcessor.getOutputStream();
112
136
  }
113
137
 
114
138
  const responseMessage = (response as ChatCompletion).choices[0].message;
115
139
  if (responseMessage.tool_calls) {
116
- return await OpenAi.handleToolCalls(
140
+ return await this.handleToolCalls(
117
141
  responseMessage.tool_calls,
142
+ model,
118
143
  stream,
119
144
  currentFunctionCalls,
120
- updatedHistory,
121
- model,
122
- functions,
123
- messageModerators,
145
+ resolvedUsageDataAccumulator,
124
146
  abortSignal,
125
- logLevel,
126
- maxFunctionCalls
147
+ onUsageData
127
148
  );
128
149
  }
129
150
 
@@ -132,15 +153,11 @@ export class OpenAi {
132
153
  throw new Error(`Response was empty for messages: ${messages.join('\n')}`);
133
154
  }
134
155
 
135
- updatedHistory.push([responseMessage]);
136
- return responseText;
156
+ this.history.push([responseMessage]);
157
+ return { message: responseText, usagedata: resolvedUsageDataAccumulator.usageData };
137
158
  }
138
159
 
139
- private static getUpdatedMessageHistory(
140
- messages: (string | ChatCompletionMessageParam)[],
141
- history?: MessageHistory,
142
- messageModerators?: MessageModerator[]
143
- ) {
160
+ private updateMessageHistory(messages: (string | ChatCompletionMessageParam)[]) {
144
161
  const messageParams: ChatCompletionMessageParam[] = messages.map((message) => {
145
162
  if (typeof message === 'string') {
146
163
  return { role: 'user', content: message };
@@ -148,69 +165,56 @@ export class OpenAi {
148
165
 
149
166
  return message;
150
167
  });
151
- if (history) {
152
- history.push(messageParams);
153
- }
154
- let messageParamsWithHistory = history ? history : new MessageHistory().push(messageParams);
155
- if (messageModerators) {
156
- messageParamsWithHistory = OpenAi.moderateHistory(messageParamsWithHistory, messageModerators);
168
+ this.history.push(messageParams);
169
+ if (this.messageModerators) {
170
+ this.moderateHistory(this.history, this.messageModerators);
157
171
  }
158
-
159
- return messageParamsWithHistory;
160
172
  }
161
173
 
162
- private static moderateHistory(history: MessageHistory, messageModerators: MessageModerator[]) {
174
+ private moderateHistory(history: MessageHistory, messageModerators: MessageModerator[]) {
163
175
  for (const messageModerator of messageModerators) {
164
176
  history.setMessages(messageModerator.observe(history.getMessages()));
165
177
  }
166
-
167
- return history;
168
178
  }
169
179
 
170
- private static async executeRequest(
171
- messageParamsWithHistory: MessageHistory,
180
+ private async executeRequest(
181
+ model: TiktokenModel,
172
182
  stream: boolean,
173
- logLevel: LogLevel,
174
- functions?: Omit<Function, 'instructions'>[],
175
- model?: string,
183
+ usageDataAccumulator: UsageDataAccumulator,
176
184
  abortSignal?: AbortSignal
177
185
  ): Promise<ChatCompletion | Stream<ChatCompletionChunk>> {
178
- const logger = new Logger({ name: 'OpenAi.executeRequest', logLevel });
186
+ const logger = new Logger({ name: 'OpenAi.executeRequest', logLevel: this.logLevel });
179
187
  const openaiApi = new OpenAIApi();
180
188
  try {
181
- const latestMessage = messageParamsWithHistory.getMessages()[messageParamsWithHistory.getMessages().length - 1];
182
- this.logRequestDetails(logger, logLevel, latestMessage, messageParamsWithHistory);
189
+ const latestMessage = this.history.getMessages()[this.history.getMessages().length - 1];
190
+ this.logRequestDetails(logger, latestMessage);
183
191
 
184
192
  const response = await openaiApi.chat.completions.create(
185
193
  {
186
- model: model ? model : DEFAULT_MODEL,
194
+ model,
187
195
  temperature: 0,
188
- messages: messageParamsWithHistory.getMessages(),
189
- tools: functions?.map((f) => ({
196
+ messages: this.history.getMessages(),
197
+ tools: this.functions?.map((f) => ({
190
198
  type: 'function',
191
199
  function: f.definition,
192
200
  })),
193
201
  stream: stream,
202
+ ...(stream && { stream_options: { include_usage: true } }),
194
203
  },
195
204
  { signal: abortSignal }
196
205
  );
197
206
 
198
207
  if (!stream) {
199
- this.logResponseDetails(logger, response as ChatCompletion);
208
+ this.logResponseDetails(logger, response as ChatCompletion, usageDataAccumulator);
200
209
  }
201
210
 
202
211
  return response;
203
212
  } catch (error: any) {
204
- return this.handleRequestError(logger, error, messageParamsWithHistory, stream, logLevel, functions, model);
213
+ return this.handleRequestError(model, logger, error, stream, usageDataAccumulator, abortSignal);
205
214
  }
206
215
  }
207
216
 
208
- private static logRequestDetails(
209
- logger: Logger,
210
- logLevel: LogLevel,
211
- latestMessage: ChatCompletionMessageParam,
212
- messageParamsWithHistory: MessageHistory
213
- ) {
217
+ private logRequestDetails(logger: Logger, latestMessage: ChatCompletionMessageParam) {
214
218
  if (latestMessage.role == 'tool') {
215
219
  logger.info({ message: `Sending request: returning output of tool call (${latestMessage.tool_call_id})` });
216
220
  } else if (latestMessage.content) {
@@ -225,12 +229,10 @@ export class OpenAi {
225
229
  logger.info({ message: `Sending request` });
226
230
  }
227
231
 
228
- if (logLevel === 'debug') {
229
- logger.debug({ message: `Sending messages:`, obj: { messages: messageParamsWithHistory.getMessages() } });
230
- }
232
+ logger.debug({ message: `Sending messages:`, obj: { messages: this.history.getMessages() } });
231
233
  }
232
234
 
233
- private static logResponseDetails(logger: Logger, response: ChatCompletion) {
235
+ private logResponseDetails(logger: Logger, response: ChatCompletion, usageDataAccumulator: UsageDataAccumulator) {
234
236
  const responseMessage = response.choices[0].message;
235
237
  if (responseMessage.content) {
236
238
  logger.info({ message: `Received response`, obj: { response: responseMessage.content } });
@@ -244,19 +246,23 @@ export class OpenAi {
244
246
  }
245
247
  if (response.usage) {
246
248
  logger.info({ message: `Usage data`, obj: { usageData: response.usage } });
249
+ usageDataAccumulator.addTokenUsage({
250
+ promptTokens: response.usage.prompt_tokens,
251
+ completionTokens: response.usage.completion_tokens,
252
+ totalTokens: response.usage.total_tokens,
253
+ });
247
254
  } else {
248
255
  logger.info({ message: `Usage data missing` });
249
256
  }
250
257
  }
251
258
 
252
- private static async handleRequestError(
259
+ private async handleRequestError(
260
+ model: TiktokenModel,
253
261
  logger: Logger,
254
262
  error: any,
255
- messageParamsWithHistory: MessageHistory,
256
263
  stream: boolean,
257
- logLevel: LogLevel,
258
- functions?: Omit<Function, 'instructions'>[],
259
- model?: string
264
+ usageDataAccumulator: UsageDataAccumulator,
265
+ abortSignal?: AbortSignal
260
266
  ): Promise<ChatCompletion | Stream<ChatCompletionChunk>> {
261
267
  if (error.type) {
262
268
  logger.info({ message: `Received error response, error type: ${error.type}` });
@@ -267,29 +273,27 @@ export class OpenAi {
267
273
  const remainingTokens = error.headers['x-ratelimit-remaining-tokens'];
268
274
  const delayMs = 15000;
269
275
  logger.warn({
270
- message: `Waiting to retry in ${delayMs / 1000}s, token reset in: ${waitTime}s, remaining tokens: ${remainingTokens}`,
276
+ message: `Waiting to retry due to throttling`,
277
+ obj: { retryDelay: `${delayMs / 1000}s`, tokenResetWaitTime: `${waitTime}s`, remainingTokens },
271
278
  });
272
279
  await delay(delayMs);
273
- return await OpenAi.executeRequest(messageParamsWithHistory, stream, logLevel, functions, model);
280
+ return await this.executeRequest(model, stream, usageDataAccumulator, abortSignal);
274
281
  }
275
282
  }
276
283
  throw error;
277
284
  }
278
285
 
279
- private static async handleToolCalls(
286
+ private async handleToolCalls(
280
287
  toolCalls: ChatCompletionMessageToolCall[],
288
+ model: TiktokenModel,
281
289
  stream: boolean,
282
290
  currentFunctionCalls: number,
283
- history: MessageHistory,
284
- model?: string,
285
- functions?: Omit<Function, 'instructions'>[],
286
- messageModerators?: MessageModerator[],
291
+ usageDataAccumulator: UsageDataAccumulator,
287
292
  abortSignal?: AbortSignal,
288
- logLevel: LogLevel = 'info',
289
- maxFunctionCalls: number = 50
290
- ): Promise<string | Readable> {
291
- if (currentFunctionCalls >= maxFunctionCalls) {
292
- throw new Error(`Max function calls (${maxFunctionCalls}) reached. Stopping execution.`);
293
+ onUsageData?: (usageData: UsageData) => Promise<void>
294
+ ): Promise<GenerateResponseReturn | Readable> {
295
+ if (currentFunctionCalls >= this.maxFunctionCalls) {
296
+ throw new Error(`Max function calls (${this.maxFunctionCalls}) reached. Stopping execution.`);
293
297
  }
294
298
 
295
299
  // Create a message for the tool calls
@@ -300,60 +304,53 @@ export class OpenAi {
300
304
  };
301
305
 
302
306
  // Add the tool call message to the history
303
- history.push([toolCallMessage]);
307
+ this.history.push([toolCallMessage]);
304
308
 
305
309
  // Call the tools and get the responses
306
- const toolMessageParams = await this.callTools(logLevel, toolCalls, functions);
310
+ const toolMessageParams = await this.callTools(toolCalls, usageDataAccumulator);
307
311
 
308
312
  // Add the tool responses to the history
309
- history.push(toolMessageParams);
313
+ this.history.push(toolMessageParams);
310
314
 
311
315
  // Generate the next response
312
- return this.generateResponseHelper(
313
- [],
314
- stream,
315
- currentFunctionCalls + toolCalls.length,
316
+ return this.generateResponseHelper({
317
+ messages: [],
316
318
  model,
317
- history,
318
- functions,
319
- messageModerators,
319
+ stream,
320
320
  abortSignal,
321
- logLevel,
322
- maxFunctionCalls
323
- );
321
+ onUsageData,
322
+ usageDataAccumulator,
323
+ currentFunctionCalls: currentFunctionCalls + toolCalls.length,
324
+ });
324
325
  }
325
326
 
326
- private static async callTools(
327
- logLevel: LogLevel,
327
+ private async callTools(
328
328
  toolCalls: ChatCompletionMessageToolCall[],
329
- functions?: Omit<Function, 'instructions'>[]
329
+ usageDataAccumulator: UsageDataAccumulator
330
330
  ): Promise<ChatCompletionMessageParam[]> {
331
331
  const toolMessageParams: ChatCompletionMessageParam[] = (
332
332
  await Promise.all(
333
- toolCalls.map(
334
- async (toolCall) => await OpenAi.callFunction(logLevel, toolCall.function, toolCall.id, functions)
335
- )
333
+ toolCalls.map(async (toolCall) => await this.callFunction(toolCall.function, toolCall.id, usageDataAccumulator))
336
334
  )
337
335
  ).reduce((acc, val) => acc.concat(val), []);
338
336
 
339
337
  return toolMessageParams;
340
338
  }
341
339
 
342
- private static async callFunction(
343
- logLevel: LogLevel,
340
+ private async callFunction(
344
341
  functionCall: ChatCompletionMessageToolCall.Function,
345
342
  toolCallId: string,
346
- functions?: Omit<Function, 'instructions'>[]
343
+ usageDataAccumulator: UsageDataAccumulator
347
344
  ): Promise<ChatCompletionMessageParam[]> {
348
- const logger = new Logger({ name: 'OpenAi.callFunction', logLevel });
349
- if (!functions) {
345
+ const logger = new Logger({ name: 'OpenAi.callFunction', logLevel: this.logLevel });
346
+ if (!this.functions) {
350
347
  const errorMessage = `Assistant attempted to call a function when no functions were provided`;
351
348
  logger.error({ message: errorMessage });
352
349
  return [{ role: 'tool', tool_call_id: toolCallId, content: JSON.stringify({ error: errorMessage }) }];
353
350
  }
354
351
 
355
352
  functionCall.name = functionCall.name.split('.').pop() as string;
356
- const f = functions.find((f) => f.definition.name === functionCall.name);
353
+ const f = this.functions.find((f) => f.definition.name === functionCall.name);
357
354
  if (!f) {
358
355
  const errorMessage = `Assistant attempted to call nonexistent function`;
359
356
  logger.error({ message: errorMessage, obj: { functionName: functionCall.name } });
@@ -372,6 +369,7 @@ export class OpenAi {
372
369
  message: `Assistant calling function: (${toolCallId}) ${f.definition.name}`,
373
370
  obj: { toolCallId, functionName: f.definition.name, args: parsedArguments },
374
371
  });
372
+ usageDataAccumulator.recordToolCall(f.definition.name);
375
373
  const returnObject = await f.call(parsedArguments);
376
374
 
377
375
  const returnObjectCompletionParams: ChatCompletionMessageParam[] = [];
@@ -424,15 +422,15 @@ export class OpenAi {
424
422
  }
425
423
  }
426
424
 
427
- static async generateCode(
428
- messages: (string | ChatCompletionMessageParam)[],
429
- model?: string,
430
- history?: MessageHistory,
431
- functions?: Omit<Function, 'instructions'>[],
432
- messageModerators?: MessageModerator[],
433
- includeSystemMessages: boolean = true,
434
- logLevel: LogLevel = 'info'
435
- ) {
425
+ async generateCode({
426
+ messages,
427
+ model,
428
+ includeSystemMessages = true,
429
+ }: {
430
+ messages: (string | ChatCompletionMessageParam)[];
431
+ model?: TiktokenModel;
432
+ includeSystemMessages?: boolean;
433
+ }) {
436
434
  const systemMessages: ChatCompletionMessageParam[] = [
437
435
  {
438
436
  role: 'system',
@@ -443,36 +441,29 @@ export class OpenAi {
443
441
  { role: 'system', content: 'Export all functions and objects generated.' },
444
442
  { role: 'system', content: 'Do not omit function implementations.' },
445
443
  ];
446
- const resolvedHistory = history
447
- ? includeSystemMessages
448
- ? history.push(systemMessages)
449
- : history
450
- : includeSystemMessages
451
- ? new MessageHistory().push(systemMessages)
452
- : undefined;
453
- const code = await this.generateResponse(messages, model, resolvedHistory, functions, messageModerators, logLevel);
454
- return this.parseCodeFromMarkdown(code);
444
+ if (includeSystemMessages) {
445
+ this.history.push(systemMessages);
446
+ }
447
+ const { message } = await this.generateResponse({ messages, model });
448
+ return OpenAi.parseCodeFromMarkdown(message);
455
449
  }
456
450
 
457
- static async updateCode(
458
- code: string,
459
- description: string,
460
- model?: string,
461
- history?: MessageHistory,
462
- functions?: Omit<Function, 'instructions'>[],
463
- messageModerators?: MessageModerator[],
464
- includeSystemMessages: boolean = true,
465
- logLevel: LogLevel = 'info'
466
- ) {
467
- return await this.generateCode(
468
- [this.updateCodeDescription(code, description)],
451
+ async updateCode({
452
+ code,
453
+ description,
454
+ model,
455
+ includeSystemMessages = true,
456
+ }: {
457
+ code: string;
458
+ description: string;
459
+ model?: TiktokenModel;
460
+ includeSystemMessages?: boolean;
461
+ }) {
462
+ return await this.generateCode({
463
+ messages: [OpenAi.updateCodeDescription(code, description)],
469
464
  model,
470
- history,
471
- functions,
472
- messageModerators,
473
465
  includeSystemMessages,
474
- logLevel
475
- );
466
+ });
476
467
  }
477
468
 
478
469
  static updateCodeDescription(code: string, description: string) {
@@ -508,15 +499,15 @@ export class OpenAi {
508
499
  return filteredLines.join('\n');
509
500
  }
510
501
 
511
- static async generateList(
512
- messages: (string | ChatCompletionMessageParam)[],
513
- model?: string,
514
- history?: MessageHistory,
515
- functions?: Omit<Function, 'instructions'>[],
516
- messageModerators?: MessageModerator[],
517
- includeSystemMessages: boolean = true,
518
- logLevel: LogLevel = 'info'
519
- ): Promise<string[]> {
502
+ async generateList({
503
+ messages,
504
+ model,
505
+ includeSystemMessages = true,
506
+ }: {
507
+ messages: (string | ChatCompletionMessageParam)[];
508
+ model?: TiktokenModel;
509
+ includeSystemMessages?: boolean;
510
+ }): Promise<string[]> {
520
511
  const systemMessages: ChatCompletionMessageParam[] = [
521
512
  {
522
513
  role: 'system',
@@ -524,14 +515,10 @@ export class OpenAi {
524
515
  },
525
516
  { role: 'system', content: 'Separate each item in the list by a ;' },
526
517
  ];
527
- const resolvedHistory = history
528
- ? includeSystemMessages
529
- ? history.push(systemMessages)
530
- : history
531
- : includeSystemMessages
532
- ? new MessageHistory().push(systemMessages)
533
- : undefined;
534
- const list = await this.generateResponse(messages, model, resolvedHistory, functions, messageModerators, logLevel);
535
- return list.split(';').map((item) => item.trim());
518
+ if (includeSystemMessages) {
519
+ this.history.push(systemMessages);
520
+ }
521
+ const { message } = await this.generateResponse({ messages, model });
522
+ return message.split(';').map((item) => item.trim());
536
523
  }
537
524
  }