@crewdle/mist-connector-openai 1.0.7 → 1.0.8

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.
@@ -47,53 +47,37 @@ export class OpenAIGenerativeAIWorkerConnector {
47
47
  outputTokens: 0,
48
48
  };
49
49
  }
50
- let responseFormat;
51
- if (parameters.grammar) {
52
- if (parameters.grammar === 'json') {
53
- responseFormat = { type: 'json_object' };
54
- }
55
- else if (parameters.grammar === 'if_else') {
56
- responseFormat = {
57
- type: 'json_schema',
58
- json_schema: {
59
- name: 'router_response',
60
- schema: {
61
- type: 'object',
62
- properties: {
63
- 'condition_result': {
64
- type: 'boolean',
65
- }
66
- },
67
- required: ['result'],
68
- additionalProperties: false,
69
- }
70
- }
71
- };
72
- }
73
- else if (parameters.grammar !== 'default') {
74
- responseFormat = {
75
- type: 'json_schema',
76
- json_schema: {
77
- name: 'custom_response',
78
- schema: parameters.grammar,
79
- }
50
+ const responseFormat = this.getResponseFormat(parameters);
51
+ const tools = this.getTools(parameters);
52
+ const messages = this.getMessages(parameters);
53
+ let totalInputTokens = 0;
54
+ let totalOutputTokens = 0;
55
+ let accumulatedOutput = '';
56
+ while (true) {
57
+ const response = await this.client.chat.completions.create({
58
+ model: options.model.id,
59
+ messages,
60
+ max_completion_tokens: parameters.maxTokens,
61
+ temperature: parameters.temperature,
62
+ response_format: responseFormat,
63
+ tools,
64
+ });
65
+ const message = response.choices[0].message;
66
+ totalInputTokens += response.usage?.prompt_tokens ?? 0;
67
+ totalOutputTokens += response.usage?.completion_tokens ?? 0;
68
+ if (!message.tool_calls) {
69
+ accumulatedOutput += message.content ?? '';
70
+ return {
71
+ type: 'prompt',
72
+ output: accumulatedOutput,
73
+ inputTokens: totalInputTokens,
74
+ outputTokens: totalOutputTokens,
80
75
  };
81
76
  }
77
+ const promises = [];
78
+ this.processToolCalls(promises, message.tool_calls, messages, parameters.functions);
79
+ await Promise.all(promises);
82
80
  }
83
- const messages = this.getMessages(parameters);
84
- const response = await this.client.chat.completions.create({
85
- model: options.model.id,
86
- messages,
87
- max_completion_tokens: parameters.maxTokens,
88
- temperature: parameters.temperature,
89
- response_format: responseFormat,
90
- });
91
- return {
92
- type: 'prompt',
93
- output: response.choices[0].message.content ?? '',
94
- inputTokens: response.usage?.prompt_tokens ?? 0,
95
- outputTokens: response.usage?.completion_tokens ?? 0,
96
- };
97
81
  }
98
82
  async *processJobStream(parameters, options) {
99
83
  if (!this.client) {
@@ -102,61 +86,8 @@ export class OpenAIGenerativeAIWorkerConnector {
102
86
  if (!options || !this.models.has(options.model.id)) {
103
87
  throw new Error('Model not initialized');
104
88
  }
105
- let responseFormat;
106
- if (parameters.grammar) {
107
- if (parameters.grammar === 'json') {
108
- responseFormat = { type: 'json_object' };
109
- }
110
- else if (parameters.grammar === 'if_else') {
111
- responseFormat = {
112
- type: 'json_schema',
113
- json_schema: {
114
- name: 'router_response',
115
- schema: {
116
- type: 'object',
117
- properties: {
118
- 'condition_result': {
119
- type: 'boolean',
120
- }
121
- },
122
- required: ['result'],
123
- additionalProperties: false,
124
- }
125
- }
126
- };
127
- }
128
- else if (parameters.grammar !== 'default') {
129
- responseFormat = {
130
- type: 'json_schema',
131
- json_schema: {
132
- name: 'custom_response',
133
- schema: parameters.grammar,
134
- }
135
- };
136
- }
137
- }
138
- let tools;
139
- if (parameters.functions && parameters.functions.size > 0) {
140
- tools = [];
141
- for (const [name, func] of parameters.functions) {
142
- let params;
143
- if (func.params) {
144
- params = {
145
- type: 'object',
146
- properties: func.params,
147
- required: Object.keys(func.params),
148
- };
149
- }
150
- tools.push({
151
- type: 'function',
152
- function: {
153
- name,
154
- description: func.description,
155
- parameters: params,
156
- }
157
- });
158
- }
159
- }
89
+ const responseFormat = this.getResponseFormat(parameters);
90
+ const tools = this.getTools(parameters);
160
91
  const messages = this.getMessages(parameters);
161
92
  while (true) {
162
93
  const stream = await this.client.chat.completions.create({
@@ -186,55 +117,64 @@ export class OpenAIGenerativeAIWorkerConnector {
186
117
  if (!message.tool_calls) {
187
118
  break;
188
119
  }
189
- messages.push({
190
- role: 'assistant',
191
- content: null,
192
- tool_calls: message.tool_calls,
193
- refusal: null,
194
- });
195
120
  const promises = [];
196
- for (const toolCall of message.tool_calls) {
197
- if (toolCall?.function && parameters.functions) {
198
- try {
199
- const func = parameters.functions.get(toolCall.function.name);
200
- if (func) {
201
- const result = func.callback(JSON.parse(toolCall.function.arguments));
202
- if (result instanceof Promise) {
203
- promises.push(result.then((res) => {
204
- messages.push({
205
- role: 'tool',
206
- tool_call_id: toolCall.id,
207
- content: res ?? 'Tool does not exist',
208
- });
209
- }));
210
- }
211
- else {
121
+ this.processToolCalls(promises, message.tool_calls, messages, parameters.functions);
122
+ await Promise.all(promises);
123
+ yield {
124
+ type: "prompt" /* GenerativeAIJobType.Prompt */,
125
+ output: '\n\n',
126
+ inputTokens: 0,
127
+ outputTokens: 0,
128
+ };
129
+ }
130
+ }
131
+ processToolCalls(promises, toolCalls, messages, functions) {
132
+ messages.push({
133
+ role: 'assistant',
134
+ content: null,
135
+ tool_calls: toolCalls,
136
+ refusal: null,
137
+ });
138
+ for (const toolCall of toolCalls) {
139
+ if (toolCall?.function && functions) {
140
+ try {
141
+ const func = functions.get(toolCall.function.name);
142
+ if (func) {
143
+ const result = func.callback(JSON.parse(toolCall.function.arguments));
144
+ if (result instanceof Promise) {
145
+ promises.push(result.then((res) => {
212
146
  messages.push({
213
147
  role: 'tool',
214
148
  tool_call_id: toolCall.id,
215
- content: result ?? 'Tool does not exist',
149
+ content: res ?? 'Tool does not exist',
216
150
  });
217
- }
151
+ }));
218
152
  }
219
153
  else {
220
154
  messages.push({
221
155
  role: 'tool',
222
156
  tool_call_id: toolCall.id,
223
- content: 'Tool does not exist',
157
+ content: result ?? 'Tool does not exist',
224
158
  });
225
159
  }
226
160
  }
227
- catch (error) {
228
- console.error('Error processing tool call', error);
161
+ else {
229
162
  messages.push({
230
163
  role: 'tool',
231
164
  tool_call_id: toolCall.id,
232
- content: 'Error processing tool call',
165
+ content: 'Tool does not exist',
233
166
  });
234
167
  }
235
168
  }
169
+ catch (error) {
170
+ console.error('Error processing tool call', error);
171
+ messages.push({
172
+ role: 'tool',
173
+ tool_call_id: toolCall.id,
174
+ content: 'Error processing tool call',
175
+ });
176
+ }
236
177
  }
237
- await Promise.all(promises);
238
178
  }
239
179
  }
240
180
  messageReducer(previous, item) {
@@ -301,4 +241,65 @@ export class OpenAIGenerativeAIWorkerConnector {
301
241
  });
302
242
  return messages;
303
243
  }
244
+ getTools(parameters) {
245
+ if (!parameters.functions || parameters.functions.size === 0) {
246
+ return undefined;
247
+ }
248
+ const tools = [];
249
+ for (const [name, func] of parameters.functions) {
250
+ let params;
251
+ if (func.params) {
252
+ params = {
253
+ type: 'object',
254
+ properties: func.params,
255
+ required: Object.keys(func.params),
256
+ };
257
+ }
258
+ tools.push({
259
+ type: 'function',
260
+ function: {
261
+ name,
262
+ description: func.description,
263
+ parameters: params,
264
+ }
265
+ });
266
+ }
267
+ return tools;
268
+ }
269
+ getResponseFormat(parameters) {
270
+ if (!parameters.grammar) {
271
+ return undefined;
272
+ }
273
+ if (parameters.grammar === 'json') {
274
+ return { type: 'json_object' };
275
+ }
276
+ if (parameters.grammar === 'if_else') {
277
+ return {
278
+ type: 'json_schema',
279
+ json_schema: {
280
+ name: 'router_response',
281
+ schema: {
282
+ type: 'object',
283
+ properties: {
284
+ 'condition_result': {
285
+ type: 'boolean',
286
+ }
287
+ },
288
+ required: ['result'],
289
+ additionalProperties: false,
290
+ }
291
+ }
292
+ };
293
+ }
294
+ if (parameters.grammar !== 'default') {
295
+ return {
296
+ type: 'json_schema',
297
+ json_schema: {
298
+ name: 'custom_response',
299
+ schema: parameters.grammar,
300
+ }
301
+ };
302
+ }
303
+ return undefined;
304
+ }
304
305
  }
@@ -9,6 +9,9 @@ export declare class OpenAIGenerativeAIWorkerConnector implements IGenerativeAIW
9
9
  getEngineType(): GenerativeAIEngineType;
10
10
  processJob(parameters: GenerativeAIWorkerConnectorParameters, options?: IGenerativeAIWorkerOptions): Promise<IGenerativeAIWorkerConnectorPromptResult>;
11
11
  processJobStream(parameters: GenerativeAIWorkerConnectorParameters, options?: IGenerativeAIWorkerOptions): AsyncGenerator<IGenerativeAIWorkerConnectorPromptResult>;
12
+ private processToolCalls;
12
13
  private messageReducer;
13
14
  private getMessages;
15
+ private getTools;
16
+ private getResponseFormat;
14
17
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewdle/mist-connector-openai",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -15,7 +15,7 @@
15
15
  "dist/"
16
16
  ],
17
17
  "devDependencies": {
18
- "@crewdle/web-sdk-types": "^1.0.37",
18
+ "@crewdle/web-sdk-types": "^1.0.38",
19
19
  "@types/node": "^22.13.9",
20
20
  "typescript": "^5.8.2"
21
21
  },