@crewdle/mist-connector-openai 1.0.6 → 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.
@@ -31,18 +31,53 @@ export class OpenAIGenerativeAIWorkerConnector {
31
31
  if (!options || !this.models.has(options.model.id)) {
32
32
  throw new Error('Model not initialized');
33
33
  }
34
- const response = await this.client.chat.completions.create({
35
- model: options.model.id,
36
- messages: this.getMessages(parameters),
37
- max_completion_tokens: parameters.maxTokens,
38
- temperature: parameters.temperature,
39
- });
40
- return {
41
- type: 'prompt',
42
- output: response.choices[0].message.content ?? '',
43
- inputTokens: response.usage?.prompt_tokens ?? 0,
44
- outputTokens: response.usage?.completion_tokens ?? 0,
45
- };
34
+ if (options.model.outputType === 'vector') {
35
+ const response = await this.client.embeddings.create({
36
+ model: options.model.id,
37
+ input: parameters.prompt,
38
+ dimensions: 1024,
39
+ });
40
+ if (!response.data || response.data.length !== 1) {
41
+ throw new Error('No response data');
42
+ }
43
+ return {
44
+ type: 'prompt',
45
+ output: response.data[0].embedding,
46
+ inputTokens: response.usage?.prompt_tokens ?? 0,
47
+ outputTokens: 0,
48
+ };
49
+ }
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,
75
+ };
76
+ }
77
+ const promises = [];
78
+ this.processToolCalls(promises, message.tool_calls, messages, parameters.functions);
79
+ await Promise.all(promises);
80
+ }
46
81
  }
47
82
  async *processJobStream(parameters, options) {
48
83
  if (!this.client) {
@@ -51,61 +86,8 @@ export class OpenAIGenerativeAIWorkerConnector {
51
86
  if (!options || !this.models.has(options.model.id)) {
52
87
  throw new Error('Model not initialized');
53
88
  }
54
- let responseFormat;
55
- if (parameters.grammar) {
56
- if (parameters.grammar === 'json') {
57
- responseFormat = { type: 'json_object' };
58
- }
59
- else if (parameters.grammar === 'if_else') {
60
- responseFormat = {
61
- type: 'json_schema',
62
- json_schema: {
63
- name: 'router_response',
64
- schema: {
65
- type: 'object',
66
- properties: {
67
- 'condition_result': {
68
- type: 'boolean',
69
- }
70
- },
71
- required: ['result'],
72
- additionalProperties: false,
73
- }
74
- }
75
- };
76
- }
77
- else if (parameters.grammar !== 'default') {
78
- responseFormat = {
79
- type: 'json_schema',
80
- json_schema: {
81
- name: 'custom_response',
82
- schema: parameters.grammar,
83
- }
84
- };
85
- }
86
- }
87
- let tools;
88
- if (parameters.functions && parameters.functions.size > 0) {
89
- tools = [];
90
- for (const [name, func] of parameters.functions) {
91
- let params;
92
- if (func.params) {
93
- params = {
94
- type: 'object',
95
- properties: func.params,
96
- required: Object.keys(func.params),
97
- };
98
- }
99
- tools.push({
100
- type: 'function',
101
- function: {
102
- name,
103
- description: func.description,
104
- parameters: params,
105
- }
106
- });
107
- }
108
- }
89
+ const responseFormat = this.getResponseFormat(parameters);
90
+ const tools = this.getTools(parameters);
109
91
  const messages = this.getMessages(parameters);
110
92
  while (true) {
111
93
  const stream = await this.client.chat.completions.create({
@@ -135,55 +117,64 @@ export class OpenAIGenerativeAIWorkerConnector {
135
117
  if (!message.tool_calls) {
136
118
  break;
137
119
  }
138
- messages.push({
139
- role: 'assistant',
140
- content: null,
141
- tool_calls: message.tool_calls,
142
- refusal: null,
143
- });
144
120
  const promises = [];
145
- for (const toolCall of message.tool_calls) {
146
- if (toolCall?.function && parameters.functions) {
147
- try {
148
- const func = parameters.functions.get(toolCall.function.name);
149
- if (func) {
150
- const result = func.callback(JSON.parse(toolCall.function.arguments));
151
- if (result instanceof Promise) {
152
- promises.push(result.then((res) => {
153
- messages.push({
154
- role: 'tool',
155
- tool_call_id: toolCall.id,
156
- content: res ?? 'Tool does not exist',
157
- });
158
- }));
159
- }
160
- 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) => {
161
146
  messages.push({
162
147
  role: 'tool',
163
148
  tool_call_id: toolCall.id,
164
- content: result ?? 'Tool does not exist',
149
+ content: res ?? 'Tool does not exist',
165
150
  });
166
- }
151
+ }));
167
152
  }
168
153
  else {
169
154
  messages.push({
170
155
  role: 'tool',
171
156
  tool_call_id: toolCall.id,
172
- content: 'Tool does not exist',
157
+ content: result ?? 'Tool does not exist',
173
158
  });
174
159
  }
175
160
  }
176
- catch (error) {
177
- console.error('Error processing tool call', error);
161
+ else {
178
162
  messages.push({
179
163
  role: 'tool',
180
164
  tool_call_id: toolCall.id,
181
- content: 'Error processing tool call',
165
+ content: 'Tool does not exist',
182
166
  });
183
167
  }
184
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
+ }
185
177
  }
186
- await Promise.all(promises);
187
178
  }
188
179
  }
189
180
  messageReducer(previous, item) {
@@ -250,4 +241,65 @@ export class OpenAIGenerativeAIWorkerConnector {
250
241
  });
251
242
  return messages;
252
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
+ }
253
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.6",
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.36",
18
+ "@crewdle/web-sdk-types": "^1.0.38",
19
19
  "@types/node": "^22.13.9",
20
20
  "typescript": "^5.8.2"
21
21
  },