@intelliweave/embedded 1.6.45

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.
@@ -0,0 +1,1109 @@
1
+ import * as onnxruntime_web from 'onnxruntime-web';
2
+ import { InferenceSession, Tensor } from 'onnxruntime-web';
3
+
4
+ /**
5
+ * This is a utility class for dealing with the ONNX runtime and model loading.
6
+ */
7
+ declare class ONNXModel {
8
+ /** ONNX runtime loader. Example: `ONNXModel.lib = () => import('onnxruntime-web')` */
9
+ static lib?: () => Promise<typeof onnxruntime_web>;
10
+ /** Loaded ONNX runtime */
11
+ static onnx?: typeof onnxruntime_web;
12
+ /** True if this device supports the ONNX runtime */
13
+ static isSupported(): boolean;
14
+ /** The loaded model */
15
+ session: InferenceSession;
16
+ /** Tensors used for state, ie they are passed from the output to the next input */
17
+ stateTensors: {
18
+ [key: string]: {
19
+ tensor: Tensor;
20
+ outputName: string;
21
+ };
22
+ };
23
+ /** Constant tensors that will always be passed as-is to the input */
24
+ constantTensors: ONNXTensors;
25
+ /** Load a model */
26
+ static load(modelURL: string): Promise<ONNXModel>;
27
+ /** Constructor */
28
+ constructor(session: InferenceSession);
29
+ /** Create a new tensor zeroed from the specified definition */
30
+ makeTensor(type: BufferType, dims: number[], fillWith?: number): onnxruntime_web.TypedTensor<"float32"> | onnxruntime_web.TypedTensor<"int8"> | onnxruntime_web.TypedTensor<"int16"> | onnxruntime_web.TypedTensor<"int32"> | onnxruntime_web.TypedTensor<"int64"> | onnxruntime_web.TypedTensor<"uint8"> | onnxruntime_web.TypedTensor<"uint16"> | onnxruntime_web.TypedTensor<"uint32"> | onnxruntime_web.TypedTensor<"uint64">;
31
+ /** Register a static tensor, ie one that will be passed to the input on every call */
32
+ registerConstant(name: string, tensor: Tensor): Tensor;
33
+ /** Create and register a static tensor, ie one that will be passed to the input on every call */
34
+ makeConstant(name: string, type: BufferType, dims: number[], fillWith?: number): Tensor;
35
+ /** Register a state tensor, ie one that will be passed from the output to the input */
36
+ registerState(inputName: string, outputName: string, tensor: Tensor): Tensor;
37
+ /** Create and register a state tensor, ie one that will be passed from the output to the input */
38
+ makeState(inputName: string, outputName: string, type: BufferType, dims: number[], fillWith?: number): Tensor;
39
+ /** True if a previous run is still active */
40
+ private _runActive;
41
+ /** If true, will ignore a request to run if a previous run is still active. Otherwise, will throw an error */
42
+ ignoreIfBusy: boolean;
43
+ /** Run the model */
44
+ run(inputs?: ONNXTensors): Promise<void | InferenceSession.OnnxValueMapType>;
45
+ /** Reset state tensors to zero */
46
+ resetState(): void;
47
+ }
48
+ /** A collection of named tensors */
49
+ type ONNXTensors = {
50
+ [key: string]: Tensor;
51
+ };
52
+ /** Buffer types */
53
+ type BufferType = 'float32' | 'int8' | 'int16' | 'int32' | 'int64' | 'uint8' | 'uint16' | 'uint32' | 'uint64';
54
+
55
+ /** Convert an array of Float32Array audio buffers to a WAV file */
56
+ declare function audioToWav(sampleRate: number, buffers: Float32Array[]): File;
57
+
58
+ /** WebSocket that lets you send packets before connection is opened */
59
+ declare class BufferedWebSocket extends WebSocket {
60
+ /** Pending data to send */
61
+ pendingData: any[];
62
+ /** Constructor */
63
+ constructor(url: string);
64
+ /** Send data */
65
+ send(data: any): void;
66
+ /** Called when the connection opens */
67
+ private _onOpen;
68
+ }
69
+
70
+ /** Supported classes */
71
+ type SupportedArrayBuffers = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array;
72
+ /**
73
+ * This class accepts an input of a variable amount of data elements, and outputs a fixed amount of data elements.
74
+ */
75
+ declare class FixedBufferStream<ArrayType extends SupportedArrayBuffers> {
76
+ /** The class to use when creating buffers, ie Int16Array, Float32Array, etc */
77
+ ArrayClass?: Function;
78
+ /** Number of elements in the output buffers */
79
+ outputBufferSize: number;
80
+ /** Partial buffers */
81
+ partialBuffers: ArrayType[];
82
+ /** The amount of bytes already consumed from the first buffer in the `buffers` array */
83
+ partialBufferOffset: number;
84
+ /** Get number of queued elements */
85
+ get queuedSize(): number;
86
+ /**
87
+ * Constructor
88
+ *
89
+ * @param outputBufferSize - Number of elements in the output buffers
90
+ */
91
+ constructor(ArrayClass: Function, outputBufferSize: number);
92
+ /** Feed data in */
93
+ feed(data: ArrayType): void;
94
+ /** True if there's enough data to return a buffer from drain() */
95
+ get canDrain(): boolean;
96
+ /** Pull the next chunk of fixed data, or else returns null if no more data */
97
+ drain(): ArrayType | null;
98
+ /** Pad the buffer with zeroes to fill the remaining chunk */
99
+ pad(): void;
100
+ }
101
+
102
+ /**
103
+ * @author Created by felix on 18-7-2.
104
+ * @email 307253927@qq.com
105
+ * @source https://github.com/felix307253927/resampler/blob/master/Resampler.js
106
+ */
107
+
108
+ class Resampler {
109
+ constructor(fromSampleRate, toSampleRate, channels, inputBufferSize) {
110
+
111
+ if (!fromSampleRate || !toSampleRate || !channels) {
112
+ throw(new Error("Invalid settings specified for the resampler."));
113
+ }
114
+ this.resampler = null;
115
+ this.fromSampleRate = fromSampleRate;
116
+ this.toSampleRate = toSampleRate;
117
+ this.channels = channels || 0;
118
+ this.inputBufferSize = inputBufferSize;
119
+ this.initialize();
120
+ }
121
+
122
+ initialize() {
123
+ if (this.fromSampleRate == this.toSampleRate) {
124
+
125
+ // Setup resampler bypass - Resampler just returns what was passed through
126
+ this.resampler = (buffer) => {
127
+ return buffer
128
+ };
129
+ this.ratioWeight = 1;
130
+
131
+ } else {
132
+
133
+ if (this.fromSampleRate < this.toSampleRate) {
134
+
135
+ // Use generic linear interpolation if upsampling,
136
+ // as linear interpolation produces a gradient that we want
137
+ // and works fine with two input sample points per output in this case.
138
+ this.linearInterpolation();
139
+ this.lastWeight = 1;
140
+
141
+ } else {
142
+
143
+ // Custom resampler I wrote that doesn't skip samples
144
+ // like standard linear interpolation in high downsampling.
145
+ // This is more accurate than linear interpolation on downsampling.
146
+ this.multiTap();
147
+ this.tailExists = false;
148
+ this.lastWeight = 0;
149
+ }
150
+
151
+ // Initialize the internal buffer:
152
+ this.initializeBuffers();
153
+ this.ratioWeight = this.fromSampleRate / this.toSampleRate;
154
+ }
155
+ }
156
+
157
+ bufferSlice(sliceAmount) {
158
+
159
+ //Typed array and normal array buffer section referencing:
160
+ try {
161
+ return this.outputBuffer.subarray(0, sliceAmount);
162
+ }
163
+ catch (error) {
164
+ try {
165
+ //Regular array pass:
166
+ this.outputBuffer.length = sliceAmount;
167
+ return this.outputBuffer;
168
+ }
169
+ catch (error) {
170
+ //Nightly Firefox 4 used to have the subarray function named as slice:
171
+ return this.outputBuffer.slice(0, sliceAmount);
172
+ }
173
+ }
174
+ }
175
+
176
+ initializeBuffers() {
177
+ this.outputBufferSize = (Math.ceil(this.inputBufferSize * this.toSampleRate / this.fromSampleRate / this.channels * 1.000000476837158203125) + this.channels) + this.channels;
178
+ try {
179
+ this.outputBuffer = new Float32Array(this.outputBufferSize);
180
+ this.lastOutput = new Float32Array(this.channels);
181
+ }
182
+ catch (error) {
183
+ this.outputBuffer = [];
184
+ this.lastOutput = [];
185
+ }
186
+ }
187
+
188
+ linearInterpolation() {
189
+ this.resampler = (buffer) => {
190
+ let bufferLength = buffer.length,
191
+ channels = this.channels,
192
+ outLength,
193
+ ratioWeight,
194
+ weight,
195
+ firstWeight,
196
+ secondWeight,
197
+ sourceOffset,
198
+ outputOffset,
199
+ outputBuffer,
200
+ channel;
201
+
202
+ if ((bufferLength % channels) !== 0) {
203
+ throw(new Error("Buffer was of incorrect sample length."));
204
+ }
205
+ if (bufferLength <= 0) {
206
+ return [];
207
+ }
208
+
209
+ outLength = this.outputBufferSize;
210
+ ratioWeight = this.ratioWeight;
211
+ weight = this.lastWeight;
212
+ firstWeight = 0;
213
+ secondWeight = 0;
214
+ sourceOffset = 0;
215
+ outputOffset = 0;
216
+ outputBuffer = this.outputBuffer;
217
+
218
+ for (; weight < 1; weight += ratioWeight) {
219
+ secondWeight = weight % 1;
220
+ firstWeight = 1 - secondWeight;
221
+ this.lastWeight = weight % 1;
222
+ for (channel = 0; channel < this.channels; ++channel) {
223
+ outputBuffer[outputOffset++] = (this.lastOutput[channel] * firstWeight) + (buffer[channel] * secondWeight);
224
+ }
225
+ }
226
+ weight -= 1;
227
+ for (bufferLength -= channels, sourceOffset = Math.floor(weight) * channels; outputOffset < outLength && sourceOffset < bufferLength;) {
228
+ secondWeight = weight % 1;
229
+ firstWeight = 1 - secondWeight;
230
+ for (channel = 0; channel < this.channels; ++channel) {
231
+ outputBuffer[outputOffset++] = (buffer[sourceOffset + ((channel > 0) ? (channel) : 0)] * firstWeight) + (buffer[sourceOffset+(channels + channel)] * secondWeight);
232
+ }
233
+ weight += ratioWeight;
234
+ sourceOffset = Math.floor(weight) * channels;
235
+ }
236
+ for (channel = 0; channel < channels; ++channel) {
237
+ this.lastOutput[channel] = buffer[sourceOffset++];
238
+ }
239
+ return this.bufferSlice(outputOffset);
240
+ };
241
+ }
242
+
243
+ multiTap() {
244
+ this.resampler = (buffer) => {
245
+ let bufferLength = buffer.length,
246
+ outLength,
247
+ output_variable_list,
248
+ channels = this.channels,
249
+ ratioWeight,
250
+ weight,
251
+ channel,
252
+ actualPosition,
253
+ amountToNext,
254
+ alreadyProcessedTail,
255
+ outputBuffer,
256
+ outputOffset,
257
+ currentPosition;
258
+
259
+ if ((bufferLength % channels) !== 0) {
260
+ throw(new Error("Buffer was of incorrect sample length."));
261
+ }
262
+ if (bufferLength <= 0) {
263
+ return [];
264
+ }
265
+
266
+ outLength = this.outputBufferSize;
267
+ output_variable_list = [];
268
+ ratioWeight = this.ratioWeight;
269
+ weight = 0;
270
+ actualPosition = 0;
271
+ amountToNext = 0;
272
+ alreadyProcessedTail = !this.tailExists;
273
+ this.tailExists = false;
274
+ outputBuffer = this.outputBuffer;
275
+ outputOffset = 0;
276
+ currentPosition = 0;
277
+
278
+ for (channel = 0; channel < channels; ++channel) {
279
+ output_variable_list[channel] = 0;
280
+ }
281
+
282
+ do {
283
+ if (alreadyProcessedTail) {
284
+ weight = ratioWeight;
285
+ for (channel = 0; channel < channels; ++channel) {
286
+ output_variable_list[channel] = 0;
287
+ }
288
+ } else {
289
+ weight = this.lastWeight;
290
+ for (channel = 0; channel < channels; ++channel) {
291
+ output_variable_list[channel] = this.lastOutput[channel];
292
+ }
293
+ alreadyProcessedTail = true;
294
+ }
295
+ while (weight > 0 && actualPosition < bufferLength) {
296
+ amountToNext = 1 + actualPosition - currentPosition;
297
+ if (weight >= amountToNext) {
298
+ for (channel = 0; channel < channels; ++channel) {
299
+ output_variable_list[channel] += buffer[actualPosition++] * amountToNext;
300
+ }
301
+ currentPosition = actualPosition;
302
+ weight -= amountToNext;
303
+ } else {
304
+ for (channel = 0; channel < channels; ++channel) {
305
+ output_variable_list[channel] += buffer[actualPosition + ((channel > 0) ? channel : 0)] * weight;
306
+ }
307
+ currentPosition += weight;
308
+ weight = 0;
309
+ break;
310
+ }
311
+ }
312
+
313
+ if (weight === 0) {
314
+ for (channel = 0; channel < channels; ++channel) {
315
+ outputBuffer[outputOffset++] = output_variable_list[channel] / ratioWeight;
316
+ }
317
+ } else {
318
+ this.lastWeight = weight;
319
+ for (channel = 0; channel < channels; ++channel) {
320
+ this.lastOutput[channel] = output_variable_list[channel];
321
+ }
322
+ this.tailExists = true;
323
+ break;
324
+ }
325
+ } while (actualPosition < bufferLength && outputOffset < outLength);
326
+ return this.bufferSlice(outputOffset);
327
+ };
328
+ }
329
+
330
+ resample(buffer) {
331
+ if (this.fromSampleRate == this.toSampleRate) {
332
+ this.ratioWeight = 1;
333
+ } else {
334
+ if (this.fromSampleRate < this.toSampleRate) {
335
+ this.lastWeight = 1;
336
+ } else {
337
+ this.tailExists = false;
338
+ this.lastWeight = 0;
339
+ }
340
+ this.initializeBuffers();
341
+ this.ratioWeight = this.fromSampleRate / this.toSampleRate;
342
+ }
343
+ return this.resampler(buffer)
344
+ }
345
+ }
346
+
347
+ /**
348
+ * 将无符号Float32Array数组转化成有符号的Int16Array数组
349
+ * @param {Float32Array} input unsinged Float32Array
350
+ * @return {Int16Array} singed int16
351
+ */
352
+ function floatTo16BitPCM(input) {
353
+ let i = input.length;
354
+ let output = new Int16Array(i);
355
+ while (i--) {
356
+ let s = Math.max(-1, Math.min(1, input[i]));
357
+ output[i] = (s < 0 ? s * 0x8000 : s * 0x7FFF);
358
+ }
359
+ return output;
360
+ }
361
+
362
+ function floatTo64BitPCM(input) {
363
+ let i = input.length;
364
+ let output = new BigInt64Array(i);
365
+ while (i--) {
366
+ let s = Math.max(-1, Math.min(1, input[i]));
367
+ output[i] = BigInt(Math.floor((s < 0 ? s * 0x8000 : s * 0x7FFF))) * 0x100000000000n;//(s < 0 ? s : s * 0x7FFFFFFFFFFFFFFFn);
368
+ }
369
+ return output;
370
+ }
371
+
372
+ /**
373
+ * 将有符号的Int16Array数组转化成无符号Float32Array数组
374
+ * @param {Int16Array} input singed int16
375
+ * @return {Float32Array} // unsinged float32
376
+ */
377
+ function int16ToFloat32BitPCM(input) {
378
+ let i = input.length;
379
+ let output = new Float32Array(i);
380
+ while (i--) {
381
+ let int = input[i];
382
+ output[i] = (int >= 0x8000) ? -(0x10000 - int) / 0x8000 : int / 0x7FFF;
383
+ }
384
+ return output;
385
+ }
386
+
387
+ /** Utility to trim whitespace from blocks of text */
388
+ declare function trimWhitespaceInText(text: string): string;
389
+ /** Get the global object */
390
+ declare function intelliweaveGlobalThis(): any;
391
+ /** Get the global IntelliWeave configuration object that has been created for this document, or create it if necessary. */
392
+ declare function intelliweaveConfig(): any;
393
+ /** An async generator which yields events from an SSE fetch request body (a readable stream) */
394
+ declare function sseEvents(stream: ReadableStream<Uint8Array>): AsyncGenerator<any, void, unknown>;
395
+ /** Get or create a user ID for this device. */
396
+ declare function getDefaultUserID(): string;
397
+
398
+ /** ChatGPT config options */
399
+ interface ChatGPTConfig {
400
+ /** API key */
401
+ apiKey: string;
402
+ /** Provider ID */
403
+ providerID?: string;
404
+ /** Endpoint URL if using a custom URL */
405
+ endpoint: string;
406
+ /** LLM model to use */
407
+ model: string;
408
+ /** System message to describe to the AI how to behave. */
409
+ systemMessage: string;
410
+ /** User ID used to uniquely identify users in ChatGPT's API */
411
+ userID: string;
412
+ /** If true, streams the text responses from the API */
413
+ stream: boolean;
414
+ /** Amount of estimated tokens to keep when trimming */
415
+ maxTokens: number;
416
+ /** Callback before the AI sends info to the LLM */
417
+ onBeforeMessageProcessing?: () => void;
418
+ /** Callback when a message from the AI is returned. If isChunk is true, it may be incomplete and be called again with more updates. */
419
+ onAIMessage?: (text: string, isChunk: boolean) => void;
420
+ /** Callback when the AI starts performing an action */
421
+ onAIToolStart?: (toolName: string, input: any) => void;
422
+ }
423
+ /** ChatGPT tool config */
424
+ interface ChatGPTToolConfig {
425
+ /** Name of the tool */
426
+ name: string;
427
+ /** Description of the tool */
428
+ description: string;
429
+ /** Parameters for the tool */
430
+ params: {
431
+ name: string;
432
+ type: string;
433
+ description: string;
434
+ }[];
435
+ /** Callback function to process the tool */
436
+ callback: (params: any) => any;
437
+ /** If true, this tool call will be removed from the message history after it is executed. */
438
+ removeFromMessageHistory?: boolean;
439
+ /** Misc app context */
440
+ [key: string]: any;
441
+ }
442
+ /**
443
+ * API for interacting with ChatGPT APIs.
444
+ */
445
+ declare class ChatGPT {
446
+ /** ID */
447
+ id: string;
448
+ /** Metadata */
449
+ metadata: any;
450
+ /** Config */
451
+ config: ChatGPTConfig;
452
+ /** List of messages in the chat history */
453
+ messages: any[];
454
+ /** List of available tools */
455
+ tools: ChatGPTToolConfig[];
456
+ /** The maximum tool calls in sequence the AI can make before an error is thrown. */
457
+ maxToolCallsPerMessage: number;
458
+ private _hasRemovedToolCallHistorySinceLastMessage;
459
+ /** Statistics */
460
+ stats: {
461
+ /** Total tokens used this session */
462
+ tokensUsed: number;
463
+ };
464
+ /** Constructor */
465
+ constructor(config: ChatGPTConfig);
466
+ /** Send a message, and get the response */
467
+ sendMessage(message: string): Promise<string>;
468
+ /** @private Process messages in the chat history */
469
+ processMessages(): Promise<void>;
470
+ /** Trim message list */
471
+ trimMessages(): Promise<void>;
472
+ /** @private Send message list to the API and store the response */
473
+ sendToAPI(generatePayloadOnly?: boolean): Promise<any>;
474
+ /** Process incoming message from the AI. Can be used to respond to encoded actions in the text response. */
475
+ processIncomingMessage(message: string): void;
476
+ /** Register a tool. */
477
+ registerTool(tool: ChatGPTToolConfig): void;
478
+ /** @private Process a tool call request from the AI */
479
+ processToolCall(toolCall: any): Promise<void>;
480
+ /** Reset the conversation */
481
+ resetConversation(): void;
482
+ }
483
+
484
+ /**
485
+ * Speech output
486
+ *
487
+ * - event `speechstart` - When the speech starts
488
+ * - event `speechend` - When the speech ends
489
+ */
490
+ declare class WebWeaverSpeechOutput extends EventTarget {
491
+ /** Reference to the AI */
492
+ private ai?;
493
+ /** Constructor */
494
+ constructor(ai: IntelliWeave);
495
+ /** Called when the AI speaks */
496
+ onTextOutputFromAI(e: CustomEvent): void;
497
+ /** Current player vars */
498
+ private currentPlayerVolume?;
499
+ private currentPlayer?;
500
+ /** Speak the text */
501
+ speak(text: string): Promise<void>;
502
+ private _speakWithLock;
503
+ /** True if currently playing audio */
504
+ get isSpeaking(): boolean;
505
+ /** Interrupt the previously playing audio */
506
+ interrupt(): Promise<void>;
507
+ /** Called when the speech output ends */
508
+ onSpeechEnd(): void;
509
+ }
510
+
511
+ /**
512
+ * An AudioWorklet module that records data from input and sends it to the host.
513
+ *
514
+ * - event `data` - Fired when data is available to be read.
515
+ */
516
+ declare class PCMReceiverNode extends AudioWorkletNode {
517
+ /** @type {'int16' | 'float32'} The output data format */
518
+ format: string;
519
+ /**
520
+ * Creates a new PCMRecorderNode ready to receive PCM data.
521
+ *
522
+ * @param context - The audio context to use.
523
+ * @param sampleRate - The sample rate of the output data stream.
524
+ * @param format - The format of the output data stream.
525
+ * @param bufferSize - The size of the output buffer in elements (Int16Array or Float32Array items, depending on `format`).
526
+ */
527
+ constructor(context: AudioContext, sampleRate: number, format: 'int16' | 'int64' | 'float32', bufferSize: number);
528
+ /** @private Called when a message is received from the worklet */
529
+ onWorkletMessage(e: MessageEvent): void;
530
+ /** Called when data is received */
531
+ onData(buffer: Float32Array | Int16Array | BigInt64Array): void;
532
+ }
533
+
534
+ /**
535
+ * An AudioNode which sends events for when speech is detected
536
+ *
537
+ * - event `speechstart` - Fired when speech is detected
538
+ * - event `speechend` - Fired when speech ends
539
+ */
540
+ declare class VoiceDetectionNode extends PCMReceiverNode {
541
+ /** True if voice is currently being detected */
542
+ isVoiceActive: boolean;
543
+ /** True if voice is active but may be ending soon */
544
+ get isVoicePossiblyEnding(): boolean;
545
+ /** Last date that voice was detected */
546
+ lastVoiceActiveDate: number;
547
+ /** Amount of time to wait after voice detection to detect that it has ended */
548
+ voiceEndTimeout: number;
549
+ /** Detection sensitivity, if the detection model outputs a number bigger than this it will be considered voice */
550
+ sensitivity: number;
551
+ /** Sensitivity threshold to end speaking */
552
+ sentivityEnd: number;
553
+ /** VAD model */
554
+ static vadModelURL: string;
555
+ /** Loaded VAD model */
556
+ private vad?;
557
+ /** Sample rate */
558
+ get sampleRate(): 8000 | 16000;
559
+ /** Number of samples */
560
+ get numberOfSamples(): number;
561
+ /** Number of sample chunks */
562
+ get numberOfSampleChunks(): number;
563
+ /** Output buffer size */
564
+ get outputBufferSize(): number;
565
+ /** True if the VAD model has been loaded */
566
+ get isModelLoaded(): boolean;
567
+ /** The time when to next reset the VAD model */
568
+ nextVadReset: number;
569
+ /** The current probability of active voice */
570
+ currentProbability: number;
571
+ /** Constructor */
572
+ constructor(audioContext: AudioContext);
573
+ /** Start loading */
574
+ loadModel(): Promise<void>;
575
+ private _lastVoiceActive;
576
+ /** Called when data is received */
577
+ onData(buffer: Float32Array): Promise<void>;
578
+ /** Called when speech is detected */
579
+ onSpeechStart(): void;
580
+ /** Called when speech ends */
581
+ onSpeechEnd(): void;
582
+ }
583
+
584
+ /**
585
+ * An AudioNode which isolates speech and outputs the audio data. Since we are reusing the VAD model node,
586
+ * output data is in 8000Hz Float32 format.
587
+ *
588
+ * - event `voicedata` - Fired when a chunk of voice is detected. `data` contains the recorded chunk of voice in a Float32Array.
589
+ * - event `voicedataend` - Fired when this chunk of voice ends. `data` contains an array of Float32Array containing the entirety of the recorded voice.
590
+ */
591
+ declare class VoiceChunkOutputNode extends VoiceDetectionNode {
592
+ /** Stored buffers */
593
+ buffers: Float32Array[];
594
+ /** Recorded audio chunks with voice in it */
595
+ recordedBuffers: Float32Array[];
596
+ /** Last active state */
597
+ _voiceRecording: boolean;
598
+ /** Amount of audio data in the buffer, in seconds */
599
+ get bufferDuration(): number;
600
+ /** Amount of data to keep from before the user started speaking */
601
+ backBufferDurationSeconds: number;
602
+ /** Called when data is received */
603
+ onData(buffer: Float32Array): Promise<void>;
604
+ /** Called when a chunk of voice is recorded */
605
+ onVoiceChunk(buffer: Float32Array): void;
606
+ /** Called when the voice recording ends */
607
+ onVoiceEnd(buffers: Float32Array[]): void;
608
+ }
609
+
610
+ /**
611
+ * This AudioNode uses OpenAI's Whisper model to transcribe spoken speech to text.
612
+ *
613
+ * - event `transcription` - Fired when a transcription is ready. `text` contains the transcribed text.
614
+ */
615
+ declare class OpenAITranscriptionNode extends VoiceChunkOutputNode {
616
+ /** OpenAI API key */
617
+ apiKey: string;
618
+ /** Pending buffers */
619
+ private pendingBuffers;
620
+ /** Last request */
621
+ private lastRequestAbortController?;
622
+ /** True if currently transcribing */
623
+ isTranscribing: boolean;
624
+ /** Constructor */
625
+ constructor(audioContext: AudioContext, apiKey: string);
626
+ /** Called when the voice recording ends */
627
+ onVoiceEnd(buffers: Float32Array[]): Promise<void>;
628
+ /** Called when a transcription is ready */
629
+ onVoiceTranscription(text: string): void;
630
+ }
631
+
632
+ /**
633
+ * This AudioNode uses IntelliWeave's servers to transcribe spoken speech to text.
634
+ *
635
+ * - event `transcription` - Fired when a transcription is ready. `text` contains the transcribed text.
636
+ */
637
+ declare class IntelliWeaveTranscriptionNode extends VoiceChunkOutputNode {
638
+ /** Debug: Export each recording as a wav file for download */
639
+ static debugExportWav: boolean;
640
+ /** Server address for transcription */
641
+ apiAddress: string;
642
+ /** OpenAI API key */
643
+ apiKey: string;
644
+ /** WebSocket connection */
645
+ private ws?;
646
+ /** True if currently transcribing */
647
+ isTranscribing: boolean;
648
+ /** WebSocket shutdown timer */
649
+ private shutdownTimer?;
650
+ /** Constructor */
651
+ constructor(audioContext: AudioContext, apiKey: string);
652
+ /** Called when a voice chunk is received */
653
+ onVoiceChunk(buffer: Float32Array): Promise<void>;
654
+ /** Called when the voice recording ends */
655
+ onVoiceEnd(buffers: Float32Array[]): Promise<void>;
656
+ /** Called when a transcription is ready */
657
+ onVoiceTranscription(text: string): void;
658
+ /** Called when the WebSocket is closed */
659
+ onSocketClose(): void;
660
+ }
661
+
662
+ /**
663
+ * Handles speech recognition from the microphone
664
+ *
665
+ * - event `speechstart` - We have detected the user started speaking
666
+ * - event `speechend` - We have detected the user stopped speaking
667
+ * - event `speech` - Speech recognition result
668
+ * - event `start` - Speech recognition started
669
+ * - event `end` - Speech recognition ended
670
+ */
671
+ declare class WebWeaverSpeechRecognition extends EventTarget {
672
+ /** Reference to the AI */
673
+ ai?: IntelliWeave;
674
+ /** True if recognition is running */
675
+ isRunning: boolean;
676
+ /** The audio analyser node */
677
+ analyserNode?: AnalyserNode;
678
+ /** The audio analyser buffer */
679
+ analyserBuffer?: Float32Array;
680
+ /** The microphone stream */
681
+ micStream?: MediaStream;
682
+ /** Returns true if speech recognition is supported by this persona and browser */
683
+ get isSupported(): boolean;
684
+ /** Currently active voice detection node */
685
+ voiceDetection?: IntelliWeaveTranscriptionNode | OpenAITranscriptionNode;
686
+ /** Constructor */
687
+ constructor(ai: IntelliWeave);
688
+ private _skipEvents;
689
+ /** Start recognition */
690
+ start(): Promise<void>;
691
+ /** Stop recognition */
692
+ stop(): void;
693
+ /** @private Maximum volume heard this session */
694
+ maxVolumeHeard: number;
695
+ /** Get current (realtime) microphone volume level, from 0 to 1 */
696
+ get volumeLevel(): number;
697
+ /** True if currently detecting words being spoken */
698
+ get wordsCurrentlyBeingSpoken(): boolean;
699
+ /** True if currently transcribing voice to text */
700
+ get isTranscribing(): boolean;
701
+ /** Called when speech has been recorded */
702
+ onTranscription(e: CustomEvent): void;
703
+ /** Called to reset the speech recognizer */
704
+ reset(): Promise<void>;
705
+ }
706
+
707
+ /** Handles creating and managing the AudioContext */
708
+ declare class AudioSystem {
709
+ /** Reference to the AI */
710
+ private ai?;
711
+ /** The speech recognition module. */
712
+ speechRecognition: WebWeaverSpeechRecognition;
713
+ /** The speech output module. */
714
+ speechOutput: WebWeaverSpeechOutput;
715
+ /** The audio context */
716
+ context?: AudioContext;
717
+ /** List of active named locks */
718
+ locks: string[];
719
+ /** Returns true if speech recognition and output is supported by this persona and browser */
720
+ static get isSupported(): boolean;
721
+ /** Constructor */
722
+ constructor(ai: IntelliWeave);
723
+ /** Create a named lock to enable the audio system */
724
+ beginAccess(namedLock: string): Promise<void>;
725
+ /** Stop accessing the audio system */
726
+ endAccess(namedLock: string): void;
727
+ }
728
+
729
+ /**
730
+ * This class allows you to use the AI as a logic engine, data extractor, etc.
731
+ */
732
+ declare class AILogic {
733
+ /** Reference to the AI */
734
+ private ai?;
735
+ /** Constructor */
736
+ constructor(ai: IntelliWeave);
737
+ /** Ask the AI a yes/no question associated with the specified data. Data must be JSON-serializable, or a string of any kind of data. */
738
+ boolean(question: string, data: any): Promise<boolean>;
739
+ /**
740
+ Ask the AI to select a choice from a list of options. The AI will return the selected choice.
741
+ @param question The question to ask the AI.
742
+ @param data The data to provide to the AI. This can be a string or a JSON-serializable object.
743
+ @param options The list of options to choose from.
744
+ */
745
+ choose(question: string, data: any, options: string[]): Promise<string | undefined>;
746
+ /**
747
+ * Ask the AI to extract data from a text. The AI will return the extracted data. Possibly an array of multiple extractions.
748
+ * Example: extract(myData, true, [
749
+ * { name: "id", type: "string", description: "The user's ID number." },
750
+ * { name: "firstName", type: "string", description: "The user's first name" },
751
+ * ])
752
+ * @param question The question to ask the AI.
753
+ * @param data The data to provide to the AI. This can be a string or a JSON-serializable object.
754
+ * @param allowMultiple Whether to allow multiple extractions or not.
755
+ * @param extractions The list of extractions to perform. Each extraction is an object with the following properties:
756
+ * - name: The name of the extraction. This will be the key in the returned object.
757
+ * - type: The type of the extraction. This can be "string", "number", "boolean", "date", "email", "url", "phone", "address", "name", "organization", "person", "location", "time", "duration", "money", "percentage", "quantity", "custom".
758
+ * - description: A description of the extraction. This is optional.
759
+ */
760
+ extract(question: string, data: any, allowMultiple: boolean, extractions: {
761
+ name: string;
762
+ type: string;
763
+ description?: string;
764
+ }[]): Promise<any>;
765
+ /**
766
+ * Generate a Markdown document based on the input query from the user.
767
+ *
768
+ * @param query The query to generate the document from.
769
+ * @param callback The callback that will be called when streaming the response. Each call will contain the full text that has been generated so far.
770
+ */
771
+ generateMarkdown(query: string, callback: (txt: string) => void): Promise<string | null>;
772
+ /**
773
+ * Perform an instruction.
774
+ *
775
+ * @param instruction Describe the action to perform.
776
+ * @param query The user query to pass to the AI.
777
+ * @param callback The callback that will be called when streaming the response. Each call will contain the full text that has been generated so far.
778
+ * @returns The final response from the AI.
779
+ */
780
+ instruct(instruction: string, query: string, callback: (txt: string) => void): Promise<string | null>;
781
+ }
782
+
783
+ /** Persona config received from the hub */
784
+ interface WebWeaverGPTConfig {
785
+ /** ID */
786
+ id: string;
787
+ /** ChatGPT config */
788
+ model: ChatGPTConfig;
789
+ /** If true, message history will be sent to the IntelliWeave hub for analysis */
790
+ analytics?: boolean;
791
+ /** Persona name */
792
+ name?: string;
793
+ /** Instructions to the AI */
794
+ instructions?: string;
795
+ /** Introduction message, used in the automatic UI */
796
+ introductionMessage?: string;
797
+ /** Voice information */
798
+ voice?: {
799
+ /** Provider ID */
800
+ providerID: string;
801
+ /** API key for the provider */
802
+ apiKey: string;
803
+ /** Voice ID within the provider */
804
+ voiceID: string;
805
+ };
806
+ /** Transcription API information */
807
+ transcription?: {
808
+ /** Provider ID */
809
+ providerID: string;
810
+ /** API key for the provider */
811
+ apiKey: string;
812
+ /** Optional URL for the transcription service */
813
+ url?: string;
814
+ };
815
+ /** Knowledge base sources */
816
+ knowledge?: KnowledgeBaseSource[];
817
+ }
818
+ /**
819
+ * IntelliWeave interface, loads a Persona from the hub and allows you to interact with it. This is the main entry point into the IntelliWeave
820
+ * SDK when not using the built-in UI.
821
+ *
822
+ * - event `load` - Fired when the AI is loaded with a new configuration.
823
+ * - event `error` - Fired when an error occurs during loading.
824
+ * - event `webweaver_loaded` - Fired when the AI is loaded with a new configuration. This is a global event that is fired on the window object.
825
+ * - event `webweaver_error` - Fired when an error occurs during loading. This is a global event that is fired on the window object.
826
+ * - event `input` - Fired when the user sends a message to the AI.
827
+ * - event `output` - Fired when the AI sends a message back to the user. If `event.detail.isChunk` is true, the message is incomplete and will be followed by more chunks.
828
+ * - event `toolstart` - Fired when the AI starts performing an action.
829
+ * - event `tool` - Fired when the AI finishes performing an action.
830
+ */
831
+ declare class IntelliWeave extends EventTarget {
832
+ /** App version */
833
+ static version: string;
834
+ /** Callback when a message from the AI is returned. If isChunk is true, it may be incomplete and be called again with more updates. */
835
+ onAIMessage?: (text: string, isChunk: boolean) => void;
836
+ /** Callback when the AI starts performing an action */
837
+ onAIToolStart?: ChatGPTConfig['onAIToolStart'];
838
+ /** Current conversation ID */
839
+ conversationID: string;
840
+ /** Knowledge database interface */
841
+ knowledgeBase: KnowledgeBase;
842
+ /** Current knowledge base items */
843
+ private _lastKBentries;
844
+ /** Config loaded from the API */
845
+ config?: WebWeaverGPTConfig;
846
+ /** Available LLMs */
847
+ models: {
848
+ id: string;
849
+ config: ChatGPTConfig;
850
+ priority?: number;
851
+ }[];
852
+ /** Current LLM */
853
+ currentModel?: ChatGPT;
854
+ /** The audio system. Set this to a new instance of AudioSystem to enable audio support */
855
+ audio: AudioSystem | null;
856
+ /** Silero VAD model blob */
857
+ vadModel?: Blob;
858
+ /** True if the AI has loaded */
859
+ get loaded(): boolean;
860
+ /** If loading fails, this stores the last error during load() */
861
+ error?: Error;
862
+ /** IntelliWeave API key */
863
+ apiKey: string;
864
+ /** Tracker for the current voice interaction */
865
+ _voiceTracker?: (text: string) => void;
866
+ /** Logic engine */
867
+ logic: AILogic;
868
+ /** A unique ID to identify this user. Defaults to a value stored in localStorage, or random. */
869
+ userID: string;
870
+ /** Extra data that will be passed to external knowledge base actions. */
871
+ extra: any;
872
+ /** Set model and load data from an API key */
873
+ load(apiKey: string): Promise<WebWeaverGPTConfig>;
874
+ /** Set the current model */
875
+ setModel(id: string): void;
876
+ private _lastSystemMsg;
877
+ /** Get the system message prefix, before the KB entries are added */
878
+ getContextPrefix(): Promise<any>;
879
+ /** Get system message to send to the AI */
880
+ onBeforeMessageProcessing(): Promise<void>;
881
+ /** Called to update the current knowledge base items */
882
+ updateKnowledgeBase(items: KnowledgeBaseItem[]): void;
883
+ private _lastOutput?;
884
+ /** @private Process incoming message from the AI. Can be used to respond to encoded actions in the text response. */
885
+ processIncomingMessage(message: string, isChunk?: boolean): void;
886
+ /** True if currently processing a message */
887
+ isProcessing: boolean;
888
+ /** Send a message, and get the response */
889
+ sendMessage(message: string): Promise<string | null>;
890
+ /** @private Called when the AI wants to run a KB action */
891
+ toolRunKBAction(kb: KnowledgeBaseItem, input: any): Promise<any>;
892
+ /** Submit an analytics event asynchronously */
893
+ submitAnalyticsEvent(data: any): void;
894
+ /** Reset the conversation */
895
+ resetConversation(): void;
896
+ /** Insert a message as if the assistant has written it */
897
+ insertAssistantMessage(message: string): void;
898
+ /** Export conversation state to a JSON object */
899
+ exportState(): {
900
+ type: string;
901
+ conversationID: string;
902
+ messages: any[] | undefined;
903
+ };
904
+ /** Import conversation state from JSON */
905
+ importState(state: any): void;
906
+ /** Clone this instance */
907
+ clone(): IntelliWeave;
908
+ }
909
+
910
+ /**
911
+ * Register knowledge base sources and perform searches.
912
+ */
913
+ declare class KnowledgeBase {
914
+ /** Reference to the AI */
915
+ ai?: IntelliWeave;
916
+ /** Knowledge base sources */
917
+ _sources: KnowledgeBaseSource[];
918
+ /** List of sources returned from the last window event */
919
+ _windowSources: KnowledgeBaseSource[];
920
+ /** List of last search results */
921
+ lastResults: KnowledgeBaseItem[];
922
+ /** Individual knowledge base entries added manually by the application */
923
+ manualEntries: KnowledgeBaseItem[];
924
+ /** Constructor */
925
+ constructor(ai: IntelliWeave);
926
+ /**
927
+ * Register a new knowledge base source. You can pass either just a query function, or an ID and a query function.
928
+ *
929
+ * @param idOrQuery The ID of the source or a function that performs the query if no ID is provided
930
+ * @param query The function that performs the query. Can be undefined if the first param is a function.
931
+ */
932
+ registerSource(idOrQuery: string | KnowledgeBaseSource['query'], query?: KnowledgeBaseSource['query']): string;
933
+ /** Remove a knowledge base source */
934
+ removeSource(idOrQuery: string | KnowledgeBaseSource['query']): void;
935
+ /** Add a knowledge base item. */
936
+ addEntry(item: KnowledgeBaseItem): void;
937
+ /** Remove a knowledge base item. */
938
+ removeEntry(id: string): void;
939
+ /** Get all knowledge base sources */
940
+ get sources(): KnowledgeBaseSource[];
941
+ /** Search the knowledge base */
942
+ search(query: string): Promise<KnowledgeBaseItem[]>;
943
+ /** Get the KB entry with the specified ID. Requires the item to have been fetched in the last knowledge base query. */
944
+ getCachedEntry(id: string): KnowledgeBaseItem | undefined;
945
+ /** Create and register an external knowledge base source from a URL */
946
+ registerSourceFromURL(url: string, id?: string): void;
947
+ /** Clone this instance */
948
+ clone(): KnowledgeBase;
949
+ }
950
+ /** Knowledge base source */
951
+ interface KnowledgeBaseSource {
952
+ /** Source ID */
953
+ id?: string;
954
+ /** Source name */
955
+ name?: string;
956
+ /** Optional description */
957
+ description?: string;
958
+ /** Optional icon URL */
959
+ icon?: string;
960
+ /** If true, this source will not be queried. */
961
+ disabled?: boolean;
962
+ /** Source query function. This function should return a list of knowledge base entries that optionally match the query. */
963
+ query?: (query: string) => (KnowledgeBaseItem[] | Promise<KnowledgeBaseItem[]>);
964
+ /** URL query for remote sources */
965
+ url?: string;
966
+ }
967
+ /** Knowledge base item */
968
+ interface KnowledgeBaseItem {
969
+ /** Item ID */
970
+ id?: string;
971
+ /** Item type. */
972
+ type: 'info' | 'action' | 'tour' | 'input-event' | 'output-event';
973
+ /** Item name */
974
+ name: string;
975
+ /** Item tags. Helps with search optimization. */
976
+ tags?: string;
977
+ /** Item content. Can be a function to return a dynamic string. */
978
+ content: string | (() => string);
979
+ /** If true, this item will always be returned from all search results. */
980
+ isContext?: boolean;
981
+ /** If true, this item will not be visible to the AI. */
982
+ disabled?: boolean;
983
+ /** List of parameters for an action function. */
984
+ parameters?: ({
985
+ name: string;
986
+ type: 'string' | 'boolean' | 'number';
987
+ description: string;
988
+ })[];
989
+ /**
990
+ * Item action. The parameters are defined in `parameters`. The response is stringified and sent to the AI.
991
+ * You can return any JSON-serializable object. You can also return a string describing to the AI the action
992
+ * that was performed. If an error is thrown, the AI will respond appropriately to the user.
993
+ */
994
+ action?: (input: any, ai: IntelliWeave) => (any | Promise<any>);
995
+ /** If true, this item will be removed from the AI's message history after it gets called. This is a special case for LLMs that struggle with follow-up function calls and need to use the KB search functino first. */
996
+ removeFromMessageHistory?: boolean;
997
+ }
998
+ /** Format for incoming KB webook. Sent from IntelliWeave to your endpoint. */
999
+ interface KnowledgeBaseWebhookRequest {
1000
+ /** Type of the request. */
1001
+ type: 'search' | 'action';
1002
+ /** Extra data given in the app */
1003
+ extra?: any;
1004
+ /** User ID of the calling user */
1005
+ userID: string;
1006
+ /** When type=search, this is the search query */
1007
+ query?: string;
1008
+ /** When type=action, this is the action ID */
1009
+ actionID?: string;
1010
+ /** When type=action, this is the action parameters */
1011
+ parameters?: any;
1012
+ }
1013
+ /** Format for the response to the webhook when type=search */
1014
+ interface KnowledgeBaseWebhookSearchResponse {
1015
+ /** Name for your KB database */
1016
+ name: string;
1017
+ /** Description of your KB database */
1018
+ description?: string;
1019
+ /** Optional icon URL */
1020
+ icon?: string;
1021
+ /** URL to display to open more information about your database */
1022
+ infoURL?: string;
1023
+ /** Items */
1024
+ items: KnowledgeBaseItem[];
1025
+ }
1026
+ /** Format for the response to the webhook when type=action */
1027
+ interface KnowledgeBaseWebhookActionResponse {
1028
+ /** The response to the AI. Can be a text instruction, an error message, a JSON object, anything. */
1029
+ response: any;
1030
+ /** An optional list of knowledge base items to update locally. */
1031
+ updateItems?: KnowledgeBaseItem[];
1032
+ }
1033
+
1034
+ /** Class to help with logging */
1035
+ declare class Logging {
1036
+ /** Current module */
1037
+ module: string;
1038
+ /** Constructor */
1039
+ constructor(moduleName: string);
1040
+ /** Enable debug logging */
1041
+ static debug: boolean;
1042
+ /** Check if verbose logging is enabled */
1043
+ get debugEnabled(): any;
1044
+ /** Log a message */
1045
+ log(...args: any[]): void;
1046
+ /** Debug message */
1047
+ debug(...args: any[]): void;
1048
+ /** Info message message */
1049
+ info(...args: any[]): void;
1050
+ /** Warning message */
1051
+ warn(...args: any[]): void;
1052
+ /** Error message */
1053
+ error(...args: any[]): void;
1054
+ /** Create a timer task, returns a function to log events in this timer */
1055
+ timer(name: string, ...args: any[]): (...args: any[]) => void;
1056
+ }
1057
+
1058
+ /**
1059
+ * Handles a stream of input/output events with the specified AI model.
1060
+ *
1061
+ * @event event - Fired when an event is emitted, either by the AI or wrapper code etc.
1062
+ */
1063
+ declare class IntelliWeaveStream extends IntelliWeave {
1064
+ /** Events that haven't been sent to the AI yet */
1065
+ pendingEvents: IntelliWeaveStreamEvent[];
1066
+ /** Get the system message prefix, before the KB entries are added */
1067
+ getContextPrefix(): Promise<string>;
1068
+ /** Get actions to be added to the context */
1069
+ /** Post an event to the AI */
1070
+ postEvent(event: Partial<IntelliWeaveStreamEvent>): void;
1071
+ /** @private Called when the AI wants to run a KB action */
1072
+ toolRunKBAction(kb: KnowledgeBaseItem, input: any): Promise<any>;
1073
+ /** Output an event to the event listener(s) */
1074
+ private emitEvent;
1075
+ private _isProcessingEvents;
1076
+ /** Process events */
1077
+ private processEvents;
1078
+ }
1079
+ /** Any event */
1080
+ interface IntelliWeaveStreamEvent {
1081
+ /** Event name */
1082
+ eventName: string;
1083
+ /** Event date, unix timestamp, number of milliseconds since Jan 1 1970 */
1084
+ timestamp: number;
1085
+ /** Human-readable event date */
1086
+ timestampDate: string;
1087
+ /** Direction of this event. Input events go into the AI for processing, output events come out of the AI system. */
1088
+ direction: 'input' | 'output';
1089
+ /** Assistant hint, added automatically if there's a KB entry with the same ID. */
1090
+ assistantHint?: string;
1091
+ /** Any extra data */
1092
+ [key: string]: any;
1093
+ }
1094
+ /** Error event schema */
1095
+ interface IntelliWeaveStreamErrorEvent extends IntelliWeaveStreamEvent {
1096
+ /** Event name */
1097
+ eventName: "error";
1098
+ /** Error details */
1099
+ errorMessage: string;
1100
+ }
1101
+ /** AI speaking event */
1102
+ interface IntelliWeaveStreamTextOutputEvent extends IntelliWeaveStreamEvent {
1103
+ /** Event name */
1104
+ eventName: "text";
1105
+ /** The text spoken */
1106
+ text: string;
1107
+ }
1108
+
1109
+ export { type BufferType, BufferedWebSocket, ChatGPT, type ChatGPTConfig, type ChatGPTToolConfig, FixedBufferStream, IntelliWeave, IntelliWeaveStream, type IntelliWeaveStreamErrorEvent, type IntelliWeaveStreamEvent, type IntelliWeaveStreamTextOutputEvent, KnowledgeBase, type KnowledgeBaseItem, type KnowledgeBaseSource, type KnowledgeBaseWebhookActionResponse, type KnowledgeBaseWebhookRequest, type KnowledgeBaseWebhookSearchResponse, Logging, ONNXModel, type ONNXTensors, Resampler, type WebWeaverGPTConfig, audioToWav, floatTo16BitPCM, floatTo64BitPCM, getDefaultUserID, int16ToFloat32BitPCM, intelliweaveConfig, intelliweaveGlobalThis, sseEvents, trimWhitespaceInText };