@crewdle/mist-connector-openai 1.0.19 → 1.0.21

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.
@@ -55,7 +55,12 @@ export class OpenAIGenerativeAIWorkerConnector {
55
55
  let file;
56
56
  for (const message of parameters.prompt) {
57
57
  if (message.type === 'input_audio') {
58
- file = new File([message.input_audio.data], 'audio.mp3', { type: message.input_audio.format });
58
+ const dataParts = message.input_audio.data.split(',');
59
+ const data = dataParts[1];
60
+ const type = dataParts[0].replace('data:', '').replace(';base64', '');
61
+ const byteArray = Uint8Array.from(Buffer.from(data, 'base64'));
62
+ const blob = new Blob([byteArray], { type });
63
+ file = new File([blob], `audio.${message.input_audio.format}`, { type });
59
64
  }
60
65
  }
61
66
  if (!file) {
@@ -72,7 +77,7 @@ export class OpenAIGenerativeAIWorkerConnector {
72
77
  console.log('OpenAIGenerativeAIWorkerConnector.processJob audio transcription response');
73
78
  return {
74
79
  type: "prompt" /* GenerativeAIJobType.Prompt */,
75
- output: response.text,
80
+ output: (!parameters.responseFormat || parameters.responseFormat === 'json') ? response.text : JSON.stringify(response),
76
81
  inputTokens: response.usage?.type === 'tokens' ? response.usage.input_tokens : 0,
77
82
  outputTokens: response.usage?.type === 'tokens' ? response.usage.output_tokens : 0,
78
83
  };
@@ -127,9 +132,10 @@ export class OpenAIGenerativeAIWorkerConnector {
127
132
  };
128
133
  }
129
134
  }
130
- const responseFormat = this.getResponseFormat(parameters);
135
+ const responseFormat = this.getResponseFormat(parameters, options.model.id);
131
136
  const tools = this.getTools(parameters);
132
137
  const messages = this.getMessages(parameters);
138
+ const reasoning = this.getReasoning(parameters, options.model.id);
133
139
  let inputTokens = 0;
134
140
  let outputTokens = 0;
135
141
  let output = '';
@@ -143,6 +149,7 @@ export class OpenAIGenerativeAIWorkerConnector {
143
149
  temperature: parameters.temperature,
144
150
  text: responseFormat,
145
151
  tools,
152
+ reasoning,
146
153
  store: parameters.privacy === true ? false : true,
147
154
  });
148
155
  console.log('OpenAIGenerativeAIWorkerConnector.processJob response');
@@ -203,21 +210,37 @@ export class OpenAIGenerativeAIWorkerConnector {
203
210
  throw new Error('No file found');
204
211
  }
205
212
  console.log('OpenAIGenerativeAIWorkerConnector.processJobStream audio transcription');
206
- const stream = await this.client.audio.transcriptions.create({
207
- model: options.model.id,
208
- file,
209
- response_format: parameters.responseFormat ? parameters.responseFormat : 'json',
210
- language: parameters.language,
211
- timestamp_granularities: parameters.timestampGranularities ? [parameters.timestampGranularities] : undefined,
212
- stream: true,
213
- });
214
- console.log('OpenAIGenerativeAIWorkerConnector.processJobStream audio transcription response');
215
- for await (const chunk of stream) {
213
+ if (!parameters.responseFormat || parameters.responseFormat === 'json') {
214
+ const stream = await this.client.audio.transcriptions.create({
215
+ model: options.model.id,
216
+ file,
217
+ response_format: 'json',
218
+ language: parameters.language,
219
+ stream: true,
220
+ });
221
+ console.log('OpenAIGenerativeAIWorkerConnector.processJobStream audio transcription response');
222
+ for await (const chunk of stream) {
223
+ yield {
224
+ type: "prompt" /* GenerativeAIJobType.Prompt */,
225
+ output: chunk.type === 'transcript.text.delta' ? chunk.delta : '',
226
+ inputTokens: chunk.type === 'transcript.text.done' ? chunk.usage?.input_tokens ?? 0 : 0,
227
+ outputTokens: chunk.type === 'transcript.text.done' ? chunk.usage?.output_tokens ?? 0 : 0,
228
+ };
229
+ }
230
+ }
231
+ else {
232
+ const response = await this.client.audio.transcriptions.create({
233
+ model: options.model.id,
234
+ file,
235
+ response_format: parameters.responseFormat ? parameters.responseFormat : 'json',
236
+ language: parameters.language,
237
+ timestamp_granularities: parameters.timestampGranularities ? [parameters.timestampGranularities] : undefined,
238
+ });
216
239
  yield {
217
240
  type: "prompt" /* GenerativeAIJobType.Prompt */,
218
- output: chunk.type === 'transcript.text.delta' ? chunk.delta : '',
219
- inputTokens: chunk.type === 'transcript.text.done' ? 0 : chunk.usage?.input_tokens ?? 0,
220
- outputTokens: chunk.type === 'transcript.text.done' ? 0 : chunk.usage?.output_tokens ?? 0,
241
+ output: JSON.stringify(response),
242
+ inputTokens: 0,
243
+ outputTokens: 0,
221
244
  };
222
245
  }
223
246
  return;
@@ -274,9 +297,11 @@ export class OpenAIGenerativeAIWorkerConnector {
274
297
  return;
275
298
  }
276
299
  }
277
- const responseFormat = this.getResponseFormat(parameters);
300
+ const responseFormat = this.getResponseFormat(parameters, options.model.id);
278
301
  const tools = this.getTools(parameters);
279
302
  const messages = this.getMessages(parameters);
303
+ const reasoning = this.getReasoning(parameters, options.model.id);
304
+ let firstChunk = true;
280
305
  while (true) {
281
306
  console.log('OpenAIGenerativeAIWorkerConnector.processJobStream', options.model.id);
282
307
  const stream = await this.client.responses.create({
@@ -286,6 +311,7 @@ export class OpenAIGenerativeAIWorkerConnector {
286
311
  temperature: parameters.temperature,
287
312
  text: responseFormat,
288
313
  tools,
314
+ reasoning,
289
315
  stream: true,
290
316
  store: parameters.privacy === true ? false : true,
291
317
  });
@@ -293,6 +319,10 @@ export class OpenAIGenerativeAIWorkerConnector {
293
319
  const promises = [];
294
320
  for await (const chunk of stream) {
295
321
  if (chunk.type === 'response.output_text.delta') {
322
+ if (firstChunk && chunk.delta.trim()) {
323
+ console.log('OpenAIGenerativeAIWorkerConnector.processJobStream first chunk');
324
+ firstChunk = false;
325
+ }
296
326
  yield {
297
327
  type: "prompt" /* GenerativeAIJobType.Prompt */,
298
328
  output: chunk.delta,
@@ -470,8 +500,22 @@ export class OpenAIGenerativeAIWorkerConnector {
470
500
  }
471
501
  return tools;
472
502
  }
473
- getResponseFormat(parameters) {
474
- if (!parameters.grammar) {
503
+ getReasoning(parameters, modelId) {
504
+ if (!modelId.startsWith('gpt-5')) {
505
+ return undefined;
506
+ }
507
+ if (!parameters.reasoning) {
508
+ return undefined;
509
+ }
510
+ return {
511
+ effort: parameters.reasoning,
512
+ };
513
+ }
514
+ getResponseFormat(parameters, modelId) {
515
+ if (!parameters.grammar || parameters.grammar === 'default') {
516
+ if (modelId.startsWith('gpt-5') && parameters.verbosity) {
517
+ return { verbosity: parameters.verbosity };
518
+ }
475
519
  return undefined;
476
520
  }
477
521
  if (parameters.grammar === 'json') {
@@ -13,5 +13,6 @@ export declare class OpenAIGenerativeAIWorkerConnector implements IGenerativeAIW
13
13
  private getMessages;
14
14
  private getInnerMessages;
15
15
  private getTools;
16
+ private getReasoning;
16
17
  private getResponseFormat;
17
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewdle/mist-connector-openai",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -15,11 +15,11 @@
15
15
  "dist/"
16
16
  ],
17
17
  "devDependencies": {
18
- "@crewdle/web-sdk-types": "^1.0.52",
18
+ "@crewdle/web-sdk-types": "^1.0.54",
19
19
  "@types/node": "^22.13.9",
20
20
  "typescript": "^5.8.2"
21
21
  },
22
22
  "dependencies": {
23
- "openai": "^5.8.2"
23
+ "openai": "^6.1.0"
24
24
  }
25
25
  }