mirror of
https://github.com/Bijit-Mondal/VoiceAgent.git
synced 2026-03-02 10:36:37 +00:00
- Added ConversationManager for managing conversation history with configurable limits. - Implemented InputQueue for serial processing of input items. - Created SpeechManager for handling text-to-speech generation and streaming. - Developed StreamProcessor for processing LLM streams and forwarding events. - Added TranscriptionManager for audio transcription using AI SDK. - Introduced WebSocketManager for managing WebSocket connections and messaging. - Updated VoiceAgent to support new architecture and improved socket handling. - Refactored index files to export new core components.
72 lines
1.7 KiB
TypeScript
72 lines
1.7 KiB
TypeScript
/**
|
|
* A generic serial input queue that ensures only one processor runs at a time.
|
|
*
|
|
* @template T The shape of each queued item (must include resolve/reject)
|
|
*/
|
|
export interface QueueItem<T = string> {
|
|
resolve: (v: T) => void;
|
|
reject: (e: unknown) => void;
|
|
}
|
|
|
|
export class InputQueue<T extends QueueItem<any>> {
|
|
private queue: T[] = [];
|
|
private processing = false;
|
|
|
|
/** Callback invoked for each item — must return a resolved value */
|
|
public processor: (item: T) => Promise<any> = async () => "";
|
|
|
|
/**
|
|
* Enqueue an item for serial processing.
|
|
*/
|
|
enqueue(item: T): void {
|
|
this.queue.push(item);
|
|
this.drain();
|
|
}
|
|
|
|
/**
|
|
* Reject all pending items (used on disconnect/destroy).
|
|
*/
|
|
rejectAll(reason: Error): void {
|
|
for (const item of this.queue) {
|
|
item.reject(reason);
|
|
}
|
|
this.queue = [];
|
|
this.processing = false;
|
|
}
|
|
|
|
/**
|
|
* Number of items waiting in the queue.
|
|
*/
|
|
get length(): number {
|
|
return this.queue.length;
|
|
}
|
|
|
|
/**
|
|
* Whether the queue is currently processing an item.
|
|
*/
|
|
get isProcessing(): boolean {
|
|
return this.processing;
|
|
}
|
|
|
|
// ── Private ──────────────────────────────────────────
|
|
|
|
private async drain(): Promise<void> {
|
|
if (this.processing) return;
|
|
this.processing = true;
|
|
|
|
try {
|
|
while (this.queue.length > 0) {
|
|
const item = this.queue.shift()!;
|
|
try {
|
|
const result = await this.processor(item);
|
|
item.resolve(result);
|
|
} catch (error) {
|
|
item.reject(error);
|
|
}
|
|
}
|
|
} finally {
|
|
this.processing = false;
|
|
}
|
|
}
|
|
}
|