@m4trix/core 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react/hooks/use-conversation/useConversation.ts","../src/utility/Logger.ts","../src/react/adapter/VoiceEndpointAdapter.ts","../src/react/utility/audio/InputAudioController.ts","../src/react/utility/audio/WebAudioInputAudioController.ts","../src/react/utility/audio/OutputAudioController.ts","../src/react/utility/audio/AudioElementOutputAudioController.ts","../src/react/hooks/use-conversation/useSocketConversation.ts","../src/react/adapter/socket/VoiceSocketAdapter.ts","../src/react/adapter/socket/VoiceSocketIOAdapter.ts","../src/react/utility/audio/WebAudioOutputAudioController.ts","../src/ui/ai-cursor/rendering/AiCursorComponent.ts","../src/ui/ai-cursor/rendering/AiCursorComponent.style.ts","../src/ui/ai-cursor/rendering/index.ts","../src/ui/ai-cursor/AiCursor.ts","../src/stream/Pump.ts","../src/stream/utility/pipe-transformers/response.ts","../src/stream/utility/rechunker/ensure-full-words.ts","../src/api/socket-handler/SocketIoFactory.ts","../src/helper/transform-messages/TransformMessages.ts","../src/helper/transform-messages/message-filter.ts","../src/helper/transform-messages/formatter.ts","../src/matrix/agent-network/agent-network.ts","../src/matrix/identifiers/channel-name.ts","../src/matrix/agent-network/channel.ts","../src/matrix/agent-network/event-plane.ts","../src/helper/types/noop.ts","../src/matrix/agent-network/stores/inmemory-network-store.ts","../src/matrix/io/expose.ts","../src/matrix/agent-network/agent-network-event.ts","../src/matrix/agent.ts","../src/matrix/agent-factory.ts","../src/matrix/io/protocols/sse.ts","../src/matrix/io/adapters/next-endpoint.ts","../src/matrix/io/adapters/express-endpoint.ts"],"names":["state","useState","useRef","useEffect","useCallback","out","window","AIMessage","i","msg","Effect","Queue","payload"],"mappings":"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","sourcesContent":["'use client';\n\nimport { useState, useRef, useEffect, useCallback } from 'react';\nimport {\n VoiceEndpointAdapter,\n BaseVoiceEndpointAdapter,\n} from '../../adapter/VoiceEndpointAdapter';\nimport { Logger } from '../../../utility/Logger';\nimport { WebAudioInputAudioController } from '../../utility/audio/WebAudioInputAudioController';\nimport { OutputAudioController } from '../../utility/audio/OutputAudioController';\nimport type {\n BaseUseConversationOptions,\n DownstreamMode,\n VoiceAgentState,\n} from './shared-types';\nimport { AudioElementOutputAudioController } from '../../utility/audio/AudioElementOutputAudioController';\nimport { InputAudioController } from '../../utility/audio/InputAudioController';\n\n// Types\nexport type EndpointConversationOptions<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = BaseUseConversationOptions & {\n downstreamMode?: DownstreamMode;\n endpointConfig?: {\n baseUrl?: string;\n endpointAdapter?: VoiceEndpointAdapter;\n headers?: Record<string, string>;\n };\n requestData?: T;\n overrideInputAudioController?: InputAudioController;\n};\n\nexport interface UseEndpointConversationResult {\n startRecording: () => void;\n stopRecording: () => void;\n enableHandsFreeRecording?: () => void;\n voiceAgentState: VoiceAgentState;\n error: Error | null;\n audioContext: AudioContext | null;\n}\n\nLogger.enableGlobalLogging();\n\n/**\n * A hook for managing voice conversations in React applications using HTTP endpoints and Web Audio API\n */\nexport function useConversation<T extends Record<string, unknown>>(\n endpoint: string,\n {\n onStartRecording,\n onStopRecording,\n onReceive,\n autoPlay = true,\n downstreamMode = 'STREAM',\n onError,\n audioConfig = {},\n requestData = {} as T,\n endpointConfig = {},\n }: EndpointConversationOptions<T>\n): UseEndpointConversationResult {\n // Refs\n const { current: logger } = useRef<Logger>(\n new Logger('@m4trix/core > useConversation')\n );\n const inputAudioControllerRef = useRef<\n WebAudioInputAudioController | undefined\n >(undefined);\n const outputAudioControllerRef = useRef<OutputAudioController | undefined>(\n undefined\n );\n\n const endpointAdapterRef = useRef<VoiceEndpointAdapter | undefined>(\n undefined\n );\n\n // State\n const [voiceAgentState, setVoiceAgentState] =\n useState<VoiceAgentState>('READY');\n const [error, setError] = useState<Error | null>(null);\n\n // ================================================\n // =============== Callbacks ======================\n // ================================================\n\n const handleError = useCallback(\n (state: VoiceAgentState, err: Error) => {\n setError(err);\n logger.error(`Error during ${state}:`, err);\n onError?.(state, err);\n },\n [onError]\n );\n\n const startRecording = useCallback(() => {\n if (inputAudioControllerRef.current) {\n try {\n logger.debug('Starting recording');\n setVoiceAgentState('RECORDING');\n inputAudioControllerRef.current.startRecording({\n onError: (err) => {\n handleError('RECORDING', err);\n },\n });\n onStartRecording?.();\n } catch (err) {\n if (err instanceof Error) {\n handleError('RECORDING', err);\n }\n }\n }\n }, [onStartRecording, handleError]);\n\n const stopRecording = useCallback(async () => {\n if (inputAudioControllerRef.current) {\n try {\n logger.debug('Stopping recording');\n await inputAudioControllerRef.current.stopRecording({\n onRecordingCompleted: async (allData) => {\n setVoiceAgentState('PROCESSING');\n try {\n // Send the recording to the endpoint\n const response = await endpointAdapterRef.current?.sendVoiceFile({\n blob: allData,\n metadata: requestData,\n });\n\n if (!response) {\n throw new Error('No response received from endpoint');\n }\n\n setVoiceAgentState('RESPONDING');\n\n // Play the response\n if (autoPlay) {\n if (downstreamMode === 'STREAM') {\n await outputAudioControllerRef.current?.playAudioStream({\n response,\n onComplete: () => {\n setVoiceAgentState('READY');\n },\n });\n } else if (downstreamMode === 'DOWNLOAD') {\n const responseBlob = await response.blob();\n await outputAudioControllerRef.current?.playAudio({\n source: responseBlob,\n onComplete: () => {\n setVoiceAgentState('READY');\n },\n });\n }\n } else {\n setVoiceAgentState('READY');\n }\n\n // Call onReceive with the recording and response\n onReceive?.(\n allData,\n async () => {\n // Play response function\n if (outputAudioControllerRef.current) {\n if (downstreamMode === 'STREAM') {\n return outputAudioControllerRef.current.playAudioStream({\n response,\n onComplete: () => {\n setVoiceAgentState('READY');\n },\n });\n } else {\n const responseBlob = await response.blob();\n return outputAudioControllerRef.current.playAudio({\n source: responseBlob,\n onComplete: () => {\n setVoiceAgentState('READY');\n },\n });\n }\n }\n },\n async () => {\n // Stop response function\n if (outputAudioControllerRef.current) {\n return outputAudioControllerRef.current.stopPlayback();\n }\n }\n );\n } catch (err) {\n if (err instanceof Error) {\n handleError('PROCESSING', err);\n }\n setVoiceAgentState('READY');\n }\n },\n });\n onStopRecording?.();\n } catch (err) {\n if (err instanceof Error) {\n handleError('RECORDING', err);\n }\n }\n }\n }, [\n onStopRecording,\n requestData,\n autoPlay,\n downstreamMode,\n handleError,\n onReceive,\n ]);\n\n // Setup endpoint adapter and audio controllers\n useEffect(() => {\n if (endpointAdapterRef.current) {\n return;\n }\n\n try {\n // Set up endpoint adapter\n const endpointAdapter = endpointConfig.endpointAdapter\n ? endpointConfig.endpointAdapter\n : new BaseVoiceEndpointAdapter({\n baseUrl: endpointConfig.baseUrl,\n endpoint: endpoint,\n headers: endpointConfig.headers,\n });\n\n endpointAdapterRef.current = endpointAdapter;\n\n // Set up audio controllers\n if (!inputAudioControllerRef.current) {\n inputAudioControllerRef.current = new WebAudioInputAudioController(\n audioConfig\n );\n }\n\n if (!outputAudioControllerRef.current) {\n outputAudioControllerRef.current =\n new AudioElementOutputAudioController();\n }\n } catch (err) {\n if (err instanceof Error) {\n handleError('READY', err);\n }\n }\n }, [endpoint, endpointConfig, audioConfig, handleError]);\n\n // On Mount and on unmount, cleanup the audio controller\n useEffect(() => {\n return () => {\n inputAudioControllerRef.current?.cleanup();\n outputAudioControllerRef.current?.cleanup();\n };\n }, []);\n\n // Return the public API\n return {\n startRecording,\n stopRecording,\n voiceAgentState,\n error,\n audioContext: inputAudioControllerRef.current?.audioContext || null,\n };\n}\n","type LogLevel = 'log' | 'debug' | 'info' | 'warn' | 'error';\n\nexport class Logger {\n private static globalEnabled = false;\n\n constructor(private namespace: string = '') {}\n\n static enableGlobalLogging(): void {\n Logger.globalEnabled = true;\n }\n\n static disableGlobalLogging(): void {\n Logger.globalEnabled = false;\n }\n\n private formatPrefix(): string {\n return this.namespace ? `[${this.namespace}]` : '';\n }\n\n private logIfEnabled(level: LogLevel, ...args: unknown[]): void {\n if (!Logger.globalEnabled) return;\n\n const prefix = this.formatPrefix();\n if (prefix) {\n console[level](prefix, ...args);\n } else {\n console[level](...args);\n }\n }\n\n log(...args: unknown[]): void {\n this.logIfEnabled('log', ...args);\n }\n\n debug(...args: unknown[]): void {\n this.logIfEnabled('debug', ...args);\n }\n\n info(...args: unknown[]): void {\n this.logIfEnabled('info', ...args);\n }\n\n warn(...args: unknown[]): void {\n this.logIfEnabled('warn', ...args);\n }\n\n error(...args: unknown[]): void {\n this.logIfEnabled('error', ...args);\n }\n}\n","import { Logger } from '../../utility/Logger';\n\nexport interface VoiceEndpointConfig {\n baseUrl?: string;\n endpoint: string;\n headers?: Record<string, string>;\n}\n\nexport interface SendVoiceFileParams {\n blob: Blob;\n metadata?: Record<string, unknown>;\n onChunk?: (chunk: Uint8Array) => void;\n onComplete?: (response: Blob) => void;\n}\n\n/**\n * Adapter for sending voice files to an API endpoint\n */\nexport abstract class VoiceEndpointAdapter {\n protected config: VoiceEndpointConfig;\n protected logger = new Logger('SuTr > EndpointAdapter');\n\n constructor(config: VoiceEndpointConfig) {\n this.config = config;\n }\n\n /**\n * Send a voice file to the API endpoint and return a Pump stream of audio chunks\n */\n abstract sendVoiceFile(params: SendVoiceFileParams): Promise<Response>;\n}\n\n/**\n * Adapter for sending voice files to an API endpoint\n */\nexport class BaseVoiceEndpointAdapter extends VoiceEndpointAdapter {\n constructor(config: VoiceEndpointConfig) {\n super(config);\n }\n\n /**\n * Send a voice file to the API endpoint and return a Pump stream of audio chunks\n */\n async sendVoiceFile({\n blob,\n metadata,\n }: SendVoiceFileParams): Promise<Response> {\n const formData = new FormData();\n formData.append('audio', blob);\n if (metadata) {\n formData.append('metadata', JSON.stringify(metadata));\n }\n this.logger.debug('Sending voice file to', this.config.endpoint, formData);\n const response = await fetch(\n `${this.config.baseUrl || ''}${this.config.endpoint}`,\n {\n method: 'POST',\n headers: this.config.headers,\n body: formData,\n }\n );\n if (!response.ok) {\n throw new Error(`API error: ${response.status} ${await response.text()}`);\n }\n if (!response.body) {\n throw new Error('No response body');\n }\n // Return a Pump stream of Uint8Array chunks\n return response;\n }\n}\n","import { Logger } from '../../../utility/Logger';\n\n/**\n * Represents the current state of the voice agent in the conversation flow.\n */\nexport type VoiceAgentState =\n | 'READY'\n | 'RECORDING'\n | 'UPSTREAMING'\n | 'PROCESSING'\n | 'DOWNSTREAMING'\n | 'RESPONDING';\n\n/**\n * Represents the state of the Web Audio API context and nodes.\n */\nexport type AudioContextState = {\n context: AudioContext | null;\n source: MediaStreamAudioSourceNode | null;\n analyser: AnalyserNode | null;\n};\n\n/**\n * Configuration options for audio processing.\n */\nexport type AudioProcessingConfig = {\n sampleRate: number;\n channelCount: number;\n};\n\nexport type StartRecordingCallbacks = {\n onRecordedChunk?: (chunk: Blob) => Promise<void> | void;\n onError?: (error: Error) => Promise<void> | void;\n};\n\nexport type StopRecordingCallbacks = {\n onRecordingCompleted?: (allData: Blob) => Promise<void> | void;\n onError?: (error: Error) => Promise<void> | void;\n};\n\n/**\n * Controller for managing audio input operations.\n * Handles recording from microphone.\n */\nexport abstract class InputAudioController {\n protected logger = new Logger('@m4trix/core > InputAudioController');\n\n constructor() {}\n\n public abstract startRecording({\n onRecordedChunk,\n onError,\n }: StartRecordingCallbacks): Promise<void>;\n\n public abstract stopRecording({\n onRecordingCompleted,\n }: StopRecordingCallbacks): Promise<void>;\n\n /**\n * Cleans up all audio recording resources.\n */\n public abstract cleanup(): void;\n}\n","import {\n AudioProcessingConfig,\n InputAudioController,\n} from './InputAudioController';\nimport { AudioContextState } from './InputAudioController';\n\n/**\n * Represents the current state of the voice agent in the conversation flow.\n */\nexport type VoiceAgentState =\n | 'READY'\n | 'RECORDING'\n | 'UPSTREAMING'\n | 'PROCESSING'\n | 'DOWNSTREAMING'\n | 'RESPONDING';\n\nexport type StartRecordingCallbacks = {\n onRecordedChunk?: (chunk: Blob) => Promise<void> | void;\n onError?: (error: Error) => Promise<void> | void;\n};\n\nexport type StopRecordingCallbacks = {\n onRecordingCompleted?: (allData: Blob) => Promise<void> | void;\n onError?: (error: Error) => Promise<void> | void;\n};\n\nconst DEFAULT_SLICING_INTERVAL = 3_000; // 3 seconds\n\n/**\n * Controller for managing audio input operations.\n * Handles recording from microphone.\n */\nexport class WebAudioInputAudioController extends InputAudioController {\n // ─── Recording state ─────────────────────────────────────────────────────\n private audioContextState: AudioContextState = {\n context: null,\n source: null,\n analyser: null,\n };\n private mediaRecorder: MediaRecorder | null = null;\n private recordedChunks: Blob[] = [];\n private recordingStream: MediaStream | null = null;\n\n constructor(private audioConfig: Partial<AudioProcessingConfig> = {}) {\n super();\n }\n\n public get audioContext(): AudioContext | null {\n return this.audioContextState.context;\n }\n\n private async createAudioContext(): Promise<AudioContextState> {\n const context = new AudioContext({\n sampleRate: this.audioConfig.sampleRate || 16_000,\n latencyHint: 'interactive',\n });\n const analyser = context.createAnalyser();\n analyser.fftSize = 2048;\n return { context, source: null, analyser };\n }\n\n private async cleanupAudioContext(): Promise<void> {\n this.logger.debug('Cleaning up audio context');\n const { source, context } = this.audioContextState;\n if (source) source.disconnect();\n if (context) await context.close();\n this.audioContextState = { context: null, source: null, analyser: null };\n }\n\n public async startRecording({\n onRecordedChunk,\n onError,\n }: StartRecordingCallbacks = {}): Promise<void> {\n try {\n this.logger.debug('Starting recording');\n this.recordedChunks = [];\n\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n this.recordingStream = stream;\n\n if (!this.audioContextState.context) {\n this.audioContextState = await this.createAudioContext();\n }\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: 'audio/webm;codecs=opus',\n });\n\n this.mediaRecorder.ondataavailable = (e: BlobEvent): void => {\n if (e.data.size > 0) {\n this.recordedChunks.push(e.data);\n onRecordedChunk?.(e.data);\n this.logger.debug('Recorded chunk', e.data.size);\n }\n };\n\n this.mediaRecorder.start(DEFAULT_SLICING_INTERVAL);\n this.logger.debug('MediaRecorder started');\n } catch (err) {\n const error =\n err instanceof Error ? err : new Error('Failed to start recording');\n this.logger.error(error);\n onError?.(error);\n }\n }\n\n public async stopRecording({\n onRecordingCompleted,\n }: StopRecordingCallbacks = {}): Promise<void> {\n this.logger.debug('Stopping recording');\n if (!this.mediaRecorder || this.mediaRecorder.state === 'inactive') return;\n\n await new Promise<void>((resolve) => {\n this.mediaRecorder!.onstop = async (): Promise<void> => {\n if (this.recordedChunks.length) {\n const blob = new Blob(this.recordedChunks, { type: 'audio/webm' });\n onRecordingCompleted?.(blob);\n this.logger.debug('Recording completed', blob.size);\n }\n this.recordingStream?.getTracks().forEach((t) => t.stop());\n this.recordingStream = null;\n await this.cleanupAudioContext();\n resolve();\n };\n this.mediaRecorder!.stop();\n });\n }\n\n /**\n * Cleans up all audio recording resources.\n */\n public cleanup(): void {\n this.cleanupAudioContext();\n if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {\n this.mediaRecorder.stop();\n }\n if (this.recordingStream) {\n this.recordingStream.getTracks().forEach((t) => t.stop());\n this.recordingStream = null;\n }\n }\n}\n","import { Logger } from '../../../utility/Logger';\n\n/**\n * Represents the current state of the voice agent in the conversation flow.\n */\nexport type VoiceAgentState =\n | 'READY'\n | 'RECORDING'\n | 'UPSTREAMING'\n | 'PROCESSING'\n | 'DOWNSTREAMING'\n | 'RESPONDING';\n\nexport type PlayAudioStreamParams = {\n response: Response;\n mimeCodec?: string;\n onComplete?: () => void;\n};\n\nexport type PlayAudioParams = {\n source: Blob | string;\n onComplete?: () => void;\n};\n\nexport type InitializeChunkStreamParams = {\n onComplete?: () => void;\n mimeCodec?: string;\n};\n\n/**\n * Abstract controller for managing audio output operations.\n * Defines the interface for playing back audio responses.\n */\nexport abstract class OutputAudioController {\n protected logger: Logger;\n\n constructor(loggerName: string) {\n this.logger = new Logger(loggerName);\n }\n\n /**\n * Play either a Blob or a URL string.\n */\n public abstract playAudio(params: PlayAudioParams): Promise<void>;\n\n /**\n * Stream audio from a Response.\n */\n public abstract playAudioStream(params: PlayAudioStreamParams): Promise<void>;\n\n /**\n * Initialize a streaming audio context for chunk-based playback.\n */\n public abstract initializeChunkStream(\n params: InitializeChunkStreamParams\n ): Promise<{\n addChunkToStream: (chunk: ArrayBuffer | Blob) => Promise<void>;\n endChunkStream: () => void;\n }>;\n\n /**\n * Stop any ongoing audio playback.\n */\n public abstract stopPlayback(): Promise<void>;\n\n /**\n * Cleans up all audio playback resources.\n */\n public abstract cleanup(): void;\n}\n","import {\n OutputAudioController,\n PlayAudioParams,\n PlayAudioStreamParams,\n InitializeChunkStreamParams,\n} from './OutputAudioController';\n\n/**\n * Web API implementation of the OutputAudioController.\n * Uses Web Audio API and MediaSource Extensions for audio playback.\n */\n\nexport class AudioElementOutputAudioController extends OutputAudioController {\n // ─── Playback state ──────────────────────────────────────────────────────\n private currentHtmlAudio: HTMLAudioElement | null = null;\n private currentAudioUrl: string | null = null;\n\n constructor() {\n super('@m4trix/core > WebApiOutputAudioController');\n }\n\n // ─── One-shot playback ────────────────────────────────────────────────────\n /**\n * Play either a Blob or a URL string.\n * Uses <audio> under the hood for maximum browser compatibility.\n */\n public async playAudio({\n source,\n onComplete,\n }: PlayAudioParams): Promise<void> {\n // Tear down any previous playback\n if (this.currentHtmlAudio) {\n this.currentHtmlAudio.pause();\n this.currentHtmlAudio.src = '';\n if (this.currentAudioUrl && source instanceof Blob) {\n URL.revokeObjectURL(this.currentAudioUrl);\n }\n }\n\n const audio = new Audio();\n this.currentHtmlAudio = audio;\n\n let url: string;\n if (source instanceof Blob) {\n url = URL.createObjectURL(source);\n this.currentAudioUrl = url;\n audio.onended = (): void => {\n URL.revokeObjectURL(url);\n onComplete?.();\n };\n } else {\n url = source;\n }\n\n audio.src = url;\n try {\n await audio.play();\n } catch (err) {\n this.logger.error('Playback failed, user gesture may be required', err);\n // UI can retry via user interaction\n }\n }\n\n // ─── Streaming playback ──────────────────────────────────────────────────\n /**\n * Stream audio from a Response via MediaSource Extensions.\n * @param params.response The fetch Response whose body is an audio stream\n * @param params.mimeCodec MIME type+codec string, e.g. 'audio/mpeg'\n * @param params.onComplete Optional callback once the stream ends\n */\n public async playAudioStream({\n response,\n mimeCodec = 'audio/mpeg',\n onComplete,\n }: PlayAudioStreamParams): Promise<void> {\n // 1) Validation\n if (!response.ok || !response.body) {\n throw new Error(`Invalid response (${response.status})`);\n }\n if (\n typeof MediaSource === 'undefined' ||\n !MediaSource.isTypeSupported(mimeCodec)\n ) {\n throw new Error(`Unsupported MIME type or codec: ${mimeCodec}`);\n }\n\n // 2) Stop any prior playback\n await this.stopPlayback();\n\n // 3) Create MediaSource + <audio>\n const mediaSource = new MediaSource();\n const url = URL.createObjectURL(mediaSource);\n this.currentAudioUrl = url;\n\n const audio = new Audio(url);\n this.currentHtmlAudio = audio;\n audio.autoplay = true;\n audio.onended = (): void => {\n URL.revokeObjectURL(url);\n this.currentAudioUrl = null;\n onComplete?.();\n };\n\n // 4) Pump incoming bytes into the SourceBuffer\n mediaSource.addEventListener(\n 'sourceopen',\n () => {\n const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);\n const reader = response.body!.getReader();\n\n const pump = async (): Promise<void> => {\n const { done, value } = await reader.read();\n if (done) {\n mediaSource.endOfStream();\n return;\n }\n if (value) {\n sourceBuffer.appendBuffer(value);\n }\n if (sourceBuffer.updating) {\n sourceBuffer.addEventListener('updateend', pump, { once: true });\n } else {\n pump();\n }\n };\n\n pump();\n },\n { once: true }\n );\n\n // 5) Kick off playback\n try {\n await audio.play();\n } catch (err) {\n this.logger.error(\n 'Streaming playback failed, user gesture may be required',\n err\n );\n }\n }\n\n // ─── Chunk-based streaming playback ─────────────────────────────────────\n /**\n * Initialize a streaming audio context for chunk-based playback.\n * This creates the necessary MediaSource and SourceBuffer for subsequent chunk additions.\n * Returns functions to add chunks and end the stream, encapsulated in a closure.\n *\n * @param mimeCodec MIME type+codec string, e.g. 'audio/mpeg'\n * @param onComplete Optional callback once the stream ends\n * @returns Object containing functions to add chunks and end the stream\n */\n public async initializeChunkStream({\n onComplete,\n mimeCodec = 'audio/mpeg',\n }: InitializeChunkStreamParams): Promise<{\n addChunkToStream: (chunk: ArrayBuffer | Blob) => Promise<void>;\n endChunkStream: () => void;\n }> {\n this.logger.debug(`Initializing chunk stream with codec: ${mimeCodec}`);\n\n // 1) Check for MediaSource support and codec support\n if (typeof MediaSource === 'undefined') {\n throw new Error('MediaSource API is not supported in this browser');\n }\n\n // Check for codec support before proceeding\n if (!MediaSource.isTypeSupported(mimeCodec)) {\n this.logger.warn(\n `Codec ${mimeCodec} not supported, falling back to standard audio/mpeg`\n );\n mimeCodec = 'audio/mpeg';\n\n // Double check for mpeg support\n if (!MediaSource.isTypeSupported(mimeCodec)) {\n throw new Error(\n 'Neither the specified codec nor the fallback codec are supported'\n );\n }\n }\n\n // 2) Stop any prior playback\n await this.stopPlayback();\n\n // 3) Create MediaSource + <audio>\n const mediaSource = new MediaSource();\n let sourceBuffer: SourceBuffer | null = null;\n\n const url = URL.createObjectURL(mediaSource);\n this.currentAudioUrl = url;\n\n const audio = new Audio(url);\n this.currentHtmlAudio = audio;\n\n // Prepare audio element\n audio.autoplay = false;\n\n // Enable audio element for debugging\n audio.controls = true; // Make controls visible for debugging\n audio.style.display = 'none'; // Hide element but keep it active\n document.body.appendChild(audio); // Attach to DOM for better browser support\n\n // Track playback state\n let playbackStarted = false;\n let hasReceivedFirstChunk = false;\n let receivedChunksCount = 0;\n\n // Create a queue to handle chunks while buffer is updating\n const pendingChunks: ArrayBuffer[] = [];\n let isProcessingQueue = false;\n\n // 4) Wait for MediaSource to be ready\n this.logger.debug('Waiting for MediaSource to open...');\n await new Promise<void>((resolve, reject) => {\n // Set timeout for MediaSource open\n const timeout = setTimeout(() => {\n reject(new Error('MediaSource failed to open (timeout)'));\n }, 5000);\n\n mediaSource.addEventListener(\n 'sourceopen',\n () => {\n clearTimeout(timeout);\n this.logger.debug('MediaSource open event received');\n\n try {\n sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);\n // Increase buffer size for smoother playback\n if (\n mediaSource.duration === Infinity ||\n isNaN(mediaSource.duration)\n ) {\n mediaSource.duration = 1000; // Set a large duration to allow for more buffering\n }\n this.logger.debug('SourceBuffer created successfully');\n resolve();\n } catch (err) {\n reject(new Error(`Failed to create SourceBuffer: ${err}`));\n }\n },\n { once: true }\n );\n });\n\n const logger = this.logger;\n\n // Process the queue of pending chunks\n const processQueue = async (): Promise<void> => {\n if (!sourceBuffer || pendingChunks.length === 0 || isProcessingQueue) {\n return;\n }\n\n isProcessingQueue = true;\n\n try {\n while (pendingChunks.length > 0) {\n if (sourceBuffer.updating) {\n // Wait for the current update to complete before processing more chunks\n await new Promise<void>((resolve) => {\n sourceBuffer!.addEventListener('updateend', () => resolve(), {\n once: true,\n });\n });\n }\n\n // Get the next chunk from the queue\n const nextChunk = pendingChunks.shift();\n if (!nextChunk) continue;\n\n try {\n sourceBuffer.appendBuffer(nextChunk);\n logger.debug(\n `Processed queued chunk of size ${nextChunk.byteLength}`\n );\n\n // Start playback on first successful append if not started yet\n if (!playbackStarted && hasReceivedFirstChunk) {\n await tryStartPlayback();\n }\n\n // Wait for this append to complete\n await new Promise<void>((resolve) => {\n sourceBuffer!.addEventListener('updateend', () => resolve(), {\n once: true,\n });\n });\n } catch (err) {\n logger.error('Error appending queued chunk to source buffer', err);\n // Continue processing the queue despite errors\n }\n }\n } finally {\n isProcessingQueue = false;\n }\n };\n\n // Try to start audio playback with proper error handling\n const tryStartPlayback = async (): Promise<void> => {\n if (playbackStarted) return;\n\n playbackStarted = true;\n logger.debug('Attempting to start audio playback...');\n\n // Ensure we have enough data before playing\n // (wait for at least 3 chunks or enough buffered time)\n if (\n receivedChunksCount < 3 &&\n audio.buffered.length > 0 &&\n audio.buffered.end(0) < 0.5\n ) {\n logger.debug('Not enough data buffered yet, delaying playback');\n return;\n }\n\n try {\n // Ensure audio element is ready\n if (audio.readyState === 0) {\n logger.debug(\n 'Audio element not ready yet, waiting for canplay event'\n );\n await new Promise<void>((resolve) => {\n audio.addEventListener('canplay', () => resolve(), { once: true });\n });\n }\n\n await audio.play();\n logger.debug('Successfully started audio playback');\n } catch (err) {\n logger.error('Failed to start playback', err);\n\n // Try again with user interaction simulation\n document.addEventListener(\n 'click',\n async () => {\n try {\n await audio.play();\n logger.debug('Started playback after user interaction');\n } catch (innerErr) {\n logger.error(\n 'Still failed to play after user interaction',\n innerErr\n );\n }\n },\n { once: true }\n );\n }\n };\n\n // Define function for adding chunks\n const addChunkToStream = async (\n chunk: ArrayBuffer | Blob\n ): Promise<void> => {\n if (!sourceBuffer) {\n throw new Error(\n 'Streaming context was closed or not properly initialized.'\n );\n }\n\n // Convert Blob to ArrayBuffer if needed\n let arrayBufferChunk: ArrayBuffer;\n if (chunk instanceof Blob) {\n logger.debug('Converting Blob to ArrayBuffer');\n arrayBufferChunk = await chunk.arrayBuffer();\n } else {\n arrayBufferChunk = chunk;\n }\n\n // Skip empty chunks\n if (!arrayBufferChunk || arrayBufferChunk.byteLength === 0) {\n logger.warn('Received empty chunk, skipping');\n return;\n }\n\n // Log first chunk received\n if (!hasReceivedFirstChunk) {\n hasReceivedFirstChunk = true;\n logger.debug(\n `First chunk received, size: ${arrayBufferChunk.byteLength} bytes`\n );\n }\n\n receivedChunksCount++;\n\n // Add the chunk to the queue\n pendingChunks.push(arrayBufferChunk);\n logger.debug(\n `Added chunk #${receivedChunksCount} to queue (size: ${arrayBufferChunk.byteLength} bytes)`\n );\n\n // Start processing the queue if not already processing\n await processQueue();\n\n // Try to start playback if we have enough data (and not started yet)\n if (\n !playbackStarted &&\n hasReceivedFirstChunk &&\n receivedChunksCount >= 3\n ) {\n await tryStartPlayback();\n }\n };\n\n // Define function for ending the stream\n const endChunkStream = (): void => {\n if (mediaSource && mediaSource.readyState === 'open') {\n try {\n // Wait for any pending chunks to be processed\n if (\n pendingChunks.length > 0 ||\n (sourceBuffer && sourceBuffer.updating)\n ) {\n logger.debug('Waiting for pending chunks before ending stream');\n setTimeout(() => endChunkStream(), 200);\n return;\n }\n\n if (hasReceivedFirstChunk) {\n mediaSource.endOfStream();\n logger.debug('MediaSource stream ended successfully');\n } else {\n logger.warn('Stream ended without receiving any chunks');\n }\n } catch (err) {\n logger.error('Error ending MediaSource stream', err);\n }\n }\n\n // Clean up audio element and URL\n audio.onended = null;\n\n // Remove from DOM if we added it\n if (audio.parentNode) {\n audio.parentNode.removeChild(audio);\n }\n\n if (this.currentAudioUrl === url) {\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n }\n\n // Reset references to allow garbage collection\n sourceBuffer = null;\n };\n\n // Set up completion handler\n audio.onended = (): void => {\n logger.debug('Audio playback completed');\n endChunkStream();\n onComplete?.();\n };\n\n return {\n addChunkToStream,\n endChunkStream,\n };\n }\n\n /**\n * Stop any ongoing HTMLAudioElement playback.\n */\n public async stopPlayback(): Promise<void> {\n if (this.currentHtmlAudio) {\n try {\n this.currentHtmlAudio.pause();\n this.currentHtmlAudio.src = '';\n } catch (err) {\n this.logger.error('Error stopping playback', err);\n }\n this.currentHtmlAudio = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n }\n\n /**\n * Cleans up all audio playback resources.\n */\n public cleanup(): void {\n this.stopPlayback();\n }\n}\n","'use client';\n// Voice conversation hook for handling audio recording and playback via socket connection\nimport { useState, useRef, useEffect, useCallback } from 'react';\nimport { VoiceSocketAdapter } from '../../adapter/socket/VoiceSocketAdapter';\nimport { VoiceSocketIOAdapter } from '../../adapter/socket/VoiceSocketIOAdapter';\nimport { Logger } from '../../../utility/Logger';\nimport { WebAudioInputAudioController } from '../../utility/audio/WebAudioInputAudioController';\nimport { OutputAudioController } from '../../utility/audio/OutputAudioController';\nimport { WebAudioOutputAudioController } from '../../utility/audio/WebAudioOutputAudioController';\nimport type {\n BaseUseConversationOptions,\n DownstreamMode,\n UpstreamMode,\n VoiceAgentState,\n} from './shared-types';\n\nexport type SocketConversationOptions<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = BaseUseConversationOptions & {\n scope?: string;\n downstreamMode?: DownstreamMode;\n upstreamMode?: UpstreamMode;\n handsFreeEnginePlugin?: unknown[];\n socketConfig?: {\n baseUrl?: string;\n socketAdapter?: VoiceSocketAdapter;\n headers?: Record<string, string>;\n };\n requestData?: T;\n};\n\nexport interface UseSocketConversationResult {\n startRecording: () => void;\n stopRecording: () => void;\n enableHandsFreeRecording?: () => void;\n voiceAgentState: VoiceAgentState;\n error: Error | null;\n audioContext: AudioContext | null;\n socket: unknown | null;\n}\n\nLogger.enableGlobalLogging();\n\n/**\n * A hook for managing voice conversations in React applications using WebSockets and Web Audio API\n */\nexport function useSocketConversation<T extends Record<string, unknown>>({\n scope,\n onStartRecording,\n onStopRecording,\n onReceive,\n upstreamMode = 'STREAM_WHILE_TALK',\n onError,\n audioConfig = {},\n socketConfig = {},\n}: SocketConversationOptions<T>): UseSocketConversationResult {\n // Refs\n const { current: logger } = useRef<Logger>(\n new Logger('SuTr > useSocketConversation')\n );\n const inputAudioControllerRef = useRef<\n WebAudioInputAudioController | undefined\n >(undefined);\n\n const outputAudioControllerRef = useRef<OutputAudioController | undefined>(\n undefined\n );\n\n const socketAdapterRef = useRef<VoiceSocketAdapter | undefined>(undefined);\n const [socket, setSocket] = useState<unknown | null>(null);\n\n // State\n const [voiceAgentState, setVoiceAgentState] =\n useState<VoiceAgentState>('READY');\n const [error, setError] = useState<Error | null>(null);\n\n // ================================================\n // =============== Inferred Config ================\n // ================================================\n\n const shouldStreamWhileTalk = upstreamMode === 'STREAM_WHILE_TALK';\n\n // ================================================\n // =============== Callbacks ======================\n // ================================================\n\n const handleError = useCallback(\n (state: VoiceAgentState, err: Error) => {\n setError(err);\n logger.error(`Error during ${state}:`, err);\n onError?.(state, err);\n },\n [onError]\n );\n\n const subscribeToSocketEventsForChunkDownstreaming = useCallback(\n async (socketAdapter: VoiceSocketAdapter) => {\n logger.debug('Setting up audio stream for receiving chunks');\n\n try {\n const { addChunkToStream, endChunkStream } =\n await outputAudioControllerRef.current!.initializeChunkStream({\n mimeCodec: 'audio/mpeg',\n onComplete: () => {\n logger.debug('Audio stream playback completed');\n setVoiceAgentState('READY');\n },\n });\n\n // Keep track of received chunks for debugging\n let chunkCount = 0;\n\n const chunkReceivedEmitter = async (chunk: unknown): Promise<void> => {\n if (chunk instanceof ArrayBuffer) {\n chunkCount++;\n logger.debug(\n `Received voice chunk #${chunkCount} from socket, size: ${chunk.byteLength} bytes`\n );\n\n if (!chunk || chunk.byteLength === 0) {\n logger.warn('Received empty chunk, skipping');\n return;\n }\n\n try {\n await addChunkToStream(chunk);\n logger.debug(\n `Successfully added chunk #${chunkCount} to audio stream`\n );\n } catch (err) {\n logger.error(\n `Failed to add chunk #${chunkCount} to audio stream`,\n err\n );\n if (err instanceof Error) {\n handleError('DOWNSTREAMING', err);\n }\n }\n }\n };\n\n socketAdapter.on('chunk-received', chunkReceivedEmitter);\n\n const endOfStreamEmitter = (): void => {\n logger.debug(\n `Received end of stream signal after ${chunkCount} chunks, ending chunk stream`\n );\n endChunkStream();\n setVoiceAgentState('READY');\n };\n\n socketAdapter.on('received-end-of-response-stream', endOfStreamEmitter);\n\n // Returning a cleanup callback to remove the event listeners\n return () => {\n logger.debug('Cleaning up socket event listeners');\n socketAdapter.off('chunk-received', chunkReceivedEmitter);\n socketAdapter.off(\n 'received-end-of-response-stream',\n endOfStreamEmitter\n );\n endChunkStream();\n };\n } catch (err) {\n if (err instanceof Error) {\n handleError('DOWNSTREAMING', err);\n }\n return () => {};\n }\n },\n [handleError]\n );\n\n const hookupSocketAdapter = useCallback(\n async (socketAdapter: VoiceSocketAdapter) => {\n logger.debug('Connecting to socket...');\n\n try {\n await socketAdapter.connect();\n\n socketAdapter.on('connect', () => {\n logger.debug('Socket adapter connected');\n setVoiceAgentState('READY');\n });\n\n socketAdapter.on('disconnect', () => {\n logger.debug('Socket adapter disconnected');\n });\n\n socketAdapter.on('error', (err: unknown) => {\n if (err instanceof Error) {\n handleError(voiceAgentState, err);\n } else {\n handleError(voiceAgentState, new Error('Unknown error'));\n }\n });\n\n setSocket(socketAdapter.exposeSocket<unknown>());\n } catch (err) {\n if (err instanceof Error) {\n handleError('READY', err);\n }\n }\n },\n [handleError, voiceAgentState]\n );\n\n const startRecording = useCallback(() => {\n if (inputAudioControllerRef.current) {\n try {\n logger.debug('Starting recording');\n setVoiceAgentState('RECORDING');\n inputAudioControllerRef.current.startRecording({\n onRecordedChunk: async (chunk) => {\n if (shouldStreamWhileTalk) {\n try {\n // We do not set UPSTREAMING since we are recording while talking\n await socketAdapterRef.current?.sendVoiceChunk(chunk);\n } catch (err) {\n if (err instanceof Error) {\n handleError('RECORDING', err);\n }\n }\n }\n },\n });\n onStartRecording?.();\n } catch (err) {\n if (err instanceof Error) {\n handleError('RECORDING', err);\n }\n }\n }\n }, [onStartRecording, shouldStreamWhileTalk, handleError]);\n\n const stopRecording = useCallback(async () => {\n if (inputAudioControllerRef.current) {\n try {\n logger.debug('Stopping recording');\n await inputAudioControllerRef.current.stopRecording({\n onRecordingCompleted: async (allData) => {\n setVoiceAgentState('PROCESSING');\n try {\n if (shouldStreamWhileTalk) {\n logger.debug('Committing voice message');\n await socketAdapterRef.current?.commitVoiceMessage();\n } else {\n await socketAdapterRef.current?.sendVoiceFile(allData);\n }\n\n setVoiceAgentState('DOWNSTREAMING');\n await subscribeToSocketEventsForChunkDownstreaming(\n socketAdapterRef.current!\n );\n\n // Handle receiving the audio response\n onReceive?.(\n allData,\n async () => {\n // Play response function\n if (outputAudioControllerRef.current) {\n // Use stopPlayback because it should also have logic to resume or start\n return outputAudioControllerRef.current.stopPlayback();\n }\n },\n async () => {\n // Stop response function\n if (outputAudioControllerRef.current) {\n return outputAudioControllerRef.current.stopPlayback();\n }\n }\n );\n\n // Event listeners are cleaned up automatically\n } catch (err) {\n if (err instanceof Error) {\n handleError('PROCESSING', err);\n }\n }\n },\n });\n onStopRecording?.();\n } catch (err) {\n if (err instanceof Error) {\n handleError('RECORDING', err);\n }\n }\n }\n }, [\n onStopRecording,\n handleError,\n subscribeToSocketEventsForChunkDownstreaming,\n onReceive,\n ]);\n\n // Setup Socket Adapter and AudioControllers\n useEffect(() => {\n if (socketAdapterRef.current) {\n return;\n }\n\n try {\n // Set up socket adapter\n const socketAdapter = socketConfig.socketAdapter\n ? socketConfig.socketAdapter\n : new VoiceSocketIOAdapter({\n scope,\n baseUrl: socketConfig.baseUrl || '',\n headers: socketConfig.headers,\n });\n\n socketAdapterRef.current = socketAdapter;\n\n if (!socketAdapter.isConnected()) {\n hookupSocketAdapter(socketAdapter);\n }\n\n // Set up audio controllers\n if (!inputAudioControllerRef.current) {\n inputAudioControllerRef.current = new WebAudioInputAudioController(\n audioConfig\n );\n }\n\n if (!outputAudioControllerRef.current) {\n outputAudioControllerRef.current = new WebAudioOutputAudioController();\n }\n } catch (err) {\n if (err instanceof Error) {\n handleError('READY', err);\n }\n }\n }, [scope, socketConfig, hookupSocketAdapter, audioConfig, handleError]);\n\n // On Mount and on unmount, cleanup the audio controller\n useEffect(() => {\n return () => {\n inputAudioControllerRef.current?.cleanup();\n outputAudioControllerRef.current?.cleanup();\n if (socketAdapterRef.current) {\n socketAdapterRef.current.disconnect();\n socketAdapterRef.current = undefined;\n }\n };\n }, []);\n\n // Return the public API\n return {\n startRecording,\n stopRecording,\n voiceAgentState,\n error,\n audioContext: inputAudioControllerRef.current?.audioContext || null,\n socket,\n };\n}\n","import { Logger } from '../../../utility/Logger';\n\nexport interface VoiceSocketConfig {\n scope?: string;\n baseUrl: string;\n protocols?: string | string[];\n headers?: Record<string, string>;\n autoReconnect?: boolean;\n}\n\nexport interface VoiceSocketMessage {\n type: 'chunk' | 'file';\n data: string; // base64 encoded\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Base class for voice socket adapters that handles voice data transmission.\n *\n * Emits:\n * - \"connect\"\n * - \"disconnect\"\n * - \"error\" (with Error)\n * - \"chunk-received\" (ArrayBuffer)\n * - \"received-end-of-response-stream\"\n * - \"chunk-sent\" (ArrayBuffer | Blob)\n * - \"file-received\" (Blob)\n * - \"file-sent\" (Blob)\n * - \"control-message\" (object)\n */\nexport abstract class VoiceSocketAdapter {\n protected config: VoiceSocketConfig;\n protected _isConnected = false;\n protected logger = new Logger('@m4trix/core > VoiceSocketAdapter');\n protected emitter = new Emitter();\n\n constructor(config: VoiceSocketConfig) {\n this.config = config;\n }\n\n on(event: string, listener: (data?: unknown) => void): void {\n this.emitter.on(event, listener);\n }\n\n off(event: string, listener: (data?: unknown) => void): void {\n this.emitter.off(event, listener);\n }\n\n once(event: string, listener: (data?: unknown) => void): void {\n this.emitter.once(event, listener);\n }\n\n protected emit(event: string, data?: unknown): void {\n this.emitter.emit(event, data);\n }\n\n isConnected(): boolean {\n return this._isConnected;\n }\n\n abstract connect(): Promise<void>;\n abstract disconnect(): void;\n abstract exposeSocket<T>(): T | null;\n\n abstract sendVoiceChunk(\n chunk: ArrayBuffer | Blob,\n metadata?: Record<string, unknown>\n ): Promise<void>;\n\n abstract commitVoiceMessage(): void;\n\n abstract sendVoiceFile(blob: Blob, metadata?: Record<string, unknown>): void;\n\n protected abstract onVoiceChunkReceived(chunk: ArrayBuffer): void;\n protected abstract onReceivedEndOfResponseStream(): void;\n protected abstract onVoiceFileReceived(blob: Blob): void;\n}\ntype Listener<T> = (event: T) => void;\n\nexport class Emitter {\n private target = new EventTarget();\n\n on<T>(type: string, listener: Listener<T>): void {\n this.target.addEventListener(type, listener as EventListener);\n }\n\n off<T>(type: string, listener: Listener<T>): void {\n this.target.removeEventListener(type, listener as EventListener);\n }\n\n once<T>(type: string, listener: Listener<T>): void {\n const wrapper = (event: Event): void => {\n this.off(type, wrapper);\n listener((event as CustomEvent).detail);\n };\n this.on(type, wrapper);\n }\n\n emit<T>(type: string, detail?: T): void {\n this.target.dispatchEvent(new CustomEvent(type, { detail }));\n }\n}\n","import { VoiceSocketAdapter, VoiceSocketConfig } from './VoiceSocketAdapter';\nimport { Socket, io } from 'socket.io-client';\n\n// Define an interface that extends the VoiceSocketAdapter with Socket.IO specific properties\nexport class VoiceSocketIOAdapter extends VoiceSocketAdapter {\n protected socket: Socket | null = null;\n\n constructor(config: VoiceSocketConfig) {\n super(config);\n }\n\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.socket) {\n this.socket = io(this.config.baseUrl, {\n extraHeaders: this.config.headers,\n autoConnect: true,\n });\n }\n\n this.socket.on('connect', () => {\n this._isConnected = true;\n this.logger.debug('Connected to socket');\n this.emit('connect');\n resolve();\n });\n\n this.socket.on('disconnect', () => {\n this._isConnected = false;\n this.emit('disconnect');\n this.logger.debug('Disconnected from socket');\n if (this.config.autoReconnect) this.connect(); // reconnect if configured\n });\n\n this.socket.on('connect_error', (error) => {\n this.logger.error('Error connecting to socket', error);\n this.emit('error', error);\n reject(error);\n });\n\n this.socket.on('voice:chunk_received', (chunk: ArrayBuffer) => {\n this.logger.debug('Received voice chunk', chunk.byteLength);\n this.onVoiceChunkReceived(chunk);\n });\n\n this.socket.on('voice:received_end_of_response_stream', () => {\n this.logger.debug('Received end of response stream');\n this.onReceivedEndOfResponseStream();\n });\n\n this.socket.on('voice:file_received', (blob: Blob) => {\n this.logger.debug('Received voice file');\n this.onVoiceFileReceived(blob);\n });\n\n // TODO: remove?\n this.socket.on('control-message', (message: Record<string, unknown>) => {\n this.logger.debug('Received control message', message);\n this.emit('control-message', message);\n });\n });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n this._isConnected = false;\n }\n\n exposeSocket<T>(): T | null {\n return this.socket as T | null;\n }\n\n async sendVoiceChunk(\n chunk: ArrayBuffer | Blob,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n this.logger.debug(\n 'Sending voice chunk %i',\n chunk instanceof Blob ? chunk.size : chunk.byteLength\n );\n if (!this.socket || !this.isConnected)\n throw new Error('Socket not connected');\n\n let chunkToSend: ArrayBuffer;\n if (chunk instanceof Blob) {\n chunkToSend = await chunk.arrayBuffer();\n } else {\n chunkToSend = chunk;\n }\n\n this.logger.debug('[Socket] Sending voice chunk', chunkToSend.byteLength);\n\n this.socket.emit('voice:send_chunk', chunkToSend, metadata);\n this.emit('chunk_sent', chunk);\n }\n\n sendVoiceFile(blob: Blob, metadata?: Record<string, unknown>): void {\n this.logger.debug('Sending voice file', blob, metadata);\n if (!this.socket || !this.isConnected)\n throw new Error('Socket not connected');\n\n this.socket.emit('voice:send_file', blob, metadata);\n this.emit('file-sent', blob);\n }\n\n commitVoiceMessage(): void {\n if (!this.socket || !this.isConnected)\n throw new Error('Socket not connected');\n\n this.socket.emit('voice:commit');\n }\n\n protected onVoiceChunkReceived(chunk: ArrayBuffer): void {\n this.emit('chunk-received', chunk);\n }\n\n protected onVoiceFileReceived(blob: Blob): void {\n this.emit('file-received', blob);\n }\n\n protected onReceivedEndOfResponseStream(): void {\n this.emit('received-end-of-response-stream');\n }\n}\n","/*\n * Web Audio API implementation of the OutputAudioController interface.\n * ---------------------------------------------------------------------\n * **PCM streaming variant – byte‑accurate**\n * Handles raw 16‑bit little‑endian PCM from ElevenLabs (`pcm_24000`). The\n * byte‑level buffer realigns odd‑sized packets before converting to\n * `AudioBuffer`s, eliminating white‑noise artefacts. Implements all methods\n * required by `OutputAudioController`.\n */\n\nimport {\n OutputAudioController,\n PlayAudioParams,\n InitializeChunkStreamParams,\n} from './OutputAudioController';\n\n// ─── PCM constants ─────────────────────────────────────────────────────\nconst STREAM_SAMPLE_RATE = 24_000; // match ElevenLabs request\nconst CHANNELS = 1; // mono\nconst SLICE_DURATION_S = 0.25; // schedule 250ms\nconst FRAMES_PER_SLICE = Math.floor(STREAM_SAMPLE_RATE * SLICE_DURATION_S);\nconst BYTES_PER_SLICE = FRAMES_PER_SLICE * 2; // 16‑bit → 2B per frame\n\n/** Scheduler jitter window (seconds). */\nconst SCHED_TOLERANCE = 0.05;\n\nexport class WebAudioOutputAudioController extends OutputAudioController {\n private readonly audioCtx = new AudioContext();\n private readonly gain = this.audioCtx.createGain();\n\n private nextPlayTime = 0;\n private activeSources = new Set<AudioBufferSourceNode>();\n private userGestureHookAttached = false;\n\n constructor() {\n super('@m4trix/core > WebAudioOutputAudioController');\n this.gain.connect(this.audioCtx.destination);\n this.resetScheduler();\n }\n\n // ─────────────────────────────────────────────────────────────────────\n // One‑shot playback\n // ─────────────────────────────────────────────────────────────────────\n public async playAudio({\n source,\n onComplete,\n }: PlayAudioParams): Promise<void> {\n await this.stopPlayback();\n const buf = await this.sourceToArrayBuffer(source);\n const decoded = await this.decode(buf);\n await this.ensureContextRunning();\n const src = this.createSource(decoded, this.audioCtx.currentTime);\n src.onended = (): void => {\n this.activeSources.delete(src);\n onComplete?.();\n };\n }\n\n public async playAudioStream(): Promise<void> {\n /* reserved for future MSE path */\n }\n\n // ─────────────────────────────────────────────────────────────────────\n // PCM streaming\n // ─────────────────────────────────────────────────────────────────────\n public async initializeChunkStream({\n onComplete,\n }: InitializeChunkStreamParams): Promise<{\n addChunkToStream: (chunk: ArrayBuffer | Blob) => Promise<void>;\n endChunkStream: () => void;\n }> {\n await this.stopPlayback();\n await this.ensureContextRunning();\n this.resetScheduler();\n\n let streamEnded = false;\n let pending = new Uint8Array(0); // may hold an odd byte\n\n const addChunkToStream = async (pkt: ArrayBuffer | Blob): Promise<void> => {\n if (streamEnded) {\n this.logger.warn('Attempt to add chunk after stream ended – ignoring.');\n return;\n }\n const bytes = new Uint8Array(\n pkt instanceof Blob ? await pkt.arrayBuffer() : pkt\n );\n if (bytes.length === 0) return;\n\n const merged = new Uint8Array(pending.length + bytes.length);\n merged.set(pending);\n merged.set(bytes, pending.length);\n pending = merged;\n\n if (pending.length % 2 === 1) return; // keep lone byte for next packet\n\n while (pending.length >= BYTES_PER_SLICE) {\n const sliceBytes = pending.slice(0, BYTES_PER_SLICE);\n pending = pending.slice(BYTES_PER_SLICE);\n\n // copy into an aligned buffer to avoid RangeError when the\n // underlying byteOffset is odd\n const aligned = sliceBytes.buffer.slice(\n sliceBytes.byteOffset,\n sliceBytes.byteOffset + sliceBytes.byteLength\n );\n const int16 = new Int16Array(aligned);\n const buf = this.audioCtx.createBuffer(\n CHANNELS,\n int16.length,\n STREAM_SAMPLE_RATE\n );\n const data = buf.getChannelData(0);\n for (let i = 0; i < int16.length; i++) data[i] = int16[i] / 32768;\n this.scheduleBuffer(buf);\n }\n };\n\n const endChunkStream = (): void => {\n if (streamEnded) return;\n streamEnded = true;\n if (onComplete) {\n if (this.activeSources.size === 0) onComplete();\n else {\n const last = Array.from(this.activeSources).pop();\n if (last) {\n const prev = last.onended;\n last.onended = (e): void => {\n if (prev) prev.call(last, e);\n onComplete();\n };\n }\n }\n }\n };\n\n return { addChunkToStream, endChunkStream };\n }\n\n // ─────────────────────────────────────────────────────────────────────\n // Buffer scheduling helpers\n // ─────────────────────────────────────────────────────────────────────\n private scheduleBuffer(buf: AudioBuffer): void {\n if (this.nextPlayTime < this.audioCtx.currentTime + SCHED_TOLERANCE) {\n this.nextPlayTime = this.audioCtx.currentTime + SCHED_TOLERANCE;\n }\n this.createSource(buf, this.nextPlayTime);\n this.nextPlayTime += buf.duration;\n }\n\n private createSource(buf: AudioBuffer, when: number): AudioBufferSourceNode {\n const src = this.audioCtx.createBufferSource();\n src.buffer = buf;\n src.connect(this.gain);\n src.start(when);\n this.activeSources.add(src);\n src.onended = (): void => {\n this.activeSources.delete(src);\n };\n return src;\n }\n\n private resetScheduler(): void {\n this.nextPlayTime = this.audioCtx.currentTime;\n }\n\n // ─── External resource helpers ───────────────────────────────────────\n private sourceToArrayBuffer(src: Blob | string): Promise<ArrayBuffer> {\n return typeof src === 'string'\n ? fetch(src).then((r) => {\n if (!r.ok) throw new Error(`${r.status}`);\n return r.arrayBuffer();\n })\n : src.arrayBuffer();\n }\n\n private decode(buf: ArrayBuffer): Promise<AudioBuffer> {\n return new Promise((res, rej) =>\n this.audioCtx.decodeAudioData(buf, res, rej)\n );\n }\n\n // ─── Lifecycle methods ───────────────────────────────────────────────\n public async stopPlayback(): Promise<void> {\n for (const src of this.activeSources) {\n try {\n src.stop();\n } catch {\n /* ignore */\n }\n src.disconnect();\n }\n this.activeSources.clear();\n this.resetScheduler();\n }\n\n public cleanup(): void {\n this.stopPlayback();\n if (this.audioCtx.state !== 'closed') this.audioCtx.close();\n }\n\n // ─── Autoplay‑policy helper ──────────────────────────────────────────\n private async ensureContextRunning(): Promise<void> {\n if (this.audioCtx.state !== 'suspended') return;\n\n try {\n await this.audioCtx.resume();\n } catch {\n /* ignore */\n }\n if ((this.audioCtx.state as string) === 'running') return;\n\n if (!this.userGestureHookAttached) {\n this.userGestureHookAttached = true;\n const resume = async (): Promise<void> => {\n try {\n await this.audioCtx.resume();\n } catch {\n /* ignore */\n }\n if (this.audioCtx.state === 'running')\n document.removeEventListener('click', resume);\n };\n document.addEventListener('click', resume);\n }\n }\n}\n","import { LitElement, PropertyValues, TemplateResult, html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { createRef, ref } from 'lit/directives/ref.js';\nimport { createTimeline, Timeline } from 'animejs';\nimport { AiCursorComponentStyle } from './AiCursorComponent.style';\n\nexport type Props = {\n /**\n * The event hooks are functions that let you connect the inner logic of the solid js component and the AiCursor Class that acts\n * as an API.\n */\n eventHooks: {\n defineSetPosition: (fn: (position: [number, number]) => void) => void;\n defineAddPositionToQueue: (\n fn: (position: [number, number]) => void\n ) => void;\n definePlayQueue: (fn: () => void) => void;\n defineSetShowCursor: (fn: (show: boolean) => void) => void;\n };\n};\n\n@customElement('ai-cursor')\nexport class AiCursorComponent extends LitElement {\n @property({\n type: Object,\n })\n eventHooks: Props['eventHooks'] = {\n defineSetPosition: () => {},\n defineAddPositionToQueue: () => {},\n definePlayQueue: () => {},\n defineSetShowCursor: () => {},\n };\n\n @property({ type: Boolean })\n isShowingCursor = true;\n @property({ type: String })\n labelText = 'AI Cursor';\n\n @property({ type: Array })\n cursorPosition: [number, number] = [0, 0];\n\n private _timeline: Timeline | undefined;\n\n @state()\n private _cursorRef = createRef<HTMLSpanElement>();\n @state()\n private _labelRef = createRef<HTMLSpanElement>();\n\n constructor() {\n super();\n }\n\n updated(_changedProperties: PropertyValues): void {\n if (_changedProperties.has('_cursorRef')) {\n if (this._cursorRef.value) {\n this.hookUpCallbacks();\n } else {\n this._timeline?.pause();\n this._timeline?.refresh();\n }\n }\n super.updated(_changedProperties);\n }\n\n // Define scoped styles right with your component, in plain CSS\n static styles = AiCursorComponentStyle;\n\n render(): TemplateResult {\n const cursorSvg = html`\n <svg\n width=${24}\n height=${24}\n viewBox=\"0 0 100 100\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g clip-path=\"url(#clip0_3576_285)\">\n <path\n class=\"cursor-path\"\n d=\"M2.14849 7.04749C1.35153 4.07321 4.07319 1.35155 7.04747 2.14851L77.3148 20.9766C80.2891 21.7735 81.2853 25.4914 79.108 27.6687L27.6687 79.108C25.4914 81.2853 21.7735 80.2891 20.9766 77.3149L2.14849 7.04749Z\"\n fill=\"currentColor\"\n />\n </g>\n <defs>\n <clipPath id=\"clip0_3576_285\">\n <rect width=\"100\" height=\"100\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n `;\n\n return html`\n <span\n id=\"cursor-graphic-parent\"\n ${ref(this._cursorRef)}\n ?hidden=${!this.isShowingCursor}\n >\n ${cursorSvg}\n <span\n ${ref(this._labelRef)}\n id=\"label-text\"\n ?hidden=${!this.isShowingCursor}\n >${this.labelText}</span\n >\n </span>\n `;\n }\n\n // private methods\n\n /**\n * The primary way to control the cursor is using an external API.\n * This interface exposes controlling methods. The Lit Component itself is\n * intended to be a controlled component.\n */\n private hookUpCallbacks(): void {\n const animationTarget = this._cursorRef.value;\n\n if (!animationTarget) {\n return;\n }\n\n this._timeline = createTimeline({ defaults: { duration: 750 } });\n\n if (!this._timeline) {\n return;\n }\n\n this.eventHooks.defineSetPosition((position) => {\n this._timeline?.add(animationTarget, {\n translateX: position[0],\n translateY: position[1],\n duration: 1,\n });\n this._timeline?.play();\n });\n\n this.eventHooks.defineAddPositionToQueue((position) => {\n this._timeline?.add(animationTarget, {\n translateX: position[0],\n translateY: position[1],\n duration: 1000,\n });\n });\n\n this.eventHooks.defineSetShowCursor((show) => {\n this.isShowingCursor = show;\n });\n\n this.eventHooks.definePlayQueue(() => {\n this._timeline?.play();\n });\n }\n\n // Getters\n get cursorRef(): HTMLSpanElement | undefined {\n return this._cursorRef.value;\n }\n\n get labelRef(): HTMLSpanElement | undefined {\n return this._labelRef.value;\n }\n}\n","import { css } from 'lit';\n\nexport const AiCursorComponentStyle = css`\n :host {\n --ai-local-cursor-size: var(--sk-ai-cursor-size, 1rem);\n --ai-local-cursor-label-padding: var(\n --sk-ai-cursor-label-padding,\n 0.25rem 0.25rem\n );\n --ai-local-cursor-border-radius: var(--sk-ai-cursor-border-radius, 0.25rem);\n --ai-local-label-offset: var(--sk-ai-cursor-label-offset, 1rem);\n\n --ai-local-label-font-size: var(--sk-ai-cursor-label-font-size, 12px);\n --ai-local-label-font-weight: var(--sk-ai-cursor-label-font-weight, bold);\n --ai-local-label-color: var(--sk-ai-cursor-label-color, white);\n --ai-local-label-background-color: var(\n --sk-ai-cursor-label-background-color,\n black\n );\n --ai-local-label-border-color: var(\n --sk-ai-cursor-label-border-color,\n white\n );\n --ai-local-label-border-width: var(\n --sk-ai-cursor-label-border-width,\n 0.1rem\n );\n\n color: black;\n stroke: white;\n position: absolute;\n /* Insetting in the parent element (body) */\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n pointer-events: none;\n width: var(--ai-local-cursor-size);\n height: var(--ai-local-cursor-size);\n }\n\n #cursor-graphic-parent {\n position: absolute;\n top: 0;\n left: 0;\n }\n\n #label-text {\n position: absolute;\n color: white;\n font-size: 12px;\n font-weight: bold;\n padding: var(--ai-local-cursor-label-padding);\n border-radius: var(--ai-local-cursor-border-radius);\n\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n\n width: fit-content;\n min-width: fit-content;\n top: var(--ai-local-label-offset);\n left: var(--ai-local-label-offset);\n\n border: var(--ai-local-label-border-width) solid\n var(--ai-local-label-border-color);\n background-color: var(--ai-local-label-background-color);\n color: var(--ai-local-label-color);\n font-size: var(--ai-local-label-font-size);\n font-weight: var(--ai-local-label-font-weight);\n }\n`;\n","import './AiCursorComponent';\nimport { AiCursorComponent, Props as AiCursorProps } from './AiCursorComponent';\n/**\n * The AI Cursor is a Lit Element.\n * Why Lit.dev?\n * Lit.dev is a tiny on memory and bundle size. It is quite fast in rendering.\n * And since UI elements in this library shall be isolated and scoped components,\n * Lit.dev is a good fit.\n * It follows reactivity principles with very fine granularity,\n *\n * Also Solid.js (which was the first version of that - prooved to be annoying because of jsx compiler extras).\n *\n * A downside of Lit.dev is that it is not a very common library. Further, it is close to the DOM using native DOM APIs.\n * Causing it to be a bit different than libs like react using virtual DOM.\n * For other contributors I would recommend reading the /life-cycle section of the docs.\n *\n * Author: @Pascal-Lohscheidt\n */\nexport const mountAiCursor = (aiCursorProps: AiCursorProps): void => {\n const root = document.body;\n const cursor = document.createElement('ai-cursor') as AiCursorComponent;\n cursor.eventHooks = aiCursorProps.eventHooks;\n\n root.appendChild(cursor);\n};\n","import { mountAiCursor } from './rendering';\nimport { Props as AiCursorProps } from './rendering/AiCursorComponent';\n\ntype Selector = string;\ntype CursorTarget = HTMLElement | Selector | [number, number];\n\n/**\n * The AiCursor is a class that is used to create a cursor element and acts an interface to control the cursor.\n * It is used to move the cursor to a target, show or hide the cursor, and to schedule moves.\n *\n * @example\n * ```ts\n * const cursor = AiCursor.spawn();\n * cursor.moveTo('#target-element');\n * ```\n *\n * @author @Pascal-Lohscheidt\n */\nexport class AiCursor {\n private setPosition?: (position: [number, number]) => void;\n private addPositionToQueue?: (position: [number, number]) => void;\n private playQueue?: () => void;\n private setShowCursor?: (show: boolean) => void;\n\n constructor() {}\n\n // Static constructors\n static spawn(): AiCursor {\n const newCursor = new AiCursor();\n newCursor.mount();\n return newCursor;\n }\n\n jumpTo(target: CursorTarget): void {\n const position = targetToPosition(target);\n if (position) {\n this.setPosition?.(position);\n }\n }\n\n moveTo(target: CursorTarget): void {\n const position = targetToPosition(target);\n if (position) {\n this.addPositionToQueue?.(position);\n this.playQueue?.();\n }\n }\n\n scheduleMoves(targets: CursorTarget[]): void {\n targets.forEach((target) => {\n const position = targetToPosition(target);\n if (position) {\n this.addPositionToQueue?.(position);\n }\n });\n this.playQueue?.();\n }\n\n show(): void {\n this.setShowCursor?.(true);\n }\n\n hide(): void {\n this.setShowCursor?.(false);\n }\n\n private mount(): void {\n mountAiCursor({\n eventHooks: {\n defineSetPosition: (callback): void => {\n this.setPosition = callback;\n },\n defineAddPositionToQueue: (callback): void => {\n this.addPositionToQueue = callback;\n },\n definePlayQueue: (callback): void => {\n this.playQueue = callback;\n },\n defineSetShowCursor: (callback): void => {\n this.setShowCursor = callback;\n },\n },\n } satisfies AiCursorProps);\n }\n}\n\nfunction calculateClickPositionFromElement(element: Element): [number, number] {\n const rect = element.getBoundingClientRect();\n return [rect.left + rect.width / 2, rect.top + rect.height / 2];\n}\n\nfunction targetToPosition(target: CursorTarget): [number, number] | undefined {\n if (\n Array.isArray(target) &&\n target.length === 2 &&\n typeof target[0] === 'number' &&\n typeof target[1] === 'number'\n ) {\n return target;\n } else if (target instanceof HTMLElement) {\n return calculateClickPositionFromElement(target);\n } else if (typeof target === 'string') {\n const element = document.querySelector(target);\n if (element) {\n return calculateClickPositionFromElement(element);\n }\n }\n return undefined;\n}\n","/**\n * StreamChunk is the base interface for all streams.\n * It can hold voice and text chunks.\n *\n * @template T The type of data contained in the chunk\n */\nexport interface StreamChunk<T> {\n sequence: number;\n data: T;\n done: boolean;\n}\n\n/**\n * MessageStream represents an asynchronous iterable stream of chunks.\n * Used as the core stream representation throughout the Pump library.\n *\n * @template T The type of data contained in the chunks of the stream\n */\nexport type MessageStream<T> = AsyncIterable<StreamChunk<T>>;\n\n/**\n * Represents any source that can be converted to a stream.\n * This includes AsyncIterable and ReadableStream sources.\n *\n * @template T The type of data contained in the source\n */\nexport type Source<T> =\n | AsyncIterable<T>\n | ReadableStream<T>\n | NodeJS.ReadableStream;\n\n/**\n * A transformer for stream data that also provides a response.\n * Used primarily to transform and consume stream data while producing a response object.\n *\n * @template T The type of data being transformed\n * @template R The type of the response (defaults to Response)\n */\nexport type StreamTransformer<T, R = Response> = {\n transform(data: T): T;\n close(): void;\n response: R;\n};\n\n/**\n * Pump is an asynchronous stream processing pipeline with fluent operators.\n * It provides a comprehensive set of operations for transforming, filtering, batching,\n * combining, and consuming stream data.\n *\n * The Pump class follows a builder pattern where each operation returns a new Pump instance,\n * allowing for chaining of operations to build complex stream processing pipelines.\n *\n * @template T The type of data contained in the stream\n */\nexport class Pump<T> {\n constructor(private readonly src: MessageStream<T>) {}\n\n /**\n * Wrap an existing AsyncIterable or Readable stream into a Pump\n *\n * @template U The type of data in the source stream\n * @param source The source stream to convert to a Pump (AsyncIterable, ReadableStream, or NodeJS.ReadableStream)\n * @returns A new Pump instance that wraps the source\n */\n static from<U>(source: Source<U>): Pump<U> {\n async function* gen(): AsyncGenerator<StreamChunk<U>> {\n let seq = 0;\n\n // Type guard functions to narrow the type\n function isAsyncIterable(obj: Source<U>): obj is AsyncIterable<U> {\n return Symbol.asyncIterator in obj;\n }\n\n function isWebReadableStream(obj: Source<U>): obj is ReadableStream {\n return 'getReader' in obj && typeof obj.getReader === 'function';\n }\n\n function isNodeReadableStream(\n obj: Source<U>\n ): obj is NodeJS.ReadableStream {\n return (\n 'pipe' in obj &&\n 'on' in obj &&\n typeof obj.pipe === 'function' &&\n typeof obj.on === 'function'\n );\n }\n\n if (isAsyncIterable(source)) {\n // Handle AsyncIterable\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (true) {\n const result = await iterator.next();\n if (result.done) break;\n yield {\n sequence: seq++,\n data: result.value,\n done: false,\n };\n }\n } finally {\n // No need to clean up AsyncIterator\n }\n } else if (isWebReadableStream(source)) {\n // Handle Web API ReadableStream\n const reader = source.getReader();\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) break;\n yield {\n sequence: seq++,\n data: result.value as U,\n done: false,\n };\n }\n } finally {\n reader.releaseLock();\n }\n } else if (isNodeReadableStream(source)) {\n // Handle Node.js ReadableStream\n try {\n // Convert Node stream to an AsyncIterable\n for await (const chunk of source) {\n yield {\n sequence: seq++,\n data: chunk as U,\n done: false,\n };\n }\n } catch (error) {\n console.error('Error reading from Node.js stream:', error);\n throw error;\n }\n }\n\n // final done signal\n yield { sequence: seq, data: undefined as unknown as U, done: true };\n }\n return new Pump<U>(gen()) as Pump<U>;\n }\n\n /**\n * Sync or async map over the data portion of each chunk\n *\n * @template U The output type after transformation\n * @param fn The mapping function that transforms each chunk\n * @returns A new Pump instance with the transformed data\n */\n map<U>(fn: (data: T) => U | Promise<U>): Pump<U> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<U>> {\n for await (const { sequence, data, done } of this.src) {\n if (done) {\n const out = data !== undefined ? await fn(data) : undefined;\n yield { sequence, data: out as unknown as U, done };\n break;\n }\n\n const out = await fn(data);\n yield { sequence, data: out, done };\n }\n }\n return new Pump<U>(gen.call(this));\n }\n\n /**\n * Stateful map allows processing stream chunks with a persistent context object.\n *\n * The context is initialized when the first chunk arrives and can be updated with each chunk.\n * This is useful for maintaining state across the stream processing.\n *\n * If you plan to use sockets you should rather opt for asyncStatefulMap.\n *\n * The pipe closes only after all processing is complete, including any final operations in onClose.\n *\n * TODO: Un-tested\n *\n * @param handlers Object containing callback functions for stream processing\n * @param handlers.onFirstChunk Function called when the first chunk arrives, initializes the context\n * @param handlers.onChunk Function called for each subsequent chunk, updates the context\n * @param handlers.onClose Optional function called when the stream closes, allows final processing\n * @returns A new Pump instance with transformed data\n */\n statefulMap<Context, U = T>(handlers: {\n onFirstChunk(\n chunk: T,\n yieldData: (data: U) => void\n ): Context | Promise<Context>;\n onChunk(\n chunk: T,\n context: Context,\n yieldData: (data: U) => void\n ): Context | Promise<Context>;\n onClose?(\n lastChunk: T | undefined,\n context: Context,\n yieldData: (data: U) => void\n ): void | Promise<void>;\n }): Pump<U> {\n const { src } = this;\n\n const gen = async function* (): AsyncGenerator<StreamChunk<U>> {\n let context: Context | undefined;\n let initialized = false;\n let lastChunk: T | undefined;\n let seq = 0;\n\n const queue: U[] = [];\n const yieldData = (data: U): void => {\n queue.push(data);\n };\n\n // <- here ->\n\n for await (const { data, done } of src) {\n if (done) {\n if (context && handlers.onClose) {\n await handlers.onClose(lastChunk, context, yieldData);\n }\n\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n\n yield {\n sequence: seq++,\n data: undefined as unknown as U,\n done: true,\n };\n break;\n }\n if (!initialized) {\n context = await handlers.onFirstChunk(data, yieldData);\n initialized = true;\n } else if (context) {\n context = await handlers.onChunk(data, context, yieldData);\n }\n\n lastChunk = data;\n\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n }\n };\n\n return new Pump<U>(gen());\n }\n\n /**\n * Async map means that each incoming chunk is causing an async operation that when it completes\n * should yield a new chunk.\n * The pipe closes only after you unlock the pipe by using the unlockCloseEvent callback.\n *\n * Stateful refers to the fact that you can create your own small context object that is passed in the subsequent callbacks.\n * This allows you to keep track of things like a socket connection.\n *\n * Why is this nice? Well if you use things like a socket the pipe might have received the close event,\n * before you got any or all of your socket responses. Sockets don't fit into the standard promise pattern,\n * which makes it harder to wait for them.\n *\n * TODO: Un-tested\n *\n * @param handlers Object containing callback functions for stream processing\n * @param handlers.onFirstChunk Function called when the first chunk arrives, initializes the context\n * @param handlers.onChunk Function called for each subsequent chunk, updates the context\n * @param handlers.onClose Optional function called when the stream closes, allows final processing\n * @returns A new Pump instance with transformed data\n */\n asyncStatefulMap<Context, U = T>(handlers: {\n onFirstChunk(\n chunk: T,\n yieldData: (data: U) => void,\n unlockCloseEvent: () => void\n ): Context | Promise<Context>;\n onChunk(\n chunk: T,\n context: Context,\n yieldData: (data: U) => void,\n unlockCloseEvent: () => void\n ): Context | Promise<Context>;\n onClose?(\n lastChunk: T | undefined,\n context: Context,\n yieldData: (data: U) => void,\n unlockCloseEvent: () => void\n ): void | Promise<void>;\n }): Pump<U> {\n const { src } = this;\n\n const gen = async function* (): AsyncGenerator<StreamChunk<U>> {\n let context: Context | undefined;\n let initialized = false;\n let lastChunk: T | undefined;\n let seq = 0;\n let lockedCloseEvent = true;\n\n const queue: U[] = [];\n const yieldData = (data: U): void => {\n queue.push(data);\n };\n const unlockCloseEvent = (): void => {\n lockedCloseEvent = false;\n };\n\n for await (const { data, done } of src) {\n if (done) {\n if (context && handlers.onClose) {\n await handlers.onClose(\n lastChunk,\n context,\n yieldData,\n unlockCloseEvent\n );\n }\n\n const timestamp = Date.now();\n // wait until the pipe is unlocked\n while (lockedCloseEvent && Date.now() - timestamp < 10_000) {\n // First emit all data in the queue\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n // put on top of event loop / call stack\n await new Promise((resolve) => setTimeout(resolve, 5));\n }\n\n // First emit all data in the queue\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n\n yield {\n sequence: seq++,\n data: undefined as unknown as U,\n done: true,\n };\n break;\n }\n if (!initialized) {\n context = await handlers.onFirstChunk(\n data,\n yieldData,\n unlockCloseEvent\n );\n initialized = true;\n } else if (context) {\n context = await handlers.onChunk(\n data,\n context,\n yieldData,\n unlockCloseEvent\n );\n }\n\n lastChunk = data;\n\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n }\n };\n\n return new Pump<U>(gen());\n }\n\n /**\n * Filter items based on a predicate\n *\n * @param predicate A function that determines whether to keep each chunk\n * @returns A new Pump instance containing only chunks that passed the predicate\n */\n filter(predicate: (data: T) => boolean | Promise<boolean>): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n for await (const { sequence, data, done } of this.src) {\n if (done) {\n yield { sequence, data, done: true };\n break;\n }\n\n const keep = await predicate(data);\n if (keep) {\n yield { sequence, data, done: false };\n }\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Bundles (accumulates) chunks together based on a condition rather than a fixed size.\n *\n * This is useful when you need to group chunks dynamically based on their content or other criteria.\n *\n * Example: Bundling text chunks with a maximum character limit\n *\n * Input chunks: [\"Hello\", \" this\", \" is\", \" a few\", \" chunks\", \" of text\"]\n * With max size of 10 characters:\n * - First bundle: [\"Hello\", \" this\"] (10 chars)\n * - Second bundle: [\" is\", \" a few\"] (8 chars)\n * - Third bundle: [\" chunks\", \" of text\"] (13 chars)\n *\n * @param closeBundleCondition - Function that determines when to close the current bundle\n * Returns true when the current bundle should be emitted\n * Parameters:\n * - chunk: The current chunk being processed\n * - accumulatedChunks: Array of chunks in the current bundle\n *\n * @returns A pump that emits arrays of bundled items\n */\n bundle(\n closeBundleCondition: (\n chunk: T,\n accumulatedChunks: Array<T>\n ) => boolean | Promise<boolean>\n ): Pump<Array<T>> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<Array<T>>> {\n let buffer: Array<T> = [];\n let lastSequence = 0;\n\n for await (const { sequence, data, done } of this.src) {\n lastSequence = sequence;\n\n if (done) {\n // Emit any remaining items in the buffer when the stream ends\n if (buffer.length > 0) {\n yield { sequence, data: [...buffer], done: false };\n }\n // Emit the termination signal\n yield {\n sequence: lastSequence,\n data: undefined as unknown as Array<T>,\n done: true,\n };\n break;\n }\n\n const shouldClose = await closeBundleCondition(data, buffer);\n buffer.push(data);\n\n if (shouldClose) {\n yield {\n sequence: lastSequence,\n data: [...buffer],\n done: false,\n };\n buffer = [];\n }\n }\n }\n return new Pump<Array<T>>(gen.call(this));\n }\n\n /**\n * Tap into each chunk without altering it\n *\n * @param fn A function that receives each chunk but doesn't affect the stream\n * @returns The same pump instance with unmodified data\n */\n onChunk(fn: (chunk: T) => void | Promise<void>): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n for await (const chunk of this.src) {\n if (chunk.data === undefined && chunk.done) {\n // Yield early since we don't need to tap into a closing signal (unless it contains data)\n yield chunk;\n }\n\n await fn(chunk.data);\n yield chunk;\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Collect all chunks in the stream and run a callback when the stream is done.\n * The callback receives an array of all chunks that passed through.\n *\n * This is useful for analytics, logging, or processing the complete stream history\n * after all chunks have been received.\n *\n * @param fn - Callback function that receives the array of all chunks when the stream is complete\n * @returns The same pump, for chaining\n */\n onClose(fn: (history: T[]) => void | Promise<void>): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n const history: T[] = [];\n\n for await (const chunk of this.src) {\n // Add non-done chunks to history\n if (chunk.data !== undefined) {\n history.push(chunk.data);\n }\n\n // If we've reached the end, run the callback\n if (chunk.done) {\n await fn(history);\n }\n\n // Pass through the chunk unchanged\n yield chunk;\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Batch `n` chunks into arrays before emitting\n *\n * @param n The number of chunks to batch together\n * @returns A new Pump instance that emits arrays of batched chunks\n */\n batch(n: number): Pump<Array<T>> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<Array<T>>> {\n let buffer: StreamChunk<T>[] = [];\n\n for await (const chunk of this.src) {\n if (chunk.done) {\n // Termination signal edge case handling\n if (chunk.data === undefined) {\n // Flush the rest\n yield {\n sequence: buffer[0].sequence,\n data: buffer.map((c) => c.data),\n done: false,\n };\n\n // and then emit the termination signal\n yield {\n sequence: chunk.sequence,\n data: undefined as unknown as Array<T>,\n done: true,\n };\n buffer = [];\n } else {\n // in that case the termination signal contains data\n // so we need to emit this as a closing singal with the rest of the buffer\n buffer.push(chunk);\n yield {\n sequence: buffer[0].sequence,\n data: buffer.map((c) => c.data),\n done: true,\n };\n }\n\n break;\n }\n\n // Normal case\n\n buffer.push(chunk);\n\n if (buffer.length === n) {\n yield {\n sequence: buffer[0].sequence,\n data: buffer.map((c) => c.data),\n done: chunk.done,\n };\n buffer = [];\n }\n }\n }\n return new Pump<Array<T>>(gen.call(this));\n }\n\n /**\n * If you want to prevent chunk starvation, you can buffer the chunks.\n * Chunks will not be bundled into arrays or object but kept as is,\n * but the pipeline will not progress at that segment until the buffer is filled up.\n * Once a buffer is filled up it will drain and never buffer again.\n *\n * @param n The number of chunks to buffer before processing continues\n * @returns A new Pump instance with buffering behavior\n */\n buffer(n: number): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n let buffer: StreamChunk<T>[] = [];\n let bufferFilled = false;\n\n for await (const chunk of this.src) {\n if (!bufferFilled) {\n if (!chunk.done) {\n buffer.push(chunk);\n }\n\n // If buffer is filled or we've reached the end of the stream\n if (buffer.length >= n || chunk.done) {\n bufferFilled = true;\n // Yield all buffered chunks\n for (const bufferedChunk of buffer) {\n yield bufferedChunk;\n }\n if (chunk.done) {\n yield {\n sequence: chunk.sequence,\n data: undefined as unknown as T,\n done: true,\n };\n break;\n }\n buffer = [];\n }\n } else {\n // After buffer is filled, just pass chunks through\n yield chunk;\n }\n }\n\n // Yield any remaining chunks in the buffer\n for (const bufferedChunk of buffer) {\n yield bufferedChunk;\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Rechunk the stream: transform one chunk into zero, one, or many output chunks.\n * The handler function receives the current buffer of chunks, a push function to emit new chunks,\n * and a flag indicating if this is the last chunk in the stream.\n *\n * @param handler Function that transforms chunks and pushes new ones\n * @returns A new Pump instance with rechunked data\n */\n rechunk(\n handler: (params: {\n buffer: T[];\n push: (chunk: T) => void;\n lastChunk: boolean;\n setBuffer: (buffer: T[]) => void;\n }) => void | Promise<void>\n ): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n let buffer: Array<T> = [];\n let seq = 0;\n const pending: Array<T> = [];\n\n const push = (chunk: T): void => {\n pending.push(chunk);\n };\n\n for await (const { data, done } of this.src) {\n if (!done) {\n if (data !== undefined) {\n buffer.push(data);\n }\n await handler({\n buffer,\n push,\n lastChunk: false,\n setBuffer: (b: T[]) => {\n buffer = b;\n },\n });\n } else {\n await handler({\n buffer,\n push,\n lastChunk: true,\n setBuffer: (b: T[]) => {\n buffer = b;\n },\n });\n }\n\n while (pending.length > 0) {\n const out = pending.shift()!;\n yield { sequence: seq++, data: out, done: false };\n }\n\n if (done) {\n break;\n }\n }\n\n yield { sequence: seq, data: undefined as unknown as T, done: true };\n }\n\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Emit sliding windows of the last `size` items with step `step`.\n * Each window is an array [current, previous1, ..., previous(size-1)].\n * Optionally, map each window through a function.\n *\n * | Step | Window | Resulting Window |\n * |------|--------|------------------|\n * | 1 | ▪︎▪︎[▪︎▫︎▫︎] | ▪︎▫︎▫︎ |\n * | 2 | ▪︎[▪︎▪︎▫︎] | ▪︎▪︎▫︎ |\n * | 3 | [▪︎▪︎▪︎] | ▪︎▪︎▪︎ |\n * | 4 | [▫︎▪︎▪︎] | ▫︎▪︎▪︎ |\n * | 5 | [▫︎▫︎▪︎] | ▫︎▫︎▪ |\n *\n * @param size The size of each window\n * @param step The number of items to move between windows\n * @returns A Pump that emits arrays representing sliding windows\n */\n slidingWindow(size: number, step: number): Pump<Array<T | undefined>>;\n /**\n * Emit sliding windows of the last `size` items with step `step`,\n * and map each window using the provided function.\n *\n * @template N The size type parameter (extends number)\n * @template U The output type after window transformation\n * @param size The size of each window\n * @param step The number of items to move between windows\n * @param fn A function to transform each window\n * @returns A Pump that emits transformed sliding windows\n */\n slidingWindow<N extends number, U>(\n size: N,\n step: number,\n fn: (window: Array<T | undefined>) => U | Promise<U>\n ): Pump<U>;\n slidingWindow<U>(\n size: number,\n step: number,\n fn?: (window: Array<T | undefined>) => U | Promise<U>\n ): Pump<Array<T | undefined>> | Pump<U> {\n async function* gen(\n this: Pump<T>\n ): AsyncGenerator<StreamChunk<Array<T | undefined>>> {\n const history: Array<T> = [];\n let offset = 0;\n let lastSeq = 0;\n\n function buildWindow(\n _offset: number,\n _size: number,\n _history: Array<T>\n ): Array<T | undefined> {\n const window: Array<T | undefined> = Array(_size).fill(undefined);\n let windowIndex = 0;\n\n for (let i = _offset; i > _offset - _size; i -= step) {\n if (i >= history.length) {\n windowIndex++;\n // we can skip this since we are filling the blank spots with undefined\n continue;\n }\n\n if (i < 0) {\n break;\n }\n\n window[windowIndex] = _history[i]; // the window follows the analoy so its filled reversed from the graphic\n windowIndex++;\n }\n\n return window;\n }\n\n for await (const { sequence, data, done } of this.src) {\n if (done) {\n // if we are done that means we are not receiving any more signals to push the window\n // so we have to emit the last window steps\n // [▪︎▪︎▫︎]\n // [▪︎▫︎▫︎]\n for (let i = 0; i < size - 1; i++) {\n const window = buildWindow(offset + i, size, history);\n yield { sequence: lastSeq, data: window, done: false };\n }\n\n if (data === undefined) {\n // final done signal\n yield {\n sequence: lastSeq,\n data: undefined as unknown as Array<T>,\n done: true,\n };\n } else {\n // final done signal\n yield {\n sequence: lastSeq,\n data: [\n history[history.length - 2] ?? undefined,\n history[history.length - 3] ?? undefined,\n history[history.length - 1],\n ],\n done: true,\n };\n }\n break;\n }\n\n lastSeq = sequence;\n history.push(data);\n\n // the rolling window goes from the oldest to the newest and pushes it self\n // with a step length. The analogy of the pipe shifts the window from right to left\n // but the array appends to the end. So in this implementation we are shifting from left to right.\n\n // lets calculate the window indexes\n // [▫︎▫︎▪︎]▪︎▪︎\n // [▫︎▪︎▪︎]▪︎\n // [▪︎▪︎▪︎]\n // [▪︎▪︎▫︎] <- this case is handled above\n // [▪︎▫︎▫︎] <- this case is handled above\n const window = buildWindow(offset, size, history);\n\n yield { sequence, data: window, done: false };\n offset++;\n }\n }\n const base = new Pump<Array<T | undefined>>(gen.call(this));\n // If fn is provided, map over the window, otherwise return the window as is\n return fn\n ? base.map(fn as (window: Array<T | undefined>) => U)\n : (base as Pump<Array<T | undefined>>);\n }\n\n /**\n * Sequentially flatten inner stream sources emitted by the pipeline.\n * Works with any Source type (AsyncIterable or ReadableStream).\n * This method is only available when the current Pump contains Source elements.\n *\n * @template U The type of data in the inner streams\n * @template F The type of inner stream source (extends Source<U>)\n * @returns A Pump instance with flattened stream data\n */\n sequenceStreams<U, F extends Source<U>>(this: Pump<F>): Pump<U> {\n async function* gen(this: Pump<F>): AsyncGenerator<StreamChunk<U>> {\n let seq = 0;\n\n for await (const { data: innerSource, done: outerDone } of this.src) {\n if (outerDone) break;\n\n // Convert the inner source to a pump first\n const innerPump = Pump.from(innerSource as unknown as Source<U>);\n\n // Then extract all items from it\n for await (const { data, done } of innerPump.src) {\n if (done) break;\n yield { sequence: seq++, data: data as U, done: false };\n }\n }\n\n yield { sequence: seq, data: undefined as unknown as U, done: true };\n }\n return new Pump<U>(gen.call(this));\n }\n\n /**\n * Fork the stream: two independent Pump<T> consumers\n * Both resulting Pumps will receive the same data, allowing for divergent processing paths.\n *\n * @returns An array containing two independent Pump instances with the same source data\n */\n fork(): [Pump<T>, Pump<T>] {\n const buffers: StreamChunk<T>[][] = [[], []];\n let done = false;\n const srcIter = this.src[Symbol.asyncIterator]();\n\n async function fill(): Promise<void> {\n const { value, done: streamDone } = await srcIter.next();\n if (streamDone) {\n done = true;\n return;\n }\n buffers.forEach((q) => q.push(value));\n if (value.done) done = true;\n }\n\n function makeStream(buf: StreamChunk<T>[]): MessageStream<T> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<StreamChunk<T>> {\n return {\n async next(): Promise<IteratorResult<StreamChunk<T>>> {\n while (buf.length === 0 && !done) {\n await fill();\n }\n if (buf.length === 0)\n return {\n done: true,\n value: undefined as unknown as StreamChunk<T>,\n };\n return { done: false, value: buf.shift()! };\n },\n };\n },\n };\n }\n\n return [new Pump(makeStream(buffers[0])), new Pump(makeStream(buffers[1]))];\n }\n\n /**\n * Drain the pipeline, consuming all chunks.\n * Returns a Promise that resolves when all chunks have been consumed.\n *\n * @returns A Promise that resolves when all chunks have been consumed\n */\n drain(): Promise<void> {\n return (async (): Promise<void> => {\n for await (const { done } of this.src) {\n if (done) break;\n }\n })();\n }\n\n /**\n * Drain the pipeline to a StreamTransformer.\n * Applies transform() to each data chunk, then closes the transformer,\n * and returns its response (which can be of any type defined by the transformer).\n *\n * Example with httpStreamResponse:\n * ```\n * const { transform, response, close } = httpStreamResponse(options);\n * return Pump.from(messageStream).drainTo({ transform, close, response });\n * ```\n *\n * @template U The type of data expected by the transformer (extends T)\n * @template R The response type produced by the transformer\n * @param transformer The StreamTransformer to drain to\n * @returns The response from the transformer\n */\n drainTo<U extends T, R>(transformer: StreamTransformer<U, R>): R {\n (async (): Promise<void> => {\n for await (const { data, done } of this.src) {\n if (done) break;\n transformer.transform(data as unknown as U);\n }\n transformer.close();\n })();\n return transformer.response;\n }\n}\n\n// ----------------------------------------------------------\n// Example usage in Next.js App Router (e.g. app/api/stream/route.ts)\n//\n// import { NextRequest } from 'next/server';\n// import { Pump } from '@m4trix/core/stream';\n// import { /*...*/ } from '@/lib';\n\n// export async function POST(req: NextRequest) {\n// // Process the incoming audio request\n// const formData = await req.formData();\n// const transcript = await transcribeFormData(formData);\n// const agentStream = await getAgentResponse(transcript);\n\n// // Process and return the stream\n// return await Pump.from(agentStream)\n// .filter(shouldChunkBeStreamed)\n// .map(messageToText)\n// .bundle(intoChunksOfMinLength(40))\n// .map((text) => text.join(\"\")) // convert array of strings to string\n// .rechunk(ensureFullWords)\n// .rechunk(fixBrokenWords)\n// .onClose(handleCompletedAgentResponse)\n// .slidingWindow(10, 1)\n// .filter(filterOutIrrelevantWindows)\n// .buffer(5)\n// .map(textToSpeech)\n// .sequenceStreams()\n// .drainTo(httpStreamResponse());\n// }\n","import { StreamTransformer } from '../..';\n\nexport interface HttpStreamOptions<T> {\n /** HTTP ResponseInit (status, headers, etc.) */\n init?: ResponseInit;\n /** Encode each chunk of type T into bytes or string */\n encoder?: (data: T) => Uint8Array | string;\n}\n\n/**\n * Create a streaming HTTP response transformer.\n * Returns an object with:\n * - transform: function to write each chunk into the response\n * - response: the Fetch API Response ready to return\n * - close: function to close the stream when done\n *\n * Usage in a Next.js route:\n * ```\n * // With the new drainTo API:\n * const transformer = httpStreamResponse(options);\n * return Pump.from(messageStream).drainTo(transformer);\n *\n * // Or with manual control:\n * const { transform, response, close } = httpStreamResponse(options);\n * await Pump.from(messageStream).map(transform).drain();\n * close();\n * return response;\n * ```\n */\nexport function httpStreamResponse<T>(\n options: HttpStreamOptions<T> = {}\n): StreamTransformer<T, Response> {\n const { init, encoder } = options;\n const encodeFn =\n encoder ??\n ((d: T): Uint8Array | string => {\n if (d instanceof Uint8Array) return d;\n if (typeof d === 'string') return d;\n return JSON.stringify(d);\n });\n\n // Create a transform stream of Uint8Array\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n const response = new Response(readable, init);\n\n const transform = (chunk: T): T => {\n const encoded = encodeFn(chunk);\n const bytes =\n typeof encoded === 'string' ? new TextEncoder().encode(encoded) : encoded;\n writer.write(bytes);\n return chunk;\n };\n\n const close = (): void => {\n writer.close();\n };\n\n return { transform, response, close };\n}\n","/**\n * A helper to be used with Pump.rechunk that ensures full word chunks.\n * Aggregates incoming chunks and emits only when a full word boundary is reached.\n */\nexport async function ensureFullWords({\n buffer,\n push,\n lastChunk,\n}: {\n buffer: string[];\n push: (chunk: string) => void;\n lastChunk: boolean;\n}): Promise<void> {\n const combined = buffer.join('');\n const lastBoundary = Math.max(\n combined.lastIndexOf(' '),\n combined.lastIndexOf('\\n'),\n combined.lastIndexOf('\\t')\n );\n\n if (lastBoundary !== -1 || lastChunk) {\n const emitPart =\n lastBoundary !== -1 ? combined.slice(0, lastBoundary + 1) : combined;\n const leftoverPart =\n lastBoundary !== -1 ? combined.slice(lastBoundary + 1) : '';\n\n if (emitPart.trim().length > 0) {\n push(emitPart);\n }\n\n buffer.length = 0;\n if (leftoverPart.length > 0) {\n buffer.push(leftoverPart);\n }\n }\n}\n","import { Socket } from 'socket.io';\nimport { Hooks, SetupSocketHandlersParams } from './socket-factory-types';\n\nexport class SocketIoFactory {\n private socket: Socket;\n private prefix: string;\n private hooks: Hooks<Socket>;\n\n private constructor(socket: Socket, prefix: string, hooks: Hooks<Socket>) {\n this.socket = socket;\n this.prefix = prefix;\n this.hooks = hooks;\n }\n\n static setupSocketHandlers({\n enableVoiceEvents,\n enableChatEvents,\n enableTranscriptEvents,\n prefix = '',\n socket,\n hooks,\n }: SetupSocketHandlersParams<\n Socket,\n {\n socket: Socket;\n }\n >): void {\n // Adapter will override the hooks\n\n const factory = new SocketIoFactory(socket, prefix, hooks!);\n if (enableVoiceEvents) {\n factory.setupVoiceEvents();\n }\n\n if (enableChatEvents) {\n factory.setupChatEvents(socket);\n }\n\n if (enableTranscriptEvents) {\n factory.setupTranscriptEvents(socket);\n }\n }\n\n private setupVoiceEvents(): void {\n const {\n onVoiceInputFile,\n onVoiceInputChunk,\n onVoiceInputCommit,\n onVoiceOutputDelta,\n onVoiceOutputCommit,\n onVoiceOutputFile,\n onVoiceOutputTranscriptDelta,\n onVoiceOutputTranscriptFull,\n } = this.hooks;\n\n const prefix = this.prefixEvent;\n\n if (onVoiceInputFile) {\n this.socket.on(prefix('voice:input_file'), onVoiceInputFile);\n }\n\n if (onVoiceInputChunk) {\n this.socket.on(prefix('voice:input_chunk'), onVoiceInputChunk);\n }\n\n if (onVoiceInputCommit) {\n this.socket.on(prefix('voice:input_commit'), onVoiceInputCommit);\n }\n\n if (onVoiceOutputDelta) {\n this.socket.on(prefix('voice:output_delta'), onVoiceOutputDelta);\n }\n\n if (onVoiceOutputCommit) {\n this.socket.on(prefix('voice:output_commit'), onVoiceOutputCommit);\n }\n\n if (onVoiceOutputFile) {\n this.socket.on(prefix('voice:output_file'), onVoiceOutputFile);\n }\n\n if (onVoiceOutputTranscriptDelta) {\n this.socket.on(\n prefix('voice:output_transcript_delta'),\n onVoiceOutputTranscriptDelta\n );\n }\n\n if (onVoiceOutputTranscriptFull) {\n this.socket.on(\n prefix('voice:output_transcript_full'),\n onVoiceOutputTranscriptFull\n );\n }\n }\n\n private setupChatEvents(_socket: Socket): void {\n // TODO: Implement chat event handler\n }\n\n private setupTranscriptEvents(_socket: Socket): void {\n // TODO: Implement transcript event handlers\n }\n\n private prefixEvent(event: string): string {\n return this.prefix ? `${this.prefix}:${event}` : event;\n }\n}\n","import { BaseMessage, AIMessage, ToolMessage } from '@langchain/core/messages';\nimport { Effect, pipe } from 'effect';\nimport {\n MessageFilter,\n MessageFilterType,\n typeOnFilter,\n} from './message-filter';\nimport { FormatType, typeOnFormatter } from './formatter';\n\n/**\n * # Transform Messages\n * In order to manage the context size often you want to slice messages or only pass certain types of messages.\n * This class is a helper to do that.\n *\n * ## Example\n * ```ts\n * const messages = [\n * new HumanMessage('Hello, how are you?'),\n * new AIMessage('I am good, thank you!'),\n * ];\n *\n * const transformedMessages = TransformMessages.from(messages).filter(HumanAndAI).last(10).format(FormatType.Concise);\n *\n * ```\n */\n\nclass TransformMessages {\n private effect: Effect.Effect<Array<BaseMessage>, never, never>;\n\n private constructor(effect: Effect.Effect<Array<BaseMessage>, never, never>) {\n this.effect = effect;\n }\n\n /**\n * Create a new TransformMessages from an array of messages.\n */\n static from(messages: Array<BaseMessage>): TransformMessages {\n return new TransformMessages(Effect.succeed(messages));\n }\n\n /**\n * Filter messages based on a predicate function\n */\n filter(\n predicate: MessageFilter | MessageFilterType,\n tags?: Array<string>\n ): TransformMessages {\n let finalPredicate: MessageFilter;\n if (typeof predicate === 'string') {\n finalPredicate = typeOnFilter[predicate];\n } else {\n finalPredicate = predicate;\n }\n\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) =>\n messages.filter((message) => finalPredicate(message, tags))\n )\n )\n );\n }\n\n /**\n * Take only the last n messages, but safely.\n * Tool calls should not be separated from the last human message.\n * Ensures all tool call conversations in the last n messages are complete.\n */\n safelyTakeLast(\n n: number,\n pruneAfterNOvershootingMessages: number = 0\n ): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => {\n const total = messages.length;\n if (n <= 0 || total === 0) return [];\n\n // Start with the last n messages\n const start = Math.max(0, total - n);\n const end = total;\n const lastSlice = messages.slice(start, end);\n\n // due to the fact that the calling AI message needs to be adjecent to the succeeding tool call message\n // we just need to check the last n messages for tool call ids\n\n // Check the first message if it is a tool call message\n // if it is iterate backwards until we find the AI message\n if (\n lastSlice[0] instanceof ToolMessage &&\n lastSlice[0].tool_call_id\n ) {\n let messagesToInclude: Array<BaseMessage> = [];\n const remainingMessages = messages.slice(0, start);\n for (let i = remainingMessages.length - 1; i >= 0; i--) {\n const msg = remainingMessages[i];\n if (\n pruneAfterNOvershootingMessages > 0 &&\n messagesToInclude.length - 1 >= pruneAfterNOvershootingMessages\n ) {\n messagesToInclude = [];\n // Return the slice but remove all the tool call messages that are at the beginning of the slice\n const filteredSlice: Array<BaseMessage> = [];\n let foundFirstNonToolMessage = false;\n for (let i = 0; i < lastSlice.length; i++) {\n const msg = lastSlice[i];\n if (msg instanceof ToolMessage) {\n if (foundFirstNonToolMessage) {\n filteredSlice.push(msg);\n }\n } else {\n foundFirstNonToolMessage = true;\n filteredSlice.push(msg);\n }\n }\n return filteredSlice;\n }\n if (msg instanceof AIMessage && Array.isArray(msg.tool_calls)) {\n messagesToInclude.push(msg);\n break;\n } else if (msg instanceof ToolMessage) {\n messagesToInclude.push(msg);\n } else {\n // This should not happen messages invalid\n throw new Error(\n 'Messages array invalid no adjacent AI message found'\n );\n }\n }\n return [...messagesToInclude.reverse(), ...lastSlice];\n } else {\n return lastSlice;\n }\n })\n )\n );\n }\n\n /**\n * Take only the last n messages\n */\n last(n: number): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => messages.slice(-n))\n )\n );\n }\n\n /**\n * Take only the first n messages\n */\n first(n: number): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => messages.slice(0, n))\n )\n );\n }\n\n /**\n * Skip the first n messages\n */\n skip(n: number): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => messages.slice(n))\n )\n );\n }\n\n /**\n * Reverse the order of messages\n */\n reverse(): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => [...messages].reverse())\n )\n );\n }\n\n /**\n * Map over messages with a transformation function\n */\n map<T extends BaseMessage>(\n fn: (message: BaseMessage) => T\n ): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => messages.map(fn))\n )\n );\n }\n\n /**\n * Format messages according to the specified format type\n */\n format(formatType: FormatType): string {\n const result = Effect.runSync(\n pipe(\n this.effect,\n Effect.map((messages) => {\n if (formatType === FormatType.JSON) {\n return JSON.stringify(messages, null, 2);\n }\n const formatter = typeOnFormatter[formatType];\n return formatter(messages);\n })\n )\n );\n return result;\n }\n\n // Sink methods\n\n /**\n * Convert to array - runs the effect and returns the result\n return pipe(\n this.effect,\n Effect.map((messages) => {\n if (formatType === FormatType.JSON) {\n return JSON.stringify(messages, null, 2);\n }\n\n const formatter = typeOnFormatter[formatType];\n return formatter(messages);\n })\n );\n }\n\n // Sink methods\n\n /**\n * Convert to array - runs the effect and returns the result\n */\n toArray(): Array<BaseMessage> {\n return Effect.runSync(this.effect);\n }\n\n /**\n * Convert to string - runs the effect and returns JSON string\n */\n toString(): string {\n const result = Effect.runSync(\n pipe(\n this.effect,\n Effect.map((messages) => JSON.stringify(messages, null, 2))\n )\n );\n return result;\n }\n\n /**\n * Get the count of messages\n */\n count(): number {\n const result = Effect.runSync(\n pipe(\n this.effect,\n Effect.map((messages) => messages.length)\n )\n );\n return result;\n }\n}\n\nexport { TransformMessages };\n","import { BaseMessage, HumanMessage, AIMessage } from '@langchain/core/messages';\n\n// Type for message filters\nexport type MessageFilter = (\n message: BaseMessage,\n tags?: Array<string>\n) => boolean;\n// Predefined filters\nconst humanAndAI: MessageFilter = (message) =>\n message instanceof HumanMessage || message instanceof AIMessage;\nconst humanOnly: MessageFilter = (message) => message instanceof HumanMessage;\nconst aiOnly: MessageFilter = (message) => message instanceof AIMessage;\n\nconst includingTags: MessageFilter = (message, tags) => {\n if (tags) {\n return tags.some((tag) =>\n Array.isArray(message.additional_kwargs?.tags)\n ? message.additional_kwargs?.tags.includes(tag)\n : false\n );\n }\n return true;\n};\n\nconst excludingTags: MessageFilter = (message, tags) => {\n if (tags) {\n return !tags.some((tag) =>\n Array.isArray(message.additional_kwargs?.tags)\n ? message.additional_kwargs?.tags.includes(tag)\n : false\n );\n }\n return true;\n};\n\nexport enum MessageFilterType {\n HumanAndAI = 'HumanAndAI',\n HumanOnly = 'HumanOnly',\n AIOnly = 'AIOnly',\n IncludingTags = 'IncludingTags',\n ExcludingTags = 'ExcludingTags',\n}\nexport const typeOnFilter = {\n [MessageFilterType.HumanAndAI]: humanAndAI,\n [MessageFilterType.HumanOnly]: humanOnly,\n [MessageFilterType.AIOnly]: aiOnly,\n [MessageFilterType.IncludingTags]: includingTags,\n [MessageFilterType.ExcludingTags]: excludingTags,\n};\n","import { AIMessage, BaseMessage } from '@langchain/core/messages';\n\n// Format types\nexport enum FormatType {\n Concise = 'concise',\n Verbose = 'verbose',\n RedactAi = 'redact-ai',\n RedactHuman = 'redact-human',\n JSON = 'json',\n}\n\n/**\n * Formats messages in a concise markdown format with alternating AI and Human prefixes.\n *\n * ### Example\n * ```markdown\n * AI: Hello, how are you?\n * Human: I am good, thank you!\n * AI: What is your name?\n * Human: My name is John.\n * AI: What is your favorite color?\n * Human: My favorite color is blue.\n * AI: What is your favorite food?\n * Human: My favorite food is pizza.\n * ```\n */\nfunction concise(messages: Array<BaseMessage>): string {\n return messages\n .map((message) => {\n const prefix = message instanceof AIMessage ? 'AI' : 'Human';\n return `${prefix}: ${message.content}`;\n })\n .join('\\n');\n}\n\n/**\n * Formats messages in a verbose markdown format with alternating AI and Human prefixes.\n *\n * ### Example\n * ```markdown\n * AI:\n * Hello, how are you?\n * -------------------\n * Human:\n * I am good, thank you!\n * -------------------\n * AI:\n * What is your name?\n * -------------------\n * Human:\n * My name is John.\n * ```\n */\nfunction verbose(messages: Array<BaseMessage>): string {\n return messages\n .map((message) => {\n const prefix = message instanceof AIMessage ? 'AI' : 'Human';\n return `${prefix}:\\n${message.content}`;\n })\n .join('\\n-------------------\\n');\n}\n\n/**\n * Formats messages in a concise markdown format, redacting AI messages with [...]\n *\n * ### Example\n * ```markdown\n * AI: [...]\n * Human: Hello, how are you?\n * AI: [...]\n * Human: I am good, thank you!\n * AI: [...]\n * Human: What is your name?\n * AI: [...]\n * Human: My name is John.\n * AI: [...]\n * ```\n */\nfunction redactAi(messages: Array<BaseMessage>): string {\n return messages\n .map((message) => {\n const prefix = message instanceof AIMessage ? 'AI' : 'Human';\n const content = message instanceof AIMessage ? '[...]' : message.content;\n return `${prefix}: ${content}`;\n })\n .join('\\n');\n}\n\n/**\n * Formats messages in a concise markdown format, redacting Human messages with [...]\n *\n * ### Example\n * ```markdown\n * AI: Hello, how are you?\n * Human: [...]\n * AI: What is your name?\n * Human: [...]\n * AI: What is your favorite color?\n * Human: [...]\n * AI: What is your favorite food?\n * Human: [...]\n * ```\n */\nfunction redactHuman(messages: Array<BaseMessage>): string {\n return messages\n .map((message) => {\n const prefix = message instanceof AIMessage ? 'AI' : 'Human';\n const content = message instanceof AIMessage ? '[...]' : message.content;\n return `${prefix}: ${content}`;\n })\n .join('\\n');\n}\nconst typeOnFormatter = {\n [FormatType.Concise]: concise,\n [FormatType.Verbose]: verbose,\n [FormatType.RedactAi]: redactAi,\n [FormatType.RedactHuman]: redactHuman,\n};\n\nexport { typeOnFormatter };\n","import { Effect, Scope } from 'effect';\nimport type { Schema as S } from 'effect';\nimport type { AgentFactory } from '../agent-factory';\nimport type { AgentNetworkEventDef } from './agent-network-event';\nimport { ChannelName, ConfiguredChannel, Sink } from './channel';\nimport { createEventPlane, run } from './event-plane';\nimport type { EventPlane } from './event-plane';\nimport { expose } from '../io/expose';\nimport type { ExposeOptions, ExposedAPI } from '../io/types';\n\n/* ─── Helper Types ─── */\n\ntype EventDef = AgentNetworkEventDef<string, S.Schema.Any>;\n\n/** Structural interface for any Agent – avoids variance issues with private fields. */\nexport interface AnyAgent {\n getId(): string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n invoke(options?: any): Promise<void>;\n /** Event names this agent listens to. Empty = listen to all. */\n getListensTo?(): readonly string[];\n}\n\n/* ─── Agent Binding (returned by registerAgent) ─── */\n\nexport type AgentBinding = {\n subscribe(channel: ConfiguredChannel): AgentBinding;\n publishTo(channel: ConfiguredChannel): AgentBinding;\n};\n\n/* ─── Spawner Builder ─── */\n\nexport type SpawnFn = (\n agent: AnyAgent,\n bindings?: { subscribe?: string[]; publishTo?: string[] },\n) => void;\n\nexport type SpawnCallbackContext<\n TRegistry extends Record<string, AgentFactory> = Record<string, AgentFactory>,\n> = {\n kind: keyof TRegistry & string;\n factory: TRegistry[keyof TRegistry & string];\n payload: {\n id: string;\n params: Record<string, unknown>;\n subscribe?: string[];\n publishTo?: string[];\n };\n spawn: SpawnFn;\n};\n\nexport type SpawnerBuilder<\n TRegistry extends Record<string, AgentFactory> = Record<string, AgentFactory>,\n> = {\n listen(\n channel: ConfiguredChannel,\n event: EventDef,\n ): SpawnerBuilder<TRegistry>;\n registry<R extends Record<string, AgentFactory>>(reg: R): SpawnerBuilder<R>;\n defaultBinding(\n fn: (ctx: { kind: string }) => {\n subscribe: string[];\n publishTo: string[];\n },\n ): SpawnerBuilder<TRegistry>;\n onSpawn(\n fn: (ctx: SpawnCallbackContext<TRegistry>) => AnyAgent,\n ): SpawnerBuilder<TRegistry>;\n};\n\n/* ─── Setup Context ─── */\n\nexport type SetupContext = {\n mainChannel: (name: string) => ConfiguredChannel;\n createChannel: (name: string) => ConfiguredChannel;\n sink: typeof Sink;\n registerAgent: (agent: AnyAgent) => AgentBinding;\n spawner: (factory: typeof AgentFactory) => SpawnerBuilder;\n};\n\n/* ─── Internal Registration Records ─── */\n\ntype AgentRegistration = {\n agent: AnyAgent;\n subscribedTo: ConfiguredChannel[];\n publishesTo: ConfiguredChannel[];\n};\n\ntype SpawnerRegistration = {\n factoryClass: typeof AgentFactory;\n listenChannel?: ConfiguredChannel;\n listenEvent?: EventDef;\n registry: Record<string, AgentFactory>;\n defaultBindingFn?: (ctx: { kind: string }) => {\n subscribe: string[];\n publishTo: string[];\n };\n onSpawnFn?: (\n ctx: SpawnCallbackContext<Record<string, AgentFactory>>,\n ) => AnyAgent;\n};\n\n/* ─── AgentNetwork ─── */\n\nexport class AgentNetwork {\n private _mainChannel: ConfiguredChannel | undefined;\n private channels: Map<ChannelName, ConfiguredChannel> = new Map();\n private agentRegistrations: Map<string, AgentRegistration> = new Map();\n private spawnerRegistrations: SpawnerRegistration[] = [];\n\n private constructor() {}\n\n /* ─── Public Static Factory ─── */\n\n static setup(callback: (ctx: SetupContext) => void): AgentNetwork {\n const network = new AgentNetwork();\n\n const ctx: SetupContext = {\n mainChannel: (name: string) => {\n const channel = network.addChannel(name);\n network.setMainChannel(channel);\n return channel;\n },\n createChannel: (name: string) => network.addChannel(name),\n sink: Sink,\n registerAgent: (agent) => network.registerAgentInternal(agent),\n spawner: (factory) => network.createSpawnerInternal(factory),\n };\n\n callback(ctx);\n\n return network;\n }\n\n /* ─── Internal Builders ─── */\n\n private addChannel(name: string): ConfiguredChannel {\n const channelName = ChannelName(name);\n const channel = new ConfiguredChannel(channelName);\n this.channels.set(channelName, channel);\n return channel;\n }\n\n private setMainChannel(channel: ConfiguredChannel): void {\n this._mainChannel = channel;\n }\n\n private registerAgentInternal(agent: AnyAgent): AgentBinding {\n const registration: AgentRegistration = {\n agent,\n subscribedTo: [],\n publishesTo: [],\n };\n this.agentRegistrations.set(agent.getId(), registration);\n\n const binding: AgentBinding = {\n subscribe(channel: ConfiguredChannel) {\n registration.subscribedTo.push(channel);\n return binding;\n },\n publishTo(channel: ConfiguredChannel) {\n registration.publishesTo.push(channel);\n return binding;\n },\n };\n\n return binding;\n }\n\n private createSpawnerInternal(\n factoryClass: typeof AgentFactory,\n ): SpawnerBuilder {\n const reg: SpawnerRegistration = {\n factoryClass,\n registry: {},\n };\n\n this.spawnerRegistrations.push(reg);\n\n const builder: SpawnerBuilder = {\n listen(channel: ConfiguredChannel, event: EventDef) {\n reg.listenChannel = channel;\n reg.listenEvent = event;\n return builder;\n },\n registry(registry: Record<string, AgentFactory>) {\n reg.registry = registry;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return builder as SpawnerBuilder<any>;\n },\n defaultBinding(\n fn: (ctx: { kind: string }) => {\n subscribe: string[];\n publishTo: string[];\n },\n ) {\n reg.defaultBindingFn = fn;\n return builder;\n },\n onSpawn(\n fn: (\n ctx: SpawnCallbackContext<Record<string, AgentFactory>>,\n ) => AnyAgent,\n ) {\n reg.onSpawnFn = fn;\n return builder;\n },\n };\n\n return builder;\n }\n\n /* ─── Accessors ─── */\n\n getChannels(): Map<string, ConfiguredChannel> {\n return this.channels;\n }\n\n getMainChannel(): ConfiguredChannel | undefined {\n return this._mainChannel;\n }\n\n getAgentRegistrations(): Map<string, AgentRegistration> {\n return this.agentRegistrations;\n }\n\n getSpawnerRegistrations(): ReadonlyArray<SpawnerRegistration> {\n return this.spawnerRegistrations;\n }\n\n /**\n * Expose the network as a streamable API (e.g. SSE). Returns an ExposedAPI\n * that adapters (NextEndpoint, ExpressEndpoint) consume to produce streamed\n * responses.\n *\n * @example\n * const api = network.expose({ protocol: \"sse\", auth, select });\n * export const GET = NextEndpoint.from(api, { requestToContextId, requestToRunId }).handler();\n */\n expose(options: ExposeOptions): ExposedAPI {\n return expose(this, options);\n }\n\n /**\n * Starts the event plane: creates one PubSub per channel and runs subscriber\n * loops for each (agent, channel) pair. Agents subscribed to a channel are\n * invoked concurrently when events are published to that channel.\n *\n * Returns the EventPlane for publishing. Use `Effect.scoped` so the run is\n * interrupted when the scope ends.\n */\n run(capacity?: number): Effect.Effect<EventPlane, never, Scope.Scope> {\n return this.runScoped(this, capacity);\n }\n\n private runScoped(\n network: AgentNetwork,\n capacity?: number,\n ): Effect.Effect<EventPlane, never, Scope.Scope> {\n return Effect.gen(function* () {\n const plane = yield* createEventPlane({ network, capacity });\n yield* Effect.fork(run(network, plane));\n return plane;\n });\n }\n}\n","import { Brand } from 'effect';\n\n/** Regex: lowercase alphanumeric segments separated by hyphens (e.g. my-channel-name) */\nconst KEBAB_CASE_REGEX = /^[a-z0-9]+(-[a-z0-9]+)*$/;\n\n/**\n * Branded type for channel names. Enforces kebab-case at runtime via refinement.\n *\n * **Branded types** add a nominal marker so TypeScript treats `ChannelName` as\n * distinct from plain `string`, preventing accidental substitution (e.g. passing\n * a raw string where a validated channel name is expected).\n *\n * **Refinement** validates at runtime that the value matches kebab-case before\n * the brand is applied. Use `ChannelName(value)` to create a validated instance.\n */\nexport type ChannelName = string & Brand.Brand<'ChannelName'>;\n\nexport const ChannelName = Brand.refined<ChannelName>(\n (s) => typeof s === 'string' && KEBAB_CASE_REGEX.test(s),\n (s) => Brand.error(`Expected kebab-case (e.g. my-channel-name), got: ${s}`),\n);\n","import { type Schema as S } from 'effect';\nimport type { AgentNetworkEventDef } from './agent-network-event';\nimport { ChannelName } from '../identifiers/channel-name';\n\nexport { ChannelName } from '../identifiers/channel-name';\n\n/* ─── Sink ─── */\n\nexport type SinkDef = {\n readonly _tag: 'SinkDef';\n readonly type: string;\n readonly config: unknown;\n};\n\nexport const Sink = {\n kafka(config: { topic: string }): SinkDef {\n return { _tag: 'SinkDef', type: 'kafka', config };\n },\n httpStream(): SinkDef {\n return { _tag: 'SinkDef', type: 'http-stream', config: {} };\n },\n};\n\nexport function isHttpStreamSink(sink: SinkDef): boolean {\n return sink.type === 'http-stream';\n}\n\n/* ─── Channel Definitions ─── */\n\ntype EventDef = AgentNetworkEventDef<string, S.Schema.Any>;\n\nexport type ChannelDef = {\n readonly _tag: 'ChannelDef';\n readonly name: ChannelName;\n};\n\n/**\n * A channel configured via the builder pattern inside `AgentNetwork.setup()`.\n * Supports `.events()`, `.sink()`, and `.sinks()` chaining.\n */\nexport class ConfiguredChannel {\n readonly _tag = 'ConfiguredChannel' as const;\n readonly name: ChannelName;\n private _events: ReadonlyArray<EventDef> = [];\n private _sinks: ReadonlyArray<SinkDef> = [];\n\n constructor(name: ChannelName) {\n this.name = name;\n }\n\n events(events: ReadonlyArray<EventDef>): this {\n this._events = [...events];\n return this;\n }\n\n sink(sink: SinkDef): this {\n this._sinks = [...this._sinks, sink];\n return this;\n }\n\n sinks(sinks: ReadonlyArray<SinkDef>): this {\n this._sinks = [...sinks];\n return this;\n }\n\n getEvents(): ReadonlyArray<EventDef> {\n return this._events;\n }\n\n getSinks(): ReadonlyArray<SinkDef> {\n return this._sinks;\n }\n}\n\nexport const Channel = {\n of(name: ChannelName): ChannelDef {\n return {\n _tag: 'ChannelDef' as const,\n name,\n };\n },\n};\n","import { Cause, Effect, Fiber, PubSub, Queue, Scope } from 'effect';\nimport type { AgentNetwork, AnyAgent } from './agent-network';\nimport type {\n ContextEvents,\n EventMeta,\n RunEvents,\n} from './agent-network-event';\nimport type { ChannelName, ConfiguredChannel } from './channel';\nimport type { AgentNetworkStore } from './stores/agent-network-store';\nimport { createInMemoryNetworkStore } from './stores/inmemory-network-store';\n\n/* ─── Envelope ─── */\n\nexport type Envelope = {\n name: string;\n meta: EventMeta;\n payload: unknown;\n};\n\n/* ─── EventPlane ─── */\n\nexport type EventPlane = {\n readonly publish: (\n channel: ChannelName,\n envelope: Envelope,\n ) => Effect.Effect<boolean>;\n readonly publishToChannels: (\n channels: readonly ConfiguredChannel[],\n envelope: Envelope,\n ) => Effect.Effect<boolean>;\n readonly subscribe: (\n channel: ChannelName,\n ) => Effect.Effect<Queue.Dequeue<Envelope>, never, Scope.Scope>;\n readonly getRunEvents: (runId: string, contextId: string) => RunEvents;\n readonly getContextEvents: (contextId: string) => ContextEvents;\n readonly shutdown: Effect.Effect<void>;\n};\n\n/* ─── Create EventPlane ─── */\n\nconst DEFAULT_CAPACITY = 16;\n\ntype CreateEventPlaneOptions = {\n network: AgentNetwork;\n capacity?: number;\n store?: AgentNetworkStore<Envelope>;\n};\n\n/**\n * Creates an EventPlane from an AgentNetwork. One PubSub per channel with\n * bounded back-pressure. Use `Effect.scoped` when running to ensure proper\n * cleanup.\n */\nexport const createEventPlane = (\n options: CreateEventPlaneOptions,\n): Effect.Effect<EventPlane> =>\n Effect.gen(function* () {\n const {\n network,\n capacity = DEFAULT_CAPACITY,\n store = createInMemoryNetworkStore<Envelope>(),\n } = options;\n\n const channels = network.getChannels();\n const pubsubs = new Map<ChannelName, PubSub.PubSub<Envelope>>();\n\n for (const channel of channels.values()) {\n const pubsub = yield* PubSub.bounded<Envelope>(capacity);\n pubsubs.set(channel.name, pubsub);\n }\n\n const getPubsub = (channel: ChannelName): PubSub.PubSub<Envelope> => {\n const p = pubsubs.get(channel);\n if (!p) throw new Error(`Channel not found: ${channel}`);\n return p;\n };\n\n const recordEvent = (envelope: Envelope): void => {\n const { contextId, runId } = envelope.meta;\n store.storeEvent(contextId, runId, envelope);\n };\n\n const publishToPubSub = (\n channel: ChannelName,\n envelope: Envelope,\n ): Effect.Effect<boolean> => PubSub.publish(getPubsub(channel), envelope);\n\n const publish = (\n channel: ChannelName,\n envelope: Envelope,\n ): Effect.Effect<boolean> =>\n Effect.sync(() => recordEvent(envelope)).pipe(\n Effect.flatMap(() => publishToPubSub(channel, envelope)),\n );\n\n const publishToChannels = (\n targetChannels: readonly ConfiguredChannel[],\n envelope: Envelope,\n ): Effect.Effect<boolean> =>\n Effect.sync(() => recordEvent(envelope)).pipe(\n Effect.flatMap(() =>\n Effect.all(\n targetChannels.map((c) => publishToPubSub(c.name, envelope)),\n { concurrency: 'unbounded' },\n ),\n ),\n Effect.map((results) => results.every(Boolean)),\n );\n\n const subscribe = (\n channel: ChannelName,\n ): Effect.Effect<Queue.Dequeue<Envelope>, never, Scope.Scope> =>\n PubSub.subscribe(getPubsub(channel));\n\n const getRunEvents = (runId: string, contextId: string): RunEvents => {\n return store.getEvents(contextId, runId).slice();\n };\n\n const getContextEvents = (contextId: string): ContextEvents => {\n const byRun = store.getContextEvents(contextId);\n const map = new Map<string, readonly Envelope[]>();\n const all: Envelope[] = [];\n for (const [runId, events] of byRun) {\n const readonlyEvents = events.slice();\n map.set(runId, readonlyEvents);\n all.push(...readonlyEvents);\n }\n return {\n all,\n byRun: (runId: string) => map.get(runId) ?? [],\n map,\n };\n };\n\n const shutdown = Effect.all([...pubsubs.values()].map(PubSub.shutdown), {\n concurrency: 'unbounded',\n }).pipe(Effect.asVoid);\n\n return {\n publish,\n publishToChannels,\n subscribe,\n getRunEvents,\n getContextEvents,\n shutdown,\n };\n });\n\n/* ─── Run Subscriber Loop ─── */\n\n/**\n * Runs a single agent's subscription loop on one channel. Takes messages from\n * the dequeue, invokes the agent with the envelope as triggerEvent when the\n * event name matches the agent's listensTo, and wires emit to publish to the\n * agent's output channels.\n */\ntype EmitQueue = Queue.Queue<{\n channels: readonly ConfiguredChannel[];\n envelope: Envelope;\n}>;\n\nexport const runSubscriber = (\n agent: AnyAgent,\n publishesTo: readonly ConfiguredChannel[],\n dequeue: Queue.Dequeue<Envelope>,\n plane: EventPlane,\n emitQueue?: EmitQueue,\n): Effect.Effect<Fiber.RuntimeFiber<void, never>> =>\n Effect.gen(function* () {\n const listensTo = agent.getListensTo?.() ?? [];\n\n const processOne = (): Effect.Effect<void, never, never> =>\n Effect.gen(function* () {\n const envelope = yield* Queue.take(dequeue);\n if (listensTo.length > 0 && !listensTo.includes(envelope.name)) {\n return;\n }\n const runEvents = plane.getRunEvents(\n envelope.meta.runId,\n envelope.meta.contextId,\n );\n const contextEvents = plane.getContextEvents(envelope.meta.contextId);\n yield* Effect.tryPromise({\n try: () =>\n agent.invoke({\n triggerEvent: envelope,\n emit: (userEvent: { name: string; payload: unknown }) => {\n const fullEnvelope: Envelope = {\n name: userEvent.name,\n meta: envelope.meta,\n payload: userEvent.payload,\n };\n if (emitQueue) {\n Effect.runPromise(\n Queue.offer(emitQueue, {\n channels: publishesTo,\n envelope: fullEnvelope,\n }),\n ).catch(() => {});\n } else {\n Effect.runFork(\n plane.publishToChannels(publishesTo, fullEnvelope),\n );\n }\n },\n runEvents,\n contextEvents,\n }),\n catch: (e) => e,\n });\n }).pipe(\n Effect.catchAllCause((cause) =>\n Cause.isInterrupted(cause)\n ? Effect.void\n : Effect.sync(() => {\n console.error(`Agent ${agent.getId()} failed:`, cause);\n }).pipe(Effect.asVoid),\n ),\n );\n\n const loop = (): Effect.Effect<void, never, never> =>\n processOne().pipe(Effect.flatMap(() => loop()));\n\n return yield* Effect.fork(loop());\n });\n\n/* ─── Run Network ─── */\n\nexport type RunOptions = {\n /** When provided, agent emits are queued and published by a drain fiber in the same Effect context. Use when run is forked from expose without a shared plane. */\n emitQueue?: EmitQueue;\n};\n\n/**\n * Runs the event plane: starts a subscriber loop for each (agent, channel)\n * pair. Runs until the scope ends (e.g. on interrupt). Use Effect.scoped\n * to ensure subscriptions are properly cleaned up.\n */\nexport const run = (\n network: AgentNetwork,\n plane: EventPlane,\n options?: RunOptions,\n): Effect.Effect<void, never, Scope.Scope> =>\n Effect.gen(function* () {\n const registrations = network.getAgentRegistrations();\n const emitQueue = options?.emitQueue;\n\n for (const reg of registrations.values()) {\n for (const channel of reg.subscribedTo) {\n const dequeue = yield* plane.subscribe(channel.name);\n yield* runSubscriber(\n reg.agent,\n reg.publishesTo,\n dequeue,\n plane,\n emitQueue,\n );\n }\n }\n\n yield* Effect.never;\n });\n","/**\n * Type-safe no-operation stubs for use as default handlers.\n *\n * `noop` and `asyncNoop` are assignable to any callback that expects\n * additional parameters — TypeScript allows a function with fewer\n * parameters to substitute for one expecting more.\n *\n * @example\n * ```ts\n * type LogicFn = (ctx: { params: Config; emit: Emitter }) => Promise<void>;\n * const defaultLogic: LogicFn = asyncNoop;\n * ```\n */\n\n/** Synchronous no-op — safe default for any `(...) => void` handler. */\nexport const noop = (): void => {};\n\n/** Asynchronous no-op — safe default for any `(...) => Promise<void>` handler. */\nexport const asyncNoop = async (): Promise<void> => {};\n\n/** Synchronous no-op that returns a given value — for handlers that must return `R`. */\nexport const noopOf =\n <R>(value: R): (() => R) =>\n () =>\n value;\n\n/** Asynchronous no-op that resolves to a given value — for handlers that must return `Promise<R>`. */\nexport const asyncNoopOf =\n <R>(value: R): (() => Promise<R>) =>\n async () =>\n value;\n","import { asyncNoop } from '../../../helper/types/noop';\nimport type { AgentNetworkStore } from './agent-network-store';\n\n/**\n * In-memory implementation of AgentNetworkStore. Events are stored in a\n * nested map: contextId -> runId -> events.\n */\nexport const createInMemoryNetworkStore = <T>(): AgentNetworkStore<T> => {\n const store = new Map<string, Map<string, T[]>>();\n\n return {\n storeEvent: (contextId: string, runId: string, event: T): void => {\n let byRun = store.get(contextId);\n if (!byRun) {\n byRun = new Map();\n store.set(contextId, byRun);\n }\n let events = byRun.get(runId);\n if (!events) {\n events = [];\n byRun.set(runId, events);\n }\n events.push(event);\n },\n\n getEvents: (contextId: string, runId: string): T[] => {\n const events = store.get(contextId)?.get(runId);\n return events ? [...events] : [];\n },\n\n getContextEvents: (contextId: string): Map<string, T[]> => {\n const byRun = store.get(contextId);\n const result = new Map<string, T[]>();\n if (byRun) {\n for (const [runId, events] of byRun) {\n result.set(runId, [...events]);\n }\n }\n return result;\n },\n\n getFullStore: (): Map<string, Map<string, T[]>> => {\n const result = new Map<string, Map<string, T[]>>();\n for (const [contextId, byRun] of store) {\n const contextMap = new Map<string, T[]>();\n for (const [runId, events] of byRun) {\n contextMap.set(runId, [...events]);\n }\n result.set(contextId, contextMap);\n }\n return result;\n },\n\n persist: (): Promise<void> => asyncNoop(),\n load: (): Promise<void> => asyncNoop(),\n };\n};\n","import { Effect, Queue } from 'effect';\nimport type { AgentNetwork } from '../agent-network/agent-network';\nimport type { ConfiguredChannel } from '../agent-network/channel';\nimport { createEventPlane, run } from '../agent-network/event-plane';\nimport type { Envelope } from '../agent-network/event-plane';\nimport { ChannelName, isHttpStreamSink } from '../agent-network/channel';\nimport type {\n ExposeOptions,\n ExposeRequest,\n ExposedAPI,\n ExposedStream,\n StreamFactory,\n} from './types';\n\n/** Extract JSON payload from ExposeRequest. POST with JSON body, or Express req.body, else {}. */\nasync function extractPayload(req: ExposeRequest): Promise<unknown> {\n const webRequest = req.request as Request | undefined;\n if (webRequest?.method === 'POST') {\n const ct = webRequest.headers?.get?.('content-type') ?? '';\n if (ct.includes('application/json')) {\n try {\n return await webRequest.json();\n } catch {\n return {};\n }\n }\n }\n const expressReq = req.req as { body?: unknown } | undefined;\n if (expressReq?.body != null) {\n return expressReq.body;\n }\n return {};\n}\n\n/** Resolve which channel(s) to subscribe to from select options */\nfunction resolveChannels(\n network: AgentNetwork,\n select?: ExposeOptions['select'],\n): ChannelName[] {\n const channels = network.getChannels();\n if (select?.channels) {\n const ch = select.channels;\n const arr = Array.isArray(ch) ? ch : [ch];\n return arr.map((c) => ChannelName(c as string));\n }\n // Prefer channels with http-stream sink (explicitly marked for frontend)\n const httpStreamChannels = [...channels.values()]\n .filter((ch) => ch.getSinks().some(isHttpStreamSink))\n .map((ch) => ch.name);\n if (httpStreamChannels.length > 0) return httpStreamChannels;\n // Fallback: prefer \"client\", else first channel\n const client = channels.get('client' as ChannelName);\n if (client) return [client.name];\n const first = channels.values().next().value;\n return first ? [first.name] : [];\n}\n\n/** Create async iterable from Queue.Dequeue, respecting AbortSignal */\nfunction streamFromDequeue(\n take: () => Promise<Envelope>,\n signal?: AbortSignal | null,\n eventFilter?: string[],\n): ExposedStream {\n const shouldInclude = (e: Envelope): boolean =>\n !eventFilter?.length || eventFilter.includes(e.name);\n\n return {\n async *[Symbol.asyncIterator](): AsyncIterableIterator<Envelope> {\n while (!signal?.aborted) {\n const takePromise = take();\n const abortPromise = signal\n ? new Promise<never>((_, reject) => {\n signal.addEventListener(\n 'abort',\n () => reject(new DOMException('Aborted', 'AbortError')),\n { once: true },\n );\n })\n : new Promise<never>(() => {});\n\n let envelope: Envelope;\n try {\n envelope = await Promise.race([takePromise, abortPromise]);\n } catch (e) {\n if (e instanceof DOMException && e.name === 'AbortError') break;\n throw e;\n }\n\n if (shouldInclude(envelope)) yield envelope;\n }\n },\n };\n}\n\n/**\n * Expose the agent network as a streamable API. Returns an ExposedAPI that\n * adapters (NextEndpoint, ExpressEndpoint) consume to produce SSE responses.\n *\n * @example\n * const api = agentNetwork.expose({ protocol: \"sse\", auth, select });\n * export const GET = NextEndpoint.from(api, { requestToContextId, requestToRunId }).handler();\n */\nexport function expose(\n network: AgentNetwork,\n options: ExposeOptions,\n): ExposedAPI {\n const {\n auth,\n select,\n plane: providedPlane,\n onRequest,\n triggerEvents,\n } = options;\n const triggerEventDef = triggerEvents?.[0];\n const triggerEventName = triggerEventDef?.name ?? 'request';\n const channels = resolveChannels(network, select);\n const eventFilter = select?.events;\n const mainChannel = network.getMainChannel();\n\n if (channels.length === 0) {\n throw new Error('expose: no channels to subscribe to');\n }\n\n const createStream = (async (\n req: ExposeRequest,\n consumer?: (stream: ExposedStream) => Promise<unknown>,\n ) => {\n const payload = await extractPayload(req);\n const signal = req.request?.signal;\n\n const program = Effect.gen(function* () {\n const plane = providedPlane ?? (yield* createEventPlane({ network }));\n if (!providedPlane) {\n const emitQueue = yield* Queue.unbounded<{\n channels: readonly ConfiguredChannel[];\n envelope: Envelope;\n }>();\n yield* Effect.fork(\n Effect.forever(\n Queue.take(emitQueue).pipe(\n Effect.flatMap(({ channels: chs, envelope }) =>\n plane.publishToChannels(chs, envelope),\n ),\n ),\n ),\n );\n yield* Effect.fork(run(network, plane, { emitQueue }));\n // Allow run() to subscribe agents before we publish (PubSub does not buffer for future subscribers)\n yield* Effect.sleep('10 millis');\n }\n\n const targetChannel = mainChannel?.name ?? channels[0]!;\n let runId = req.runId ?? crypto.randomUUID();\n let contextId = req.contextId ?? crypto.randomUUID();\n\n const setRunId = (id: string): void => {\n runId = id;\n };\n const setContextId = (id: string): void => {\n contextId = id;\n };\n\n const emitStartEvent = (opts: {\n contextId: string;\n runId: string;\n event: { name: string; payload: unknown };\n }): void => {\n const meta = {\n runId: opts.runId,\n contextId: opts.contextId,\n };\n const envelope: Envelope = {\n name: opts.event.name,\n meta,\n payload: opts.event.payload,\n };\n Effect.runPromise(plane.publish(targetChannel, envelope)).catch(\n () => {},\n );\n };\n\n // Subscribe to first channel before emitting (so we don't miss agent output)\n const dequeue = yield* plane.subscribe(channels[0]!);\n\n if (onRequest) {\n yield* Effect.tryPromise(() =>\n Promise.resolve(\n onRequest({\n setRunId,\n setContextId,\n emitStartEvent,\n req,\n payload,\n }),\n ),\n );\n } else if (!providedPlane) {\n const envelope: Envelope = {\n name: triggerEventName,\n meta: { runId, contextId },\n payload,\n };\n yield* plane.publish(targetChannel, envelope);\n yield* Effect.sleep('10 millis');\n }\n const take = (): Promise<Envelope> =>\n Effect.runPromise(Queue.take(dequeue)) as Promise<Envelope>;\n\n const stream = streamFromDequeue(take, signal ?? undefined, eventFilter);\n if (consumer) {\n return yield* Effect.tryPromise(() => consumer(stream));\n }\n return stream;\n });\n\n return Effect.runPromise(program.pipe(Effect.scoped));\n }) as StreamFactory;\n\n return {\n protocol: 'sse',\n createStream: (async (\n req: ExposeRequest,\n consumer?: (stream: ExposedStream) => Promise<unknown>,\n ) => {\n if (auth) {\n const result = await auth(req);\n if (!result.allowed) {\n throw new ExposeAuthError(\n result.message ?? 'Unauthorized',\n result.status ?? 401,\n );\n }\n }\n return consumer ? createStream(req, consumer) : createStream(req);\n }) as StreamFactory,\n };\n}\n\n/** Thrown when auth denies the request */\nexport class ExposeAuthError extends Error {\n constructor(\n message: string,\n public readonly status: number = 401,\n ) {\n super(message);\n this.name = 'ExposeAuthError';\n }\n}\n","import { Effect, Schema as S } from 'effect';\nimport type { ParseError } from 'effect/ParseResult';\n\n/** Standard meta carried by every event */\nexport const EventMetaSchema = S.Struct({\n runId: S.String,\n contextId: S.String,\n correlationId: S.optional(S.String),\n causationId: S.optional(S.String),\n ts: S.optional(S.Number),\n});\n\nexport type EventMeta = S.Schema.Type<typeof EventMetaSchema>;\n\n/** Envelope-like shape for events (avoids circular dep with event-plane) */\nexport type EnvelopeLike = { name: string; meta: EventMeta; payload: unknown };\nexport type RunEvents = readonly EnvelopeLike[];\n\nexport type ContextEvents = {\n /** All events in the context across all runs */\n readonly all: readonly EnvelopeLike[];\n /** Get events for a specific run */\n byRun(runId: string): readonly EnvelopeLike[];\n /** Map of runId -> events */\n readonly map: ReadonlyMap<string, readonly EnvelopeLike[]>;\n};\n\n// Re-export Schema from effect for convenience\nexport { Schema as S } from 'effect';\n\nexport type AgentNetworkEventDef<\n EventName extends string,\n PayloadSchema extends S.Schema.Any,\n> = {\n readonly _tag: 'AgentNetworkEventDef';\n readonly name: EventName;\n readonly payload: PayloadSchema;\n\n /** Decode unknown payload -> typed payload (Effect) */\n readonly decodePayload: (\n u: unknown,\n ) => Effect.Effect<S.Schema.Type<PayloadSchema>, ParseError>;\n\n /** Decode the full envelope (meta + payload) */\n readonly decode: (\n u: unknown,\n ) => Effect.Effect<\n { name: EventName; meta: EventMeta; payload: S.Schema.Type<PayloadSchema> },\n ParseError\n >;\n\n /**\n * Create an unbound event (name + payload only) for emit. Validates payload via schema.\n * Meta is injected by the runtime when the event is emitted.\n */\n readonly make: (payload: unknown) => {\n name: EventName;\n payload: S.Schema.Type<PayloadSchema>;\n };\n\n /**\n * Create a full envelope (meta + payload) for tests or manual trigger events.\n * Sync, throws on validation error.\n */\n readonly makeBound: (\n meta: unknown,\n payload: unknown,\n ) => {\n name: EventName;\n meta: EventMeta;\n payload: S.Schema.Type<PayloadSchema>;\n };\n\n /**\n * Effect version of make. Use when composing in Effect pipelines.\n */\n readonly makeEffect: (\n payload: unknown,\n ) => Effect.Effect<\n { name: EventName; payload: S.Schema.Type<PayloadSchema> },\n ParseError\n >;\n\n /**\n * Effect version of makeBound. Use when composing in Effect pipelines.\n */\n readonly makeBoundEffect: (\n meta: unknown,\n payload: unknown,\n ) => Effect.Effect<\n { name: EventName; meta: EventMeta; payload: S.Schema.Type<PayloadSchema> },\n ParseError\n >;\n\n /**\n * Type guard: returns true if `u` is a valid event of this type.\n */\n readonly is: (u: unknown) => u is {\n name: EventName;\n meta: EventMeta;\n payload: S.Schema.Type<PayloadSchema>;\n };\n};\n\ntype Envelope<EventName extends string, Meta, Payload> = {\n name: EventName;\n meta: Meta;\n payload: Payload;\n};\n\nexport const AgentNetworkEvent = {\n of<const EventName extends string, PS extends S.Schema.Any>(\n name: EventName,\n payload: PS,\n ): AgentNetworkEventDef<EventName, PS> {\n const decodePayload = S.decodeUnknown(payload);\n const envelopeSchema = S.Struct({\n name: S.Literal(name),\n meta: EventMetaSchema,\n payload,\n });\n const decodeEnvelope = S.decodeUnknown(envelopeSchema);\n\n const make = (\n payload: unknown,\n ): { name: EventName; payload: S.Schema.Type<PS> } => {\n const decoded = Effect.runSync(\n decodePayload(payload) as unknown as Effect.Effect<\n S.Schema.Type<PS>,\n ParseError\n >,\n );\n return { name, payload: decoded };\n };\n\n const makeBound = (\n meta: unknown,\n payload: unknown,\n ): Envelope<EventName, EventMeta, S.Schema.Type<PS>> =>\n Effect.runSync(\n decodeEnvelope({ name, meta, payload }) as unknown as Effect.Effect<\n Envelope<EventName, EventMeta, S.Schema.Type<PS>>,\n ParseError\n >,\n );\n\n const makeEffect = (\n payload: unknown,\n ): Effect.Effect<\n { name: EventName; payload: S.Schema.Type<PS> },\n ParseError\n > =>\n (\n decodePayload(payload) as unknown as Effect.Effect<\n S.Schema.Type<PS>,\n ParseError\n >\n ).pipe(Effect.map((p) => ({ name, payload: p })));\n\n const makeBoundEffect = (\n meta: unknown,\n payload: unknown,\n ): Effect.Effect<\n Envelope<EventName, EventMeta, S.Schema.Type<PS>>,\n ParseError\n > =>\n decodeEnvelope({ name, meta, payload }) as unknown as Effect.Effect<\n Envelope<EventName, EventMeta, S.Schema.Type<PS>>,\n ParseError\n >;\n\n const is = S.is(envelopeSchema) as unknown as (\n u: unknown,\n ) => u is Envelope<EventName, EventMeta, S.Schema.Type<PS>>;\n\n return {\n _tag: 'AgentNetworkEventDef' as const,\n name,\n payload,\n decodePayload: decodePayload as unknown as AgentNetworkEventDef<\n EventName,\n PS\n >['decodePayload'],\n decode: decodeEnvelope as unknown as AgentNetworkEventDef<\n EventName,\n PS\n >['decode'],\n make,\n makeBound,\n makeEffect,\n makeBoundEffect,\n is,\n };\n },\n};\n","import { randomUUID } from 'crypto';\nimport type {\n ContextEvents,\n RunEvents,\n} from './agent-network/agent-network-event';\n\ntype LogicFn<TParams, TTriggerEvent, TEmitEvent> = (ctx: {\n params: TParams;\n triggerEvent: TTriggerEvent;\n emit: (event: TEmitEvent) => void;\n runEvents: RunEvents;\n contextEvents: ContextEvents;\n}) => Promise<void>;\n\nexport class Agent<TParams, TTriggerEvent = never, TEmitEvent = never> {\n #params: TParams;\n #logic: LogicFn<TParams, TTriggerEvent, TEmitEvent>;\n #id: string;\n #listensTo: readonly string[];\n\n constructor(\n logic: LogicFn<TParams, TTriggerEvent, TEmitEvent>,\n params: TParams,\n listensTo?: readonly string[],\n ) {\n this.#logic = logic;\n this.#params = params;\n this.#id = `agent-${randomUUID()}`;\n this.#listensTo = listensTo ?? [];\n }\n\n getListensTo(): readonly string[] {\n return this.#listensTo;\n }\n\n async invoke(options?: {\n triggerEvent?: TTriggerEvent;\n emit?: (event: TEmitEvent) => void;\n runEvents?: RunEvents;\n contextEvents?: ContextEvents;\n }): Promise<void> {\n const { triggerEvent, emit, runEvents, contextEvents } = options ?? {};\n\n const emitFn =\n emit ??\n ((_event: TEmitEvent): void => {\n // no-op – will be wired by the network at runtime\n });\n\n await this.#logic({\n params: this.#params,\n triggerEvent: triggerEvent ?? (undefined as TTriggerEvent),\n emit: emitFn,\n runEvents: runEvents ?? [],\n contextEvents: contextEvents ?? {\n all: [],\n byRun: () => [],\n map: new Map(),\n },\n });\n }\n\n getId(): string {\n return this.#id;\n }\n}\n","import { Schema as S } from 'effect';\nimport { Agent } from './agent';\nimport {\n AgentNetworkEventDef,\n type ContextEvents,\n type EventMeta,\n type RunEvents,\n} from './agent-network/agent-network-event';\nimport { BaseSchemaDefintion } from './types';\n\ntype EventDef = AgentNetworkEventDef<string, S.Schema.Any>;\n\n/** Extracts the envelope type (name, meta, payload) from an event definition */\nexport type EventEnvelope<E extends EventDef> =\n E extends AgentNetworkEventDef<infer N, infer PS>\n ? { name: N; meta: EventMeta; payload: S.Schema.Type<PS> }\n : never;\n\n/** What the user passes to emit() – no meta required */\nexport type EmitPayload<E extends EventDef> =\n E extends AgentNetworkEventDef<infer N, infer PS>\n ? { name: N; payload: S.Schema.Type<PS> }\n : never;\n\n/** Internal logic function */\ntype LogicFn<TParams, TTriggerEvent, TEmitEvent> = (ctx: {\n params: TParams;\n triggerEvent: TTriggerEvent;\n emit: (event: TEmitEvent) => void;\n runEvents: RunEvents;\n contextEvents: ContextEvents;\n}) => Promise<void>;\n\ntype ConstructorParams<\n TParams,\n TListensTo extends EventDef,\n TEmits extends EventDef,\n> = {\n logic?: LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>;\n paramsSchema?: BaseSchemaDefintion;\n listensTo?: ReadonlyArray<TListensTo>;\n emits?: ReadonlyArray<TEmits>;\n};\n\nexport class AgentFactory<\n TParams = unknown,\n TListensTo extends EventDef = never,\n TEmits extends EventDef = never,\n> {\n private _listensTo: ReadonlyArray<TListensTo>;\n private _emits: ReadonlyArray<TEmits>;\n private _logic:\n | LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>\n | undefined;\n private _paramsSchema: BaseSchemaDefintion | undefined;\n\n private constructor({\n logic,\n paramsSchema,\n listensTo = [],\n emits = [],\n }: ConstructorParams<TParams, TListensTo, TEmits>) {\n this._logic = logic;\n this._paramsSchema = paramsSchema;\n this._listensTo = listensTo;\n this._emits = emits;\n }\n\n private getConstructorState(): ConstructorParams<\n TParams,\n TListensTo,\n TEmits\n > {\n return {\n logic: this._logic,\n paramsSchema: this._paramsSchema,\n listensTo: this._listensTo,\n emits: this._emits,\n };\n }\n\n /** Union of all event definitions this agent listens to */\n getListensTo(): ReadonlyArray<TListensTo> {\n return this._listensTo;\n }\n\n /** Union of all event definitions this agent can emit */\n getEmits(): ReadonlyArray<TEmits> {\n return this._emits;\n }\n\n getLogic():\n | LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>\n | undefined {\n return this._logic;\n }\n\n static run(): AgentFactory<unknown, never, never> {\n return new AgentFactory<unknown, never, never>({});\n }\n\n params<TSchema extends BaseSchemaDefintion>(\n params: TSchema,\n ): AgentFactory<TSchema['Type'], TListensTo, TEmits> {\n const { logic, ...rest } = this.getConstructorState();\n\n return new AgentFactory({\n ...rest,\n logic: logic as LogicFn<\n TSchema['Type'],\n EventEnvelope<TListensTo>,\n EmitPayload<TEmits>\n >,\n paramsSchema: params,\n });\n }\n\n listensTo<E extends EventDef>(\n events: Array<E>,\n ): AgentFactory<TParams, TListensTo | E, TEmits> {\n return new AgentFactory<TParams, TListensTo | E, TEmits>({\n ...(this.getConstructorState() as unknown as ConstructorParams<\n TParams,\n TListensTo | E,\n TEmits\n >),\n listensTo: [...this._listensTo, ...events] as ReadonlyArray<\n TListensTo | E\n >,\n });\n }\n\n emits<E extends EventDef>(\n events: Array<E>,\n ): AgentFactory<TParams, TListensTo, TEmits | E> {\n return new AgentFactory<TParams, TListensTo, TEmits | E>({\n ...(this.getConstructorState() as unknown as ConstructorParams<\n TParams,\n TListensTo,\n TEmits | E\n >),\n emits: [...this._emits, ...events] as ReadonlyArray<TEmits | E>,\n });\n }\n\n logic(\n fn: LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>,\n ): AgentFactory<TParams, TListensTo, TEmits> {\n return new AgentFactory<TParams, TListensTo, TEmits>({\n ...this.getConstructorState(),\n logic: fn,\n });\n }\n\n produce(\n params: TParams,\n ): Agent<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>> {\n const listensTo = this._listensTo.map((e) => e.name);\n return new Agent<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>(\n this._logic!,\n params,\n listensTo,\n );\n }\n}\n","import type { Envelope } from '../../agent-network/event-plane';\n\n/** Format a single SSE message (event + data) */\nexport function formatSSE(envelope: Envelope): string {\n const data = JSON.stringify(envelope);\n return `event: ${envelope.name}\\ndata: ${data}\\n\\n`;\n}\n\n/** Create a ReadableStream that encodes envelopes as SSE */\nexport function toSSEStream(\n source: AsyncIterable<Envelope>,\n signal?: AbortSignal | null,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n return new ReadableStream<Uint8Array>({\n async start(controller): Promise<void> {\n const onAbort = (): void => controller.close();\n signal?.addEventListener('abort', onAbort, { once: true });\n\n try {\n for await (const envelope of source) {\n if (signal?.aborted) break;\n controller.enqueue(encoder.encode(formatSSE(envelope)));\n }\n } finally {\n signal?.removeEventListener('abort', onAbort);\n controller.close();\n }\n },\n });\n}\n","import type { ExposedAPI } from '../types';\nimport { ExposeAuthError } from '../expose';\nimport { formatSSE } from '../protocols/sse';\n\n/** Next.js App Router GET/POST handler signature */\nexport type NextGetHandler = (request: Request) => Promise<Response>;\n\n/** Options for NextEndpoint.from() - required to define how request maps to contextId and runId */\nexport type NextEndpointOptions = {\n requestToContextId: (request: Request) => string;\n requestToRunId: (request: Request) => string;\n};\n\n/**\n * Adapter for Next.js App Router. Maps an ExposedAPI to a route handler\n * that streams events as SSE. Use for both GET and POST; POST with JSON body\n * is recommended for passing the start event payload.\n *\n * @example\n * const api = agentNetwork.expose({ protocol: \"sse\", auth, select });\n * const handler = NextEndpoint.from(api, {\n * requestToContextId: (req) => req.headers.get('x-correlation-id') ?? crypto.randomUUID(),\n * requestToRunId: () => crypto.randomUUID(),\n * }).handler();\n * export const GET = handler;\n * export const POST = handler;\n */\nexport const NextEndpoint = {\n from(api: ExposedAPI, options: NextEndpointOptions): {\n handler(): NextGetHandler;\n } {\n if (api.protocol !== 'sse') {\n throw new Error(`NextEndpoint: unsupported protocol \"${api.protocol}\"`);\n }\n\n const { requestToContextId, requestToRunId } = options;\n\n return {\n handler(): NextGetHandler {\n return async (request: Request) => {\n const req = {\n request,\n contextId: requestToContextId(request),\n runId: requestToRunId(request),\n };\n\n try {\n const encoder = new TextEncoder();\n const { readable, writable } =\n new TransformStream<Uint8Array>();\n\n // Signal that the consumer callback has been entered (auth passed, stream ready)\n let consumerStarted!: () => void;\n const started = new Promise<void>((resolve) => {\n consumerStarted = resolve;\n });\n\n const streamDone = api.createStream(req, async (stream) => {\n consumerStarted();\n const writer = writable.getWriter();\n try {\n for await (const envelope of stream) {\n if (request.signal?.aborted) break;\n await writer.write(encoder.encode(formatSSE(envelope)));\n }\n } finally {\n await writer.close();\n }\n });\n\n // Race: consumer starts (auth passed) vs. createStream rejects (auth failed)\n await Promise.race([started, streamDone]);\n\n // Auth passed. Stream is being written in the background.\n streamDone.catch(() => {}); // prevent unhandled rejection\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n } catch (e) {\n if (e instanceof ExposeAuthError) {\n return new Response(e.message, { status: e.status });\n }\n throw e;\n }\n };\n },\n };\n },\n};\n","import type { ExposedAPI } from '../types';\nimport { ExposeAuthError } from '../expose';\nimport { formatSSE } from '../protocols/sse';\n\n/** Minimal Express-like request (compatible with express.Request) */\nexport type ExpressRequest = {\n on(event: 'close', fn: () => void): void;\n};\n\n/** Options for ExpressEndpoint.from() - required to define how request maps to contextId and runId */\nexport type ExpressEndpointOptions = {\n requestToContextId: (req: ExpressRequest) => string;\n requestToRunId: (req: ExpressRequest) => string;\n};\n\n/** Minimal Express-like response (compatible with express.Response) */\nexport type ExpressResponse = {\n setHeader(name: string, value: string | number): void;\n flushHeaders?(): void;\n write(chunk: Uint8Array): void;\n flush?(): void;\n end(): void;\n status(code: number): ExpressResponse;\n send(body: string): void;\n};\n\n/** Express route handler signature */\nexport type ExpressHandler = (\n req: ExpressRequest,\n res: ExpressResponse,\n) => void | Promise<void>;\n\n/**\n * Adapter for Express. Maps an ExposedAPI to an Express route handler\n * that streams events as SSE.\n *\n * @example\n * const api = agentNetwork.expose({ protocol: \"sse\", auth, select });\n * app.get(\"/events\", ExpressEndpoint.from(api, {\n * requestToContextId: (req) => req.headers?.['x-correlation-id'] ?? crypto.randomUUID(),\n * requestToRunId: () => crypto.randomUUID(),\n * }).handler());\n */\nexport const ExpressEndpoint = {\n from(api: ExposedAPI, options: ExpressEndpointOptions): {\n handler(): ExpressHandler;\n } {\n if (api.protocol !== 'sse') {\n throw new Error(\n `ExpressEndpoint: unsupported protocol \"${api.protocol}\"`,\n );\n }\n\n const { requestToContextId, requestToRunId } = options;\n\n return {\n handler(): ExpressHandler {\n return async (req: ExpressRequest, res: ExpressResponse) => {\n const controller = new AbortController();\n req.on('close', () => controller.abort());\n\n const exposeReq = {\n request: { signal: controller.signal } as Request,\n req,\n res,\n contextId: requestToContextId(req),\n runId: requestToRunId(req),\n };\n\n try {\n const encoder = new TextEncoder();\n await api.createStream(exposeReq, async (stream) => {\n // Set SSE headers only after auth has passed\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.flushHeaders?.();\n\n try {\n for await (const envelope of stream) {\n if (controller.signal.aborted) break;\n res.write(encoder.encode(formatSSE(envelope)));\n res.flush?.();\n }\n } finally {\n res.end();\n }\n });\n } catch (e) {\n if (e instanceof ExposeAuthError) {\n res.status(e.status).send(e.message);\n return;\n }\n throw e;\n }\n };\n },\n };\n },\n};\n"]}
1
+ {"version":3,"sources":["../src/stream/Pump.ts","../src/stream/utility/pipe-transformers/response.ts","../src/stream/utility/rechunker/ensure-full-words.ts","../src/api/socket-handler/SocketIoFactory.ts","../src/helper/transform-messages/TransformMessages.ts","../src/helper/transform-messages/message-filter.ts","../src/helper/transform-messages/formatter.ts","../src/matrix/agent-network/agent-network.ts","../src/matrix/identifiers/channel-name.ts","../src/matrix/agent-network/channel.ts","../src/matrix/agent-network/event-plane.ts","../src/helper/types/noop.ts","../src/matrix/agent-network/stores/inmemory-network-store.ts","../src/matrix/io/expose.ts","../src/matrix/agent-network/agent-network-event.ts","../src/matrix/agent.ts","../src/matrix/agent-factory.ts","../src/matrix/io/protocols/sse.ts","../src/matrix/io/adapters/next-endpoint.ts","../src/matrix/io/adapters/express-endpoint.ts","../src/matrix/console-tracer.ts"],"names":["out","window","AIMessage","i","msg","Effect","Queue","payload"],"mappings":"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","sourcesContent":["/**\n * StreamChunk is the base interface for all streams.\n * It can hold voice and text chunks.\n *\n * @template T The type of data contained in the chunk\n */\nexport interface StreamChunk<T> {\n sequence: number;\n data: T;\n done: boolean;\n}\n\n/**\n * MessageStream represents an asynchronous iterable stream of chunks.\n * Used as the core stream representation throughout the Pump library.\n *\n * @template T The type of data contained in the chunks of the stream\n */\nexport type MessageStream<T> = AsyncIterable<StreamChunk<T>>;\n\n/**\n * Represents any source that can be converted to a stream.\n * This includes AsyncIterable and ReadableStream sources.\n *\n * @template T The type of data contained in the source\n */\nexport type Source<T> =\n | AsyncIterable<T>\n | ReadableStream<T>\n | NodeJS.ReadableStream;\n\n/**\n * A transformer for stream data that also provides a response.\n * Used primarily to transform and consume stream data while producing a response object.\n *\n * @template T The type of data being transformed\n * @template R The type of the response (defaults to Response)\n */\nexport type StreamTransformer<T, R = Response> = {\n transform(data: T): T;\n close(): void;\n response: R;\n};\n\n/**\n * Pump is an asynchronous stream processing pipeline with fluent operators.\n * It provides a comprehensive set of operations for transforming, filtering, batching,\n * combining, and consuming stream data.\n *\n * The Pump class follows a builder pattern where each operation returns a new Pump instance,\n * allowing for chaining of operations to build complex stream processing pipelines.\n *\n * @template T The type of data contained in the stream\n */\nexport class Pump<T> {\n constructor(private readonly src: MessageStream<T>) {}\n\n /**\n * Wrap an existing AsyncIterable or Readable stream into a Pump\n *\n * @template U The type of data in the source stream\n * @param source The source stream to convert to a Pump (AsyncIterable, ReadableStream, or NodeJS.ReadableStream)\n * @returns A new Pump instance that wraps the source\n */\n static from<U>(source: Source<U>): Pump<U> {\n async function* gen(): AsyncGenerator<StreamChunk<U>> {\n let seq = 0;\n\n // Type guard functions to narrow the type\n function isAsyncIterable(obj: Source<U>): obj is AsyncIterable<U> {\n return Symbol.asyncIterator in obj;\n }\n\n function isWebReadableStream(obj: Source<U>): obj is ReadableStream {\n return 'getReader' in obj && typeof obj.getReader === 'function';\n }\n\n function isNodeReadableStream(\n obj: Source<U>\n ): obj is NodeJS.ReadableStream {\n return (\n 'pipe' in obj &&\n 'on' in obj &&\n typeof obj.pipe === 'function' &&\n typeof obj.on === 'function'\n );\n }\n\n if (isAsyncIterable(source)) {\n // Handle AsyncIterable\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (true) {\n const result = await iterator.next();\n if (result.done) break;\n yield {\n sequence: seq++,\n data: result.value,\n done: false,\n };\n }\n } finally {\n // No need to clean up AsyncIterator\n }\n } else if (isWebReadableStream(source)) {\n // Handle Web API ReadableStream\n const reader = source.getReader();\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) break;\n yield {\n sequence: seq++,\n data: result.value as U,\n done: false,\n };\n }\n } finally {\n reader.releaseLock();\n }\n } else if (isNodeReadableStream(source)) {\n // Handle Node.js ReadableStream\n try {\n // Convert Node stream to an AsyncIterable\n for await (const chunk of source) {\n yield {\n sequence: seq++,\n data: chunk as U,\n done: false,\n };\n }\n } catch (error) {\n console.error('Error reading from Node.js stream:', error);\n throw error;\n }\n }\n\n // final done signal\n yield { sequence: seq, data: undefined as unknown as U, done: true };\n }\n return new Pump<U>(gen()) as Pump<U>;\n }\n\n /**\n * Sync or async map over the data portion of each chunk\n *\n * @template U The output type after transformation\n * @param fn The mapping function that transforms each chunk\n * @returns A new Pump instance with the transformed data\n */\n map<U>(fn: (data: T) => U | Promise<U>): Pump<U> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<U>> {\n for await (const { sequence, data, done } of this.src) {\n if (done) {\n const out = data !== undefined ? await fn(data) : undefined;\n yield { sequence, data: out as unknown as U, done };\n break;\n }\n\n const out = await fn(data);\n yield { sequence, data: out, done };\n }\n }\n return new Pump<U>(gen.call(this));\n }\n\n /**\n * Stateful map allows processing stream chunks with a persistent context object.\n *\n * The context is initialized when the first chunk arrives and can be updated with each chunk.\n * This is useful for maintaining state across the stream processing.\n *\n * If you plan to use sockets you should rather opt for asyncStatefulMap.\n *\n * The pipe closes only after all processing is complete, including any final operations in onClose.\n *\n * TODO: Un-tested\n *\n * @param handlers Object containing callback functions for stream processing\n * @param handlers.onFirstChunk Function called when the first chunk arrives, initializes the context\n * @param handlers.onChunk Function called for each subsequent chunk, updates the context\n * @param handlers.onClose Optional function called when the stream closes, allows final processing\n * @returns A new Pump instance with transformed data\n */\n statefulMap<Context, U = T>(handlers: {\n onFirstChunk(\n chunk: T,\n yieldData: (data: U) => void\n ): Context | Promise<Context>;\n onChunk(\n chunk: T,\n context: Context,\n yieldData: (data: U) => void\n ): Context | Promise<Context>;\n onClose?(\n lastChunk: T | undefined,\n context: Context,\n yieldData: (data: U) => void\n ): void | Promise<void>;\n }): Pump<U> {\n const { src } = this;\n\n const gen = async function* (): AsyncGenerator<StreamChunk<U>> {\n let context: Context | undefined;\n let initialized = false;\n let lastChunk: T | undefined;\n let seq = 0;\n\n const queue: U[] = [];\n const yieldData = (data: U): void => {\n queue.push(data);\n };\n\n // <- here ->\n\n for await (const { data, done } of src) {\n if (done) {\n if (context && handlers.onClose) {\n await handlers.onClose(lastChunk, context, yieldData);\n }\n\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n\n yield {\n sequence: seq++,\n data: undefined as unknown as U,\n done: true,\n };\n break;\n }\n if (!initialized) {\n context = await handlers.onFirstChunk(data, yieldData);\n initialized = true;\n } else if (context) {\n context = await handlers.onChunk(data, context, yieldData);\n }\n\n lastChunk = data;\n\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n }\n };\n\n return new Pump<U>(gen());\n }\n\n /**\n * Async map means that each incoming chunk is causing an async operation that when it completes\n * should yield a new chunk.\n * The pipe closes only after you unlock the pipe by using the unlockCloseEvent callback.\n *\n * Stateful refers to the fact that you can create your own small context object that is passed in the subsequent callbacks.\n * This allows you to keep track of things like a socket connection.\n *\n * Why is this nice? Well if you use things like a socket the pipe might have received the close event,\n * before you got any or all of your socket responses. Sockets don't fit into the standard promise pattern,\n * which makes it harder to wait for them.\n *\n * TODO: Un-tested\n *\n * @param handlers Object containing callback functions for stream processing\n * @param handlers.onFirstChunk Function called when the first chunk arrives, initializes the context\n * @param handlers.onChunk Function called for each subsequent chunk, updates the context\n * @param handlers.onClose Optional function called when the stream closes, allows final processing\n * @returns A new Pump instance with transformed data\n */\n asyncStatefulMap<Context, U = T>(handlers: {\n onFirstChunk(\n chunk: T,\n yieldData: (data: U) => void,\n unlockCloseEvent: () => void\n ): Context | Promise<Context>;\n onChunk(\n chunk: T,\n context: Context,\n yieldData: (data: U) => void,\n unlockCloseEvent: () => void\n ): Context | Promise<Context>;\n onClose?(\n lastChunk: T | undefined,\n context: Context,\n yieldData: (data: U) => void,\n unlockCloseEvent: () => void\n ): void | Promise<void>;\n }): Pump<U> {\n const { src } = this;\n\n const gen = async function* (): AsyncGenerator<StreamChunk<U>> {\n let context: Context | undefined;\n let initialized = false;\n let lastChunk: T | undefined;\n let seq = 0;\n let lockedCloseEvent = true;\n\n const queue: U[] = [];\n const yieldData = (data: U): void => {\n queue.push(data);\n };\n const unlockCloseEvent = (): void => {\n lockedCloseEvent = false;\n };\n\n for await (const { data, done } of src) {\n if (done) {\n if (context && handlers.onClose) {\n await handlers.onClose(\n lastChunk,\n context,\n yieldData,\n unlockCloseEvent\n );\n }\n\n const timestamp = Date.now();\n // wait until the pipe is unlocked\n while (lockedCloseEvent && Date.now() - timestamp < 10_000) {\n // First emit all data in the queue\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n // put on top of event loop / call stack\n await new Promise((resolve) => setTimeout(resolve, 5));\n }\n\n // First emit all data in the queue\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n\n yield {\n sequence: seq++,\n data: undefined as unknown as U,\n done: true,\n };\n break;\n }\n if (!initialized) {\n context = await handlers.onFirstChunk(\n data,\n yieldData,\n unlockCloseEvent\n );\n initialized = true;\n } else if (context) {\n context = await handlers.onChunk(\n data,\n context,\n yieldData,\n unlockCloseEvent\n );\n }\n\n lastChunk = data;\n\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n }\n };\n\n return new Pump<U>(gen());\n }\n\n /**\n * Filter items based on a predicate\n *\n * @param predicate A function that determines whether to keep each chunk\n * @returns A new Pump instance containing only chunks that passed the predicate\n */\n filter(predicate: (data: T) => boolean | Promise<boolean>): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n for await (const { sequence, data, done } of this.src) {\n if (done) {\n yield { sequence, data, done: true };\n break;\n }\n\n const keep = await predicate(data);\n if (keep) {\n yield { sequence, data, done: false };\n }\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Bundles (accumulates) chunks together based on a condition rather than a fixed size.\n *\n * This is useful when you need to group chunks dynamically based on their content or other criteria.\n *\n * Example: Bundling text chunks with a maximum character limit\n *\n * Input chunks: [\"Hello\", \" this\", \" is\", \" a few\", \" chunks\", \" of text\"]\n * With max size of 10 characters:\n * - First bundle: [\"Hello\", \" this\"] (10 chars)\n * - Second bundle: [\" is\", \" a few\"] (8 chars)\n * - Third bundle: [\" chunks\", \" of text\"] (13 chars)\n *\n * @param closeBundleCondition - Function that determines when to close the current bundle\n * Returns true when the current bundle should be emitted\n * Parameters:\n * - chunk: The current chunk being processed\n * - accumulatedChunks: Array of chunks in the current bundle\n *\n * @returns A pump that emits arrays of bundled items\n */\n bundle(\n closeBundleCondition: (\n chunk: T,\n accumulatedChunks: Array<T>\n ) => boolean | Promise<boolean>\n ): Pump<Array<T>> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<Array<T>>> {\n let buffer: Array<T> = [];\n let lastSequence = 0;\n\n for await (const { sequence, data, done } of this.src) {\n lastSequence = sequence;\n\n if (done) {\n // Emit any remaining items in the buffer when the stream ends\n if (buffer.length > 0) {\n yield { sequence, data: [...buffer], done: false };\n }\n // Emit the termination signal\n yield {\n sequence: lastSequence,\n data: undefined as unknown as Array<T>,\n done: true,\n };\n break;\n }\n\n const shouldClose = await closeBundleCondition(data, buffer);\n buffer.push(data);\n\n if (shouldClose) {\n yield {\n sequence: lastSequence,\n data: [...buffer],\n done: false,\n };\n buffer = [];\n }\n }\n }\n return new Pump<Array<T>>(gen.call(this));\n }\n\n /**\n * Tap into each chunk without altering it\n *\n * @param fn A function that receives each chunk but doesn't affect the stream\n * @returns The same pump instance with unmodified data\n */\n onChunk(fn: (chunk: T) => void | Promise<void>): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n for await (const chunk of this.src) {\n if (chunk.data === undefined && chunk.done) {\n // Yield early since we don't need to tap into a closing signal (unless it contains data)\n yield chunk;\n }\n\n await fn(chunk.data);\n yield chunk;\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Collect all chunks in the stream and run a callback when the stream is done.\n * The callback receives an array of all chunks that passed through.\n *\n * This is useful for analytics, logging, or processing the complete stream history\n * after all chunks have been received.\n *\n * @param fn - Callback function that receives the array of all chunks when the stream is complete\n * @returns The same pump, for chaining\n */\n onClose(fn: (history: T[]) => void | Promise<void>): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n const history: T[] = [];\n\n for await (const chunk of this.src) {\n // Add non-done chunks to history\n if (chunk.data !== undefined) {\n history.push(chunk.data);\n }\n\n // If we've reached the end, run the callback\n if (chunk.done) {\n await fn(history);\n }\n\n // Pass through the chunk unchanged\n yield chunk;\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Batch `n` chunks into arrays before emitting\n *\n * @param n The number of chunks to batch together\n * @returns A new Pump instance that emits arrays of batched chunks\n */\n batch(n: number): Pump<Array<T>> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<Array<T>>> {\n let buffer: StreamChunk<T>[] = [];\n\n for await (const chunk of this.src) {\n if (chunk.done) {\n // Termination signal edge case handling\n if (chunk.data === undefined) {\n // Flush the rest\n yield {\n sequence: buffer[0].sequence,\n data: buffer.map((c) => c.data),\n done: false,\n };\n\n // and then emit the termination signal\n yield {\n sequence: chunk.sequence,\n data: undefined as unknown as Array<T>,\n done: true,\n };\n buffer = [];\n } else {\n // in that case the termination signal contains data\n // so we need to emit this as a closing singal with the rest of the buffer\n buffer.push(chunk);\n yield {\n sequence: buffer[0].sequence,\n data: buffer.map((c) => c.data),\n done: true,\n };\n }\n\n break;\n }\n\n // Normal case\n\n buffer.push(chunk);\n\n if (buffer.length === n) {\n yield {\n sequence: buffer[0].sequence,\n data: buffer.map((c) => c.data),\n done: chunk.done,\n };\n buffer = [];\n }\n }\n }\n return new Pump<Array<T>>(gen.call(this));\n }\n\n /**\n * If you want to prevent chunk starvation, you can buffer the chunks.\n * Chunks will not be bundled into arrays or object but kept as is,\n * but the pipeline will not progress at that segment until the buffer is filled up.\n * Once a buffer is filled up it will drain and never buffer again.\n *\n * @param n The number of chunks to buffer before processing continues\n * @returns A new Pump instance with buffering behavior\n */\n buffer(n: number): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n let buffer: StreamChunk<T>[] = [];\n let bufferFilled = false;\n\n for await (const chunk of this.src) {\n if (!bufferFilled) {\n if (!chunk.done) {\n buffer.push(chunk);\n }\n\n // If buffer is filled or we've reached the end of the stream\n if (buffer.length >= n || chunk.done) {\n bufferFilled = true;\n // Yield all buffered chunks\n for (const bufferedChunk of buffer) {\n yield bufferedChunk;\n }\n if (chunk.done) {\n yield {\n sequence: chunk.sequence,\n data: undefined as unknown as T,\n done: true,\n };\n break;\n }\n buffer = [];\n }\n } else {\n // After buffer is filled, just pass chunks through\n yield chunk;\n }\n }\n\n // Yield any remaining chunks in the buffer\n for (const bufferedChunk of buffer) {\n yield bufferedChunk;\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Rechunk the stream: transform one chunk into zero, one, or many output chunks.\n * The handler function receives the current buffer of chunks, a push function to emit new chunks,\n * and a flag indicating if this is the last chunk in the stream.\n *\n * @param handler Function that transforms chunks and pushes new ones\n * @returns A new Pump instance with rechunked data\n */\n rechunk(\n handler: (params: {\n buffer: T[];\n push: (chunk: T) => void;\n lastChunk: boolean;\n setBuffer: (buffer: T[]) => void;\n }) => void | Promise<void>\n ): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n let buffer: Array<T> = [];\n let seq = 0;\n const pending: Array<T> = [];\n\n const push = (chunk: T): void => {\n pending.push(chunk);\n };\n\n for await (const { data, done } of this.src) {\n if (!done) {\n if (data !== undefined) {\n buffer.push(data);\n }\n await handler({\n buffer,\n push,\n lastChunk: false,\n setBuffer: (b: T[]) => {\n buffer = b;\n },\n });\n } else {\n await handler({\n buffer,\n push,\n lastChunk: true,\n setBuffer: (b: T[]) => {\n buffer = b;\n },\n });\n }\n\n while (pending.length > 0) {\n const out = pending.shift()!;\n yield { sequence: seq++, data: out, done: false };\n }\n\n if (done) {\n break;\n }\n }\n\n yield { sequence: seq, data: undefined as unknown as T, done: true };\n }\n\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Emit sliding windows of the last `size` items with step `step`.\n * Each window is an array [current, previous1, ..., previous(size-1)].\n * Optionally, map each window through a function.\n *\n * | Step | Window | Resulting Window |\n * |------|--------|------------------|\n * | 1 | ▪︎▪︎[▪︎▫︎▫︎] | ▪︎▫︎▫︎ |\n * | 2 | ▪︎[▪︎▪︎▫︎] | ▪︎▪︎▫︎ |\n * | 3 | [▪︎▪︎▪︎] | ▪︎▪︎▪︎ |\n * | 4 | [▫︎▪︎▪︎] | ▫︎▪︎▪︎ |\n * | 5 | [▫︎▫︎▪︎] | ▫︎▫︎▪ |\n *\n * @param size The size of each window\n * @param step The number of items to move between windows\n * @returns A Pump that emits arrays representing sliding windows\n */\n slidingWindow(size: number, step: number): Pump<Array<T | undefined>>;\n /**\n * Emit sliding windows of the last `size` items with step `step`,\n * and map each window using the provided function.\n *\n * @template N The size type parameter (extends number)\n * @template U The output type after window transformation\n * @param size The size of each window\n * @param step The number of items to move between windows\n * @param fn A function to transform each window\n * @returns A Pump that emits transformed sliding windows\n */\n slidingWindow<N extends number, U>(\n size: N,\n step: number,\n fn: (window: Array<T | undefined>) => U | Promise<U>\n ): Pump<U>;\n slidingWindow<U>(\n size: number,\n step: number,\n fn?: (window: Array<T | undefined>) => U | Promise<U>\n ): Pump<Array<T | undefined>> | Pump<U> {\n async function* gen(\n this: Pump<T>\n ): AsyncGenerator<StreamChunk<Array<T | undefined>>> {\n const history: Array<T> = [];\n let offset = 0;\n let lastSeq = 0;\n\n function buildWindow(\n _offset: number,\n _size: number,\n _history: Array<T>\n ): Array<T | undefined> {\n const window: Array<T | undefined> = Array(_size).fill(undefined);\n let windowIndex = 0;\n\n for (let i = _offset; i > _offset - _size; i -= step) {\n if (i >= history.length) {\n windowIndex++;\n // we can skip this since we are filling the blank spots with undefined\n continue;\n }\n\n if (i < 0) {\n break;\n }\n\n window[windowIndex] = _history[i]; // the window follows the analoy so its filled reversed from the graphic\n windowIndex++;\n }\n\n return window;\n }\n\n for await (const { sequence, data, done } of this.src) {\n if (done) {\n // if we are done that means we are not receiving any more signals to push the window\n // so we have to emit the last window steps\n // [▪︎▪︎▫︎]\n // [▪︎▫︎▫︎]\n for (let i = 0; i < size - 1; i++) {\n const window = buildWindow(offset + i, size, history);\n yield { sequence: lastSeq, data: window, done: false };\n }\n\n if (data === undefined) {\n // final done signal\n yield {\n sequence: lastSeq,\n data: undefined as unknown as Array<T>,\n done: true,\n };\n } else {\n // final done signal\n yield {\n sequence: lastSeq,\n data: [\n history[history.length - 2] ?? undefined,\n history[history.length - 3] ?? undefined,\n history[history.length - 1],\n ],\n done: true,\n };\n }\n break;\n }\n\n lastSeq = sequence;\n history.push(data);\n\n // the rolling window goes from the oldest to the newest and pushes it self\n // with a step length. The analogy of the pipe shifts the window from right to left\n // but the array appends to the end. So in this implementation we are shifting from left to right.\n\n // lets calculate the window indexes\n // [▫︎▫︎▪︎]▪︎▪︎\n // [▫︎▪︎▪︎]▪︎\n // [▪︎▪︎▪︎]\n // [▪︎▪︎▫︎] <- this case is handled above\n // [▪︎▫︎▫︎] <- this case is handled above\n const window = buildWindow(offset, size, history);\n\n yield { sequence, data: window, done: false };\n offset++;\n }\n }\n const base = new Pump<Array<T | undefined>>(gen.call(this));\n // If fn is provided, map over the window, otherwise return the window as is\n return fn\n ? base.map(fn as (window: Array<T | undefined>) => U)\n : (base as Pump<Array<T | undefined>>);\n }\n\n /**\n * Sequentially flatten inner stream sources emitted by the pipeline.\n * Works with any Source type (AsyncIterable or ReadableStream).\n * This method is only available when the current Pump contains Source elements.\n *\n * @template U The type of data in the inner streams\n * @template F The type of inner stream source (extends Source<U>)\n * @returns A Pump instance with flattened stream data\n */\n sequenceStreams<U, F extends Source<U>>(this: Pump<F>): Pump<U> {\n async function* gen(this: Pump<F>): AsyncGenerator<StreamChunk<U>> {\n let seq = 0;\n\n for await (const { data: innerSource, done: outerDone } of this.src) {\n if (outerDone) break;\n\n // Convert the inner source to a pump first\n const innerPump = Pump.from(innerSource as unknown as Source<U>);\n\n // Then extract all items from it\n for await (const { data, done } of innerPump.src) {\n if (done) break;\n yield { sequence: seq++, data: data as U, done: false };\n }\n }\n\n yield { sequence: seq, data: undefined as unknown as U, done: true };\n }\n return new Pump<U>(gen.call(this));\n }\n\n /**\n * Fork the stream: two independent Pump<T> consumers\n * Both resulting Pumps will receive the same data, allowing for divergent processing paths.\n *\n * @returns An array containing two independent Pump instances with the same source data\n */\n fork(): [Pump<T>, Pump<T>] {\n const buffers: StreamChunk<T>[][] = [[], []];\n let done = false;\n const srcIter = this.src[Symbol.asyncIterator]();\n\n async function fill(): Promise<void> {\n const { value, done: streamDone } = await srcIter.next();\n if (streamDone) {\n done = true;\n return;\n }\n buffers.forEach((q) => q.push(value));\n if (value.done) done = true;\n }\n\n function makeStream(buf: StreamChunk<T>[]): MessageStream<T> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<StreamChunk<T>> {\n return {\n async next(): Promise<IteratorResult<StreamChunk<T>>> {\n while (buf.length === 0 && !done) {\n await fill();\n }\n if (buf.length === 0)\n return {\n done: true,\n value: undefined as unknown as StreamChunk<T>,\n };\n return { done: false, value: buf.shift()! };\n },\n };\n },\n };\n }\n\n return [new Pump(makeStream(buffers[0])), new Pump(makeStream(buffers[1]))];\n }\n\n /**\n * Drain the pipeline, consuming all chunks.\n * Returns a Promise that resolves when all chunks have been consumed.\n *\n * @returns A Promise that resolves when all chunks have been consumed\n */\n drain(): Promise<void> {\n return (async (): Promise<void> => {\n for await (const { done } of this.src) {\n if (done) break;\n }\n })();\n }\n\n /**\n * Drain the pipeline to a StreamTransformer.\n * Applies transform() to each data chunk, then closes the transformer,\n * and returns its response (which can be of any type defined by the transformer).\n *\n * Example with httpStreamResponse:\n * ```\n * const { transform, response, close } = httpStreamResponse(options);\n * return Pump.from(messageStream).drainTo({ transform, close, response });\n * ```\n *\n * @template U The type of data expected by the transformer (extends T)\n * @template R The response type produced by the transformer\n * @param transformer The StreamTransformer to drain to\n * @returns The response from the transformer\n */\n drainTo<U extends T, R>(transformer: StreamTransformer<U, R>): R {\n (async (): Promise<void> => {\n for await (const { data, done } of this.src) {\n if (done) break;\n transformer.transform(data as unknown as U);\n }\n transformer.close();\n })();\n return transformer.response;\n }\n}\n\n// ----------------------------------------------------------\n// Example usage in Next.js App Router (e.g. app/api/stream/route.ts)\n//\n// import { NextRequest } from 'next/server';\n// import { Pump } from '@m4trix/core/stream';\n// import { /*...*/ } from '@/lib';\n\n// export async function POST(req: NextRequest) {\n// // Process the incoming audio request\n// const formData = await req.formData();\n// const transcript = await transcribeFormData(formData);\n// const agentStream = await getAgentResponse(transcript);\n\n// // Process and return the stream\n// return await Pump.from(agentStream)\n// .filter(shouldChunkBeStreamed)\n// .map(messageToText)\n// .bundle(intoChunksOfMinLength(40))\n// .map((text) => text.join(\"\")) // convert array of strings to string\n// .rechunk(ensureFullWords)\n// .rechunk(fixBrokenWords)\n// .onClose(handleCompletedAgentResponse)\n// .slidingWindow(10, 1)\n// .filter(filterOutIrrelevantWindows)\n// .buffer(5)\n// .map(textToSpeech)\n// .sequenceStreams()\n// .drainTo(httpStreamResponse());\n// }\n","import { StreamTransformer } from '../..';\n\nexport interface HttpStreamOptions<T> {\n /** HTTP ResponseInit (status, headers, etc.) */\n init?: ResponseInit;\n /** Encode each chunk of type T into bytes or string */\n encoder?: (data: T) => Uint8Array | string;\n}\n\n/**\n * Create a streaming HTTP response transformer.\n * Returns an object with:\n * - transform: function to write each chunk into the response\n * - response: the Fetch API Response ready to return\n * - close: function to close the stream when done\n *\n * Usage in a Next.js route:\n * ```\n * // With the new drainTo API:\n * const transformer = httpStreamResponse(options);\n * return Pump.from(messageStream).drainTo(transformer);\n *\n * // Or with manual control:\n * const { transform, response, close } = httpStreamResponse(options);\n * await Pump.from(messageStream).map(transform).drain();\n * close();\n * return response;\n * ```\n */\nexport function httpStreamResponse<T>(\n options: HttpStreamOptions<T> = {}\n): StreamTransformer<T, Response> {\n const { init, encoder } = options;\n const encodeFn =\n encoder ??\n ((d: T): Uint8Array | string => {\n if (d instanceof Uint8Array) return d;\n if (typeof d === 'string') return d;\n return JSON.stringify(d);\n });\n\n // Create a transform stream of Uint8Array\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n const response = new Response(readable, init);\n\n const transform = (chunk: T): T => {\n const encoded = encodeFn(chunk);\n const bytes =\n typeof encoded === 'string' ? new TextEncoder().encode(encoded) : encoded;\n writer.write(bytes);\n return chunk;\n };\n\n const close = (): void => {\n writer.close();\n };\n\n return { transform, response, close };\n}\n","/**\n * A helper to be used with Pump.rechunk that ensures full word chunks.\n * Aggregates incoming chunks and emits only when a full word boundary is reached.\n */\nexport async function ensureFullWords({\n buffer,\n push,\n lastChunk,\n}: {\n buffer: string[];\n push: (chunk: string) => void;\n lastChunk: boolean;\n}): Promise<void> {\n const combined = buffer.join('');\n const lastBoundary = Math.max(\n combined.lastIndexOf(' '),\n combined.lastIndexOf('\\n'),\n combined.lastIndexOf('\\t')\n );\n\n if (lastBoundary !== -1 || lastChunk) {\n const emitPart =\n lastBoundary !== -1 ? combined.slice(0, lastBoundary + 1) : combined;\n const leftoverPart =\n lastBoundary !== -1 ? combined.slice(lastBoundary + 1) : '';\n\n if (emitPart.trim().length > 0) {\n push(emitPart);\n }\n\n buffer.length = 0;\n if (leftoverPart.length > 0) {\n buffer.push(leftoverPart);\n }\n }\n}\n","import { Socket } from 'socket.io';\nimport { Hooks, SetupSocketHandlersParams } from './socket-factory-types';\n\nexport class SocketIoFactory {\n private socket: Socket;\n private prefix: string;\n private hooks: Hooks<Socket>;\n\n private constructor(socket: Socket, prefix: string, hooks: Hooks<Socket>) {\n this.socket = socket;\n this.prefix = prefix;\n this.hooks = hooks;\n }\n\n static setupSocketHandlers({\n enableVoiceEvents,\n enableChatEvents,\n enableTranscriptEvents,\n prefix = '',\n socket,\n hooks,\n }: SetupSocketHandlersParams<\n Socket,\n {\n socket: Socket;\n }\n >): void {\n // Adapter will override the hooks\n\n const factory = new SocketIoFactory(socket, prefix, hooks!);\n if (enableVoiceEvents) {\n factory.setupVoiceEvents();\n }\n\n if (enableChatEvents) {\n factory.setupChatEvents(socket);\n }\n\n if (enableTranscriptEvents) {\n factory.setupTranscriptEvents(socket);\n }\n }\n\n private setupVoiceEvents(): void {\n const {\n onVoiceInputFile,\n onVoiceInputChunk,\n onVoiceInputCommit,\n onVoiceOutputDelta,\n onVoiceOutputCommit,\n onVoiceOutputFile,\n onVoiceOutputTranscriptDelta,\n onVoiceOutputTranscriptFull,\n } = this.hooks;\n\n const prefix = this.prefixEvent;\n\n if (onVoiceInputFile) {\n this.socket.on(prefix('voice:input_file'), onVoiceInputFile);\n }\n\n if (onVoiceInputChunk) {\n this.socket.on(prefix('voice:input_chunk'), onVoiceInputChunk);\n }\n\n if (onVoiceInputCommit) {\n this.socket.on(prefix('voice:input_commit'), onVoiceInputCommit);\n }\n\n if (onVoiceOutputDelta) {\n this.socket.on(prefix('voice:output_delta'), onVoiceOutputDelta);\n }\n\n if (onVoiceOutputCommit) {\n this.socket.on(prefix('voice:output_commit'), onVoiceOutputCommit);\n }\n\n if (onVoiceOutputFile) {\n this.socket.on(prefix('voice:output_file'), onVoiceOutputFile);\n }\n\n if (onVoiceOutputTranscriptDelta) {\n this.socket.on(\n prefix('voice:output_transcript_delta'),\n onVoiceOutputTranscriptDelta\n );\n }\n\n if (onVoiceOutputTranscriptFull) {\n this.socket.on(\n prefix('voice:output_transcript_full'),\n onVoiceOutputTranscriptFull\n );\n }\n }\n\n private setupChatEvents(_socket: Socket): void {\n // TODO: Implement chat event handler\n }\n\n private setupTranscriptEvents(_socket: Socket): void {\n // TODO: Implement transcript event handlers\n }\n\n private prefixEvent(event: string): string {\n return this.prefix ? `${this.prefix}:${event}` : event;\n }\n}\n","import { BaseMessage, AIMessage, ToolMessage } from '@langchain/core/messages';\nimport { Effect, pipe } from 'effect';\nimport {\n MessageFilter,\n MessageFilterType,\n typeOnFilter,\n} from './message-filter';\nimport { FormatType, typeOnFormatter } from './formatter';\n\n/**\n * # Transform Messages\n * In order to manage the context size often you want to slice messages or only pass certain types of messages.\n * This class is a helper to do that.\n *\n * ## Example\n * ```ts\n * const messages = [\n * new HumanMessage('Hello, how are you?'),\n * new AIMessage('I am good, thank you!'),\n * ];\n *\n * const transformedMessages = TransformMessages.from(messages).filter(HumanAndAI).last(10).format(FormatType.Concise);\n *\n * ```\n */\n\nclass TransformMessages {\n private effect: Effect.Effect<Array<BaseMessage>, never, never>;\n\n private constructor(effect: Effect.Effect<Array<BaseMessage>, never, never>) {\n this.effect = effect;\n }\n\n /**\n * Create a new TransformMessages from an array of messages.\n */\n static from(messages: Array<BaseMessage>): TransformMessages {\n return new TransformMessages(Effect.succeed(messages));\n }\n\n /**\n * Filter messages based on a predicate function\n */\n filter(\n predicate: MessageFilter | MessageFilterType,\n tags?: Array<string>\n ): TransformMessages {\n let finalPredicate: MessageFilter;\n if (typeof predicate === 'string') {\n finalPredicate = typeOnFilter[predicate];\n } else {\n finalPredicate = predicate;\n }\n\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) =>\n messages.filter((message) => finalPredicate(message, tags))\n )\n )\n );\n }\n\n /**\n * Take only the last n messages, but safely.\n * Tool calls should not be separated from the last human message.\n * Ensures all tool call conversations in the last n messages are complete.\n */\n safelyTakeLast(\n n: number,\n pruneAfterNOvershootingMessages: number = 0\n ): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => {\n const total = messages.length;\n if (n <= 0 || total === 0) return [];\n\n // Start with the last n messages\n const start = Math.max(0, total - n);\n const end = total;\n const lastSlice = messages.slice(start, end);\n\n // due to the fact that the calling AI message needs to be adjecent to the succeeding tool call message\n // we just need to check the last n messages for tool call ids\n\n // Check the first message if it is a tool call message\n // if it is iterate backwards until we find the AI message\n if (\n lastSlice[0] instanceof ToolMessage &&\n lastSlice[0].tool_call_id\n ) {\n let messagesToInclude: Array<BaseMessage> = [];\n const remainingMessages = messages.slice(0, start);\n for (let i = remainingMessages.length - 1; i >= 0; i--) {\n const msg = remainingMessages[i];\n if (\n pruneAfterNOvershootingMessages > 0 &&\n messagesToInclude.length - 1 >= pruneAfterNOvershootingMessages\n ) {\n messagesToInclude = [];\n // Return the slice but remove all the tool call messages that are at the beginning of the slice\n const filteredSlice: Array<BaseMessage> = [];\n let foundFirstNonToolMessage = false;\n for (let i = 0; i < lastSlice.length; i++) {\n const msg = lastSlice[i];\n if (msg instanceof ToolMessage) {\n if (foundFirstNonToolMessage) {\n filteredSlice.push(msg);\n }\n } else {\n foundFirstNonToolMessage = true;\n filteredSlice.push(msg);\n }\n }\n return filteredSlice;\n }\n if (msg instanceof AIMessage && Array.isArray(msg.tool_calls)) {\n messagesToInclude.push(msg);\n break;\n } else if (msg instanceof ToolMessage) {\n messagesToInclude.push(msg);\n } else {\n // This should not happen messages invalid\n throw new Error(\n 'Messages array invalid no adjacent AI message found'\n );\n }\n }\n return [...messagesToInclude.reverse(), ...lastSlice];\n } else {\n return lastSlice;\n }\n })\n )\n );\n }\n\n /**\n * Take only the last n messages\n */\n last(n: number): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => messages.slice(-n))\n )\n );\n }\n\n /**\n * Take only the first n messages\n */\n first(n: number): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => messages.slice(0, n))\n )\n );\n }\n\n /**\n * Skip the first n messages\n */\n skip(n: number): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => messages.slice(n))\n )\n );\n }\n\n /**\n * Reverse the order of messages\n */\n reverse(): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => [...messages].reverse())\n )\n );\n }\n\n /**\n * Map over messages with a transformation function\n */\n map<T extends BaseMessage>(\n fn: (message: BaseMessage) => T\n ): TransformMessages {\n return new TransformMessages(\n pipe(\n this.effect,\n Effect.map((messages) => messages.map(fn))\n )\n );\n }\n\n /**\n * Format messages according to the specified format type\n */\n format(formatType: FormatType): string {\n const result = Effect.runSync(\n pipe(\n this.effect,\n Effect.map((messages) => {\n if (formatType === FormatType.JSON) {\n return JSON.stringify(messages, null, 2);\n }\n const formatter = typeOnFormatter[formatType];\n return formatter(messages);\n })\n )\n );\n return result;\n }\n\n // Sink methods\n\n /**\n * Convert to array - runs the effect and returns the result\n return pipe(\n this.effect,\n Effect.map((messages) => {\n if (formatType === FormatType.JSON) {\n return JSON.stringify(messages, null, 2);\n }\n\n const formatter = typeOnFormatter[formatType];\n return formatter(messages);\n })\n );\n }\n\n // Sink methods\n\n /**\n * Convert to array - runs the effect and returns the result\n */\n toArray(): Array<BaseMessage> {\n return Effect.runSync(this.effect);\n }\n\n /**\n * Convert to string - runs the effect and returns JSON string\n */\n toString(): string {\n const result = Effect.runSync(\n pipe(\n this.effect,\n Effect.map((messages) => JSON.stringify(messages, null, 2))\n )\n );\n return result;\n }\n\n /**\n * Get the count of messages\n */\n count(): number {\n const result = Effect.runSync(\n pipe(\n this.effect,\n Effect.map((messages) => messages.length)\n )\n );\n return result;\n }\n}\n\nexport { TransformMessages };\n","import { BaseMessage, HumanMessage, AIMessage } from '@langchain/core/messages';\n\n// Type for message filters\nexport type MessageFilter = (\n message: BaseMessage,\n tags?: Array<string>\n) => boolean;\n// Predefined filters\nconst humanAndAI: MessageFilter = (message) =>\n message instanceof HumanMessage || message instanceof AIMessage;\nconst humanOnly: MessageFilter = (message) => message instanceof HumanMessage;\nconst aiOnly: MessageFilter = (message) => message instanceof AIMessage;\n\nconst includingTags: MessageFilter = (message, tags) => {\n if (tags) {\n return tags.some((tag) =>\n Array.isArray(message.additional_kwargs?.tags)\n ? message.additional_kwargs?.tags.includes(tag)\n : false\n );\n }\n return true;\n};\n\nconst excludingTags: MessageFilter = (message, tags) => {\n if (tags) {\n return !tags.some((tag) =>\n Array.isArray(message.additional_kwargs?.tags)\n ? message.additional_kwargs?.tags.includes(tag)\n : false\n );\n }\n return true;\n};\n\nexport enum MessageFilterType {\n HumanAndAI = 'HumanAndAI',\n HumanOnly = 'HumanOnly',\n AIOnly = 'AIOnly',\n IncludingTags = 'IncludingTags',\n ExcludingTags = 'ExcludingTags',\n}\nexport const typeOnFilter = {\n [MessageFilterType.HumanAndAI]: humanAndAI,\n [MessageFilterType.HumanOnly]: humanOnly,\n [MessageFilterType.AIOnly]: aiOnly,\n [MessageFilterType.IncludingTags]: includingTags,\n [MessageFilterType.ExcludingTags]: excludingTags,\n};\n","import { AIMessage, BaseMessage } from '@langchain/core/messages';\n\n// Format types\nexport enum FormatType {\n Concise = 'concise',\n Verbose = 'verbose',\n RedactAi = 'redact-ai',\n RedactHuman = 'redact-human',\n JSON = 'json',\n}\n\n/**\n * Formats messages in a concise markdown format with alternating AI and Human prefixes.\n *\n * ### Example\n * ```markdown\n * AI: Hello, how are you?\n * Human: I am good, thank you!\n * AI: What is your name?\n * Human: My name is John.\n * AI: What is your favorite color?\n * Human: My favorite color is blue.\n * AI: What is your favorite food?\n * Human: My favorite food is pizza.\n * ```\n */\nfunction concise(messages: Array<BaseMessage>): string {\n return messages\n .map((message) => {\n const prefix = message instanceof AIMessage ? 'AI' : 'Human';\n return `${prefix}: ${message.content}`;\n })\n .join('\\n');\n}\n\n/**\n * Formats messages in a verbose markdown format with alternating AI and Human prefixes.\n *\n * ### Example\n * ```markdown\n * AI:\n * Hello, how are you?\n * -------------------\n * Human:\n * I am good, thank you!\n * -------------------\n * AI:\n * What is your name?\n * -------------------\n * Human:\n * My name is John.\n * ```\n */\nfunction verbose(messages: Array<BaseMessage>): string {\n return messages\n .map((message) => {\n const prefix = message instanceof AIMessage ? 'AI' : 'Human';\n return `${prefix}:\\n${message.content}`;\n })\n .join('\\n-------------------\\n');\n}\n\n/**\n * Formats messages in a concise markdown format, redacting AI messages with [...]\n *\n * ### Example\n * ```markdown\n * AI: [...]\n * Human: Hello, how are you?\n * AI: [...]\n * Human: I am good, thank you!\n * AI: [...]\n * Human: What is your name?\n * AI: [...]\n * Human: My name is John.\n * AI: [...]\n * ```\n */\nfunction redactAi(messages: Array<BaseMessage>): string {\n return messages\n .map((message) => {\n const prefix = message instanceof AIMessage ? 'AI' : 'Human';\n const content = message instanceof AIMessage ? '[...]' : message.content;\n return `${prefix}: ${content}`;\n })\n .join('\\n');\n}\n\n/**\n * Formats messages in a concise markdown format, redacting Human messages with [...]\n *\n * ### Example\n * ```markdown\n * AI: Hello, how are you?\n * Human: [...]\n * AI: What is your name?\n * Human: [...]\n * AI: What is your favorite color?\n * Human: [...]\n * AI: What is your favorite food?\n * Human: [...]\n * ```\n */\nfunction redactHuman(messages: Array<BaseMessage>): string {\n return messages\n .map((message) => {\n const prefix = message instanceof AIMessage ? 'AI' : 'Human';\n const content = message instanceof AIMessage ? '[...]' : message.content;\n return `${prefix}: ${content}`;\n })\n .join('\\n');\n}\nconst typeOnFormatter = {\n [FormatType.Concise]: concise,\n [FormatType.Verbose]: verbose,\n [FormatType.RedactAi]: redactAi,\n [FormatType.RedactHuman]: redactHuman,\n};\n\nexport { typeOnFormatter };\n","import { Effect, Scope } from 'effect';\nimport type { Schema as S } from 'effect';\nimport type { AgentFactory } from '../agent-factory';\nimport type { AgentNetworkEventDef } from './agent-network-event';\nimport { ChannelName, ConfiguredChannel, Sink } from './channel';\nimport { createEventPlane, run } from './event-plane';\nimport type { Envelope, EventPlane } from './event-plane';\nimport { expose } from '../io/expose';\nimport type { ExposeOptions, ExposedAPI } from '../io/types';\nimport type { AgentNetworkStore } from './stores/agent-network-store';\nimport { createInMemoryNetworkStore } from './stores/inmemory-network-store';\n\n/* ─── Helper Types ─── */\n\ntype EventDef = AgentNetworkEventDef<string, S.Schema.Any>;\n\n/** Structural interface for any Agent – avoids variance issues with private fields. */\nexport interface AnyAgent {\n getId(): string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n invoke(options?: any): Promise<void>;\n /** Event names this agent listens to. Empty = listen to all. */\n getListensTo?(): readonly string[];\n}\n\n/* ─── Agent Binding (returned by registerAgent) ─── */\n\nexport type AgentBinding = {\n subscribe(channel: ConfiguredChannel): AgentBinding;\n publishTo(channel: ConfiguredChannel): AgentBinding;\n};\n\n/* ─── Spawner Builder ─── */\n\nexport type SpawnFn = (\n agent: AnyAgent,\n bindings?: { subscribe?: string[]; publishTo?: string[] },\n) => void;\n\nexport type SpawnCallbackContext<\n TRegistry extends Record<string, AgentFactory> = Record<string, AgentFactory>,\n> = {\n kind: keyof TRegistry & string;\n factory: TRegistry[keyof TRegistry & string];\n payload: {\n id: string;\n params: Record<string, unknown>;\n subscribe?: string[];\n publishTo?: string[];\n };\n spawn: SpawnFn;\n};\n\nexport type SpawnerBuilder<\n TRegistry extends Record<string, AgentFactory> = Record<string, AgentFactory>,\n> = {\n listen(\n channel: ConfiguredChannel,\n event: EventDef,\n ): SpawnerBuilder<TRegistry>;\n registry<R extends Record<string, AgentFactory>>(reg: R): SpawnerBuilder<R>;\n defaultBinding(\n fn: (ctx: { kind: string }) => {\n subscribe: string[];\n publishTo: string[];\n },\n ): SpawnerBuilder<TRegistry>;\n onSpawn(\n fn: (ctx: SpawnCallbackContext<TRegistry>) => AnyAgent,\n ): SpawnerBuilder<TRegistry>;\n};\n\n/* ─── Setup Context ─── */\n\nexport type SetupContext = {\n mainChannel: (name: string) => ConfiguredChannel;\n createChannel: (name: string) => ConfiguredChannel;\n sink: typeof Sink;\n registerAgent: (agent: AnyAgent) => AgentBinding;\n spawner: (factory: typeof AgentFactory) => SpawnerBuilder;\n};\n\n/* ─── Internal Registration Records ─── */\n\ntype AgentRegistration = {\n agent: AnyAgent;\n subscribedTo: ConfiguredChannel[];\n publishesTo: ConfiguredChannel[];\n};\n\ntype SpawnerRegistration = {\n factoryClass: typeof AgentFactory;\n listenChannel?: ConfiguredChannel;\n listenEvent?: EventDef;\n registry: Record<string, AgentFactory>;\n defaultBindingFn?: (ctx: { kind: string }) => {\n subscribe: string[];\n publishTo: string[];\n };\n onSpawnFn?: (\n ctx: SpawnCallbackContext<Record<string, AgentFactory>>,\n ) => AnyAgent;\n};\n\n/* ─── AgentNetwork ─── */\n\nexport class AgentNetwork {\n private _mainChannel: ConfiguredChannel | undefined;\n private channels: Map<ChannelName, ConfiguredChannel> = new Map();\n private agentRegistrations: Map<string, AgentRegistration> = new Map();\n private spawnerRegistrations: SpawnerRegistration[] = [];\n private _store: AgentNetworkStore<Envelope>;\n\n private constructor() {\n this._store = createInMemoryNetworkStore<Envelope>();\n }\n\n /* ─── Public Static Factory ─── */\n\n static setup(callback: (ctx: SetupContext) => void): AgentNetwork {\n const network = new AgentNetwork();\n\n const ctx: SetupContext = {\n mainChannel: (name: string) => {\n const channel = network.addChannel(name);\n network.setMainChannel(channel);\n return channel;\n },\n createChannel: (name: string) => network.addChannel(name),\n sink: Sink,\n registerAgent: (agent) => network.registerAgentInternal(agent),\n spawner: (factory) => network.createSpawnerInternal(factory),\n };\n\n callback(ctx);\n\n return network;\n }\n\n /* ─── Internal Builders ─── */\n\n private addChannel(name: string): ConfiguredChannel {\n const channelName = ChannelName(name);\n const channel = new ConfiguredChannel(channelName);\n this.channels.set(channelName, channel);\n return channel;\n }\n\n private setMainChannel(channel: ConfiguredChannel): void {\n this._mainChannel = channel;\n }\n\n private registerAgentInternal(agent: AnyAgent): AgentBinding {\n const registration: AgentRegistration = {\n agent,\n subscribedTo: [],\n publishesTo: [],\n };\n this.agentRegistrations.set(agent.getId(), registration);\n\n const binding: AgentBinding = {\n subscribe(channel: ConfiguredChannel) {\n registration.subscribedTo.push(channel);\n return binding;\n },\n publishTo(channel: ConfiguredChannel) {\n registration.publishesTo.push(channel);\n return binding;\n },\n };\n\n return binding;\n }\n\n private createSpawnerInternal(\n factoryClass: typeof AgentFactory,\n ): SpawnerBuilder {\n const reg: SpawnerRegistration = {\n factoryClass,\n registry: {},\n };\n\n this.spawnerRegistrations.push(reg);\n\n const builder: SpawnerBuilder = {\n listen(channel: ConfiguredChannel, event: EventDef) {\n reg.listenChannel = channel;\n reg.listenEvent = event;\n return builder;\n },\n registry(registry: Record<string, AgentFactory>) {\n reg.registry = registry;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return builder as SpawnerBuilder<any>;\n },\n defaultBinding(\n fn: (ctx: { kind: string }) => {\n subscribe: string[];\n publishTo: string[];\n },\n ) {\n reg.defaultBindingFn = fn;\n return builder;\n },\n onSpawn(\n fn: (\n ctx: SpawnCallbackContext<Record<string, AgentFactory>>,\n ) => AnyAgent,\n ) {\n reg.onSpawnFn = fn;\n return builder;\n },\n };\n\n return builder;\n }\n\n /* ─── Accessors ─── */\n\n getChannels(): Map<string, ConfiguredChannel> {\n return this.channels;\n }\n\n getMainChannel(): ConfiguredChannel | undefined {\n return this._mainChannel;\n }\n\n getAgentRegistrations(): Map<string, AgentRegistration> {\n return this.agentRegistrations;\n }\n\n getSpawnerRegistrations(): ReadonlyArray<SpawnerRegistration> {\n return this.spawnerRegistrations;\n }\n\n /** Store defined at network setup time. Shared across all event planes created for this network. */\n getStore(): AgentNetworkStore<Envelope> {\n return this._store;\n }\n\n /**\n * Expose the network as a streamable API (e.g. SSE). Returns an ExposedAPI\n * that adapters (NextEndpoint, ExpressEndpoint) consume to produce streamed\n * responses.\n *\n * @example\n * const api = network.expose({ protocol: \"sse\", auth, select });\n * export const GET = NextEndpoint.from(api, { requestToContextId, requestToRunId }).handler();\n */\n expose(options: ExposeOptions): ExposedAPI {\n return expose(this, options);\n }\n\n /**\n * Starts the event plane: creates one PubSub per channel and runs subscriber\n * loops for each (agent, channel) pair. Agents subscribed to a channel are\n * invoked concurrently when events are published to that channel.\n *\n * Returns the EventPlane for publishing. Use `Effect.scoped` so the run is\n * interrupted when the scope ends.\n */\n run(capacity?: number): Effect.Effect<EventPlane, never, Scope.Scope> {\n return this.runScoped(this, capacity);\n }\n\n private runScoped(\n network: AgentNetwork,\n capacity?: number,\n ): Effect.Effect<EventPlane, never, Scope.Scope> {\n return Effect.gen(function* () {\n const plane = yield* createEventPlane({\n network,\n capacity,\n store: network.getStore(),\n });\n yield* Effect.fork(run(network, plane));\n return plane;\n });\n }\n}\n","import { Brand } from 'effect';\n\n/** Regex: lowercase alphanumeric segments separated by hyphens (e.g. my-channel-name) */\nconst KEBAB_CASE_REGEX = /^[a-z0-9]+(-[a-z0-9]+)*$/;\n\n/**\n * Branded type for channel names. Enforces kebab-case at runtime via refinement.\n *\n * **Branded types** add a nominal marker so TypeScript treats `ChannelName` as\n * distinct from plain `string`, preventing accidental substitution (e.g. passing\n * a raw string where a validated channel name is expected).\n *\n * **Refinement** validates at runtime that the value matches kebab-case before\n * the brand is applied. Use `ChannelName(value)` to create a validated instance.\n */\nexport type ChannelName = string & Brand.Brand<'ChannelName'>;\n\nexport const ChannelName = Brand.refined<ChannelName>(\n (s) => typeof s === 'string' && KEBAB_CASE_REGEX.test(s),\n (s) => Brand.error(`Expected kebab-case (e.g. my-channel-name), got: ${s}`),\n);\n","import { type Schema as S } from 'effect';\nimport type { AgentNetworkEventDef } from './agent-network-event';\nimport { ChannelName } from '../identifiers/channel-name';\n\nexport { ChannelName } from '../identifiers/channel-name';\n\n/* ─── Sink ─── */\n\nexport type SinkDef = {\n readonly _tag: 'SinkDef';\n readonly type: string;\n readonly config: unknown;\n};\n\nexport const Sink = {\n kafka(config: { topic: string }): SinkDef {\n return { _tag: 'SinkDef', type: 'kafka', config };\n },\n httpStream(): SinkDef {\n return { _tag: 'SinkDef', type: 'http-stream', config: {} };\n },\n};\n\nexport function isHttpStreamSink(sink: SinkDef): boolean {\n return sink.type === 'http-stream';\n}\n\n/* ─── Channel Definitions ─── */\n\ntype EventDef = AgentNetworkEventDef<string, S.Schema.Any>;\n\nexport type ChannelDef = {\n readonly _tag: 'ChannelDef';\n readonly name: ChannelName;\n};\n\n/**\n * A channel configured via the builder pattern inside `AgentNetwork.setup()`.\n * Supports `.events()`, `.sink()`, and `.sinks()` chaining.\n */\nexport class ConfiguredChannel {\n readonly _tag = 'ConfiguredChannel' as const;\n readonly name: ChannelName;\n private _events: ReadonlyArray<EventDef> = [];\n private _sinks: ReadonlyArray<SinkDef> = [];\n\n constructor(name: ChannelName) {\n this.name = name;\n }\n\n events(events: ReadonlyArray<EventDef>): this {\n this._events = [...events];\n return this;\n }\n\n sink(sink: SinkDef): this {\n this._sinks = [...this._sinks, sink];\n return this;\n }\n\n sinks(sinks: ReadonlyArray<SinkDef>): this {\n this._sinks = [...sinks];\n return this;\n }\n\n getEvents(): ReadonlyArray<EventDef> {\n return this._events;\n }\n\n getSinks(): ReadonlyArray<SinkDef> {\n return this._sinks;\n }\n}\n\nexport const Channel = {\n of(name: ChannelName): ChannelDef {\n return {\n _tag: 'ChannelDef' as const,\n name,\n };\n },\n};\n","import { Cause, Effect, Fiber, PubSub, Queue, Scope } from 'effect';\nimport type { AgentNetwork, AnyAgent } from './agent-network';\nimport type {\n ContextEvents,\n EventMeta,\n RunEvents,\n} from './agent-network-event';\nimport type { ChannelName, ConfiguredChannel } from './channel';\nimport type { AgentNetworkStore } from './stores/agent-network-store';\nimport { createInMemoryNetworkStore } from './stores/inmemory-network-store';\n\n/* ─── Envelope ─── */\n\nexport type Envelope = {\n name: string;\n meta: EventMeta;\n payload: unknown;\n};\n\n/* ─── EventPlane ─── */\n\nexport type EventPlane = {\n readonly publish: (\n channel: ChannelName,\n envelope: Envelope,\n ) => Effect.Effect<boolean>;\n readonly publishToChannels: (\n channels: readonly ConfiguredChannel[],\n envelope: Envelope,\n ) => Effect.Effect<boolean>;\n readonly subscribe: (\n channel: ChannelName,\n ) => Effect.Effect<Queue.Dequeue<Envelope>, never, Scope.Scope>;\n readonly getRunEvents: (runId: string, contextId: string) => RunEvents;\n readonly getContextEvents: (contextId: string) => ContextEvents;\n readonly shutdown: Effect.Effect<void>;\n};\n\n/* ─── Create EventPlane ─── */\n\nconst DEFAULT_CAPACITY = 16;\n\ntype CreateEventPlaneOptions = {\n network: AgentNetwork;\n capacity?: number;\n store?: AgentNetworkStore<Envelope>;\n};\n\n/**\n * Creates an EventPlane from an AgentNetwork. One PubSub per channel with\n * bounded back-pressure. Use `Effect.scoped` when running to ensure proper\n * cleanup.\n */\nexport const createEventPlane = (\n options: CreateEventPlaneOptions,\n): Effect.Effect<EventPlane> =>\n Effect.gen(function* () {\n const {\n network,\n capacity = DEFAULT_CAPACITY,\n store = createInMemoryNetworkStore<Envelope>(),\n } = options;\n\n const channels = network.getChannels();\n const pubsubs = new Map<ChannelName, PubSub.PubSub<Envelope>>();\n\n for (const channel of channels.values()) {\n const pubsub = yield* PubSub.bounded<Envelope>(capacity);\n pubsubs.set(channel.name, pubsub);\n }\n\n const getPubsub = (channel: ChannelName): PubSub.PubSub<Envelope> => {\n const p = pubsubs.get(channel);\n if (!p) throw new Error(`Channel not found: ${channel}`);\n return p;\n };\n\n const recordEvent = (envelope: Envelope): void => {\n const { contextId, runId } = envelope.meta;\n store.storeEvent(contextId, runId, envelope);\n };\n\n const publishToPubSub = (\n channel: ChannelName,\n envelope: Envelope,\n ): Effect.Effect<boolean> => PubSub.publish(getPubsub(channel), envelope);\n\n const publish = (\n channel: ChannelName,\n envelope: Envelope,\n ): Effect.Effect<boolean> =>\n Effect.sync(() => recordEvent(envelope)).pipe(\n Effect.flatMap(() => publishToPubSub(channel, envelope)),\n Effect.withSpan('event.publish', {\n attributes: {\n 'event.name': envelope.name,\n 'event.payload': payloadForSpan(envelope.payload),\n channel,\n runId: envelope.meta.runId,\n contextId: envelope.meta.contextId,\n },\n }),\n );\n\n const publishToChannels = (\n targetChannels: readonly ConfiguredChannel[],\n envelope: Envelope,\n ): Effect.Effect<boolean> =>\n Effect.sync(() => recordEvent(envelope)).pipe(\n Effect.flatMap(() =>\n Effect.all(\n targetChannels.map((c) => publishToPubSub(c.name, envelope)),\n { concurrency: 'unbounded' },\n ),\n ),\n Effect.map((results) => results.every(Boolean)),\n Effect.withSpan('event.publish', {\n attributes: {\n 'event.name': envelope.name,\n 'event.payload': payloadForSpan(envelope.payload),\n runId: envelope.meta.runId,\n contextId: envelope.meta.contextId,\n },\n }),\n );\n\n const subscribe = (\n channel: ChannelName,\n ): Effect.Effect<Queue.Dequeue<Envelope>, never, Scope.Scope> =>\n PubSub.subscribe(getPubsub(channel));\n\n const getRunEvents = (runId: string, contextId: string): RunEvents => {\n return store.getEvents(contextId, runId).slice();\n };\n\n const getContextEvents = (contextId: string): ContextEvents => {\n const byRun = store.getContextEvents(contextId);\n const map = new Map<string, readonly Envelope[]>();\n const all: Envelope[] = [];\n for (const [runId, events] of byRun) {\n const readonlyEvents = events.slice();\n map.set(runId, readonlyEvents);\n all.push(...readonlyEvents);\n }\n return {\n all,\n byRun: (runId: string) => map.get(runId) ?? [],\n map,\n };\n };\n\n const shutdown = Effect.all([...pubsubs.values()].map(PubSub.shutdown), {\n concurrency: 'unbounded',\n }).pipe(Effect.asVoid);\n\n return {\n publish,\n publishToChannels,\n subscribe,\n getRunEvents,\n getContextEvents,\n shutdown,\n };\n });\n\n/** Serialize payload for span attributes; truncate if too long */\nfunction payloadForSpan(payload: unknown, maxLen = 500): string {\n try {\n const s = JSON.stringify(payload);\n return s.length > maxLen ? `${s.slice(0, maxLen)}...` : s;\n } catch {\n return String(payload);\n }\n}\n\n/* ─── Run Subscriber Loop ─── */\n\n/**\n * Runs a single agent's subscription loop on one channel. Takes messages from\n * the dequeue, invokes the agent with the envelope as triggerEvent when the\n * event name matches the agent's listensTo, and wires emit to publish to the\n * agent's output channels.\n */\ntype EmitQueue = Queue.Queue<{\n channels: readonly ConfiguredChannel[];\n envelope: Envelope;\n}>;\n\nexport const runSubscriber = (\n agent: AnyAgent,\n publishesTo: readonly ConfiguredChannel[],\n dequeue: Queue.Dequeue<Envelope>,\n plane: EventPlane,\n emitQueue?: EmitQueue,\n channelName?: ChannelName,\n): Effect.Effect<Fiber.RuntimeFiber<void, never>> =>\n Effect.gen(function* () {\n const listensTo = agent.getListensTo?.() ?? [];\n const agentId = agent.getId();\n\n const processOne = (): Effect.Effect<void, never, never> =>\n Effect.gen(function* () {\n const envelope = yield* Queue.take(dequeue);\n if (listensTo.length > 0 && !listensTo.includes(envelope.name)) {\n return;\n }\n const runEvents = plane.getRunEvents(\n envelope.meta.runId,\n envelope.meta.contextId,\n );\n const contextEvents = plane.getContextEvents(envelope.meta.contextId);\n yield* Effect.withSpan('agent.listen', {\n attributes: {\n agentId,\n 'event.name': envelope.name,\n 'event.payload': payloadForSpan(envelope.payload),\n ...(channelName !== undefined && { channel: channelName }),\n },\n })(\n Effect.withSpan('agent.invoke', {\n attributes: {\n agentId,\n 'event.name': envelope.name,\n 'event.payload': payloadForSpan(envelope.payload),\n },\n })(\n Effect.tryPromise({\n try: () =>\n agent.invoke({\n triggerEvent: envelope,\n emit: (userEvent: { name: string; payload: unknown }) => {\n const fullEnvelope: Envelope = {\n name: userEvent.name,\n meta: envelope.meta,\n payload: userEvent.payload,\n };\n if (emitQueue) {\n Effect.runPromise(\n Queue.offer(emitQueue, {\n channels: publishesTo,\n envelope: fullEnvelope,\n }),\n ).catch(() => {});\n } else {\n Effect.runFork(\n plane.publishToChannels(publishesTo, fullEnvelope),\n );\n }\n },\n runEvents,\n contextEvents,\n }),\n catch: (e) => e,\n }),\n ),\n );\n }).pipe(\n Effect.catchAllCause((cause) =>\n Cause.isInterrupted(cause)\n ? Effect.void\n : Effect.sync(() => {\n console.error(`Agent ${agent.getId()} failed:`, cause);\n }).pipe(Effect.asVoid),\n ),\n );\n\n const loop = (): Effect.Effect<void, never, never> =>\n processOne().pipe(Effect.flatMap(() => loop()));\n\n return yield* Effect.fork(loop());\n });\n\n/* ─── Run Network ─── */\n\nexport type RunOptions = {\n /** When provided, agent emits are queued and published by a drain fiber in the same Effect context. Use when run is forked from expose without a shared plane. */\n emitQueue?: EmitQueue;\n};\n\n/**\n * Runs the event plane: starts a subscriber loop for each (agent, channel)\n * pair. Runs until the scope ends (e.g. on interrupt). Use Effect.scoped\n * to ensure subscriptions are properly cleaned up.\n */\nexport const run = (\n network: AgentNetwork,\n plane: EventPlane,\n options?: RunOptions,\n): Effect.Effect<void, never, Scope.Scope> =>\n Effect.gen(function* () {\n const registrations = network.getAgentRegistrations();\n const emitQueue = options?.emitQueue;\n\n for (const reg of registrations.values()) {\n for (const channel of reg.subscribedTo) {\n const dequeue = yield* plane.subscribe(channel.name);\n yield* runSubscriber(\n reg.agent,\n reg.publishesTo,\n dequeue,\n plane,\n emitQueue,\n channel.name,\n );\n }\n }\n\n yield* Effect.never;\n });\n","/**\n * Type-safe no-operation stubs for use as default handlers.\n *\n * `noop` and `asyncNoop` are assignable to any callback that expects\n * additional parameters — TypeScript allows a function with fewer\n * parameters to substitute for one expecting more.\n *\n * @example\n * ```ts\n * type LogicFn = (ctx: { params: Config; emit: Emitter }) => Promise<void>;\n * const defaultLogic: LogicFn = asyncNoop;\n * ```\n */\n\n/** Synchronous no-op — safe default for any `(...) => void` handler. */\nexport const noop = (): void => {};\n\n/** Asynchronous no-op — safe default for any `(...) => Promise<void>` handler. */\nexport const asyncNoop = async (): Promise<void> => {};\n\n/** Synchronous no-op that returns a given value — for handlers that must return `R`. */\nexport const noopOf =\n <R>(value: R): (() => R) =>\n () =>\n value;\n\n/** Asynchronous no-op that resolves to a given value — for handlers that must return `Promise<R>`. */\nexport const asyncNoopOf =\n <R>(value: R): (() => Promise<R>) =>\n async () =>\n value;\n","import { asyncNoop } from '../../../helper/types/noop';\nimport type { AgentNetworkStore } from './agent-network-store';\n\n/**\n * In-memory implementation of AgentNetworkStore. Events are stored in a\n * nested map: contextId -> runId -> events.\n */\nexport const createInMemoryNetworkStore = <T>(): AgentNetworkStore<T> => {\n const store = new Map<string, Map<string, T[]>>();\n\n return {\n storeEvent: (contextId: string, runId: string, event: T): void => {\n let byRun = store.get(contextId);\n if (!byRun) {\n byRun = new Map();\n store.set(contextId, byRun);\n }\n let events = byRun.get(runId);\n if (!events) {\n events = [];\n byRun.set(runId, events);\n }\n events.push(event);\n },\n\n getEvents: (contextId: string, runId: string): T[] => {\n const events = store.get(contextId)?.get(runId);\n return events ? [...events] : [];\n },\n\n getContextEvents: (contextId: string): Map<string, T[]> => {\n const byRun = store.get(contextId);\n const result = new Map<string, T[]>();\n if (byRun) {\n for (const [runId, events] of byRun) {\n result.set(runId, [...events]);\n }\n }\n return result;\n },\n\n getFullStore: (): Map<string, Map<string, T[]>> => {\n const result = new Map<string, Map<string, T[]>>();\n for (const [contextId, byRun] of store) {\n const contextMap = new Map<string, T[]>();\n for (const [runId, events] of byRun) {\n contextMap.set(runId, [...events]);\n }\n result.set(contextId, contextMap);\n }\n return result;\n },\n\n persist: (): Promise<void> => asyncNoop(),\n load: (): Promise<void> => asyncNoop(),\n };\n};\n","import { Effect, Queue } from 'effect';\nimport type { AgentNetwork } from '../agent-network/agent-network';\nimport type { ConfiguredChannel } from '../agent-network/channel';\nimport { createEventPlane, run } from '../agent-network/event-plane';\nimport type { Envelope } from '../agent-network/event-plane';\nimport { ChannelName, isHttpStreamSink } from '../agent-network/channel';\nimport type {\n ExposeOptions,\n ExposeRequest,\n ExposedAPI,\n ExposedStream,\n StreamFactory,\n} from './types';\n\n/** Extract JSON payload from ExposeRequest. POST with JSON body, or Express req.body, else {}. */\nasync function extractPayload(req: ExposeRequest): Promise<unknown> {\n const webRequest = req.request as Request | undefined;\n if (webRequest?.method === 'POST') {\n const ct = webRequest.headers?.get?.('content-type') ?? '';\n if (ct.includes('application/json')) {\n try {\n return await webRequest.json();\n } catch {\n return {};\n }\n }\n }\n const expressReq = req.req as { body?: unknown } | undefined;\n if (expressReq?.body != null) {\n return expressReq.body;\n }\n return {};\n}\n\n/** Resolve which channel(s) to subscribe to from select options */\nfunction resolveChannels(\n network: AgentNetwork,\n select?: ExposeOptions['select'],\n): ChannelName[] {\n const channels = network.getChannels();\n if (select?.channels) {\n const ch = select.channels;\n const arr = Array.isArray(ch) ? ch : [ch];\n return arr.map((c) => ChannelName(c as string));\n }\n // Prefer channels with http-stream sink (explicitly marked for frontend)\n const httpStreamChannels = [...channels.values()]\n .filter((ch) => ch.getSinks().some(isHttpStreamSink))\n .map((ch) => ch.name);\n if (httpStreamChannels.length > 0) return httpStreamChannels;\n // Fallback: prefer \"client\", else first channel\n const client = channels.get('client' as ChannelName);\n if (client) return [client.name];\n const first = channels.values().next().value;\n return first ? [first.name] : [];\n}\n\n/** Create async iterable from Queue.Dequeue, respecting AbortSignal */\nfunction streamFromDequeue(\n take: () => Promise<Envelope>,\n signal?: AbortSignal | null,\n eventFilter?: string[],\n): ExposedStream {\n const shouldInclude = (e: Envelope): boolean =>\n !eventFilter?.length || eventFilter.includes(e.name);\n\n return {\n async *[Symbol.asyncIterator](): AsyncIterableIterator<Envelope> {\n while (!signal?.aborted) {\n const takePromise = take();\n const abortPromise = signal\n ? new Promise<never>((_, reject) => {\n signal.addEventListener(\n 'abort',\n () => reject(new DOMException('Aborted', 'AbortError')),\n { once: true },\n );\n })\n : new Promise<never>(() => {});\n\n let envelope: Envelope;\n try {\n envelope = await Promise.race([takePromise, abortPromise]);\n } catch (e) {\n if (e instanceof DOMException && e.name === 'AbortError') break;\n throw e;\n }\n\n if (shouldInclude(envelope)) yield envelope;\n }\n },\n };\n}\n\n/**\n * Expose the agent network as a streamable API. Returns an ExposedAPI that\n * adapters (NextEndpoint, ExpressEndpoint) consume to produce SSE responses.\n *\n * @example\n * const api = agentNetwork.expose({ protocol: \"sse\", auth, select });\n * export const GET = NextEndpoint.from(api, { requestToContextId, requestToRunId }).handler();\n */\nexport function expose(\n network: AgentNetwork,\n options: ExposeOptions,\n): ExposedAPI {\n const {\n auth,\n select,\n plane: providedPlane,\n onRequest,\n triggerEvents,\n tracingLayer,\n } = options;\n const triggerEventDef = triggerEvents?.[0];\n const triggerEventName = triggerEventDef?.name ?? 'request';\n const channels = resolveChannels(network, select);\n const eventFilter = select?.events;\n const mainChannel = network.getMainChannel();\n\n if (channels.length === 0) {\n throw new Error('expose: no channels to subscribe to');\n }\n\n const createStream = (async (\n req: ExposeRequest,\n consumer?: (stream: ExposedStream) => Promise<unknown>,\n ) => {\n const payload = await extractPayload(req);\n const signal = req.request?.signal;\n\n const program = Effect.gen(function* () {\n const plane =\n providedPlane ??\n (yield* createEventPlane({ network, store: network.getStore() }));\n if (!providedPlane) {\n const emitQueue = yield* Queue.unbounded<{\n channels: readonly ConfiguredChannel[];\n envelope: Envelope;\n }>();\n yield* Effect.fork(\n Effect.forever(\n Queue.take(emitQueue).pipe(\n Effect.flatMap(({ channels: chs, envelope }) =>\n plane.publishToChannels(chs, envelope),\n ),\n ),\n ),\n );\n yield* Effect.fork(run(network, plane, { emitQueue }));\n // Allow run() to subscribe agents before we publish (PubSub does not buffer for future subscribers)\n yield* Effect.sleep('10 millis');\n }\n\n const targetChannel = mainChannel?.name ?? channels[0]!;\n let runId = req.runId ?? crypto.randomUUID();\n let contextId = req.contextId ?? crypto.randomUUID();\n\n const setRunId = (id: string): void => {\n runId = id;\n };\n const setContextId = (id: string): void => {\n contextId = id;\n };\n\n const emitStartEvent = (opts: {\n contextId: string;\n runId: string;\n event: { name: string; payload: unknown };\n }): void => {\n const meta = {\n runId: opts.runId,\n contextId: opts.contextId,\n };\n const envelope: Envelope = {\n name: opts.event.name,\n meta,\n payload: opts.event.payload,\n };\n Effect.runPromise(plane.publish(targetChannel, envelope)).catch(\n () => {},\n );\n };\n\n // Subscribe to first channel before emitting (so we don't miss agent output)\n const dequeue = yield* plane.subscribe(channels[0]!);\n\n if (onRequest) {\n yield* Effect.tryPromise(() =>\n Promise.resolve(\n onRequest({\n setRunId,\n setContextId,\n emitStartEvent,\n req,\n payload,\n }),\n ),\n );\n } else if (!providedPlane) {\n const envelope: Envelope = {\n name: triggerEventName,\n meta: { runId, contextId },\n payload,\n };\n yield* plane.publish(targetChannel, envelope);\n yield* Effect.sleep('10 millis');\n }\n const take = (): Promise<Envelope> =>\n Effect.runPromise(Queue.take(dequeue)) as Promise<Envelope>;\n\n const stream = streamFromDequeue(take, signal ?? undefined, eventFilter);\n if (consumer) {\n return yield* Effect.tryPromise(() => consumer(stream));\n }\n return stream;\n });\n\n const runnable = tracingLayer\n ? program.pipe(Effect.provide(tracingLayer), Effect.scoped)\n : program.pipe(Effect.scoped);\n return Effect.runPromise(runnable);\n }) as StreamFactory;\n\n return {\n protocol: 'sse',\n createStream: (async (\n req: ExposeRequest,\n consumer?: (stream: ExposedStream) => Promise<unknown>,\n ) => {\n if (auth) {\n const result = await auth(req);\n if (!result.allowed) {\n throw new ExposeAuthError(\n result.message ?? 'Unauthorized',\n result.status ?? 401,\n );\n }\n }\n return consumer ? createStream(req, consumer) : createStream(req);\n }) as StreamFactory,\n };\n}\n\n/** Thrown when auth denies the request */\nexport class ExposeAuthError extends Error {\n constructor(\n message: string,\n public readonly status: number = 401,\n ) {\n super(message);\n this.name = 'ExposeAuthError';\n }\n}\n","import { Effect, Schema as S } from 'effect';\nimport type { ParseError } from 'effect/ParseResult';\n\n/** Standard meta carried by every event */\nexport const EventMetaSchema = S.Struct({\n runId: S.String,\n contextId: S.String,\n correlationId: S.optional(S.String),\n causationId: S.optional(S.String),\n ts: S.optional(S.Number),\n});\n\nexport type EventMeta = S.Schema.Type<typeof EventMetaSchema>;\n\n/** Envelope-like shape for events (avoids circular dep with event-plane) */\nexport type EnvelopeLike = { name: string; meta: EventMeta; payload: unknown };\nexport type RunEvents = readonly EnvelopeLike[];\n\nexport type ContextEvents = {\n /** All events in the context across all runs */\n readonly all: readonly EnvelopeLike[];\n /** Get events for a specific run */\n byRun(runId: string): readonly EnvelopeLike[];\n /** Map of runId -> events */\n readonly map: ReadonlyMap<string, readonly EnvelopeLike[]>;\n};\n\n// Re-export Schema from effect for convenience\nexport { Schema as S } from 'effect';\n\nexport type AgentNetworkEventDef<\n EventName extends string,\n PayloadSchema extends S.Schema.Any,\n> = {\n readonly _tag: 'AgentNetworkEventDef';\n readonly name: EventName;\n readonly payload: PayloadSchema;\n\n /** Decode unknown payload -> typed payload (Effect) */\n readonly decodePayload: (\n u: unknown,\n ) => Effect.Effect<S.Schema.Type<PayloadSchema>, ParseError>;\n\n /** Decode the full envelope (meta + payload) */\n readonly decode: (\n u: unknown,\n ) => Effect.Effect<\n { name: EventName; meta: EventMeta; payload: S.Schema.Type<PayloadSchema> },\n ParseError\n >;\n\n /**\n * Create an unbound event (name + payload only) for emit. Validates payload via schema.\n * Meta is injected by the runtime when the event is emitted.\n */\n readonly make: (payload: unknown) => {\n name: EventName;\n payload: S.Schema.Type<PayloadSchema>;\n };\n\n /**\n * Create a full envelope (meta + payload) for tests or manual trigger events.\n * Sync, throws on validation error.\n */\n readonly makeBound: (\n meta: unknown,\n payload: unknown,\n ) => {\n name: EventName;\n meta: EventMeta;\n payload: S.Schema.Type<PayloadSchema>;\n };\n\n /**\n * Effect version of make. Use when composing in Effect pipelines.\n */\n readonly makeEffect: (\n payload: unknown,\n ) => Effect.Effect<\n { name: EventName; payload: S.Schema.Type<PayloadSchema> },\n ParseError\n >;\n\n /**\n * Effect version of makeBound. Use when composing in Effect pipelines.\n */\n readonly makeBoundEffect: (\n meta: unknown,\n payload: unknown,\n ) => Effect.Effect<\n { name: EventName; meta: EventMeta; payload: S.Schema.Type<PayloadSchema> },\n ParseError\n >;\n\n /**\n * Type guard: returns true if `u` is a valid event of this type.\n */\n readonly is: (u: unknown) => u is {\n name: EventName;\n meta: EventMeta;\n payload: S.Schema.Type<PayloadSchema>;\n };\n};\n\ntype Envelope<EventName extends string, Meta, Payload> = {\n name: EventName;\n meta: Meta;\n payload: Payload;\n};\n\nexport const AgentNetworkEvent = {\n of<const EventName extends string, PS extends S.Schema.Any>(\n name: EventName,\n payload: PS,\n ): AgentNetworkEventDef<EventName, PS> {\n const decodePayload = S.decodeUnknown(payload);\n const envelopeSchema = S.Struct({\n name: S.Literal(name),\n meta: EventMetaSchema,\n payload,\n });\n const decodeEnvelope = S.decodeUnknown(envelopeSchema);\n\n const make = (\n payload: unknown,\n ): { name: EventName; payload: S.Schema.Type<PS> } => {\n const decoded = Effect.runSync(\n decodePayload(payload) as unknown as Effect.Effect<\n S.Schema.Type<PS>,\n ParseError\n >,\n );\n return { name, payload: decoded };\n };\n\n const makeBound = (\n meta: unknown,\n payload: unknown,\n ): Envelope<EventName, EventMeta, S.Schema.Type<PS>> =>\n Effect.runSync(\n decodeEnvelope({ name, meta, payload }) as unknown as Effect.Effect<\n Envelope<EventName, EventMeta, S.Schema.Type<PS>>,\n ParseError\n >,\n );\n\n const makeEffect = (\n payload: unknown,\n ): Effect.Effect<\n { name: EventName; payload: S.Schema.Type<PS> },\n ParseError\n > =>\n (\n decodePayload(payload) as unknown as Effect.Effect<\n S.Schema.Type<PS>,\n ParseError\n >\n ).pipe(Effect.map((p) => ({ name, payload: p })));\n\n const makeBoundEffect = (\n meta: unknown,\n payload: unknown,\n ): Effect.Effect<\n Envelope<EventName, EventMeta, S.Schema.Type<PS>>,\n ParseError\n > =>\n decodeEnvelope({ name, meta, payload }) as unknown as Effect.Effect<\n Envelope<EventName, EventMeta, S.Schema.Type<PS>>,\n ParseError\n >;\n\n const is = S.is(envelopeSchema) as unknown as (\n u: unknown,\n ) => u is Envelope<EventName, EventMeta, S.Schema.Type<PS>>;\n\n return {\n _tag: 'AgentNetworkEventDef' as const,\n name,\n payload,\n decodePayload: decodePayload as unknown as AgentNetworkEventDef<\n EventName,\n PS\n >['decodePayload'],\n decode: decodeEnvelope as unknown as AgentNetworkEventDef<\n EventName,\n PS\n >['decode'],\n make,\n makeBound,\n makeEffect,\n makeBoundEffect,\n is,\n };\n },\n};\n","import { randomUUID } from 'crypto';\nimport type {\n ContextEvents,\n RunEvents,\n} from './agent-network/agent-network-event';\n\ntype LogicFn<TParams, TTriggerEvent, TEmitEvent> = (ctx: {\n params: TParams;\n triggerEvent: TTriggerEvent;\n emit: (event: TEmitEvent) => void;\n runEvents: RunEvents;\n contextEvents: ContextEvents;\n}) => Promise<void>;\n\nexport class Agent<TParams, TTriggerEvent = never, TEmitEvent = never> {\n #params: TParams;\n #logic: LogicFn<TParams, TTriggerEvent, TEmitEvent>;\n #id: string;\n #listensTo: readonly string[];\n\n constructor(\n logic: LogicFn<TParams, TTriggerEvent, TEmitEvent>,\n params: TParams,\n listensTo?: readonly string[],\n ) {\n this.#logic = logic;\n this.#params = params;\n this.#id = `agent-${randomUUID()}`;\n this.#listensTo = listensTo ?? [];\n }\n\n getListensTo(): readonly string[] {\n return this.#listensTo;\n }\n\n async invoke(options?: {\n triggerEvent?: TTriggerEvent;\n emit?: (event: TEmitEvent) => void;\n runEvents?: RunEvents;\n contextEvents?: ContextEvents;\n }): Promise<void> {\n const { triggerEvent, emit, runEvents, contextEvents } = options ?? {};\n\n const emitFn =\n emit ??\n ((_event: TEmitEvent): void => {\n // no-op – will be wired by the network at runtime\n });\n\n await this.#logic({\n params: this.#params,\n triggerEvent: triggerEvent ?? (undefined as TTriggerEvent),\n emit: emitFn,\n runEvents: runEvents ?? [],\n contextEvents: contextEvents ?? {\n all: [],\n byRun: () => [],\n map: new Map(),\n },\n });\n }\n\n getId(): string {\n return this.#id;\n }\n}\n","import { Schema as S } from 'effect';\nimport { Agent } from './agent';\nimport {\n AgentNetworkEventDef,\n type ContextEvents,\n type EventMeta,\n type RunEvents,\n} from './agent-network/agent-network-event';\nimport { BaseSchemaDefintion } from './types';\n\ntype EventDef = AgentNetworkEventDef<string, S.Schema.Any>;\n\n/** Extracts the envelope type (name, meta, payload) from an event definition */\nexport type EventEnvelope<E extends EventDef> =\n E extends AgentNetworkEventDef<infer N, infer PS>\n ? { name: N; meta: EventMeta; payload: S.Schema.Type<PS> }\n : never;\n\n/** What the user passes to emit() – no meta required */\nexport type EmitPayload<E extends EventDef> =\n E extends AgentNetworkEventDef<infer N, infer PS>\n ? { name: N; payload: S.Schema.Type<PS> }\n : never;\n\n/** Internal logic function */\ntype LogicFn<TParams, TTriggerEvent, TEmitEvent> = (ctx: {\n params: TParams;\n triggerEvent: TTriggerEvent;\n emit: (event: TEmitEvent) => void;\n runEvents: RunEvents;\n contextEvents: ContextEvents;\n}) => Promise<void>;\n\ntype ConstructorParams<\n TParams,\n TListensTo extends EventDef,\n TEmits extends EventDef,\n> = {\n logic?: LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>;\n paramsSchema?: BaseSchemaDefintion;\n listensTo?: ReadonlyArray<TListensTo>;\n emits?: ReadonlyArray<TEmits>;\n};\n\nexport class AgentFactory<\n TParams = unknown,\n TListensTo extends EventDef = never,\n TEmits extends EventDef = never,\n> {\n private _listensTo: ReadonlyArray<TListensTo>;\n private _emits: ReadonlyArray<TEmits>;\n private _logic:\n | LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>\n | undefined;\n private _paramsSchema: BaseSchemaDefintion | undefined;\n\n private constructor({\n logic,\n paramsSchema,\n listensTo = [],\n emits = [],\n }: ConstructorParams<TParams, TListensTo, TEmits>) {\n this._logic = logic;\n this._paramsSchema = paramsSchema;\n this._listensTo = listensTo;\n this._emits = emits;\n }\n\n private getConstructorState(): ConstructorParams<\n TParams,\n TListensTo,\n TEmits\n > {\n return {\n logic: this._logic,\n paramsSchema: this._paramsSchema,\n listensTo: this._listensTo,\n emits: this._emits,\n };\n }\n\n /** Union of all event definitions this agent listens to */\n getListensTo(): ReadonlyArray<TListensTo> {\n return this._listensTo;\n }\n\n /** Union of all event definitions this agent can emit */\n getEmits(): ReadonlyArray<TEmits> {\n return this._emits;\n }\n\n getLogic():\n | LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>\n | undefined {\n return this._logic;\n }\n\n static run(): AgentFactory<unknown, never, never> {\n return new AgentFactory<unknown, never, never>({});\n }\n\n params<TSchema extends BaseSchemaDefintion>(\n params: TSchema,\n ): AgentFactory<TSchema['Type'], TListensTo, TEmits> {\n const { logic, ...rest } = this.getConstructorState();\n\n return new AgentFactory({\n ...rest,\n logic: logic as LogicFn<\n TSchema['Type'],\n EventEnvelope<TListensTo>,\n EmitPayload<TEmits>\n >,\n paramsSchema: params,\n });\n }\n\n listensTo<E extends EventDef>(\n events: Array<E>,\n ): AgentFactory<TParams, TListensTo | E, TEmits> {\n return new AgentFactory<TParams, TListensTo | E, TEmits>({\n ...(this.getConstructorState() as unknown as ConstructorParams<\n TParams,\n TListensTo | E,\n TEmits\n >),\n listensTo: [...this._listensTo, ...events] as ReadonlyArray<\n TListensTo | E\n >,\n });\n }\n\n emits<E extends EventDef>(\n events: Array<E>,\n ): AgentFactory<TParams, TListensTo, TEmits | E> {\n return new AgentFactory<TParams, TListensTo, TEmits | E>({\n ...(this.getConstructorState() as unknown as ConstructorParams<\n TParams,\n TListensTo,\n TEmits | E\n >),\n emits: [...this._emits, ...events] as ReadonlyArray<TEmits | E>,\n });\n }\n\n logic(\n fn: LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>,\n ): AgentFactory<TParams, TListensTo, TEmits> {\n return new AgentFactory<TParams, TListensTo, TEmits>({\n ...this.getConstructorState(),\n logic: fn,\n });\n }\n\n produce(\n params: TParams,\n ): Agent<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>> {\n const listensTo = this._listensTo.map((e) => e.name);\n return new Agent<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>(\n this._logic!,\n params,\n listensTo,\n );\n }\n}\n","import type { Envelope } from '../../agent-network/event-plane';\n\n/** Format a single SSE message (event + data) */\nexport function formatSSE(envelope: Envelope): string {\n const data = JSON.stringify(envelope);\n return `event: ${envelope.name}\\ndata: ${data}\\n\\n`;\n}\n\n/** Create a ReadableStream that encodes envelopes as SSE */\nexport function toSSEStream(\n source: AsyncIterable<Envelope>,\n signal?: AbortSignal | null,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n return new ReadableStream<Uint8Array>({\n async start(controller): Promise<void> {\n const onAbort = (): void => controller.close();\n signal?.addEventListener('abort', onAbort, { once: true });\n\n try {\n for await (const envelope of source) {\n if (signal?.aborted) break;\n controller.enqueue(encoder.encode(formatSSE(envelope)));\n }\n } finally {\n signal?.removeEventListener('abort', onAbort);\n controller.close();\n }\n },\n });\n}\n","import type { ExposedAPI } from '../types';\nimport { ExposeAuthError } from '../expose';\nimport { formatSSE } from '../protocols/sse';\n\n/** Next.js App Router GET/POST handler signature */\nexport type NextGetHandler = (request: Request) => Promise<Response>;\n\n/** Options for NextEndpoint.from() - required to define how request maps to contextId and runId */\nexport type NextEndpointOptions = {\n requestToContextId: (request: Request) => string;\n requestToRunId: (request: Request) => string;\n};\n\n/**\n * Adapter for Next.js App Router. Maps an ExposedAPI to a route handler\n * that streams events as SSE. Use for both GET and POST; POST with JSON body\n * is recommended for passing the start event payload.\n *\n * @example\n * const api = agentNetwork.expose({ protocol: \"sse\", auth, select });\n * const handler = NextEndpoint.from(api, {\n * requestToContextId: (req) => req.headers.get('x-correlation-id') ?? crypto.randomUUID(),\n * requestToRunId: () => crypto.randomUUID(),\n * }).handler();\n * export const GET = handler;\n * export const POST = handler;\n */\nexport const NextEndpoint = {\n from(api: ExposedAPI, options: NextEndpointOptions): {\n handler(): NextGetHandler;\n } {\n if (api.protocol !== 'sse') {\n throw new Error(`NextEndpoint: unsupported protocol \"${api.protocol}\"`);\n }\n\n const { requestToContextId, requestToRunId } = options;\n\n return {\n handler(): NextGetHandler {\n return async (request: Request) => {\n const req = {\n request,\n contextId: requestToContextId(request),\n runId: requestToRunId(request),\n };\n\n try {\n const encoder = new TextEncoder();\n const { readable, writable } =\n new TransformStream<Uint8Array>();\n\n // Signal that the consumer callback has been entered (auth passed, stream ready)\n let consumerStarted!: () => void;\n const started = new Promise<void>((resolve) => {\n consumerStarted = resolve;\n });\n\n const streamDone = api.createStream(req, async (stream) => {\n consumerStarted();\n const writer = writable.getWriter();\n try {\n for await (const envelope of stream) {\n if (request.signal?.aborted) break;\n await writer.write(encoder.encode(formatSSE(envelope)));\n }\n } finally {\n await writer.close();\n }\n });\n\n // Race: consumer starts (auth passed) vs. createStream rejects (auth failed)\n await Promise.race([started, streamDone]);\n\n // Auth passed. Stream is being written in the background.\n streamDone.catch(() => {}); // prevent unhandled rejection\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n } catch (e) {\n if (e instanceof ExposeAuthError) {\n return new Response(e.message, { status: e.status });\n }\n throw e;\n }\n };\n },\n };\n },\n};\n","import type { ExposedAPI } from '../types';\nimport { ExposeAuthError } from '../expose';\nimport { formatSSE } from '../protocols/sse';\n\n/** Minimal Express-like request (compatible with express.Request) */\nexport type ExpressRequest = {\n on(event: 'close', fn: () => void): void;\n};\n\n/** Options for ExpressEndpoint.from() - required to define how request maps to contextId and runId */\nexport type ExpressEndpointOptions = {\n requestToContextId: (req: ExpressRequest) => string;\n requestToRunId: (req: ExpressRequest) => string;\n};\n\n/** Minimal Express-like response (compatible with express.Response) */\nexport type ExpressResponse = {\n setHeader(name: string, value: string | number): void;\n flushHeaders?(): void;\n write(chunk: Uint8Array): void;\n flush?(): void;\n end(): void;\n status(code: number): ExpressResponse;\n send(body: string): void;\n};\n\n/** Express route handler signature */\nexport type ExpressHandler = (\n req: ExpressRequest,\n res: ExpressResponse,\n) => void | Promise<void>;\n\n/**\n * Adapter for Express. Maps an ExposedAPI to an Express route handler\n * that streams events as SSE.\n *\n * @example\n * const api = agentNetwork.expose({ protocol: \"sse\", auth, select });\n * app.get(\"/events\", ExpressEndpoint.from(api, {\n * requestToContextId: (req) => req.headers?.['x-correlation-id'] ?? crypto.randomUUID(),\n * requestToRunId: () => crypto.randomUUID(),\n * }).handler());\n */\nexport const ExpressEndpoint = {\n from(api: ExposedAPI, options: ExpressEndpointOptions): {\n handler(): ExpressHandler;\n } {\n if (api.protocol !== 'sse') {\n throw new Error(\n `ExpressEndpoint: unsupported protocol \"${api.protocol}\"`,\n );\n }\n\n const { requestToContextId, requestToRunId } = options;\n\n return {\n handler(): ExpressHandler {\n return async (req: ExpressRequest, res: ExpressResponse) => {\n const controller = new AbortController();\n req.on('close', () => controller.abort());\n\n const exposeReq = {\n request: { signal: controller.signal } as Request,\n req,\n res,\n contextId: requestToContextId(req),\n runId: requestToRunId(req),\n };\n\n try {\n const encoder = new TextEncoder();\n await api.createStream(exposeReq, async (stream) => {\n // Set SSE headers only after auth has passed\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.flushHeaders?.();\n\n try {\n for await (const envelope of stream) {\n if (controller.signal.aborted) break;\n res.write(encoder.encode(formatSSE(envelope)));\n res.flush?.();\n }\n } finally {\n res.end();\n }\n });\n } catch (e) {\n if (e instanceof ExposeAuthError) {\n res.status(e.status).send(e.message);\n return;\n }\n throw e;\n }\n };\n },\n };\n },\n};\n","import { Context, Exit, Layer, Option, Tracer } from 'effect';\n\nconst randomHexString = (length: number): string => {\n const chars = 'abcdef0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n};\n\n/** Span that logs to console when ended */\nclass ConsoleSpan implements Tracer.Span {\n readonly _tag = 'Span' as const;\n readonly spanId: string;\n readonly traceId: string;\n readonly sampled = true;\n status: Tracer.SpanStatus;\n attributes: Map<string, unknown> = new Map();\n links: Tracer.SpanLink[] = [];\n\n constructor(\n readonly name: string,\n readonly parent: Option.Option<Tracer.AnySpan>,\n readonly context: Context.Context<never>,\n links: Iterable<Tracer.SpanLink>,\n readonly startTime: bigint,\n readonly kind: Tracer.SpanKind,\n private readonly depth: number,\n ) {\n this.traceId =\n parent._tag === 'Some' ? parent.value.traceId : randomHexString(32);\n this.spanId = randomHexString(16);\n this.links = Array.from(links);\n this.status = { _tag: 'Started', startTime };\n }\n\n end(endTime: bigint, exit: Exit.Exit<unknown, unknown>): void {\n if (this.status._tag === 'Ended') return;\n const startTime = this.status.startTime;\n const durationNs = endTime - startTime;\n const durationMs = Number(durationNs) / 1_000_000;\n const indent = ' '.repeat(this.depth);\n const attrs = Object.fromEntries(this.attributes);\n const status = Exit.isSuccess(exit) ? 'ok' : 'error';\n // eslint-disable-next-line no-console\n console.log(\n `${indent}[trace] ${this.name} ${durationMs.toFixed(2)}ms (${status})`,\n Object.keys(attrs).length > 0 ? attrs : '',\n );\n this.status = { _tag: 'Ended', startTime, endTime, exit };\n }\n\n attribute(key: string, value: unknown): void {\n this.attributes.set(key, value);\n }\n\n event(\n _name: string,\n _startTime: bigint,\n _attributes?: Record<string, unknown>,\n ): void {\n // no-op for console tracer\n }\n\n addLinks(links: ReadonlyArray<Tracer.SpanLink>): void {\n this.links.push(...links);\n }\n}\n\nfunction getDepth(parent: Option.Option<Tracer.AnySpan>): number {\n if (parent._tag === 'None') return 0;\n const p = parent.value;\n if (p._tag === 'ExternalSpan') return 0;\n return 1 + getDepth((p as Tracer.Span).parent);\n}\n\n/**\n * A Tracer that logs spans to console when they end. No optional dependencies\n * required. Use `consoleTracerLayer` when running your program to enable.\n *\n * @example\n * ```ts\n * import { Effect } from 'effect';\n * import { AgentNetwork, consoleTracerLayer } from '@m4trix/core/matrix';\n *\n * const network = AgentNetwork.setup(({ ... }) => { ... });\n * const program = network.run().pipe(\n * Effect.provide(consoleTracerLayer),\n * Effect.scoped\n * );\n * Effect.runPromise(program);\n * ```\n */\nexport const consoleTracer: Tracer.Tracer = Tracer.make({\n span: (name, parent, context, links, startTime, kind) =>\n new ConsoleSpan(\n name,\n parent,\n context,\n links,\n startTime,\n kind,\n getDepth(parent),\n ),\n context: (f) => f(),\n});\n\n/**\n * Layer that provides the console tracer. Pipe your program with\n * `Effect.provide(consoleTracerLayer)` before running to see spans in stdout.\n */\nexport const consoleTracerLayer: Layer.Layer<never> = Layer.setTracer(\n consoleTracer,\n);\n"]}