@livekit/agents-plugin-openai 1.0.50 → 1.1.0
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/dist/index.cjs +5 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/llm.cjs +8 -0
- package/dist/llm.cjs.map +1 -1
- package/dist/llm.d.cts +1 -0
- package/dist/llm.d.ts +1 -0
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +8 -0
- package/dist/llm.js.map +1 -1
- package/dist/llm.test.cjs +31 -16
- package/dist/llm.test.cjs.map +1 -1
- package/dist/llm.test.js +32 -17
- package/dist/llm.test.js.map +1 -1
- package/dist/realtime/api_proto.cjs.map +1 -1
- package/dist/realtime/api_proto.d.cts +7 -3
- package/dist/realtime/api_proto.d.ts +7 -3
- package/dist/realtime/api_proto.d.ts.map +1 -1
- package/dist/realtime/api_proto.js.map +1 -1
- package/dist/realtime/realtime_model.cjs +46 -22
- package/dist/realtime/realtime_model.cjs.map +1 -1
- package/dist/realtime/realtime_model.d.cts +2 -1
- package/dist/realtime/realtime_model.d.ts +2 -1
- package/dist/realtime/realtime_model.d.ts.map +1 -1
- package/dist/realtime/realtime_model.js +46 -22
- package/dist/realtime/realtime_model.js.map +1 -1
- package/dist/realtime/realtime_model.test.cjs +104 -14
- package/dist/realtime/realtime_model.test.cjs.map +1 -1
- package/dist/realtime/realtime_model.test.js +104 -14
- package/dist/realtime/realtime_model.test.js.map +1 -1
- package/dist/realtime/realtime_model_beta.cjs +40 -22
- package/dist/realtime/realtime_model_beta.cjs.map +1 -1
- package/dist/realtime/realtime_model_beta.d.ts.map +1 -1
- package/dist/realtime/realtime_model_beta.js +40 -22
- package/dist/realtime/realtime_model_beta.js.map +1 -1
- package/dist/responses/llm.cjs +71 -16
- package/dist/responses/llm.cjs.map +1 -1
- package/dist/responses/llm.d.cts +10 -25
- package/dist/responses/llm.d.ts +10 -25
- package/dist/responses/llm.d.ts.map +1 -1
- package/dist/responses/llm.js +71 -14
- package/dist/responses/llm.js.map +1 -1
- package/dist/responses/llm.test.cjs +32 -17
- package/dist/responses/llm.test.cjs.map +1 -1
- package/dist/responses/llm.test.js +33 -18
- package/dist/responses/llm.test.js.map +1 -1
- package/dist/stt.cjs +18 -3
- package/dist/stt.cjs.map +1 -1
- package/dist/stt.d.cts +2 -0
- package/dist/stt.d.ts +2 -0
- package/dist/stt.d.ts.map +1 -1
- package/dist/stt.js +19 -4
- package/dist/stt.js.map +1 -1
- package/dist/stt.test.cjs +11 -3
- package/dist/stt.test.cjs.map +1 -1
- package/dist/stt.test.js +12 -4
- package/dist/stt.test.js.map +1 -1
- package/dist/tts.cjs +11 -0
- package/dist/tts.cjs.map +1 -1
- package/dist/tts.d.cts +2 -0
- package/dist/tts.d.ts +2 -0
- package/dist/tts.d.ts.map +1 -1
- package/dist/tts.js +11 -0
- package/dist/tts.js.map +1 -1
- package/dist/tts.test.cjs +11 -3
- package/dist/tts.test.cjs.map +1 -1
- package/dist/tts.test.js +12 -4
- package/dist/tts.test.js.map +1 -1
- package/dist/ws/index.cjs +29 -0
- package/dist/ws/index.cjs.map +1 -0
- package/dist/ws/index.d.cts +3 -0
- package/dist/ws/index.d.ts +3 -0
- package/dist/ws/index.d.ts.map +1 -0
- package/dist/ws/index.js +5 -0
- package/dist/ws/index.js.map +1 -0
- package/dist/ws/llm.cjs +502 -0
- package/dist/ws/llm.cjs.map +1 -0
- package/dist/ws/llm.d.cts +74 -0
- package/dist/ws/llm.d.ts +74 -0
- package/dist/ws/llm.d.ts.map +1 -0
- package/dist/ws/llm.js +485 -0
- package/dist/ws/llm.js.map +1 -0
- package/dist/ws/llm.test.cjs +26 -0
- package/dist/ws/llm.test.cjs.map +1 -0
- package/dist/ws/llm.test.d.cts +2 -0
- package/dist/ws/llm.test.d.ts +2 -0
- package/dist/ws/llm.test.d.ts.map +1 -0
- package/dist/ws/llm.test.js +25 -0
- package/dist/ws/llm.test.js.map +1 -0
- package/dist/ws/types.cjs +128 -0
- package/dist/ws/types.cjs.map +1 -0
- package/dist/ws/types.d.cts +167 -0
- package/dist/ws/types.d.ts +167 -0
- package/dist/ws/types.d.ts.map +1 -0
- package/dist/ws/types.js +95 -0
- package/dist/ws/types.js.map +1 -0
- package/package.json +6 -5
- package/src/index.ts +1 -0
- package/src/llm.test.ts +31 -17
- package/src/llm.ts +9 -0
- package/src/realtime/api_proto.ts +8 -2
- package/src/realtime/realtime_model.test.ts +129 -14
- package/src/realtime/realtime_model.ts +51 -26
- package/src/realtime/realtime_model_beta.ts +42 -25
- package/src/responses/llm.test.ts +32 -18
- package/src/responses/llm.ts +105 -19
- package/src/stt.test.ts +12 -4
- package/src/stt.ts +21 -4
- package/src/tts.test.ts +12 -4
- package/src/tts.ts +13 -0
- package/src/ws/index.ts +17 -0
- package/src/ws/llm.test.ts +30 -0
- package/src/ws/llm.ts +665 -0
- package/src/ws/types.ts +131 -0
package/src/responses/llm.ts
CHANGED
|
@@ -8,12 +8,14 @@ import {
|
|
|
8
8
|
APITimeoutError,
|
|
9
9
|
DEFAULT_API_CONNECT_OPTIONS,
|
|
10
10
|
llm,
|
|
11
|
+
log,
|
|
11
12
|
toError,
|
|
12
13
|
} from '@livekit/agents';
|
|
13
14
|
import OpenAI from 'openai';
|
|
14
15
|
import type { ChatModels } from '../models.js';
|
|
16
|
+
import { WSLLM } from '../ws/llm.js';
|
|
15
17
|
|
|
16
|
-
interface LLMOptions {
|
|
18
|
+
export interface LLMOptions {
|
|
17
19
|
model: string | ChatModels;
|
|
18
20
|
apiKey?: string;
|
|
19
21
|
baseURL?: string;
|
|
@@ -24,30 +26,32 @@ interface LLMOptions {
|
|
|
24
26
|
store?: boolean;
|
|
25
27
|
metadata?: Record<string, string>;
|
|
26
28
|
strictToolSchema?: boolean;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Whether to use the WebSocket API.
|
|
32
|
+
* @default true
|
|
33
|
+
*/
|
|
34
|
+
useWebSocket?: boolean;
|
|
27
35
|
}
|
|
28
36
|
|
|
37
|
+
type HttpLLMOptions = Omit<LLMOptions, 'useWebSocket'>;
|
|
38
|
+
|
|
29
39
|
const defaultLLMOptions: LLMOptions = {
|
|
30
40
|
model: 'gpt-4.1',
|
|
31
41
|
apiKey: process.env.OPENAI_API_KEY,
|
|
32
42
|
strictToolSchema: true,
|
|
43
|
+
useWebSocket: true,
|
|
33
44
|
};
|
|
34
45
|
|
|
35
|
-
|
|
46
|
+
class ResponsesHttpLLM extends llm.LLM {
|
|
36
47
|
#client: OpenAI;
|
|
37
|
-
#opts:
|
|
48
|
+
#opts: HttpLLMOptions;
|
|
38
49
|
|
|
39
|
-
|
|
40
|
-
* Create a new instance of OpenAI Responses LLM.
|
|
41
|
-
*
|
|
42
|
-
* @remarks
|
|
43
|
-
* `apiKey` must be set to your OpenAI API key, either using the argument or by setting the
|
|
44
|
-
* `OPENAI_API_KEY` environment variable.
|
|
45
|
-
*/
|
|
46
|
-
constructor(opts: Partial<LLMOptions> = defaultLLMOptions) {
|
|
50
|
+
constructor(opts: Partial<HttpLLMOptions> = defaultLLMOptions) {
|
|
47
51
|
super();
|
|
48
52
|
|
|
49
53
|
this.#opts = { ...defaultLLMOptions, ...opts };
|
|
50
|
-
if (this.#opts.apiKey === undefined) {
|
|
54
|
+
if (this.#opts.apiKey === undefined && this.#opts.client === undefined) {
|
|
51
55
|
throw new Error('OpenAI API key is required, whether as an argument or as $OPENAI_API_KEY');
|
|
52
56
|
}
|
|
53
57
|
|
|
@@ -59,15 +63,15 @@ export class LLM extends llm.LLM {
|
|
|
59
63
|
});
|
|
60
64
|
}
|
|
61
65
|
|
|
62
|
-
label(): string {
|
|
66
|
+
override label(): string {
|
|
63
67
|
return 'openai.responses.LLM';
|
|
64
68
|
}
|
|
65
69
|
|
|
66
|
-
get model(): string {
|
|
70
|
+
override get model(): string {
|
|
67
71
|
return this.#opts.model;
|
|
68
72
|
}
|
|
69
73
|
|
|
70
|
-
chat({
|
|
74
|
+
override chat({
|
|
71
75
|
chatCtx,
|
|
72
76
|
toolCtx,
|
|
73
77
|
connOptions = DEFAULT_API_CONNECT_OPTIONS,
|
|
@@ -81,7 +85,7 @@ export class LLM extends llm.LLM {
|
|
|
81
85
|
parallelToolCalls?: boolean;
|
|
82
86
|
toolChoice?: llm.ToolChoice;
|
|
83
87
|
extraKwargs?: Record<string, unknown>;
|
|
84
|
-
}):
|
|
88
|
+
}): ResponsesHttpLLMStream {
|
|
85
89
|
const modelOptions: Record<string, unknown> = { ...(extraKwargs || {}) };
|
|
86
90
|
|
|
87
91
|
parallelToolCalls =
|
|
@@ -110,7 +114,7 @@ export class LLM extends llm.LLM {
|
|
|
110
114
|
modelOptions.metadata = this.#opts.metadata;
|
|
111
115
|
}
|
|
112
116
|
|
|
113
|
-
return new
|
|
117
|
+
return new ResponsesHttpLLMStream(this, {
|
|
114
118
|
model: this.#opts.model,
|
|
115
119
|
client: this.#client,
|
|
116
120
|
chatCtx,
|
|
@@ -122,7 +126,7 @@ export class LLM extends llm.LLM {
|
|
|
122
126
|
}
|
|
123
127
|
}
|
|
124
128
|
|
|
125
|
-
|
|
129
|
+
class ResponsesHttpLLMStream extends llm.LLMStream {
|
|
126
130
|
private model: string | ChatModels;
|
|
127
131
|
private client: OpenAI;
|
|
128
132
|
private modelOptions: Record<string, unknown>;
|
|
@@ -130,7 +134,7 @@ export class LLMStream extends llm.LLMStream {
|
|
|
130
134
|
private responseId: string;
|
|
131
135
|
|
|
132
136
|
constructor(
|
|
133
|
-
llm:
|
|
137
|
+
llm: ResponsesHttpLLM,
|
|
134
138
|
{
|
|
135
139
|
model,
|
|
136
140
|
client,
|
|
@@ -325,3 +329,85 @@ export class LLMStream extends llm.LLMStream {
|
|
|
325
329
|
return undefined;
|
|
326
330
|
}
|
|
327
331
|
}
|
|
332
|
+
|
|
333
|
+
export class LLM extends llm.LLM {
|
|
334
|
+
#opts: LLMOptions;
|
|
335
|
+
#llm: llm.LLM;
|
|
336
|
+
#logger = log();
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Create a new instance of OpenAI Responses LLM.
|
|
340
|
+
*
|
|
341
|
+
* @remarks
|
|
342
|
+
* `apiKey` must be set to your OpenAI API key, either using the argument or by setting the
|
|
343
|
+
* `OPENAI_API_KEY` environment variable.
|
|
344
|
+
*/
|
|
345
|
+
constructor(opts: Partial<LLMOptions> = defaultLLMOptions) {
|
|
346
|
+
super();
|
|
347
|
+
|
|
348
|
+
this.#opts = { ...defaultLLMOptions, ...opts };
|
|
349
|
+
const { useWebSocket, client, ...baseOpts } = this.#opts;
|
|
350
|
+
|
|
351
|
+
if (useWebSocket) {
|
|
352
|
+
if (client !== undefined) {
|
|
353
|
+
this.#logger.warn(
|
|
354
|
+
'WebSocket mode does not support custom client; provided client will be ignored',
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
this.#llm = new WSLLM(baseOpts);
|
|
358
|
+
} else {
|
|
359
|
+
this.#llm = new ResponsesHttpLLM({ ...baseOpts, client });
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Forward events from the inner delegate so consumers listening on this
|
|
363
|
+
// wrapper instance (e.g. AgentActivity) receive them.
|
|
364
|
+
this.#llm.on('metrics_collected', (metrics) => this.emit('metrics_collected', metrics));
|
|
365
|
+
this.#llm.on('error', (error) => this.emit('error', error));
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
override label(): string {
|
|
369
|
+
return this.#llm.label();
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
override get model(): string {
|
|
373
|
+
return this.#llm.model;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
override prewarm(): void {
|
|
377
|
+
this.#llm.prewarm();
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Ref: python livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/responses/llm.py - 229-233 lines
|
|
381
|
+
override async aclose(): Promise<void> {
|
|
382
|
+
await this.#llm.aclose();
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
async close(): Promise<void> {
|
|
386
|
+
await this.aclose();
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
override chat({
|
|
390
|
+
chatCtx,
|
|
391
|
+
toolCtx,
|
|
392
|
+
connOptions = DEFAULT_API_CONNECT_OPTIONS,
|
|
393
|
+
parallelToolCalls,
|
|
394
|
+
toolChoice,
|
|
395
|
+
extraKwargs,
|
|
396
|
+
}: {
|
|
397
|
+
chatCtx: llm.ChatContext;
|
|
398
|
+
toolCtx?: llm.ToolContext;
|
|
399
|
+
connOptions?: APIConnectOptions;
|
|
400
|
+
parallelToolCalls?: boolean;
|
|
401
|
+
toolChoice?: llm.ToolChoice;
|
|
402
|
+
extraKwargs?: Record<string, unknown>;
|
|
403
|
+
}): llm.LLMStream {
|
|
404
|
+
return this.#llm.chat({
|
|
405
|
+
chatCtx,
|
|
406
|
+
toolCtx,
|
|
407
|
+
connOptions,
|
|
408
|
+
parallelToolCalls,
|
|
409
|
+
toolChoice,
|
|
410
|
+
extraKwargs,
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
}
|
package/src/stt.test.ts
CHANGED
|
@@ -3,9 +3,17 @@
|
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
import { VAD } from '@livekit/agents-plugin-silero';
|
|
5
5
|
import { stt } from '@livekit/agents-plugins-test';
|
|
6
|
-
import { describe } from 'vitest';
|
|
6
|
+
import { describe, it } from 'vitest';
|
|
7
7
|
import { STT } from './stt.js';
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const hasOpenAIApiKey = Boolean(process.env.OPENAI_API_KEY);
|
|
10
|
+
|
|
11
|
+
if (hasOpenAIApiKey) {
|
|
12
|
+
describe('OpenAI', async () => {
|
|
13
|
+
await stt(new STT(), await VAD.load(), { streaming: false });
|
|
14
|
+
});
|
|
15
|
+
} else {
|
|
16
|
+
describe('OpenAI', () => {
|
|
17
|
+
it.skip('requires OPENAI_API_KEY', () => {});
|
|
18
|
+
});
|
|
19
|
+
}
|
package/src/stt.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
import { type AudioBuffer, mergeFrames, stt } from '@livekit/agents';
|
|
4
|
+
import { type AudioBuffer, mergeFrames, normalizeLanguage, stt } from '@livekit/agents';
|
|
5
5
|
import type { AudioFrame } from '@livekit/rtc-node';
|
|
6
6
|
import { OpenAI } from 'openai';
|
|
7
7
|
import type { GroqAudioModels, WhisperModels } from './models.js';
|
|
@@ -28,6 +28,19 @@ export class STT extends stt.STT {
|
|
|
28
28
|
#client: OpenAI;
|
|
29
29
|
label = 'openai.STT';
|
|
30
30
|
|
|
31
|
+
get model(): string {
|
|
32
|
+
return this.#opts.model;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
get provider(): string {
|
|
36
|
+
try {
|
|
37
|
+
const url = new URL(this.#client.baseURL);
|
|
38
|
+
return url.host;
|
|
39
|
+
} catch {
|
|
40
|
+
return 'api.openai.com';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
31
44
|
/**
|
|
32
45
|
* Create a new instance of OpenAI STT.
|
|
33
46
|
*
|
|
@@ -38,7 +51,11 @@ export class STT extends stt.STT {
|
|
|
38
51
|
constructor(opts: Partial<STTOptions> = defaultSTTOptions) {
|
|
39
52
|
super({ streaming: false, interimResults: false, alignedTranscript: false });
|
|
40
53
|
|
|
41
|
-
this.#opts = {
|
|
54
|
+
this.#opts = {
|
|
55
|
+
...defaultSTTOptions,
|
|
56
|
+
...opts,
|
|
57
|
+
language: normalizeLanguage(opts.language ?? defaultSTTOptions.language),
|
|
58
|
+
};
|
|
42
59
|
if (this.#opts.apiKey === undefined) {
|
|
43
60
|
throw new Error('OpenAI API key is required, whether as an argument or as $OPENAI_API_KEY');
|
|
44
61
|
}
|
|
@@ -113,7 +130,7 @@ export class STT extends stt.STT {
|
|
|
113
130
|
|
|
114
131
|
#sanitizeOptions(language?: string): STTOptions {
|
|
115
132
|
if (language) {
|
|
116
|
-
return { ...this.#opts, language };
|
|
133
|
+
return { ...this.#opts, language: normalizeLanguage(language) };
|
|
117
134
|
} else {
|
|
118
135
|
return this.#opts;
|
|
119
136
|
}
|
|
@@ -165,7 +182,7 @@ export class STT extends stt.STT {
|
|
|
165
182
|
alternatives: [
|
|
166
183
|
{
|
|
167
184
|
text: resp.text || '',
|
|
168
|
-
language: config.language || '',
|
|
185
|
+
language: normalizeLanguage(config.language || ''),
|
|
169
186
|
startTime: 0,
|
|
170
187
|
endTime: 0,
|
|
171
188
|
confidence: 0,
|
package/src/tts.test.ts
CHANGED
|
@@ -2,10 +2,18 @@
|
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
import { tts } from '@livekit/agents-plugins-test';
|
|
5
|
-
import { describe } from 'vitest';
|
|
5
|
+
import { describe, it } from 'vitest';
|
|
6
6
|
import { STT } from './stt.js';
|
|
7
7
|
import { TTS } from './tts.js';
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const hasOpenAIApiKey = Boolean(process.env.OPENAI_API_KEY);
|
|
10
|
+
|
|
11
|
+
if (hasOpenAIApiKey) {
|
|
12
|
+
describe('OpenAI', async () => {
|
|
13
|
+
await tts(new TTS(), new STT(), { streaming: false });
|
|
14
|
+
});
|
|
15
|
+
} else {
|
|
16
|
+
describe('OpenAI', () => {
|
|
17
|
+
it.skip('requires OPENAI_API_KEY', () => {});
|
|
18
|
+
});
|
|
19
|
+
}
|
package/src/tts.ts
CHANGED
|
@@ -32,6 +32,19 @@ export class TTS extends tts.TTS {
|
|
|
32
32
|
label = 'openai.TTS';
|
|
33
33
|
private abortController = new AbortController();
|
|
34
34
|
|
|
35
|
+
get model(): string {
|
|
36
|
+
return this.#opts.model;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get provider(): string {
|
|
40
|
+
try {
|
|
41
|
+
const url = new URL(this.#client.baseURL);
|
|
42
|
+
return url.host;
|
|
43
|
+
} catch {
|
|
44
|
+
return 'api.openai.com';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
35
48
|
/**
|
|
36
49
|
* Create a new instance of OpenAI TTS.
|
|
37
50
|
*
|
package/src/ws/index.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
export { ResponsesWebSocket } from './llm.js';
|
|
6
|
+
export type {
|
|
7
|
+
WsErrorEvent,
|
|
8
|
+
WsFunctionCallItem,
|
|
9
|
+
WsOutputItem,
|
|
10
|
+
WsOutputItemDoneEvent,
|
|
11
|
+
WsOutputTextDeltaEvent,
|
|
12
|
+
WsResponseCompletedEvent,
|
|
13
|
+
WsResponseCreateEvent,
|
|
14
|
+
WsResponseCreatedEvent,
|
|
15
|
+
WsResponseFailedEvent,
|
|
16
|
+
WsServerEvent,
|
|
17
|
+
} from './types.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { initializeLogger } from '@livekit/agents';
|
|
5
|
+
import { llm, llmStrict } from '@livekit/agents-plugins-test';
|
|
6
|
+
import { describe } from 'vitest';
|
|
7
|
+
import { LLM } from '../responses/llm.js';
|
|
8
|
+
|
|
9
|
+
initializeLogger({ level: 'silent', pretty: false });
|
|
10
|
+
|
|
11
|
+
describe('OpenAI Responses WS wrapper', async () => {
|
|
12
|
+
await llm(
|
|
13
|
+
new LLM({
|
|
14
|
+
temperature: 0,
|
|
15
|
+
strictToolSchema: false,
|
|
16
|
+
useWebSocket: true,
|
|
17
|
+
}),
|
|
18
|
+
true,
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('OpenAI Responses WS wrapper strict tool schema', async () => {
|
|
23
|
+
await llmStrict(
|
|
24
|
+
new LLM({
|
|
25
|
+
temperature: 0,
|
|
26
|
+
strictToolSchema: true,
|
|
27
|
+
useWebSocket: true,
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
});
|