@openai/agents-realtime 0.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/LICENSE +21 -0
- package/README.md +13 -0
- package/dist/bundle/openai-realtime-agents.mjs +8777 -0
- package/dist/bundle/openai-realtime-agents.umd.js +11 -0
- package/dist/clientMessages.d.ts +40 -0
- package/dist/clientMessages.js +2 -0
- package/dist/clientMessages.js.map +1 -0
- package/dist/clientMessages.mjs +2 -0
- package/dist/clientMessages.mjs.map +1 -0
- package/dist/guardrail.d.ts +32 -0
- package/dist/guardrail.js +34 -0
- package/dist/guardrail.js.map +1 -0
- package/dist/guardrail.mjs +34 -0
- package/dist/guardrail.mjs.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +13 -0
- package/dist/index.mjs.map +1 -0
- package/dist/items.d.ts +183 -0
- package/dist/items.js +47 -0
- package/dist/items.js.map +1 -0
- package/dist/items.mjs +47 -0
- package/dist/items.mjs.map +1 -0
- package/dist/logger.d.ts +2 -0
- package/dist/logger.js +4 -0
- package/dist/logger.js.map +1 -0
- package/dist/logger.mjs +4 -0
- package/dist/logger.mjs.map +1 -0
- package/dist/metadata.d.ts +9 -0
- package/dist/metadata.js +11 -0
- package/dist/metadata.js.map +1 -0
- package/dist/metadata.mjs +11 -0
- package/dist/metadata.mjs.map +1 -0
- package/dist/openaiRealtimeBase.d.ts +143 -0
- package/dist/openaiRealtimeBase.js +449 -0
- package/dist/openaiRealtimeBase.js.map +1 -0
- package/dist/openaiRealtimeBase.mjs +449 -0
- package/dist/openaiRealtimeBase.mjs.map +1 -0
- package/dist/openaiRealtimeEvents.d.ts +3242 -0
- package/dist/openaiRealtimeEvents.js +439 -0
- package/dist/openaiRealtimeEvents.js.map +1 -0
- package/dist/openaiRealtimeEvents.mjs +439 -0
- package/dist/openaiRealtimeEvents.mjs.map +1 -0
- package/dist/openaiRealtimeWebRtc.d.ts +102 -0
- package/dist/openaiRealtimeWebRtc.js +245 -0
- package/dist/openaiRealtimeWebRtc.js.map +1 -0
- package/dist/openaiRealtimeWebRtc.mjs +245 -0
- package/dist/openaiRealtimeWebRtc.mjs.map +1 -0
- package/dist/openaiRealtimeWebsocket.d.ts +126 -0
- package/dist/openaiRealtimeWebsocket.js +293 -0
- package/dist/openaiRealtimeWebsocket.js.map +1 -0
- package/dist/openaiRealtimeWebsocket.mjs +293 -0
- package/dist/openaiRealtimeWebsocket.mjs.map +1 -0
- package/dist/realtimeAgent.d.ts +49 -0
- package/dist/realtimeAgent.js +37 -0
- package/dist/realtimeAgent.js.map +1 -0
- package/dist/realtimeAgent.mjs +37 -0
- package/dist/realtimeAgent.mjs.map +1 -0
- package/dist/realtimeSession.d.ts +210 -0
- package/dist/realtimeSession.js +469 -0
- package/dist/realtimeSession.js.map +1 -0
- package/dist/realtimeSession.mjs +469 -0
- package/dist/realtimeSession.mjs.map +1 -0
- package/dist/realtimeSessionEvents.d.ts +118 -0
- package/dist/realtimeSessionEvents.js +2 -0
- package/dist/realtimeSessionEvents.js.map +1 -0
- package/dist/realtimeSessionEvents.mjs +2 -0
- package/dist/realtimeSessionEvents.mjs.map +1 -0
- package/dist/shims/shims-browser.d.ts +9 -0
- package/dist/shims/shims-browser.js +6 -0
- package/dist/shims/shims-browser.js.map +1 -0
- package/dist/shims/shims-browser.mjs +6 -0
- package/dist/shims/shims-browser.mjs.map +1 -0
- package/dist/shims/shims-node.d.ts +2 -0
- package/dist/shims/shims-node.js +5 -0
- package/dist/shims/shims-node.js.map +1 -0
- package/dist/shims/shims-node.mjs +5 -0
- package/dist/shims/shims-node.mjs.map +1 -0
- package/dist/shims/shims.d.ts +1 -0
- package/dist/shims/shims.js +2 -0
- package/dist/shims/shims.js.map +1 -0
- package/dist/shims/shims.mjs +2 -0
- package/dist/shims/shims.mjs.map +1 -0
- package/dist/transportLayer.d.ts +96 -0
- package/dist/transportLayer.js +2 -0
- package/dist/transportLayer.js.map +1 -0
- package/dist/transportLayer.mjs +2 -0
- package/dist/transportLayer.mjs.map +1 -0
- package/dist/transportLayerEvents.d.ts +99 -0
- package/dist/transportLayerEvents.js +2 -0
- package/dist/transportLayerEvents.js.map +1 -0
- package/dist/transportLayerEvents.mjs +2 -0
- package/dist/transportLayerEvents.mjs.map +1 -0
- package/dist/utils.d.ts +61 -0
- package/dist/utils.js +183 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.mjs +183 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { RuntimeEventEmitter } from '@openai/agents-core';
|
|
2
|
+
import type { MessageEvent as WebSocketMessageEvent } from 'ws';
|
|
3
|
+
import { RealtimeClientMessage, RealtimeSessionConfig, RealtimeTracingConfig, RealtimeUserInput } from './clientMessages';
|
|
4
|
+
import { RealtimeItem } from './items';
|
|
5
|
+
import { ApiKey, RealtimeTransportLayer, RealtimeTransportLayerConnectOptions } from './transportLayer';
|
|
6
|
+
import { RealtimeTranportEventTypes, TransportToolCallEvent } from './transportLayerEvents';
|
|
7
|
+
import { EventEmitterDelegate } from '@openai/agents-core/utils';
|
|
8
|
+
/**
|
|
9
|
+
* The models that are supported by the OpenAI Realtime API.
|
|
10
|
+
*/
|
|
11
|
+
export type OpenAIRealtimeModels = 'gpt-4o-realtime-preview' | 'gpt-4o-mini-realtime-preview' | 'gpt-4o-realtime-preview-2025-06-03' | 'gpt-4o-realtime-preview-2024-12-17' | 'gpt-4o-realtime-preview-2024-10-01' | 'gpt-4o-mini-realtime-preview-2024-12-17' | (string & {});
|
|
12
|
+
/**
|
|
13
|
+
* The default model that is used during the connection if no model is provided.
|
|
14
|
+
*/
|
|
15
|
+
export declare const DEFAULT_OPENAI_REALTIME_MODEL: OpenAIRealtimeModels;
|
|
16
|
+
/**
|
|
17
|
+
* The default session config that gets send over during session connection unless overriden
|
|
18
|
+
* by the user.
|
|
19
|
+
*/
|
|
20
|
+
export declare const DEFAULT_OPENAI_REALTIME_SESSION_CONFIG: Partial<RealtimeSessionConfig>;
|
|
21
|
+
/**
|
|
22
|
+
* The options for the OpenAI Realtime transport layer.
|
|
23
|
+
*/
|
|
24
|
+
export type OpenAIRealtimeBaseOptions = {
|
|
25
|
+
/**
|
|
26
|
+
* The model to used during the connection.
|
|
27
|
+
*/
|
|
28
|
+
model?: OpenAIRealtimeModels;
|
|
29
|
+
/**
|
|
30
|
+
* The API key to use for the connection.
|
|
31
|
+
*/
|
|
32
|
+
apiKey?: ApiKey;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* The events that are emitted by the OpenAI Realtime transport layer.
|
|
36
|
+
*/
|
|
37
|
+
export type OpenAIRealtimeEventTypes = {
|
|
38
|
+
/**
|
|
39
|
+
* Triggered when the connection is established.
|
|
40
|
+
*/
|
|
41
|
+
connected: [];
|
|
42
|
+
/**
|
|
43
|
+
* Triggered when the connection is closed.
|
|
44
|
+
*/
|
|
45
|
+
disconnected: [];
|
|
46
|
+
} & RealtimeTranportEventTypes;
|
|
47
|
+
export declare abstract class OpenAIRealtimeBase extends EventEmitterDelegate<OpenAIRealtimeEventTypes> implements RealtimeTransportLayer {
|
|
48
|
+
#private;
|
|
49
|
+
protected eventEmitter: RuntimeEventEmitter<OpenAIRealtimeEventTypes>;
|
|
50
|
+
constructor(options?: OpenAIRealtimeBaseOptions);
|
|
51
|
+
/**
|
|
52
|
+
* The current model that is being used by the transport layer.
|
|
53
|
+
*/
|
|
54
|
+
get currentModel(): OpenAIRealtimeModels;
|
|
55
|
+
/**
|
|
56
|
+
* The current model that is being used by the transport layer.
|
|
57
|
+
* **Note**: The model cannot be changed mid conversation.
|
|
58
|
+
*/
|
|
59
|
+
set currentModel(model: OpenAIRealtimeModels);
|
|
60
|
+
abstract get status(): 'connected' | 'disconnected' | 'connecting' | 'disconnecting';
|
|
61
|
+
abstract connect(options: RealtimeTransportLayerConnectOptions): Promise<void>;
|
|
62
|
+
abstract sendEvent(event: RealtimeClientMessage): void;
|
|
63
|
+
abstract mute(muted: boolean): void;
|
|
64
|
+
abstract close(): void;
|
|
65
|
+
abstract interrupt(): void;
|
|
66
|
+
abstract readonly muted: boolean | null;
|
|
67
|
+
protected _getApiKey(options: RealtimeTransportLayerConnectOptions): Promise<string>;
|
|
68
|
+
protected _onMessage(event: MessageEvent | WebSocketMessageEvent): void;
|
|
69
|
+
protected _onError(error: any): void;
|
|
70
|
+
protected _onOpen(): void;
|
|
71
|
+
protected _onClose(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Send a message to the Realtime API. This will create a new item in the conversation and
|
|
74
|
+
* trigger a response.
|
|
75
|
+
*
|
|
76
|
+
* @param message - The message to send.
|
|
77
|
+
* @param otherEventData - Additional event data to send.
|
|
78
|
+
*/
|
|
79
|
+
sendMessage(message: RealtimeUserInput, otherEventData: Record<string, any>): void;
|
|
80
|
+
protected _getMergedSessionConfig(config: Partial<RealtimeSessionConfig>): {
|
|
81
|
+
instructions: string | undefined;
|
|
82
|
+
model: string;
|
|
83
|
+
voice: string | undefined;
|
|
84
|
+
modalities: ("text" | "audio")[] | undefined;
|
|
85
|
+
input_audio_format: import("./clientMessages").RealtimeAudioFormat | undefined;
|
|
86
|
+
output_audio_format: import("./clientMessages").RealtimeAudioFormat | undefined;
|
|
87
|
+
input_audio_transcription: Record<string, any> | undefined;
|
|
88
|
+
turn_detection: Record<string, any> | undefined;
|
|
89
|
+
tool_choice: import("@openai/agents-core").ModelSettingsToolChoice | undefined;
|
|
90
|
+
tools: {
|
|
91
|
+
strict: undefined;
|
|
92
|
+
type: "function";
|
|
93
|
+
name: string;
|
|
94
|
+
description: string;
|
|
95
|
+
parameters: import("@openai/agents-core/types").JsonObjectSchema<any>;
|
|
96
|
+
}[] | undefined;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Sets the internal tracing config. This is used to track the tracing config that has been set
|
|
100
|
+
* during the session.create event.
|
|
101
|
+
*/
|
|
102
|
+
set _tracingConfig(tracingConfig: RealtimeTracingConfig | null);
|
|
103
|
+
/**
|
|
104
|
+
* Sets the tracing config for the session. This will send the tracing config to the Realtime API.
|
|
105
|
+
*
|
|
106
|
+
* @param tracingConfig - The tracing config to set. We don't support 'auto' here as the SDK will always configure a Workflow Name unless it exists
|
|
107
|
+
*/
|
|
108
|
+
protected _updateTracingConfig(tracingConfig: RealtimeTracingConfig): void;
|
|
109
|
+
/**
|
|
110
|
+
* Updates the session config. This will merge it with the current session config with the default
|
|
111
|
+
* values and send it to the Realtime API.
|
|
112
|
+
*
|
|
113
|
+
* @param config - The session config to update.
|
|
114
|
+
*/
|
|
115
|
+
updateSessionConfig(config: Partial<RealtimeSessionConfig>): void;
|
|
116
|
+
/**
|
|
117
|
+
* Send the output of a function call to the Realtime API.
|
|
118
|
+
*
|
|
119
|
+
* @param toolCall - The tool call to send the output for.
|
|
120
|
+
* @param output - The output of the function call.
|
|
121
|
+
* @param startResponse - Whether to start a new response after sending the output.
|
|
122
|
+
*/
|
|
123
|
+
sendFunctionCallOutput(toolCall: TransportToolCallEvent, output: string, startResponse?: boolean): void;
|
|
124
|
+
/**
|
|
125
|
+
* Send an audio buffer to the Realtime API. If `{ commit: true }` is passed, the audio buffer
|
|
126
|
+
* will be committed and the model will start processing it. This is necessary if you have
|
|
127
|
+
* disabled turn detection / voice activity detection (VAD).
|
|
128
|
+
*
|
|
129
|
+
* @param audio - The audio buffer to send.
|
|
130
|
+
* @param options - The options for the audio buffer.
|
|
131
|
+
*/
|
|
132
|
+
sendAudio(audio: ArrayBuffer, { commit }?: {
|
|
133
|
+
commit?: boolean;
|
|
134
|
+
}): void;
|
|
135
|
+
/**
|
|
136
|
+
* Reset the history of the conversation. This will create a diff between the old and new history
|
|
137
|
+
* and send the necessary events to the Realtime API to update the history.
|
|
138
|
+
*
|
|
139
|
+
* @param oldHistory - The old history of the conversation.
|
|
140
|
+
* @param newHistory - The new history of the conversation.
|
|
141
|
+
*/
|
|
142
|
+
resetHistory(oldHistory: RealtimeItem[], newHistory: RealtimeItem[]): void;
|
|
143
|
+
}
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
import { RuntimeEventEmitter, Usage } from '@openai/agents-core';
|
|
2
|
+
import { realtimeMessageItemSchema, realtimeToolCallItem, } from "./items.js";
|
|
3
|
+
import logger from "./logger.js";
|
|
4
|
+
import { parseRealtimeEvent, responseDoneEventSchema, } from "./openaiRealtimeEvents.js";
|
|
5
|
+
import { arrayBufferToBase64, diffRealtimeHistory } from "./utils.js";
|
|
6
|
+
import { EventEmitterDelegate } from '@openai/agents-core/utils';
|
|
7
|
+
/**
|
|
8
|
+
* The default model that is used during the connection if no model is provided.
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_OPENAI_REALTIME_MODEL = 'gpt-4o-realtime-preview';
|
|
11
|
+
/**
|
|
12
|
+
* The default session config that gets send over during session connection unless overriden
|
|
13
|
+
* by the user.
|
|
14
|
+
*/
|
|
15
|
+
export const DEFAULT_OPENAI_REALTIME_SESSION_CONFIG = {
|
|
16
|
+
voice: 'ash',
|
|
17
|
+
modalities: ['text', 'audio'],
|
|
18
|
+
inputAudioFormat: 'pcm16',
|
|
19
|
+
outputAudioFormat: 'pcm16',
|
|
20
|
+
inputAudioTranscription: {
|
|
21
|
+
model: 'gpt-4o-mini-transcribe',
|
|
22
|
+
},
|
|
23
|
+
turnDetection: {
|
|
24
|
+
type: 'semantic_vad',
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
export class OpenAIRealtimeBase extends EventEmitterDelegate {
|
|
28
|
+
#model;
|
|
29
|
+
#apiKey;
|
|
30
|
+
#tracingConfig = null;
|
|
31
|
+
eventEmitter = new RuntimeEventEmitter();
|
|
32
|
+
constructor(options = {}) {
|
|
33
|
+
super();
|
|
34
|
+
this.#model = options.model ?? DEFAULT_OPENAI_REALTIME_MODEL;
|
|
35
|
+
this.#apiKey = options.apiKey;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The current model that is being used by the transport layer.
|
|
39
|
+
*/
|
|
40
|
+
get currentModel() {
|
|
41
|
+
return this.#model;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The current model that is being used by the transport layer.
|
|
45
|
+
* **Note**: The model cannot be changed mid conversation.
|
|
46
|
+
*/
|
|
47
|
+
set currentModel(model) {
|
|
48
|
+
this.#model = model;
|
|
49
|
+
}
|
|
50
|
+
async _getApiKey(options) {
|
|
51
|
+
const apiKey = options.apiKey ?? this.#apiKey;
|
|
52
|
+
if (typeof apiKey === 'function') {
|
|
53
|
+
return await apiKey();
|
|
54
|
+
}
|
|
55
|
+
return apiKey;
|
|
56
|
+
}
|
|
57
|
+
_onMessage(event) {
|
|
58
|
+
const { data: parsed, isGeneric } = parseRealtimeEvent(event);
|
|
59
|
+
if (parsed === null) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
this.emit('*', parsed);
|
|
63
|
+
if (isGeneric) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (parsed.type === 'error') {
|
|
67
|
+
this.emit('error', { type: 'error', error: parsed });
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
this.emit(parsed.type, parsed);
|
|
71
|
+
}
|
|
72
|
+
if (parsed.type === 'response.created') {
|
|
73
|
+
this.emit('turn_started', {
|
|
74
|
+
type: 'response_started',
|
|
75
|
+
providerData: {
|
|
76
|
+
...parsed,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (parsed.type === 'response.done') {
|
|
82
|
+
const response = responseDoneEventSchema.safeParse(parsed);
|
|
83
|
+
if (!response.success) {
|
|
84
|
+
logger.error('Error parsing response done event', response.error);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const inputTokens = response.data.response.usage?.input_tokens ?? 0;
|
|
88
|
+
const outputTokens = response.data.response.usage?.output_tokens ?? 0;
|
|
89
|
+
const totalTokens = inputTokens + outputTokens;
|
|
90
|
+
const usage = new Usage({
|
|
91
|
+
inputTokens,
|
|
92
|
+
inputTokensDetails: response.data.response.usage?.input_tokens_details ?? {},
|
|
93
|
+
outputTokens,
|
|
94
|
+
outputTokensDetails: response.data.response.usage?.output_tokens_details ?? {},
|
|
95
|
+
totalTokens,
|
|
96
|
+
});
|
|
97
|
+
this.emit('usage_update', usage);
|
|
98
|
+
this.emit('turn_done', {
|
|
99
|
+
type: 'response_done',
|
|
100
|
+
response: {
|
|
101
|
+
id: response.data.response.id ?? '',
|
|
102
|
+
output: response.data.response.output ?? [],
|
|
103
|
+
usage: {
|
|
104
|
+
inputTokens,
|
|
105
|
+
inputTokensDetails: response.data.response.usage?.input_tokens_details ?? {},
|
|
106
|
+
outputTokens,
|
|
107
|
+
outputTokensDetails: response.data.response.usage?.output_tokens_details ?? {},
|
|
108
|
+
totalTokens,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (parsed.type === 'response.audio.done') {
|
|
115
|
+
this.emit('audio_done');
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (parsed.type === 'conversation.item.deleted') {
|
|
119
|
+
this.emit('item_deleted', {
|
|
120
|
+
itemId: parsed.item_id,
|
|
121
|
+
});
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (parsed.type === 'conversation.item.input_audio_transcription.completed' ||
|
|
125
|
+
parsed.type === 'conversation.item.truncated') {
|
|
126
|
+
// right now rather than keeping track of partials and rebuilding the item we
|
|
127
|
+
// will retrieve it instead which triggers the `conversation.item.retrieved` event below
|
|
128
|
+
this.sendEvent({
|
|
129
|
+
type: 'conversation.item.retrieve',
|
|
130
|
+
item_id: parsed.item_id,
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (parsed.type === 'conversation.item.input_audio_transcription.delta' ||
|
|
135
|
+
parsed.type === 'response.text.delta' ||
|
|
136
|
+
parsed.type === 'response.audio_transcript.delta' ||
|
|
137
|
+
parsed.type === 'response.function_call_arguments.delta') {
|
|
138
|
+
if (parsed.type === 'response.audio_transcript.delta') {
|
|
139
|
+
this.emit('audio_transcript_delta', {
|
|
140
|
+
type: 'transcript_delta',
|
|
141
|
+
delta: parsed.delta,
|
|
142
|
+
itemId: parsed.item_id,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
// no support for partial transcripts yet.
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (parsed.type === 'conversation.item.created' ||
|
|
149
|
+
parsed.type === 'conversation.item.retrieved') {
|
|
150
|
+
if (parsed.item.type === 'message') {
|
|
151
|
+
const previousItemId = parsed.type === 'conversation.item.created'
|
|
152
|
+
? parsed.previous_item_id
|
|
153
|
+
: null;
|
|
154
|
+
const item = realtimeMessageItemSchema.parse({
|
|
155
|
+
itemId: parsed.item.id,
|
|
156
|
+
previousItemId,
|
|
157
|
+
type: parsed.item.type,
|
|
158
|
+
role: parsed.item.role,
|
|
159
|
+
content: parsed.item.content,
|
|
160
|
+
status: parsed.item.status,
|
|
161
|
+
});
|
|
162
|
+
this.emit('item_update', item);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (parsed.type === 'response.output_item.done' ||
|
|
167
|
+
parsed.type === 'response.output_item.added') {
|
|
168
|
+
const item = parsed.item;
|
|
169
|
+
if (item.type === 'function_call' && item.status === 'completed') {
|
|
170
|
+
const toolCall = realtimeToolCallItem.parse({
|
|
171
|
+
itemId: item.id,
|
|
172
|
+
type: item.type,
|
|
173
|
+
status: 'in_progress', // we set it to in_progress for the UI as it will only be completed with the output
|
|
174
|
+
arguments: item.arguments,
|
|
175
|
+
name: item.name,
|
|
176
|
+
output: null,
|
|
177
|
+
});
|
|
178
|
+
this.emit('item_update', toolCall);
|
|
179
|
+
this.emit('function_call', {
|
|
180
|
+
id: item.id,
|
|
181
|
+
type: 'function_call',
|
|
182
|
+
callId: item.call_id ?? '',
|
|
183
|
+
arguments: item.arguments ?? '',
|
|
184
|
+
name: item.name ?? '',
|
|
185
|
+
});
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (item.type === 'message') {
|
|
189
|
+
const realtimeItem = realtimeMessageItemSchema.parse({
|
|
190
|
+
itemId: parsed.item.id,
|
|
191
|
+
type: parsed.item.type,
|
|
192
|
+
role: parsed.item.role,
|
|
193
|
+
content: parsed.item.content,
|
|
194
|
+
status: 'in_progress',
|
|
195
|
+
});
|
|
196
|
+
this.emit('item_update', realtimeItem);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
_onError(error) {
|
|
202
|
+
this.emit('error', {
|
|
203
|
+
type: 'error',
|
|
204
|
+
error,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
_onOpen() {
|
|
208
|
+
this.emit('connected');
|
|
209
|
+
}
|
|
210
|
+
_onClose() {
|
|
211
|
+
this.emit('disconnected');
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Send a message to the Realtime API. This will create a new item in the conversation and
|
|
215
|
+
* trigger a response.
|
|
216
|
+
*
|
|
217
|
+
* @param message - The message to send.
|
|
218
|
+
* @param otherEventData - Additional event data to send.
|
|
219
|
+
*/
|
|
220
|
+
sendMessage(message, otherEventData) {
|
|
221
|
+
this.sendEvent({
|
|
222
|
+
type: 'conversation.item.create',
|
|
223
|
+
item: typeof message === 'string'
|
|
224
|
+
? {
|
|
225
|
+
type: 'message',
|
|
226
|
+
role: 'user',
|
|
227
|
+
content: [
|
|
228
|
+
{
|
|
229
|
+
type: 'input_text',
|
|
230
|
+
text: message,
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
}
|
|
234
|
+
: message,
|
|
235
|
+
...otherEventData,
|
|
236
|
+
});
|
|
237
|
+
this.sendEvent({
|
|
238
|
+
type: 'response.create',
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
_getMergedSessionConfig(config) {
|
|
242
|
+
const sessionData = {
|
|
243
|
+
instructions: config.instructions,
|
|
244
|
+
model: config.model ??
|
|
245
|
+
this.#model ??
|
|
246
|
+
DEFAULT_OPENAI_REALTIME_SESSION_CONFIG.model,
|
|
247
|
+
voice: config.voice ?? DEFAULT_OPENAI_REALTIME_SESSION_CONFIG.voice,
|
|
248
|
+
modalities: config.modalities ?? DEFAULT_OPENAI_REALTIME_SESSION_CONFIG.modalities,
|
|
249
|
+
input_audio_format: config.inputAudioFormat ??
|
|
250
|
+
DEFAULT_OPENAI_REALTIME_SESSION_CONFIG.inputAudioFormat,
|
|
251
|
+
output_audio_format: config.outputAudioFormat ??
|
|
252
|
+
DEFAULT_OPENAI_REALTIME_SESSION_CONFIG.outputAudioFormat,
|
|
253
|
+
input_audio_transcription: config.inputAudioTranscription ??
|
|
254
|
+
DEFAULT_OPENAI_REALTIME_SESSION_CONFIG.inputAudioTranscription,
|
|
255
|
+
turn_detection: config.turnDetection ??
|
|
256
|
+
DEFAULT_OPENAI_REALTIME_SESSION_CONFIG.turnDetection,
|
|
257
|
+
tool_choice: config.toolChoice ?? DEFAULT_OPENAI_REALTIME_SESSION_CONFIG.toolChoice,
|
|
258
|
+
tools: config.tools?.map((tool) => ({
|
|
259
|
+
...tool,
|
|
260
|
+
strict: undefined,
|
|
261
|
+
})),
|
|
262
|
+
// We don't set tracing here to make sure that we don't try to override it on every
|
|
263
|
+
// session.update as it might lead to errors
|
|
264
|
+
...(config.providerData ?? {}),
|
|
265
|
+
};
|
|
266
|
+
return sessionData;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Sets the internal tracing config. This is used to track the tracing config that has been set
|
|
270
|
+
* during the session.create event.
|
|
271
|
+
*/
|
|
272
|
+
set _tracingConfig(tracingConfig) {
|
|
273
|
+
this.#tracingConfig = tracingConfig;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Sets the tracing config for the session. This will send the tracing config to the Realtime API.
|
|
277
|
+
*
|
|
278
|
+
* @param tracingConfig - The tracing config to set. We don't support 'auto' here as the SDK will always configure a Workflow Name unless it exists
|
|
279
|
+
*/
|
|
280
|
+
_updateTracingConfig(tracingConfig) {
|
|
281
|
+
if (typeof this.#tracingConfig === 'undefined') {
|
|
282
|
+
// treating it as default value
|
|
283
|
+
this.#tracingConfig = null;
|
|
284
|
+
}
|
|
285
|
+
if (tracingConfig === 'auto') {
|
|
286
|
+
// turn on tracing in auto mode
|
|
287
|
+
this.sendEvent({
|
|
288
|
+
type: 'session.update',
|
|
289
|
+
session: {
|
|
290
|
+
tracing: 'auto',
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (typeof this.#tracingConfig !== 'string' &&
|
|
296
|
+
typeof tracingConfig !== 'string') {
|
|
297
|
+
// tracing is already set, we can't change it
|
|
298
|
+
logger.warn('Tracing config is already set, skipping setting it again. This likely happens when you already set a tracing config on session creation.');
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
if (tracingConfig === null) {
|
|
302
|
+
logger.debug('Disabling tracing for this session. It cannot be turned on for this session from this point on.');
|
|
303
|
+
this.sendEvent({
|
|
304
|
+
type: 'session.update',
|
|
305
|
+
session: {
|
|
306
|
+
tracing: null,
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
if (this.#tracingConfig === null ||
|
|
312
|
+
typeof this.#tracingConfig === 'string') {
|
|
313
|
+
// tracing is currently not set so we can set it to the new value
|
|
314
|
+
this.sendEvent({
|
|
315
|
+
type: 'session.update',
|
|
316
|
+
session: {
|
|
317
|
+
tracing: tracingConfig,
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
if (tracingConfig?.group_id !== this.#tracingConfig?.group_id ||
|
|
323
|
+
tracingConfig?.metadata !== this.#tracingConfig?.metadata ||
|
|
324
|
+
tracingConfig?.workflow_name !== this.#tracingConfig?.workflow_name) {
|
|
325
|
+
logger.warn('Mismatch in tracing config. Ignoring the new tracing config. This likely happens when you already set a tracing config on session creation. Current tracing config: %s, new tracing config: %s', JSON.stringify(this.#tracingConfig), JSON.stringify(tracingConfig));
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
this.sendEvent({
|
|
329
|
+
type: 'session.update',
|
|
330
|
+
session: {
|
|
331
|
+
tracing: tracingConfig,
|
|
332
|
+
},
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Updates the session config. This will merge it with the current session config with the default
|
|
337
|
+
* values and send it to the Realtime API.
|
|
338
|
+
*
|
|
339
|
+
* @param config - The session config to update.
|
|
340
|
+
*/
|
|
341
|
+
updateSessionConfig(config) {
|
|
342
|
+
const sessionData = this._getMergedSessionConfig(config);
|
|
343
|
+
this.sendEvent({
|
|
344
|
+
type: 'session.update',
|
|
345
|
+
session: sessionData,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Send the output of a function call to the Realtime API.
|
|
350
|
+
*
|
|
351
|
+
* @param toolCall - The tool call to send the output for.
|
|
352
|
+
* @param output - The output of the function call.
|
|
353
|
+
* @param startResponse - Whether to start a new response after sending the output.
|
|
354
|
+
*/
|
|
355
|
+
sendFunctionCallOutput(toolCall, output, startResponse = true) {
|
|
356
|
+
this.sendEvent({
|
|
357
|
+
type: 'conversation.item.create',
|
|
358
|
+
item: {
|
|
359
|
+
type: 'function_call_output',
|
|
360
|
+
output,
|
|
361
|
+
call_id: toolCall.callId,
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
try {
|
|
365
|
+
const item = realtimeToolCallItem.parse({
|
|
366
|
+
itemId: toolCall.id,
|
|
367
|
+
previousItemId: toolCall.previousItemId,
|
|
368
|
+
type: 'function_call',
|
|
369
|
+
status: 'completed',
|
|
370
|
+
arguments: toolCall.arguments,
|
|
371
|
+
name: toolCall.name,
|
|
372
|
+
output,
|
|
373
|
+
});
|
|
374
|
+
this.emit('item_update', item);
|
|
375
|
+
}
|
|
376
|
+
catch (error) {
|
|
377
|
+
logger.error('Error parsing tool call item', error, toolCall);
|
|
378
|
+
}
|
|
379
|
+
if (startResponse) {
|
|
380
|
+
this.sendEvent({
|
|
381
|
+
type: 'response.create',
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Send an audio buffer to the Realtime API. If `{ commit: true }` is passed, the audio buffer
|
|
387
|
+
* will be committed and the model will start processing it. This is necessary if you have
|
|
388
|
+
* disabled turn detection / voice activity detection (VAD).
|
|
389
|
+
*
|
|
390
|
+
* @param audio - The audio buffer to send.
|
|
391
|
+
* @param options - The options for the audio buffer.
|
|
392
|
+
*/
|
|
393
|
+
sendAudio(audio, { commit = false } = {}) {
|
|
394
|
+
this.sendEvent({
|
|
395
|
+
type: 'input_audio_buffer.append',
|
|
396
|
+
audio: arrayBufferToBase64(audio),
|
|
397
|
+
});
|
|
398
|
+
if (commit) {
|
|
399
|
+
this.sendEvent({
|
|
400
|
+
type: 'input_audio_buffer.commit',
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Reset the history of the conversation. This will create a diff between the old and new history
|
|
406
|
+
* and send the necessary events to the Realtime API to update the history.
|
|
407
|
+
*
|
|
408
|
+
* @param oldHistory - The old history of the conversation.
|
|
409
|
+
* @param newHistory - The new history of the conversation.
|
|
410
|
+
*/
|
|
411
|
+
resetHistory(oldHistory, newHistory) {
|
|
412
|
+
const { removals, additions, updates } = diffRealtimeHistory(oldHistory, newHistory);
|
|
413
|
+
const removalIds = new Set(removals.map((item) => item.itemId));
|
|
414
|
+
// we don't have an update event for items so we will remove and re-add what's there
|
|
415
|
+
for (const update of updates) {
|
|
416
|
+
removalIds.add(update.itemId);
|
|
417
|
+
}
|
|
418
|
+
if (removalIds.size > 0) {
|
|
419
|
+
for (const itemId of removalIds) {
|
|
420
|
+
this.sendEvent({
|
|
421
|
+
type: 'conversation.item.delete',
|
|
422
|
+
item_id: itemId,
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
const additionsAndUpdates = [...additions, ...updates];
|
|
427
|
+
for (const addition of additionsAndUpdates) {
|
|
428
|
+
if (addition.type === 'message') {
|
|
429
|
+
const itemEntry = {
|
|
430
|
+
type: 'message',
|
|
431
|
+
role: addition.role,
|
|
432
|
+
content: addition.content,
|
|
433
|
+
id: addition.itemId,
|
|
434
|
+
};
|
|
435
|
+
if (addition.role !== 'system' && addition.status) {
|
|
436
|
+
itemEntry.status = addition.status;
|
|
437
|
+
}
|
|
438
|
+
this.sendEvent({
|
|
439
|
+
type: 'conversation.item.create',
|
|
440
|
+
item: itemEntry,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
else if (addition.type === 'function_call') {
|
|
444
|
+
logger.warn('Function calls cannot be manually added or updated at the moment. Ignoring.');
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
//# sourceMappingURL=openaiRealtimeBase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openaiRealtimeBase.js","sourceRoot":"","sources":["../src/openaiRealtimeBase.ts"],"names":[],"mappings":"OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,qBAAqB;OASzD,EAEL,yBAAyB,EACzB,oBAAoB,GACrB;OACM,MAAM;OACN,EACL,kBAAkB,EAClB,uBAAuB,GACxB;OAUM,EAAE,mBAAmB,EAAE,mBAAmB,EAAE;OAC5C,EAAE,oBAAoB,EAAE,MAAM,2BAA2B;AAchE;;GAEG;AACH,MAAM,CAAC,MAAM,6BAA6B,GACxC,yBAAyB,CAAC;AAE5B;;;GAGG;AACH,MAAM,CAAC,MAAM,sCAAsC,GACjD;IACE,KAAK,EAAE,KAAK;IACZ,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;IAC7B,gBAAgB,EAAE,OAAO;IACzB,iBAAiB,EAAE,OAAO;IAC1B,uBAAuB,EAAE;QACvB,KAAK,EAAE,wBAAwB;KAChC;IACD,aAAa,EAAE;QACb,IAAI,EAAE,cAAc;KACrB;CACF,CAAC;AA8BJ,MAAM,OAAgB,kBACpB,SAAQ,oBAA8C;IAGtD,MAAM,CAAS;IACf,OAAO,CAAqB;IAC5B,cAAc,GAAiC,IAAI,CAAC;IAE1C,YAAY,GACpB,IAAI,mBAAmB,EAA4B,CAAC;IAEtD,YAAY,UAAqC,EAAE;QACjD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,6BAA6B,CAAC;QAC7D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,IAAI,YAAY,CAAC,KAA2B;QAC1C,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAsBS,KAAK,CAAC,UAAU,CAAC,OAA6C;QACtE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC;QAE9C,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;YACjC,OAAO,MAAM,MAAM,EAAE,CAAC;QACxB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAES,UAAU,CAAC,KAA2C;QAC9D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC9D,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvB,IAAI,SAAS,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;gBACxB,IAAI,EAAE,kBAAkB;gBACxB,YAAY,EAAE;oBACZ,GAAG,MAAM;iBACV;aACF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,uBAAuB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC3D,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAClE,OAAO;YACT,CAAC;YACD,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC,CAAC;YACpE,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC,CAAC;YACtE,MAAM,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;YAC/C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;gBACtB,WAAW;gBACX,kBAAkB,EAChB,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,oBAAoB,IAAI,EAAE;gBAC1D,YAAY;gBACZ,mBAAmB,EACjB,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,qBAAqB,IAAI,EAAE;gBAC3D,WAAW;aACZ,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBACrB,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE;oBACR,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE;oBACnC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE;oBAC3C,KAAK,EAAE;wBACL,WAAW;wBACX,kBAAkB,EAChB,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,oBAAoB,IAAI,EAAE;wBAC1D,YAAY;wBACZ,mBAAmB,EACjB,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,qBAAqB,IAAI,EAAE;wBAC3D,WAAW;qBACZ;iBACF;aACF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,2BAA2B,EAAE,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;gBACxB,MAAM,EAAE,MAAM,CAAC,OAAO;aACvB,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IACE,MAAM,CAAC,IAAI,KAAK,uDAAuD;YACvE,MAAM,CAAC,IAAI,KAAK,6BAA6B,EAC7C,CAAC;YACD,6EAA6E;YAC7E,wFAAwF;YACxF,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,4BAA4B;gBAClC,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IACE,MAAM,CAAC,IAAI,KAAK,mDAAmD;YACnE,MAAM,CAAC,IAAI,KAAK,qBAAqB;YACrC,MAAM,CAAC,IAAI,KAAK,iCAAiC;YACjD,MAAM,CAAC,IAAI,KAAK,wCAAwC,EACxD,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,KAAK,iCAAiC,EAAE,CAAC;gBACtD,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE;oBAClC,IAAI,EAAE,kBAAkB;oBACxB,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,MAAM,EAAE,MAAM,CAAC,OAAO;iBACvB,CAAC,CAAC;YACL,CAAC;YACD,0CAA0C;YAC1C,OAAO;QACT,CAAC;QAED,IACE,MAAM,CAAC,IAAI,KAAK,2BAA2B;YAC3C,MAAM,CAAC,IAAI,KAAK,6BAA6B,EAC7C,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACnC,MAAM,cAAc,GAClB,MAAM,CAAC,IAAI,KAAK,2BAA2B;oBACzC,CAAC,CAAC,MAAM,CAAC,gBAAgB;oBACzB,CAAC,CAAC,IAAI,CAAC;gBACX,MAAM,IAAI,GAAG,yBAAyB,CAAC,KAAK,CAAC;oBAC3C,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE;oBACtB,cAAc;oBACd,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;oBACtB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;oBACtB,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO;oBAC5B,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;iBAC3B,CAAC,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;gBAC/B,OAAO;YACT,CAAC;QACH,CAAC;QAED,IACE,MAAM,CAAC,IAAI,KAAK,2BAA2B;YAC3C,MAAM,CAAC,IAAI,KAAK,4BAA4B,EAC5C,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACzB,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBACjE,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC;oBAC1C,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,MAAM,EAAE,aAAa,EAAE,mFAAmF;oBAC1G,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,MAAM,EAAE,IAAI;iBACb,CAAC,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;gBACnC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;oBACzB,EAAE,EAAE,IAAI,CAAC,EAAE;oBACX,IAAI,EAAE,eAAe;oBACrB,MAAM,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;oBAC1B,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;oBAC/B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;iBACtB,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC5B,MAAM,YAAY,GAAG,yBAAyB,CAAC,KAAK,CAAC;oBACnD,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE;oBACtB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;oBACtB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;oBACtB,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO;oBAC5B,MAAM,EAAE,aAAa;iBACtB,CAAC,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;gBACvC,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC;IAES,QAAQ,CAAC,KAAU;QAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,IAAI,EAAE,OAAO;YACb,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAES,OAAO;QACf,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzB,CAAC;IAES,QAAQ;QAChB,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC5B,CAAC;IAED;;;;;;OAMG;IACH,WAAW,CAAC,OAA0B,EAAE,cAAmC;QACzE,IAAI,CAAC,SAAS,CAAC;YACb,IAAI,EAAE,0BAA0B;YAChC,IAAI,EACF,OAAO,OAAO,KAAK,QAAQ;gBACzB,CAAC,CAAC;oBACE,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,YAAY;4BAClB,IAAI,EAAE,OAAO;yBACd;qBACF;iBACF;gBACH,CAAC,CAAC,OAAO;YACb,GAAG,cAAc;SAClB,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC;YACb,IAAI,EAAE,iBAAiB;SACxB,CAAC,CAAC;IACL,CAAC;IAES,uBAAuB,CAAC,MAAsC;QACtE,MAAM,WAAW,GAAG;YAClB,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,KAAK,EACH,MAAM,CAAC,KAAK;gBACZ,IAAI,CAAC,MAAM;gBACX,sCAAsC,CAAC,KAAK;YAC9C,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,sCAAsC,CAAC,KAAK;YACnE,UAAU,EACR,MAAM,CAAC,UAAU,IAAI,sCAAsC,CAAC,UAAU;YACxE,kBAAkB,EAChB,MAAM,CAAC,gBAAgB;gBACvB,sCAAsC,CAAC,gBAAgB;YACzD,mBAAmB,EACjB,MAAM,CAAC,iBAAiB;gBACxB,sCAAsC,CAAC,iBAAiB;YAC1D,yBAAyB,EACvB,MAAM,CAAC,uBAAuB;gBAC9B,sCAAsC,CAAC,uBAAuB;YAChE,cAAc,EACZ,MAAM,CAAC,aAAa;gBACpB,sCAAsC,CAAC,aAAa;YACtD,WAAW,EACT,MAAM,CAAC,UAAU,IAAI,sCAAsC,CAAC,UAAU;YACxE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAClC,GAAG,IAAI;gBACP,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;YACH,mFAAmF;YACnF,4CAA4C;YAC5C,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;SAC/B,CAAC;QAEF,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,IAAI,cAAc,CAAC,aAA2C;QAC5D,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;IACtC,CAAC;IAED;;;;OAIG;IACO,oBAAoB,CAAC,aAAoC;QACjE,IAAI,OAAO,IAAI,CAAC,cAAc,KAAK,WAAW,EAAE,CAAC;YAC/C,+BAA+B;YAC/B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QAED,IAAI,aAAa,KAAK,MAAM,EAAE,CAAC;YAC7B,+BAA+B;YAC/B,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,gBAAgB;gBACtB,OAAO,EAAE;oBACP,OAAO,EAAE,MAAM;iBAChB;aACF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IACE,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ;YACvC,OAAO,aAAa,KAAK,QAAQ,EACjC,CAAC;YACD,6CAA6C;YAC7C,MAAM,CAAC,IAAI,CACT,0IAA0I,CAC3I,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,CACV,iGAAiG,CAClG,CAAC;YAEF,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,gBAAgB;gBACtB,OAAO,EAAE;oBACP,OAAO,EAAE,IAAI;iBACd;aACF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IACE,IAAI,CAAC,cAAc,KAAK,IAAI;YAC5B,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ,EACvC,CAAC;YACD,iEAAiE;YACjE,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,gBAAgB;gBACtB,OAAO,EAAE;oBACP,OAAO,EAAE,aAAa;iBACvB;aACF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IACE,aAAa,EAAE,QAAQ,KAAK,IAAI,CAAC,cAAc,EAAE,QAAQ;YACzD,aAAa,EAAE,QAAQ,KAAK,IAAI,CAAC,cAAc,EAAE,QAAQ;YACzD,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC,cAAc,EAAE,aAAa,EACnE,CAAC;YACD,MAAM,CAAC,IAAI,CACT,gMAAgM,EAChM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,EACnC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAC9B,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,CAAC,SAAS,CAAC;YACb,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE;gBACP,OAAO,EAAE,aAAa;aACvB;SACF,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,mBAAmB,CAAC,MAAsC;QACxD,MAAM,WAAW,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;QAEzD,IAAI,CAAC,SAAS,CAAC;YACb,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,WAAW;SACrB,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,sBAAsB,CACpB,QAAgC,EAChC,MAAc,EACd,gBAAyB,IAAI;QAE7B,IAAI,CAAC,SAAS,CAAC;YACb,IAAI,EAAE,0BAA0B;YAChC,IAAI,EAAE;gBACJ,IAAI,EAAE,sBAAsB;gBAC5B,MAAM;gBACN,OAAO,EAAE,QAAQ,CAAC,MAAM;aACzB;SACF,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAAC;gBACtC,MAAM,EAAE,QAAQ,CAAC,EAAE;gBACnB,cAAc,EAAE,QAAQ,CAAC,cAAc;gBACvC,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,WAAW;gBACnB,SAAS,EAAE,QAAQ,CAAC,SAAS;gBAC7B,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,MAAM;aACP,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QAChE,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,iBAAiB;aACxB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,CACP,KAAkB,EAClB,EAAE,MAAM,GAAG,KAAK,KAA2B,EAAE;QAE7C,IAAI,CAAC,SAAS,CAAC;YACb,IAAI,EAAE,2BAA2B;YACjC,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC;SAClC,CAAC,CAAC;QAEH,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,2BAA2B;aAClC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAC,UAA0B,EAAE,UAA0B;QACjE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,mBAAmB,CAC1D,UAAU,EACV,UAAU,CACX,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAChE,oFAAoF;QACpF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QAED,IAAI,UAAU,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACxB,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;gBAChC,IAAI,CAAC,SAAS,CAAC;oBACb,IAAI,EAAE,0BAA0B;oBAChC,OAAO,EAAE,MAAM;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,mBAAmB,GAAG,CAAC,GAAG,SAAS,EAAE,GAAG,OAAO,CAAC,CAAC;QAEvD,KAAK,MAAM,QAAQ,IAAI,mBAAmB,EAAE,CAAC;YAC3C,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAChC,MAAM,SAAS,GAAwB;oBACrC,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,QAAQ,CAAC,IAAI;oBACnB,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,EAAE,EAAE,QAAQ,CAAC,MAAM;iBACpB,CAAC;gBACF,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;oBAClD,SAAS,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;gBACrC,CAAC;gBACD,IAAI,CAAC,SAAS,CAAC;oBACb,IAAI,EAAE,0BAA0B;oBAChC,IAAI,EAAE,SAAS;iBAChB,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBAC7C,MAAM,CAAC,IAAI,CACT,6EAA6E,CAC9E,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|