vocal-stack 1.0.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/LICENSE +21 -0
- package/README.md +269 -0
- package/dist/flow/index.cjs +571 -0
- package/dist/flow/index.cjs.map +1 -0
- package/dist/flow/index.d.cts +337 -0
- package/dist/flow/index.d.ts +337 -0
- package/dist/flow/index.js +559 -0
- package/dist/flow/index.js.map +1 -0
- package/dist/index.cjs +1026 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +32 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +1003 -0
- package/dist/index.js.map +1 -0
- package/dist/monitor/index.cjs +291 -0
- package/dist/monitor/index.cjs.map +1 -0
- package/dist/monitor/index.d.cts +122 -0
- package/dist/monitor/index.d.ts +122 -0
- package/dist/monitor/index.js +286 -0
- package/dist/monitor/index.js.map +1 -0
- package/dist/sanitizer/index.cjs +190 -0
- package/dist/sanitizer/index.cjs.map +1 -0
- package/dist/sanitizer/index.d.cts +83 -0
- package/dist/sanitizer/index.d.ts +83 -0
- package/dist/sanitizer/index.js +186 -0
- package/dist/sanitizer/index.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/sanitizer/rules/code-blocks.ts","../src/sanitizer/rules/markdown.ts","../src/sanitizer/rules/punctuation.ts","../src/sanitizer/rules/urls.ts","../src/sanitizer/rules/index.ts","../src/sanitizer/sanitizer.ts","../src/monitor/exporters/csv.ts","../src/monitor/exporters/json.ts","../src/monitor/metrics-collector.ts","../src/monitor/voice-auditor.ts","../src/flow/buffer-manager.ts","../src/flow/constants.ts","../src/flow/filler-injector.ts","../src/flow/stall-detector.ts","../src/flow/types.ts","../src/flow/state-machine.ts","../src/flow/flow-controller.ts","../src/flow/flow-manager.ts"],"names":["ConversationState"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Base error class for all vocal-stack errors\n */\nexport class VocalStackError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly context?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'VocalStackError';\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\n/**\n * Error thrown during text sanitization\n */\nexport class SanitizerError extends VocalStackError {\n constructor(message: string, context?: Record<string, unknown>) {\n super(message, 'SANITIZER_ERROR', context);\n this.name = 'SanitizerError';\n }\n}\n\n/**\n * Error thrown during flow control operations\n */\nexport class FlowControlError extends VocalStackError {\n constructor(message: string, context?: Record<string, unknown>) {\n super(message, 'FLOW_CONTROL_ERROR', context);\n this.name = 'FlowControlError';\n }\n}\n\n/**\n * Error thrown during monitoring operations\n */\nexport class MonitorError extends VocalStackError {\n constructor(message: string, context?: Record<string, unknown>) {\n super(message, 'MONITOR_ERROR', context);\n this.name = 'MonitorError';\n }\n}\n","import type { SanitizerConfig } from '../types';\n\n/**\n * Remove code blocks and inline code to make text speakable\n */\nexport function codeBlocksRule(text: string, _config: Required<SanitizerConfig>): string {\n let result = text;\n\n // Remove fenced code blocks (```code```)\n // Match both with and without language specifier\n result = result.replace(/```[\\s\\S]*?```/g, '');\n\n // Remove indented code blocks (4 spaces or 1 tab at line start)\n result = result.replace(/^(?: {4}|\\t).+$/gm, '');\n\n // Note: Inline code (`code`) is handled by markdown rule\n\n return result;\n}\n","import type { SanitizerConfig } from '../types';\n\n/**\n * Strip markdown syntax to make text speakable\n */\nexport function markdownRule(text: string, _config: Required<SanitizerConfig>): string {\n let result = text;\n\n // Remove headers (##, ###, etc.)\n result = result.replace(/^#{1,6}\\s+/gm, '');\n\n // Remove bold/italic (**text**, *text*, __text__, _text_)\n result = result.replace(/(\\*\\*|__)(.*?)\\1/g, '$2');\n result = result.replace(/(\\*|_)(.*?)\\1/g, '$2');\n\n // Remove inline code (`code`)\n result = result.replace(/`([^`]+)`/g, '$1');\n\n // Remove links but keep text [text](url) -> text\n result = result.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n\n // Remove images  -> alt or empty\n result = result.replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, '$1');\n\n // Remove blockquotes (>)\n result = result.replace(/^>\\s+/gm, '');\n\n // Remove horizontal rules (---, ***, ___)\n result = result.replace(/^[\\-*_]{3,}$/gm, '');\n\n // Remove list markers (-, *, 1., etc.)\n result = result.replace(/^[\\s]*[-*+]\\s+/gm, '');\n result = result.replace(/^[\\s]*\\d+\\.\\s+/gm, '');\n\n // Remove strikethrough (~~text~~)\n result = result.replace(/~~(.*?)~~/g, '$1');\n\n // Remove task list markers (- [ ], - [x])\n result = result.replace(/^[\\s]*-\\s+\\[[ xX]\\]\\s+/gm, '');\n\n return result;\n}\n","import type { SanitizerConfig } from '../types';\n\n/**\n * Normalize punctuation for better TTS handling\n */\nexport function punctuationRule(text: string, _config: Required<SanitizerConfig>): string {\n let result = text;\n\n // Replace multiple exclamation marks with single\n result = result.replace(/!{2,}/g, '!');\n\n // Replace multiple question marks with single\n result = result.replace(/\\?{2,}/g, '?');\n\n // Replace ellipsis variations with single space or period\n result = result.replace(/\\.{3,}/g, '.');\n\n // Remove multiple dashes/hyphens\n result = result.replace(/-{2,}/g, ' ');\n\n // Replace em dash and en dash with space\n result = result.replace(/[—–]/g, ' ');\n\n // Remove parentheses and brackets but keep content\n result = result.replace(/[()[\\]{}]/g, '');\n\n // Replace multiple commas with single\n result = result.replace(/,{2,}/g, ',');\n\n // Remove semicolons and colons (can be disruptive in speech)\n result = result.replace(/[;:]/g, ',');\n\n // Remove quotation marks\n result = result.replace(/[\"'\"'`]/g, '');\n\n // Remove asterisks and underscores (from markdown remnants)\n result = result.replace(/[*_]/g, '');\n\n // Remove forward slashes and backslashes\n result = result.replace(/[/\\\\]/g, ' ');\n\n // Remove pipes and ampersands\n result = result.replace(/[|&]/g, ' ');\n\n // Remove @ # $ % symbols\n result = result.replace(/[@#$%]/g, '');\n\n return result;\n}\n","import type { SanitizerConfig } from '../types';\n\n/**\n * Remove or replace URLs to make text speakable\n */\nexport function urlsRule(text: string, _config: Required<SanitizerConfig>): string {\n let result = text;\n\n // Match URLs with protocol (http://, https://, ftp://, etc.)\n const urlWithProtocol = /\\b(https?:\\/\\/|ftp:\\/\\/|www\\.)[^\\s<>\"{}|\\\\^`[\\]]+/gi;\n\n // Match email addresses\n const emailPattern = /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b/g;\n\n // Remove URLs with protocol\n result = result.replace(urlWithProtocol, '');\n\n // Remove email addresses\n result = result.replace(emailPattern, '');\n\n // Remove standalone domain-like patterns (example.com)\n result = result.replace(/\\b[a-z0-9-]+\\.[a-z]{2,}\\b/gi, '');\n\n return result;\n}\n","import type { RuleFunction } from '../types';\nimport { codeBlocksRule } from './code-blocks';\nimport { markdownRule } from './markdown';\nimport { punctuationRule } from './punctuation';\nimport { urlsRule } from './urls';\n\n/**\n * Registry of built-in sanitization rules\n */\nexport const ruleRegistry = new Map<string, RuleFunction>([\n ['markdown', markdownRule],\n ['urls', urlsRule],\n ['code-blocks', codeBlocksRule],\n ['punctuation', punctuationRule],\n]);\n","import { SanitizerError } from '../errors';\nimport { ruleRegistry } from './rules';\nimport type { SanitizationResult, SanitizerConfig, SanitizerPlugin } from './types';\n\n/**\n * Speech sanitizer that transforms text for TTS optimization\n */\nexport class SpeechSanitizer {\n private readonly config: Required<SanitizerConfig>;\n private readonly plugins: readonly SanitizerPlugin[];\n\n constructor(config: SanitizerConfig = {}) {\n this.config = {\n rules: config.rules ?? ['markdown', 'urls', 'code-blocks', 'punctuation'],\n plugins: config.plugins ?? [],\n preserveLineBreaks: config.preserveLineBreaks ?? false,\n customReplacements: config.customReplacements ?? new Map(),\n };\n this.plugins = [...this.config.plugins].sort((a, b) => a.priority - b.priority);\n }\n\n /**\n * Sanitize a string synchronously\n */\n sanitize(text: string): string {\n if (!text || text.trim().length === 0) {\n return '';\n }\n\n let result = text;\n\n try {\n // Apply built-in rules\n for (const rule of this.config.rules) {\n const ruleFunction = ruleRegistry.get(rule);\n if (ruleFunction) {\n result = ruleFunction(result, this.config);\n }\n }\n\n // Apply plugins (sync only in this version)\n for (const plugin of this.plugins) {\n const transformed = plugin.transform(result);\n if (transformed instanceof Promise) {\n throw new SanitizerError(\n `Plugin ${plugin.name} returned a Promise in sync sanitize(). Use sanitizeAsync() instead.`\n );\n }\n result = transformed;\n }\n\n // Apply custom replacements\n for (const [pattern, replacement] of this.config.customReplacements) {\n if (typeof pattern === 'string') {\n result = result.replaceAll(pattern, replacement);\n } else {\n result = result.replace(pattern, replacement);\n }\n }\n\n // Clean up whitespace\n if (this.config.preserveLineBreaks) {\n // Collapse multiple spaces on same line but keep line breaks\n result = result.replace(/ +/g, ' ').replace(/^\\s+|\\s+$/gm, '');\n } else {\n // Collapse all whitespace including line breaks\n result = result.replace(/\\s+/g, ' ').trim();\n }\n\n return result;\n } catch (error) {\n if (error instanceof SanitizerError) {\n throw error;\n }\n throw new SanitizerError('Failed to sanitize text', {\n originalText: text.substring(0, 100),\n error,\n });\n }\n }\n\n /**\n * Sanitize with detailed result metadata\n */\n sanitizeWithMetadata(text: string): SanitizationResult {\n const original = text;\n const sanitized = this.sanitize(text);\n\n return {\n original,\n sanitized,\n appliedRules: this.config.rules as string[],\n metadata: {\n removedCount: original.length - sanitized.length,\n transformedCount: this.config.rules.length + this.plugins.length,\n },\n };\n }\n\n /**\n * Sanitize a stream of text chunks (AsyncIterable)\n */\n async *sanitizeStream(input: AsyncIterable<string>): AsyncIterable<string> {\n let buffer = '';\n const sentenceBoundary = /[.!?]\\s+/;\n\n for await (const chunk of input) {\n buffer += chunk;\n\n // Process complete sentences\n const sentences = buffer.split(sentenceBoundary);\n buffer = sentences.pop() ?? ''; // Keep incomplete sentence\n\n for (const sentence of sentences) {\n if (sentence.trim()) {\n yield `${this.sanitize(sentence)} `;\n }\n }\n }\n\n // Process remaining buffer\n if (buffer.trim()) {\n yield this.sanitize(buffer);\n }\n }\n}\n\n/**\n * Convenience function for one-off sanitization\n */\nexport function sanitizeForSpeech(text: string, config?: SanitizerConfig): string {\n const sanitizer = new SpeechSanitizer(config);\n return sanitizer.sanitize(text);\n}\n","import type { VoiceMetric } from '../types';\n\n/**\n * Export metrics to CSV format\n */\nexport function exportToCsv(metrics: readonly VoiceMetric[]): string {\n const headers = [\n 'id',\n 'timestamp',\n 'completed',\n 'timeToFirstToken',\n 'totalDuration',\n 'tokenCount',\n 'averageTokenLatency',\n 'tags',\n ];\n\n const rows = metrics.map((m) => [\n m.id,\n m.timestamp.toString(),\n m.completed.toString(),\n m.metrics.timeToFirstToken?.toString() ?? '',\n m.metrics.totalDuration?.toString() ?? '',\n m.metrics.tokenCount.toString(),\n m.metrics.averageTokenLatency?.toString() ?? '',\n JSON.stringify(m.tags),\n ]);\n\n const csvLines = [\n headers.join(','),\n ...rows.map((row) =>\n row\n .map((cell) => {\n // Escape commas and quotes in cell values\n if (cell.includes(',') || cell.includes('\"') || cell.includes('\\n')) {\n return `\"${cell.replace(/\"/g, '\"\"')}\"`;\n }\n return cell;\n })\n .join(',')\n ),\n ];\n\n return csvLines.join('\\n');\n}\n","import type { VoiceMetric } from '../types';\n\n/**\n * Export metrics to JSON format\n */\nexport function exportToJson(metrics: readonly VoiceMetric[]): string {\n return JSON.stringify(\n {\n exportedAt: new Date().toISOString(),\n count: metrics.length,\n metrics: metrics.map((m) => ({\n id: m.id,\n timestamp: m.timestamp,\n completed: m.completed,\n timeToFirstToken: m.metrics.timeToFirstToken,\n totalDuration: m.metrics.totalDuration,\n tokenCount: m.metrics.tokenCount,\n averageTokenLatency: m.metrics.averageTokenLatency,\n tags: m.tags,\n })),\n },\n null,\n 2\n );\n}\n","import type { MetricsSummary, VoiceMetric } from './types';\n\n/**\n * Collects and aggregates metrics\n */\nexport class MetricsCollector {\n private metrics: VoiceMetric[] = [];\n\n addMetric(metric: VoiceMetric): void {\n this.metrics.push(metric);\n }\n\n getMetrics(): readonly VoiceMetric[] {\n return [...this.metrics];\n }\n\n getSummary(): MetricsSummary {\n if (this.metrics.length === 0) {\n return {\n count: 0,\n avgTimeToFirstToken: 0,\n avgTotalDuration: 0,\n p50TimeToFirstToken: 0,\n p95TimeToFirstToken: 0,\n p99TimeToFirstToken: 0,\n minTimeToFirstToken: 0,\n maxTimeToFirstToken: 0,\n };\n }\n\n const ttfts = this.metrics\n .map((m) => m.metrics.timeToFirstToken)\n .filter((t): t is number => t !== null)\n .sort((a, b) => a - b);\n\n const durations = this.metrics\n .map((m) => m.metrics.totalDuration)\n .filter((d): d is number => d !== null);\n\n const percentile = (arr: number[], p: number): number => {\n if (arr.length === 0) return 0;\n const index = Math.ceil(arr.length * p) - 1;\n return arr[index] ?? 0;\n };\n\n return {\n count: this.metrics.length,\n avgTimeToFirstToken: ttfts.reduce((a, b) => a + b, 0) / ttfts.length || 0,\n avgTotalDuration: durations.reduce((a, b) => a + b, 0) / durations.length || 0,\n p50TimeToFirstToken: percentile(ttfts, 0.5),\n p95TimeToFirstToken: percentile(ttfts, 0.95),\n p99TimeToFirstToken: percentile(ttfts, 0.99),\n minTimeToFirstToken: ttfts.length > 0 ? Math.min(...ttfts) : 0,\n maxTimeToFirstToken: ttfts.length > 0 ? Math.max(...ttfts) : 0,\n };\n }\n\n clear(): void {\n this.metrics = [];\n }\n}\n","import { MonitorError } from '../errors';\nimport { exportToCsv, exportToJson } from './exporters';\nimport { MetricsCollector } from './metrics-collector';\nimport type { AuditorConfig, ExportFormat, MetricsSummary, VoiceMetric } from './types';\n\n/**\n * Voice latency auditor and profiler\n */\nexport class VoiceAuditor {\n private readonly config: Required<AuditorConfig>;\n private readonly collector: MetricsCollector;\n private activeMetrics = new Map<string, VoiceMetric>();\n\n constructor(config: AuditorConfig = {}) {\n this.config = {\n enableRealtime: config.enableRealtime ?? false,\n onMetric: config.onMetric ?? (() => {}),\n tags: config.tags ?? {},\n };\n this.collector = new MetricsCollector();\n }\n\n /**\n * Start tracking a new voice interaction\n */\n startTracking(id: string, tags?: Record<string, string>): VoiceMetric {\n if (this.activeMetrics.has(id)) {\n throw new MonitorError(`Metric with id ${id} is already being tracked`);\n }\n\n const metric: VoiceMetric = {\n id,\n timestamp: Date.now(),\n startTime: Date.now(),\n firstTokenReceivedTime: null,\n lastTokenReceivedTime: null,\n completed: false,\n metrics: {\n timeToFirstToken: null,\n totalDuration: null,\n tokenCount: 0,\n averageTokenLatency: null,\n },\n tags: { ...this.config.tags, ...tags },\n };\n\n this.activeMetrics.set(id, metric);\n return metric;\n }\n\n /**\n * Record first token received\n */\n recordFirstToken(id: string): void {\n const metric = this.activeMetrics.get(id);\n if (!metric) {\n throw new MonitorError(`No active metric found for id ${id}`);\n }\n\n if (metric.firstTokenReceivedTime === null) {\n const updated: VoiceMetric = {\n ...metric,\n firstTokenReceivedTime: Date.now(),\n metrics: {\n ...metric.metrics,\n timeToFirstToken: Date.now() - metric.startTime,\n tokenCount: 1,\n },\n };\n this.activeMetrics.set(id, updated);\n\n if (this.config.enableRealtime) {\n this.config.onMetric(updated);\n }\n }\n }\n\n /**\n * Record token received\n */\n recordToken(id: string): void {\n const metric = this.activeMetrics.get(id);\n if (!metric) {\n throw new MonitorError(`No active metric found for id ${id}`);\n }\n\n const updated: VoiceMetric = {\n ...metric,\n lastTokenReceivedTime: Date.now(),\n metrics: {\n ...metric.metrics,\n tokenCount: metric.metrics.tokenCount + 1,\n },\n };\n this.activeMetrics.set(id, updated);\n }\n\n /**\n * Complete tracking for a voice interaction\n */\n completeTracking(id: string): VoiceMetric {\n const metric = this.activeMetrics.get(id);\n if (!metric) {\n throw new MonitorError(`No active metric found for id ${id}`);\n }\n\n const lastTime = metric.lastTokenReceivedTime ?? Date.now();\n const totalDuration = lastTime - metric.startTime;\n const avgLatency =\n metric.metrics.tokenCount > 0 ? totalDuration / metric.metrics.tokenCount : null;\n\n const completed: VoiceMetric = {\n ...metric,\n completed: true,\n metrics: {\n ...metric.metrics,\n totalDuration,\n averageTokenLatency: avgLatency,\n },\n };\n\n this.activeMetrics.delete(id);\n this.collector.addMetric(completed);\n\n if (this.config.enableRealtime) {\n this.config.onMetric(completed);\n }\n\n return completed;\n }\n\n /**\n * Wrap an async iterable with automatic tracking\n */\n async *track(\n id: string,\n input: AsyncIterable<string>,\n tags?: Record<string, string>\n ): AsyncIterable<string> {\n this.startTracking(id, tags);\n\n let firstToken = true;\n try {\n for await (const chunk of input) {\n if (firstToken) {\n this.recordFirstToken(id);\n firstToken = false;\n } else {\n this.recordToken(id);\n }\n yield chunk;\n }\n } finally {\n this.completeTracking(id);\n }\n }\n\n /**\n * Get all collected metrics\n */\n getMetrics(): readonly VoiceMetric[] {\n return this.collector.getMetrics();\n }\n\n /**\n * Get summary statistics\n */\n getSummary(): MetricsSummary {\n return this.collector.getSummary();\n }\n\n /**\n * Export metrics in specified format\n */\n export(format: ExportFormat): string {\n const metrics = this.collector.getMetrics();\n\n switch (format) {\n case 'json':\n return exportToJson(metrics);\n case 'csv':\n return exportToCsv(metrics);\n default:\n throw new MonitorError(`Unsupported export format: ${format}`);\n }\n }\n\n /**\n * Clear all collected metrics\n */\n clear(): void {\n this.activeMetrics.clear();\n this.collector.clear();\n }\n}\n","/**\n * Buffer manager for barge-in scenarios\n */\nexport class BufferManager {\n private buffer: string[] = [];\n private readonly maxSize: number;\n private head = 0;\n private size = 0;\n\n constructor(maxSize = 10) {\n if (maxSize <= 0) {\n throw new Error('Buffer size must be positive');\n }\n this.maxSize = maxSize;\n }\n\n /**\n * Add chunk to buffer\n */\n add(chunk: string): void {\n if (this.size < this.maxSize) {\n this.buffer.push(chunk);\n this.size++;\n } else {\n // Circular buffer - overwrite oldest\n this.buffer[this.head] = chunk;\n this.head = (this.head + 1) % this.maxSize;\n }\n }\n\n /**\n * Get all buffered chunks in order\n */\n getAll(): readonly string[] {\n if (this.size < this.maxSize) {\n return [...this.buffer];\n }\n\n // Return in order: from head to end, then from start to head\n return [...this.buffer.slice(this.head), ...this.buffer.slice(0, this.head)];\n }\n\n /**\n * Clear all buffered chunks\n */\n clear(): void {\n this.buffer = [];\n this.head = 0;\n this.size = 0;\n }\n\n /**\n * Get current buffer size\n */\n getSize(): number {\n return this.size;\n }\n\n /**\n * Check if buffer is empty\n */\n isEmpty(): boolean {\n return this.size === 0;\n }\n\n /**\n * Check if buffer is full\n */\n isFull(): boolean {\n return this.size === this.maxSize;\n }\n}\n","/**\n * Default stall threshold in milliseconds\n * Based on human perception of silence: 500-1000ms feels like a pause\n * Most LLM APIs stream chunks every 50-200ms when active\n */\nexport const DEFAULT_STALL_THRESHOLD_MS = 700;\n\n/**\n * Default filler phrases to inject during stalls\n */\nexport const DEFAULT_FILLER_PHRASES = ['um', 'let me think', 'hmm'];\n\n/**\n * Default maximum fillers per response\n * Prevents over-use of filler words\n */\nexport const DEFAULT_MAX_FILLERS_PER_RESPONSE = 3;\n","/**\n * Manages filler phrase injection\n */\nexport class FillerInjector {\n private readonly phrases: readonly string[];\n private readonly maxFillers: number;\n private fillersUsed = 0;\n private lastFillerIndex = -1;\n\n constructor(phrases: readonly string[], maxFillers: number) {\n this.phrases = phrases;\n this.maxFillers = maxFillers;\n }\n\n /**\n * Get next filler phrase (returns null if limit reached)\n */\n getFiller(): string | null {\n if (this.fillersUsed >= this.maxFillers) {\n return null;\n }\n\n // Rotate through phrases to avoid repetition\n this.lastFillerIndex = (this.lastFillerIndex + 1) % this.phrases.length;\n this.fillersUsed++;\n\n return this.phrases[this.lastFillerIndex] ?? null;\n }\n\n /**\n * Reset filler state\n */\n reset(): void {\n this.fillersUsed = 0;\n this.lastFillerIndex = -1;\n }\n\n /**\n * Check if more fillers can be injected\n */\n canInjectMore(): boolean {\n return this.fillersUsed < this.maxFillers;\n }\n\n /**\n * Get count of fillers used\n */\n getUsedCount(): number {\n return this.fillersUsed;\n }\n}\n","/**\n * Detects stream stalls based on timing\n */\nexport class StallDetector {\n private lastChunkTime: number | null = null;\n private stallTimer: NodeJS.Timeout | null = null;\n private readonly thresholdMs: number;\n private readonly onStall: (durationMs: number) => void;\n\n constructor(thresholdMs: number, onStall: (durationMs: number) => void) {\n this.thresholdMs = thresholdMs;\n this.onStall = onStall;\n }\n\n /**\n * Notify detector that a chunk was received\n */\n notifyChunk(): void {\n this.lastChunkTime = Date.now();\n this.clearTimer();\n this.scheduleStallCheck();\n }\n\n /**\n * Start monitoring for stalls\n */\n start(): void {\n this.lastChunkTime = Date.now();\n this.scheduleStallCheck();\n }\n\n /**\n * Stop monitoring\n */\n stop(): void {\n this.clearTimer();\n this.lastChunkTime = null;\n }\n\n private scheduleStallCheck(): void {\n this.clearTimer();\n this.stallTimer = setTimeout(() => {\n if (this.lastChunkTime !== null) {\n const elapsed = Date.now() - this.lastChunkTime;\n if (elapsed >= this.thresholdMs) {\n this.onStall(elapsed);\n // Continue checking for additional stalls\n this.scheduleStallCheck();\n }\n }\n }, this.thresholdMs);\n }\n\n private clearTimer(): void {\n if (this.stallTimer) {\n clearTimeout(this.stallTimer);\n this.stallTimer = null;\n }\n }\n}\n","/**\n * Configuration for flow control\n */\nexport interface FlowConfig {\n /**\n * Stall threshold in milliseconds\n * @default 700\n */\n readonly stallThresholdMs?: number;\n\n /**\n * Filler phrases to inject\n * @default ['um', 'let me think', 'hmm']\n */\n readonly fillerPhrases?: readonly string[];\n\n /**\n * Whether to enable filler injection\n * @default true\n */\n readonly enableFillers?: boolean;\n\n /**\n * Maximum number of fillers to inject per response\n * @default 3\n */\n readonly maxFillersPerResponse?: number;\n\n /**\n * Callback when filler is injected\n */\n readonly onFillerInjected?: (filler: string) => void;\n\n /**\n * Callback when stall is detected\n */\n readonly onStallDetected?: (durationMs: number) => void;\n\n /**\n * Callback when first chunk is emitted\n */\n readonly onFirstChunk?: () => void;\n}\n\n/**\n * Conversation states\n */\nexport enum ConversationState {\n IDLE = 'idle',\n WAITING = 'waiting',\n SPEAKING = 'speaking',\n INTERRUPTED = 'interrupted',\n}\n\n/**\n * Statistics tracked by flow controller\n */\nexport interface FlowStats {\n readonly fillersInjected: number;\n readonly stallsDetected: number;\n readonly chunksProcessed: number;\n readonly firstChunkTime: number | null;\n readonly totalDurationMs: number;\n}\n\n/**\n * Flow events for low-level API\n */\nexport type FlowEvent =\n | {\n type: 'stall-detected';\n durationMs: number;\n }\n | {\n type: 'filler-injected';\n filler: string;\n }\n | {\n type: 'first-chunk';\n chunk: string;\n }\n | {\n type: 'state-change';\n from: ConversationState;\n to: ConversationState;\n }\n | {\n type: 'interrupted';\n }\n | {\n type: 'chunk-processed';\n chunk: string;\n }\n | {\n type: 'completed';\n stats: FlowStats;\n };\n\n/**\n * Event listener for flow events\n */\nexport type FlowEventListener = (event: FlowEvent) => void;\n\n/**\n * Configuration for low-level FlowManager\n */\nexport interface FlowManagerConfig {\n /**\n * Stall threshold in milliseconds\n * @default 700\n */\n readonly stallThresholdMs?: number;\n\n /**\n * Filler phrases to inject\n * @default ['um', 'let me think', 'hmm']\n */\n readonly fillerPhrases?: readonly string[];\n\n /**\n * Whether to enable filler injection\n * @default true\n */\n readonly enableFillers?: boolean;\n\n /**\n * Maximum number of fillers to inject per response\n * @default 3\n */\n readonly maxFillersPerResponse?: number;\n\n /**\n * Buffer size for barge-in scenarios\n * @default 10\n */\n readonly bufferSize?: number;\n}\n","import { FlowControlError } from '../errors';\nimport { ConversationState } from './types';\n\n/**\n * Valid state transitions\n * IDLE → SPEAKING/WAITING\n * WAITING → SPEAKING/IDLE/INTERRUPTED\n * SPEAKING → INTERRUPTED/IDLE\n * INTERRUPTED → IDLE/WAITING\n */\nconst VALID_TRANSITIONS: ReadonlyMap<ConversationState, readonly ConversationState[]> = new Map([\n [ConversationState.IDLE, [ConversationState.SPEAKING, ConversationState.WAITING]],\n [\n ConversationState.WAITING,\n [ConversationState.SPEAKING, ConversationState.IDLE, ConversationState.INTERRUPTED],\n ],\n [ConversationState.SPEAKING, [ConversationState.INTERRUPTED, ConversationState.IDLE]],\n [ConversationState.INTERRUPTED, [ConversationState.IDLE, ConversationState.WAITING]],\n]);\n\n/**\n * Conversation state machine\n */\nexport class ConversationStateMachine {\n private currentState: ConversationState = ConversationState.IDLE;\n private readonly listeners: Set<(from: ConversationState, to: ConversationState) => void> =\n new Set();\n\n /**\n * Get current state\n */\n getState(): ConversationState {\n return this.currentState;\n }\n\n /**\n * Attempt to transition to new state\n */\n transition(to: ConversationState): boolean {\n const validTransitions = VALID_TRANSITIONS.get(this.currentState);\n\n if (!validTransitions?.includes(to)) {\n throw new FlowControlError(`Invalid state transition: ${this.currentState} -> ${to}`, {\n from: this.currentState,\n to,\n });\n }\n\n const from = this.currentState;\n this.currentState = to;\n\n // Notify listeners\n for (const listener of this.listeners) {\n listener(from, to);\n }\n\n return true;\n }\n\n /**\n * Add state change listener\n */\n onStateChange(listener: (from: ConversationState, to: ConversationState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Reset to IDLE\n */\n reset(): void {\n this.currentState = ConversationState.IDLE;\n }\n}\n","import { FlowControlError } from '../errors';\nimport { BufferManager } from './buffer-manager';\nimport {\n DEFAULT_FILLER_PHRASES,\n DEFAULT_MAX_FILLERS_PER_RESPONSE,\n DEFAULT_STALL_THRESHOLD_MS,\n} from './constants';\nimport { FillerInjector } from './filler-injector';\nimport { StallDetector } from './stall-detector';\nimport { ConversationStateMachine } from './state-machine';\nimport { ConversationState, type FlowConfig, type FlowStats } from './types';\n\n/**\n * High-level stream wrapper for flow control\n */\nexport class FlowController {\n private readonly config: Required<FlowConfig>;\n private readonly stateMachine: ConversationStateMachine;\n private readonly stallDetector: StallDetector;\n private readonly fillerInjector: FillerInjector;\n private readonly bufferManager: BufferManager;\n private firstChunkEmitted = false;\n private stats: {\n fillersInjected: number;\n stallsDetected: number;\n chunksProcessed: number;\n firstChunkTime: number | null;\n totalDurationMs: number;\n } = {\n fillersInjected: 0,\n stallsDetected: 0,\n chunksProcessed: 0,\n firstChunkTime: null,\n totalDurationMs: 0,\n };\n private startTime: number | null = null;\n\n constructor(config: FlowConfig = {}) {\n this.config = {\n stallThresholdMs: config.stallThresholdMs ?? DEFAULT_STALL_THRESHOLD_MS,\n fillerPhrases: config.fillerPhrases ?? DEFAULT_FILLER_PHRASES,\n enableFillers: config.enableFillers ?? true,\n maxFillersPerResponse: config.maxFillersPerResponse ?? DEFAULT_MAX_FILLERS_PER_RESPONSE,\n onFillerInjected: config.onFillerInjected ?? (() => {}),\n onStallDetected: config.onStallDetected ?? (() => {}),\n onFirstChunk: config.onFirstChunk ?? (() => {}),\n };\n\n this.stateMachine = new ConversationStateMachine();\n this.fillerInjector = new FillerInjector(\n this.config.fillerPhrases,\n this.config.maxFillersPerResponse\n );\n this.bufferManager = new BufferManager(10); // Default buffer size of 10\n\n this.stallDetector = new StallDetector(\n this.config.stallThresholdMs,\n this.handleStall.bind(this)\n );\n }\n\n /**\n * Wrap an async iterable with flow control\n */\n async *wrap(input: AsyncIterable<string>): AsyncIterable<string> {\n this.reset();\n this.startTime = Date.now();\n this.stateMachine.transition(ConversationState.WAITING);\n this.stallDetector.start();\n\n try {\n for await (const chunk of input) {\n // Check if interrupted\n if (this.stateMachine.getState() === ConversationState.INTERRUPTED) {\n break;\n }\n\n this.stallDetector.notifyChunk();\n this.stats.chunksProcessed++;\n\n // Add to buffer before yielding\n this.bufferManager.add(chunk);\n\n // Handle first chunk\n if (!this.firstChunkEmitted) {\n this.firstChunkEmitted = true;\n this.stats.firstChunkTime = Date.now() - (this.startTime ?? Date.now());\n this.stateMachine.transition(ConversationState.SPEAKING);\n this.config.onFirstChunk();\n }\n\n yield chunk;\n }\n\n // Only transition to IDLE if not interrupted\n if (this.stateMachine.getState() !== ConversationState.INTERRUPTED) {\n this.stateMachine.transition(ConversationState.IDLE);\n }\n } catch (error) {\n throw new FlowControlError('Flow control error during stream processing', { error });\n } finally {\n this.stallDetector.stop();\n this.stats.totalDurationMs = Date.now() - (this.startTime ?? Date.now());\n }\n }\n\n /**\n * Interrupt the current flow (for barge-in)\n */\n interrupt(): void {\n const currentState = this.stateMachine.getState();\n if (currentState === ConversationState.SPEAKING || currentState === ConversationState.WAITING) {\n this.stateMachine.transition(ConversationState.INTERRUPTED);\n this.stallDetector.stop();\n this.fillerInjector.reset(); // Cancel any pending fillers\n this.bufferManager.clear(); // Clear buffered chunks\n }\n }\n\n /**\n * Get current conversation state\n */\n getState(): ConversationState {\n return this.stateMachine.getState();\n }\n\n /**\n * Get flow statistics\n */\n getStats(): FlowStats {\n return { ...this.stats };\n }\n\n /**\n * Get buffered chunks (for advanced barge-in scenarios)\n */\n getBufferedChunks(): readonly string[] {\n return this.bufferManager.getAll();\n }\n\n private handleStall(durationMs: number): void {\n // Only inject fillers if:\n // 1. Fillers are enabled\n // 2. First chunk hasn't been emitted yet\n // 3. Not interrupted\n if (\n this.config.enableFillers &&\n !this.firstChunkEmitted &&\n this.stateMachine.getState() !== ConversationState.INTERRUPTED\n ) {\n const filler = this.fillerInjector.getFiller();\n if (filler) {\n this.stats.fillersInjected++;\n this.config.onFillerInjected(filler);\n }\n }\n\n this.stats.stallsDetected++;\n this.config.onStallDetected(durationMs);\n }\n\n private reset(): void {\n this.firstChunkEmitted = false;\n this.fillerInjector.reset();\n this.bufferManager.clear();\n this.stats = {\n fillersInjected: 0,\n stallsDetected: 0,\n chunksProcessed: 0,\n firstChunkTime: null,\n totalDurationMs: 0,\n };\n }\n}\n\n/**\n * Convenience function to create and use flow controller\n */\nexport function withFlowControl(\n input: AsyncIterable<string>,\n config?: FlowConfig\n): AsyncIterable<string> {\n const controller = new FlowController(config);\n return controller.wrap(input);\n}\n","import { FlowControlError } from '../errors';\nimport { BufferManager } from './buffer-manager';\nimport {\n DEFAULT_FILLER_PHRASES,\n DEFAULT_MAX_FILLERS_PER_RESPONSE,\n DEFAULT_STALL_THRESHOLD_MS,\n} from './constants';\nimport { FillerInjector } from './filler-injector';\nimport { StallDetector } from './stall-detector';\nimport { ConversationStateMachine } from './state-machine';\nimport {\n ConversationState,\n type FlowEvent,\n type FlowEventListener,\n type FlowManagerConfig,\n type FlowStats,\n} from './types';\n\n/**\n * Low-level event-based flow manager\n */\nexport class FlowManager {\n private readonly config: Required<FlowManagerConfig>;\n private readonly stateMachine: ConversationStateMachine;\n private readonly stallDetector: StallDetector;\n private readonly fillerInjector: FillerInjector;\n private readonly bufferManager: BufferManager;\n private readonly listeners: Set<FlowEventListener> = new Set();\n private firstChunkEmitted = false;\n private stats: {\n fillersInjected: number;\n stallsDetected: number;\n chunksProcessed: number;\n firstChunkTime: number | null;\n totalDurationMs: number;\n } = {\n fillersInjected: 0,\n stallsDetected: 0,\n chunksProcessed: 0,\n firstChunkTime: null,\n totalDurationMs: 0,\n };\n private startTime: number | null = null;\n private stateChangeUnsubscribe: (() => void) | null = null;\n\n constructor(config: FlowManagerConfig = {}) {\n this.config = {\n stallThresholdMs: config.stallThresholdMs ?? DEFAULT_STALL_THRESHOLD_MS,\n fillerPhrases: config.fillerPhrases ?? DEFAULT_FILLER_PHRASES,\n enableFillers: config.enableFillers ?? true,\n maxFillersPerResponse: config.maxFillersPerResponse ?? DEFAULT_MAX_FILLERS_PER_RESPONSE,\n bufferSize: config.bufferSize ?? 10,\n };\n\n this.stateMachine = new ConversationStateMachine();\n this.fillerInjector = new FillerInjector(\n this.config.fillerPhrases,\n this.config.maxFillersPerResponse\n );\n this.bufferManager = new BufferManager(this.config.bufferSize);\n this.stallDetector = new StallDetector(\n this.config.stallThresholdMs,\n this.handleStall.bind(this)\n );\n }\n\n /**\n * Add event listener\n */\n on(listener: FlowEventListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Start flow tracking\n */\n start(): void {\n if (this.startTime !== null) {\n throw new FlowControlError('FlowManager already started');\n }\n\n this.reset();\n this.startTime = Date.now();\n this.stateMachine.transition(ConversationState.WAITING);\n this.stallDetector.start();\n\n // Listen to state changes\n this.stateChangeUnsubscribe = this.stateMachine.onStateChange((from, to) => {\n this.emit({\n type: 'state-change',\n from,\n to,\n });\n });\n }\n\n /**\n * Process a chunk from the stream\n */\n processChunk(chunk: string): void {\n if (this.startTime === null) {\n throw new FlowControlError('FlowManager not started. Call start() first.');\n }\n\n // Check if interrupted\n if (this.stateMachine.getState() === ConversationState.INTERRUPTED) {\n return;\n }\n\n this.stallDetector.notifyChunk();\n this.stats.chunksProcessed++;\n\n // Add to buffer\n this.bufferManager.add(chunk);\n\n // Handle first chunk\n if (!this.firstChunkEmitted) {\n this.firstChunkEmitted = true;\n this.stats.firstChunkTime = Date.now() - this.startTime;\n this.stateMachine.transition(ConversationState.SPEAKING);\n this.emit({\n type: 'first-chunk',\n chunk,\n });\n }\n\n this.emit({\n type: 'chunk-processed',\n chunk,\n });\n }\n\n /**\n * Complete the flow\n */\n complete(): void {\n if (this.startTime === null) {\n throw new FlowControlError('FlowManager not started');\n }\n\n this.stallDetector.stop();\n this.stats.totalDurationMs = Date.now() - this.startTime;\n\n // Only transition to IDLE if not interrupted\n if (this.stateMachine.getState() !== ConversationState.INTERRUPTED) {\n this.stateMachine.transition(ConversationState.IDLE);\n }\n\n this.emit({\n type: 'completed',\n stats: this.getStats(),\n });\n\n // Cleanup\n if (this.stateChangeUnsubscribe) {\n this.stateChangeUnsubscribe();\n this.stateChangeUnsubscribe = null;\n }\n\n this.startTime = null;\n }\n\n /**\n * Interrupt the flow (for barge-in)\n */\n interrupt(): void {\n const currentState = this.stateMachine.getState();\n if (currentState === ConversationState.SPEAKING || currentState === ConversationState.WAITING) {\n this.stateMachine.transition(ConversationState.INTERRUPTED);\n this.stallDetector.stop();\n this.fillerInjector.reset();\n this.bufferManager.clear();\n\n this.emit({\n type: 'interrupted',\n });\n }\n }\n\n /**\n * Get current conversation state\n */\n getState(): ConversationState {\n return this.stateMachine.getState();\n }\n\n /**\n * Get flow statistics\n */\n getStats(): FlowStats {\n return { ...this.stats };\n }\n\n /**\n * Get buffered chunks\n */\n getBufferedChunks(): readonly string[] {\n return this.bufferManager.getAll();\n }\n\n private handleStall(durationMs: number): void {\n this.stats.stallsDetected++;\n\n this.emit({\n type: 'stall-detected',\n durationMs,\n });\n\n // Only inject fillers if:\n // 1. Fillers are enabled\n // 2. First chunk hasn't been emitted yet\n // 3. Not interrupted\n if (\n this.config.enableFillers &&\n !this.firstChunkEmitted &&\n this.stateMachine.getState() !== ConversationState.INTERRUPTED\n ) {\n const filler = this.fillerInjector.getFiller();\n if (filler) {\n this.stats.fillersInjected++;\n this.emit({\n type: 'filler-injected',\n filler,\n });\n }\n }\n }\n\n private emit(event: FlowEvent): void {\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch (error) {\n // Don't let listener errors break the flow\n console.error('Error in FlowManager event listener:', error);\n }\n }\n }\n\n private reset(): void {\n this.firstChunkEmitted = false;\n this.fillerInjector.reset();\n this.bufferManager.clear();\n this.stats = {\n fillersInjected: 0,\n stallsDetected: 0,\n chunksProcessed: 0,\n firstChunkTime: null,\n totalDurationMs: 0,\n };\n }\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export { RuleFunction, SanitizationResult, SanitizerConfig, SanitizerPlugin, SanitizerRule, SpeechSanitizer, ruleRegistry, sanitizeForSpeech } from './sanitizer/index.cjs';
|
|
2
|
+
export { AuditorConfig, ExportFormat, MetricsCollector, MetricsSummary, VoiceAuditor, VoiceMetric, exportToCsv, exportToJson } from './monitor/index.cjs';
|
|
3
|
+
export { BufferManager, ConversationState, ConversationStateMachine, DEFAULT_FILLER_PHRASES, DEFAULT_MAX_FILLERS_PER_RESPONSE, DEFAULT_STALL_THRESHOLD_MS, FillerInjector, FlowConfig, FlowController, FlowEvent, FlowEventListener, FlowManager, FlowManagerConfig, FlowStats, StallDetector, withFlowControl } from './flow/index.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Base error class for all vocal-stack errors
|
|
7
|
+
*/
|
|
8
|
+
declare class VocalStackError extends Error {
|
|
9
|
+
readonly code: string;
|
|
10
|
+
readonly context?: Record<string, unknown> | undefined;
|
|
11
|
+
constructor(message: string, code: string, context?: Record<string, unknown> | undefined);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Error thrown during text sanitization
|
|
15
|
+
*/
|
|
16
|
+
declare class SanitizerError extends VocalStackError {
|
|
17
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error thrown during flow control operations
|
|
21
|
+
*/
|
|
22
|
+
declare class FlowControlError extends VocalStackError {
|
|
23
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Error thrown during monitoring operations
|
|
27
|
+
*/
|
|
28
|
+
declare class MonitorError extends VocalStackError {
|
|
29
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { FlowControlError, MonitorError, SanitizerError, VocalStackError };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export { RuleFunction, SanitizationResult, SanitizerConfig, SanitizerPlugin, SanitizerRule, SpeechSanitizer, ruleRegistry, sanitizeForSpeech } from './sanitizer/index.js';
|
|
2
|
+
export { AuditorConfig, ExportFormat, MetricsCollector, MetricsSummary, VoiceAuditor, VoiceMetric, exportToCsv, exportToJson } from './monitor/index.js';
|
|
3
|
+
export { BufferManager, ConversationState, ConversationStateMachine, DEFAULT_FILLER_PHRASES, DEFAULT_MAX_FILLERS_PER_RESPONSE, DEFAULT_STALL_THRESHOLD_MS, FillerInjector, FlowConfig, FlowController, FlowEvent, FlowEventListener, FlowManager, FlowManagerConfig, FlowStats, StallDetector, withFlowControl } from './flow/index.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Base error class for all vocal-stack errors
|
|
7
|
+
*/
|
|
8
|
+
declare class VocalStackError extends Error {
|
|
9
|
+
readonly code: string;
|
|
10
|
+
readonly context?: Record<string, unknown> | undefined;
|
|
11
|
+
constructor(message: string, code: string, context?: Record<string, unknown> | undefined);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Error thrown during text sanitization
|
|
15
|
+
*/
|
|
16
|
+
declare class SanitizerError extends VocalStackError {
|
|
17
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error thrown during flow control operations
|
|
21
|
+
*/
|
|
22
|
+
declare class FlowControlError extends VocalStackError {
|
|
23
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Error thrown during monitoring operations
|
|
27
|
+
*/
|
|
28
|
+
declare class MonitorError extends VocalStackError {
|
|
29
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { FlowControlError, MonitorError, SanitizerError, VocalStackError };
|