@directive-run/ai 1.17.2 → 1.19.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/ann-index-27QV9tPC.d.ts +616 -0
- package/dist/ann-index-HoZFIUA-.d.cts +616 -0
- package/dist/anthropic.d.cts +1 -1
- package/dist/anthropic.d.ts +1 -1
- package/dist/chunk-2PG26JZU.cjs +16 -0
- package/dist/chunk-2PG26JZU.cjs.map +1 -0
- package/dist/{chunk-7DPTXZZI.cjs → chunk-7EJN6TYX.cjs} +4 -4
- package/dist/chunk-7EJN6TYX.cjs.map +1 -0
- package/dist/{chunk-FN4GUZAI.js → chunk-G7CRWJT7.js} +4 -4
- package/dist/chunk-G7CRWJT7.js.map +1 -0
- package/dist/chunk-MIHH5GPT.js +16 -0
- package/dist/chunk-MIHH5GPT.js.map +1 -0
- package/dist/{chunk-56LYSE63.js → chunk-RHJAMXLS.js} +3 -3
- package/dist/{chunk-56LYSE63.js.map → chunk-RHJAMXLS.js.map} +1 -1
- package/dist/{chunk-PB276BX2.cjs → chunk-XGHNOSXT.cjs} +4 -4
- package/dist/{chunk-PB276BX2.cjs.map → chunk-XGHNOSXT.cjs.map} +1 -1
- package/dist/{debug-timeline-L13P-U2I.d.ts → debug-timeline-BGcPa0JO.d.ts} +1 -1
- package/dist/{debug-timeline-DpnRMnLU.d.cts → debug-timeline-Dn1lC_gK.d.cts} +1 -1
- package/dist/devtools.d.cts +5 -5
- package/dist/devtools.d.ts +5 -5
- package/dist/evals.d.cts +2 -2
- package/dist/evals.d.ts +2 -2
- package/dist/gemini.d.cts +1 -1
- package/dist/gemini.d.ts +1 -1
- package/dist/guardrails.cjs +1 -1
- package/dist/guardrails.cjs.map +1 -1
- package/dist/guardrails.d.cts +164 -592
- package/dist/guardrails.d.ts +164 -592
- package/dist/guardrails.js +1 -1
- package/dist/guardrails.js.map +1 -1
- package/dist/{health-monitor-C6xoXrQz.d.cts → health-monitor-Cq5sDvid.d.cts} +1 -1
- package/dist/{health-monitor-qL9RNMH3.d.ts → health-monitor-DtwmIJkb.d.ts} +1 -1
- package/dist/index.cjs +15 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +94 -11
- package/dist/index.d.ts +94 -11
- package/dist/index.js +15 -15
- package/dist/index.js.map +1 -1
- package/dist/multi-agent-orchestrator-OX2TKD5Y.cjs +2 -0
- package/dist/{multi-agent-orchestrator-KFYIDKTF.cjs.map → multi-agent-orchestrator-OX2TKD5Y.cjs.map} +1 -1
- package/dist/{multi-agent-orchestrator-ZHSMWIKP.js → multi-agent-orchestrator-RMTLPKB4.js} +2 -2
- package/dist/{multi-agent-orchestrator-ZHSMWIKP.js.map → multi-agent-orchestrator-RMTLPKB4.js.map} +1 -1
- package/dist/multi-agent.cjs +1 -1
- package/dist/multi-agent.d.cts +6 -6
- package/dist/multi-agent.d.ts +6 -6
- package/dist/multi-agent.js +1 -1
- package/dist/ollama.d.cts +1 -1
- package/dist/ollama.d.ts +1 -1
- package/dist/openai.d.cts +2 -2
- package/dist/openai.d.ts +2 -2
- package/dist/{orchestrator-types-ZK9lv5Sm.d.ts → orchestrator-types-C5D5JZUj.d.ts} +103 -3
- package/dist/{orchestrator-types-CbNE7Rjp.d.cts → orchestrator-types-s0766dDB.d.cts} +103 -3
- package/dist/predicate.d.cts +1 -1
- package/dist/predicate.d.ts +1 -1
- package/dist/{semantic-cache-DM7ev7NQ.d.cts → semantic-cache-Ba0-jEwb.d.cts} +1 -1
- package/dist/{semantic-cache-DM7ev7NQ.d.ts → semantic-cache-Ba0-jEwb.d.ts} +1 -1
- package/dist/testing.cjs +1 -1
- package/dist/testing.d.cts +4 -4
- package/dist/testing.d.ts +4 -4
- package/dist/testing.js +1 -1
- package/dist/{types-DJ09LjZX.d.cts → types-CUp1N0uU.d.cts} +1 -1
- package/dist/{types-DJ09LjZX.d.ts → types-CUp1N0uU.d.ts} +1 -1
- package/package.json +2 -2
- package/dist/chunk-7DPTXZZI.cjs.map +0 -1
- package/dist/chunk-D5APTMCT.cjs +0 -16
- package/dist/chunk-D5APTMCT.cjs.map +0 -1
- package/dist/chunk-FN4GUZAI.js.map +0 -1
- package/dist/chunk-YT4QN3KO.js +0 -16
- package/dist/chunk-YT4QN3KO.js.map +0 -1
- package/dist/multi-agent-orchestrator-KFYIDKTF.cjs +0 -2
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/pipe.ts","../src/memory.ts","../src/plugins/audit.ts","../src/plugins/compliance.ts","../src/stream-channel.ts","../src/rag.ts","../src/sse-transport.ts","../src/retry.ts","../src/fallback.ts","../src/budget.ts","../src/model-selector.ts","../src/batch.ts","../src/provider-routing.ts","../src/otel.ts"],"names":["pipe","runner","middlewares","result","mw","estimateTokens","message","tokenizer","content","estimateTotalTokens","messages","sum","msg","createSlidingWindowStrategy","defaultConfig","configOverride","config","maxMessages","preserveRecentCount","recentMessages","olderMessages","olderToKeep","keptOlder","toSummarize","keep","createTokenBasedStrategy","maxTokens","countSystemMessages","recentTokens","currentTokens","i","msgTokens","createHybridStrategy","slidingWindow","tokenBased","windowResult","tokenResult","createAgentMemory","strategy","summarizer","strategyConfig","autoManage","onMemoryManaged","onManageError","maxContextTokens","state","isManaging","manage","messagesBefore","estimatedTokensBefore","summary","manageResult","triggerAutoManage","error","err","s","contextMessages","summaryContent","totalTokens","importedState","createTruncationSummarizer","maxLength","m","text","createKeyPointsSummarizer","keyPoints","questions","q","createLLMSummarizer","llmCall","options","maxSummaryLength","preserveKeyFacts","conversationText","prompt","DEFAULT_MAX_ENTRIES","DEFAULT_RETENTION_MS","DEFAULT_EXPORT_INTERVAL","GENESIS_PREVIOUS_HASH","generateId","stringToBytes","str","bytesToHex","bytes","b","sha256","hashBuffer","createHashContent","entry","id","timestamp","eventType","previousHash","payload","actorId","sessionId","deepClone","obj","maskPayload","masked","processValue","value","detectPII","itemsToRedact","item","redactPII","processed","k","v","key","createAuditTrail","maxEntries","retentionMs","exportInterval","exporter","piiMasking","signing","events","entries","lastExportIndex","entriesPruned","entriesExported","chainVerified","exportTimer","getLastHash","addEntry","overrides","hashContent","hash","fullEntry","toExport","filter","typeSet","e","expectedHash","prevEntry","since","cutoff","initialLength","pruned","byEventType","prev","changes","c","req","byResolver","resolver","duration","createAgentAuditHandlers","audit","agentName","input","output","tokens","cost","toolName","toolCallId","args","reason","toCSV","data","keys","record","headers","lines","values","createInMemoryComplianceStorage","consents","certificates","subjectId","categories","category","subjectMap","records","count","olderThan","categoryData","ids","idSet","filtered","r","purpose","certificate","createCompliance","storage","retention","exportExpirationMs","consent","existing","request","subjectData","allRecords","auditEntries","checksum","recordsAffected","categoriesAffected","certificateContent","totalDeleted","now","expired","deleted","_subjectId","createStreamChannel","bufferSize","buffer","streamError","consumerWaiter","producerWaiter","hasConsumer","resolveConsumer","waiter","endConsumer","errorConsumer","resolveProducer","resolve","reject","createBidirectionalStream","channelAtoB","channelBtoA","pipeThrough","source","destination","transform","transformed","mergeStreams","sources","doneCount","errorState","stopped","hasWarnedDrop","sourceIterators","notifyWaiter","w","iter","defaultFormatChunk","chunk","_similarity","title","section","url","defaultFormatContext","formattedChunks","_query","clamp","min","max","createRAGEnricher","embedder","defaultTopK","rawMinSimilarity","formatChunk","formatContext","onError","minSimilarity","retrieve","query","topK","queryEmbedding","scored","cosineSimilarity","a","enrich","prefix","history","matches","contextBlock","parts","historyBlock","validateFilePath","filePath","baseDir","resolved","path","resolvedBase","createJSONFileStore","mapEntry","ttlMs","resolvedPath","cached","cachedAt","load","raw","DEFAULT_ERROR_MESSAGE","createSSETransport","maxResponseChars","truncationMessage","heartbeatIntervalMs","errorMessages","extraHeaders","resolveErrorMessage","code","buildStream","agentId","opts","encoder","frame","event","controller","heartbeatTimer","tokenStream","totalChars","sentDone","token","sseHeaders","stream","RetryExhaustedError","retryCount","lastError","NON_RETRYABLE_STATUSES","parseHttpStatus","errObj","match","status","parseRetryAfter","seconds","calculateBackoffDelay","attempt","baseDelayMs","maxDelayMs","exponential","jitter","delay","getRetryDelay","retryAfter","isStatusRetryable","withRetry","maxRetries","isRetryable","onRetry","agent","delayMs","signal","timer","onAbort","AllProvidersFailedError","errors","withFallback","runners","shouldFallback","onFallback","BudgetExceededError","details","CostLedger","windowMs","total","pruneIndex","WINDOW_MS","estimateInputTokens","charsPerToken","calculateCost","usage","pricing","estimateCallCost","inputTokens","outputMultiplier","estimatedOutputTokens","withBudget","maxCostPerCall","budgets","estimatedOutputMultiplier","onBudgetExceeded","budget","windowLedgers","baseLedger","budgetRunner","estimated","spent","remaining","ledger","actualCost","getSpent","window","byInputLength","model","_agent","byAgentName","name","byPattern","pattern","withModelSelection","configOrRules","rules","onModelSelected","selectedModel","rule","effectiveAgent","createBatchQueue","maxBatchSize","maxWaitMs","concurrency","queue","flushTimer","destroyed","flushPromise","scheduleFlush","flushInternal","cancelTimer","executeBatch","batch","index","runNext","current","call","workers","createEmptyStats","createConstraintRouter","providers","defaultProvider","constraints","onProviderSelected","errorCooldownMs","preferCheapest","providerMap","provider","facts","totalLatencyMs","sortedConstraints","selectProvider","constraint","availableProviders","p","stats","sorted","aCost","bCost","recordCall","providerName","latencyMs","statsTotal","routerRunner","startTime","clonedProviders","OtelStatusCode","CollectedSpan","spanId","traceId","parentSpanId","initialAttributes","onEnd","attributes","CollectorTracer","span","createOtelPlugin","instrumentEvents","spanTtlMs","isCollector","collectorTracer","tracer","spanCounter","generateTraceId","activeSpans","keyCounter","spanKeyIndex","patternStack","attachedTimeline","warnedExternalGetSpans","shouldInstrument","type","makeSpanKey","findActiveSpan","indexKey","registerSpan","removeSpan","idx","cleanupStaleSpans","setAttributeTracked","setStatusTracked","endSpan","startSpan","parentEntry","spanToData","addEventTracked","handleEvent","handleAgentStart","handleAgentComplete","handleAgentError","handleGuardrailCheck","handleConstraintEvaluate","handleResolverStart","handleResolverComplete","handleResolverError","handlePatternStart","handlePatternComplete","found","timeline","unsub","cleanupInterval","_key"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Middleware composition utility — left-to-right pipeline for AgentRunner wrappers.\n *\n * Each middleware is a function that takes an `AgentRunner` and returns a new\n * `AgentRunner`. `pipe` applies them left to right, so the first middleware\n * in the list wraps the runner first (innermost), and the last wraps last\n * (outermost).\n *\n * @module\n *\n * @example\n * ```typescript\n * import { pipe, withRetry, withFallback, withBudget } from '@directive-run/ai';\n *\n * const runner = pipe(\n * baseRunner,\n * withFallback([anthropicRunner, openaiRunner]),\n * withRetry({ maxRetries: 3 }),\n * withBudget({ budgets: [{ window: 'hour', maxCost: 5, pricing }] }),\n * );\n * ```\n */\n\nimport type { AgentRunner } from \"./types.js\";\n\n/** A function that wraps an AgentRunner, returning a new AgentRunner. */\nexport type RunnerMiddleware = (runner: AgentRunner) => AgentRunner;\n\n/**\n * Compose middleware left-to-right onto a base runner.\n *\n * @param runner - The base `AgentRunner` to wrap.\n * @param middlewares - One or more middleware functions to apply in order.\n * @returns A new `AgentRunner` with all middleware applied.\n */\nexport function pipe(\n runner: AgentRunner,\n ...middlewares: RunnerMiddleware[]\n): AgentRunner {\n let result = runner;\n for (const mw of middlewares) {\n result = mw(result);\n }\n\n return result;\n}\n","/**\n * Agent Memory System\n *\n * Provides sliding window message management and automatic summarization\n * for long-running agent conversations.\n *\n * @example\n * ```typescript\n * import { createAgentMemory, createSlidingWindowStrategy } from '@directive-run/ai';\n *\n * const memory = createAgentMemory({\n * strategy: createSlidingWindowStrategy({ maxMessages: 50 }),\n * summarizer: async (messages) => {\n * // Call LLM to summarize older messages\n * return await summarizeWithLLM(messages);\n * },\n * });\n *\n * // Use with orchestrator\n * const orchestrator = createAgentOrchestrator({\n * memory,\n * runner: run,\n * });\n * ```\n */\n\n// ============================================================================\n// Message Types\n// ============================================================================\n\n/**\n * Memory-compatible message type.\n * Extends the standard Message type to include system messages for summaries.\n */\nexport interface MemoryMessage {\n role: \"user\" | \"assistant\" | \"tool\" | \"system\";\n content: string;\n toolCallId?: string;\n}\n\n// Alias for compatibility\nexport type Message = MemoryMessage;\n\n// ============================================================================\n// Memory Strategy Types\n// ============================================================================\n\n/** Configuration for memory management strategies */\nexport interface MemoryStrategyConfig {\n /** Maximum number of messages to keep in active memory */\n maxMessages?: number;\n /** Maximum total tokens to keep in active memory */\n maxTokens?: number;\n /** Number of recent messages to always keep (protected from summarization) */\n preserveRecentCount?: number;\n /** Whether to include system messages in token count */\n countSystemMessages?: boolean;\n}\n\n/** Result of a memory strategy evaluation */\nexport interface MemoryStrategyResult {\n /** Messages to keep in active memory */\n keep: Message[];\n /** Messages to summarize or discard */\n toSummarize: Message[];\n /** Estimated token count of kept messages */\n estimatedTokens: number;\n}\n\n/** Memory management strategy function */\nexport type MemoryStrategy = (\n messages: Message[],\n config: MemoryStrategyConfig,\n) => MemoryStrategyResult;\n\n/** Summarizer function to compress older messages */\nexport type MessageSummarizer = (messages: Message[]) => Promise<string>;\n\n// ============================================================================\n// Memory Instance Types\n// ============================================================================\n\n/** Agent memory configuration */\nexport interface AgentMemoryConfig {\n /** Memory management strategy */\n strategy: MemoryStrategy;\n /** Optional summarizer for compressing old messages */\n summarizer?: MessageSummarizer;\n /** Strategy configuration */\n strategyConfig?: MemoryStrategyConfig;\n /** Whether to auto-manage memory after each interaction */\n autoManage?: boolean;\n /** Callback when memory is managed */\n onMemoryManaged?: (result: MemoryManageResult) => void;\n /** Callback when auto-manage encounters an error */\n onManageError?: (error: Error) => void;\n /** Maximum context window tokens (triggers additional summarization if exceeded) */\n maxContextTokens?: number;\n}\n\n/** Result of memory management */\nexport interface MemoryManageResult {\n /** Number of messages before management */\n messagesBefore: number;\n /** Number of messages after management */\n messagesAfter: number;\n /** Number of messages summarized */\n messagesSummarized: number;\n /** The summary that was generated (if any) */\n summary?: string;\n /** Estimated tokens before */\n estimatedTokensBefore: number;\n /** Estimated tokens after */\n estimatedTokensAfter: number;\n}\n\n/** Memory state for a conversation */\nexport interface MemoryState {\n /** Active messages in memory */\n messages: Message[];\n /** Summaries of older messages */\n summaries: Array<{\n content: string;\n messagesCount: number;\n createdAt: number;\n }>;\n /** Total messages ever processed */\n totalMessagesProcessed: number;\n /** Estimated current token count */\n estimatedTokens: number;\n}\n\n/** Agent memory instance */\nexport interface AgentMemory {\n /** Get current memory state */\n getState(): MemoryState;\n /** Add a message to memory */\n addMessage(message: Message): void;\n /** Check if memory management is currently in progress */\n isManaging(): boolean;\n /** Add multiple messages to memory */\n addMessages(messages: Message[]): void;\n /** Get messages for context (includes summaries as system messages) */\n getContextMessages(): Message[];\n /** Manually trigger memory management */\n manage(): Promise<MemoryManageResult>;\n /** Clear all memory */\n clear(): void;\n /** Export memory state for persistence */\n export(): MemoryState;\n /** Import memory state from persistence */\n import(state: MemoryState): void;\n}\n\n// ============================================================================\n// Token Estimation\n// ============================================================================\n\n/** Approximate characters per token (default heuristic) */\nconst APPROX_CHARS_PER_TOKEN = 4;\n\n/**\n * Estimate the token count for a single message.\n *\n * Uses a simple heuristic (~4 characters per token) by default.\n * For more accurate counts, pass a custom tokenizer function.\n *\n * @param message - The message to estimate tokens for.\n * @param tokenizer - Optional custom tokenizer function (e.g., tiktoken).\n * @returns The estimated number of tokens.\n *\n * @example\n * ```typescript\n * // Default heuristic\n * const tokens = estimateTokens({ role: 'user', content: 'Hello world' });\n *\n * // Custom tokenizer (e.g., tiktoken)\n * const tokens = estimateTokens(msg, (text) => tiktoken.encode(text).length);\n * ```\n */\nexport function estimateTokens(\n message: Message,\n tokenizer?: (text: string) => number,\n): number {\n const content =\n typeof message.content === \"string\"\n ? message.content\n : JSON.stringify(message.content);\n\n if (tokenizer) {\n return tokenizer(content);\n }\n\n return Math.ceil(content.length / APPROX_CHARS_PER_TOKEN);\n}\n\n/**\n * Estimate the total token count for an array of messages.\n *\n * @param messages - The messages to estimate tokens for.\n * @param tokenizer - Optional custom tokenizer function.\n * @returns The total estimated token count across all messages.\n */\nexport function estimateTotalTokens(\n messages: Message[],\n tokenizer?: (text: string) => number,\n): number {\n return messages.reduce((sum, msg) => sum + estimateTokens(msg, tokenizer), 0);\n}\n\n// ============================================================================\n// Built-in Strategies\n// ============================================================================\n\n/**\n * Create a sliding window memory strategy that keeps the most recent N messages.\n *\n * Messages beyond `maxMessages` are moved to the summarization queue.\n * The most recent `preserveRecentCount` messages are always kept.\n *\n * @param defaultConfig - Default strategy configuration (can be overridden per-call).\n * @returns A {@link MemoryStrategy} function.\n *\n * @example\n * ```typescript\n * const strategy = createSlidingWindowStrategy({\n * maxMessages: 50,\n * preserveRecentCount: 10,\n * });\n * ```\n * @public\n */\nexport function createSlidingWindowStrategy(\n defaultConfig: MemoryStrategyConfig = {},\n): MemoryStrategy {\n return (messages: Message[], configOverride: MemoryStrategyConfig = {}) => {\n const config = { ...defaultConfig, ...configOverride };\n const maxMessages = config.maxMessages ?? 100;\n const preserveRecentCount = config.preserveRecentCount ?? 5;\n\n if (messages.length <= maxMessages) {\n return {\n keep: [...messages],\n toSummarize: [],\n estimatedTokens: estimateTotalTokens(messages),\n };\n }\n\n // Always keep the most recent messages\n const recentMessages = messages.slice(-preserveRecentCount);\n const olderMessages = messages.slice(0, -preserveRecentCount);\n\n // Calculate how many older messages we can keep\n const olderToKeep = Math.max(0, maxMessages - preserveRecentCount);\n const keptOlder = olderMessages.slice(-olderToKeep);\n const toSummarize = olderMessages.slice(0, -olderToKeep || undefined);\n\n const keep = [...keptOlder, ...recentMessages];\n\n return {\n keep,\n toSummarize: toSummarize.length > 0 ? toSummarize : [],\n estimatedTokens: estimateTotalTokens(keep),\n };\n };\n}\n\n/**\n * Create a token-based memory strategy that keeps messages until a token limit is reached.\n *\n * Adds messages from newest to oldest until `maxTokens` would be exceeded,\n * then moves the remaining older messages to the summarization queue.\n *\n * @param defaultConfig - Default strategy configuration (can be overridden per-call).\n * @returns A {@link MemoryStrategy} function.\n *\n * @example\n * ```typescript\n * const strategy = createTokenBasedStrategy({\n * maxTokens: 4000,\n * preserveRecentCount: 5,\n * });\n * ```\n * @public\n */\nexport function createTokenBasedStrategy(\n defaultConfig: MemoryStrategyConfig = {},\n): MemoryStrategy {\n return (messages: Message[], configOverride: MemoryStrategyConfig = {}) => {\n const config = { ...defaultConfig, ...configOverride };\n const maxTokens = config.maxTokens ?? 4000;\n const preserveRecentCount = config.preserveRecentCount ?? 5;\n const countSystemMessages = config.countSystemMessages ?? true;\n\n // Always keep recent messages\n const recentMessages = messages.slice(-preserveRecentCount);\n const olderMessages = messages.slice(0, -preserveRecentCount);\n\n const recentTokens = recentMessages.reduce((sum, msg) => {\n if (!countSystemMessages && msg.role === \"system\") return sum;\n return sum + estimateTokens(msg);\n }, 0);\n\n // Add older messages from newest to oldest until we hit the limit\n const keep: Message[] = [];\n const toSummarize: Message[] = [];\n let currentTokens = recentTokens;\n\n for (let i = olderMessages.length - 1; i >= 0; i--) {\n const msg = olderMessages[i]!; // Safe: i is within bounds\n const msgTokens =\n !countSystemMessages && msg.role === \"system\" ? 0 : estimateTokens(msg);\n\n if (currentTokens + msgTokens <= maxTokens) {\n keep.unshift(msg);\n currentTokens += msgTokens;\n } else {\n // All remaining older messages go to summarization\n toSummarize.push(...olderMessages.slice(0, i + 1));\n break;\n }\n }\n\n return {\n keep: [...keep, ...recentMessages],\n toSummarize,\n estimatedTokens: currentTokens,\n };\n };\n}\n\n/**\n * Create a hybrid strategy that combines message count and token limits.\n *\n * Applies both {@link createSlidingWindowStrategy} and {@link createTokenBasedStrategy},\n * then uses whichever result keeps fewer messages (the more restrictive outcome).\n *\n * @param defaultConfig - Default strategy configuration (can be overridden per-call).\n * @returns A {@link MemoryStrategy} function.\n *\n * @example\n * ```typescript\n * const strategy = createHybridStrategy({\n * maxMessages: 50,\n * maxTokens: 4000,\n * preserveRecentCount: 5,\n * });\n * ```\n * @public\n */\nexport function createHybridStrategy(\n defaultConfig: MemoryStrategyConfig = {},\n): MemoryStrategy {\n const slidingWindow = createSlidingWindowStrategy(defaultConfig);\n const tokenBased = createTokenBasedStrategy(defaultConfig);\n\n return (messages: Message[], configOverride: MemoryStrategyConfig = {}) => {\n const config = { ...defaultConfig, ...configOverride };\n\n // Apply both strategies and use the more restrictive result\n const windowResult = slidingWindow(messages, config);\n const tokenResult = tokenBased(messages, config);\n\n // Use the strategy that keeps fewer messages\n if (windowResult.keep.length <= tokenResult.keep.length) {\n return windowResult;\n }\n return tokenResult;\n };\n}\n\n// ============================================================================\n// Agent Memory Factory\n// ============================================================================\n\n/**\n * Create an agent memory instance for managing conversation history.\n *\n * Provides sliding window management, automatic summarization of older messages,\n * and import/export for persistence. Pass the returned instance to an orchestrator's\n * `memory` option to auto-inject context and auto-store results.\n *\n * @param config - Memory configuration including strategy, optional summarizer, and auto-manage settings.\n * @returns An {@link AgentMemory} instance with `addMessage`, `getContextMessages`, `manage`, and `export`/`import` APIs.\n *\n * @example\n * ```typescript\n * const memory = createAgentMemory({\n * strategy: createSlidingWindowStrategy({ maxMessages: 50 }),\n * summarizer: async (messages) => {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4o-mini',\n * messages: [\n * { role: 'system', content: 'Summarize the following conversation concisely.' },\n * ...messages.map(m => ({ role: m.role, content: m.content })),\n * ],\n * });\n * return response.choices[0].message.content;\n * },\n * autoManage: true,\n * });\n * ```\n * @public\n */\nexport function createAgentMemory(config: AgentMemoryConfig): AgentMemory {\n const {\n strategy,\n summarizer,\n strategyConfig = {},\n autoManage = false,\n onMemoryManaged,\n onManageError,\n maxContextTokens,\n } = config;\n\n let state: MemoryState = {\n messages: [],\n summaries: [],\n totalMessagesProcessed: 0,\n estimatedTokens: 0,\n };\n\n // Flag to prevent concurrent management operations\n let isManaging = false;\n\n async function manage(): Promise<MemoryManageResult> {\n // Prevent concurrent management\n if (isManaging) {\n return {\n messagesBefore: state.messages.length,\n messagesAfter: state.messages.length,\n messagesSummarized: 0,\n estimatedTokensBefore: state.estimatedTokens,\n estimatedTokensAfter: state.estimatedTokens,\n };\n }\n\n isManaging = true;\n\n try {\n const messagesBefore = state.messages.length;\n const estimatedTokensBefore = state.estimatedTokens;\n\n const result = strategy(state.messages, strategyConfig);\n\n if (result.toSummarize.length === 0) {\n return {\n messagesBefore,\n messagesAfter: messagesBefore,\n messagesSummarized: 0,\n estimatedTokensBefore,\n estimatedTokensAfter: result.estimatedTokens,\n };\n }\n\n let summary: string | undefined;\n\n if (summarizer && result.toSummarize.length > 0) {\n summary = await summarizer(result.toSummarize);\n state.summaries.push({\n content: summary,\n messagesCount: result.toSummarize.length,\n createdAt: Date.now(),\n });\n }\n\n state.messages = result.keep;\n state.estimatedTokens = result.estimatedTokens;\n\n const manageResult: MemoryManageResult = {\n messagesBefore,\n messagesAfter: state.messages.length,\n messagesSummarized: result.toSummarize.length,\n summary,\n estimatedTokensBefore,\n estimatedTokensAfter: result.estimatedTokens,\n };\n\n onMemoryManaged?.(manageResult);\n\n return manageResult;\n } finally {\n isManaging = false;\n }\n }\n\n // Safe auto-manage that handles errors properly\n function triggerAutoManage(): void {\n if (isManaging) return;\n\n const check = strategy(state.messages, strategyConfig);\n if (check.toSummarize.length > 0) {\n manage().catch((error) => {\n const err = error instanceof Error ? error : new Error(String(error));\n if (onManageError) {\n onManageError(err);\n } else {\n console.error(\"[Directive Memory] Auto-manage error:\", err);\n }\n });\n }\n }\n\n return {\n getState() {\n return {\n ...state,\n messages: [...state.messages],\n summaries: state.summaries.map((s) => ({ ...s })),\n };\n },\n\n addMessage(message: Message) {\n state.messages.push(message);\n state.totalMessagesProcessed++;\n state.estimatedTokens += estimateTokens(message);\n\n if (autoManage) {\n triggerAutoManage();\n }\n },\n\n addMessages(messages: Message[]) {\n for (const message of messages) {\n state.messages.push(message);\n state.totalMessagesProcessed++;\n state.estimatedTokens += estimateTokens(message);\n }\n\n if (autoManage) {\n triggerAutoManage();\n }\n },\n\n getContextMessages(): Message[] {\n const contextMessages: Message[] = [];\n\n // Add summaries as system messages at the beginning\n if (state.summaries.length > 0) {\n const summaryContent = state.summaries\n .map((s) => s.content)\n .join(\"\\n\\n---\\n\\n\");\n\n contextMessages.push({\n role: \"system\",\n content: `[Previous conversation summary]\\n\\n${summaryContent}`,\n });\n }\n\n // Add current messages\n contextMessages.push(...state.messages);\n\n // Check if context exceeds max tokens and warn\n if (maxContextTokens) {\n const totalTokens = estimateTotalTokens(contextMessages);\n if (totalTokens > maxContextTokens) {\n console.warn(\n `[Directive Memory] Context messages (${totalTokens} tokens) exceed maxContextTokens (${maxContextTokens}). Consider calling manage() or reducing message count.`,\n );\n }\n }\n\n return contextMessages;\n },\n\n manage,\n\n /** Check if memory management is currently in progress */\n isManaging() {\n return isManaging;\n },\n\n clear() {\n state = {\n messages: [],\n summaries: [],\n totalMessagesProcessed: 0,\n estimatedTokens: 0,\n };\n },\n\n export() {\n return {\n ...state,\n messages: [...state.messages],\n summaries: state.summaries.map((s) => ({ ...s })),\n };\n },\n\n import(importedState: MemoryState) {\n state = {\n ...importedState,\n messages: [...importedState.messages],\n summaries: importedState.summaries.map((s) => ({ ...s })),\n };\n },\n };\n}\n\n// ============================================================================\n// Built-in Summarizers\n// ============================================================================\n\n/**\n * Create a simple truncation summarizer that clips messages to a maximum length.\n *\n * Useful for testing or when LLM-based summarization is not needed.\n * Concatenates non-system messages with role prefixes and truncates to `maxLength`.\n *\n * @param maxLength - Maximum character length of the summary (default: 500).\n * @returns A {@link MessageSummarizer} function.\n * @public\n */\nexport function createTruncationSummarizer(maxLength = 500): MessageSummarizer {\n return async (messages: Message[]) => {\n const content = messages\n .filter((m) => m.role !== \"system\")\n .map((m) => {\n const text =\n typeof m.content === \"string\" ? m.content : JSON.stringify(m.content);\n return `${m.role}: ${text.slice(0, 100)}${text.length > 100 ? \"...\" : \"\"}`;\n })\n .join(\"\\n\");\n\n if (content.length <= maxLength) {\n return content;\n }\n\n return `${content.slice(0, maxLength)}\\n[truncated]`;\n };\n}\n\n/**\n * Create a summarizer that extracts user questions from messages.\n *\n * Scans for sentences ending with `?` in user messages and lists them as key topics.\n *\n * @returns A {@link MessageSummarizer} function.\n * @public\n */\nexport function createKeyPointsSummarizer(): MessageSummarizer {\n return async (messages: Message[]) => {\n const keyPoints: string[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"user\") {\n const content =\n typeof msg.content === \"string\"\n ? msg.content\n : JSON.stringify(msg.content);\n // Extract questions (sentences ending with ?)\n const questions = content.match(/[^.!?]*\\?/g);\n if (questions) {\n keyPoints.push(...questions.map((q) => `Q: ${q.trim()}`));\n }\n }\n }\n\n if (keyPoints.length === 0) {\n return `[${messages.length} messages processed - no key questions found]`;\n }\n\n return `Key topics discussed:\\n${keyPoints.join(\"\\n\")}`;\n };\n}\n\n/**\n * Create a summarizer that delegates to an LLM for conversation compression.\n *\n * You provide the LLM call function; this handles prompt construction\n * including length limits and key-fact preservation instructions.\n *\n * @param llmCall - Async function that sends a prompt to an LLM and returns the response text.\n * @param options - Optional `maxSummaryLength` and `preserveKeyFacts` settings.\n * @returns A {@link MessageSummarizer} function.\n *\n * @example\n * ```typescript\n * const summarizer = createLLMSummarizer(async (prompt) => {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4o-mini',\n * messages: [{ role: 'user', content: prompt }],\n * });\n * return response.choices[0].message.content ?? '';\n * });\n * ```\n * @public\n */\nexport function createLLMSummarizer(\n llmCall: (prompt: string) => Promise<string>,\n options: {\n maxSummaryLength?: number;\n preserveKeyFacts?: boolean;\n } = {},\n): MessageSummarizer {\n const { maxSummaryLength = 500, preserveKeyFacts = true } = options;\n\n return async (messages: Message[]) => {\n const conversationText = messages\n .filter((m) => m.role !== \"system\")\n .map((m) => {\n const content =\n typeof m.content === \"string\" ? m.content : JSON.stringify(m.content);\n return `${m.role.toUpperCase()}: ${content}`;\n })\n .join(\"\\n\\n\");\n\n const prompt = `Summarize the following conversation in ${maxSummaryLength} characters or less.\n${preserveKeyFacts ? \"Preserve key facts, decisions, and action items.\" : \"\"}\nFocus on information that would be useful context for continuing the conversation.\n\nCONVERSATION:\n${conversationText}\n\nSUMMARY:`;\n\n return llmCall(prompt);\n };\n}\n","/**\n * Audit Plugin - Immutable Audit Trail with Hash Chain\n *\n * Provides enterprise-grade audit logging with:\n * - Cryptographic hash chain for tamper detection\n * - Bounded storage with FIFO eviction\n * - PII masking with configurable redaction\n * - Optional signing for non-repudiation\n * - Async export to external systems\n *\n * @example\n * ```typescript\n * import { createAuditTrail } from '@directive-run/ai';\n *\n * const audit = createAuditTrail({\n * maxEntries: 10000,\n * retentionMs: 7 * 24 * 60 * 60 * 1000, // 7 days\n * piiMasking: {\n * enabled: true,\n * types: ['ssn', 'credit_card', 'email'],\n * redactionStyle: 'typed',\n * },\n * exporter: async (entries) => {\n * await sendToSIEM(entries);\n * },\n * });\n *\n * const system = createSystem({\n * module: myModule,\n * plugins: [audit.createPlugin()],\n * });\n * ```\n */\n\nimport type { ModuleSchema, Plugin } from \"@directive-run/core\";\nimport type { PIIType, RedactionStyle } from \"../guardrails/pii-enhanced.js\";\nimport { detectPII, redactPII } from \"../guardrails/pii-enhanced.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Audit event types - 22 total covering all system operations */\nexport type AuditEventType =\n // Agent lifecycle\n | \"agent.run.start\"\n | \"agent.run.complete\"\n | \"agent.run.error\"\n // Tool operations\n | \"tool.call.start\"\n | \"tool.call.complete\"\n | \"tool.call.error\"\n // Human-in-the-loop\n | \"approval.requested\"\n | \"approval.granted\"\n | \"approval.denied\"\n // Requirement lifecycle\n | \"requirement.created\"\n | \"requirement.met\"\n // Resolver operations\n | \"resolver.start\"\n | \"resolver.complete\"\n | \"resolver.error\"\n // Fact mutations\n | \"fact.set\"\n | \"fact.batch\"\n // Error handling\n | \"error.occurred\"\n | \"error.recovery\"\n // Checkpoint operations\n | \"checkpoint.save\"\n | \"checkpoint.restore\"\n | \"checkpoint.fork\"\n | \"checkpoint.replay\";\n\n/** Single audit entry with hash chain linking */\nexport interface AuditEntry {\n /** Unique identifier for this entry */\n id: string;\n /** Unix timestamp in milliseconds */\n timestamp: number;\n /** Type of event */\n eventType: AuditEventType;\n /** SHA-256 hash of previous entry (empty string for genesis) */\n previousHash: string;\n /** SHA-256 hash of this entry's content */\n hash: string;\n /** Event payload data */\n payload: Record<string, unknown>;\n /** PII-redacted version of payload (if masking enabled) */\n maskedPayload?: Record<string, unknown>;\n /** Actor identifier (user, agent, or system) */\n actorId?: string;\n /** Session identifier for correlation */\n sessionId?: string;\n /** Cryptographic signature (if signing enabled) */\n signature?: string;\n}\n\n/** Filter options for querying audit entries */\nexport interface AuditEntryFilter {\n /** Filter by event types */\n eventTypes?: AuditEventType[];\n /** Filter by actor ID */\n actorId?: string;\n /** Filter by session ID */\n sessionId?: string;\n /** Start of time range */\n since?: number;\n /** End of time range */\n until?: number;\n /** Maximum entries to return */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n}\n\n/** Result of chain verification */\nexport interface AuditVerificationResult {\n /** Whether the chain is valid */\n valid: boolean;\n /** Number of entries verified */\n entriesVerified: number;\n /** First broken link (if any) */\n brokenAt?: {\n index: number;\n entryId: string;\n expectedHash: string;\n actualHash: string;\n };\n /** Verification timestamp */\n verifiedAt: number;\n}\n\n/** Audit statistics */\nexport interface AuditStats {\n /** Total entries in trail */\n totalEntries: number;\n /** Entries by event type */\n byEventType: Partial<Record<AuditEventType, number>>;\n /** Oldest entry timestamp */\n oldestEntry?: number;\n /** Newest entry timestamp */\n newestEntry?: number;\n /** Number of entries pruned */\n entriesPruned: number;\n /** Number of entries exported */\n entriesExported: number;\n /** Chain integrity (true if verified valid) */\n chainIntegrity: boolean;\n}\n\n/** PII masking configuration */\nexport interface PIIMaskingConfig {\n /** Enable PII masking */\n enabled: boolean;\n /** PII types to detect and mask */\n types: PIIType[];\n /** Redaction style */\n redactionStyle: RedactionStyle;\n /** Custom allowlist (values to skip) */\n allowlist?: string[];\n /** Minimum confidence threshold */\n minConfidence?: number;\n}\n\n/** Signing configuration for non-repudiation */\nexport interface SigningConfig {\n /** Function to sign a hash value */\n signFn: (hash: string) => Promise<string>;\n /** Function to verify a signature */\n verifyFn?: (hash: string, signature: string) => Promise<boolean>;\n}\n\n/** Audit plugin configuration */\nexport interface AuditPluginConfig {\n /** Maximum entries to retain (default: 10000) */\n maxEntries?: number;\n /** Retention period in milliseconds (default: 7 days) */\n retentionMs?: number;\n /** Export interval in milliseconds (default: 60000) */\n exportInterval?: number;\n /** Async exporter function */\n exporter?: (entries: AuditEntry[]) => Promise<void>;\n /** PII masking configuration */\n piiMasking?: PIIMaskingConfig;\n /** Signing configuration for non-repudiation */\n signing?: SigningConfig;\n /** Session ID for all entries */\n sessionId?: string;\n /** Actor ID for all entries */\n actorId?: string;\n /** Event callbacks */\n events?: {\n onEntryAdded?: (entry: AuditEntry) => void;\n onChainBroken?: (result: AuditVerificationResult) => void;\n onExportError?: (error: Error, entries: AuditEntry[]) => void;\n };\n}\n\n/** Audit trail instance */\nexport interface AuditInstance {\n /** Get entries with optional filtering */\n getEntries(filter?: AuditEntryFilter): AuditEntry[];\n /** Verify the integrity of the hash chain */\n verifyChain(): Promise<AuditVerificationResult>;\n /** Export entries since timestamp */\n export(since?: number): Promise<AuditEntry[]>;\n /** Prune old entries based on retention policy */\n prune(): number;\n /** Get audit statistics */\n getStats(): AuditStats;\n /** Destroy the instance (clears timers, flushes exports) */\n destroy(): Promise<void>;\n /** Create a plugin for a directive system */\n createPlugin<M extends ModuleSchema>(): Plugin<M>;\n /** Add a custom audit entry */\n addEntry(\n eventType: AuditEventType,\n payload: Record<string, unknown>,\n ): Promise<AuditEntry>;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Default maximum entries */\nconst DEFAULT_MAX_ENTRIES = 10000;\n\n/** Default retention period (7 days) */\nconst DEFAULT_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;\n\n/** Default export interval (60 seconds) */\nconst DEFAULT_EXPORT_INTERVAL = 60000;\n\n/** Genesis block previous hash */\nconst GENESIS_PREVIOUS_HASH = \"0\".repeat(64);\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/** Generate a unique ID */\nfunction generateId(): string {\n return (\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 11)}`\n );\n}\n\n/** Convert string to Uint8Array */\nfunction stringToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\n/** Convert Uint8Array to hex string */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/** Calculate SHA-256 hash of content */\nasync function sha256(content: string): Promise<string> {\n const bytes = stringToBytes(content);\n const hashBuffer = await globalThis.crypto.subtle.digest(\n \"SHA-256\",\n bytes as unknown as ArrayBuffer,\n );\n return bytesToHex(new Uint8Array(hashBuffer));\n}\n\n/** Create hash content from entry (deterministic serialization) */\nfunction createHashContent(\n entry: Omit<AuditEntry, \"hash\" | \"signature\">,\n): string {\n const {\n id,\n timestamp,\n eventType,\n previousHash,\n payload,\n actorId,\n sessionId,\n } = entry;\n return JSON.stringify({\n id,\n timestamp,\n eventType,\n previousHash,\n payload,\n actorId,\n sessionId,\n });\n}\n\n/** Deep clone an object */\nfunction deepClone<T>(obj: T): T {\n return JSON.parse(JSON.stringify(obj));\n}\n\n/** Mask PII in a payload object */\nasync function maskPayload(\n payload: Record<string, unknown>,\n config: PIIMaskingConfig,\n): Promise<Record<string, unknown>> {\n const masked = deepClone(payload);\n\n // Recursively process all string values\n async function processValue(value: unknown): Promise<unknown> {\n if (typeof value === \"string\") {\n const result = await detectPII(value, {\n types: config.types,\n minConfidence: config.minConfidence ?? 0.7,\n });\n\n if (result.detected) {\n // Filter by allowlist\n const itemsToRedact = config.allowlist\n ? result.items.filter(\n (item) => !config.allowlist!.includes(item.value.toLowerCase()),\n )\n : result.items;\n\n if (itemsToRedact.length > 0) {\n return redactPII(value, itemsToRedact, config.redactionStyle);\n }\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n return Promise.all(value.map(processValue));\n }\n\n if (value && typeof value === \"object\") {\n const processed: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n processed[k] = await processValue(v);\n }\n return processed;\n }\n\n return value;\n }\n\n for (const [key, value] of Object.entries(masked)) {\n masked[key] = await processValue(value);\n }\n\n return masked;\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Create an audit trail instance for enterprise-grade audit logging.\n *\n * Features:\n * - Immutable hash chain for tamper detection\n * - Bounded storage with automatic FIFO eviction\n * - PII masking with configurable redaction styles\n * - Optional cryptographic signing for non-repudiation\n * - Async export to external SIEM/logging systems\n *\n * @example\n * ```typescript\n * const audit = createAuditTrail({\n * maxEntries: 10000,\n * piiMasking: {\n * enabled: true,\n * types: ['ssn', 'credit_card'],\n * redactionStyle: 'typed',\n * },\n * exporter: async (entries) => {\n * await fetch('/api/audit', {\n * method: 'POST',\n * body: JSON.stringify(entries),\n * });\n * },\n * });\n *\n * // Use with directive system\n * const system = createSystem({\n * module: myModule,\n * plugins: [audit.createPlugin()],\n * });\n *\n * // Query audit entries\n * const recentErrors = audit.getEntries({\n * eventTypes: ['error.occurred', 'error.recovery'],\n * since: Date.now() - 3600000, // Last hour\n * });\n *\n * // Verify chain integrity\n * const verification = await audit.verifyChain();\n * if (!verification.valid) {\n * console.error('Audit chain tampered!', verification.brokenAt);\n * }\n * ```\n */\nexport function createAuditTrail(\n config: AuditPluginConfig = {},\n): AuditInstance {\n const {\n maxEntries = DEFAULT_MAX_ENTRIES,\n retentionMs = DEFAULT_RETENTION_MS,\n exportInterval = DEFAULT_EXPORT_INTERVAL,\n exporter,\n piiMasking,\n signing,\n sessionId,\n actorId,\n events = {},\n } = config;\n\n // State\n const entries: AuditEntry[] = [];\n let lastExportIndex = 0;\n let entriesPruned = 0;\n let entriesExported = 0;\n let chainVerified = true;\n let exportTimer: ReturnType<typeof setInterval> | undefined;\n\n // Get the hash of the last entry (or genesis hash)\n function getLastHash(): string {\n if (entries.length === 0) {\n return GENESIS_PREVIOUS_HASH;\n }\n return entries[entries.length - 1]!.hash;\n }\n\n // Add a new entry to the trail\n async function addEntry(\n eventType: AuditEventType,\n payload: Record<string, unknown>,\n overrides?: { actorId?: string; sessionId?: string },\n ): Promise<AuditEntry> {\n const entry: Omit<AuditEntry, \"hash\" | \"signature\"> = {\n id: generateId(),\n timestamp: Date.now(),\n eventType,\n previousHash: getLastHash(),\n payload,\n actorId: overrides?.actorId ?? actorId,\n sessionId: overrides?.sessionId ?? sessionId,\n };\n\n // Apply PII masking if enabled\n if (piiMasking?.enabled) {\n entry.maskedPayload = await maskPayload(payload, piiMasking);\n }\n\n // Calculate hash\n const hashContent = createHashContent(entry);\n const hash = await sha256(hashContent);\n\n const fullEntry: AuditEntry = {\n ...entry,\n hash,\n };\n\n // Apply signing if configured\n if (signing) {\n fullEntry.signature = await signing.signFn(hash);\n }\n\n // Add to trail\n entries.push(fullEntry);\n\n // Enforce max entries (FIFO eviction)\n while (entries.length > maxEntries) {\n entries.shift();\n entriesPruned++;\n // Adjust export index if entries were evicted\n if (lastExportIndex > 0) {\n lastExportIndex--;\n }\n }\n\n events.onEntryAdded?.(fullEntry);\n\n return fullEntry;\n }\n\n // Start export timer if configured\n if (exporter && exportInterval > 0) {\n exportTimer = setInterval(async () => {\n try {\n const toExport = entries.slice(lastExportIndex);\n if (toExport.length > 0) {\n await exporter(toExport);\n entriesExported += toExport.length;\n lastExportIndex = entries.length;\n }\n } catch (error) {\n events.onExportError?.(\n error instanceof Error ? error : new Error(String(error)),\n entries.slice(lastExportIndex),\n );\n }\n }, exportInterval);\n }\n\n return {\n getEntries(filter?: AuditEntryFilter): AuditEntry[] {\n let result = [...entries];\n\n if (filter) {\n if (filter.eventTypes?.length) {\n const typeSet = new Set(filter.eventTypes);\n result = result.filter((e) => typeSet.has(e.eventType));\n }\n\n if (filter.actorId) {\n result = result.filter((e) => e.actorId === filter.actorId);\n }\n\n if (filter.sessionId) {\n result = result.filter((e) => e.sessionId === filter.sessionId);\n }\n\n if (filter.since !== undefined) {\n result = result.filter((e) => e.timestamp >= filter.since!);\n }\n\n if (filter.until !== undefined) {\n result = result.filter((e) => e.timestamp <= filter.until!);\n }\n\n if (filter.offset !== undefined) {\n result = result.slice(filter.offset);\n }\n\n if (filter.limit !== undefined) {\n result = result.slice(0, filter.limit);\n }\n }\n\n return result;\n },\n\n async verifyChain(): Promise<AuditVerificationResult> {\n if (entries.length === 0) {\n return {\n valid: true,\n entriesVerified: 0,\n verifiedAt: Date.now(),\n };\n }\n\n // Verify first entry links to genesis\n const firstEntry = entries[0]!;\n if (firstEntry.previousHash !== GENESIS_PREVIOUS_HASH) {\n // First entry doesn't link to genesis - this could happen after pruning\n // We verify the chain is internally consistent instead\n }\n\n // Verify each entry's hash and link\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i]!;\n\n // Recalculate hash\n const hashContent = createHashContent({\n id: entry.id,\n timestamp: entry.timestamp,\n eventType: entry.eventType,\n previousHash: entry.previousHash,\n payload: entry.payload,\n actorId: entry.actorId,\n sessionId: entry.sessionId,\n });\n const expectedHash = await sha256(hashContent);\n\n if (entry.hash !== expectedHash) {\n chainVerified = false;\n const result: AuditVerificationResult = {\n valid: false,\n entriesVerified: i,\n brokenAt: {\n index: i,\n entryId: entry.id,\n expectedHash,\n actualHash: entry.hash,\n },\n verifiedAt: Date.now(),\n };\n events.onChainBroken?.(result);\n return result;\n }\n\n // Verify chain linkage (except for first entry after pruning)\n if (i > 0) {\n const prevEntry = entries[i - 1]!;\n if (entry.previousHash !== prevEntry.hash) {\n chainVerified = false;\n const result: AuditVerificationResult = {\n valid: false,\n entriesVerified: i,\n brokenAt: {\n index: i,\n entryId: entry.id,\n expectedHash: prevEntry.hash,\n actualHash: entry.previousHash,\n },\n verifiedAt: Date.now(),\n };\n events.onChainBroken?.(result);\n return result;\n }\n }\n\n // Verify signature if signing is configured\n if (signing?.verifyFn && entry.signature) {\n const signatureValid = await signing.verifyFn(\n entry.hash,\n entry.signature,\n );\n if (!signatureValid) {\n chainVerified = false;\n const result: AuditVerificationResult = {\n valid: false,\n entriesVerified: i,\n brokenAt: {\n index: i,\n entryId: entry.id,\n expectedHash: \"signature-invalid\",\n actualHash: entry.signature,\n },\n verifiedAt: Date.now(),\n };\n events.onChainBroken?.(result);\n return result;\n }\n }\n }\n\n chainVerified = true;\n return {\n valid: true,\n entriesVerified: entries.length,\n verifiedAt: Date.now(),\n };\n },\n\n async export(since?: number): Promise<AuditEntry[]> {\n let toExport = [...entries];\n\n if (since !== undefined) {\n toExport = toExport.filter((e) => e.timestamp >= since);\n }\n\n if (exporter && toExport.length > 0) {\n await exporter(toExport);\n entriesExported += toExport.length;\n }\n\n return toExport;\n },\n\n prune(): number {\n const cutoff = Date.now() - retentionMs;\n const initialLength = entries.length;\n\n // Remove entries older than retention period\n while (entries.length > 0 && entries[0]!.timestamp < cutoff) {\n entries.shift();\n if (lastExportIndex > 0) {\n lastExportIndex--;\n }\n }\n\n const pruned = initialLength - entries.length;\n entriesPruned += pruned;\n return pruned;\n },\n\n getStats(): AuditStats {\n const byEventType: Partial<Record<AuditEventType, number>> = {};\n\n for (const entry of entries) {\n byEventType[entry.eventType] = (byEventType[entry.eventType] ?? 0) + 1;\n }\n\n return {\n totalEntries: entries.length,\n byEventType,\n oldestEntry: entries[0]?.timestamp,\n newestEntry: entries[entries.length - 1]?.timestamp,\n entriesPruned,\n entriesExported,\n chainIntegrity: chainVerified,\n };\n },\n\n async destroy(): Promise<void> {\n // Clear export timer\n if (exportTimer) {\n clearInterval(exportTimer);\n exportTimer = undefined;\n }\n\n // Flush remaining entries to exporter\n if (exporter) {\n try {\n const toExport = entries.slice(lastExportIndex);\n if (toExport.length > 0) {\n await exporter(toExport);\n entriesExported += toExport.length;\n }\n } catch (error) {\n events.onExportError?.(\n error instanceof Error ? error : new Error(String(error)),\n entries.slice(lastExportIndex),\n );\n }\n }\n },\n\n addEntry(\n eventType: AuditEventType,\n payload: Record<string, unknown>,\n ): Promise<AuditEntry> {\n return addEntry(eventType, payload);\n },\n\n createPlugin<M extends ModuleSchema>(): Plugin<M> {\n return {\n name: \"audit-trail\",\n\n // Fact operations\n onFactSet: (key, value, prev) => {\n addEntry(\"fact.set\", { key, value, prev }).catch(console.error);\n },\n\n onFactsBatch: (changes) => {\n addEntry(\"fact.batch\", {\n changes: changes.map((c) => ({\n key: c.key,\n value: c.value,\n prev: c.prev,\n })),\n }).catch(console.error);\n },\n\n // Requirement lifecycle\n onRequirementCreated: (req) => {\n addEntry(\"requirement.created\", {\n id: req.id,\n type: req.requirement.type,\n payload: req.requirement,\n }).catch(console.error);\n },\n\n onRequirementMet: (req, byResolver) => {\n addEntry(\"requirement.met\", {\n id: req.id,\n type: req.requirement.type,\n byResolver,\n }).catch(console.error);\n },\n\n // Resolver operations\n onResolverStart: (resolver, req) => {\n addEntry(\"resolver.start\", {\n resolver,\n requirementId: req.id,\n requirementType: req.requirement.type,\n }).catch(console.error);\n },\n\n onResolverComplete: (resolver, req, duration) => {\n addEntry(\"resolver.complete\", {\n resolver,\n requirementId: req.id,\n requirementType: req.requirement.type,\n duration,\n }).catch(console.error);\n },\n\n onResolverError: (resolver, req, error) => {\n addEntry(\"resolver.error\", {\n resolver,\n requirementId: req.id,\n requirementType: req.requirement.type,\n error: error instanceof Error ? error.message : String(error),\n }).catch(console.error);\n },\n\n // Error handling\n onError: (error) => {\n addEntry(\"error.occurred\", {\n source: error.source,\n sourceId: error.sourceId,\n message: error.message,\n context: error.context,\n }).catch(console.error);\n },\n\n onErrorRecovery: (error, strategy) => {\n addEntry(\"error.recovery\", {\n source: error.source,\n message: error.message,\n strategy,\n }).catch(console.error);\n },\n };\n },\n };\n}\n\n// ============================================================================\n// Agent Orchestrator Integration\n// ============================================================================\n\n/**\n * Create audit event handlers for agent orchestrator integration.\n * Use this to audit agent operations when using the agent orchestrator.\n *\n * @example\n * ```typescript\n * const audit = createAuditTrail({ ... });\n * const handlers = createAgentAuditHandlers(audit);\n *\n * // Use in orchestrator callbacks\n * orchestrator.run(agent, input, {\n * onStart: handlers.onAgentStart,\n * onComplete: handlers.onAgentComplete,\n * // ...\n * });\n * ```\n */\nexport function createAgentAuditHandlers(audit: AuditInstance) {\n return {\n onAgentStart: (agentName: string, input: string) => {\n audit.addEntry(\"agent.run.start\", { agentName, input });\n },\n\n onAgentComplete: (\n agentName: string,\n output: unknown,\n tokens: number,\n cost: number,\n ) => {\n audit.addEntry(\"agent.run.complete\", { agentName, output, tokens, cost });\n },\n\n onAgentError: (agentName: string, error: Error) => {\n audit.addEntry(\"agent.run.error\", {\n agentName,\n error: error.message,\n stack: error.stack,\n });\n },\n\n onToolStart: (toolName: string, toolCallId: string, args: unknown) => {\n audit.addEntry(\"tool.call.start\", { toolName, toolCallId, args });\n },\n\n onToolComplete: (toolName: string, toolCallId: string, result: unknown) => {\n audit.addEntry(\"tool.call.complete\", { toolName, toolCallId, result });\n },\n\n onToolError: (toolName: string, toolCallId: string, error: Error) => {\n audit.addEntry(\"tool.call.error\", {\n toolName,\n toolCallId,\n error: error.message,\n });\n },\n\n onApprovalRequested: (\n toolName: string,\n toolCallId: string,\n args: unknown,\n ) => {\n audit.addEntry(\"approval.requested\", { toolName, toolCallId, args });\n },\n\n onApprovalGranted: (toolName: string, toolCallId: string) => {\n audit.addEntry(\"approval.granted\", { toolName, toolCallId });\n },\n\n onApprovalDenied: (\n toolName: string,\n toolCallId: string,\n reason?: string,\n ) => {\n audit.addEntry(\"approval.denied\", { toolName, toolCallId, reason });\n },\n };\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport {\n createAuditTrail as create,\n createAgentAuditHandlers as createHandlers,\n};\n","/**\n * Compliance Plugin - GDPR/CCPA Data Subject Rights\n *\n * Provides enterprise-grade compliance features:\n * - Data Export (DSR) - Export all data for a subject\n * - Data Deletion - Soft/hard delete with certificates\n * - Consent Tracking - Track and enforce consent\n * - Retention Policies - Automatic data retention enforcement\n *\n * @example\n * ```typescript\n * import { createCompliance } from '@directive-run/ai';\n *\n * const compliance = createCompliance({\n * storage: myStorageAdapter,\n * retention: {\n * defaultRetentionMs: 365 * 24 * 60 * 60 * 1000, // 1 year\n * categoryRetention: {\n * audit: 7 * 365 * 24 * 60 * 60 * 1000, // 7 years for audit\n * sessions: 30 * 24 * 60 * 60 * 1000, // 30 days for sessions\n * },\n * },\n * });\n *\n * // Handle data subject request\n * const exportResult = await compliance.exportData({\n * subjectId: 'user-123',\n * format: 'json',\n * includeAudit: true,\n * });\n *\n * // Delete user data\n * const deleteResult = await compliance.deleteData({\n * subjectId: 'user-123',\n * scope: 'all',\n * });\n * ```\n */\n\nimport type {\n GuardrailFn,\n GuardrailResult,\n InputGuardrailData,\n} from \"../types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Data export request (GDPR Article 20) */\nexport interface DataExportRequest {\n /** Subject identifier (user ID) */\n subjectId: string;\n /** Export format */\n format: \"json\" | \"csv\";\n /** Include audit trail entries */\n includeAudit?: boolean;\n /** Include derived data */\n includeDerived?: boolean;\n /** Specific data categories to export */\n categories?: string[];\n /** Request metadata */\n metadata?: Record<string, unknown>;\n}\n\n/** Result of data export */\nexport interface DataExportResult {\n /** Whether export was successful */\n success: boolean;\n /** Subject identifier */\n subjectId: string;\n /** Export format used */\n format: \"json\" | \"csv\";\n /** Exported data */\n data: string;\n /** Data categories included */\n categories: string[];\n /** Number of records exported */\n recordCount: number;\n /** SHA-256 checksum of exported data */\n checksum: string;\n /** Export timestamp */\n exportedAt: number;\n /** Expiration timestamp for download link (if applicable) */\n expiresAt?: number;\n /** Error message if failed */\n error?: string;\n}\n\n/** Data deletion scope */\nexport type DeletionScope = \"all\" | \"facts\" | \"audit\" | \"specific\";\n\n/** Data deletion request (GDPR Article 17) */\nexport interface DataDeletionRequest {\n /** Subject identifier (user ID) */\n subjectId: string;\n /** Scope of deletion */\n scope: DeletionScope;\n /** Anonymize instead of delete (retain structure, remove PII) */\n anonymize?: boolean;\n /** Specific data categories to delete (when scope is 'specific') */\n categories?: string[];\n /** Reason for deletion */\n reason?: string;\n /** Request metadata */\n metadata?: Record<string, unknown>;\n}\n\n/** Result of data deletion */\nexport interface DataDeletionResult {\n /** Whether deletion was successful */\n success: boolean;\n /** Subject identifier */\n subjectId: string;\n /** Scope of deletion performed */\n scope: DeletionScope;\n /** Whether data was anonymized vs deleted */\n anonymized: boolean;\n /** Number of records deleted/anonymized */\n recordsAffected: number;\n /** Data categories affected */\n categoriesAffected: string[];\n /** Deletion certificate (for compliance records) */\n certificate: DeletionCertificate;\n /** Deletion timestamp */\n deletedAt: number;\n /** Error message if failed */\n error?: string;\n}\n\n/** Deletion certificate for compliance records */\nexport interface DeletionCertificate {\n /** Certificate ID */\n id: string;\n /** Subject identifier */\n subjectId: string;\n /** Type of deletion */\n type: \"soft\" | \"hard\" | \"anonymization\";\n /** Scope of deletion */\n scope: DeletionScope;\n /** Categories deleted */\n categories: string[];\n /** Record count */\n recordCount: number;\n /** Deletion timestamp */\n deletedAt: number;\n /** Reason for deletion */\n reason?: string;\n /** SHA-256 hash of certificate content */\n hash: string;\n}\n\n/** Consent record for a subject */\nexport interface ConsentRecord {\n /** Subject identifier */\n subjectId: string;\n /** Consent purpose (e.g., 'marketing', 'analytics', 'personalization') */\n purpose: string;\n /** Whether consent is granted */\n granted: boolean;\n /** When consent was granted (if granted) */\n grantedAt?: number;\n /** When consent expires (if applicable) */\n expiresAt?: number;\n /** When consent was revoked (if revoked) */\n revokedAt?: number;\n /** Source of consent (e.g., 'signup_form', 'settings_page') */\n source?: string;\n /** Consent version/hash (for tracking which T&C version was accepted) */\n version?: string;\n}\n\n/** Consent tracker interface */\nexport interface ConsentTracker {\n /** Record consent grant */\n grant(\n subjectId: string,\n purpose: string,\n options?: {\n expiresAt?: number;\n source?: string;\n version?: string;\n },\n ): Promise<ConsentRecord>;\n /** Revoke consent */\n revoke(subjectId: string, purpose: string): Promise<ConsentRecord | null>;\n /** Check if consent is granted */\n check(subjectId: string, purpose: string): Promise<boolean>;\n /** Get all consents for a subject */\n getForSubject(subjectId: string): Promise<ConsentRecord[]>;\n /** Get all subjects with consent for a purpose */\n getForPurpose(purpose: string): Promise<ConsentRecord[]>;\n}\n\n/** Retention policy */\nexport interface RetentionPolicy {\n /** Policy name */\n name: string;\n /** Default retention period in milliseconds */\n defaultRetentionMs: number;\n /** Category-specific retention periods */\n categoryRetention?: Record<string, number>;\n /** Callback before data is deleted */\n onBeforeDelete?: (data: { category: string; count: number }) => Promise<void>;\n /** Callback after data is deleted */\n onAfterDelete?: (data: { category: string; count: number }) => void;\n}\n\n/** Storage adapter for compliance data */\nexport interface ComplianceStorage {\n /** Get all data for a subject */\n getSubjectData(\n subjectId: string,\n categories?: string[],\n ): Promise<\n {\n category: string;\n records: Array<{\n id: string;\n data: Record<string, unknown>;\n createdAt: number;\n }>;\n }[]\n >;\n /** Delete data for a subject */\n deleteSubjectData(subjectId: string, categories?: string[]): Promise<number>;\n /** Anonymize data for a subject */\n anonymizeSubjectData(\n subjectId: string,\n categories?: string[],\n ): Promise<number>;\n /** Get audit entries for a subject */\n getAuditEntries?(subjectId: string): Promise<\n Array<{\n id: string;\n timestamp: number;\n eventType: string;\n payload: Record<string, unknown>;\n }>\n >;\n /** Get data older than timestamp by category */\n getExpiredData(\n category: string,\n olderThan: number,\n ): Promise<Array<{ id: string; createdAt: number }>>;\n /** Delete records by IDs */\n deleteByIds(ids: string[]): Promise<number>;\n /** Store consent record */\n storeConsent(record: ConsentRecord): Promise<void>;\n /** Get consent record */\n getConsent(subjectId: string, purpose: string): Promise<ConsentRecord | null>;\n /** Get consents by subject */\n getConsentsBySubject(subjectId: string): Promise<ConsentRecord[]>;\n /** Get consents by purpose */\n getConsentsByPurpose(purpose: string): Promise<ConsentRecord[]>;\n /** Store deletion certificate */\n storeDeletionCertificate(certificate: DeletionCertificate): Promise<void>;\n}\n\n/** Compliance configuration */\nexport interface ComplianceConfig {\n /** Storage adapter */\n storage: ComplianceStorage;\n /** Retention policy */\n retention?: RetentionPolicy;\n /** Consent purposes to track */\n consentPurposes?: string[];\n /** Export link expiration (default: 24 hours) */\n exportExpirationMs?: number;\n /** Audit all compliance operations */\n auditOperations?: boolean;\n /** Event callbacks */\n events?: {\n onExport?: (result: DataExportResult) => void;\n onDelete?: (result: DataDeletionResult) => void;\n onConsentChange?: (record: ConsentRecord) => void;\n onRetentionEnforced?: (category: string, count: number) => void;\n };\n}\n\n/** Compliance instance */\nexport interface ComplianceInstance {\n /** Export data for a subject (GDPR Article 20) */\n exportData(request: DataExportRequest): Promise<DataExportResult>;\n /** Delete data for a subject (GDPR Article 17) */\n deleteData(request: DataDeletionRequest): Promise<DataDeletionResult>;\n /** Consent tracker */\n consent: ConsentTracker;\n /** Enforce retention policy */\n enforceRetention(): Promise<number>;\n /** Create a guardrail that checks consent before processing */\n createConsentGuardrail(purpose: string): GuardrailFn<InputGuardrailData>;\n /** Get deletion certificate by ID */\n getDeletionCertificate(\n subjectId: string,\n ): Promise<DeletionCertificate | null>;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Default export link expiration (24 hours) */\nconst DEFAULT_EXPORT_EXPIRATION_MS = 24 * 60 * 60 * 1000;\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/** Generate a unique ID */\nfunction generateId(): string {\n return (\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 11)}`\n );\n}\n\n/** Convert string to Uint8Array */\nfunction stringToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\n/** Convert Uint8Array to hex string */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/** Calculate SHA-256 hash of content */\nasync function sha256(content: string): Promise<string> {\n const bytes = stringToBytes(content);\n const hashBuffer = await globalThis.crypto.subtle.digest(\n \"SHA-256\",\n bytes as unknown as ArrayBuffer,\n );\n return bytesToHex(new Uint8Array(hashBuffer));\n}\n\n/** Convert data to CSV format */\nfunction toCSV(data: Record<string, unknown>[]): string {\n if (data.length === 0) return \"\";\n\n // Get all unique keys\n const keys = new Set<string>();\n for (const record of data) {\n for (const key of Object.keys(record)) {\n keys.add(key);\n }\n }\n\n const headers = Array.from(keys);\n\n // Build CSV\n const lines: string[] = [headers.join(\",\")];\n\n for (const record of data) {\n const values = headers.map((key) => {\n const value = record[key];\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"object\")\n return JSON.stringify(value).replace(/\"/g, '\"\"');\n const str = String(value);\n // Escape quotes and wrap in quotes if contains comma or newline\n if (str.includes(\",\") || str.includes(\"\\n\") || str.includes('\"')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n return str;\n });\n lines.push(values.join(\",\"));\n }\n\n return lines.join(\"\\n\");\n}\n\n// ============================================================================\n// In-Memory Storage (for testing/development)\n// ============================================================================\n\n/** Create an in-memory compliance storage adapter */\nexport function createInMemoryComplianceStorage(): ComplianceStorage {\n const data = new Map<\n string,\n Map<\n string,\n Array<{\n id: string;\n data: Record<string, unknown>;\n createdAt: number;\n }>\n >\n >();\n const consents = new Map<string, ConsentRecord>();\n const certificates = new Map<string, DeletionCertificate>();\n\n return {\n async getSubjectData(subjectId, categories) {\n const result: Array<{\n category: string;\n records: Array<{\n id: string;\n data: Record<string, unknown>;\n createdAt: number;\n }>;\n }> = [];\n\n for (const [category, subjectMap] of data) {\n if (categories && !categories.includes(category)) continue;\n\n const records = subjectMap.get(subjectId);\n if (records && records.length > 0) {\n result.push({ category, records: [...records] });\n }\n }\n\n return result;\n },\n\n async deleteSubjectData(subjectId, categories) {\n let count = 0;\n\n for (const [category, subjectMap] of data) {\n if (categories && !categories.includes(category)) continue;\n\n const records = subjectMap.get(subjectId);\n if (records) {\n count += records.length;\n subjectMap.delete(subjectId);\n }\n }\n\n return count;\n },\n\n async anonymizeSubjectData(subjectId, categories) {\n let count = 0;\n\n for (const [category, subjectMap] of data) {\n if (categories && !categories.includes(category)) continue;\n\n const records = subjectMap.get(subjectId);\n if (records) {\n for (const record of records) {\n // Replace PII with anonymized values\n record.data = {\n ...record.data,\n _anonymized: true,\n _anonymizedAt: Date.now(),\n };\n count++;\n }\n }\n }\n\n return count;\n },\n\n async getExpiredData(category, olderThan) {\n const result: Array<{ id: string; createdAt: number }> = [];\n const categoryData = data.get(category);\n\n if (categoryData) {\n for (const records of categoryData.values()) {\n for (const record of records) {\n if (record.createdAt < olderThan) {\n result.push({ id: record.id, createdAt: record.createdAt });\n }\n }\n }\n }\n\n return result;\n },\n\n async deleteByIds(ids) {\n const idSet = new Set(ids);\n let count = 0;\n\n for (const categoryData of data.values()) {\n for (const [subjectId, records] of categoryData) {\n const filtered = records.filter((r) => !idSet.has(r.id));\n if (filtered.length !== records.length) {\n count += records.length - filtered.length;\n if (filtered.length === 0) {\n categoryData.delete(subjectId);\n } else {\n categoryData.set(subjectId, filtered);\n }\n }\n }\n }\n\n return count;\n },\n\n async storeConsent(record) {\n consents.set(`${record.subjectId}:${record.purpose}`, record);\n },\n\n async getConsent(subjectId, purpose) {\n return consents.get(`${subjectId}:${purpose}`) ?? null;\n },\n\n async getConsentsBySubject(subjectId) {\n const result: ConsentRecord[] = [];\n for (const [key, record] of consents) {\n if (key.startsWith(`${subjectId}:`)) {\n result.push(record);\n }\n }\n return result;\n },\n\n async getConsentsByPurpose(purpose) {\n const result: ConsentRecord[] = [];\n for (const [key, record] of consents) {\n if (key.endsWith(`:${purpose}`)) {\n result.push(record);\n }\n }\n return result;\n },\n\n async storeDeletionCertificate(certificate) {\n certificates.set(certificate.subjectId, certificate);\n },\n };\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Create a compliance instance for GDPR/CCPA data subject rights.\n *\n * Features:\n * - Data Export (GDPR Article 20) - Portable data export\n * - Data Deletion (GDPR Article 17) - Right to erasure\n * - Consent Tracking - Track and verify consent\n * - Retention Policies - Automatic data retention\n *\n * @example\n * ```typescript\n * const compliance = createCompliance({\n * storage: myStorageAdapter,\n * retention: {\n * name: 'default',\n * defaultRetentionMs: 365 * 24 * 60 * 60 * 1000, // 1 year\n * categoryRetention: {\n * audit: 7 * 365 * 24 * 60 * 60 * 1000, // 7 years\n * },\n * },\n * consentPurposes: ['marketing', 'analytics', 'personalization'],\n * });\n *\n * // Export user data\n * const exportResult = await compliance.exportData({\n * subjectId: 'user-123',\n * format: 'json',\n * });\n *\n * // Check consent\n * const hasConsent = await compliance.consent.check('user-123', 'marketing');\n * ```\n */\nexport function createCompliance(config: ComplianceConfig): ComplianceInstance {\n const {\n storage,\n retention,\n exportExpirationMs = DEFAULT_EXPORT_EXPIRATION_MS,\n events = {},\n } = config;\n\n // Consent tracker implementation\n const consent: ConsentTracker = {\n async grant(subjectId, purpose, options = {}) {\n const record: ConsentRecord = {\n subjectId,\n purpose,\n granted: true,\n grantedAt: Date.now(),\n expiresAt: options.expiresAt,\n source: options.source,\n version: options.version,\n };\n\n await storage.storeConsent(record);\n events.onConsentChange?.(record);\n\n return record;\n },\n\n async revoke(subjectId, purpose) {\n const existing = await storage.getConsent(subjectId, purpose);\n if (!existing) return null;\n\n const record: ConsentRecord = {\n ...existing,\n granted: false,\n revokedAt: Date.now(),\n };\n\n await storage.storeConsent(record);\n events.onConsentChange?.(record);\n\n return record;\n },\n\n async check(subjectId, purpose) {\n const record = await storage.getConsent(subjectId, purpose);\n if (!record) return false;\n if (!record.granted) return false;\n if (record.expiresAt && record.expiresAt < Date.now()) return false;\n return true;\n },\n\n async getForSubject(subjectId) {\n return storage.getConsentsBySubject(subjectId);\n },\n\n async getForPurpose(purpose) {\n return storage.getConsentsByPurpose(purpose);\n },\n };\n\n return {\n async exportData(request) {\n try {\n const subjectData = await storage.getSubjectData(\n request.subjectId,\n request.categories,\n );\n\n // Flatten records for export\n const allRecords: Array<{\n category: string;\n id: string;\n data: Record<string, unknown>;\n createdAt: number;\n }> = [];\n\n const categories: string[] = [];\n\n for (const { category, records } of subjectData) {\n categories.push(category);\n for (const record of records) {\n allRecords.push({ category, ...record });\n }\n }\n\n // Include audit entries if requested\n if (request.includeAudit && storage.getAuditEntries) {\n const auditEntries = await storage.getAuditEntries(request.subjectId);\n categories.push(\"audit\");\n for (const entry of auditEntries) {\n allRecords.push({\n category: \"audit\",\n id: entry.id,\n data: entry.payload,\n createdAt: entry.timestamp,\n });\n }\n }\n\n // Format data\n let data: string;\n if (request.format === \"csv\") {\n data = toCSV(\n allRecords.map((r) => ({\n category: r.category,\n id: r.id,\n createdAt: new Date(r.createdAt).toISOString(),\n ...r.data,\n })),\n );\n } else {\n data = JSON.stringify(\n {\n subjectId: request.subjectId,\n exportedAt: new Date().toISOString(),\n recordCount: allRecords.length,\n categories,\n records: allRecords,\n },\n null,\n 2,\n );\n }\n\n // Calculate checksum\n const checksum = await sha256(data);\n\n const result: DataExportResult = {\n success: true,\n subjectId: request.subjectId,\n format: request.format,\n data,\n categories,\n recordCount: allRecords.length,\n checksum,\n exportedAt: Date.now(),\n expiresAt: Date.now() + exportExpirationMs,\n };\n\n events.onExport?.(result);\n return result;\n } catch (error) {\n return {\n success: false,\n subjectId: request.subjectId,\n format: request.format,\n data: \"\",\n categories: [],\n recordCount: 0,\n checksum: \"\",\n exportedAt: Date.now(),\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n\n async deleteData(request) {\n try {\n let recordsAffected = 0;\n const categoriesAffected: string[] = [];\n\n if (request.anonymize) {\n recordsAffected = await storage.anonymizeSubjectData(\n request.subjectId,\n request.categories,\n );\n } else {\n recordsAffected = await storage.deleteSubjectData(\n request.subjectId,\n request.categories,\n );\n }\n\n // Track affected categories\n if (request.categories) {\n categoriesAffected.push(...request.categories);\n } else if (request.scope === \"all\") {\n categoriesAffected.push(\"all\");\n }\n\n // Create deletion certificate\n const certificateContent = JSON.stringify({\n subjectId: request.subjectId,\n type: request.anonymize ? \"anonymization\" : \"hard\",\n scope: request.scope,\n categories: categoriesAffected,\n recordCount: recordsAffected,\n deletedAt: Date.now(),\n reason: request.reason,\n });\n\n const certificate: DeletionCertificate = {\n id: generateId(),\n subjectId: request.subjectId,\n type: request.anonymize ? \"anonymization\" : \"hard\",\n scope: request.scope,\n categories: categoriesAffected,\n recordCount: recordsAffected,\n deletedAt: Date.now(),\n reason: request.reason,\n hash: await sha256(certificateContent),\n };\n\n await storage.storeDeletionCertificate(certificate);\n\n const result: DataDeletionResult = {\n success: true,\n subjectId: request.subjectId,\n scope: request.scope,\n anonymized: request.anonymize ?? false,\n recordsAffected,\n categoriesAffected,\n certificate,\n deletedAt: Date.now(),\n };\n\n events.onDelete?.(result);\n return result;\n } catch (error) {\n return {\n success: false,\n subjectId: request.subjectId,\n scope: request.scope,\n anonymized: request.anonymize ?? false,\n recordsAffected: 0,\n categoriesAffected: [],\n certificate: {\n id: \"error\",\n subjectId: request.subjectId,\n type: \"hard\",\n scope: request.scope,\n categories: [],\n recordCount: 0,\n deletedAt: Date.now(),\n hash: \"\",\n },\n deletedAt: Date.now(),\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n\n consent,\n\n async enforceRetention() {\n if (!retention) return 0;\n\n let totalDeleted = 0;\n const now = Date.now();\n\n // Get all categories to check\n const categories = new Set<string>();\n if (retention.categoryRetention) {\n for (const category of Object.keys(retention.categoryRetention)) {\n categories.add(category);\n }\n }\n\n // Default category for anything not specified\n categories.add(\"default\");\n\n for (const category of categories) {\n const retentionMs =\n retention.categoryRetention?.[category] ??\n retention.defaultRetentionMs;\n const cutoff = now - retentionMs;\n\n const expired = await storage.getExpiredData(category, cutoff);\n\n if (expired.length > 0) {\n await retention.onBeforeDelete?.({ category, count: expired.length });\n\n const deleted = await storage.deleteByIds(expired.map((e) => e.id));\n totalDeleted += deleted;\n\n retention.onAfterDelete?.({ category, count: deleted });\n events.onRetentionEnforced?.(category, deleted);\n }\n }\n\n return totalDeleted;\n },\n\n createConsentGuardrail(purpose: string): GuardrailFn<InputGuardrailData> {\n return async (data): Promise<GuardrailResult> => {\n // Extract subject ID from input or context\n // This is a simple implementation - in practice you'd extract from context\n const subjectIdMatch = data.input.match(\n /user[_-]?id[:\\s]*([a-zA-Z0-9-]+)/i,\n );\n const subjectId = subjectIdMatch?.[1];\n\n if (!subjectId) {\n // No subject ID found - allow (fail open) or block (fail closed)\n // Default to fail open for better UX\n return { passed: true };\n }\n\n const hasConsent = await consent.check(subjectId, purpose);\n\n if (!hasConsent) {\n return {\n passed: false,\n reason: `No consent for '${purpose}' from subject ${subjectId}`,\n };\n }\n\n return { passed: true };\n };\n },\n\n async getDeletionCertificate(_subjectId) {\n // This would need to be implemented in the storage adapter\n // For now, return null as the interface doesn't expose get\n return null;\n },\n };\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport {\n createCompliance as create,\n createInMemoryComplianceStorage as createInMemoryStorage,\n};\n","/**\n * Streaming Channel for Agent-to-Agent Communication\n *\n * Provides AsyncIterable-based streaming for large data transfers between agents.\n * Supports backpressure, buffering, and graceful termination.\n *\n * @example\n * ```typescript\n * import { createStreamChannel } from '@directive-run/ai';\n *\n * // Producer side\n * const channel = createStreamChannel<string>({ bufferSize: 100 });\n *\n * // Send data\n * await channel.send('chunk 1');\n * await channel.send('chunk 2');\n * channel.end(); // Signal completion\n *\n * // Consumer side (async iteration)\n * for await (const chunk of channel) {\n * console.log(chunk);\n * }\n * ```\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Stream channel configuration */\nexport interface StreamChannelConfig {\n /** Maximum buffer size before backpressure is applied (default: 100) */\n bufferSize?: number;\n /** Channel name for debugging */\n name?: string;\n}\n\n/** Stream channel state */\nexport type StreamChannelState = \"open\" | \"closed\" | \"error\";\n\n/** Stream channel instance */\nexport interface StreamChannel<T> extends AsyncIterable<T> {\n /** Send a value to the channel. Resolves when consumed or buffered. */\n send(value: T): Promise<void>;\n /** Signal that no more values will be sent */\n end(): void;\n /** Signal an error and terminate the stream */\n error(err: Error): void;\n /** Get the current state */\n getState(): StreamChannelState;\n /** Get the number of buffered items */\n bufferedCount(): number;\n}\n\n/** Bidirectional stream between two agents */\nexport interface BidirectionalStream<TSend, TReceive> {\n /** Send a value to the remote end */\n send(value: TSend): Promise<void>;\n /** Iterate over received values */\n receive: AsyncIterable<TReceive>;\n /** Close both directions */\n close(): void;\n}\n\n// ============================================================================\n// Stream Channel Factory\n// ============================================================================\n\n/**\n * Create a stream channel for async data transfer.\n *\n * Implements proper backpressure: `send()` will pause when the buffer is full\n * and resume when the consumer catches up.\n *\n * @example\n * ```typescript\n * const channel = createStreamChannel<{ token: string }>();\n *\n * // Producer (e.g., LLM streaming response)\n * (async () => {\n * for (const token of tokens) {\n * await channel.send({ token });\n * }\n * channel.end();\n * })();\n *\n * // Consumer (e.g., downstream agent)\n * for await (const chunk of channel) {\n * process.stdout.write(chunk.token);\n * }\n * ```\n */\nexport function createStreamChannel<T>(\n config: StreamChannelConfig = {},\n): StreamChannel<T> {\n const { bufferSize = 100 } = config;\n\n if (bufferSize < 1 || !Number.isFinite(bufferSize)) {\n throw new Error(\n `[Directive StreamChannel] bufferSize must be >= 1, got ${bufferSize}`,\n );\n }\n\n const buffer: T[] = [];\n let state: StreamChannelState = \"open\";\n let streamError: Error | null = null;\n\n // Waiters for the consumer (when buffer is empty, consumer waits)\n let consumerWaiter: {\n resolve: (value: IteratorResult<T>) => void;\n reject: (err: Error) => void;\n } | null = null;\n\n // Waiters for the producer (when buffer is full, producer waits)\n let producerWaiter: (() => void) | null = null;\n\n // Single-consumer guard\n let hasConsumer = false;\n\n function resolveConsumer(value: T): void {\n if (consumerWaiter) {\n const waiter = consumerWaiter;\n consumerWaiter = null;\n waiter.resolve({ value, done: false });\n }\n }\n\n function endConsumer(): void {\n if (consumerWaiter) {\n const waiter = consumerWaiter;\n consumerWaiter = null;\n waiter.resolve({ value: undefined as unknown as T, done: true });\n }\n }\n\n function errorConsumer(err: Error): void {\n if (consumerWaiter) {\n const waiter = consumerWaiter;\n consumerWaiter = null;\n hasConsumer = false;\n waiter.reject(err);\n }\n }\n\n function resolveProducer(): void {\n if (producerWaiter) {\n const waiter = producerWaiter;\n producerWaiter = null;\n waiter();\n }\n }\n\n const channel: StreamChannel<T> = {\n async send(value: T): Promise<void> {\n if (state !== \"open\") {\n throw new Error(\n `[Directive StreamChannel] Cannot send to ${state} channel${config.name ? ` \"${config.name}\"` : \"\"}`,\n );\n }\n\n // If consumer is waiting, deliver directly\n if (consumerWaiter) {\n resolveConsumer(value);\n return;\n }\n\n // Apply backpressure if buffer is full (wait before adding)\n if (buffer.length >= bufferSize) {\n await new Promise<void>((resolve) => {\n producerWaiter = resolve;\n });\n // Re-check state after backpressure wait\n if (state !== \"open\") {\n throw new Error(\n `[Directive StreamChannel] Cannot send to ${state} channel${config.name ? ` \"${config.name}\"` : \"\"}`,\n );\n }\n // If consumer became available during wait, deliver directly\n if (consumerWaiter) {\n resolveConsumer(value);\n return;\n }\n }\n\n // Buffer the value\n buffer.push(value);\n },\n\n end(): void {\n if (state !== \"open\") return;\n state = \"closed\";\n endConsumer();\n },\n\n error(err: Error): void {\n if (state !== \"open\") return;\n state = \"error\";\n streamError = err;\n errorConsumer(err);\n resolveProducer(); // Unblock any waiting producer\n },\n\n getState(): StreamChannelState {\n return state;\n },\n\n bufferedCount(): number {\n return buffer.length;\n },\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n if (hasConsumer) {\n throw new Error(\n \"[Directive StreamChannel] Channel only supports a single consumer. \" +\n \"Create a separate channel for each consumer.\",\n );\n }\n hasConsumer = true;\n\n return {\n next(): Promise<IteratorResult<T>> {\n // Check for error\n if (state === \"error\" && streamError) {\n hasConsumer = false;\n return Promise.reject(streamError);\n }\n\n // Check buffer first\n if (buffer.length > 0) {\n const value = buffer.shift()!;\n resolveProducer(); // Unblock producer if waiting\n return Promise.resolve({ value, done: false });\n }\n\n // Check if stream is closed\n if (state === \"closed\") {\n hasConsumer = false;\n return Promise.resolve({\n value: undefined as unknown as T,\n done: true,\n });\n }\n\n // Wait for next value\n return new Promise((resolve, reject) => {\n consumerWaiter = { resolve, reject };\n });\n },\n\n return(): Promise<IteratorResult<T>> {\n state = \"closed\";\n buffer.length = 0;\n hasConsumer = false;\n resolveProducer();\n return Promise.resolve({\n value: undefined as unknown as T,\n done: true,\n });\n },\n };\n },\n };\n\n return channel;\n}\n\n// ============================================================================\n// Bidirectional Stream\n// ============================================================================\n\n/**\n * Create a bidirectional stream channel for two-way communication between agents.\n *\n * @example\n * ```typescript\n * const { sideA, sideB } = createBidirectionalStream<string, string>();\n *\n * // Agent A sends and receives\n * await sideA.send('question?');\n * for await (const reply of sideA.receive) {\n * console.log('A got:', reply);\n * }\n *\n * // Agent B receives and responds\n * for await (const msg of sideB.receive) {\n * await sideB.send(`reply to: ${msg}`);\n * }\n * ```\n */\nexport function createBidirectionalStream<TA, TB>(\n config?: StreamChannelConfig,\n): { sideA: BidirectionalStream<TA, TB>; sideB: BidirectionalStream<TB, TA> } {\n const channelAtoB = createStreamChannel<TA>(config);\n const channelBtoA = createStreamChannel<TB>(config);\n\n return {\n sideA: {\n send: (value: TA) => channelAtoB.send(value),\n receive: channelBtoA,\n close() {\n channelAtoB.end();\n channelBtoA.end();\n },\n },\n sideB: {\n send: (value: TB) => channelBtoA.send(value),\n receive: channelAtoB,\n close() {\n channelAtoB.end();\n channelBtoA.end();\n },\n },\n };\n}\n\n// ============================================================================\n// Stream Utilities\n// ============================================================================\n\n/**\n * Pipe one stream channel through a transform function into another.\n *\n * @example\n * ```typescript\n * const input = createStreamChannel<string>();\n * const output = createStreamChannel<number>();\n *\n * pipeThrough(input, output, (chunk) => chunk.length);\n * ```\n */\nexport async function pipeThrough<TIn, TOut>(\n source: AsyncIterable<TIn>,\n destination: StreamChannel<TOut>,\n transform: (value: TIn) => TOut | Promise<TOut>,\n): Promise<void> {\n try {\n for await (const value of source) {\n const transformed = await transform(value);\n await destination.send(transformed);\n }\n destination.end();\n } catch (error) {\n destination.error(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n}\n\n/**\n * Merge multiple async iterables into a single stream.\n * Values are emitted as soon as they arrive from any source.\n *\n * Note: The internal buffer is capped at 10,000 items. Values exceeding this\n * limit are dropped. For high-throughput scenarios, ensure the consumer keeps up\n * or use bounded `StreamChannel` sources.\n *\n * @example\n * ```typescript\n * const merged = mergeStreams(channel1, channel2, channel3);\n * for await (const value of merged) {\n * console.log(value);\n * }\n * ```\n */\nexport function mergeStreams<T>(\n ...sources: AsyncIterable<T>[]\n): AsyncIterable<T> {\n const MAX_BUFFER = 10000;\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<T> {\n const buffer: T[] = [];\n let doneCount = 0;\n let waiter: ((value: IteratorResult<T>) => void) | null = null;\n let errorState: Error | null = null;\n let stopped = false;\n let hasWarnedDrop = false;\n const sourceIterators: AsyncIterator<T>[] = [];\n\n function notifyWaiter(result: IteratorResult<T>): boolean {\n if (waiter) {\n const w = waiter;\n waiter = null;\n w(result);\n return true;\n }\n return false;\n }\n\n // Start consuming all sources\n for (const source of sources) {\n const iter = source[Symbol.asyncIterator]();\n sourceIterators.push(iter);\n (async () => {\n try {\n while (!stopped) {\n const result = await iter.next();\n if (result.done || stopped) break;\n if (!notifyWaiter({ value: result.value, done: false })) {\n if (buffer.length < MAX_BUFFER) {\n buffer.push(result.value);\n } else if (!hasWarnedDrop) {\n hasWarnedDrop = true;\n console.warn(\n `[Directive mergeStreams] Buffer exceeded ${MAX_BUFFER} items. Values are being dropped. Ensure the consumer keeps up or use bounded StreamChannel sources.`,\n );\n }\n }\n }\n } catch (error) {\n if (!stopped) {\n stopped = true;\n errorState =\n error instanceof Error ? error : new Error(String(error));\n notifyWaiter({ value: undefined as unknown as T, done: true });\n }\n }\n doneCount++;\n if (doneCount >= sources.length && !stopped) {\n notifyWaiter({ value: undefined as unknown as T, done: true });\n }\n })();\n }\n\n return {\n next(): Promise<IteratorResult<T>> {\n if (errorState) {\n return Promise.reject(errorState);\n }\n\n if (buffer.length > 0) {\n return Promise.resolve({ value: buffer.shift()!, done: false });\n }\n\n if (doneCount >= sources.length) {\n return Promise.resolve({\n value: undefined as unknown as T,\n done: true,\n });\n }\n\n return new Promise((resolve) => {\n waiter = resolve;\n });\n },\n\n return(): Promise<IteratorResult<T>> {\n stopped = true;\n buffer.length = 0;\n for (const iter of sourceIterators) {\n iter.return?.({ value: undefined as unknown as T, done: true });\n }\n if (waiter) {\n const w = waiter;\n waiter = null;\n w({ value: undefined as unknown as T, done: true });\n }\n return Promise.resolve({\n value: undefined as unknown as T,\n done: true,\n });\n },\n };\n },\n };\n}\n","/**\n * RAG Enricher — Composable retrieval-augmented generation pipeline.\n *\n * Embeds a query, searches a chunk store by cosine similarity, and assembles\n * an enriched input string (context + history + query) for any agent.\n *\n * @example\n * ```typescript\n * import {\n * createRAGEnricher,\n * createJSONFileStore,\n * } from '@directive-run/ai';\n *\n * const enricher = createRAGEnricher({\n * embedder: myEmbedder, // Provide your own EmbedderFn\n * storage: createJSONFileStore({ filePath: './embeddings.json' }),\n * });\n *\n * const enrichedInput = await enricher.enrich('How do constraints work?', {\n * prefix: 'User is viewing: /docs/constraints',\n * history: [{ role: 'user', content: 'Hello' }],\n * });\n * ```\n */\n\nimport path from \"node:path\";\nimport { cosineSimilarity } from \"./guardrails/semantic-cache.js\";\nimport type { EmbedderFn, Embedding } from \"./guardrails/semantic-cache.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** A document chunk with embedding and metadata */\nexport interface RAGChunk {\n id: string;\n content: string;\n embedding: Embedding;\n metadata: Record<string, unknown>;\n}\n\n/** Pluggable storage backend */\nexport interface RAGStorage {\n getChunks(): Promise<RAGChunk[]>;\n size(): Promise<number>;\n /** Optional: optimized vector search (bypasses full getChunks scan) */\n search?(\n query: Embedding,\n topK: number,\n minSimilarity: number,\n ): Promise<Array<RAGChunk & { similarity: number }>>;\n /** Reload storage (clear cache, re-read from source) */\n reload?(): Promise<void>;\n /** Destroy and release resources */\n destroy?(): void;\n}\n\nexport interface RAGEnricherConfig {\n /** Function to generate query embeddings */\n embedder: EmbedderFn;\n /** Storage backend for document chunks */\n storage: RAGStorage;\n /** Number of top results to return (default: 5) */\n topK?: number;\n /** Minimum similarity score to include, clamped to [0, 1] (default: 0.3) */\n minSimilarity?: number;\n /** Custom chunk formatter */\n formatChunk?: (chunk: RAGChunk, similarity: number) => string;\n /** Custom context block formatter */\n formatContext?: (formattedChunks: string[], query: string) => string;\n /** Error callback — embedder/storage errors are non-fatal by default */\n onError?: (error: Error) => void;\n}\n\nexport interface RAGEnrichOptions {\n /** Prefix line (e.g. \"User is viewing: /docs/constraints\") */\n prefix?: string;\n /** Conversation history */\n history?: Array<{ role: string; content: string }>;\n /** Per-call topK override */\n topK?: number;\n /** Filter chunks before ranking (e.g. by metadata tag or section) */\n filter?: (chunk: RAGChunk) => boolean;\n}\n\nexport interface RAGEnricher {\n /** Retrieve relevant chunks for a query */\n retrieve(\n query: string,\n topK?: number,\n ): Promise<Array<RAGChunk & { similarity: number }>>;\n /** Retrieve + format into an enriched input string */\n enrich(input: string, options?: RAGEnrichOptions): Promise<string>;\n}\n\n// ============================================================================\n// Default Formatters\n// ============================================================================\n\nfunction defaultFormatChunk(chunk: RAGChunk, _similarity: number): string {\n const title = (chunk.metadata.title as string) ?? \"\";\n const section = (chunk.metadata.section as string) ?? \"\";\n const url = (chunk.metadata.url as string) ?? \"\";\n const header =\n title && section && url\n ? `[${title} — ${section}](${url})`\n : title\n ? title\n : chunk.id;\n return `${header}\\n${chunk.content}`;\n}\n\nfunction defaultFormatContext(\n formattedChunks: string[],\n _query: string,\n): string {\n if (formattedChunks.length === 0) return \"\";\n return `Relevant documentation context:\\n\\n${formattedChunks.join(\"\\n\\n\")}`;\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/** Clamp a number to [min, max]. */\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\n/**\n * Create a RAG enricher that retrieves relevant document chunks and\n * assembles enriched input for an agent.\n */\nexport function createRAGEnricher(config: RAGEnricherConfig): RAGEnricher {\n const {\n embedder,\n storage,\n topK: defaultTopK = 5,\n minSimilarity: rawMinSimilarity = 0.3,\n formatChunk = defaultFormatChunk,\n formatContext = defaultFormatContext,\n onError,\n } = config;\n\n const minSimilarity = clamp(rawMinSimilarity, 0, 1);\n\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV === \"development\" &&\n rawMinSimilarity !== minSimilarity\n ) {\n console.warn(\n `[Directive] RAG: minSimilarity ${rawMinSimilarity} clamped to ${minSimilarity} (valid range: 0-1)`,\n );\n }\n\n async function retrieve(\n query: string,\n topK?: number,\n ): Promise<Array<RAGChunk & { similarity: number }>> {\n const k = Math.max(1, Math.floor(topK ?? defaultTopK));\n\n // Use optimized search() if the storage backend provides it\n if (storage.search) {\n return storage.search(await embedder(query), k, minSimilarity);\n }\n\n const queryEmbedding = await embedder(query);\n const chunks = await storage.getChunks();\n\n const scored = chunks.map((chunk) => ({\n ...chunk,\n similarity: cosineSimilarity(queryEmbedding, chunk.embedding),\n }));\n\n scored.sort((a, b) => b.similarity - a.similarity);\n\n return scored.filter((c) => c.similarity >= minSimilarity).slice(0, k);\n }\n\n async function enrich(\n input: string,\n options: RAGEnrichOptions = {},\n ): Promise<string> {\n const { prefix, history, topK, filter } = options;\n\n let matches: Array<RAGChunk & { similarity: number }> = [];\n try {\n matches = await retrieve(input, topK);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error(String(err)));\n }\n\n if (filter) {\n matches = matches.filter((m) => filter(m));\n }\n\n const formattedChunks = matches.map((m) => formatChunk(m, m.similarity));\n const contextBlock = formatContext(formattedChunks, input);\n\n const parts: string[] = [];\n if (prefix) parts.push(prefix);\n if (contextBlock) parts.push(contextBlock);\n if (history && history.length > 0) {\n const historyBlock = history\n .map(\n (m) =>\n `${m.role.charAt(0).toUpperCase() + m.role.slice(1)}: ${m.content}`,\n )\n .join(\"\\n\\n\");\n parts.push(`Previous conversation:\\n${historyBlock}`);\n }\n parts.push(input);\n\n return parts.join(\"\\n\\n---\\n\\n\");\n }\n\n return { retrieve, enrich };\n}\n\n// ============================================================================\n// Built-in Storage: JSON File Store\n// ============================================================================\n\nexport interface JSONFileStoreOptions {\n /** Absolute or relative path to the JSON embeddings file */\n filePath: string;\n /** Optional transform from raw JSON entries to RAGChunk */\n mapEntry?: (entry: Record<string, unknown>) => RAGChunk;\n /** Cache TTL in ms. 0 = cache forever (default) */\n ttlMs?: number;\n /** Base directory to confine file access. Resolved paths must start with this. */\n baseDir?: string;\n}\n\n/**\n * Validate that a file path does not escape the allowed directory.\n * Resolves the path, rejects `..` segments, and (if baseDir is provided)\n * ensures the resolved path is inside the base directory.\n */\nfunction validateFilePath(filePath: string, baseDir?: string): string {\n const resolved = path.resolve(filePath);\n\n // Defense in depth: reject paths that still contain \"..\" after resolution\n const segments = resolved.split(path.sep);\n if (segments.includes(\"..\")) {\n throw new Error(\n `[Directive] File path escapes allowed directory: ${filePath}`,\n );\n }\n\n if (baseDir) {\n const resolvedBase = path.resolve(baseDir) + path.sep;\n if (\n !resolved.startsWith(resolvedBase) &&\n resolved !== resolvedBase.slice(0, -1)\n ) {\n throw new Error(\n `[Directive] File path escapes allowed directory: ${filePath}`,\n );\n }\n }\n\n return resolved;\n}\n\n/**\n * Create a RAGStorage backed by a JSON file (lazy-loaded, cached in memory).\n * Uses dynamic `import('node:fs')` for isomorphic safety.\n */\nexport function createJSONFileStore(options: JSONFileStoreOptions): RAGStorage {\n const { filePath, mapEntry, ttlMs = 0, baseDir } = options;\n const resolvedPath = validateFilePath(filePath, baseDir);\n let cached: RAGChunk[] | null = null;\n let cachedAt = 0;\n\n async function load(): Promise<RAGChunk[]> {\n if (cached && (ttlMs === 0 || Date.now() - cachedAt < ttlMs)) {\n return cached;\n }\n\n try {\n const fs = await import(\"node:fs\");\n const data = await fs.promises.readFile(resolvedPath, \"utf-8\");\n const raw = JSON.parse(data) as Record<string, unknown>[];\n\n cached = mapEntry ? raw.map(mapEntry) : (raw as unknown as RAGChunk[]);\n\n cachedAt = Date.now();\n return cached;\n } catch (err) {\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV === \"development\"\n ) {\n console.warn(\n `[Directive] JSONFileStore: failed to load ${resolvedPath}:`,\n err,\n );\n }\n cached = [];\n cachedAt = Date.now();\n return cached;\n }\n }\n\n return {\n async getChunks() {\n return load();\n },\n async size() {\n const chunks = await load();\n return chunks.length;\n },\n async reload() {\n cached = null;\n cachedAt = 0;\n await load();\n },\n destroy() {\n cached = null;\n cachedAt = 0;\n },\n };\n}\n","/**\n * SSE Transport — Wrap a streamable source into an HTTP Server-Sent Events\n * response.\n *\n * Framework-agnostic: uses the WinterCG `Response` constructor (Node 18+,\n * Deno, Bun, Cloudflare Workers, Next.js).\n *\n * @example\n * ```typescript\n * import {\n * createSSETransport,\n * createAgentOrchestrator,\n * createStreamingRunner,\n * } from '@directive-run/ai';\n *\n * const transport = createSSETransport({\n * maxResponseChars: 10_000,\n * errorMessages: {\n * INPUT_GUARDRAIL_FAILED: 'Your message was flagged by our safety filter.',\n * },\n * });\n *\n * // Next.js route handler\n * export async function POST(req: Request) {\n * const { message } = await req.json();\n * return transport.toResponse(streamable, 'docs-qa', message);\n * }\n * ```\n */\n\n// ============================================================================\n// Structural types — describe only what SSE transport actually needs\n// ============================================================================\n\n/** Async iterable of string tokens with result promise and abort */\ninterface SSETokenStream extends AsyncIterable<string> {\n result: Promise<unknown>;\n abort(): void;\n}\n\n/** Any object with a .stream() method compatible with SSE transport */\ninterface SSEStreamable {\n stream(\n agentId: string,\n input: string,\n opts?: { signal?: AbortSignal },\n ): SSETokenStream;\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type SSEEvent =\n | { type: \"text\"; text: string }\n | { type: \"truncated\"; text: string }\n | { type: \"done\" }\n | { type: \"error\"; message: string }\n | { type: \"heartbeat\"; timestamp: number };\n\nexport interface SSETransportConfig {\n /** Truncate response after this many characters (default: Infinity) */\n maxResponseChars?: number;\n /** Message shown when response is truncated */\n truncationMessage?: string;\n /** Heartbeat interval in ms (default: 0 = disabled) */\n heartbeatIntervalMs?: number;\n /** Map error codes/types to user-facing messages */\n errorMessages?: Record<string, string> | ((error: unknown) => string);\n /** Extra headers merged into the SSE response */\n headers?: Record<string, string>;\n}\n\nexport interface SSETransport {\n /** Create a full HTTP Response with SSE headers */\n toResponse(\n source: SSEStreamable,\n agentId: string,\n input: string,\n opts?: { signal?: AbortSignal },\n ): Response;\n /** Return just the ReadableStream (for Express/Koa `res.write()`) */\n toStream(\n source: SSEStreamable,\n agentId: string,\n input: string,\n opts?: { signal?: AbortSignal },\n ): ReadableStream<Uint8Array>;\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nconst DEFAULT_ERROR_MESSAGE =\n \"AI service temporarily unavailable. Please try again.\";\n\n/**\n * Create an SSE transport that converts a token stream into Server-Sent Events.\n */\nexport function createSSETransport(\n config: SSETransportConfig = {},\n): SSETransport {\n const {\n maxResponseChars = Number.POSITIVE_INFINITY,\n truncationMessage = \"\\n\\n*[Response truncated]*\",\n heartbeatIntervalMs = 0,\n errorMessages,\n headers: extraHeaders,\n } = config;\n\n if (maxResponseChars < 0) {\n throw new RangeError(\"maxResponseChars must be non-negative\");\n }\n if (heartbeatIntervalMs < 0) {\n throw new RangeError(\"heartbeatIntervalMs must be non-negative\");\n }\n\n function resolveErrorMessage(error: unknown): string {\n if (typeof errorMessages === \"function\") {\n try {\n return errorMessages(error);\n } catch {\n return DEFAULT_ERROR_MESSAGE;\n }\n }\n if (errorMessages && typeof errorMessages === \"object\") {\n const code =\n error != null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n typeof (error as { code: unknown }).code === \"string\"\n ? (error as { code: string }).code\n : undefined;\n if (code && code in errorMessages) {\n return errorMessages[code]!;\n }\n }\n return DEFAULT_ERROR_MESSAGE;\n }\n\n function buildStream(\n source: SSEStreamable,\n agentId: string,\n input: string,\n opts?: { signal?: AbortSignal },\n ): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n function frame(event: SSEEvent): Uint8Array {\n return encoder.encode(`data: ${JSON.stringify(event)}\\n\\n`);\n }\n\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n let heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n let tokenStream: SSETokenStream | null = null;\n\n try {\n // Heartbeat\n if (heartbeatIntervalMs > 0) {\n heartbeatTimer = setInterval(() => {\n try {\n controller.enqueue(\n frame({ type: \"heartbeat\", timestamp: Date.now() }),\n );\n } catch {\n // Controller may be closed\n }\n }, heartbeatIntervalMs);\n }\n\n tokenStream = source.stream(agentId, input, {\n signal: opts?.signal,\n });\n\n let totalChars = 0;\n let sentDone = false;\n\n for await (const token of tokenStream) {\n totalChars += token.length;\n\n if (totalChars > maxResponseChars) {\n controller.enqueue(\n frame({ type: \"truncated\", text: truncationMessage }),\n );\n controller.enqueue(frame({ type: \"done\" }));\n sentDone = true;\n tokenStream.abort();\n break;\n }\n\n controller.enqueue(frame({ type: \"text\", text: token }));\n }\n\n // Wait for final result (tracks tokens, metrics, etc.)\n try {\n await tokenStream.result;\n } catch {\n // May have been aborted due to truncation\n }\n\n if (!sentDone) {\n controller.enqueue(frame({ type: \"done\" }));\n }\n } catch (err: unknown) {\n const message = resolveErrorMessage(err);\n controller.enqueue(frame({ type: \"error\", message }));\n } finally {\n if (heartbeatTimer) clearInterval(heartbeatTimer);\n controller.close();\n }\n },\n });\n }\n\n const sseHeaders: Record<string, string> = {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n ...extraHeaders,\n };\n\n return {\n toResponse(source, agentId, input, opts) {\n const stream = buildStream(source, agentId, input, opts);\n return new Response(stream, { headers: sseHeaders });\n },\n toStream(source, agentId, input, opts) {\n return buildStream(source, agentId, input, opts);\n },\n };\n}\n","/**\n * P2: Intelligent Retry — HTTP-status-aware retry wrapper for AgentRunner.\n *\n * Respects 429 Retry-After headers, uses exponential backoff with jitter for 503,\n * and never retries client errors (400/401/403/404/422).\n *\n * @module\n *\n * @example\n * ```typescript\n * import { withRetry, RetryExhaustedError } from '@directive-run/ai';\n *\n * const runner = withRetry(baseRunner, {\n * maxRetries: 3,\n * baseDelayMs: 1000,\n * maxDelayMs: 30000,\n * onRetry: (attempt, error, delayMs) => {\n * console.log(`Retry ${attempt} in ${delayMs}ms: ${error.message}`);\n * },\n * });\n *\n * try {\n * const result = await runner(agent, input);\n * } catch (err) {\n * if (err instanceof RetryExhaustedError) {\n * console.error(`All ${err.retryCount} retries failed:`, err.lastError);\n * }\n * }\n * ```\n */\n\nimport type { AgentLike, AgentRunner, RunOptions, RunResult } from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Configuration for the intelligent retry wrapper.\n *\n * @example\n * ```typescript\n * const config: RetryConfig = {\n * maxRetries: 3,\n * baseDelayMs: 1000,\n * maxDelayMs: 30000,\n * isRetryable: (error) => !error.message.includes(\"invalid API key\"),\n * onRetry: (attempt, error, delayMs) => {\n * console.log(`Retry ${attempt} after ${delayMs}ms: ${error.message}`);\n * },\n * };\n * ```\n */\nexport interface RetryConfig {\n /** Maximum number of retry attempts (not counting the initial call). @default 3 */\n maxRetries?: number;\n /** Base delay in ms for exponential backoff. @default 1000 */\n baseDelayMs?: number;\n /** Maximum delay in ms (caps exponential growth). @default 30000 */\n maxDelayMs?: number;\n /** Custom predicate — return `false` to skip retry for specific errors. Called after the built-in HTTP status check. */\n isRetryable?: (error: Error) => boolean;\n /** Called before each retry wait. Useful for logging or metrics. */\n onRetry?: (attempt: number, error: Error, delayMs: number) => void;\n}\n\n/** Error enriched with retry metadata, thrown when all retries are exhausted. */\nexport class RetryExhaustedError extends Error {\n readonly retryCount: number;\n readonly lastError: Error;\n\n constructor(retryCount: number, lastError: Error) {\n super(\n `[Directive] All ${retryCount} retries exhausted: ${lastError.message}`,\n );\n this.name = \"RetryExhaustedError\";\n this.retryCount = retryCount;\n this.lastError = lastError;\n this.cause = lastError;\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** HTTP status codes that should never be retried. */\nconst NON_RETRYABLE_STATUSES = new Set([400, 401, 403, 404, 422]);\n\n/**\n * Extract HTTP status code from error message or error properties.\n *\n * Checks `error.status` / `error.statusCode` properties first, then falls back\n * to matching common error message patterns like \"request failed: 429\" or \"HTTP 503\".\n */\nexport function parseHttpStatus(error: Error): number | null {\n // Check error properties first (many HTTP libraries set these)\n const errObj = error as unknown as Record<string, unknown>;\n if (\n typeof errObj.status === \"number\" &&\n errObj.status >= 100 &&\n errObj.status <= 599\n ) {\n return errObj.status;\n }\n if (\n typeof errObj.statusCode === \"number\" &&\n errObj.statusCode >= 100 &&\n errObj.statusCode <= 599\n ) {\n return errObj.statusCode;\n }\n\n // Match common error message patterns:\n // \"request failed: 429\", \"HTTP 503\", \"status 401\", \"Error 400\"\n // Guard against scanning very large error messages (ReDoS protection)\n const msg =\n error.message.length > 1000 ? error.message.slice(0, 1000) : error.message;\n const match = msg.match(/(?:failed|error|status|http)[:\\s]+(\\d{3})\\b/i);\n if (!match) {\n return null;\n }\n\n const status = Number(match[1]);\n if (status >= 100 && status <= 599) {\n return status;\n }\n\n return null;\n}\n\n/**\n * Extract Retry-After value (in ms) from error message.\n *\n * Per HTTP spec, `Retry-After` numeric values are always in seconds.\n * Returns the value converted to milliseconds.\n */\nexport function parseRetryAfter(error: Error): number | null {\n // Check error properties first (many HTTP libraries set these)\n const errObj = error as unknown as Record<string, unknown>;\n if (typeof errObj.retryAfter === \"number\" && errObj.retryAfter > 0) {\n return errObj.retryAfter * 1000;\n }\n\n // Guard against scanning very large error messages (ReDoS protection)\n const msg =\n error.message.length > 1000 ? error.message.slice(0, 1000) : error.message;\n const match = msg.match(/retry[- ]?after[:\\s]+(\\d+)/i);\n if (!match) {\n return null;\n }\n\n const seconds = Number(match![1]);\n if (seconds > 0) {\n return seconds * 1000;\n }\n\n return null;\n}\n\n/** Calculate delay with exponential backoff and jitter. */\nfunction calculateBackoffDelay(\n attempt: number,\n baseDelayMs: number,\n maxDelayMs: number,\n): number {\n const exponential = baseDelayMs * 2 ** (attempt - 1);\n const jitter = Math.random() * baseDelayMs * 0.5;\n const delay = exponential + jitter;\n\n return Math.min(delay, maxDelayMs);\n}\n\n/** Determine delay for a given error and attempt. */\nfunction getRetryDelay(\n error: Error,\n attempt: number,\n baseDelayMs: number,\n maxDelayMs: number,\n): number {\n const status = parseHttpStatus(error);\n\n // 429: Prefer Retry-After header value\n if (status === 429) {\n const retryAfter = parseRetryAfter(error);\n if (retryAfter !== null) {\n return Math.min(retryAfter, maxDelayMs);\n }\n }\n\n // All retryable statuses: exponential backoff with jitter\n return calculateBackoffDelay(attempt, baseDelayMs, maxDelayMs);\n}\n\n/** Check if an error is retryable based on HTTP status. */\nfunction isStatusRetryable(error: Error): boolean {\n const status = parseHttpStatus(error);\n if (status === null) {\n // No HTTP status — default to retryable (network errors, timeouts, etc.)\n return true;\n }\n\n return !NON_RETRYABLE_STATUSES.has(status);\n}\n\n// ============================================================================\n// Wrapper\n// ============================================================================\n\n/**\n * Wrap an AgentRunner with intelligent retry logic.\n *\n * @example\n * ```typescript\n * const runner = withRetry(baseRunner, {\n * maxRetries: 3,\n * baseDelayMs: 1000,\n * onRetry: (attempt, error, delayMs) => {\n * console.log(`Retry ${attempt} after ${delayMs}ms: ${error.message}`);\n * },\n * });\n * ```\n */\nexport function withRetry(\n runner: AgentRunner,\n config: RetryConfig = {},\n): AgentRunner {\n const {\n maxRetries = 3,\n baseDelayMs = 1000,\n maxDelayMs = 30000,\n isRetryable,\n onRetry,\n } = config;\n\n // Validate config\n if (!Number.isFinite(maxRetries) || maxRetries < 0) {\n throw new Error(\n \"[Directive] withRetry: maxRetries must be a non-negative finite number.\",\n );\n }\n if (!Number.isFinite(baseDelayMs) || baseDelayMs < 0) {\n throw new Error(\n \"[Directive] withRetry: baseDelayMs must be a non-negative finite number.\",\n );\n }\n if (!Number.isFinite(maxDelayMs) || maxDelayMs < 0) {\n throw new Error(\n \"[Directive] withRetry: maxDelayMs must be a non-negative finite number.\",\n );\n }\n\n return async <T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> => {\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await runner<T>(agent, input, options);\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n\n // Check if we should retry\n if (attempt >= maxRetries) {\n break;\n }\n\n // Check custom retryable predicate\n if (isRetryable) {\n try {\n if (!isRetryable(lastError)) {\n break;\n }\n } catch {\n // isRetryable threw — treat as non-retryable\n break;\n }\n }\n\n // Check HTTP status retryability\n if (!isStatusRetryable(lastError)) {\n break;\n }\n\n // Calculate delay\n const delayMs = getRetryDelay(\n lastError,\n attempt + 1,\n baseDelayMs,\n maxDelayMs,\n );\n try {\n onRetry?.(attempt + 1, lastError, delayMs);\n } catch {\n /* callback error must not disrupt retry flow */\n }\n\n // Wait before retrying (abortable via signal)\n const signal = options?.signal;\n if (signal?.aborted) {\n break;\n }\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, delayMs);\n function onAbort() {\n clearTimeout(timer);\n reject(signal!.reason ?? new Error(\"Aborted\"));\n }\n if (signal) {\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n }\n }\n\n // All retries exhausted\n throw new RetryExhaustedError(maxRetries, lastError!);\n };\n}\n","/**\n * P0: Provider Fallback Chains — Automatic failover across multiple AgentRunners.\n *\n * Tries runners in order, moving to the next on failure.\n * Composes naturally with {@link withRetry} (each runner can have its own retry policy).\n *\n * @module\n *\n * @example\n * ```typescript\n * import { withFallback, withRetry, AllProvidersFailedError } from '@directive-run/ai';\n *\n * const runner = withFallback([\n * withRetry(openaiRunner, { maxRetries: 2 }),\n * withRetry(anthropicRunner, { maxRetries: 2 }),\n * ollamaRunner,\n * ], {\n * onFallback: (from, to, error) => {\n * console.log(`Provider ${from} failed, trying ${to}: ${error.message}`);\n * },\n * });\n *\n * try {\n * const result = await runner(agent, input);\n * } catch (err) {\n * if (err instanceof AllProvidersFailedError) {\n * console.error(`All ${err.errors.length} providers failed`);\n * }\n * }\n * ```\n */\n\nimport type { AgentLike, AgentRunner, RunOptions, RunResult } from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FallbackConfig {\n /** Custom predicate to decide whether to fall back on a given error. Default: always fall back. */\n shouldFallback?: (error: Error) => boolean;\n /** Called when falling back from one provider to the next. */\n onFallback?: (fromIndex: number, toIndex: number, error: Error) => void;\n}\n\n/** Error thrown when all providers in the fallback chain have failed. */\nexport class AllProvidersFailedError extends Error {\n readonly errors: Error[];\n\n constructor(errors: Error[]) {\n const summary = errors.map((e, i) => ` [${i}] ${e.message}`).join(\"\\n\");\n super(`[Directive] All ${errors.length} providers failed:\\n${summary}`);\n this.name = \"AllProvidersFailedError\";\n this.errors = Object.freeze([...errors]) as Error[];\n // Chain causes for debugging\n if (errors.length > 0) {\n this.cause = errors[errors.length - 1];\n }\n }\n}\n\n// ============================================================================\n// Wrapper\n// ============================================================================\n\n/**\n * Wrap multiple AgentRunners into a fallback chain.\n *\n * @example\n * ```typescript\n * const runner = withFallback([\n * withRetry(openaiRunner, { maxRetries: 2 }),\n * withRetry(anthropicRunner, { maxRetries: 2 }),\n * ollamaRunner,\n * ], {\n * onFallback: (from, to, error) => {\n * console.log(`Falling back from provider ${from} to ${to}: ${error.message}`);\n * },\n * });\n * ```\n */\nexport function withFallback(\n runners: AgentRunner[],\n config: FallbackConfig = {},\n): AgentRunner {\n if (runners.length === 0) {\n throw new Error(\"[Directive] withFallback requires at least one runner.\");\n }\n\n const { shouldFallback, onFallback } = config;\n\n return async <T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> => {\n const errors: Error[] = [];\n\n for (let i = 0; i < runners.length; i++) {\n try {\n return await runners[i]!<T>(agent, input, options);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n errors.push(error);\n\n // Check if we should fall back to next provider\n if (i < runners.length - 1) {\n if (shouldFallback) {\n try {\n if (!shouldFallback(error)) {\n break;\n }\n } catch {\n // shouldFallback threw — treat as non-fallbackable\n break;\n }\n }\n try {\n onFallback?.(i, i + 1, error);\n } catch {\n /* callback error must not disrupt fallback flow */\n }\n }\n }\n }\n\n throw new AllProvidersFailedError(errors);\n };\n}\n","/**\n * P1: Cost Budget Guards — Pre-call estimation + rolling budget windows.\n *\n * Prevents runaway LLM costs by estimating costs before each call\n * and tracking actual costs after each call. Supports per-call limits\n * and rolling time-window budgets (hourly, daily).\n *\n * @module\n *\n * @example\n * ```typescript\n * import { withBudget, BudgetExceededError } from '@directive-run/ai';\n * import type { BudgetRunner } from '@directive-run/ai';\n *\n * const pricing = { inputPerMillion: 3, outputPerMillion: 15 };\n *\n * const runner = withBudget(baseRunner, {\n * maxCostPerCall: 0.10,\n * pricing,\n * budgets: [\n * { window: \"hour\", maxCost: 5.00, pricing },\n * { window: \"day\", maxCost: 50.00, pricing },\n * ],\n * });\n *\n * // Check spending via escape hatch\n * const spent = (runner as BudgetRunner).getSpent(\"hour\");\n * if (spent > 4.00) {\n * console.warn(\"Approaching hourly budget limit!\");\n * }\n * ```\n */\n\nimport type {\n AgentLike,\n AgentRunner,\n RunOptions,\n RunResult,\n TokenUsage,\n} from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Token pricing for a specific model or provider.\n *\n * @example\n * ```typescript\n * // GPT-4o pricing (as of 2024)\n * const gpt4oPricing: TokenPricing = {\n * inputPerMillion: 5,\n * outputPerMillion: 15,\n * };\n * ```\n */\nexport interface TokenPricing {\n /** Cost per million input tokens (in dollars). */\n inputPerMillion: number;\n /** Cost per million output tokens (in dollars). */\n outputPerMillion: number;\n}\n\n/**\n * Rolling budget window configuration.\n *\n * Each window tracks cost independently, preventing double-counting\n * when multiple windows are configured.\n *\n * @example\n * ```typescript\n * const hourlyBudget: BudgetWindow = {\n * window: \"hour\",\n * maxCost: 5.00,\n * pricing: { inputPerMillion: 3, outputPerMillion: 15 },\n * };\n * ```\n */\nexport interface BudgetWindow {\n /** Time window for the budget. */\n window: \"hour\" | \"day\";\n /** Maximum cost in dollars for this window. */\n maxCost: number;\n /** Token pricing for cost calculation within this window. */\n pricing: TokenPricing;\n}\n\nexport interface BudgetConfig {\n /** Maximum estimated cost per individual call. */\n maxCostPerCall?: number;\n /** Rolling budget windows. */\n budgets?: BudgetWindow[];\n /** Pricing used for per-call estimation (when maxCostPerCall is set). */\n pricing?: TokenPricing;\n /** Approximate characters per token for input estimation. @default 4 */\n charsPerToken?: number;\n /**\n * Multiplier for estimated output tokens relative to input tokens.\n * For summarization tasks, use a value less than 1 (e.g., 0.3).\n * For generation tasks, use a value greater than 1 (e.g., 3.0).\n * @default 1.0\n */\n estimatedOutputMultiplier?: number;\n /** Called when a budget check fails (before throwing). */\n onBudgetExceeded?: (details: BudgetExceededDetails) => void;\n}\n\nexport interface BudgetExceededDetails {\n estimated: number;\n remaining: number;\n window: \"per-call\" | \"hour\" | \"day\";\n}\n\n/** Error thrown when a budget limit is exceeded. */\nexport class BudgetExceededError extends Error {\n readonly estimated: number;\n readonly remaining: number;\n readonly window: \"per-call\" | \"hour\" | \"day\";\n\n constructor(details: BudgetExceededDetails) {\n super(\n `[Directive] Budget exceeded (${details.window}): estimated $${details.estimated.toFixed(4)}, ` +\n `remaining $${details.remaining.toFixed(4)}`,\n );\n this.name = \"BudgetExceededError\";\n this.estimated = details.estimated;\n this.remaining = details.remaining;\n this.window = details.window;\n }\n}\n\n// ============================================================================\n// Internal: Cost Ledger\n// ============================================================================\n\ninterface CostEntry {\n timestamp: number;\n cost: number;\n}\n\nclass CostLedger {\n private entries: CostEntry[] = [];\n\n record(cost: number): void {\n this.entries.push({ timestamp: Date.now(), cost });\n }\n\n /** Get total cost within a time window. */\n getCostInWindow(windowMs: number): number {\n const cutoff = Date.now() - windowMs;\n this.prune(cutoff);\n\n let total = 0;\n for (const entry of this.entries) {\n if (entry.timestamp >= cutoff) {\n total += entry.cost;\n }\n }\n\n return total;\n }\n\n /** Remove entries older than the cutoff. */\n private prune(cutoff: number): void {\n let pruneIndex = 0;\n while (\n pruneIndex < this.entries.length &&\n this.entries[pruneIndex]!.timestamp < cutoff\n ) {\n pruneIndex++;\n }\n if (pruneIndex > 0) {\n this.entries.splice(0, pruneIndex);\n }\n }\n\n clear(): void {\n this.entries = [];\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst WINDOW_MS: Record<string, number> = {\n hour: 60 * 60 * 1000,\n day: 24 * 60 * 60 * 1000,\n};\n\nfunction estimateInputTokens(input: string, charsPerToken: number): number {\n return Math.ceil(input.length / charsPerToken);\n}\n\nfunction calculateCost(usage: TokenUsage, pricing: TokenPricing): number {\n return (\n (usage.inputTokens / 1_000_000) * pricing.inputPerMillion +\n (usage.outputTokens / 1_000_000) * pricing.outputPerMillion\n );\n}\n\nfunction estimateCallCost(\n inputTokens: number,\n pricing: TokenPricing,\n outputMultiplier = 1.0,\n): number {\n const estimatedOutputTokens = Math.ceil(inputTokens * outputMultiplier);\n\n return (\n (inputTokens / 1_000_000) * pricing.inputPerMillion +\n (estimatedOutputTokens / 1_000_000) * pricing.outputPerMillion\n );\n}\n\n// ============================================================================\n// Wrapper\n// ============================================================================\n\n/**\n * Wrap an AgentRunner with cost budget guards.\n *\n * @example\n * ```typescript\n * const runner = withBudget(baseRunner, {\n * maxCostPerCall: 0.10,\n * pricing: { inputPerMillion: 3, outputPerMillion: 15 },\n * budgets: [\n * { window: \"hour\", maxCost: 5.00, pricing: { inputPerMillion: 3, outputPerMillion: 15 } },\n * { window: \"day\", maxCost: 50.00, pricing: { inputPerMillion: 3, outputPerMillion: 15 } },\n * ],\n * });\n * ```\n */\nexport function withBudget(\n runner: AgentRunner,\n config: BudgetConfig,\n): BudgetRunner {\n const {\n maxCostPerCall,\n budgets = [],\n pricing,\n charsPerToken = 4,\n estimatedOutputMultiplier = 1.0,\n onBudgetExceeded,\n } = config;\n\n // Validate config\n if (!Number.isFinite(charsPerToken) || charsPerToken <= 0) {\n throw new Error(\n \"[Directive] withBudget: charsPerToken must be a positive finite number.\",\n );\n }\n if (\n maxCostPerCall != null &&\n (!Number.isFinite(maxCostPerCall) || maxCostPerCall < 0)\n ) {\n throw new Error(\n \"[Directive] withBudget: maxCostPerCall must be a non-negative finite number.\",\n );\n }\n if (\n !Number.isFinite(estimatedOutputMultiplier) ||\n estimatedOutputMultiplier < 0\n ) {\n throw new Error(\n \"[Directive] withBudget: estimatedOutputMultiplier must be a non-negative finite number.\",\n );\n }\n if (maxCostPerCall != null && !pricing) {\n console.warn(\n \"[Directive] withBudget: maxCostPerCall has no effect without pricing. Provide a pricing config to enable per-call cost estimation.\",\n );\n }\n for (const budget of budgets) {\n if (!Number.isFinite(budget.maxCost) || budget.maxCost < 0) {\n throw new Error(\n `[Directive] withBudget: budgets[${budget.window}].maxCost must be a non-negative finite number.`,\n );\n }\n }\n\n // Per-window ledgers to avoid double-counting\n const windowLedgers = new Map<string, CostLedger>();\n for (const budget of budgets) {\n windowLedgers.set(budget.window, new CostLedger());\n }\n // Base pricing ledger (used when no budget windows are configured)\n const baseLedger = new CostLedger();\n\n const budgetRunner: AgentRunner = async <T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> => {\n const inputTokens = estimateInputTokens(input, charsPerToken);\n\n // Pre-call: Check per-call budget\n if (maxCostPerCall != null && pricing) {\n const estimated = estimateCallCost(\n inputTokens,\n pricing,\n estimatedOutputMultiplier,\n );\n if (estimated > maxCostPerCall) {\n const details: BudgetExceededDetails = {\n estimated,\n remaining: maxCostPerCall,\n window: \"per-call\",\n };\n try {\n onBudgetExceeded?.(details);\n } catch {\n /* callback error must not disrupt budget flow */\n }\n throw new BudgetExceededError(details);\n }\n }\n\n // Pre-call: Check rolling window budgets\n for (const budget of budgets) {\n const windowMs = WINDOW_MS[budget.window]!;\n const ledger = windowLedgers.get(budget.window)!;\n const spent = ledger.getCostInWindow(windowMs);\n const remaining = budget.maxCost - spent;\n const estimated = estimateCallCost(\n inputTokens,\n budget.pricing,\n estimatedOutputMultiplier,\n );\n\n if (estimated > remaining) {\n const details: BudgetExceededDetails = {\n estimated,\n remaining: Math.max(0, remaining),\n window: budget.window,\n };\n try {\n onBudgetExceeded?.(details);\n } catch {\n /* callback error must not disrupt budget flow */\n }\n throw new BudgetExceededError(details);\n }\n }\n\n // Execute the call\n const result = await runner<T>(agent, input, options);\n\n // Post-call: Record actual costs in per-window ledgers\n if (result.tokenUsage) {\n for (const budget of budgets) {\n const ledger = windowLedgers.get(budget.window)!;\n const actualCost = calculateCost(result.tokenUsage, budget.pricing);\n ledger.record(actualCost);\n }\n // Record in base ledger when no windows configured\n if (pricing && budgets.length === 0) {\n const actualCost = calculateCost(result.tokenUsage, pricing);\n baseLedger.record(actualCost);\n }\n }\n\n return result;\n };\n\n /**\n * Get cost spent within a given window. Useful for dashboards and preemptive alerts.\n *\n * @example\n * ```typescript\n * const runner = withBudget(baseRunner, { budgets: [{ window: \"hour\", maxCost: 10, pricing }] });\n * const spent = (runner as BudgetRunner).getSpent(\"hour\");\n * if (spent > 8) console.warn(\"Approaching hourly budget limit!\");\n * ```\n */\n function getSpent(window: \"hour\" | \"day\"): number {\n const ledger = windowLedgers.get(window);\n if (!ledger) {\n return 0;\n }\n const windowMs = WINDOW_MS[window]!;\n\n return ledger.getCostInWindow(windowMs);\n }\n\n // Attach getSpent as a direct property for type-safe access without casting\n (budgetRunner as unknown as Record<string, unknown>).getSpent = getSpent;\n\n return budgetRunner as unknown as BudgetRunner;\n}\n\n/** Helper type for accessing budget runner's getSpent method. */\nexport type BudgetRunner = AgentRunner & {\n /** Get cost spent within a rolling window. */\n getSpent(window: \"hour\" | \"day\"): number;\n};\n","/**\n * P3: Smart Model Selection — Rule-based model routing for AgentRunner.\n *\n * Route simple tasks to cheaper models and complex tasks to expensive ones,\n * reducing cost without sacrificing quality where it matters.\n *\n * Rules are evaluated in order; the first match wins. If no rule matches,\n * the agent's original model is used unchanged.\n *\n * Accepts either a {@link ModelSelectionConfig} object (recommended) or\n * a bare `ModelRule[]` array for convenience.\n *\n * @module\n *\n * @example Config object (recommended)\n * ```typescript\n * import { withModelSelection, byInputLength, byAgentName, byPattern } from '@directive-run/ai';\n *\n * const runner = withModelSelection(baseRunner, {\n * rules: [\n * byInputLength(200, \"gpt-4o-mini\"),\n * byAgentName(\"summarizer\", \"gpt-4o-mini\"),\n * byPattern(/classify|categorize/i, \"gpt-4o-mini\"),\n * ],\n * onModelSelected: (original, selected) => {\n * if (original !== selected) console.log(`Routed ${original} → ${selected}`);\n * },\n * });\n * ```\n *\n * @example Shorthand (rules array)\n * ```typescript\n * const runner = withModelSelection(baseRunner, [\n * byInputLength(200, \"gpt-4o-mini\"),\n * ]);\n * ```\n */\n\nimport type { AgentLike, AgentRunner, RunOptions, RunResult } from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** A single model selection rule. First match wins. */\nexport interface ModelRule {\n /** Predicate that determines if this rule applies. */\n match: (agent: AgentLike, input: string) => boolean;\n /** The model to use when this rule matches. */\n model: string;\n}\n\n/** Configuration for model selection. */\nexport interface ModelSelectionConfig {\n /** Rules evaluated in order. First match wins. */\n rules: ModelRule[];\n /** Called when a model is selected (even if it matches the original). */\n onModelSelected?: (\n originalModel: string | undefined,\n selectedModel: string | undefined,\n ) => void;\n}\n\n// ============================================================================\n// Convenience Matchers\n// ============================================================================\n\n/**\n * Match when input character length is at most `maxLength`.\n *\n * @example\n * ```typescript\n * byInputLength(500, \"gpt-4o-mini\") // inputs up to 500 chars use mini\n * ```\n */\nexport function byInputLength(maxLength: number, model: string): ModelRule {\n return {\n match: (_agent, input) => input.length <= maxLength,\n model,\n };\n}\n\n/**\n * Match by agent name (exact string match).\n *\n * @example\n * ```typescript\n * byAgentName(\"classifier\", \"gpt-4o-mini\")\n * ```\n */\nexport function byAgentName(name: string, model: string): ModelRule {\n return {\n match: (agent) => agent.name === name,\n model,\n };\n}\n\n/**\n * Match by regex pattern on the input text.\n *\n * @example\n * ```typescript\n * byPattern(/classify|categorize/i, \"gpt-4o-mini\") // classification prompts use mini\n * ```\n */\nexport function byPattern(pattern: RegExp, model: string): ModelRule {\n return {\n match: (_agent, input) => {\n // Reset lastIndex for stateful regexes (e.g., /g flag)\n pattern.lastIndex = 0;\n\n return pattern.test(input);\n },\n model,\n };\n}\n\n// ============================================================================\n// Wrapper\n// ============================================================================\n\n/**\n * Wrap an AgentRunner with rule-based model selection.\n *\n * Rules are evaluated in order. The first match wins and overrides `agent.model`.\n * If no rule matches, the agent's original model is used.\n *\n * Accepts either a config object or a bare `ModelRule[]` for convenience.\n *\n * @example\n * ```typescript\n * // Config object (recommended)\n * const runner = withModelSelection(baseRunner, {\n * rules: [\n * byInputLength(200, \"gpt-4o-mini\"),\n * byAgentName(\"summarizer\", \"gpt-4o-mini\"),\n * byPattern(/classify|categorize/i, \"gpt-4o-mini\"),\n * ],\n * onModelSelected: (original, selected) => {\n * console.log(`Model: ${original} → ${selected}`);\n * },\n * });\n *\n * // Shorthand (rules array)\n * const runner = withModelSelection(baseRunner, [\n * byInputLength(200, \"gpt-4o-mini\"),\n * ]);\n * ```\n */\nexport function withModelSelection(\n runner: AgentRunner,\n configOrRules: ModelSelectionConfig | ModelRule[],\n): AgentRunner {\n const config = Array.isArray(configOrRules)\n ? { rules: configOrRules }\n : configOrRules;\n const { rules, onModelSelected } = config;\n\n return async <T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> => {\n let selectedModel = agent.model;\n\n for (const rule of rules) {\n try {\n if (rule.match(agent, input)) {\n selectedModel = rule.model;\n break;\n }\n } catch {\n // Throwing match function is skipped — do not crash model selection\n }\n }\n\n try {\n onModelSelected?.(agent.model, selectedModel);\n } catch {\n /* callback error must not disrupt model selection flow */\n }\n\n // Override model if a rule matched and model is different\n const effectiveAgent =\n selectedModel !== agent.model\n ? { ...agent, model: selectedModel }\n : agent;\n\n return runner<T>(effectiveAgent, input, options);\n };\n}\n","/**\n * P5: Batch Queue — Application-level batching for agent calls.\n *\n * Accumulates calls and flushes them in batches to reduce overhead.\n * Each `submit()` returns a promise that resolves when its individual call completes.\n * Batches execute calls in parallel up to a configurable concurrency limit.\n *\n * @module\n *\n * @example\n * ```typescript\n * import { createBatchQueue } from '@directive-run/ai';\n *\n * const queue = createBatchQueue(runner, {\n * maxBatchSize: 20,\n * maxWaitMs: 5000,\n * concurrency: 5,\n * });\n *\n * // Submit calls — they batch automatically\n * const [r1, r2, r3] = await Promise.all([\n * queue.submit(agent, \"input 1\"),\n * queue.submit(agent, \"input 2\"),\n * queue.submit(agent, \"input 3\"),\n * ]);\n *\n * // Force immediate flush\n * await queue.flush();\n *\n * // Clean up (flushes remaining calls)\n * await queue.destroy();\n * ```\n */\n\nimport type { AgentLike, AgentRunner, RunOptions, RunResult } from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BatchQueueConfig {\n /** Maximum number of calls per batch. @default 20 */\n maxBatchSize?: number;\n /** Maximum time to wait before flushing (ms). @default 5000 */\n maxWaitMs?: number;\n /** Number of calls to run in parallel within a batch. @default 5 */\n concurrency?: number;\n}\n\nexport interface BatchQueue {\n /** Submit a call to the queue. Returns a promise that resolves when the call completes. */\n submit<T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>>;\n /** Flush all pending calls immediately. */\n flush(): Promise<void>;\n /** Get the number of pending calls. */\n readonly pending: number;\n /** Destroy the queue, flushing remaining calls. */\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Internal\n// ============================================================================\n\ninterface QueuedCall {\n agent: AgentLike;\n input: string;\n options?: RunOptions;\n resolve: (result: RunResult<unknown>) => void;\n reject: (error: Error) => void;\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Create a batch queue for grouping agent calls.\n *\n * @example\n * ```typescript\n * const queue = createBatchQueue(runner, {\n * maxBatchSize: 20,\n * maxWaitMs: 5000,\n * concurrency: 5,\n * });\n *\n * // Submit multiple calls — they batch automatically\n * const [result1, result2, result3] = await Promise.all([\n * queue.submit(agent, \"input 1\"),\n * queue.submit(agent, \"input 2\"),\n * queue.submit(agent, \"input 3\"),\n * ]);\n *\n * // Clean up\n * await queue.destroy();\n * ```\n */\nexport function createBatchQueue(\n runner: AgentRunner,\n config: BatchQueueConfig = {},\n): BatchQueue {\n const { maxBatchSize = 20, maxWaitMs = 5000, concurrency = 5 } = config;\n\n // Validate config\n if (!Number.isFinite(maxBatchSize) || maxBatchSize < 1) {\n throw new Error(\n \"[Directive] createBatchQueue: maxBatchSize must be a positive finite number (>= 1).\",\n );\n }\n if (!Number.isFinite(maxWaitMs) || maxWaitMs < 0) {\n throw new Error(\n \"[Directive] createBatchQueue: maxWaitMs must be a non-negative finite number.\",\n );\n }\n if (!Number.isFinite(concurrency) || concurrency < 1) {\n throw new Error(\n \"[Directive] createBatchQueue: concurrency must be a positive finite number (>= 1).\",\n );\n }\n\n const queue: QueuedCall[] = [];\n let flushTimer: ReturnType<typeof setTimeout> | null = null;\n let destroyed = false;\n let flushPromise: Promise<void> | null = null;\n\n function scheduleFlush(): void {\n if (flushTimer !== null) {\n return;\n }\n flushTimer = setTimeout(() => {\n flushTimer = null;\n flushInternal().catch(() => {\n // Errors are delivered to individual call promises\n });\n }, maxWaitMs);\n }\n\n function cancelTimer(): void {\n if (flushTimer !== null) {\n clearTimeout(flushTimer);\n flushTimer = null;\n }\n }\n\n /** Execute calls with concurrency limit. */\n async function executeBatch(batch: QueuedCall[]): Promise<void> {\n let index = 0;\n\n async function runNext(): Promise<void> {\n while (index < batch.length) {\n const current = index++;\n const call = batch[current]!;\n\n try {\n const result = await runner(call.agent, call.input, call.options);\n call.resolve(result);\n } catch (err) {\n call.reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n }\n\n // Run up to `concurrency` workers\n const workers = Array.from(\n { length: Math.min(concurrency, batch.length) },\n () => runNext(),\n );\n await Promise.all(workers);\n }\n\n async function flushInternal(): Promise<void> {\n // Wait for any in-progress flush to complete first\n if (flushPromise) {\n await flushPromise;\n }\n\n if (queue.length === 0) {\n return;\n }\n\n cancelTimer();\n\n // Drain the queue\n const batch = queue.splice(0);\n\n flushPromise = executeBatch(batch).finally(() => {\n flushPromise = null;\n\n // If more calls came in during flush, schedule another\n if (queue.length > 0) {\n scheduleFlush();\n }\n });\n\n await flushPromise;\n }\n\n return {\n submit<T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> {\n if (destroyed) {\n return Promise.reject(\n new Error(\"[Directive] BatchQueue has been destroyed.\"),\n );\n }\n\n return new Promise<RunResult<T>>((resolve, reject) => {\n queue.push({\n agent,\n input,\n options,\n resolve: resolve as (result: RunResult<unknown>) => void,\n reject,\n });\n\n // Flush immediately if batch is full\n if (queue.length >= maxBatchSize) {\n cancelTimer();\n flushInternal().catch(() => {\n // Errors are delivered to individual call promises\n });\n } else {\n scheduleFlush();\n }\n });\n },\n\n async flush(): Promise<void> {\n await flushInternal();\n },\n\n get pending(): number {\n return queue.length;\n },\n\n async destroy(): Promise<void> {\n if (destroyed) {\n return;\n }\n destroyed = true;\n cancelTimer();\n // Flush remaining calls\n if (queue.length > 0) {\n await flushInternal();\n }\n },\n };\n}\n","/**\n * P4: Constraint-Driven Provider Routing — Directive's unique differentiator.\n *\n * Uses user-supplied constraints to select providers based on runtime state:\n * cost, latency, error rates, and compliance regions.\n *\n * Tracks per-provider stats (call count, error count, cost, latency) and\n * exposes them as {@link RoutingFacts} for constraint evaluation.\n *\n * @module\n *\n * @example\n * ```typescript\n * import { createConstraintRouter } from '@directive-run/ai';\n * import type { ConstraintRouterRunner } from '@directive-run/ai';\n *\n * const router = createConstraintRouter({\n * providers: [\n * { name: \"openai\", runner: openaiRunner, pricing: { inputPerMillion: 5, outputPerMillion: 15 } },\n * { name: \"anthropic\", runner: anthropicRunner, pricing: { inputPerMillion: 3, outputPerMillion: 15 } },\n * { name: \"ollama\", runner: ollamaRunner },\n * ],\n * defaultProvider: \"openai\",\n * constraints: [\n * { when: (facts) => facts.totalCost > 100, provider: \"ollama\", priority: 10 },\n * { when: (facts) => facts.providers[\"openai\"]?.errorCount > 5, provider: \"anthropic\" },\n * ],\n * preferCheapest: true, // opt-in to cheapest-provider heuristic\n * onProviderSelected: (name, reason) => console.log(`Using ${name} (${reason})`),\n * });\n *\n * // Access runtime stats\n * console.log(router.facts.totalCost, router.facts.callCount);\n * ```\n */\n\nimport type {\n AgentLike,\n AgentRunner,\n RunOptions,\n RunResult,\n TokenUsage,\n} from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Provider definition for the constraint router.\n *\n * Each provider has its own runner, optional pricing (for cost tracking\n * and cheapest-provider heuristic), and optional region tag.\n */\nexport interface RoutingProvider {\n /** Unique name for this provider. */\n name: string;\n /** The runner to use for this provider. */\n runner: AgentRunner;\n /** Token pricing (cost per million tokens). */\n pricing?: { inputPerMillion: number; outputPerMillion: number };\n /** Geographic region (for compliance routing). */\n region?: string;\n}\n\n/**\n * Runtime facts tracked by the router — exposed for user constraints.\n *\n * Access via the `facts` property on the returned {@link ConstraintRouterRunner}.\n */\nexport interface RoutingFacts {\n totalCost: number;\n callCount: number;\n errorCount: number;\n lastProvider: string | null;\n avgLatencyMs: number;\n /** Per-provider stats. */\n providers: Record<string, ProviderStats>;\n}\n\nexport interface ProviderStats {\n callCount: number;\n errorCount: number;\n totalCost: number;\n avgLatencyMs: number;\n lastErrorAt: number | null;\n}\n\n/** User-supplied routing constraint. */\nexport interface RoutingConstraint {\n /** When this constraint is active. */\n when: (facts: RoutingFacts) => boolean;\n /** The provider to route to. */\n provider: string;\n /** Priority — higher wins when multiple constraints match. @default 0 */\n priority?: number;\n}\n\nexport interface ConstraintRouterConfig {\n /** Available providers. */\n providers: RoutingProvider[];\n /** Default provider name. */\n defaultProvider: string;\n /** User-supplied routing constraints. */\n constraints?: RoutingConstraint[];\n /** Called when a provider is selected. */\n onProviderSelected?: (\n providerName: string,\n reason: \"constraint\" | \"cheapest\" | \"default\",\n ) => void;\n /** Error cooldown — skip a provider for this many ms after an error. @default 30000 */\n errorCooldownMs?: number;\n /**\n * When true, automatically prefer the cheapest available provider\n * (based on pricing) when no user constraint matches.\n * When false, the default provider is used unless a constraint overrides it.\n * @default false\n */\n preferCheapest?: boolean;\n}\n\n// ============================================================================\n// Internal\n// ============================================================================\n\nfunction createEmptyStats(): ProviderStats {\n return {\n callCount: 0,\n errorCount: 0,\n totalCost: 0,\n avgLatencyMs: 0,\n lastErrorAt: null,\n };\n}\n\nfunction calculateCost(\n usage: TokenUsage | undefined,\n pricing?: { inputPerMillion: number; outputPerMillion: number },\n): number {\n if (!usage || !pricing) {\n return 0;\n }\n\n return (\n (usage.inputTokens / 1_000_000) * pricing.inputPerMillion +\n (usage.outputTokens / 1_000_000) * pricing.outputPerMillion\n );\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Create a constraint-driven provider router.\n *\n * @example\n * ```typescript\n * const runner = createConstraintRouter({\n * providers: [\n * { name: \"openai\", runner: openaiRunner, pricing: { inputPerMillion: 5, outputPerMillion: 15 } },\n * { name: \"anthropic\", runner: anthropicRunner, pricing: { inputPerMillion: 3, outputPerMillion: 15 } },\n * { name: \"ollama\", runner: ollamaRunner },\n * ],\n * defaultProvider: \"openai\",\n * constraints: [\n * { when: (facts) => facts.totalCost > 100, provider: \"ollama\", priority: 10 },\n * { when: (facts) => facts.providers[\"openai\"]?.errorCount > 5, provider: \"anthropic\" },\n * ],\n * });\n * ```\n */\nexport function createConstraintRouter(\n config: ConstraintRouterConfig,\n): ConstraintRouterRunner {\n const {\n providers,\n defaultProvider,\n constraints = [],\n onProviderSelected,\n errorCooldownMs = 30000,\n preferCheapest = false,\n } = config;\n\n // Validate config\n if (!Number.isFinite(errorCooldownMs) || errorCooldownMs < 0) {\n throw new Error(\n \"[Directive] createConstraintRouter: errorCooldownMs must be a non-negative finite number.\",\n );\n }\n\n // Validate\n const providerMap = new Map<string, RoutingProvider>();\n for (const provider of providers) {\n providerMap.set(provider.name, provider);\n }\n\n if (!providerMap.has(defaultProvider)) {\n throw new Error(\n `[Directive] Default provider \"${defaultProvider}\" not found in providers list.`,\n );\n }\n\n // Initialize facts\n const facts: RoutingFacts = {\n totalCost: 0,\n callCount: 0,\n errorCount: 0,\n lastProvider: null,\n avgLatencyMs: 0,\n providers: Object.create(null) as Record<string, ProviderStats>,\n };\n\n for (const provider of providers) {\n facts.providers[provider.name] = createEmptyStats();\n }\n\n // Total latency for averaging\n let totalLatencyMs = 0;\n\n // Pre-sort constraints at construction time (not per-call)\n const sortedConstraints = [...constraints].sort(\n (a, b) => (b.priority ?? 0) - (a.priority ?? 0),\n );\n\n /** Select provider based on constraints and heuristics. */\n function selectProvider(): {\n provider: RoutingProvider;\n reason: \"constraint\" | \"cheapest\" | \"default\";\n } {\n const now = Date.now();\n\n for (const constraint of sortedConstraints) {\n try {\n if (constraint.when(facts)) {\n const provider = providerMap.get(constraint.provider);\n if (provider) {\n return { provider, reason: \"constraint\" };\n }\n }\n } catch {\n // Throwing constraint is skipped — do not crash the router\n }\n }\n\n // 2. Filter out providers in error cooldown\n const availableProviders = providers.filter((p) => {\n const stats = facts.providers[p.name];\n if (!stats) {\n return true;\n }\n if (stats.lastErrorAt && now - stats.lastErrorAt < errorCooldownMs) {\n return false;\n }\n\n return true;\n });\n\n // 3. Cheapest-provider heuristic (opt-in via preferCheapest)\n if (preferCheapest && availableProviders.length > 0) {\n const sorted = [...availableProviders].sort((a, b) => {\n const aCost = a.pricing\n ? a.pricing.inputPerMillion + a.pricing.outputPerMillion\n : Number.POSITIVE_INFINITY;\n const bCost = b.pricing\n ? b.pricing.inputPerMillion + b.pricing.outputPerMillion\n : Number.POSITIVE_INFINITY;\n if (aCost !== bCost) {\n return aCost - bCost;\n }\n // Tie-break: prefer default provider\n if (a.name === defaultProvider) {\n return -1;\n }\n if (b.name === defaultProvider) {\n return 1;\n }\n\n return 0;\n });\n\n if (sorted[0] !== providerMap.get(defaultProvider)) {\n return { provider: sorted[0]!, reason: \"cheapest\" };\n }\n }\n\n // 4. If default is in cooldown, pick the first available\n if (\n availableProviders.length > 0 &&\n !availableProviders.some((p) => p.name === defaultProvider)\n ) {\n return { provider: availableProviders[0]!, reason: \"default\" };\n }\n\n // 5. Fallback to default\n return { provider: providerMap.get(defaultProvider)!, reason: \"default\" };\n }\n\n /** Update facts after a call. */\n function recordCall(\n providerName: string,\n latencyMs: number,\n usage: TokenUsage | undefined,\n pricing?: { inputPerMillion: number; outputPerMillion: number },\n error?: Error,\n ): void {\n const stats = facts.providers[providerName] ?? createEmptyStats();\n\n stats.callCount++;\n facts.callCount++;\n\n if (error) {\n stats.errorCount++;\n facts.errorCount++;\n stats.lastErrorAt = Date.now();\n } else {\n const cost = calculateCost(usage, pricing);\n stats.totalCost += cost;\n facts.totalCost += cost;\n }\n\n // Update average latency\n totalLatencyMs += latencyMs;\n facts.avgLatencyMs = totalLatencyMs / facts.callCount;\n\n const statsTotal =\n stats.callCount > 0\n ? (stats.avgLatencyMs * (stats.callCount - 1) + latencyMs) /\n stats.callCount\n : latencyMs;\n stats.avgLatencyMs = statsTotal;\n\n facts.providers[providerName] = stats;\n facts.lastProvider = providerName;\n }\n\n const routerRunner: AgentRunner = async <T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> => {\n const { provider, reason } = selectProvider();\n try {\n onProviderSelected?.(provider.name, reason);\n } catch {\n /* callback error must not disrupt routing flow */\n }\n\n const startTime = Date.now();\n\n try {\n const result = await provider.runner<T>(agent, input, options);\n const latencyMs = Date.now() - startTime;\n\n recordCall(provider.name, latencyMs, result.tokenUsage, provider.pricing);\n\n return result;\n } catch (err) {\n const latencyMs = Date.now() - startTime;\n const error = err instanceof Error ? err : new Error(String(err));\n\n recordCall(provider.name, latencyMs, undefined, provider.pricing, error);\n\n throw error;\n }\n };\n\n /** Expose facts for external inspection (deep-cloned to prevent mutation). */\n Object.defineProperty(routerRunner, \"facts\", {\n get: () => {\n const clonedProviders: Record<string, ProviderStats> = Object.create(\n null,\n ) as Record<string, ProviderStats>;\n for (const key of Object.keys(facts.providers)) {\n clonedProviders[key] = { ...facts.providers[key]! };\n }\n\n return { ...facts, providers: clonedProviders };\n },\n enumerable: true,\n });\n\n return routerRunner as ConstraintRouterRunner;\n}\n\n/** Helper type for accessing router facts. */\nexport type ConstraintRouterRunner = AgentRunner & {\n readonly facts: RoutingFacts;\n};\n","/**\n * OpenTelemetry Integration — AI-specific observability spans.\n *\n * Auto-instruments agent orchestrators with OpenTelemetry spans for\n * agent runs, guardrail checks, constraint evaluations, and DAG execution.\n * Works with any OTEL-compatible collector (Jaeger, Zipkin, Honeycomb, etc.).\n *\n * Uses OpenTelemetry GenAI semantic conventions (`gen_ai.*`) for\n * AI-specific attributes alongside Directive-specific attributes.\n *\n * @example\n * ```typescript\n * import { createOtelPlugin } from \"@directive-run/ai\";\n *\n * const orchestrator = createAgentOrchestrator({\n * runner,\n * plugins: [createOtelPlugin({ serviceName: \"my-ai-app\" })],\n * });\n * // Every run() creates spans with: agent name, model, tokens, cost, duration\n * ```\n *\n * @module\n */\n\nimport type { DebugTimeline } from \"./debug-timeline.js\";\nimport type {\n AgentCompleteEvent,\n AgentErrorEvent,\n AgentStartEvent,\n ConstraintEvaluateEvent,\n DebugEvent,\n GuardrailCheckEvent,\n PatternCompleteEvent,\n PatternStartEvent,\n ResolverCompleteEvent,\n ResolverErrorEvent,\n ResolverStartEvent,\n} from \"./types.js\";\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Default TTL for active spans (5 minutes). Spans older than this are cleaned up. */\nconst DEFAULT_SPAN_TTL_MS = 300_000;\n\n/** Maximum active spans before triggering cleanup */\nconst MAX_ACTIVE_SPANS = 10_000;\n\n/** Maximum depth of the pattern span stack */\nconst MAX_PATTERN_STACK = 100;\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Minimal span interface compatible with OpenTelemetry API */\nexport interface OtelSpan {\n /** Set an attribute on the span */\n setAttribute(key: string, value: string | number | boolean): void;\n /** Add an event to the span */\n addEvent(\n name: string,\n attributes?: Record<string, string | number | boolean>,\n ): void;\n /** Set the span status */\n setStatus(status: { code: number; message?: string }): void;\n /** End the span */\n end(): void;\n}\n\n/** OTEL status codes as a const object (no enum overhead) */\nexport const OtelStatusCode = {\n UNSET: 0,\n OK: 1,\n ERROR: 2,\n} as const;\n\nexport type OtelStatusCode =\n (typeof OtelStatusCode)[keyof typeof OtelStatusCode];\n\n/** Tracer interface compatible with OpenTelemetry API */\nexport interface OtelTracer {\n /** Start a new span */\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): OtelSpan;\n}\n\n/** Configuration for the OTEL plugin */\nexport interface OtelPluginConfig {\n /** Service name for span attribution */\n serviceName: string;\n /** Custom tracer instance. If not provided, uses a no-op tracer for standalone span collection. */\n tracer?: OtelTracer;\n /** Span prefix. Default: \"directive.ai\" */\n spanPrefix?: string;\n /** Span processor callback — called for every completed span. Useful for custom exporters. */\n onSpanEnd?: (spanData: SpanData) => void;\n /** Event types to instrument. Default: all */\n instrumentEvents?: Set<string>;\n /** TTL for active spans in ms. Spans older than this are cleaned up. Default: 300000 (5 min) */\n spanTtlMs?: number;\n}\n\n/** Serializable span data for export */\nexport interface SpanData {\n name: string;\n traceId: string;\n spanId: string;\n parentSpanId?: string;\n attributes: Record<string, string | number | boolean>;\n events: Array<{\n name: string;\n attributes?: Record<string, string | number | boolean>;\n timestamp: number;\n }>;\n status: { code: OtelStatusCode; message?: string };\n startTime: number;\n endTime: number;\n durationMs: number;\n}\n\n/** OTEL Plugin instance */\nexport interface OtelPlugin {\n /** Attach to a debug timeline to auto-instrument */\n attach(timeline: DebugTimeline): () => void;\n /** Get all collected spans (when using built-in collector) */\n getSpans(): SpanData[];\n /** Clear collected spans */\n clearSpans(): void;\n /** Get the underlying tracer */\n getTracer(): OtelTracer;\n /** Get count of currently active (in-flight) spans */\n getActiveSpanCount(): number;\n}\n\n// ============================================================================\n// No-Op Tracer (for standalone span collection)\n// ============================================================================\n\nclass CollectedSpan implements OtelSpan {\n readonly attributes: Record<string, string | number | boolean> =\n Object.create(null);\n readonly spanEvents: Array<{\n name: string;\n attributes?: Record<string, string | number | boolean>;\n timestamp: number;\n }> = [];\n status: { code: OtelStatusCode; message?: string } = {\n code: OtelStatusCode.UNSET,\n };\n readonly startTime: number;\n endTime = 0;\n\n constructor(\n readonly name: string,\n readonly spanId: string,\n readonly traceId: string,\n readonly parentSpanId: string | undefined,\n initialAttributes?: Record<string, string | number | boolean>,\n private readonly onEnd?: (span: CollectedSpan) => void,\n ) {\n this.startTime = Date.now();\n if (initialAttributes) {\n for (const [key, value] of Object.entries(initialAttributes)) {\n this.attributes[key] = value;\n }\n }\n }\n\n setAttribute(key: string, value: string | number | boolean): void {\n this.attributes[key] = value;\n }\n\n addEvent(\n name: string,\n attributes?: Record<string, string | number | boolean>,\n ): void {\n this.spanEvents.push({ name, attributes, timestamp: Date.now() });\n }\n\n setStatus(status: { code: OtelStatusCode; message?: string }): void {\n this.status = status;\n }\n\n end(): void {\n this.endTime = Date.now();\n this.onEnd?.(this);\n }\n\n toSpanData(): SpanData {\n return {\n name: this.name,\n traceId: this.traceId,\n spanId: this.spanId,\n parentSpanId: this.parentSpanId,\n attributes: { ...this.attributes },\n events: [...this.spanEvents],\n status: { ...this.status },\n startTime: this.startTime,\n endTime: this.endTime,\n durationMs: this.endTime - this.startTime,\n };\n }\n}\n\nclass CollectorTracer implements OtelTracer {\n readonly spans: SpanData[] = [];\n\n startSpan(\n name: string,\n options?: {\n attributes?: Record<string, string | number | boolean>;\n spanId?: string;\n traceId?: string;\n parentSpanId?: string;\n },\n ): OtelSpan {\n const spanId = options?.spanId ?? `fallback-${crypto.randomUUID()}`;\n const traceId = options?.traceId ?? `fallback-${crypto.randomUUID()}`;\n const parentSpanId = options?.parentSpanId;\n\n return new CollectedSpan(\n name,\n spanId,\n traceId,\n parentSpanId,\n options?.attributes,\n (span) => {\n this.spans.push(span.toSpanData());\n },\n );\n }\n\n clear(): void {\n this.spans.length = 0;\n }\n}\n\n// ============================================================================\n// External Tracer Shadow Data\n// ============================================================================\n\n/**\n * When using an external tracer, we track span metadata alongside\n * the external span so `onSpanEnd` can provide meaningful SpanData.\n */\ninterface ExternalSpanShadow {\n span: OtelSpan;\n name: string;\n spanId: string;\n traceId: string;\n parentSpanId?: string;\n attributes: Record<string, string | number | boolean>;\n events: Array<{\n name: string;\n attributes?: Record<string, string | number | boolean>;\n timestamp: number;\n }>;\n status: { code: OtelStatusCode; message?: string };\n startTime: number;\n}\n\n// ============================================================================\n// Active Span Entry\n// ============================================================================\n\ninterface ActiveSpanEntry {\n span: OtelSpan;\n shadow?: ExternalSpanShadow;\n spanId: string;\n traceId: string;\n startTime: number;\n /** A13: Pre-computed index key to avoid parsing from span key */\n indexKey?: string;\n}\n\n// ============================================================================\n// Plugin Implementation\n// ============================================================================\n\n/**\n * Create an OpenTelemetry plugin for AI observability.\n *\n * Subscribes to a DebugTimeline and creates spans for agent runs,\n * guardrail checks, constraint evaluations, resolver executions,\n * and execution patterns (DAG, parallel, sequential, etc.).\n *\n * Parent-child relationships:\n * - Pattern spans are roots\n * - Agent spans are children of the active pattern span (if any)\n * - Guardrail/resolver spans within an agent run are children of the agent span\n * - Constraint evaluations within an agent run are recorded as span events\n *\n * @example\n * ```typescript\n * // With built-in span collection:\n * const otel = createOtelPlugin({ serviceName: \"my-app\" });\n * const unsub = otel.attach(orchestrator.timeline);\n * await orchestrator.run(agent, input);\n * console.log(otel.getSpans()); // All spans from the run\n *\n * // With custom OTEL tracer:\n * import { trace } from \"@opentelemetry/api\";\n * const otel = createOtelPlugin({\n * serviceName: \"my-app\",\n * tracer: trace.getTracer(\"directive-ai\"),\n * });\n * ```\n */\nexport function createOtelPlugin(config: OtelPluginConfig): OtelPlugin {\n const prefix = config.spanPrefix ?? \"directive.ai\";\n const instrumentEvents = config.instrumentEvents;\n const spanTtlMs = config.spanTtlMs ?? DEFAULT_SPAN_TTL_MS;\n\n // Use provided tracer or built-in collector\n const isCollector = !config.tracer;\n const collectorTracer = isCollector ? new CollectorTracer() : null;\n const tracer = config.tracer ?? collectorTracer!;\n\n // Instance-scoped ID generation (prevents cross-test leakage)\n let spanCounter = 0;\n\n function generateId(): string {\n return `${Date.now().toString(36)}-${(spanCounter++).toString(36)}`;\n }\n\n function generateTraceId(): string {\n return `${Date.now().toString(36)}-${crypto.randomUUID().slice(0, 8)}`;\n }\n\n // Track active spans by unique key for correlation\n // Key format: \"type:id:counter\" to prevent collisions\n const activeSpans = new Map<string, ActiveSpanEntry>();\n let keyCounter = 0;\n\n // Secondary index for O(1) span lookup by \"type:id\" prefix\n const spanKeyIndex = new Map<string, string[]>();\n\n /**\n * Pattern span stack for proper nesting (inner patterns don't clobber outer).\n *\n * WARNING: A single OtelPlugin instance must NOT be attached to more than one\n * timeline simultaneously. The patternStack is local to this closure and is\n * shared across all events emitted through it. Concurrent use across multiple\n * timelines will interleave push/pop operations, producing incorrect span\n * hierarchies and potentially orphaned spans.\n */\n const patternStack: ActiveSpanEntry[] = [];\n\n // A7: Track attached timeline to prevent double-attach\n let attachedTimeline: DebugTimeline | null = null;\n\n // Dev warning dedup\n let warnedExternalGetSpans = false;\n\n function shouldInstrument(type: string): boolean {\n if (!instrumentEvents) {\n return true;\n }\n\n return instrumentEvents.has(type);\n }\n\n function makeSpanKey(type: string, id: string): string {\n return `${type}:${id}:${keyCounter++}`;\n }\n\n function findActiveSpan(\n type: string,\n id: string,\n ): { key: string; entry: ActiveSpanEntry } | null {\n const indexKey = `${type}:${id}`;\n const keys = spanKeyIndex.get(indexKey);\n if (keys) {\n // Walk from end to find latest active span\n for (let i = keys.length - 1; i >= 0; i--) {\n const entry = activeSpans.get(keys[i]!);\n if (entry) {\n return { key: keys[i]!, entry };\n }\n }\n\n // All stale\n spanKeyIndex.delete(indexKey);\n }\n\n return null;\n }\n\n function registerSpan(\n type: string,\n id: string,\n key: string,\n entry: ActiveSpanEntry,\n ): void {\n // A13: Store indexKey explicitly to avoid parsing from key later\n const indexKey = `${type}:${id}`;\n entry.indexKey = indexKey;\n activeSpans.set(key, entry);\n const existing = spanKeyIndex.get(indexKey);\n if (existing) {\n existing.push(key);\n } else {\n spanKeyIndex.set(indexKey, [key]);\n }\n }\n\n function removeSpan(key: string): void {\n // A13: Use stored indexKey instead of parsing from key string\n const entry = activeSpans.get(key);\n activeSpans.delete(key);\n\n const indexKey = entry?.indexKey;\n if (indexKey) {\n const keys = spanKeyIndex.get(indexKey);\n if (keys) {\n const idx = keys.indexOf(key);\n if (idx !== -1) {\n keys.splice(idx, 1);\n }\n if (keys.length === 0) {\n spanKeyIndex.delete(indexKey);\n }\n }\n }\n }\n\n function cleanupStaleSpans(): void {\n // A3: Always run TTL-based pruning (not gated behind size check)\n const now = Date.now();\n if (activeSpans.size < MAX_ACTIVE_SPANS) {\n // Below hard cap: only prune spans that exceeded TTL\n let hasPruned = false;\n for (const [key, entry] of activeSpans) {\n if (now - entry.startTime > spanTtlMs) {\n setAttributeTracked(entry, \"directive.stale\", true);\n setStatusTracked(entry, {\n code: OtelStatusCode.ERROR,\n message: \"Span TTL exceeded — cleaned up\",\n });\n endSpan(entry);\n removeSpan(key);\n hasPruned = true;\n }\n }\n\n if (hasPruned) {\n return;\n }\n\n return;\n }\n\n for (const [key, entry] of activeSpans) {\n if (now - entry.startTime > spanTtlMs) {\n setAttributeTracked(entry, \"directive.stale\", true);\n setStatusTracked(entry, {\n code: OtelStatusCode.ERROR,\n message: \"Span TTL exceeded — cleaned up\",\n });\n endSpan(entry);\n removeSpan(key);\n }\n }\n }\n\n function startSpan(\n name: string,\n attributes: Record<string, string | number | boolean>,\n parentEntry?: ActiveSpanEntry | null,\n ): { span: OtelSpan; entry: ActiveSpanEntry } {\n const spanId = generateId();\n const traceId = parentEntry?.traceId ?? generateTraceId();\n const parentSpanId = parentEntry?.spanId;\n\n let span: OtelSpan;\n\n if (isCollector) {\n span = (tracer as CollectorTracer).startSpan(name, {\n attributes,\n spanId,\n traceId,\n parentSpanId,\n });\n } else {\n span = tracer.startSpan(name, { attributes });\n }\n\n const entry: ActiveSpanEntry = {\n span,\n spanId,\n traceId,\n startTime: Date.now(),\n };\n\n // Track shadow data for external tracers\n if (!isCollector) {\n entry.shadow = {\n span,\n name,\n spanId,\n traceId,\n parentSpanId,\n attributes: { ...attributes },\n events: [],\n status: { code: OtelStatusCode.UNSET },\n startTime: entry.startTime,\n };\n }\n\n return { span, entry };\n }\n\n function endSpan(entry: ActiveSpanEntry): void {\n entry.span.end();\n\n if (config.onSpanEnd) {\n config.onSpanEnd(spanToData(entry));\n }\n }\n\n function spanToData(entry: ActiveSpanEntry): SpanData {\n if (entry.span instanceof CollectedSpan) {\n return entry.span.toSpanData();\n }\n\n // For external tracers, use shadow data\n if (entry.shadow) {\n const now = Date.now();\n\n return {\n name: entry.shadow.name,\n traceId: entry.shadow.traceId,\n spanId: entry.shadow.spanId,\n parentSpanId: entry.shadow.parentSpanId,\n attributes: { ...entry.shadow.attributes },\n events: [...entry.shadow.events],\n status: { ...entry.shadow.status },\n startTime: entry.shadow.startTime,\n endTime: now,\n durationMs: now - entry.shadow.startTime,\n };\n }\n\n // Fallback — should not happen\n const now = Date.now();\n\n return {\n name: \"unknown\",\n traceId: entry.traceId,\n spanId: entry.spanId,\n attributes: {},\n events: [],\n status: { code: OtelStatusCode.UNSET },\n startTime: entry.startTime,\n endTime: now,\n durationMs: now - entry.startTime,\n };\n }\n\n function setAttributeTracked(\n entry: ActiveSpanEntry,\n key: string,\n value: string | number | boolean,\n ): void {\n entry.span.setAttribute(key, value);\n if (entry.shadow) {\n entry.shadow.attributes[key] = value;\n }\n }\n\n function addEventTracked(\n entry: ActiveSpanEntry,\n name: string,\n attributes?: Record<string, string | number | boolean>,\n ): void {\n entry.span.addEvent(name, attributes);\n if (entry.shadow) {\n entry.shadow.events.push({ name, attributes, timestamp: Date.now() });\n }\n }\n\n function setStatusTracked(\n entry: ActiveSpanEntry,\n status: { code: OtelStatusCode; message?: string },\n ): void {\n entry.span.setStatus(status);\n if (entry.shadow) {\n entry.shadow.status = { ...status };\n }\n }\n\n function handleEvent(event: DebugEvent): void {\n if (!shouldInstrument(event.type)) {\n return;\n }\n\n cleanupStaleSpans();\n\n switch (event.type) {\n case \"agent_start\":\n handleAgentStart(event);\n break;\n case \"agent_complete\":\n handleAgentComplete(event);\n break;\n case \"agent_error\":\n handleAgentError(event);\n break;\n case \"guardrail_check\":\n handleGuardrailCheck(event);\n break;\n case \"constraint_evaluate\":\n handleConstraintEvaluate(event);\n break;\n case \"resolver_start\":\n handleResolverStart(event);\n break;\n case \"resolver_complete\":\n handleResolverComplete(event);\n break;\n case \"resolver_error\":\n handleResolverError(event);\n break;\n case \"pattern_start\":\n handlePatternStart(event);\n break;\n case \"pattern_complete\":\n handlePatternComplete(event);\n break;\n default:\n // Other events are recorded as span events on the active agent span\n if (event.agentId) {\n const found = findActiveSpan(\"agent\", event.agentId);\n if (found) {\n addEventTracked(found.entry, event.type, {\n \"event.id\": event.id,\n \"event.timestamp\": event.timestamp,\n });\n }\n }\n }\n }\n\n function handleAgentStart(event: AgentStartEvent): void {\n // Agent span is a child of the active pattern span (top of stack)\n const parentEntry =\n patternStack.length > 0 ? patternStack[patternStack.length - 1]! : null;\n\n const { entry } = startSpan(\n `${prefix}.agent.run`,\n {\n \"directive.service\": config.serviceName,\n \"directive.agent.name\": event.agentId,\n \"directive.agent.input_length\": event.inputLength,\n // GenAI semantic conventions\n \"gen_ai.operation.name\": \"agent.run\",\n \"gen_ai.agent.name\": event.agentId,\n },\n parentEntry,\n );\n\n const key = makeSpanKey(\"agent\", event.agentId);\n registerSpan(\"agent\", event.agentId, key, entry);\n }\n\n function handleAgentComplete(event: AgentCompleteEvent): void {\n const found = findActiveSpan(\"agent\", event.agentId);\n if (found) {\n setAttributeTracked(\n found.entry,\n \"directive.agent.output_length\",\n event.outputLength,\n );\n setAttributeTracked(\n found.entry,\n \"directive.agent.total_tokens\",\n event.totalTokens,\n );\n setAttributeTracked(\n found.entry,\n \"directive.agent.duration_ms\",\n event.durationMs,\n );\n // GenAI semantic conventions\n setAttributeTracked(\n found.entry,\n \"gen_ai.usage.total_tokens\",\n event.totalTokens,\n );\n\n setStatusTracked(found.entry, { code: OtelStatusCode.OK });\n endSpan(found.entry);\n removeSpan(found.key);\n }\n }\n\n function handleAgentError(event: AgentErrorEvent): void {\n const found = findActiveSpan(\"agent\", event.agentId);\n if (found) {\n setAttributeTracked(\n found.entry,\n \"directive.agent.duration_ms\",\n event.durationMs,\n );\n setAttributeTracked(\n found.entry,\n \"directive.agent.error\",\n event.errorMessage,\n );\n // GenAI semantic conventions\n setAttributeTracked(\n found.entry,\n \"gen_ai.error.message\",\n event.errorMessage,\n );\n\n setStatusTracked(found.entry, {\n code: OtelStatusCode.ERROR,\n message: event.errorMessage,\n });\n endSpan(found.entry);\n removeSpan(found.key);\n }\n }\n\n function handleGuardrailCheck(event: GuardrailCheckEvent): void {\n // Guardrail span is a child of the active agent span for this event's agent\n const parentEntry = event.agentId\n ? (findActiveSpan(\"agent\", event.agentId)?.entry ?? null)\n : null;\n\n const { entry } = startSpan(\n `${prefix}.guardrail.check`,\n {\n \"directive.service\": config.serviceName,\n \"directive.guardrail.name\": event.guardrailName,\n \"directive.guardrail.type\": event.guardrailType,\n \"directive.guardrail.passed\": event.passed,\n \"directive.guardrail.duration_ms\": event.durationMs,\n // GenAI semantic conventions\n \"gen_ai.guardrail.name\": event.guardrailName,\n \"gen_ai.guardrail.type\": event.guardrailType,\n \"gen_ai.guardrail.passed\": event.passed,\n },\n parentEntry,\n );\n\n if (event.reason) {\n setAttributeTracked(entry, \"directive.guardrail.reason\", event.reason);\n }\n\n setStatusTracked(entry, {\n code: event.passed ? OtelStatusCode.OK : OtelStatusCode.ERROR,\n message: event.passed ? undefined : event.reason,\n });\n endSpan(entry);\n }\n\n function handleConstraintEvaluate(event: ConstraintEvaluateEvent): void {\n // Constraints are lightweight — record as events on the active agent span\n if (event.agentId) {\n const found = findActiveSpan(\"agent\", event.agentId);\n if (found) {\n addEventTracked(found.entry, \"constraint_evaluate\", {\n \"directive.constraint.id\": event.constraintId,\n \"directive.constraint.fired\": event.fired,\n });\n\n return;\n }\n }\n\n // No parent span — create a standalone span\n const { entry } = startSpan(\n `${prefix}.constraint.evaluate`,\n {\n \"directive.service\": config.serviceName,\n \"directive.constraint.id\": event.constraintId,\n \"directive.constraint.fired\": event.fired,\n },\n null,\n );\n setStatusTracked(entry, { code: OtelStatusCode.OK });\n endSpan(entry);\n }\n\n function handleResolverStart(event: ResolverStartEvent): void {\n // Resolver spans can be children of the active agent span\n const agentParent = event.agentId\n ? (findActiveSpan(\"agent\", event.agentId)?.entry ?? null)\n : null;\n // Or fall back to pattern span (top of stack)\n const parentEntry =\n agentParent ??\n (patternStack.length > 0 ? patternStack[patternStack.length - 1]! : null);\n\n const { entry } = startSpan(\n `${prefix}.resolver.execute`,\n {\n \"directive.service\": config.serviceName,\n \"directive.resolver.id\": event.resolverId,\n \"directive.resolver.requirement_type\": event.requirementType,\n },\n parentEntry,\n );\n\n const key = makeSpanKey(\"resolver\", event.resolverId);\n registerSpan(\"resolver\", event.resolverId, key, entry);\n }\n\n function handleResolverComplete(event: ResolverCompleteEvent): void {\n const found = findActiveSpan(\"resolver\", event.resolverId);\n if (found) {\n setAttributeTracked(\n found.entry,\n \"directive.resolver.duration_ms\",\n event.durationMs,\n );\n setStatusTracked(found.entry, { code: OtelStatusCode.OK });\n endSpan(found.entry);\n removeSpan(found.key);\n }\n }\n\n function handleResolverError(event: ResolverErrorEvent): void {\n const found = findActiveSpan(\"resolver\", event.resolverId);\n if (found) {\n setAttributeTracked(\n found.entry,\n \"directive.resolver.duration_ms\",\n event.durationMs,\n );\n setAttributeTracked(\n found.entry,\n \"directive.resolver.error\",\n event.errorMessage,\n );\n setStatusTracked(found.entry, {\n code: OtelStatusCode.ERROR,\n message: event.errorMessage,\n });\n endSpan(found.entry);\n removeSpan(found.key);\n }\n }\n\n function handlePatternStart(event: PatternStartEvent): void {\n const parentEntry =\n patternStack.length > 0 ? patternStack[patternStack.length - 1]! : null;\n const { entry } = startSpan(\n `${prefix}.pattern.${event.patternType}`,\n {\n \"directive.service\": config.serviceName,\n \"directive.pattern.id\": event.patternId,\n \"directive.pattern.type\": event.patternType,\n },\n parentEntry,\n );\n\n const key = makeSpanKey(\"pattern\", event.patternId);\n registerSpan(\"pattern\", event.patternId, key, entry);\n // A3: Cap pattern stack to prevent overflow\n if (patternStack.length < MAX_PATTERN_STACK) {\n patternStack.push(entry);\n }\n }\n\n function handlePatternComplete(event: PatternCompleteEvent): void {\n const found = findActiveSpan(\"pattern\", event.patternId);\n if (found) {\n setAttributeTracked(\n found.entry,\n \"directive.pattern.duration_ms\",\n event.durationMs,\n );\n if (event.error) {\n setAttributeTracked(\n found.entry,\n \"directive.pattern.error\",\n event.error,\n );\n setStatusTracked(found.entry, {\n code: OtelStatusCode.ERROR,\n message: event.error,\n });\n } else {\n setStatusTracked(found.entry, { code: OtelStatusCode.OK });\n }\n endSpan(found.entry);\n removeSpan(found.key);\n\n // Remove from pattern stack\n const idx = patternStack.indexOf(found.entry);\n if (idx !== -1) {\n patternStack.splice(idx, 1);\n }\n }\n }\n\n return {\n attach(timeline: DebugTimeline): () => void {\n // A7: Prevent attaching to multiple timelines simultaneously\n if (attachedTimeline && attachedTimeline !== timeline) {\n throw new Error(\n \"[Directive OTEL] Plugin already attached to a different timeline. Create a new plugin instance.\",\n );\n }\n\n attachedTimeline = timeline;\n const unsub = timeline.subscribe(handleEvent);\n const cleanupInterval = setInterval(\n cleanupStaleSpans,\n Math.min(spanTtlMs, 60_000),\n );\n\n return () => {\n unsub();\n clearInterval(cleanupInterval);\n attachedTimeline = null;\n\n // Cleanup: end all active spans on detach\n for (const [_key, entry] of activeSpans) {\n setAttributeTracked(entry, \"directive.detached\", true);\n setStatusTracked(entry, {\n code: OtelStatusCode.ERROR,\n message: \"Plugin detached while span was active\",\n });\n endSpan(entry);\n }\n activeSpans.clear();\n spanKeyIndex.clear();\n patternStack.length = 0;\n };\n },\n\n getSpans(): SpanData[] {\n if (collectorTracer) {\n return [...collectorTracer.spans];\n }\n\n if (!warnedExternalGetSpans) {\n warnedExternalGetSpans = true;\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\"\n ) {\n console.warn(\n \"[Directive OTEL] getSpans() returns [] when using an external tracer. \" +\n \"Use the onSpanEnd callback to collect span data instead.\",\n );\n }\n }\n\n return [];\n },\n\n clearSpans(): void {\n collectorTracer?.clear();\n },\n\n getTracer(): OtelTracer {\n return tracer;\n },\n\n getActiveSpanCount(): number {\n return activeSpans.size;\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/pipe.ts","../src/memory.ts","../src/plugins/audit.ts","../src/plugins/compliance.ts","../src/stream-channel.ts","../src/rag.ts","../src/sse-transport.ts","../src/retry.ts","../src/fallback.ts","../src/budget.ts","../src/model-selector.ts","../src/batch.ts","../src/provider-routing.ts","../src/otel.ts","../src/otel-sources.ts"],"names":["pipe","runner","middlewares","result","mw","estimateTokens","message","tokenizer","content","estimateTotalTokens","messages","sum","msg","createSlidingWindowStrategy","defaultConfig","configOverride","config","maxMessages","preserveRecentCount","recentMessages","olderMessages","olderToKeep","keptOlder","toSummarize","keep","createTokenBasedStrategy","maxTokens","countSystemMessages","recentTokens","currentTokens","i","msgTokens","createHybridStrategy","slidingWindow","tokenBased","windowResult","tokenResult","createAgentMemory","strategy","summarizer","strategyConfig","autoManage","onMemoryManaged","onManageError","maxContextTokens","state","isManaging","manage","messagesBefore","estimatedTokensBefore","summary","manageResult","triggerAutoManage","error","err","s","contextMessages","summaryContent","totalTokens","importedState","createTruncationSummarizer","maxLength","m","text","createKeyPointsSummarizer","keyPoints","questions","q","createLLMSummarizer","llmCall","options","maxSummaryLength","preserveKeyFacts","conversationText","prompt","DEFAULT_MAX_ENTRIES","DEFAULT_RETENTION_MS","DEFAULT_EXPORT_INTERVAL","GENESIS_PREVIOUS_HASH","generateId","stringToBytes","str","bytesToHex","bytes","b","sha256","hashBuffer","createHashContent","entry","id","timestamp","eventType","previousHash","payload","actorId","sessionId","deepClone","obj","maskPayload","masked","processValue","value","detectPII","itemsToRedact","item","redactPII","processed","k","v","key","createAuditTrail","maxEntries","retentionMs","exportInterval","exporter","piiMasking","signing","events","entries","lastExportIndex","entriesPruned","entriesExported","chainVerified","exportTimer","getLastHash","addEntry","overrides","hashContent","hash","fullEntry","toExport","filter","typeSet","e","expectedHash","prevEntry","since","cutoff","initialLength","pruned","byEventType","prev","changes","c","req","byResolver","resolver","duration","createAgentAuditHandlers","audit","agentName","input","output","tokens","cost","toolName","toolCallId","args","reason","toCSV","data","keys","record","headers","lines","values","createInMemoryComplianceStorage","consents","certificates","subjectId","categories","category","subjectMap","records","count","olderThan","categoryData","ids","idSet","filtered","r","purpose","certificate","createCompliance","storage","retention","exportExpirationMs","consent","existing","request","subjectData","allRecords","auditEntries","checksum","recordsAffected","categoriesAffected","certificateContent","totalDeleted","now","expired","deleted","_subjectId","createStreamChannel","bufferSize","buffer","streamError","consumerWaiter","producerWaiter","hasConsumer","resolveConsumer","waiter","endConsumer","errorConsumer","resolveProducer","resolve","reject","createBidirectionalStream","channelAtoB","channelBtoA","pipeThrough","source","destination","transform","transformed","mergeStreams","sources","doneCount","errorState","stopped","hasWarnedDrop","sourceIterators","notifyWaiter","w","iter","defaultFormatChunk","chunk","_similarity","title","section","url","defaultFormatContext","formattedChunks","_query","clamp","min","max","createRAGEnricher","embedder","defaultTopK","rawMinSimilarity","formatChunk","formatContext","onError","minSimilarity","retrieve","query","topK","queryEmbedding","scored","cosineSimilarity","a","enrich","prefix","history","matches","contextBlock","parts","historyBlock","validateFilePath","filePath","baseDir","resolved","path","resolvedBase","createJSONFileStore","mapEntry","ttlMs","resolvedPath","cached","cachedAt","load","raw","DEFAULT_ERROR_MESSAGE","createSSETransport","maxResponseChars","truncationMessage","heartbeatIntervalMs","errorMessages","extraHeaders","resolveErrorMessage","code","buildStream","agentId","opts","encoder","frame","event","controller","heartbeatTimer","tokenStream","totalChars","sentDone","token","sseHeaders","stream","RetryExhaustedError","retryCount","lastError","NON_RETRYABLE_STATUSES","parseHttpStatus","errObj","match","status","parseRetryAfter","seconds","calculateBackoffDelay","attempt","baseDelayMs","maxDelayMs","exponential","jitter","delay","getRetryDelay","retryAfter","isStatusRetryable","withRetry","maxRetries","isRetryable","onRetry","agent","delayMs","signal","timer","onAbort","AllProvidersFailedError","errors","withFallback","runners","shouldFallback","onFallback","BudgetExceededError","details","CostLedger","windowMs","total","pruneIndex","WINDOW_MS","estimateInputTokens","charsPerToken","calculateCost","usage","pricing","estimateCallCost","inputTokens","outputMultiplier","estimatedOutputTokens","withBudget","maxCostPerCall","budgets","estimatedOutputMultiplier","onBudgetExceeded","budget","windowLedgers","baseLedger","budgetRunner","estimated","spent","remaining","ledger","actualCost","getSpent","window","byInputLength","model","_agent","byAgentName","name","byPattern","pattern","withModelSelection","configOrRules","rules","onModelSelected","selectedModel","rule","effectiveAgent","createBatchQueue","maxBatchSize","maxWaitMs","concurrency","queue","flushTimer","destroyed","flushPromise","scheduleFlush","flushInternal","cancelTimer","executeBatch","batch","index","runNext","current","call","workers","createEmptyStats","createConstraintRouter","providers","defaultProvider","constraints","onProviderSelected","errorCooldownMs","preferCheapest","providerMap","provider","facts","totalLatencyMs","sortedConstraints","selectProvider","constraint","availableProviders","p","stats","sorted","aCost","bCost","recordCall","providerName","latencyMs","statsTotal","routerRunner","startTime","clonedProviders","OtelStatusCode","CollectedSpan","spanId","traceId","parentSpanId","initialAttributes","onEnd","attributes","CollectorTracer","span","createOtelPlugin","instrumentEvents","spanTtlMs","isCollector","collectorTracer","tracer","spanCounter","generateTraceId","activeSpans","keyCounter","spanKeyIndex","patternStack","attachedTimeline","warnedExternalGetSpans","shouldInstrument","type","makeSpanKey","findActiveSpan","indexKey","registerSpan","removeSpan","idx","cleanupStaleSpans","setAttributeTracked","setStatusTracked","endSpan","startSpan","parentEntry","spanToData","addEventTracked","handleEvent","handleAgentStart","handleAgentComplete","handleAgentError","handleGuardrailCheck","handleConstraintEvaluate","handleResolverStart","handleResolverComplete","handleResolverError","handlePatternStart","handlePatternComplete","found","timeline","unsub","cleanupInterval","_key","attachSourcesToOtel","system","serviceName","spanPrefix","publishSampleRate","activeByKey","keyOf","moduleId","commonAttrs","handle","eventName","active","phase","errVal","errorSpan","unobserve"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Middleware composition utility — left-to-right pipeline for AgentRunner wrappers.\n *\n * Each middleware is a function that takes an `AgentRunner` and returns a new\n * `AgentRunner`. `pipe` applies them left to right, so the first middleware\n * in the list wraps the runner first (innermost), and the last wraps last\n * (outermost).\n *\n * @module\n *\n * @example\n * ```typescript\n * import { pipe, withRetry, withFallback, withBudget } from '@directive-run/ai';\n *\n * const runner = pipe(\n * baseRunner,\n * withFallback([anthropicRunner, openaiRunner]),\n * withRetry({ maxRetries: 3 }),\n * withBudget({ budgets: [{ window: 'hour', maxCost: 5, pricing }] }),\n * );\n * ```\n */\n\nimport type { AgentRunner } from \"./types.js\";\n\n/** A function that wraps an AgentRunner, returning a new AgentRunner. */\nexport type RunnerMiddleware = (runner: AgentRunner) => AgentRunner;\n\n/**\n * Compose middleware left-to-right onto a base runner.\n *\n * @param runner - The base `AgentRunner` to wrap.\n * @param middlewares - One or more middleware functions to apply in order.\n * @returns A new `AgentRunner` with all middleware applied.\n */\nexport function pipe(\n runner: AgentRunner,\n ...middlewares: RunnerMiddleware[]\n): AgentRunner {\n let result = runner;\n for (const mw of middlewares) {\n result = mw(result);\n }\n\n return result;\n}\n","/**\n * Agent Memory System\n *\n * Provides sliding window message management and automatic summarization\n * for long-running agent conversations.\n *\n * @example\n * ```typescript\n * import { createAgentMemory, createSlidingWindowStrategy } from '@directive-run/ai';\n *\n * const memory = createAgentMemory({\n * strategy: createSlidingWindowStrategy({ maxMessages: 50 }),\n * summarizer: async (messages) => {\n * // Call LLM to summarize older messages\n * return await summarizeWithLLM(messages);\n * },\n * });\n *\n * // Use with orchestrator\n * const orchestrator = createAgentOrchestrator({\n * memory,\n * runner: run,\n * });\n * ```\n */\n\n// ============================================================================\n// Message Types\n// ============================================================================\n\n/**\n * Memory-compatible message type.\n * Extends the standard Message type to include system messages for summaries.\n */\nexport interface MemoryMessage {\n role: \"user\" | \"assistant\" | \"tool\" | \"system\";\n content: string;\n toolCallId?: string;\n}\n\n// Alias for compatibility\nexport type Message = MemoryMessage;\n\n// ============================================================================\n// Memory Strategy Types\n// ============================================================================\n\n/** Configuration for memory management strategies */\nexport interface MemoryStrategyConfig {\n /** Maximum number of messages to keep in active memory */\n maxMessages?: number;\n /** Maximum total tokens to keep in active memory */\n maxTokens?: number;\n /** Number of recent messages to always keep (protected from summarization) */\n preserveRecentCount?: number;\n /** Whether to include system messages in token count */\n countSystemMessages?: boolean;\n}\n\n/** Result of a memory strategy evaluation */\nexport interface MemoryStrategyResult {\n /** Messages to keep in active memory */\n keep: Message[];\n /** Messages to summarize or discard */\n toSummarize: Message[];\n /** Estimated token count of kept messages */\n estimatedTokens: number;\n}\n\n/** Memory management strategy function */\nexport type MemoryStrategy = (\n messages: Message[],\n config: MemoryStrategyConfig,\n) => MemoryStrategyResult;\n\n/** Summarizer function to compress older messages */\nexport type MessageSummarizer = (messages: Message[]) => Promise<string>;\n\n// ============================================================================\n// Memory Instance Types\n// ============================================================================\n\n/** Agent memory configuration */\nexport interface AgentMemoryConfig {\n /** Memory management strategy */\n strategy: MemoryStrategy;\n /** Optional summarizer for compressing old messages */\n summarizer?: MessageSummarizer;\n /** Strategy configuration */\n strategyConfig?: MemoryStrategyConfig;\n /** Whether to auto-manage memory after each interaction */\n autoManage?: boolean;\n /** Callback when memory is managed */\n onMemoryManaged?: (result: MemoryManageResult) => void;\n /** Callback when auto-manage encounters an error */\n onManageError?: (error: Error) => void;\n /** Maximum context window tokens (triggers additional summarization if exceeded) */\n maxContextTokens?: number;\n}\n\n/** Result of memory management */\nexport interface MemoryManageResult {\n /** Number of messages before management */\n messagesBefore: number;\n /** Number of messages after management */\n messagesAfter: number;\n /** Number of messages summarized */\n messagesSummarized: number;\n /** The summary that was generated (if any) */\n summary?: string;\n /** Estimated tokens before */\n estimatedTokensBefore: number;\n /** Estimated tokens after */\n estimatedTokensAfter: number;\n}\n\n/** Memory state for a conversation */\nexport interface MemoryState {\n /** Active messages in memory */\n messages: Message[];\n /** Summaries of older messages */\n summaries: Array<{\n content: string;\n messagesCount: number;\n createdAt: number;\n }>;\n /** Total messages ever processed */\n totalMessagesProcessed: number;\n /** Estimated current token count */\n estimatedTokens: number;\n}\n\n/** Agent memory instance */\nexport interface AgentMemory {\n /** Get current memory state */\n getState(): MemoryState;\n /** Add a message to memory */\n addMessage(message: Message): void;\n /** Check if memory management is currently in progress */\n isManaging(): boolean;\n /** Add multiple messages to memory */\n addMessages(messages: Message[]): void;\n /** Get messages for context (includes summaries as system messages) */\n getContextMessages(): Message[];\n /** Manually trigger memory management */\n manage(): Promise<MemoryManageResult>;\n /** Clear all memory */\n clear(): void;\n /** Export memory state for persistence */\n export(): MemoryState;\n /** Import memory state from persistence */\n import(state: MemoryState): void;\n}\n\n// ============================================================================\n// Token Estimation\n// ============================================================================\n\n/** Approximate characters per token (default heuristic) */\nconst APPROX_CHARS_PER_TOKEN = 4;\n\n/**\n * Estimate the token count for a single message.\n *\n * Uses a simple heuristic (~4 characters per token) by default.\n * For more accurate counts, pass a custom tokenizer function.\n *\n * @param message - The message to estimate tokens for.\n * @param tokenizer - Optional custom tokenizer function (e.g., tiktoken).\n * @returns The estimated number of tokens.\n *\n * @example\n * ```typescript\n * // Default heuristic\n * const tokens = estimateTokens({ role: 'user', content: 'Hello world' });\n *\n * // Custom tokenizer (e.g., tiktoken)\n * const tokens = estimateTokens(msg, (text) => tiktoken.encode(text).length);\n * ```\n */\nexport function estimateTokens(\n message: Message,\n tokenizer?: (text: string) => number,\n): number {\n const content =\n typeof message.content === \"string\"\n ? message.content\n : JSON.stringify(message.content);\n\n if (tokenizer) {\n return tokenizer(content);\n }\n\n return Math.ceil(content.length / APPROX_CHARS_PER_TOKEN);\n}\n\n/**\n * Estimate the total token count for an array of messages.\n *\n * @param messages - The messages to estimate tokens for.\n * @param tokenizer - Optional custom tokenizer function.\n * @returns The total estimated token count across all messages.\n */\nexport function estimateTotalTokens(\n messages: Message[],\n tokenizer?: (text: string) => number,\n): number {\n return messages.reduce((sum, msg) => sum + estimateTokens(msg, tokenizer), 0);\n}\n\n// ============================================================================\n// Built-in Strategies\n// ============================================================================\n\n/**\n * Create a sliding window memory strategy that keeps the most recent N messages.\n *\n * Messages beyond `maxMessages` are moved to the summarization queue.\n * The most recent `preserveRecentCount` messages are always kept.\n *\n * @param defaultConfig - Default strategy configuration (can be overridden per-call).\n * @returns A {@link MemoryStrategy} function.\n *\n * @example\n * ```typescript\n * const strategy = createSlidingWindowStrategy({\n * maxMessages: 50,\n * preserveRecentCount: 10,\n * });\n * ```\n * @public\n */\nexport function createSlidingWindowStrategy(\n defaultConfig: MemoryStrategyConfig = {},\n): MemoryStrategy {\n return (messages: Message[], configOverride: MemoryStrategyConfig = {}) => {\n const config = { ...defaultConfig, ...configOverride };\n const maxMessages = config.maxMessages ?? 100;\n const preserveRecentCount = config.preserveRecentCount ?? 5;\n\n if (messages.length <= maxMessages) {\n return {\n keep: [...messages],\n toSummarize: [],\n estimatedTokens: estimateTotalTokens(messages),\n };\n }\n\n // Always keep the most recent messages\n const recentMessages = messages.slice(-preserveRecentCount);\n const olderMessages = messages.slice(0, -preserveRecentCount);\n\n // Calculate how many older messages we can keep\n const olderToKeep = Math.max(0, maxMessages - preserveRecentCount);\n const keptOlder = olderMessages.slice(-olderToKeep);\n const toSummarize = olderMessages.slice(0, -olderToKeep || undefined);\n\n const keep = [...keptOlder, ...recentMessages];\n\n return {\n keep,\n toSummarize: toSummarize.length > 0 ? toSummarize : [],\n estimatedTokens: estimateTotalTokens(keep),\n };\n };\n}\n\n/**\n * Create a token-based memory strategy that keeps messages until a token limit is reached.\n *\n * Adds messages from newest to oldest until `maxTokens` would be exceeded,\n * then moves the remaining older messages to the summarization queue.\n *\n * @param defaultConfig - Default strategy configuration (can be overridden per-call).\n * @returns A {@link MemoryStrategy} function.\n *\n * @example\n * ```typescript\n * const strategy = createTokenBasedStrategy({\n * maxTokens: 4000,\n * preserveRecentCount: 5,\n * });\n * ```\n * @public\n */\nexport function createTokenBasedStrategy(\n defaultConfig: MemoryStrategyConfig = {},\n): MemoryStrategy {\n return (messages: Message[], configOverride: MemoryStrategyConfig = {}) => {\n const config = { ...defaultConfig, ...configOverride };\n const maxTokens = config.maxTokens ?? 4000;\n const preserveRecentCount = config.preserveRecentCount ?? 5;\n const countSystemMessages = config.countSystemMessages ?? true;\n\n // Always keep recent messages\n const recentMessages = messages.slice(-preserveRecentCount);\n const olderMessages = messages.slice(0, -preserveRecentCount);\n\n const recentTokens = recentMessages.reduce((sum, msg) => {\n if (!countSystemMessages && msg.role === \"system\") return sum;\n return sum + estimateTokens(msg);\n }, 0);\n\n // Add older messages from newest to oldest until we hit the limit\n const keep: Message[] = [];\n const toSummarize: Message[] = [];\n let currentTokens = recentTokens;\n\n for (let i = olderMessages.length - 1; i >= 0; i--) {\n const msg = olderMessages[i]!; // Safe: i is within bounds\n const msgTokens =\n !countSystemMessages && msg.role === \"system\" ? 0 : estimateTokens(msg);\n\n if (currentTokens + msgTokens <= maxTokens) {\n keep.unshift(msg);\n currentTokens += msgTokens;\n } else {\n // All remaining older messages go to summarization\n toSummarize.push(...olderMessages.slice(0, i + 1));\n break;\n }\n }\n\n return {\n keep: [...keep, ...recentMessages],\n toSummarize,\n estimatedTokens: currentTokens,\n };\n };\n}\n\n/**\n * Create a hybrid strategy that combines message count and token limits.\n *\n * Applies both {@link createSlidingWindowStrategy} and {@link createTokenBasedStrategy},\n * then uses whichever result keeps fewer messages (the more restrictive outcome).\n *\n * @param defaultConfig - Default strategy configuration (can be overridden per-call).\n * @returns A {@link MemoryStrategy} function.\n *\n * @example\n * ```typescript\n * const strategy = createHybridStrategy({\n * maxMessages: 50,\n * maxTokens: 4000,\n * preserveRecentCount: 5,\n * });\n * ```\n * @public\n */\nexport function createHybridStrategy(\n defaultConfig: MemoryStrategyConfig = {},\n): MemoryStrategy {\n const slidingWindow = createSlidingWindowStrategy(defaultConfig);\n const tokenBased = createTokenBasedStrategy(defaultConfig);\n\n return (messages: Message[], configOverride: MemoryStrategyConfig = {}) => {\n const config = { ...defaultConfig, ...configOverride };\n\n // Apply both strategies and use the more restrictive result\n const windowResult = slidingWindow(messages, config);\n const tokenResult = tokenBased(messages, config);\n\n // Use the strategy that keeps fewer messages\n if (windowResult.keep.length <= tokenResult.keep.length) {\n return windowResult;\n }\n return tokenResult;\n };\n}\n\n// ============================================================================\n// Agent Memory Factory\n// ============================================================================\n\n/**\n * Create an agent memory instance for managing conversation history.\n *\n * Provides sliding window management, automatic summarization of older messages,\n * and import/export for persistence. Pass the returned instance to an orchestrator's\n * `memory` option to auto-inject context and auto-store results.\n *\n * @param config - Memory configuration including strategy, optional summarizer, and auto-manage settings.\n * @returns An {@link AgentMemory} instance with `addMessage`, `getContextMessages`, `manage`, and `export`/`import` APIs.\n *\n * @example\n * ```typescript\n * const memory = createAgentMemory({\n * strategy: createSlidingWindowStrategy({ maxMessages: 50 }),\n * summarizer: async (messages) => {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4o-mini',\n * messages: [\n * { role: 'system', content: 'Summarize the following conversation concisely.' },\n * ...messages.map(m => ({ role: m.role, content: m.content })),\n * ],\n * });\n * return response.choices[0].message.content;\n * },\n * autoManage: true,\n * });\n * ```\n * @public\n */\nexport function createAgentMemory(config: AgentMemoryConfig): AgentMemory {\n const {\n strategy,\n summarizer,\n strategyConfig = {},\n autoManage = false,\n onMemoryManaged,\n onManageError,\n maxContextTokens,\n } = config;\n\n let state: MemoryState = {\n messages: [],\n summaries: [],\n totalMessagesProcessed: 0,\n estimatedTokens: 0,\n };\n\n // Flag to prevent concurrent management operations\n let isManaging = false;\n\n async function manage(): Promise<MemoryManageResult> {\n // Prevent concurrent management\n if (isManaging) {\n return {\n messagesBefore: state.messages.length,\n messagesAfter: state.messages.length,\n messagesSummarized: 0,\n estimatedTokensBefore: state.estimatedTokens,\n estimatedTokensAfter: state.estimatedTokens,\n };\n }\n\n isManaging = true;\n\n try {\n const messagesBefore = state.messages.length;\n const estimatedTokensBefore = state.estimatedTokens;\n\n const result = strategy(state.messages, strategyConfig);\n\n if (result.toSummarize.length === 0) {\n return {\n messagesBefore,\n messagesAfter: messagesBefore,\n messagesSummarized: 0,\n estimatedTokensBefore,\n estimatedTokensAfter: result.estimatedTokens,\n };\n }\n\n let summary: string | undefined;\n\n if (summarizer && result.toSummarize.length > 0) {\n summary = await summarizer(result.toSummarize);\n state.summaries.push({\n content: summary,\n messagesCount: result.toSummarize.length,\n createdAt: Date.now(),\n });\n }\n\n state.messages = result.keep;\n state.estimatedTokens = result.estimatedTokens;\n\n const manageResult: MemoryManageResult = {\n messagesBefore,\n messagesAfter: state.messages.length,\n messagesSummarized: result.toSummarize.length,\n summary,\n estimatedTokensBefore,\n estimatedTokensAfter: result.estimatedTokens,\n };\n\n onMemoryManaged?.(manageResult);\n\n return manageResult;\n } finally {\n isManaging = false;\n }\n }\n\n // Safe auto-manage that handles errors properly\n function triggerAutoManage(): void {\n if (isManaging) return;\n\n const check = strategy(state.messages, strategyConfig);\n if (check.toSummarize.length > 0) {\n manage().catch((error) => {\n const err = error instanceof Error ? error : new Error(String(error));\n if (onManageError) {\n onManageError(err);\n } else {\n console.error(\"[Directive Memory] Auto-manage error:\", err);\n }\n });\n }\n }\n\n return {\n getState() {\n return {\n ...state,\n messages: [...state.messages],\n summaries: state.summaries.map((s) => ({ ...s })),\n };\n },\n\n addMessage(message: Message) {\n state.messages.push(message);\n state.totalMessagesProcessed++;\n state.estimatedTokens += estimateTokens(message);\n\n if (autoManage) {\n triggerAutoManage();\n }\n },\n\n addMessages(messages: Message[]) {\n for (const message of messages) {\n state.messages.push(message);\n state.totalMessagesProcessed++;\n state.estimatedTokens += estimateTokens(message);\n }\n\n if (autoManage) {\n triggerAutoManage();\n }\n },\n\n getContextMessages(): Message[] {\n const contextMessages: Message[] = [];\n\n // Add summaries as system messages at the beginning\n if (state.summaries.length > 0) {\n const summaryContent = state.summaries\n .map((s) => s.content)\n .join(\"\\n\\n---\\n\\n\");\n\n contextMessages.push({\n role: \"system\",\n content: `[Previous conversation summary]\\n\\n${summaryContent}`,\n });\n }\n\n // Add current messages\n contextMessages.push(...state.messages);\n\n // Check if context exceeds max tokens and warn\n if (maxContextTokens) {\n const totalTokens = estimateTotalTokens(contextMessages);\n if (totalTokens > maxContextTokens) {\n console.warn(\n `[Directive Memory] Context messages (${totalTokens} tokens) exceed maxContextTokens (${maxContextTokens}). Consider calling manage() or reducing message count.`,\n );\n }\n }\n\n return contextMessages;\n },\n\n manage,\n\n /** Check if memory management is currently in progress */\n isManaging() {\n return isManaging;\n },\n\n clear() {\n state = {\n messages: [],\n summaries: [],\n totalMessagesProcessed: 0,\n estimatedTokens: 0,\n };\n },\n\n export() {\n return {\n ...state,\n messages: [...state.messages],\n summaries: state.summaries.map((s) => ({ ...s })),\n };\n },\n\n import(importedState: MemoryState) {\n state = {\n ...importedState,\n messages: [...importedState.messages],\n summaries: importedState.summaries.map((s) => ({ ...s })),\n };\n },\n };\n}\n\n// ============================================================================\n// Built-in Summarizers\n// ============================================================================\n\n/**\n * Create a simple truncation summarizer that clips messages to a maximum length.\n *\n * Useful for testing or when LLM-based summarization is not needed.\n * Concatenates non-system messages with role prefixes and truncates to `maxLength`.\n *\n * @param maxLength - Maximum character length of the summary (default: 500).\n * @returns A {@link MessageSummarizer} function.\n * @public\n */\nexport function createTruncationSummarizer(maxLength = 500): MessageSummarizer {\n return async (messages: Message[]) => {\n const content = messages\n .filter((m) => m.role !== \"system\")\n .map((m) => {\n const text =\n typeof m.content === \"string\" ? m.content : JSON.stringify(m.content);\n return `${m.role}: ${text.slice(0, 100)}${text.length > 100 ? \"...\" : \"\"}`;\n })\n .join(\"\\n\");\n\n if (content.length <= maxLength) {\n return content;\n }\n\n return `${content.slice(0, maxLength)}\\n[truncated]`;\n };\n}\n\n/**\n * Create a summarizer that extracts user questions from messages.\n *\n * Scans for sentences ending with `?` in user messages and lists them as key topics.\n *\n * @returns A {@link MessageSummarizer} function.\n * @public\n */\nexport function createKeyPointsSummarizer(): MessageSummarizer {\n return async (messages: Message[]) => {\n const keyPoints: string[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"user\") {\n const content =\n typeof msg.content === \"string\"\n ? msg.content\n : JSON.stringify(msg.content);\n // Extract questions (sentences ending with ?)\n const questions = content.match(/[^.!?]*\\?/g);\n if (questions) {\n keyPoints.push(...questions.map((q) => `Q: ${q.trim()}`));\n }\n }\n }\n\n if (keyPoints.length === 0) {\n return `[${messages.length} messages processed - no key questions found]`;\n }\n\n return `Key topics discussed:\\n${keyPoints.join(\"\\n\")}`;\n };\n}\n\n/**\n * Create a summarizer that delegates to an LLM for conversation compression.\n *\n * You provide the LLM call function; this handles prompt construction\n * including length limits and key-fact preservation instructions.\n *\n * @param llmCall - Async function that sends a prompt to an LLM and returns the response text.\n * @param options - Optional `maxSummaryLength` and `preserveKeyFacts` settings.\n * @returns A {@link MessageSummarizer} function.\n *\n * @example\n * ```typescript\n * const summarizer = createLLMSummarizer(async (prompt) => {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4o-mini',\n * messages: [{ role: 'user', content: prompt }],\n * });\n * return response.choices[0].message.content ?? '';\n * });\n * ```\n * @public\n */\nexport function createLLMSummarizer(\n llmCall: (prompt: string) => Promise<string>,\n options: {\n maxSummaryLength?: number;\n preserveKeyFacts?: boolean;\n } = {},\n): MessageSummarizer {\n const { maxSummaryLength = 500, preserveKeyFacts = true } = options;\n\n return async (messages: Message[]) => {\n const conversationText = messages\n .filter((m) => m.role !== \"system\")\n .map((m) => {\n const content =\n typeof m.content === \"string\" ? m.content : JSON.stringify(m.content);\n return `${m.role.toUpperCase()}: ${content}`;\n })\n .join(\"\\n\\n\");\n\n const prompt = `Summarize the following conversation in ${maxSummaryLength} characters or less.\n${preserveKeyFacts ? \"Preserve key facts, decisions, and action items.\" : \"\"}\nFocus on information that would be useful context for continuing the conversation.\n\nCONVERSATION:\n${conversationText}\n\nSUMMARY:`;\n\n return llmCall(prompt);\n };\n}\n","/**\n * Audit Plugin - Immutable Audit Trail with Hash Chain\n *\n * Provides enterprise-grade audit logging with:\n * - Cryptographic hash chain for tamper detection\n * - Bounded storage with FIFO eviction\n * - PII masking with configurable redaction\n * - Optional signing for non-repudiation\n * - Async export to external systems\n *\n * @example\n * ```typescript\n * import { createAuditTrail } from '@directive-run/ai';\n *\n * const audit = createAuditTrail({\n * maxEntries: 10000,\n * retentionMs: 7 * 24 * 60 * 60 * 1000, // 7 days\n * piiMasking: {\n * enabled: true,\n * types: ['ssn', 'credit_card', 'email'],\n * redactionStyle: 'typed',\n * },\n * exporter: async (entries) => {\n * await sendToSIEM(entries);\n * },\n * });\n *\n * const system = createSystem({\n * module: myModule,\n * plugins: [audit.createPlugin()],\n * });\n * ```\n */\n\nimport type { ModuleSchema, Plugin } from \"@directive-run/core\";\nimport type { PIIType, RedactionStyle } from \"../guardrails/pii-enhanced.js\";\nimport { detectPII, redactPII } from \"../guardrails/pii-enhanced.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Audit event types - 22 total covering all system operations */\nexport type AuditEventType =\n // Agent lifecycle\n | \"agent.run.start\"\n | \"agent.run.complete\"\n | \"agent.run.error\"\n // Tool operations\n | \"tool.call.start\"\n | \"tool.call.complete\"\n | \"tool.call.error\"\n // Human-in-the-loop\n | \"approval.requested\"\n | \"approval.granted\"\n | \"approval.denied\"\n // Requirement lifecycle\n | \"requirement.created\"\n | \"requirement.met\"\n // Resolver operations\n | \"resolver.start\"\n | \"resolver.complete\"\n | \"resolver.error\"\n // Fact mutations\n | \"fact.set\"\n | \"fact.batch\"\n // Error handling\n | \"error.occurred\"\n | \"error.recovery\"\n // Checkpoint operations\n | \"checkpoint.save\"\n | \"checkpoint.restore\"\n | \"checkpoint.fork\"\n | \"checkpoint.replay\";\n\n/** Single audit entry with hash chain linking */\nexport interface AuditEntry {\n /** Unique identifier for this entry */\n id: string;\n /** Unix timestamp in milliseconds */\n timestamp: number;\n /** Type of event */\n eventType: AuditEventType;\n /** SHA-256 hash of previous entry (empty string for genesis) */\n previousHash: string;\n /** SHA-256 hash of this entry's content */\n hash: string;\n /** Event payload data */\n payload: Record<string, unknown>;\n /** PII-redacted version of payload (if masking enabled) */\n maskedPayload?: Record<string, unknown>;\n /** Actor identifier (user, agent, or system) */\n actorId?: string;\n /** Session identifier for correlation */\n sessionId?: string;\n /** Cryptographic signature (if signing enabled) */\n signature?: string;\n}\n\n/** Filter options for querying audit entries */\nexport interface AuditEntryFilter {\n /** Filter by event types */\n eventTypes?: AuditEventType[];\n /** Filter by actor ID */\n actorId?: string;\n /** Filter by session ID */\n sessionId?: string;\n /** Start of time range */\n since?: number;\n /** End of time range */\n until?: number;\n /** Maximum entries to return */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n}\n\n/** Result of chain verification */\nexport interface AuditVerificationResult {\n /** Whether the chain is valid */\n valid: boolean;\n /** Number of entries verified */\n entriesVerified: number;\n /** First broken link (if any) */\n brokenAt?: {\n index: number;\n entryId: string;\n expectedHash: string;\n actualHash: string;\n };\n /** Verification timestamp */\n verifiedAt: number;\n}\n\n/** Audit statistics */\nexport interface AuditStats {\n /** Total entries in trail */\n totalEntries: number;\n /** Entries by event type */\n byEventType: Partial<Record<AuditEventType, number>>;\n /** Oldest entry timestamp */\n oldestEntry?: number;\n /** Newest entry timestamp */\n newestEntry?: number;\n /** Number of entries pruned */\n entriesPruned: number;\n /** Number of entries exported */\n entriesExported: number;\n /** Chain integrity (true if verified valid) */\n chainIntegrity: boolean;\n}\n\n/** PII masking configuration */\nexport interface PIIMaskingConfig {\n /** Enable PII masking */\n enabled: boolean;\n /** PII types to detect and mask */\n types: PIIType[];\n /** Redaction style */\n redactionStyle: RedactionStyle;\n /** Custom allowlist (values to skip) */\n allowlist?: string[];\n /** Minimum confidence threshold */\n minConfidence?: number;\n}\n\n/** Signing configuration for non-repudiation */\nexport interface SigningConfig {\n /** Function to sign a hash value */\n signFn: (hash: string) => Promise<string>;\n /** Function to verify a signature */\n verifyFn?: (hash: string, signature: string) => Promise<boolean>;\n}\n\n/** Audit plugin configuration */\nexport interface AuditPluginConfig {\n /** Maximum entries to retain (default: 10000) */\n maxEntries?: number;\n /** Retention period in milliseconds (default: 7 days) */\n retentionMs?: number;\n /** Export interval in milliseconds (default: 60000) */\n exportInterval?: number;\n /** Async exporter function */\n exporter?: (entries: AuditEntry[]) => Promise<void>;\n /** PII masking configuration */\n piiMasking?: PIIMaskingConfig;\n /** Signing configuration for non-repudiation */\n signing?: SigningConfig;\n /** Session ID for all entries */\n sessionId?: string;\n /** Actor ID for all entries */\n actorId?: string;\n /** Event callbacks */\n events?: {\n onEntryAdded?: (entry: AuditEntry) => void;\n onChainBroken?: (result: AuditVerificationResult) => void;\n onExportError?: (error: Error, entries: AuditEntry[]) => void;\n };\n}\n\n/** Audit trail instance */\nexport interface AuditInstance {\n /** Get entries with optional filtering */\n getEntries(filter?: AuditEntryFilter): AuditEntry[];\n /** Verify the integrity of the hash chain */\n verifyChain(): Promise<AuditVerificationResult>;\n /** Export entries since timestamp */\n export(since?: number): Promise<AuditEntry[]>;\n /** Prune old entries based on retention policy */\n prune(): number;\n /** Get audit statistics */\n getStats(): AuditStats;\n /** Destroy the instance (clears timers, flushes exports) */\n destroy(): Promise<void>;\n /** Create a plugin for a directive system */\n createPlugin<M extends ModuleSchema>(): Plugin<M>;\n /** Add a custom audit entry */\n addEntry(\n eventType: AuditEventType,\n payload: Record<string, unknown>,\n ): Promise<AuditEntry>;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Default maximum entries */\nconst DEFAULT_MAX_ENTRIES = 10000;\n\n/** Default retention period (7 days) */\nconst DEFAULT_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;\n\n/** Default export interval (60 seconds) */\nconst DEFAULT_EXPORT_INTERVAL = 60000;\n\n/** Genesis block previous hash */\nconst GENESIS_PREVIOUS_HASH = \"0\".repeat(64);\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/** Generate a unique ID */\nfunction generateId(): string {\n return (\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 11)}`\n );\n}\n\n/** Convert string to Uint8Array */\nfunction stringToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\n/** Convert Uint8Array to hex string */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/** Calculate SHA-256 hash of content */\nasync function sha256(content: string): Promise<string> {\n const bytes = stringToBytes(content);\n const hashBuffer = await globalThis.crypto.subtle.digest(\n \"SHA-256\",\n bytes as unknown as ArrayBuffer,\n );\n return bytesToHex(new Uint8Array(hashBuffer));\n}\n\n/** Create hash content from entry (deterministic serialization) */\nfunction createHashContent(\n entry: Omit<AuditEntry, \"hash\" | \"signature\">,\n): string {\n const {\n id,\n timestamp,\n eventType,\n previousHash,\n payload,\n actorId,\n sessionId,\n } = entry;\n return JSON.stringify({\n id,\n timestamp,\n eventType,\n previousHash,\n payload,\n actorId,\n sessionId,\n });\n}\n\n/** Deep clone an object */\nfunction deepClone<T>(obj: T): T {\n return JSON.parse(JSON.stringify(obj));\n}\n\n/** Mask PII in a payload object */\nasync function maskPayload(\n payload: Record<string, unknown>,\n config: PIIMaskingConfig,\n): Promise<Record<string, unknown>> {\n const masked = deepClone(payload);\n\n // Recursively process all string values\n async function processValue(value: unknown): Promise<unknown> {\n if (typeof value === \"string\") {\n const result = await detectPII(value, {\n types: config.types,\n minConfidence: config.minConfidence ?? 0.7,\n });\n\n if (result.detected) {\n // Filter by allowlist\n const itemsToRedact = config.allowlist\n ? result.items.filter(\n (item) => !config.allowlist!.includes(item.value.toLowerCase()),\n )\n : result.items;\n\n if (itemsToRedact.length > 0) {\n return redactPII(value, itemsToRedact, config.redactionStyle);\n }\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n return Promise.all(value.map(processValue));\n }\n\n if (value && typeof value === \"object\") {\n const processed: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n processed[k] = await processValue(v);\n }\n return processed;\n }\n\n return value;\n }\n\n for (const [key, value] of Object.entries(masked)) {\n masked[key] = await processValue(value);\n }\n\n return masked;\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Create an audit trail instance for enterprise-grade audit logging.\n *\n * Features:\n * - Immutable hash chain for tamper detection\n * - Bounded storage with automatic FIFO eviction\n * - PII masking with configurable redaction styles\n * - Optional cryptographic signing for non-repudiation\n * - Async export to external SIEM/logging systems\n *\n * @example\n * ```typescript\n * const audit = createAuditTrail({\n * maxEntries: 10000,\n * piiMasking: {\n * enabled: true,\n * types: ['ssn', 'credit_card'],\n * redactionStyle: 'typed',\n * },\n * exporter: async (entries) => {\n * await fetch('/api/audit', {\n * method: 'POST',\n * body: JSON.stringify(entries),\n * });\n * },\n * });\n *\n * // Use with directive system\n * const system = createSystem({\n * module: myModule,\n * plugins: [audit.createPlugin()],\n * });\n *\n * // Query audit entries\n * const recentErrors = audit.getEntries({\n * eventTypes: ['error.occurred', 'error.recovery'],\n * since: Date.now() - 3600000, // Last hour\n * });\n *\n * // Verify chain integrity\n * const verification = await audit.verifyChain();\n * if (!verification.valid) {\n * console.error('Audit chain tampered!', verification.brokenAt);\n * }\n * ```\n */\nexport function createAuditTrail(\n config: AuditPluginConfig = {},\n): AuditInstance {\n const {\n maxEntries = DEFAULT_MAX_ENTRIES,\n retentionMs = DEFAULT_RETENTION_MS,\n exportInterval = DEFAULT_EXPORT_INTERVAL,\n exporter,\n piiMasking,\n signing,\n sessionId,\n actorId,\n events = {},\n } = config;\n\n // State\n const entries: AuditEntry[] = [];\n let lastExportIndex = 0;\n let entriesPruned = 0;\n let entriesExported = 0;\n let chainVerified = true;\n let exportTimer: ReturnType<typeof setInterval> | undefined;\n\n // Get the hash of the last entry (or genesis hash)\n function getLastHash(): string {\n if (entries.length === 0) {\n return GENESIS_PREVIOUS_HASH;\n }\n return entries[entries.length - 1]!.hash;\n }\n\n // Add a new entry to the trail\n async function addEntry(\n eventType: AuditEventType,\n payload: Record<string, unknown>,\n overrides?: { actorId?: string; sessionId?: string },\n ): Promise<AuditEntry> {\n const entry: Omit<AuditEntry, \"hash\" | \"signature\"> = {\n id: generateId(),\n timestamp: Date.now(),\n eventType,\n previousHash: getLastHash(),\n payload,\n actorId: overrides?.actorId ?? actorId,\n sessionId: overrides?.sessionId ?? sessionId,\n };\n\n // Apply PII masking if enabled\n if (piiMasking?.enabled) {\n entry.maskedPayload = await maskPayload(payload, piiMasking);\n }\n\n // Calculate hash\n const hashContent = createHashContent(entry);\n const hash = await sha256(hashContent);\n\n const fullEntry: AuditEntry = {\n ...entry,\n hash,\n };\n\n // Apply signing if configured\n if (signing) {\n fullEntry.signature = await signing.signFn(hash);\n }\n\n // Add to trail\n entries.push(fullEntry);\n\n // Enforce max entries (FIFO eviction)\n while (entries.length > maxEntries) {\n entries.shift();\n entriesPruned++;\n // Adjust export index if entries were evicted\n if (lastExportIndex > 0) {\n lastExportIndex--;\n }\n }\n\n events.onEntryAdded?.(fullEntry);\n\n return fullEntry;\n }\n\n // Start export timer if configured\n if (exporter && exportInterval > 0) {\n exportTimer = setInterval(async () => {\n try {\n const toExport = entries.slice(lastExportIndex);\n if (toExport.length > 0) {\n await exporter(toExport);\n entriesExported += toExport.length;\n lastExportIndex = entries.length;\n }\n } catch (error) {\n events.onExportError?.(\n error instanceof Error ? error : new Error(String(error)),\n entries.slice(lastExportIndex),\n );\n }\n }, exportInterval);\n }\n\n return {\n getEntries(filter?: AuditEntryFilter): AuditEntry[] {\n let result = [...entries];\n\n if (filter) {\n if (filter.eventTypes?.length) {\n const typeSet = new Set(filter.eventTypes);\n result = result.filter((e) => typeSet.has(e.eventType));\n }\n\n if (filter.actorId) {\n result = result.filter((e) => e.actorId === filter.actorId);\n }\n\n if (filter.sessionId) {\n result = result.filter((e) => e.sessionId === filter.sessionId);\n }\n\n if (filter.since !== undefined) {\n result = result.filter((e) => e.timestamp >= filter.since!);\n }\n\n if (filter.until !== undefined) {\n result = result.filter((e) => e.timestamp <= filter.until!);\n }\n\n if (filter.offset !== undefined) {\n result = result.slice(filter.offset);\n }\n\n if (filter.limit !== undefined) {\n result = result.slice(0, filter.limit);\n }\n }\n\n return result;\n },\n\n async verifyChain(): Promise<AuditVerificationResult> {\n if (entries.length === 0) {\n return {\n valid: true,\n entriesVerified: 0,\n verifiedAt: Date.now(),\n };\n }\n\n // Verify first entry links to genesis\n const firstEntry = entries[0]!;\n if (firstEntry.previousHash !== GENESIS_PREVIOUS_HASH) {\n // First entry doesn't link to genesis - this could happen after pruning\n // We verify the chain is internally consistent instead\n }\n\n // Verify each entry's hash and link\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i]!;\n\n // Recalculate hash\n const hashContent = createHashContent({\n id: entry.id,\n timestamp: entry.timestamp,\n eventType: entry.eventType,\n previousHash: entry.previousHash,\n payload: entry.payload,\n actorId: entry.actorId,\n sessionId: entry.sessionId,\n });\n const expectedHash = await sha256(hashContent);\n\n if (entry.hash !== expectedHash) {\n chainVerified = false;\n const result: AuditVerificationResult = {\n valid: false,\n entriesVerified: i,\n brokenAt: {\n index: i,\n entryId: entry.id,\n expectedHash,\n actualHash: entry.hash,\n },\n verifiedAt: Date.now(),\n };\n events.onChainBroken?.(result);\n return result;\n }\n\n // Verify chain linkage (except for first entry after pruning)\n if (i > 0) {\n const prevEntry = entries[i - 1]!;\n if (entry.previousHash !== prevEntry.hash) {\n chainVerified = false;\n const result: AuditVerificationResult = {\n valid: false,\n entriesVerified: i,\n brokenAt: {\n index: i,\n entryId: entry.id,\n expectedHash: prevEntry.hash,\n actualHash: entry.previousHash,\n },\n verifiedAt: Date.now(),\n };\n events.onChainBroken?.(result);\n return result;\n }\n }\n\n // Verify signature if signing is configured\n if (signing?.verifyFn && entry.signature) {\n const signatureValid = await signing.verifyFn(\n entry.hash,\n entry.signature,\n );\n if (!signatureValid) {\n chainVerified = false;\n const result: AuditVerificationResult = {\n valid: false,\n entriesVerified: i,\n brokenAt: {\n index: i,\n entryId: entry.id,\n expectedHash: \"signature-invalid\",\n actualHash: entry.signature,\n },\n verifiedAt: Date.now(),\n };\n events.onChainBroken?.(result);\n return result;\n }\n }\n }\n\n chainVerified = true;\n return {\n valid: true,\n entriesVerified: entries.length,\n verifiedAt: Date.now(),\n };\n },\n\n async export(since?: number): Promise<AuditEntry[]> {\n let toExport = [...entries];\n\n if (since !== undefined) {\n toExport = toExport.filter((e) => e.timestamp >= since);\n }\n\n if (exporter && toExport.length > 0) {\n await exporter(toExport);\n entriesExported += toExport.length;\n }\n\n return toExport;\n },\n\n prune(): number {\n const cutoff = Date.now() - retentionMs;\n const initialLength = entries.length;\n\n // Remove entries older than retention period\n while (entries.length > 0 && entries[0]!.timestamp < cutoff) {\n entries.shift();\n if (lastExportIndex > 0) {\n lastExportIndex--;\n }\n }\n\n const pruned = initialLength - entries.length;\n entriesPruned += pruned;\n return pruned;\n },\n\n getStats(): AuditStats {\n const byEventType: Partial<Record<AuditEventType, number>> = {};\n\n for (const entry of entries) {\n byEventType[entry.eventType] = (byEventType[entry.eventType] ?? 0) + 1;\n }\n\n return {\n totalEntries: entries.length,\n byEventType,\n oldestEntry: entries[0]?.timestamp,\n newestEntry: entries[entries.length - 1]?.timestamp,\n entriesPruned,\n entriesExported,\n chainIntegrity: chainVerified,\n };\n },\n\n async destroy(): Promise<void> {\n // Clear export timer\n if (exportTimer) {\n clearInterval(exportTimer);\n exportTimer = undefined;\n }\n\n // Flush remaining entries to exporter\n if (exporter) {\n try {\n const toExport = entries.slice(lastExportIndex);\n if (toExport.length > 0) {\n await exporter(toExport);\n entriesExported += toExport.length;\n }\n } catch (error) {\n events.onExportError?.(\n error instanceof Error ? error : new Error(String(error)),\n entries.slice(lastExportIndex),\n );\n }\n }\n },\n\n addEntry(\n eventType: AuditEventType,\n payload: Record<string, unknown>,\n ): Promise<AuditEntry> {\n return addEntry(eventType, payload);\n },\n\n createPlugin<M extends ModuleSchema>(): Plugin<M> {\n return {\n name: \"audit-trail\",\n\n // Fact operations\n onFactSet: (key, value, prev) => {\n addEntry(\"fact.set\", { key, value, prev }).catch(console.error);\n },\n\n onFactsBatch: (changes) => {\n addEntry(\"fact.batch\", {\n changes: changes.map((c) => ({\n key: c.key,\n value: c.value,\n prev: c.prev,\n })),\n }).catch(console.error);\n },\n\n // Requirement lifecycle\n onRequirementCreated: (req) => {\n addEntry(\"requirement.created\", {\n id: req.id,\n type: req.requirement.type,\n payload: req.requirement,\n }).catch(console.error);\n },\n\n onRequirementMet: (req, byResolver) => {\n addEntry(\"requirement.met\", {\n id: req.id,\n type: req.requirement.type,\n byResolver,\n }).catch(console.error);\n },\n\n // Resolver operations\n onResolverStart: (resolver, req) => {\n addEntry(\"resolver.start\", {\n resolver,\n requirementId: req.id,\n requirementType: req.requirement.type,\n }).catch(console.error);\n },\n\n onResolverComplete: (resolver, req, duration) => {\n addEntry(\"resolver.complete\", {\n resolver,\n requirementId: req.id,\n requirementType: req.requirement.type,\n duration,\n }).catch(console.error);\n },\n\n onResolverError: (resolver, req, error) => {\n addEntry(\"resolver.error\", {\n resolver,\n requirementId: req.id,\n requirementType: req.requirement.type,\n error: error instanceof Error ? error.message : String(error),\n }).catch(console.error);\n },\n\n // Error handling\n onError: (error) => {\n addEntry(\"error.occurred\", {\n source: error.source,\n sourceId: error.sourceId,\n message: error.message,\n context: error.context,\n }).catch(console.error);\n },\n\n onErrorRecovery: (error, strategy) => {\n addEntry(\"error.recovery\", {\n source: error.source,\n message: error.message,\n strategy,\n }).catch(console.error);\n },\n };\n },\n };\n}\n\n// ============================================================================\n// Agent Orchestrator Integration\n// ============================================================================\n\n/**\n * Create audit event handlers for agent orchestrator integration.\n * Use this to audit agent operations when using the agent orchestrator.\n *\n * @example\n * ```typescript\n * const audit = createAuditTrail({ ... });\n * const handlers = createAgentAuditHandlers(audit);\n *\n * // Use in orchestrator callbacks\n * orchestrator.run(agent, input, {\n * onStart: handlers.onAgentStart,\n * onComplete: handlers.onAgentComplete,\n * // ...\n * });\n * ```\n */\nexport function createAgentAuditHandlers(audit: AuditInstance) {\n return {\n onAgentStart: (agentName: string, input: string) => {\n audit.addEntry(\"agent.run.start\", { agentName, input });\n },\n\n onAgentComplete: (\n agentName: string,\n output: unknown,\n tokens: number,\n cost: number,\n ) => {\n audit.addEntry(\"agent.run.complete\", { agentName, output, tokens, cost });\n },\n\n onAgentError: (agentName: string, error: Error) => {\n audit.addEntry(\"agent.run.error\", {\n agentName,\n error: error.message,\n stack: error.stack,\n });\n },\n\n onToolStart: (toolName: string, toolCallId: string, args: unknown) => {\n audit.addEntry(\"tool.call.start\", { toolName, toolCallId, args });\n },\n\n onToolComplete: (toolName: string, toolCallId: string, result: unknown) => {\n audit.addEntry(\"tool.call.complete\", { toolName, toolCallId, result });\n },\n\n onToolError: (toolName: string, toolCallId: string, error: Error) => {\n audit.addEntry(\"tool.call.error\", {\n toolName,\n toolCallId,\n error: error.message,\n });\n },\n\n onApprovalRequested: (\n toolName: string,\n toolCallId: string,\n args: unknown,\n ) => {\n audit.addEntry(\"approval.requested\", { toolName, toolCallId, args });\n },\n\n onApprovalGranted: (toolName: string, toolCallId: string) => {\n audit.addEntry(\"approval.granted\", { toolName, toolCallId });\n },\n\n onApprovalDenied: (\n toolName: string,\n toolCallId: string,\n reason?: string,\n ) => {\n audit.addEntry(\"approval.denied\", { toolName, toolCallId, reason });\n },\n };\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport {\n createAuditTrail as create,\n createAgentAuditHandlers as createHandlers,\n};\n","/**\n * Compliance Plugin - GDPR/CCPA Data Subject Rights\n *\n * Provides enterprise-grade compliance features:\n * - Data Export (DSR) - Export all data for a subject\n * - Data Deletion - Soft/hard delete with certificates\n * - Consent Tracking - Track and enforce consent\n * - Retention Policies - Automatic data retention enforcement\n *\n * @example\n * ```typescript\n * import { createCompliance } from '@directive-run/ai';\n *\n * const compliance = createCompliance({\n * storage: myStorageAdapter,\n * retention: {\n * defaultRetentionMs: 365 * 24 * 60 * 60 * 1000, // 1 year\n * categoryRetention: {\n * audit: 7 * 365 * 24 * 60 * 60 * 1000, // 7 years for audit\n * sessions: 30 * 24 * 60 * 60 * 1000, // 30 days for sessions\n * },\n * },\n * });\n *\n * // Handle data subject request\n * const exportResult = await compliance.exportData({\n * subjectId: 'user-123',\n * format: 'json',\n * includeAudit: true,\n * });\n *\n * // Delete user data\n * const deleteResult = await compliance.deleteData({\n * subjectId: 'user-123',\n * scope: 'all',\n * });\n * ```\n */\n\nimport type {\n GuardrailFn,\n GuardrailResult,\n InputGuardrailData,\n} from \"../types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Data export request (GDPR Article 20) */\nexport interface DataExportRequest {\n /** Subject identifier (user ID) */\n subjectId: string;\n /** Export format */\n format: \"json\" | \"csv\";\n /** Include audit trail entries */\n includeAudit?: boolean;\n /** Include derived data */\n includeDerived?: boolean;\n /** Specific data categories to export */\n categories?: string[];\n /** Request metadata */\n metadata?: Record<string, unknown>;\n}\n\n/** Result of data export */\nexport interface DataExportResult {\n /** Whether export was successful */\n success: boolean;\n /** Subject identifier */\n subjectId: string;\n /** Export format used */\n format: \"json\" | \"csv\";\n /** Exported data */\n data: string;\n /** Data categories included */\n categories: string[];\n /** Number of records exported */\n recordCount: number;\n /** SHA-256 checksum of exported data */\n checksum: string;\n /** Export timestamp */\n exportedAt: number;\n /** Expiration timestamp for download link (if applicable) */\n expiresAt?: number;\n /** Error message if failed */\n error?: string;\n}\n\n/** Data deletion scope */\nexport type DeletionScope = \"all\" | \"facts\" | \"audit\" | \"specific\";\n\n/** Data deletion request (GDPR Article 17) */\nexport interface DataDeletionRequest {\n /** Subject identifier (user ID) */\n subjectId: string;\n /** Scope of deletion */\n scope: DeletionScope;\n /** Anonymize instead of delete (retain structure, remove PII) */\n anonymize?: boolean;\n /** Specific data categories to delete (when scope is 'specific') */\n categories?: string[];\n /** Reason for deletion */\n reason?: string;\n /** Request metadata */\n metadata?: Record<string, unknown>;\n}\n\n/** Result of data deletion */\nexport interface DataDeletionResult {\n /** Whether deletion was successful */\n success: boolean;\n /** Subject identifier */\n subjectId: string;\n /** Scope of deletion performed */\n scope: DeletionScope;\n /** Whether data was anonymized vs deleted */\n anonymized: boolean;\n /** Number of records deleted/anonymized */\n recordsAffected: number;\n /** Data categories affected */\n categoriesAffected: string[];\n /** Deletion certificate (for compliance records) */\n certificate: DeletionCertificate;\n /** Deletion timestamp */\n deletedAt: number;\n /** Error message if failed */\n error?: string;\n}\n\n/** Deletion certificate for compliance records */\nexport interface DeletionCertificate {\n /** Certificate ID */\n id: string;\n /** Subject identifier */\n subjectId: string;\n /** Type of deletion */\n type: \"soft\" | \"hard\" | \"anonymization\";\n /** Scope of deletion */\n scope: DeletionScope;\n /** Categories deleted */\n categories: string[];\n /** Record count */\n recordCount: number;\n /** Deletion timestamp */\n deletedAt: number;\n /** Reason for deletion */\n reason?: string;\n /** SHA-256 hash of certificate content */\n hash: string;\n}\n\n/** Consent record for a subject */\nexport interface ConsentRecord {\n /** Subject identifier */\n subjectId: string;\n /** Consent purpose (e.g., 'marketing', 'analytics', 'personalization') */\n purpose: string;\n /** Whether consent is granted */\n granted: boolean;\n /** When consent was granted (if granted) */\n grantedAt?: number;\n /** When consent expires (if applicable) */\n expiresAt?: number;\n /** When consent was revoked (if revoked) */\n revokedAt?: number;\n /** Source of consent (e.g., 'signup_form', 'settings_page') */\n source?: string;\n /** Consent version/hash (for tracking which T&C version was accepted) */\n version?: string;\n}\n\n/** Consent tracker interface */\nexport interface ConsentTracker {\n /** Record consent grant */\n grant(\n subjectId: string,\n purpose: string,\n options?: {\n expiresAt?: number;\n source?: string;\n version?: string;\n },\n ): Promise<ConsentRecord>;\n /** Revoke consent */\n revoke(subjectId: string, purpose: string): Promise<ConsentRecord | null>;\n /** Check if consent is granted */\n check(subjectId: string, purpose: string): Promise<boolean>;\n /** Get all consents for a subject */\n getForSubject(subjectId: string): Promise<ConsentRecord[]>;\n /** Get all subjects with consent for a purpose */\n getForPurpose(purpose: string): Promise<ConsentRecord[]>;\n}\n\n/** Retention policy */\nexport interface RetentionPolicy {\n /** Policy name */\n name: string;\n /** Default retention period in milliseconds */\n defaultRetentionMs: number;\n /** Category-specific retention periods */\n categoryRetention?: Record<string, number>;\n /** Callback before data is deleted */\n onBeforeDelete?: (data: { category: string; count: number }) => Promise<void>;\n /** Callback after data is deleted */\n onAfterDelete?: (data: { category: string; count: number }) => void;\n}\n\n/** Storage adapter for compliance data */\nexport interface ComplianceStorage {\n /** Get all data for a subject */\n getSubjectData(\n subjectId: string,\n categories?: string[],\n ): Promise<\n {\n category: string;\n records: Array<{\n id: string;\n data: Record<string, unknown>;\n createdAt: number;\n }>;\n }[]\n >;\n /** Delete data for a subject */\n deleteSubjectData(subjectId: string, categories?: string[]): Promise<number>;\n /** Anonymize data for a subject */\n anonymizeSubjectData(\n subjectId: string,\n categories?: string[],\n ): Promise<number>;\n /** Get audit entries for a subject */\n getAuditEntries?(subjectId: string): Promise<\n Array<{\n id: string;\n timestamp: number;\n eventType: string;\n payload: Record<string, unknown>;\n }>\n >;\n /** Get data older than timestamp by category */\n getExpiredData(\n category: string,\n olderThan: number,\n ): Promise<Array<{ id: string; createdAt: number }>>;\n /** Delete records by IDs */\n deleteByIds(ids: string[]): Promise<number>;\n /** Store consent record */\n storeConsent(record: ConsentRecord): Promise<void>;\n /** Get consent record */\n getConsent(subjectId: string, purpose: string): Promise<ConsentRecord | null>;\n /** Get consents by subject */\n getConsentsBySubject(subjectId: string): Promise<ConsentRecord[]>;\n /** Get consents by purpose */\n getConsentsByPurpose(purpose: string): Promise<ConsentRecord[]>;\n /** Store deletion certificate */\n storeDeletionCertificate(certificate: DeletionCertificate): Promise<void>;\n}\n\n/** Compliance configuration */\nexport interface ComplianceConfig {\n /** Storage adapter */\n storage: ComplianceStorage;\n /** Retention policy */\n retention?: RetentionPolicy;\n /** Consent purposes to track */\n consentPurposes?: string[];\n /** Export link expiration (default: 24 hours) */\n exportExpirationMs?: number;\n /** Audit all compliance operations */\n auditOperations?: boolean;\n /** Event callbacks */\n events?: {\n onExport?: (result: DataExportResult) => void;\n onDelete?: (result: DataDeletionResult) => void;\n onConsentChange?: (record: ConsentRecord) => void;\n onRetentionEnforced?: (category: string, count: number) => void;\n };\n}\n\n/** Compliance instance */\nexport interface ComplianceInstance {\n /** Export data for a subject (GDPR Article 20) */\n exportData(request: DataExportRequest): Promise<DataExportResult>;\n /** Delete data for a subject (GDPR Article 17) */\n deleteData(request: DataDeletionRequest): Promise<DataDeletionResult>;\n /** Consent tracker */\n consent: ConsentTracker;\n /** Enforce retention policy */\n enforceRetention(): Promise<number>;\n /** Create a guardrail that checks consent before processing */\n createConsentGuardrail(purpose: string): GuardrailFn<InputGuardrailData>;\n /** Get deletion certificate by ID */\n getDeletionCertificate(\n subjectId: string,\n ): Promise<DeletionCertificate | null>;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Default export link expiration (24 hours) */\nconst DEFAULT_EXPORT_EXPIRATION_MS = 24 * 60 * 60 * 1000;\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/** Generate a unique ID */\nfunction generateId(): string {\n return (\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 11)}`\n );\n}\n\n/** Convert string to Uint8Array */\nfunction stringToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\n/** Convert Uint8Array to hex string */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/** Calculate SHA-256 hash of content */\nasync function sha256(content: string): Promise<string> {\n const bytes = stringToBytes(content);\n const hashBuffer = await globalThis.crypto.subtle.digest(\n \"SHA-256\",\n bytes as unknown as ArrayBuffer,\n );\n return bytesToHex(new Uint8Array(hashBuffer));\n}\n\n/** Convert data to CSV format */\nfunction toCSV(data: Record<string, unknown>[]): string {\n if (data.length === 0) return \"\";\n\n // Get all unique keys\n const keys = new Set<string>();\n for (const record of data) {\n for (const key of Object.keys(record)) {\n keys.add(key);\n }\n }\n\n const headers = Array.from(keys);\n\n // Build CSV\n const lines: string[] = [headers.join(\",\")];\n\n for (const record of data) {\n const values = headers.map((key) => {\n const value = record[key];\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"object\")\n return JSON.stringify(value).replace(/\"/g, '\"\"');\n const str = String(value);\n // Escape quotes and wrap in quotes if contains comma or newline\n if (str.includes(\",\") || str.includes(\"\\n\") || str.includes('\"')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n return str;\n });\n lines.push(values.join(\",\"));\n }\n\n return lines.join(\"\\n\");\n}\n\n// ============================================================================\n// In-Memory Storage (for testing/development)\n// ============================================================================\n\n/** Create an in-memory compliance storage adapter */\nexport function createInMemoryComplianceStorage(): ComplianceStorage {\n const data = new Map<\n string,\n Map<\n string,\n Array<{\n id: string;\n data: Record<string, unknown>;\n createdAt: number;\n }>\n >\n >();\n const consents = new Map<string, ConsentRecord>();\n const certificates = new Map<string, DeletionCertificate>();\n\n return {\n async getSubjectData(subjectId, categories) {\n const result: Array<{\n category: string;\n records: Array<{\n id: string;\n data: Record<string, unknown>;\n createdAt: number;\n }>;\n }> = [];\n\n for (const [category, subjectMap] of data) {\n if (categories && !categories.includes(category)) continue;\n\n const records = subjectMap.get(subjectId);\n if (records && records.length > 0) {\n result.push({ category, records: [...records] });\n }\n }\n\n return result;\n },\n\n async deleteSubjectData(subjectId, categories) {\n let count = 0;\n\n for (const [category, subjectMap] of data) {\n if (categories && !categories.includes(category)) continue;\n\n const records = subjectMap.get(subjectId);\n if (records) {\n count += records.length;\n subjectMap.delete(subjectId);\n }\n }\n\n return count;\n },\n\n async anonymizeSubjectData(subjectId, categories) {\n let count = 0;\n\n for (const [category, subjectMap] of data) {\n if (categories && !categories.includes(category)) continue;\n\n const records = subjectMap.get(subjectId);\n if (records) {\n for (const record of records) {\n // Replace PII with anonymized values\n record.data = {\n ...record.data,\n _anonymized: true,\n _anonymizedAt: Date.now(),\n };\n count++;\n }\n }\n }\n\n return count;\n },\n\n async getExpiredData(category, olderThan) {\n const result: Array<{ id: string; createdAt: number }> = [];\n const categoryData = data.get(category);\n\n if (categoryData) {\n for (const records of categoryData.values()) {\n for (const record of records) {\n if (record.createdAt < olderThan) {\n result.push({ id: record.id, createdAt: record.createdAt });\n }\n }\n }\n }\n\n return result;\n },\n\n async deleteByIds(ids) {\n const idSet = new Set(ids);\n let count = 0;\n\n for (const categoryData of data.values()) {\n for (const [subjectId, records] of categoryData) {\n const filtered = records.filter((r) => !idSet.has(r.id));\n if (filtered.length !== records.length) {\n count += records.length - filtered.length;\n if (filtered.length === 0) {\n categoryData.delete(subjectId);\n } else {\n categoryData.set(subjectId, filtered);\n }\n }\n }\n }\n\n return count;\n },\n\n async storeConsent(record) {\n consents.set(`${record.subjectId}:${record.purpose}`, record);\n },\n\n async getConsent(subjectId, purpose) {\n return consents.get(`${subjectId}:${purpose}`) ?? null;\n },\n\n async getConsentsBySubject(subjectId) {\n const result: ConsentRecord[] = [];\n for (const [key, record] of consents) {\n if (key.startsWith(`${subjectId}:`)) {\n result.push(record);\n }\n }\n return result;\n },\n\n async getConsentsByPurpose(purpose) {\n const result: ConsentRecord[] = [];\n for (const [key, record] of consents) {\n if (key.endsWith(`:${purpose}`)) {\n result.push(record);\n }\n }\n return result;\n },\n\n async storeDeletionCertificate(certificate) {\n certificates.set(certificate.subjectId, certificate);\n },\n };\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Create a compliance instance for GDPR/CCPA data subject rights.\n *\n * Features:\n * - Data Export (GDPR Article 20) - Portable data export\n * - Data Deletion (GDPR Article 17) - Right to erasure\n * - Consent Tracking - Track and verify consent\n * - Retention Policies - Automatic data retention\n *\n * @example\n * ```typescript\n * const compliance = createCompliance({\n * storage: myStorageAdapter,\n * retention: {\n * name: 'default',\n * defaultRetentionMs: 365 * 24 * 60 * 60 * 1000, // 1 year\n * categoryRetention: {\n * audit: 7 * 365 * 24 * 60 * 60 * 1000, // 7 years\n * },\n * },\n * consentPurposes: ['marketing', 'analytics', 'personalization'],\n * });\n *\n * // Export user data\n * const exportResult = await compliance.exportData({\n * subjectId: 'user-123',\n * format: 'json',\n * });\n *\n * // Check consent\n * const hasConsent = await compliance.consent.check('user-123', 'marketing');\n * ```\n */\nexport function createCompliance(config: ComplianceConfig): ComplianceInstance {\n const {\n storage,\n retention,\n exportExpirationMs = DEFAULT_EXPORT_EXPIRATION_MS,\n events = {},\n } = config;\n\n // Consent tracker implementation\n const consent: ConsentTracker = {\n async grant(subjectId, purpose, options = {}) {\n const record: ConsentRecord = {\n subjectId,\n purpose,\n granted: true,\n grantedAt: Date.now(),\n expiresAt: options.expiresAt,\n source: options.source,\n version: options.version,\n };\n\n await storage.storeConsent(record);\n events.onConsentChange?.(record);\n\n return record;\n },\n\n async revoke(subjectId, purpose) {\n const existing = await storage.getConsent(subjectId, purpose);\n if (!existing) return null;\n\n const record: ConsentRecord = {\n ...existing,\n granted: false,\n revokedAt: Date.now(),\n };\n\n await storage.storeConsent(record);\n events.onConsentChange?.(record);\n\n return record;\n },\n\n async check(subjectId, purpose) {\n const record = await storage.getConsent(subjectId, purpose);\n if (!record) return false;\n if (!record.granted) return false;\n if (record.expiresAt && record.expiresAt < Date.now()) return false;\n return true;\n },\n\n async getForSubject(subjectId) {\n return storage.getConsentsBySubject(subjectId);\n },\n\n async getForPurpose(purpose) {\n return storage.getConsentsByPurpose(purpose);\n },\n };\n\n return {\n async exportData(request) {\n try {\n const subjectData = await storage.getSubjectData(\n request.subjectId,\n request.categories,\n );\n\n // Flatten records for export\n const allRecords: Array<{\n category: string;\n id: string;\n data: Record<string, unknown>;\n createdAt: number;\n }> = [];\n\n const categories: string[] = [];\n\n for (const { category, records } of subjectData) {\n categories.push(category);\n for (const record of records) {\n allRecords.push({ category, ...record });\n }\n }\n\n // Include audit entries if requested\n if (request.includeAudit && storage.getAuditEntries) {\n const auditEntries = await storage.getAuditEntries(request.subjectId);\n categories.push(\"audit\");\n for (const entry of auditEntries) {\n allRecords.push({\n category: \"audit\",\n id: entry.id,\n data: entry.payload,\n createdAt: entry.timestamp,\n });\n }\n }\n\n // Format data\n let data: string;\n if (request.format === \"csv\") {\n data = toCSV(\n allRecords.map((r) => ({\n category: r.category,\n id: r.id,\n createdAt: new Date(r.createdAt).toISOString(),\n ...r.data,\n })),\n );\n } else {\n data = JSON.stringify(\n {\n subjectId: request.subjectId,\n exportedAt: new Date().toISOString(),\n recordCount: allRecords.length,\n categories,\n records: allRecords,\n },\n null,\n 2,\n );\n }\n\n // Calculate checksum\n const checksum = await sha256(data);\n\n const result: DataExportResult = {\n success: true,\n subjectId: request.subjectId,\n format: request.format,\n data,\n categories,\n recordCount: allRecords.length,\n checksum,\n exportedAt: Date.now(),\n expiresAt: Date.now() + exportExpirationMs,\n };\n\n events.onExport?.(result);\n return result;\n } catch (error) {\n return {\n success: false,\n subjectId: request.subjectId,\n format: request.format,\n data: \"\",\n categories: [],\n recordCount: 0,\n checksum: \"\",\n exportedAt: Date.now(),\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n\n async deleteData(request) {\n try {\n let recordsAffected = 0;\n const categoriesAffected: string[] = [];\n\n if (request.anonymize) {\n recordsAffected = await storage.anonymizeSubjectData(\n request.subjectId,\n request.categories,\n );\n } else {\n recordsAffected = await storage.deleteSubjectData(\n request.subjectId,\n request.categories,\n );\n }\n\n // Track affected categories\n if (request.categories) {\n categoriesAffected.push(...request.categories);\n } else if (request.scope === \"all\") {\n categoriesAffected.push(\"all\");\n }\n\n // Create deletion certificate\n const certificateContent = JSON.stringify({\n subjectId: request.subjectId,\n type: request.anonymize ? \"anonymization\" : \"hard\",\n scope: request.scope,\n categories: categoriesAffected,\n recordCount: recordsAffected,\n deletedAt: Date.now(),\n reason: request.reason,\n });\n\n const certificate: DeletionCertificate = {\n id: generateId(),\n subjectId: request.subjectId,\n type: request.anonymize ? \"anonymization\" : \"hard\",\n scope: request.scope,\n categories: categoriesAffected,\n recordCount: recordsAffected,\n deletedAt: Date.now(),\n reason: request.reason,\n hash: await sha256(certificateContent),\n };\n\n await storage.storeDeletionCertificate(certificate);\n\n const result: DataDeletionResult = {\n success: true,\n subjectId: request.subjectId,\n scope: request.scope,\n anonymized: request.anonymize ?? false,\n recordsAffected,\n categoriesAffected,\n certificate,\n deletedAt: Date.now(),\n };\n\n events.onDelete?.(result);\n return result;\n } catch (error) {\n return {\n success: false,\n subjectId: request.subjectId,\n scope: request.scope,\n anonymized: request.anonymize ?? false,\n recordsAffected: 0,\n categoriesAffected: [],\n certificate: {\n id: \"error\",\n subjectId: request.subjectId,\n type: \"hard\",\n scope: request.scope,\n categories: [],\n recordCount: 0,\n deletedAt: Date.now(),\n hash: \"\",\n },\n deletedAt: Date.now(),\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n\n consent,\n\n async enforceRetention() {\n if (!retention) return 0;\n\n let totalDeleted = 0;\n const now = Date.now();\n\n // Get all categories to check\n const categories = new Set<string>();\n if (retention.categoryRetention) {\n for (const category of Object.keys(retention.categoryRetention)) {\n categories.add(category);\n }\n }\n\n // Default category for anything not specified\n categories.add(\"default\");\n\n for (const category of categories) {\n const retentionMs =\n retention.categoryRetention?.[category] ??\n retention.defaultRetentionMs;\n const cutoff = now - retentionMs;\n\n const expired = await storage.getExpiredData(category, cutoff);\n\n if (expired.length > 0) {\n await retention.onBeforeDelete?.({ category, count: expired.length });\n\n const deleted = await storage.deleteByIds(expired.map((e) => e.id));\n totalDeleted += deleted;\n\n retention.onAfterDelete?.({ category, count: deleted });\n events.onRetentionEnforced?.(category, deleted);\n }\n }\n\n return totalDeleted;\n },\n\n createConsentGuardrail(purpose: string): GuardrailFn<InputGuardrailData> {\n return async (data): Promise<GuardrailResult> => {\n // Extract subject ID from input or context\n // This is a simple implementation - in practice you'd extract from context\n const subjectIdMatch = data.input.match(\n /user[_-]?id[:\\s]*([a-zA-Z0-9-]+)/i,\n );\n const subjectId = subjectIdMatch?.[1];\n\n if (!subjectId) {\n // No subject ID found - allow (fail open) or block (fail closed)\n // Default to fail open for better UX\n return { passed: true };\n }\n\n const hasConsent = await consent.check(subjectId, purpose);\n\n if (!hasConsent) {\n return {\n passed: false,\n reason: `No consent for '${purpose}' from subject ${subjectId}`,\n };\n }\n\n return { passed: true };\n };\n },\n\n async getDeletionCertificate(_subjectId) {\n // This would need to be implemented in the storage adapter\n // For now, return null as the interface doesn't expose get\n return null;\n },\n };\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport {\n createCompliance as create,\n createInMemoryComplianceStorage as createInMemoryStorage,\n};\n","/**\n * Streaming Channel for Agent-to-Agent Communication\n *\n * Provides AsyncIterable-based streaming for large data transfers between agents.\n * Supports backpressure, buffering, and graceful termination.\n *\n * @example\n * ```typescript\n * import { createStreamChannel } from '@directive-run/ai';\n *\n * // Producer side\n * const channel = createStreamChannel<string>({ bufferSize: 100 });\n *\n * // Send data\n * await channel.send('chunk 1');\n * await channel.send('chunk 2');\n * channel.end(); // Signal completion\n *\n * // Consumer side (async iteration)\n * for await (const chunk of channel) {\n * console.log(chunk);\n * }\n * ```\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Stream channel configuration */\nexport interface StreamChannelConfig {\n /** Maximum buffer size before backpressure is applied (default: 100) */\n bufferSize?: number;\n /** Channel name for debugging */\n name?: string;\n}\n\n/** Stream channel state */\nexport type StreamChannelState = \"open\" | \"closed\" | \"error\";\n\n/** Stream channel instance */\nexport interface StreamChannel<T> extends AsyncIterable<T> {\n /** Send a value to the channel. Resolves when consumed or buffered. */\n send(value: T): Promise<void>;\n /** Signal that no more values will be sent */\n end(): void;\n /** Signal an error and terminate the stream */\n error(err: Error): void;\n /** Get the current state */\n getState(): StreamChannelState;\n /** Get the number of buffered items */\n bufferedCount(): number;\n}\n\n/** Bidirectional stream between two agents */\nexport interface BidirectionalStream<TSend, TReceive> {\n /** Send a value to the remote end */\n send(value: TSend): Promise<void>;\n /** Iterate over received values */\n receive: AsyncIterable<TReceive>;\n /** Close both directions */\n close(): void;\n}\n\n// ============================================================================\n// Stream Channel Factory\n// ============================================================================\n\n/**\n * Create a stream channel for async data transfer.\n *\n * Implements proper backpressure: `send()` will pause when the buffer is full\n * and resume when the consumer catches up.\n *\n * @example\n * ```typescript\n * const channel = createStreamChannel<{ token: string }>();\n *\n * // Producer (e.g., LLM streaming response)\n * (async () => {\n * for (const token of tokens) {\n * await channel.send({ token });\n * }\n * channel.end();\n * })();\n *\n * // Consumer (e.g., downstream agent)\n * for await (const chunk of channel) {\n * process.stdout.write(chunk.token);\n * }\n * ```\n */\nexport function createStreamChannel<T>(\n config: StreamChannelConfig = {},\n): StreamChannel<T> {\n const { bufferSize = 100 } = config;\n\n if (bufferSize < 1 || !Number.isFinite(bufferSize)) {\n throw new Error(\n `[Directive StreamChannel] bufferSize must be >= 1, got ${bufferSize}`,\n );\n }\n\n const buffer: T[] = [];\n let state: StreamChannelState = \"open\";\n let streamError: Error | null = null;\n\n // Waiters for the consumer (when buffer is empty, consumer waits)\n let consumerWaiter: {\n resolve: (value: IteratorResult<T>) => void;\n reject: (err: Error) => void;\n } | null = null;\n\n // Waiters for the producer (when buffer is full, producer waits)\n let producerWaiter: (() => void) | null = null;\n\n // Single-consumer guard\n let hasConsumer = false;\n\n function resolveConsumer(value: T): void {\n if (consumerWaiter) {\n const waiter = consumerWaiter;\n consumerWaiter = null;\n waiter.resolve({ value, done: false });\n }\n }\n\n function endConsumer(): void {\n if (consumerWaiter) {\n const waiter = consumerWaiter;\n consumerWaiter = null;\n waiter.resolve({ value: undefined as unknown as T, done: true });\n }\n }\n\n function errorConsumer(err: Error): void {\n if (consumerWaiter) {\n const waiter = consumerWaiter;\n consumerWaiter = null;\n hasConsumer = false;\n waiter.reject(err);\n }\n }\n\n function resolveProducer(): void {\n if (producerWaiter) {\n const waiter = producerWaiter;\n producerWaiter = null;\n waiter();\n }\n }\n\n const channel: StreamChannel<T> = {\n async send(value: T): Promise<void> {\n if (state !== \"open\") {\n throw new Error(\n `[Directive StreamChannel] Cannot send to ${state} channel${config.name ? ` \"${config.name}\"` : \"\"}`,\n );\n }\n\n // If consumer is waiting, deliver directly\n if (consumerWaiter) {\n resolveConsumer(value);\n return;\n }\n\n // Apply backpressure if buffer is full (wait before adding)\n if (buffer.length >= bufferSize) {\n await new Promise<void>((resolve) => {\n producerWaiter = resolve;\n });\n // Re-check state after backpressure wait\n if (state !== \"open\") {\n throw new Error(\n `[Directive StreamChannel] Cannot send to ${state} channel${config.name ? ` \"${config.name}\"` : \"\"}`,\n );\n }\n // If consumer became available during wait, deliver directly\n if (consumerWaiter) {\n resolveConsumer(value);\n return;\n }\n }\n\n // Buffer the value\n buffer.push(value);\n },\n\n end(): void {\n if (state !== \"open\") return;\n state = \"closed\";\n endConsumer();\n },\n\n error(err: Error): void {\n if (state !== \"open\") return;\n state = \"error\";\n streamError = err;\n errorConsumer(err);\n resolveProducer(); // Unblock any waiting producer\n },\n\n getState(): StreamChannelState {\n return state;\n },\n\n bufferedCount(): number {\n return buffer.length;\n },\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n if (hasConsumer) {\n throw new Error(\n \"[Directive StreamChannel] Channel only supports a single consumer. \" +\n \"Create a separate channel for each consumer.\",\n );\n }\n hasConsumer = true;\n\n return {\n next(): Promise<IteratorResult<T>> {\n // Check for error\n if (state === \"error\" && streamError) {\n hasConsumer = false;\n return Promise.reject(streamError);\n }\n\n // Check buffer first\n if (buffer.length > 0) {\n const value = buffer.shift()!;\n resolveProducer(); // Unblock producer if waiting\n return Promise.resolve({ value, done: false });\n }\n\n // Check if stream is closed\n if (state === \"closed\") {\n hasConsumer = false;\n return Promise.resolve({\n value: undefined as unknown as T,\n done: true,\n });\n }\n\n // Wait for next value\n return new Promise((resolve, reject) => {\n consumerWaiter = { resolve, reject };\n });\n },\n\n return(): Promise<IteratorResult<T>> {\n state = \"closed\";\n buffer.length = 0;\n hasConsumer = false;\n resolveProducer();\n return Promise.resolve({\n value: undefined as unknown as T,\n done: true,\n });\n },\n };\n },\n };\n\n return channel;\n}\n\n// ============================================================================\n// Bidirectional Stream\n// ============================================================================\n\n/**\n * Create a bidirectional stream channel for two-way communication between agents.\n *\n * @example\n * ```typescript\n * const { sideA, sideB } = createBidirectionalStream<string, string>();\n *\n * // Agent A sends and receives\n * await sideA.send('question?');\n * for await (const reply of sideA.receive) {\n * console.log('A got:', reply);\n * }\n *\n * // Agent B receives and responds\n * for await (const msg of sideB.receive) {\n * await sideB.send(`reply to: ${msg}`);\n * }\n * ```\n */\nexport function createBidirectionalStream<TA, TB>(\n config?: StreamChannelConfig,\n): { sideA: BidirectionalStream<TA, TB>; sideB: BidirectionalStream<TB, TA> } {\n const channelAtoB = createStreamChannel<TA>(config);\n const channelBtoA = createStreamChannel<TB>(config);\n\n return {\n sideA: {\n send: (value: TA) => channelAtoB.send(value),\n receive: channelBtoA,\n close() {\n channelAtoB.end();\n channelBtoA.end();\n },\n },\n sideB: {\n send: (value: TB) => channelBtoA.send(value),\n receive: channelAtoB,\n close() {\n channelAtoB.end();\n channelBtoA.end();\n },\n },\n };\n}\n\n// ============================================================================\n// Stream Utilities\n// ============================================================================\n\n/**\n * Pipe one stream channel through a transform function into another.\n *\n * @example\n * ```typescript\n * const input = createStreamChannel<string>();\n * const output = createStreamChannel<number>();\n *\n * pipeThrough(input, output, (chunk) => chunk.length);\n * ```\n */\nexport async function pipeThrough<TIn, TOut>(\n source: AsyncIterable<TIn>,\n destination: StreamChannel<TOut>,\n transform: (value: TIn) => TOut | Promise<TOut>,\n): Promise<void> {\n try {\n for await (const value of source) {\n const transformed = await transform(value);\n await destination.send(transformed);\n }\n destination.end();\n } catch (error) {\n destination.error(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n}\n\n/**\n * Merge multiple async iterables into a single stream.\n * Values are emitted as soon as they arrive from any source.\n *\n * Note: The internal buffer is capped at 10,000 items. Values exceeding this\n * limit are dropped. For high-throughput scenarios, ensure the consumer keeps up\n * or use bounded `StreamChannel` sources.\n *\n * @example\n * ```typescript\n * const merged = mergeStreams(channel1, channel2, channel3);\n * for await (const value of merged) {\n * console.log(value);\n * }\n * ```\n */\nexport function mergeStreams<T>(\n ...sources: AsyncIterable<T>[]\n): AsyncIterable<T> {\n const MAX_BUFFER = 10000;\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<T> {\n const buffer: T[] = [];\n let doneCount = 0;\n let waiter: ((value: IteratorResult<T>) => void) | null = null;\n let errorState: Error | null = null;\n let stopped = false;\n let hasWarnedDrop = false;\n const sourceIterators: AsyncIterator<T>[] = [];\n\n function notifyWaiter(result: IteratorResult<T>): boolean {\n if (waiter) {\n const w = waiter;\n waiter = null;\n w(result);\n return true;\n }\n return false;\n }\n\n // Start consuming all sources\n for (const source of sources) {\n const iter = source[Symbol.asyncIterator]();\n sourceIterators.push(iter);\n (async () => {\n try {\n while (!stopped) {\n const result = await iter.next();\n if (result.done || stopped) break;\n if (!notifyWaiter({ value: result.value, done: false })) {\n if (buffer.length < MAX_BUFFER) {\n buffer.push(result.value);\n } else if (!hasWarnedDrop) {\n hasWarnedDrop = true;\n console.warn(\n `[Directive mergeStreams] Buffer exceeded ${MAX_BUFFER} items. Values are being dropped. Ensure the consumer keeps up or use bounded StreamChannel sources.`,\n );\n }\n }\n }\n } catch (error) {\n if (!stopped) {\n stopped = true;\n errorState =\n error instanceof Error ? error : new Error(String(error));\n notifyWaiter({ value: undefined as unknown as T, done: true });\n }\n }\n doneCount++;\n if (doneCount >= sources.length && !stopped) {\n notifyWaiter({ value: undefined as unknown as T, done: true });\n }\n })();\n }\n\n return {\n next(): Promise<IteratorResult<T>> {\n if (errorState) {\n return Promise.reject(errorState);\n }\n\n if (buffer.length > 0) {\n return Promise.resolve({ value: buffer.shift()!, done: false });\n }\n\n if (doneCount >= sources.length) {\n return Promise.resolve({\n value: undefined as unknown as T,\n done: true,\n });\n }\n\n return new Promise((resolve) => {\n waiter = resolve;\n });\n },\n\n return(): Promise<IteratorResult<T>> {\n stopped = true;\n buffer.length = 0;\n for (const iter of sourceIterators) {\n iter.return?.({ value: undefined as unknown as T, done: true });\n }\n if (waiter) {\n const w = waiter;\n waiter = null;\n w({ value: undefined as unknown as T, done: true });\n }\n return Promise.resolve({\n value: undefined as unknown as T,\n done: true,\n });\n },\n };\n },\n };\n}\n","/**\n * RAG Enricher — Composable retrieval-augmented generation pipeline.\n *\n * Embeds a query, searches a chunk store by cosine similarity, and assembles\n * an enriched input string (context + history + query) for any agent.\n *\n * @example\n * ```typescript\n * import {\n * createRAGEnricher,\n * createJSONFileStore,\n * } from '@directive-run/ai';\n *\n * const enricher = createRAGEnricher({\n * embedder: myEmbedder, // Provide your own EmbedderFn\n * storage: createJSONFileStore({ filePath: './embeddings.json' }),\n * });\n *\n * const enrichedInput = await enricher.enrich('How do constraints work?', {\n * prefix: 'User is viewing: /docs/constraints',\n * history: [{ role: 'user', content: 'Hello' }],\n * });\n * ```\n */\n\nimport path from \"node:path\";\nimport { cosineSimilarity } from \"./guardrails/semantic-cache.js\";\nimport type { EmbedderFn, Embedding } from \"./guardrails/semantic-cache.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** A document chunk with embedding and metadata */\nexport interface RAGChunk {\n id: string;\n content: string;\n embedding: Embedding;\n metadata: Record<string, unknown>;\n}\n\n/** Pluggable storage backend */\nexport interface RAGStorage {\n getChunks(): Promise<RAGChunk[]>;\n size(): Promise<number>;\n /** Optional: optimized vector search (bypasses full getChunks scan) */\n search?(\n query: Embedding,\n topK: number,\n minSimilarity: number,\n ): Promise<Array<RAGChunk & { similarity: number }>>;\n /** Reload storage (clear cache, re-read from source) */\n reload?(): Promise<void>;\n /** Destroy and release resources */\n destroy?(): void;\n}\n\nexport interface RAGEnricherConfig {\n /** Function to generate query embeddings */\n embedder: EmbedderFn;\n /** Storage backend for document chunks */\n storage: RAGStorage;\n /** Number of top results to return (default: 5) */\n topK?: number;\n /** Minimum similarity score to include, clamped to [0, 1] (default: 0.3) */\n minSimilarity?: number;\n /** Custom chunk formatter */\n formatChunk?: (chunk: RAGChunk, similarity: number) => string;\n /** Custom context block formatter */\n formatContext?: (formattedChunks: string[], query: string) => string;\n /** Error callback — embedder/storage errors are non-fatal by default */\n onError?: (error: Error) => void;\n}\n\nexport interface RAGEnrichOptions {\n /** Prefix line (e.g. \"User is viewing: /docs/constraints\") */\n prefix?: string;\n /** Conversation history */\n history?: Array<{ role: string; content: string }>;\n /** Per-call topK override */\n topK?: number;\n /** Filter chunks before ranking (e.g. by metadata tag or section) */\n filter?: (chunk: RAGChunk) => boolean;\n}\n\nexport interface RAGEnricher {\n /** Retrieve relevant chunks for a query */\n retrieve(\n query: string,\n topK?: number,\n ): Promise<Array<RAGChunk & { similarity: number }>>;\n /** Retrieve + format into an enriched input string */\n enrich(input: string, options?: RAGEnrichOptions): Promise<string>;\n}\n\n// ============================================================================\n// Default Formatters\n// ============================================================================\n\nfunction defaultFormatChunk(chunk: RAGChunk, _similarity: number): string {\n const title = (chunk.metadata.title as string) ?? \"\";\n const section = (chunk.metadata.section as string) ?? \"\";\n const url = (chunk.metadata.url as string) ?? \"\";\n const header =\n title && section && url\n ? `[${title} — ${section}](${url})`\n : title\n ? title\n : chunk.id;\n return `${header}\\n${chunk.content}`;\n}\n\nfunction defaultFormatContext(\n formattedChunks: string[],\n _query: string,\n): string {\n if (formattedChunks.length === 0) return \"\";\n return `Relevant documentation context:\\n\\n${formattedChunks.join(\"\\n\\n\")}`;\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/** Clamp a number to [min, max]. */\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\n/**\n * Create a RAG enricher that retrieves relevant document chunks and\n * assembles enriched input for an agent.\n */\nexport function createRAGEnricher(config: RAGEnricherConfig): RAGEnricher {\n const {\n embedder,\n storage,\n topK: defaultTopK = 5,\n minSimilarity: rawMinSimilarity = 0.3,\n formatChunk = defaultFormatChunk,\n formatContext = defaultFormatContext,\n onError,\n } = config;\n\n const minSimilarity = clamp(rawMinSimilarity, 0, 1);\n\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV === \"development\" &&\n rawMinSimilarity !== minSimilarity\n ) {\n console.warn(\n `[Directive] RAG: minSimilarity ${rawMinSimilarity} clamped to ${minSimilarity} (valid range: 0-1)`,\n );\n }\n\n async function retrieve(\n query: string,\n topK?: number,\n ): Promise<Array<RAGChunk & { similarity: number }>> {\n const k = Math.max(1, Math.floor(topK ?? defaultTopK));\n\n // Use optimized search() if the storage backend provides it\n if (storage.search) {\n return storage.search(await embedder(query), k, minSimilarity);\n }\n\n const queryEmbedding = await embedder(query);\n const chunks = await storage.getChunks();\n\n const scored = chunks.map((chunk) => ({\n ...chunk,\n similarity: cosineSimilarity(queryEmbedding, chunk.embedding),\n }));\n\n scored.sort((a, b) => b.similarity - a.similarity);\n\n return scored.filter((c) => c.similarity >= minSimilarity).slice(0, k);\n }\n\n async function enrich(\n input: string,\n options: RAGEnrichOptions = {},\n ): Promise<string> {\n const { prefix, history, topK, filter } = options;\n\n let matches: Array<RAGChunk & { similarity: number }> = [];\n try {\n matches = await retrieve(input, topK);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error(String(err)));\n }\n\n if (filter) {\n matches = matches.filter((m) => filter(m));\n }\n\n const formattedChunks = matches.map((m) => formatChunk(m, m.similarity));\n const contextBlock = formatContext(formattedChunks, input);\n\n const parts: string[] = [];\n if (prefix) parts.push(prefix);\n if (contextBlock) parts.push(contextBlock);\n if (history && history.length > 0) {\n const historyBlock = history\n .map(\n (m) =>\n `${m.role.charAt(0).toUpperCase() + m.role.slice(1)}: ${m.content}`,\n )\n .join(\"\\n\\n\");\n parts.push(`Previous conversation:\\n${historyBlock}`);\n }\n parts.push(input);\n\n return parts.join(\"\\n\\n---\\n\\n\");\n }\n\n return { retrieve, enrich };\n}\n\n// ============================================================================\n// Built-in Storage: JSON File Store\n// ============================================================================\n\nexport interface JSONFileStoreOptions {\n /** Absolute or relative path to the JSON embeddings file */\n filePath: string;\n /** Optional transform from raw JSON entries to RAGChunk */\n mapEntry?: (entry: Record<string, unknown>) => RAGChunk;\n /** Cache TTL in ms. 0 = cache forever (default) */\n ttlMs?: number;\n /** Base directory to confine file access. Resolved paths must start with this. */\n baseDir?: string;\n}\n\n/**\n * Validate that a file path does not escape the allowed directory.\n * Resolves the path, rejects `..` segments, and (if baseDir is provided)\n * ensures the resolved path is inside the base directory.\n */\nfunction validateFilePath(filePath: string, baseDir?: string): string {\n const resolved = path.resolve(filePath);\n\n // Defense in depth: reject paths that still contain \"..\" after resolution\n const segments = resolved.split(path.sep);\n if (segments.includes(\"..\")) {\n throw new Error(\n `[Directive] File path escapes allowed directory: ${filePath}`,\n );\n }\n\n if (baseDir) {\n const resolvedBase = path.resolve(baseDir) + path.sep;\n if (\n !resolved.startsWith(resolvedBase) &&\n resolved !== resolvedBase.slice(0, -1)\n ) {\n throw new Error(\n `[Directive] File path escapes allowed directory: ${filePath}`,\n );\n }\n }\n\n return resolved;\n}\n\n/**\n * Create a RAGStorage backed by a JSON file (lazy-loaded, cached in memory).\n * Uses dynamic `import('node:fs')` for isomorphic safety.\n */\nexport function createJSONFileStore(options: JSONFileStoreOptions): RAGStorage {\n const { filePath, mapEntry, ttlMs = 0, baseDir } = options;\n const resolvedPath = validateFilePath(filePath, baseDir);\n let cached: RAGChunk[] | null = null;\n let cachedAt = 0;\n\n async function load(): Promise<RAGChunk[]> {\n if (cached && (ttlMs === 0 || Date.now() - cachedAt < ttlMs)) {\n return cached;\n }\n\n try {\n const fs = await import(\"node:fs\");\n const data = await fs.promises.readFile(resolvedPath, \"utf-8\");\n const raw = JSON.parse(data) as Record<string, unknown>[];\n\n cached = mapEntry ? raw.map(mapEntry) : (raw as unknown as RAGChunk[]);\n\n cachedAt = Date.now();\n return cached;\n } catch (err) {\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV === \"development\"\n ) {\n console.warn(\n `[Directive] JSONFileStore: failed to load ${resolvedPath}:`,\n err,\n );\n }\n cached = [];\n cachedAt = Date.now();\n return cached;\n }\n }\n\n return {\n async getChunks() {\n return load();\n },\n async size() {\n const chunks = await load();\n return chunks.length;\n },\n async reload() {\n cached = null;\n cachedAt = 0;\n await load();\n },\n destroy() {\n cached = null;\n cachedAt = 0;\n },\n };\n}\n","/**\n * SSE Transport — Wrap a streamable source into an HTTP Server-Sent Events\n * response.\n *\n * Framework-agnostic: uses the WinterCG `Response` constructor (Node 18+,\n * Deno, Bun, Cloudflare Workers, Next.js).\n *\n * @example\n * ```typescript\n * import {\n * createSSETransport,\n * createAgentOrchestrator,\n * createStreamingRunner,\n * } from '@directive-run/ai';\n *\n * const transport = createSSETransport({\n * maxResponseChars: 10_000,\n * errorMessages: {\n * INPUT_GUARDRAIL_FAILED: 'Your message was flagged by our safety filter.',\n * },\n * });\n *\n * // Next.js route handler\n * export async function POST(req: Request) {\n * const { message } = await req.json();\n * return transport.toResponse(streamable, 'docs-qa', message);\n * }\n * ```\n */\n\n// ============================================================================\n// Structural types — describe only what SSE transport actually needs\n// ============================================================================\n\n/** Async iterable of string tokens with result promise and abort */\ninterface SSETokenStream extends AsyncIterable<string> {\n result: Promise<unknown>;\n abort(): void;\n}\n\n/** Any object with a .stream() method compatible with SSE transport */\ninterface SSEStreamable {\n stream(\n agentId: string,\n input: string,\n opts?: { signal?: AbortSignal },\n ): SSETokenStream;\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type SSEEvent =\n | { type: \"text\"; text: string }\n | { type: \"truncated\"; text: string }\n | { type: \"done\" }\n | { type: \"error\"; message: string }\n | { type: \"heartbeat\"; timestamp: number };\n\nexport interface SSETransportConfig {\n /** Truncate response after this many characters (default: Infinity) */\n maxResponseChars?: number;\n /** Message shown when response is truncated */\n truncationMessage?: string;\n /** Heartbeat interval in ms (default: 0 = disabled) */\n heartbeatIntervalMs?: number;\n /** Map error codes/types to user-facing messages */\n errorMessages?: Record<string, string> | ((error: unknown) => string);\n /** Extra headers merged into the SSE response */\n headers?: Record<string, string>;\n}\n\nexport interface SSETransport {\n /** Create a full HTTP Response with SSE headers */\n toResponse(\n source: SSEStreamable,\n agentId: string,\n input: string,\n opts?: { signal?: AbortSignal },\n ): Response;\n /** Return just the ReadableStream (for Express/Koa `res.write()`) */\n toStream(\n source: SSEStreamable,\n agentId: string,\n input: string,\n opts?: { signal?: AbortSignal },\n ): ReadableStream<Uint8Array>;\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nconst DEFAULT_ERROR_MESSAGE =\n \"AI service temporarily unavailable. Please try again.\";\n\n/**\n * Create an SSE transport that converts a token stream into Server-Sent Events.\n */\nexport function createSSETransport(\n config: SSETransportConfig = {},\n): SSETransport {\n const {\n maxResponseChars = Number.POSITIVE_INFINITY,\n truncationMessage = \"\\n\\n*[Response truncated]*\",\n heartbeatIntervalMs = 0,\n errorMessages,\n headers: extraHeaders,\n } = config;\n\n if (maxResponseChars < 0) {\n throw new RangeError(\"maxResponseChars must be non-negative\");\n }\n if (heartbeatIntervalMs < 0) {\n throw new RangeError(\"heartbeatIntervalMs must be non-negative\");\n }\n\n function resolveErrorMessage(error: unknown): string {\n if (typeof errorMessages === \"function\") {\n try {\n return errorMessages(error);\n } catch {\n return DEFAULT_ERROR_MESSAGE;\n }\n }\n if (errorMessages && typeof errorMessages === \"object\") {\n const code =\n error != null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n typeof (error as { code: unknown }).code === \"string\"\n ? (error as { code: string }).code\n : undefined;\n if (code && code in errorMessages) {\n return errorMessages[code]!;\n }\n }\n return DEFAULT_ERROR_MESSAGE;\n }\n\n function buildStream(\n source: SSEStreamable,\n agentId: string,\n input: string,\n opts?: { signal?: AbortSignal },\n ): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n function frame(event: SSEEvent): Uint8Array {\n return encoder.encode(`data: ${JSON.stringify(event)}\\n\\n`);\n }\n\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n let heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n let tokenStream: SSETokenStream | null = null;\n\n try {\n // Heartbeat\n if (heartbeatIntervalMs > 0) {\n heartbeatTimer = setInterval(() => {\n try {\n controller.enqueue(\n frame({ type: \"heartbeat\", timestamp: Date.now() }),\n );\n } catch {\n // Controller may be closed\n }\n }, heartbeatIntervalMs);\n }\n\n tokenStream = source.stream(agentId, input, {\n signal: opts?.signal,\n });\n\n let totalChars = 0;\n let sentDone = false;\n\n for await (const token of tokenStream) {\n totalChars += token.length;\n\n if (totalChars > maxResponseChars) {\n controller.enqueue(\n frame({ type: \"truncated\", text: truncationMessage }),\n );\n controller.enqueue(frame({ type: \"done\" }));\n sentDone = true;\n tokenStream.abort();\n break;\n }\n\n controller.enqueue(frame({ type: \"text\", text: token }));\n }\n\n // Wait for final result (tracks tokens, metrics, etc.)\n try {\n await tokenStream.result;\n } catch {\n // May have been aborted due to truncation\n }\n\n if (!sentDone) {\n controller.enqueue(frame({ type: \"done\" }));\n }\n } catch (err: unknown) {\n const message = resolveErrorMessage(err);\n controller.enqueue(frame({ type: \"error\", message }));\n } finally {\n if (heartbeatTimer) clearInterval(heartbeatTimer);\n controller.close();\n }\n },\n });\n }\n\n const sseHeaders: Record<string, string> = {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n ...extraHeaders,\n };\n\n return {\n toResponse(source, agentId, input, opts) {\n const stream = buildStream(source, agentId, input, opts);\n return new Response(stream, { headers: sseHeaders });\n },\n toStream(source, agentId, input, opts) {\n return buildStream(source, agentId, input, opts);\n },\n };\n}\n","/**\n * P2: Intelligent Retry — HTTP-status-aware retry wrapper for AgentRunner.\n *\n * Respects 429 Retry-After headers, uses exponential backoff with jitter for 503,\n * and never retries client errors (400/401/403/404/422).\n *\n * @module\n *\n * @example\n * ```typescript\n * import { withRetry, RetryExhaustedError } from '@directive-run/ai';\n *\n * const runner = withRetry(baseRunner, {\n * maxRetries: 3,\n * baseDelayMs: 1000,\n * maxDelayMs: 30000,\n * onRetry: (attempt, error, delayMs) => {\n * console.log(`Retry ${attempt} in ${delayMs}ms: ${error.message}`);\n * },\n * });\n *\n * try {\n * const result = await runner(agent, input);\n * } catch (err) {\n * if (err instanceof RetryExhaustedError) {\n * console.error(`All ${err.retryCount} retries failed:`, err.lastError);\n * }\n * }\n * ```\n */\n\nimport type { AgentLike, AgentRunner, RunOptions, RunResult } from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Configuration for the intelligent retry wrapper.\n *\n * @example\n * ```typescript\n * const config: RetryConfig = {\n * maxRetries: 3,\n * baseDelayMs: 1000,\n * maxDelayMs: 30000,\n * isRetryable: (error) => !error.message.includes(\"invalid API key\"),\n * onRetry: (attempt, error, delayMs) => {\n * console.log(`Retry ${attempt} after ${delayMs}ms: ${error.message}`);\n * },\n * };\n * ```\n */\nexport interface RetryConfig {\n /** Maximum number of retry attempts (not counting the initial call). @default 3 */\n maxRetries?: number;\n /** Base delay in ms for exponential backoff. @default 1000 */\n baseDelayMs?: number;\n /** Maximum delay in ms (caps exponential growth). @default 30000 */\n maxDelayMs?: number;\n /** Custom predicate — return `false` to skip retry for specific errors. Called after the built-in HTTP status check. */\n isRetryable?: (error: Error) => boolean;\n /** Called before each retry wait. Useful for logging or metrics. */\n onRetry?: (attempt: number, error: Error, delayMs: number) => void;\n}\n\n/** Error enriched with retry metadata, thrown when all retries are exhausted. */\nexport class RetryExhaustedError extends Error {\n readonly retryCount: number;\n readonly lastError: Error;\n\n constructor(retryCount: number, lastError: Error) {\n super(\n `[Directive] All ${retryCount} retries exhausted: ${lastError.message}`,\n );\n this.name = \"RetryExhaustedError\";\n this.retryCount = retryCount;\n this.lastError = lastError;\n this.cause = lastError;\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** HTTP status codes that should never be retried. */\nconst NON_RETRYABLE_STATUSES = new Set([400, 401, 403, 404, 422]);\n\n/**\n * Extract HTTP status code from error message or error properties.\n *\n * Checks `error.status` / `error.statusCode` properties first, then falls back\n * to matching common error message patterns like \"request failed: 429\" or \"HTTP 503\".\n */\nexport function parseHttpStatus(error: Error): number | null {\n // Check error properties first (many HTTP libraries set these)\n const errObj = error as unknown as Record<string, unknown>;\n if (\n typeof errObj.status === \"number\" &&\n errObj.status >= 100 &&\n errObj.status <= 599\n ) {\n return errObj.status;\n }\n if (\n typeof errObj.statusCode === \"number\" &&\n errObj.statusCode >= 100 &&\n errObj.statusCode <= 599\n ) {\n return errObj.statusCode;\n }\n\n // Match common error message patterns:\n // \"request failed: 429\", \"HTTP 503\", \"status 401\", \"Error 400\"\n // Guard against scanning very large error messages (ReDoS protection)\n const msg =\n error.message.length > 1000 ? error.message.slice(0, 1000) : error.message;\n const match = msg.match(/(?:failed|error|status|http)[:\\s]+(\\d{3})\\b/i);\n if (!match) {\n return null;\n }\n\n const status = Number(match[1]);\n if (status >= 100 && status <= 599) {\n return status;\n }\n\n return null;\n}\n\n/**\n * Extract Retry-After value (in ms) from error message.\n *\n * Per HTTP spec, `Retry-After` numeric values are always in seconds.\n * Returns the value converted to milliseconds.\n */\nexport function parseRetryAfter(error: Error): number | null {\n // Check error properties first (many HTTP libraries set these)\n const errObj = error as unknown as Record<string, unknown>;\n if (typeof errObj.retryAfter === \"number\" && errObj.retryAfter > 0) {\n return errObj.retryAfter * 1000;\n }\n\n // Guard against scanning very large error messages (ReDoS protection)\n const msg =\n error.message.length > 1000 ? error.message.slice(0, 1000) : error.message;\n const match = msg.match(/retry[- ]?after[:\\s]+(\\d+)/i);\n if (!match) {\n return null;\n }\n\n const seconds = Number(match![1]);\n if (seconds > 0) {\n return seconds * 1000;\n }\n\n return null;\n}\n\n/** Calculate delay with exponential backoff and jitter. */\nfunction calculateBackoffDelay(\n attempt: number,\n baseDelayMs: number,\n maxDelayMs: number,\n): number {\n const exponential = baseDelayMs * 2 ** (attempt - 1);\n const jitter = Math.random() * baseDelayMs * 0.5;\n const delay = exponential + jitter;\n\n return Math.min(delay, maxDelayMs);\n}\n\n/** Determine delay for a given error and attempt. */\nfunction getRetryDelay(\n error: Error,\n attempt: number,\n baseDelayMs: number,\n maxDelayMs: number,\n): number {\n const status = parseHttpStatus(error);\n\n // 429: Prefer Retry-After header value\n if (status === 429) {\n const retryAfter = parseRetryAfter(error);\n if (retryAfter !== null) {\n return Math.min(retryAfter, maxDelayMs);\n }\n }\n\n // All retryable statuses: exponential backoff with jitter\n return calculateBackoffDelay(attempt, baseDelayMs, maxDelayMs);\n}\n\n/** Check if an error is retryable based on HTTP status. */\nfunction isStatusRetryable(error: Error): boolean {\n const status = parseHttpStatus(error);\n if (status === null) {\n // No HTTP status — default to retryable (network errors, timeouts, etc.)\n return true;\n }\n\n return !NON_RETRYABLE_STATUSES.has(status);\n}\n\n// ============================================================================\n// Wrapper\n// ============================================================================\n\n/**\n * Wrap an AgentRunner with intelligent retry logic.\n *\n * @example\n * ```typescript\n * const runner = withRetry(baseRunner, {\n * maxRetries: 3,\n * baseDelayMs: 1000,\n * onRetry: (attempt, error, delayMs) => {\n * console.log(`Retry ${attempt} after ${delayMs}ms: ${error.message}`);\n * },\n * });\n * ```\n */\nexport function withRetry(\n runner: AgentRunner,\n config: RetryConfig = {},\n): AgentRunner {\n const {\n maxRetries = 3,\n baseDelayMs = 1000,\n maxDelayMs = 30000,\n isRetryable,\n onRetry,\n } = config;\n\n // Validate config\n if (!Number.isFinite(maxRetries) || maxRetries < 0) {\n throw new Error(\n \"[Directive] withRetry: maxRetries must be a non-negative finite number.\",\n );\n }\n if (!Number.isFinite(baseDelayMs) || baseDelayMs < 0) {\n throw new Error(\n \"[Directive] withRetry: baseDelayMs must be a non-negative finite number.\",\n );\n }\n if (!Number.isFinite(maxDelayMs) || maxDelayMs < 0) {\n throw new Error(\n \"[Directive] withRetry: maxDelayMs must be a non-negative finite number.\",\n );\n }\n\n return async <T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> => {\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await runner<T>(agent, input, options);\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n\n // Check if we should retry\n if (attempt >= maxRetries) {\n break;\n }\n\n // Check custom retryable predicate\n if (isRetryable) {\n try {\n if (!isRetryable(lastError)) {\n break;\n }\n } catch {\n // isRetryable threw — treat as non-retryable\n break;\n }\n }\n\n // Check HTTP status retryability\n if (!isStatusRetryable(lastError)) {\n break;\n }\n\n // Calculate delay\n const delayMs = getRetryDelay(\n lastError,\n attempt + 1,\n baseDelayMs,\n maxDelayMs,\n );\n try {\n onRetry?.(attempt + 1, lastError, delayMs);\n } catch {\n /* callback error must not disrupt retry flow */\n }\n\n // Wait before retrying (abortable via signal)\n const signal = options?.signal;\n if (signal?.aborted) {\n break;\n }\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, delayMs);\n function onAbort() {\n clearTimeout(timer);\n reject(signal!.reason ?? new Error(\"Aborted\"));\n }\n if (signal) {\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n }\n }\n\n // All retries exhausted\n throw new RetryExhaustedError(maxRetries, lastError!);\n };\n}\n","/**\n * P0: Provider Fallback Chains — Automatic failover across multiple AgentRunners.\n *\n * Tries runners in order, moving to the next on failure.\n * Composes naturally with {@link withRetry} (each runner can have its own retry policy).\n *\n * @module\n *\n * @example\n * ```typescript\n * import { withFallback, withRetry, AllProvidersFailedError } from '@directive-run/ai';\n *\n * const runner = withFallback([\n * withRetry(openaiRunner, { maxRetries: 2 }),\n * withRetry(anthropicRunner, { maxRetries: 2 }),\n * ollamaRunner,\n * ], {\n * onFallback: (from, to, error) => {\n * console.log(`Provider ${from} failed, trying ${to}: ${error.message}`);\n * },\n * });\n *\n * try {\n * const result = await runner(agent, input);\n * } catch (err) {\n * if (err instanceof AllProvidersFailedError) {\n * console.error(`All ${err.errors.length} providers failed`);\n * }\n * }\n * ```\n */\n\nimport type { AgentLike, AgentRunner, RunOptions, RunResult } from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FallbackConfig {\n /** Custom predicate to decide whether to fall back on a given error. Default: always fall back. */\n shouldFallback?: (error: Error) => boolean;\n /** Called when falling back from one provider to the next. */\n onFallback?: (fromIndex: number, toIndex: number, error: Error) => void;\n}\n\n/** Error thrown when all providers in the fallback chain have failed. */\nexport class AllProvidersFailedError extends Error {\n readonly errors: Error[];\n\n constructor(errors: Error[]) {\n const summary = errors.map((e, i) => ` [${i}] ${e.message}`).join(\"\\n\");\n super(`[Directive] All ${errors.length} providers failed:\\n${summary}`);\n this.name = \"AllProvidersFailedError\";\n this.errors = Object.freeze([...errors]) as Error[];\n // Chain causes for debugging\n if (errors.length > 0) {\n this.cause = errors[errors.length - 1];\n }\n }\n}\n\n// ============================================================================\n// Wrapper\n// ============================================================================\n\n/**\n * Wrap multiple AgentRunners into a fallback chain.\n *\n * @example\n * ```typescript\n * const runner = withFallback([\n * withRetry(openaiRunner, { maxRetries: 2 }),\n * withRetry(anthropicRunner, { maxRetries: 2 }),\n * ollamaRunner,\n * ], {\n * onFallback: (from, to, error) => {\n * console.log(`Falling back from provider ${from} to ${to}: ${error.message}`);\n * },\n * });\n * ```\n */\nexport function withFallback(\n runners: AgentRunner[],\n config: FallbackConfig = {},\n): AgentRunner {\n if (runners.length === 0) {\n throw new Error(\"[Directive] withFallback requires at least one runner.\");\n }\n\n const { shouldFallback, onFallback } = config;\n\n return async <T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> => {\n const errors: Error[] = [];\n\n for (let i = 0; i < runners.length; i++) {\n try {\n return await runners[i]!<T>(agent, input, options);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n errors.push(error);\n\n // Check if we should fall back to next provider\n if (i < runners.length - 1) {\n if (shouldFallback) {\n try {\n if (!shouldFallback(error)) {\n break;\n }\n } catch {\n // shouldFallback threw — treat as non-fallbackable\n break;\n }\n }\n try {\n onFallback?.(i, i + 1, error);\n } catch {\n /* callback error must not disrupt fallback flow */\n }\n }\n }\n }\n\n throw new AllProvidersFailedError(errors);\n };\n}\n","/**\n * P1: Cost Budget Guards — Pre-call estimation + rolling budget windows.\n *\n * Prevents runaway LLM costs by estimating costs before each call\n * and tracking actual costs after each call. Supports per-call limits\n * and rolling time-window budgets (hourly, daily).\n *\n * @module\n *\n * @example\n * ```typescript\n * import { withBudget, BudgetExceededError } from '@directive-run/ai';\n * import type { BudgetRunner } from '@directive-run/ai';\n *\n * const pricing = { inputPerMillion: 3, outputPerMillion: 15 };\n *\n * const runner = withBudget(baseRunner, {\n * maxCostPerCall: 0.10,\n * pricing,\n * budgets: [\n * { window: \"hour\", maxCost: 5.00, pricing },\n * { window: \"day\", maxCost: 50.00, pricing },\n * ],\n * });\n *\n * // Check spending via escape hatch\n * const spent = (runner as BudgetRunner).getSpent(\"hour\");\n * if (spent > 4.00) {\n * console.warn(\"Approaching hourly budget limit!\");\n * }\n * ```\n */\n\nimport type {\n AgentLike,\n AgentRunner,\n RunOptions,\n RunResult,\n TokenUsage,\n} from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Token pricing for a specific model or provider.\n *\n * @example\n * ```typescript\n * // GPT-4o pricing (as of 2024)\n * const gpt4oPricing: TokenPricing = {\n * inputPerMillion: 5,\n * outputPerMillion: 15,\n * };\n * ```\n */\nexport interface TokenPricing {\n /** Cost per million input tokens (in dollars). */\n inputPerMillion: number;\n /** Cost per million output tokens (in dollars). */\n outputPerMillion: number;\n}\n\n/**\n * Rolling budget window configuration.\n *\n * Each window tracks cost independently, preventing double-counting\n * when multiple windows are configured.\n *\n * @example\n * ```typescript\n * const hourlyBudget: BudgetWindow = {\n * window: \"hour\",\n * maxCost: 5.00,\n * pricing: { inputPerMillion: 3, outputPerMillion: 15 },\n * };\n * ```\n */\nexport interface BudgetWindow {\n /** Time window for the budget. */\n window: \"hour\" | \"day\";\n /** Maximum cost in dollars for this window. */\n maxCost: number;\n /** Token pricing for cost calculation within this window. */\n pricing: TokenPricing;\n}\n\nexport interface BudgetConfig {\n /** Maximum estimated cost per individual call. */\n maxCostPerCall?: number;\n /** Rolling budget windows. */\n budgets?: BudgetWindow[];\n /** Pricing used for per-call estimation (when maxCostPerCall is set). */\n pricing?: TokenPricing;\n /** Approximate characters per token for input estimation. @default 4 */\n charsPerToken?: number;\n /**\n * Multiplier for estimated output tokens relative to input tokens.\n * For summarization tasks, use a value less than 1 (e.g., 0.3).\n * For generation tasks, use a value greater than 1 (e.g., 3.0).\n * @default 1.0\n */\n estimatedOutputMultiplier?: number;\n /** Called when a budget check fails (before throwing). */\n onBudgetExceeded?: (details: BudgetExceededDetails) => void;\n}\n\nexport interface BudgetExceededDetails {\n estimated: number;\n remaining: number;\n window: \"per-call\" | \"hour\" | \"day\";\n}\n\n/** Error thrown when a budget limit is exceeded. */\nexport class BudgetExceededError extends Error {\n readonly estimated: number;\n readonly remaining: number;\n readonly window: \"per-call\" | \"hour\" | \"day\";\n\n constructor(details: BudgetExceededDetails) {\n super(\n `[Directive] Budget exceeded (${details.window}): estimated $${details.estimated.toFixed(4)}, ` +\n `remaining $${details.remaining.toFixed(4)}`,\n );\n this.name = \"BudgetExceededError\";\n this.estimated = details.estimated;\n this.remaining = details.remaining;\n this.window = details.window;\n }\n}\n\n// ============================================================================\n// Internal: Cost Ledger\n// ============================================================================\n\ninterface CostEntry {\n timestamp: number;\n cost: number;\n}\n\nclass CostLedger {\n private entries: CostEntry[] = [];\n\n record(cost: number): void {\n this.entries.push({ timestamp: Date.now(), cost });\n }\n\n /** Get total cost within a time window. */\n getCostInWindow(windowMs: number): number {\n const cutoff = Date.now() - windowMs;\n this.prune(cutoff);\n\n let total = 0;\n for (const entry of this.entries) {\n if (entry.timestamp >= cutoff) {\n total += entry.cost;\n }\n }\n\n return total;\n }\n\n /** Remove entries older than the cutoff. */\n private prune(cutoff: number): void {\n let pruneIndex = 0;\n while (\n pruneIndex < this.entries.length &&\n this.entries[pruneIndex]!.timestamp < cutoff\n ) {\n pruneIndex++;\n }\n if (pruneIndex > 0) {\n this.entries.splice(0, pruneIndex);\n }\n }\n\n clear(): void {\n this.entries = [];\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst WINDOW_MS: Record<string, number> = {\n hour: 60 * 60 * 1000,\n day: 24 * 60 * 60 * 1000,\n};\n\nfunction estimateInputTokens(input: string, charsPerToken: number): number {\n return Math.ceil(input.length / charsPerToken);\n}\n\nfunction calculateCost(usage: TokenUsage, pricing: TokenPricing): number {\n return (\n (usage.inputTokens / 1_000_000) * pricing.inputPerMillion +\n (usage.outputTokens / 1_000_000) * pricing.outputPerMillion\n );\n}\n\nfunction estimateCallCost(\n inputTokens: number,\n pricing: TokenPricing,\n outputMultiplier = 1.0,\n): number {\n const estimatedOutputTokens = Math.ceil(inputTokens * outputMultiplier);\n\n return (\n (inputTokens / 1_000_000) * pricing.inputPerMillion +\n (estimatedOutputTokens / 1_000_000) * pricing.outputPerMillion\n );\n}\n\n// ============================================================================\n// Wrapper\n// ============================================================================\n\n/**\n * Wrap an AgentRunner with cost budget guards.\n *\n * @example\n * ```typescript\n * const runner = withBudget(baseRunner, {\n * maxCostPerCall: 0.10,\n * pricing: { inputPerMillion: 3, outputPerMillion: 15 },\n * budgets: [\n * { window: \"hour\", maxCost: 5.00, pricing: { inputPerMillion: 3, outputPerMillion: 15 } },\n * { window: \"day\", maxCost: 50.00, pricing: { inputPerMillion: 3, outputPerMillion: 15 } },\n * ],\n * });\n * ```\n */\nexport function withBudget(\n runner: AgentRunner,\n config: BudgetConfig,\n): BudgetRunner {\n const {\n maxCostPerCall,\n budgets = [],\n pricing,\n charsPerToken = 4,\n estimatedOutputMultiplier = 1.0,\n onBudgetExceeded,\n } = config;\n\n // Validate config\n if (!Number.isFinite(charsPerToken) || charsPerToken <= 0) {\n throw new Error(\n \"[Directive] withBudget: charsPerToken must be a positive finite number.\",\n );\n }\n if (\n maxCostPerCall != null &&\n (!Number.isFinite(maxCostPerCall) || maxCostPerCall < 0)\n ) {\n throw new Error(\n \"[Directive] withBudget: maxCostPerCall must be a non-negative finite number.\",\n );\n }\n if (\n !Number.isFinite(estimatedOutputMultiplier) ||\n estimatedOutputMultiplier < 0\n ) {\n throw new Error(\n \"[Directive] withBudget: estimatedOutputMultiplier must be a non-negative finite number.\",\n );\n }\n if (maxCostPerCall != null && !pricing) {\n console.warn(\n \"[Directive] withBudget: maxCostPerCall has no effect without pricing. Provide a pricing config to enable per-call cost estimation.\",\n );\n }\n for (const budget of budgets) {\n if (!Number.isFinite(budget.maxCost) || budget.maxCost < 0) {\n throw new Error(\n `[Directive] withBudget: budgets[${budget.window}].maxCost must be a non-negative finite number.`,\n );\n }\n }\n\n // Per-window ledgers to avoid double-counting\n const windowLedgers = new Map<string, CostLedger>();\n for (const budget of budgets) {\n windowLedgers.set(budget.window, new CostLedger());\n }\n // Base pricing ledger (used when no budget windows are configured)\n const baseLedger = new CostLedger();\n\n const budgetRunner: AgentRunner = async <T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> => {\n const inputTokens = estimateInputTokens(input, charsPerToken);\n\n // Pre-call: Check per-call budget\n if (maxCostPerCall != null && pricing) {\n const estimated = estimateCallCost(\n inputTokens,\n pricing,\n estimatedOutputMultiplier,\n );\n if (estimated > maxCostPerCall) {\n const details: BudgetExceededDetails = {\n estimated,\n remaining: maxCostPerCall,\n window: \"per-call\",\n };\n try {\n onBudgetExceeded?.(details);\n } catch {\n /* callback error must not disrupt budget flow */\n }\n throw new BudgetExceededError(details);\n }\n }\n\n // Pre-call: Check rolling window budgets\n for (const budget of budgets) {\n const windowMs = WINDOW_MS[budget.window]!;\n const ledger = windowLedgers.get(budget.window)!;\n const spent = ledger.getCostInWindow(windowMs);\n const remaining = budget.maxCost - spent;\n const estimated = estimateCallCost(\n inputTokens,\n budget.pricing,\n estimatedOutputMultiplier,\n );\n\n if (estimated > remaining) {\n const details: BudgetExceededDetails = {\n estimated,\n remaining: Math.max(0, remaining),\n window: budget.window,\n };\n try {\n onBudgetExceeded?.(details);\n } catch {\n /* callback error must not disrupt budget flow */\n }\n throw new BudgetExceededError(details);\n }\n }\n\n // Execute the call\n const result = await runner<T>(agent, input, options);\n\n // Post-call: Record actual costs in per-window ledgers\n if (result.tokenUsage) {\n for (const budget of budgets) {\n const ledger = windowLedgers.get(budget.window)!;\n const actualCost = calculateCost(result.tokenUsage, budget.pricing);\n ledger.record(actualCost);\n }\n // Record in base ledger when no windows configured\n if (pricing && budgets.length === 0) {\n const actualCost = calculateCost(result.tokenUsage, pricing);\n baseLedger.record(actualCost);\n }\n }\n\n return result;\n };\n\n /**\n * Get cost spent within a given window. Useful for dashboards and preemptive alerts.\n *\n * @example\n * ```typescript\n * const runner = withBudget(baseRunner, { budgets: [{ window: \"hour\", maxCost: 10, pricing }] });\n * const spent = (runner as BudgetRunner).getSpent(\"hour\");\n * if (spent > 8) console.warn(\"Approaching hourly budget limit!\");\n * ```\n */\n function getSpent(window: \"hour\" | \"day\"): number {\n const ledger = windowLedgers.get(window);\n if (!ledger) {\n return 0;\n }\n const windowMs = WINDOW_MS[window]!;\n\n return ledger.getCostInWindow(windowMs);\n }\n\n // Attach getSpent as a direct property for type-safe access without casting\n (budgetRunner as unknown as Record<string, unknown>).getSpent = getSpent;\n\n return budgetRunner as unknown as BudgetRunner;\n}\n\n/** Helper type for accessing budget runner's getSpent method. */\nexport type BudgetRunner = AgentRunner & {\n /** Get cost spent within a rolling window. */\n getSpent(window: \"hour\" | \"day\"): number;\n};\n","/**\n * P3: Smart Model Selection — Rule-based model routing for AgentRunner.\n *\n * Route simple tasks to cheaper models and complex tasks to expensive ones,\n * reducing cost without sacrificing quality where it matters.\n *\n * Rules are evaluated in order; the first match wins. If no rule matches,\n * the agent's original model is used unchanged.\n *\n * Accepts either a {@link ModelSelectionConfig} object (recommended) or\n * a bare `ModelRule[]` array for convenience.\n *\n * @module\n *\n * @example Config object (recommended)\n * ```typescript\n * import { withModelSelection, byInputLength, byAgentName, byPattern } from '@directive-run/ai';\n *\n * const runner = withModelSelection(baseRunner, {\n * rules: [\n * byInputLength(200, \"gpt-4o-mini\"),\n * byAgentName(\"summarizer\", \"gpt-4o-mini\"),\n * byPattern(/classify|categorize/i, \"gpt-4o-mini\"),\n * ],\n * onModelSelected: (original, selected) => {\n * if (original !== selected) console.log(`Routed ${original} → ${selected}`);\n * },\n * });\n * ```\n *\n * @example Shorthand (rules array)\n * ```typescript\n * const runner = withModelSelection(baseRunner, [\n * byInputLength(200, \"gpt-4o-mini\"),\n * ]);\n * ```\n */\n\nimport type { AgentLike, AgentRunner, RunOptions, RunResult } from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** A single model selection rule. First match wins. */\nexport interface ModelRule {\n /** Predicate that determines if this rule applies. */\n match: (agent: AgentLike, input: string) => boolean;\n /** The model to use when this rule matches. */\n model: string;\n}\n\n/** Configuration for model selection. */\nexport interface ModelSelectionConfig {\n /** Rules evaluated in order. First match wins. */\n rules: ModelRule[];\n /** Called when a model is selected (even if it matches the original). */\n onModelSelected?: (\n originalModel: string | undefined,\n selectedModel: string | undefined,\n ) => void;\n}\n\n// ============================================================================\n// Convenience Matchers\n// ============================================================================\n\n/**\n * Match when input character length is at most `maxLength`.\n *\n * @example\n * ```typescript\n * byInputLength(500, \"gpt-4o-mini\") // inputs up to 500 chars use mini\n * ```\n */\nexport function byInputLength(maxLength: number, model: string): ModelRule {\n return {\n match: (_agent, input) => input.length <= maxLength,\n model,\n };\n}\n\n/**\n * Match by agent name (exact string match).\n *\n * @example\n * ```typescript\n * byAgentName(\"classifier\", \"gpt-4o-mini\")\n * ```\n */\nexport function byAgentName(name: string, model: string): ModelRule {\n return {\n match: (agent) => agent.name === name,\n model,\n };\n}\n\n/**\n * Match by regex pattern on the input text.\n *\n * @example\n * ```typescript\n * byPattern(/classify|categorize/i, \"gpt-4o-mini\") // classification prompts use mini\n * ```\n */\nexport function byPattern(pattern: RegExp, model: string): ModelRule {\n return {\n match: (_agent, input) => {\n // Reset lastIndex for stateful regexes (e.g., /g flag)\n pattern.lastIndex = 0;\n\n return pattern.test(input);\n },\n model,\n };\n}\n\n// ============================================================================\n// Wrapper\n// ============================================================================\n\n/**\n * Wrap an AgentRunner with rule-based model selection.\n *\n * Rules are evaluated in order. The first match wins and overrides `agent.model`.\n * If no rule matches, the agent's original model is used.\n *\n * Accepts either a config object or a bare `ModelRule[]` for convenience.\n *\n * @example\n * ```typescript\n * // Config object (recommended)\n * const runner = withModelSelection(baseRunner, {\n * rules: [\n * byInputLength(200, \"gpt-4o-mini\"),\n * byAgentName(\"summarizer\", \"gpt-4o-mini\"),\n * byPattern(/classify|categorize/i, \"gpt-4o-mini\"),\n * ],\n * onModelSelected: (original, selected) => {\n * console.log(`Model: ${original} → ${selected}`);\n * },\n * });\n *\n * // Shorthand (rules array)\n * const runner = withModelSelection(baseRunner, [\n * byInputLength(200, \"gpt-4o-mini\"),\n * ]);\n * ```\n */\nexport function withModelSelection(\n runner: AgentRunner,\n configOrRules: ModelSelectionConfig | ModelRule[],\n): AgentRunner {\n const config = Array.isArray(configOrRules)\n ? { rules: configOrRules }\n : configOrRules;\n const { rules, onModelSelected } = config;\n\n return async <T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> => {\n let selectedModel = agent.model;\n\n for (const rule of rules) {\n try {\n if (rule.match(agent, input)) {\n selectedModel = rule.model;\n break;\n }\n } catch {\n // Throwing match function is skipped — do not crash model selection\n }\n }\n\n try {\n onModelSelected?.(agent.model, selectedModel);\n } catch {\n /* callback error must not disrupt model selection flow */\n }\n\n // Override model if a rule matched and model is different\n const effectiveAgent =\n selectedModel !== agent.model\n ? { ...agent, model: selectedModel }\n : agent;\n\n return runner<T>(effectiveAgent, input, options);\n };\n}\n","/**\n * P5: Batch Queue — Application-level batching for agent calls.\n *\n * Accumulates calls and flushes them in batches to reduce overhead.\n * Each `submit()` returns a promise that resolves when its individual call completes.\n * Batches execute calls in parallel up to a configurable concurrency limit.\n *\n * @module\n *\n * @example\n * ```typescript\n * import { createBatchQueue } from '@directive-run/ai';\n *\n * const queue = createBatchQueue(runner, {\n * maxBatchSize: 20,\n * maxWaitMs: 5000,\n * concurrency: 5,\n * });\n *\n * // Submit calls — they batch automatically\n * const [r1, r2, r3] = await Promise.all([\n * queue.submit(agent, \"input 1\"),\n * queue.submit(agent, \"input 2\"),\n * queue.submit(agent, \"input 3\"),\n * ]);\n *\n * // Force immediate flush\n * await queue.flush();\n *\n * // Clean up (flushes remaining calls)\n * await queue.destroy();\n * ```\n */\n\nimport type { AgentLike, AgentRunner, RunOptions, RunResult } from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BatchQueueConfig {\n /** Maximum number of calls per batch. @default 20 */\n maxBatchSize?: number;\n /** Maximum time to wait before flushing (ms). @default 5000 */\n maxWaitMs?: number;\n /** Number of calls to run in parallel within a batch. @default 5 */\n concurrency?: number;\n}\n\nexport interface BatchQueue {\n /** Submit a call to the queue. Returns a promise that resolves when the call completes. */\n submit<T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>>;\n /** Flush all pending calls immediately. */\n flush(): Promise<void>;\n /** Get the number of pending calls. */\n readonly pending: number;\n /** Destroy the queue, flushing remaining calls. */\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Internal\n// ============================================================================\n\ninterface QueuedCall {\n agent: AgentLike;\n input: string;\n options?: RunOptions;\n resolve: (result: RunResult<unknown>) => void;\n reject: (error: Error) => void;\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Create a batch queue for grouping agent calls.\n *\n * @example\n * ```typescript\n * const queue = createBatchQueue(runner, {\n * maxBatchSize: 20,\n * maxWaitMs: 5000,\n * concurrency: 5,\n * });\n *\n * // Submit multiple calls — they batch automatically\n * const [result1, result2, result3] = await Promise.all([\n * queue.submit(agent, \"input 1\"),\n * queue.submit(agent, \"input 2\"),\n * queue.submit(agent, \"input 3\"),\n * ]);\n *\n * // Clean up\n * await queue.destroy();\n * ```\n */\nexport function createBatchQueue(\n runner: AgentRunner,\n config: BatchQueueConfig = {},\n): BatchQueue {\n const { maxBatchSize = 20, maxWaitMs = 5000, concurrency = 5 } = config;\n\n // Validate config\n if (!Number.isFinite(maxBatchSize) || maxBatchSize < 1) {\n throw new Error(\n \"[Directive] createBatchQueue: maxBatchSize must be a positive finite number (>= 1).\",\n );\n }\n if (!Number.isFinite(maxWaitMs) || maxWaitMs < 0) {\n throw new Error(\n \"[Directive] createBatchQueue: maxWaitMs must be a non-negative finite number.\",\n );\n }\n if (!Number.isFinite(concurrency) || concurrency < 1) {\n throw new Error(\n \"[Directive] createBatchQueue: concurrency must be a positive finite number (>= 1).\",\n );\n }\n\n const queue: QueuedCall[] = [];\n let flushTimer: ReturnType<typeof setTimeout> | null = null;\n let destroyed = false;\n let flushPromise: Promise<void> | null = null;\n\n function scheduleFlush(): void {\n if (flushTimer !== null) {\n return;\n }\n flushTimer = setTimeout(() => {\n flushTimer = null;\n flushInternal().catch(() => {\n // Errors are delivered to individual call promises\n });\n }, maxWaitMs);\n }\n\n function cancelTimer(): void {\n if (flushTimer !== null) {\n clearTimeout(flushTimer);\n flushTimer = null;\n }\n }\n\n /** Execute calls with concurrency limit. */\n async function executeBatch(batch: QueuedCall[]): Promise<void> {\n let index = 0;\n\n async function runNext(): Promise<void> {\n while (index < batch.length) {\n const current = index++;\n const call = batch[current]!;\n\n try {\n const result = await runner(call.agent, call.input, call.options);\n call.resolve(result);\n } catch (err) {\n call.reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n }\n\n // Run up to `concurrency` workers\n const workers = Array.from(\n { length: Math.min(concurrency, batch.length) },\n () => runNext(),\n );\n await Promise.all(workers);\n }\n\n async function flushInternal(): Promise<void> {\n // Wait for any in-progress flush to complete first\n if (flushPromise) {\n await flushPromise;\n }\n\n if (queue.length === 0) {\n return;\n }\n\n cancelTimer();\n\n // Drain the queue\n const batch = queue.splice(0);\n\n flushPromise = executeBatch(batch).finally(() => {\n flushPromise = null;\n\n // If more calls came in during flush, schedule another\n if (queue.length > 0) {\n scheduleFlush();\n }\n });\n\n await flushPromise;\n }\n\n return {\n submit<T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> {\n if (destroyed) {\n return Promise.reject(\n new Error(\"[Directive] BatchQueue has been destroyed.\"),\n );\n }\n\n return new Promise<RunResult<T>>((resolve, reject) => {\n queue.push({\n agent,\n input,\n options,\n resolve: resolve as (result: RunResult<unknown>) => void,\n reject,\n });\n\n // Flush immediately if batch is full\n if (queue.length >= maxBatchSize) {\n cancelTimer();\n flushInternal().catch(() => {\n // Errors are delivered to individual call promises\n });\n } else {\n scheduleFlush();\n }\n });\n },\n\n async flush(): Promise<void> {\n await flushInternal();\n },\n\n get pending(): number {\n return queue.length;\n },\n\n async destroy(): Promise<void> {\n if (destroyed) {\n return;\n }\n destroyed = true;\n cancelTimer();\n // Flush remaining calls\n if (queue.length > 0) {\n await flushInternal();\n }\n },\n };\n}\n","/**\n * P4: Constraint-Driven Provider Routing — Directive's unique differentiator.\n *\n * Uses user-supplied constraints to select providers based on runtime state:\n * cost, latency, error rates, and compliance regions.\n *\n * Tracks per-provider stats (call count, error count, cost, latency) and\n * exposes them as {@link RoutingFacts} for constraint evaluation.\n *\n * @module\n *\n * @example\n * ```typescript\n * import { createConstraintRouter } from '@directive-run/ai';\n * import type { ConstraintRouterRunner } from '@directive-run/ai';\n *\n * const router = createConstraintRouter({\n * providers: [\n * { name: \"openai\", runner: openaiRunner, pricing: { inputPerMillion: 5, outputPerMillion: 15 } },\n * { name: \"anthropic\", runner: anthropicRunner, pricing: { inputPerMillion: 3, outputPerMillion: 15 } },\n * { name: \"ollama\", runner: ollamaRunner },\n * ],\n * defaultProvider: \"openai\",\n * constraints: [\n * { when: (facts) => facts.totalCost > 100, provider: \"ollama\", priority: 10 },\n * { when: (facts) => facts.providers[\"openai\"]?.errorCount > 5, provider: \"anthropic\" },\n * ],\n * preferCheapest: true, // opt-in to cheapest-provider heuristic\n * onProviderSelected: (name, reason) => console.log(`Using ${name} (${reason})`),\n * });\n *\n * // Access runtime stats\n * console.log(router.facts.totalCost, router.facts.callCount);\n * ```\n */\n\nimport type {\n AgentLike,\n AgentRunner,\n RunOptions,\n RunResult,\n TokenUsage,\n} from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Provider definition for the constraint router.\n *\n * Each provider has its own runner, optional pricing (for cost tracking\n * and cheapest-provider heuristic), and optional region tag.\n */\nexport interface RoutingProvider {\n /** Unique name for this provider. */\n name: string;\n /** The runner to use for this provider. */\n runner: AgentRunner;\n /** Token pricing (cost per million tokens). */\n pricing?: { inputPerMillion: number; outputPerMillion: number };\n /** Geographic region (for compliance routing). */\n region?: string;\n}\n\n/**\n * Runtime facts tracked by the router — exposed for user constraints.\n *\n * Access via the `facts` property on the returned {@link ConstraintRouterRunner}.\n */\nexport interface RoutingFacts {\n totalCost: number;\n callCount: number;\n errorCount: number;\n lastProvider: string | null;\n avgLatencyMs: number;\n /** Per-provider stats. */\n providers: Record<string, ProviderStats>;\n}\n\nexport interface ProviderStats {\n callCount: number;\n errorCount: number;\n totalCost: number;\n avgLatencyMs: number;\n lastErrorAt: number | null;\n}\n\n/** User-supplied routing constraint. */\nexport interface RoutingConstraint {\n /** When this constraint is active. */\n when: (facts: RoutingFacts) => boolean;\n /** The provider to route to. */\n provider: string;\n /** Priority — higher wins when multiple constraints match. @default 0 */\n priority?: number;\n}\n\nexport interface ConstraintRouterConfig {\n /** Available providers. */\n providers: RoutingProvider[];\n /** Default provider name. */\n defaultProvider: string;\n /** User-supplied routing constraints. */\n constraints?: RoutingConstraint[];\n /** Called when a provider is selected. */\n onProviderSelected?: (\n providerName: string,\n reason: \"constraint\" | \"cheapest\" | \"default\",\n ) => void;\n /** Error cooldown — skip a provider for this many ms after an error. @default 30000 */\n errorCooldownMs?: number;\n /**\n * When true, automatically prefer the cheapest available provider\n * (based on pricing) when no user constraint matches.\n * When false, the default provider is used unless a constraint overrides it.\n * @default false\n */\n preferCheapest?: boolean;\n}\n\n// ============================================================================\n// Internal\n// ============================================================================\n\nfunction createEmptyStats(): ProviderStats {\n return {\n callCount: 0,\n errorCount: 0,\n totalCost: 0,\n avgLatencyMs: 0,\n lastErrorAt: null,\n };\n}\n\nfunction calculateCost(\n usage: TokenUsage | undefined,\n pricing?: { inputPerMillion: number; outputPerMillion: number },\n): number {\n if (!usage || !pricing) {\n return 0;\n }\n\n return (\n (usage.inputTokens / 1_000_000) * pricing.inputPerMillion +\n (usage.outputTokens / 1_000_000) * pricing.outputPerMillion\n );\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Create a constraint-driven provider router.\n *\n * @example\n * ```typescript\n * const runner = createConstraintRouter({\n * providers: [\n * { name: \"openai\", runner: openaiRunner, pricing: { inputPerMillion: 5, outputPerMillion: 15 } },\n * { name: \"anthropic\", runner: anthropicRunner, pricing: { inputPerMillion: 3, outputPerMillion: 15 } },\n * { name: \"ollama\", runner: ollamaRunner },\n * ],\n * defaultProvider: \"openai\",\n * constraints: [\n * { when: (facts) => facts.totalCost > 100, provider: \"ollama\", priority: 10 },\n * { when: (facts) => facts.providers[\"openai\"]?.errorCount > 5, provider: \"anthropic\" },\n * ],\n * });\n * ```\n */\nexport function createConstraintRouter(\n config: ConstraintRouterConfig,\n): ConstraintRouterRunner {\n const {\n providers,\n defaultProvider,\n constraints = [],\n onProviderSelected,\n errorCooldownMs = 30000,\n preferCheapest = false,\n } = config;\n\n // Validate config\n if (!Number.isFinite(errorCooldownMs) || errorCooldownMs < 0) {\n throw new Error(\n \"[Directive] createConstraintRouter: errorCooldownMs must be a non-negative finite number.\",\n );\n }\n\n // Validate\n const providerMap = new Map<string, RoutingProvider>();\n for (const provider of providers) {\n providerMap.set(provider.name, provider);\n }\n\n if (!providerMap.has(defaultProvider)) {\n throw new Error(\n `[Directive] Default provider \"${defaultProvider}\" not found in providers list.`,\n );\n }\n\n // Initialize facts\n const facts: RoutingFacts = {\n totalCost: 0,\n callCount: 0,\n errorCount: 0,\n lastProvider: null,\n avgLatencyMs: 0,\n providers: Object.create(null) as Record<string, ProviderStats>,\n };\n\n for (const provider of providers) {\n facts.providers[provider.name] = createEmptyStats();\n }\n\n // Total latency for averaging\n let totalLatencyMs = 0;\n\n // Pre-sort constraints at construction time (not per-call)\n const sortedConstraints = [...constraints].sort(\n (a, b) => (b.priority ?? 0) - (a.priority ?? 0),\n );\n\n /** Select provider based on constraints and heuristics. */\n function selectProvider(): {\n provider: RoutingProvider;\n reason: \"constraint\" | \"cheapest\" | \"default\";\n } {\n const now = Date.now();\n\n for (const constraint of sortedConstraints) {\n try {\n if (constraint.when(facts)) {\n const provider = providerMap.get(constraint.provider);\n if (provider) {\n return { provider, reason: \"constraint\" };\n }\n }\n } catch {\n // Throwing constraint is skipped — do not crash the router\n }\n }\n\n // 2. Filter out providers in error cooldown\n const availableProviders = providers.filter((p) => {\n const stats = facts.providers[p.name];\n if (!stats) {\n return true;\n }\n if (stats.lastErrorAt && now - stats.lastErrorAt < errorCooldownMs) {\n return false;\n }\n\n return true;\n });\n\n // 3. Cheapest-provider heuristic (opt-in via preferCheapest)\n if (preferCheapest && availableProviders.length > 0) {\n const sorted = [...availableProviders].sort((a, b) => {\n const aCost = a.pricing\n ? a.pricing.inputPerMillion + a.pricing.outputPerMillion\n : Number.POSITIVE_INFINITY;\n const bCost = b.pricing\n ? b.pricing.inputPerMillion + b.pricing.outputPerMillion\n : Number.POSITIVE_INFINITY;\n if (aCost !== bCost) {\n return aCost - bCost;\n }\n // Tie-break: prefer default provider\n if (a.name === defaultProvider) {\n return -1;\n }\n if (b.name === defaultProvider) {\n return 1;\n }\n\n return 0;\n });\n\n if (sorted[0] !== providerMap.get(defaultProvider)) {\n return { provider: sorted[0]!, reason: \"cheapest\" };\n }\n }\n\n // 4. If default is in cooldown, pick the first available\n if (\n availableProviders.length > 0 &&\n !availableProviders.some((p) => p.name === defaultProvider)\n ) {\n return { provider: availableProviders[0]!, reason: \"default\" };\n }\n\n // 5. Fallback to default\n return { provider: providerMap.get(defaultProvider)!, reason: \"default\" };\n }\n\n /** Update facts after a call. */\n function recordCall(\n providerName: string,\n latencyMs: number,\n usage: TokenUsage | undefined,\n pricing?: { inputPerMillion: number; outputPerMillion: number },\n error?: Error,\n ): void {\n const stats = facts.providers[providerName] ?? createEmptyStats();\n\n stats.callCount++;\n facts.callCount++;\n\n if (error) {\n stats.errorCount++;\n facts.errorCount++;\n stats.lastErrorAt = Date.now();\n } else {\n const cost = calculateCost(usage, pricing);\n stats.totalCost += cost;\n facts.totalCost += cost;\n }\n\n // Update average latency\n totalLatencyMs += latencyMs;\n facts.avgLatencyMs = totalLatencyMs / facts.callCount;\n\n const statsTotal =\n stats.callCount > 0\n ? (stats.avgLatencyMs * (stats.callCount - 1) + latencyMs) /\n stats.callCount\n : latencyMs;\n stats.avgLatencyMs = statsTotal;\n\n facts.providers[providerName] = stats;\n facts.lastProvider = providerName;\n }\n\n const routerRunner: AgentRunner = async <T = unknown>(\n agent: AgentLike,\n input: string,\n options?: RunOptions,\n ): Promise<RunResult<T>> => {\n const { provider, reason } = selectProvider();\n try {\n onProviderSelected?.(provider.name, reason);\n } catch {\n /* callback error must not disrupt routing flow */\n }\n\n const startTime = Date.now();\n\n try {\n const result = await provider.runner<T>(agent, input, options);\n const latencyMs = Date.now() - startTime;\n\n recordCall(provider.name, latencyMs, result.tokenUsage, provider.pricing);\n\n return result;\n } catch (err) {\n const latencyMs = Date.now() - startTime;\n const error = err instanceof Error ? err : new Error(String(err));\n\n recordCall(provider.name, latencyMs, undefined, provider.pricing, error);\n\n throw error;\n }\n };\n\n /** Expose facts for external inspection (deep-cloned to prevent mutation). */\n Object.defineProperty(routerRunner, \"facts\", {\n get: () => {\n const clonedProviders: Record<string, ProviderStats> = Object.create(\n null,\n ) as Record<string, ProviderStats>;\n for (const key of Object.keys(facts.providers)) {\n clonedProviders[key] = { ...facts.providers[key]! };\n }\n\n return { ...facts, providers: clonedProviders };\n },\n enumerable: true,\n });\n\n return routerRunner as ConstraintRouterRunner;\n}\n\n/** Helper type for accessing router facts. */\nexport type ConstraintRouterRunner = AgentRunner & {\n readonly facts: RoutingFacts;\n};\n","/**\n * OpenTelemetry Integration — AI-specific observability spans.\n *\n * Auto-instruments agent orchestrators with OpenTelemetry spans for\n * agent runs, guardrail checks, constraint evaluations, and DAG execution.\n * Works with any OTEL-compatible collector (Jaeger, Zipkin, Honeycomb, etc.).\n *\n * Uses OpenTelemetry GenAI semantic conventions (`gen_ai.*`) for\n * AI-specific attributes alongside Directive-specific attributes.\n *\n * @example\n * ```typescript\n * import { createOtelPlugin } from \"@directive-run/ai\";\n *\n * const orchestrator = createAgentOrchestrator({\n * runner,\n * plugins: [createOtelPlugin({ serviceName: \"my-ai-app\" })],\n * });\n * // Every run() creates spans with: agent name, model, tokens, cost, duration\n * ```\n *\n * @module\n */\n\nimport type { DebugTimeline } from \"./debug-timeline.js\";\nimport type {\n AgentCompleteEvent,\n AgentErrorEvent,\n AgentStartEvent,\n ConstraintEvaluateEvent,\n DebugEvent,\n GuardrailCheckEvent,\n PatternCompleteEvent,\n PatternStartEvent,\n ResolverCompleteEvent,\n ResolverErrorEvent,\n ResolverStartEvent,\n} from \"./types.js\";\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Default TTL for active spans (5 minutes). Spans older than this are cleaned up. */\nconst DEFAULT_SPAN_TTL_MS = 300_000;\n\n/** Maximum active spans before triggering cleanup */\nconst MAX_ACTIVE_SPANS = 10_000;\n\n/** Maximum depth of the pattern span stack */\nconst MAX_PATTERN_STACK = 100;\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Minimal span interface compatible with OpenTelemetry API */\nexport interface OtelSpan {\n /** Set an attribute on the span */\n setAttribute(key: string, value: string | number | boolean): void;\n /** Add an event to the span */\n addEvent(\n name: string,\n attributes?: Record<string, string | number | boolean>,\n ): void;\n /** Set the span status */\n setStatus(status: { code: number; message?: string }): void;\n /** End the span */\n end(): void;\n}\n\n/** OTEL status codes as a const object (no enum overhead) */\nexport const OtelStatusCode = {\n UNSET: 0,\n OK: 1,\n ERROR: 2,\n} as const;\n\nexport type OtelStatusCode =\n (typeof OtelStatusCode)[keyof typeof OtelStatusCode];\n\n/** Tracer interface compatible with OpenTelemetry API */\nexport interface OtelTracer {\n /** Start a new span */\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): OtelSpan;\n}\n\n/** Configuration for the OTEL plugin */\nexport interface OtelPluginConfig {\n /** Service name for span attribution */\n serviceName: string;\n /** Custom tracer instance. If not provided, uses a no-op tracer for standalone span collection. */\n tracer?: OtelTracer;\n /** Span prefix. Default: \"directive.ai\" */\n spanPrefix?: string;\n /** Span processor callback — called for every completed span. Useful for custom exporters. */\n onSpanEnd?: (spanData: SpanData) => void;\n /** Event types to instrument. Default: all */\n instrumentEvents?: Set<string>;\n /** TTL for active spans in ms. Spans older than this are cleaned up. Default: 300000 (5 min) */\n spanTtlMs?: number;\n}\n\n/** Serializable span data for export */\nexport interface SpanData {\n name: string;\n traceId: string;\n spanId: string;\n parentSpanId?: string;\n attributes: Record<string, string | number | boolean>;\n events: Array<{\n name: string;\n attributes?: Record<string, string | number | boolean>;\n timestamp: number;\n }>;\n status: { code: OtelStatusCode; message?: string };\n startTime: number;\n endTime: number;\n durationMs: number;\n}\n\n/** OTEL Plugin instance */\nexport interface OtelPlugin {\n /** Attach to a debug timeline to auto-instrument */\n attach(timeline: DebugTimeline): () => void;\n /** Get all collected spans (when using built-in collector) */\n getSpans(): SpanData[];\n /** Clear collected spans */\n clearSpans(): void;\n /** Get the underlying tracer */\n getTracer(): OtelTracer;\n /** Get count of currently active (in-flight) spans */\n getActiveSpanCount(): number;\n}\n\n// ============================================================================\n// No-Op Tracer (for standalone span collection)\n// ============================================================================\n\nclass CollectedSpan implements OtelSpan {\n readonly attributes: Record<string, string | number | boolean> =\n Object.create(null);\n readonly spanEvents: Array<{\n name: string;\n attributes?: Record<string, string | number | boolean>;\n timestamp: number;\n }> = [];\n status: { code: OtelStatusCode; message?: string } = {\n code: OtelStatusCode.UNSET,\n };\n readonly startTime: number;\n endTime = 0;\n\n constructor(\n readonly name: string,\n readonly spanId: string,\n readonly traceId: string,\n readonly parentSpanId: string | undefined,\n initialAttributes?: Record<string, string | number | boolean>,\n private readonly onEnd?: (span: CollectedSpan) => void,\n ) {\n this.startTime = Date.now();\n if (initialAttributes) {\n for (const [key, value] of Object.entries(initialAttributes)) {\n this.attributes[key] = value;\n }\n }\n }\n\n setAttribute(key: string, value: string | number | boolean): void {\n this.attributes[key] = value;\n }\n\n addEvent(\n name: string,\n attributes?: Record<string, string | number | boolean>,\n ): void {\n this.spanEvents.push({ name, attributes, timestamp: Date.now() });\n }\n\n setStatus(status: { code: OtelStatusCode; message?: string }): void {\n this.status = status;\n }\n\n end(): void {\n this.endTime = Date.now();\n this.onEnd?.(this);\n }\n\n toSpanData(): SpanData {\n return {\n name: this.name,\n traceId: this.traceId,\n spanId: this.spanId,\n parentSpanId: this.parentSpanId,\n attributes: { ...this.attributes },\n events: [...this.spanEvents],\n status: { ...this.status },\n startTime: this.startTime,\n endTime: this.endTime,\n durationMs: this.endTime - this.startTime,\n };\n }\n}\n\nclass CollectorTracer implements OtelTracer {\n readonly spans: SpanData[] = [];\n\n startSpan(\n name: string,\n options?: {\n attributes?: Record<string, string | number | boolean>;\n spanId?: string;\n traceId?: string;\n parentSpanId?: string;\n },\n ): OtelSpan {\n const spanId = options?.spanId ?? `fallback-${crypto.randomUUID()}`;\n const traceId = options?.traceId ?? `fallback-${crypto.randomUUID()}`;\n const parentSpanId = options?.parentSpanId;\n\n return new CollectedSpan(\n name,\n spanId,\n traceId,\n parentSpanId,\n options?.attributes,\n (span) => {\n this.spans.push(span.toSpanData());\n },\n );\n }\n\n clear(): void {\n this.spans.length = 0;\n }\n}\n\n// ============================================================================\n// External Tracer Shadow Data\n// ============================================================================\n\n/**\n * When using an external tracer, we track span metadata alongside\n * the external span so `onSpanEnd` can provide meaningful SpanData.\n */\ninterface ExternalSpanShadow {\n span: OtelSpan;\n name: string;\n spanId: string;\n traceId: string;\n parentSpanId?: string;\n attributes: Record<string, string | number | boolean>;\n events: Array<{\n name: string;\n attributes?: Record<string, string | number | boolean>;\n timestamp: number;\n }>;\n status: { code: OtelStatusCode; message?: string };\n startTime: number;\n}\n\n// ============================================================================\n// Active Span Entry\n// ============================================================================\n\ninterface ActiveSpanEntry {\n span: OtelSpan;\n shadow?: ExternalSpanShadow;\n spanId: string;\n traceId: string;\n startTime: number;\n /** A13: Pre-computed index key to avoid parsing from span key */\n indexKey?: string;\n}\n\n// ============================================================================\n// Plugin Implementation\n// ============================================================================\n\n/**\n * Create an OpenTelemetry plugin for AI observability.\n *\n * Subscribes to a DebugTimeline and creates spans for agent runs,\n * guardrail checks, constraint evaluations, resolver executions,\n * and execution patterns (DAG, parallel, sequential, etc.).\n *\n * Parent-child relationships:\n * - Pattern spans are roots\n * - Agent spans are children of the active pattern span (if any)\n * - Guardrail/resolver spans within an agent run are children of the agent span\n * - Constraint evaluations within an agent run are recorded as span events\n *\n * @example\n * ```typescript\n * // With built-in span collection:\n * const otel = createOtelPlugin({ serviceName: \"my-app\" });\n * const unsub = otel.attach(orchestrator.timeline);\n * await orchestrator.run(agent, input);\n * console.log(otel.getSpans()); // All spans from the run\n *\n * // With custom OTEL tracer:\n * import { trace } from \"@opentelemetry/api\";\n * const otel = createOtelPlugin({\n * serviceName: \"my-app\",\n * tracer: trace.getTracer(\"directive-ai\"),\n * });\n * ```\n */\nexport function createOtelPlugin(config: OtelPluginConfig): OtelPlugin {\n const prefix = config.spanPrefix ?? \"directive.ai\";\n const instrumentEvents = config.instrumentEvents;\n const spanTtlMs = config.spanTtlMs ?? DEFAULT_SPAN_TTL_MS;\n\n // Use provided tracer or built-in collector\n const isCollector = !config.tracer;\n const collectorTracer = isCollector ? new CollectorTracer() : null;\n const tracer = config.tracer ?? collectorTracer!;\n\n // Instance-scoped ID generation (prevents cross-test leakage)\n let spanCounter = 0;\n\n function generateId(): string {\n return `${Date.now().toString(36)}-${(spanCounter++).toString(36)}`;\n }\n\n function generateTraceId(): string {\n return `${Date.now().toString(36)}-${crypto.randomUUID().slice(0, 8)}`;\n }\n\n // Track active spans by unique key for correlation\n // Key format: \"type:id:counter\" to prevent collisions\n const activeSpans = new Map<string, ActiveSpanEntry>();\n let keyCounter = 0;\n\n // Secondary index for O(1) span lookup by \"type:id\" prefix\n const spanKeyIndex = new Map<string, string[]>();\n\n /**\n * Pattern span stack for proper nesting (inner patterns don't clobber outer).\n *\n * WARNING: A single OtelPlugin instance must NOT be attached to more than one\n * timeline simultaneously. The patternStack is local to this closure and is\n * shared across all events emitted through it. Concurrent use across multiple\n * timelines will interleave push/pop operations, producing incorrect span\n * hierarchies and potentially orphaned spans.\n */\n const patternStack: ActiveSpanEntry[] = [];\n\n // A7: Track attached timeline to prevent double-attach\n let attachedTimeline: DebugTimeline | null = null;\n\n // Dev warning dedup\n let warnedExternalGetSpans = false;\n\n function shouldInstrument(type: string): boolean {\n if (!instrumentEvents) {\n return true;\n }\n\n return instrumentEvents.has(type);\n }\n\n function makeSpanKey(type: string, id: string): string {\n return `${type}:${id}:${keyCounter++}`;\n }\n\n function findActiveSpan(\n type: string,\n id: string,\n ): { key: string; entry: ActiveSpanEntry } | null {\n const indexKey = `${type}:${id}`;\n const keys = spanKeyIndex.get(indexKey);\n if (keys) {\n // Walk from end to find latest active span\n for (let i = keys.length - 1; i >= 0; i--) {\n const entry = activeSpans.get(keys[i]!);\n if (entry) {\n return { key: keys[i]!, entry };\n }\n }\n\n // All stale\n spanKeyIndex.delete(indexKey);\n }\n\n return null;\n }\n\n function registerSpan(\n type: string,\n id: string,\n key: string,\n entry: ActiveSpanEntry,\n ): void {\n // A13: Store indexKey explicitly to avoid parsing from key later\n const indexKey = `${type}:${id}`;\n entry.indexKey = indexKey;\n activeSpans.set(key, entry);\n const existing = spanKeyIndex.get(indexKey);\n if (existing) {\n existing.push(key);\n } else {\n spanKeyIndex.set(indexKey, [key]);\n }\n }\n\n function removeSpan(key: string): void {\n // A13: Use stored indexKey instead of parsing from key string\n const entry = activeSpans.get(key);\n activeSpans.delete(key);\n\n const indexKey = entry?.indexKey;\n if (indexKey) {\n const keys = spanKeyIndex.get(indexKey);\n if (keys) {\n const idx = keys.indexOf(key);\n if (idx !== -1) {\n keys.splice(idx, 1);\n }\n if (keys.length === 0) {\n spanKeyIndex.delete(indexKey);\n }\n }\n }\n }\n\n function cleanupStaleSpans(): void {\n // A3: Always run TTL-based pruning (not gated behind size check)\n const now = Date.now();\n if (activeSpans.size < MAX_ACTIVE_SPANS) {\n // Below hard cap: only prune spans that exceeded TTL\n let hasPruned = false;\n for (const [key, entry] of activeSpans) {\n if (now - entry.startTime > spanTtlMs) {\n setAttributeTracked(entry, \"directive.stale\", true);\n setStatusTracked(entry, {\n code: OtelStatusCode.ERROR,\n message: \"Span TTL exceeded — cleaned up\",\n });\n endSpan(entry);\n removeSpan(key);\n hasPruned = true;\n }\n }\n\n if (hasPruned) {\n return;\n }\n\n return;\n }\n\n for (const [key, entry] of activeSpans) {\n if (now - entry.startTime > spanTtlMs) {\n setAttributeTracked(entry, \"directive.stale\", true);\n setStatusTracked(entry, {\n code: OtelStatusCode.ERROR,\n message: \"Span TTL exceeded — cleaned up\",\n });\n endSpan(entry);\n removeSpan(key);\n }\n }\n }\n\n function startSpan(\n name: string,\n attributes: Record<string, string | number | boolean>,\n parentEntry?: ActiveSpanEntry | null,\n ): { span: OtelSpan; entry: ActiveSpanEntry } {\n const spanId = generateId();\n const traceId = parentEntry?.traceId ?? generateTraceId();\n const parentSpanId = parentEntry?.spanId;\n\n let span: OtelSpan;\n\n if (isCollector) {\n span = (tracer as CollectorTracer).startSpan(name, {\n attributes,\n spanId,\n traceId,\n parentSpanId,\n });\n } else {\n span = tracer.startSpan(name, { attributes });\n }\n\n const entry: ActiveSpanEntry = {\n span,\n spanId,\n traceId,\n startTime: Date.now(),\n };\n\n // Track shadow data for external tracers\n if (!isCollector) {\n entry.shadow = {\n span,\n name,\n spanId,\n traceId,\n parentSpanId,\n attributes: { ...attributes },\n events: [],\n status: { code: OtelStatusCode.UNSET },\n startTime: entry.startTime,\n };\n }\n\n return { span, entry };\n }\n\n function endSpan(entry: ActiveSpanEntry): void {\n entry.span.end();\n\n if (config.onSpanEnd) {\n config.onSpanEnd(spanToData(entry));\n }\n }\n\n function spanToData(entry: ActiveSpanEntry): SpanData {\n if (entry.span instanceof CollectedSpan) {\n return entry.span.toSpanData();\n }\n\n // For external tracers, use shadow data\n if (entry.shadow) {\n const now = Date.now();\n\n return {\n name: entry.shadow.name,\n traceId: entry.shadow.traceId,\n spanId: entry.shadow.spanId,\n parentSpanId: entry.shadow.parentSpanId,\n attributes: { ...entry.shadow.attributes },\n events: [...entry.shadow.events],\n status: { ...entry.shadow.status },\n startTime: entry.shadow.startTime,\n endTime: now,\n durationMs: now - entry.shadow.startTime,\n };\n }\n\n // Fallback — should not happen\n const now = Date.now();\n\n return {\n name: \"unknown\",\n traceId: entry.traceId,\n spanId: entry.spanId,\n attributes: {},\n events: [],\n status: { code: OtelStatusCode.UNSET },\n startTime: entry.startTime,\n endTime: now,\n durationMs: now - entry.startTime,\n };\n }\n\n function setAttributeTracked(\n entry: ActiveSpanEntry,\n key: string,\n value: string | number | boolean,\n ): void {\n entry.span.setAttribute(key, value);\n if (entry.shadow) {\n entry.shadow.attributes[key] = value;\n }\n }\n\n function addEventTracked(\n entry: ActiveSpanEntry,\n name: string,\n attributes?: Record<string, string | number | boolean>,\n ): void {\n entry.span.addEvent(name, attributes);\n if (entry.shadow) {\n entry.shadow.events.push({ name, attributes, timestamp: Date.now() });\n }\n }\n\n function setStatusTracked(\n entry: ActiveSpanEntry,\n status: { code: OtelStatusCode; message?: string },\n ): void {\n entry.span.setStatus(status);\n if (entry.shadow) {\n entry.shadow.status = { ...status };\n }\n }\n\n function handleEvent(event: DebugEvent): void {\n if (!shouldInstrument(event.type)) {\n return;\n }\n\n cleanupStaleSpans();\n\n switch (event.type) {\n case \"agent_start\":\n handleAgentStart(event);\n break;\n case \"agent_complete\":\n handleAgentComplete(event);\n break;\n case \"agent_error\":\n handleAgentError(event);\n break;\n case \"guardrail_check\":\n handleGuardrailCheck(event);\n break;\n case \"constraint_evaluate\":\n handleConstraintEvaluate(event);\n break;\n case \"resolver_start\":\n handleResolverStart(event);\n break;\n case \"resolver_complete\":\n handleResolverComplete(event);\n break;\n case \"resolver_error\":\n handleResolverError(event);\n break;\n case \"pattern_start\":\n handlePatternStart(event);\n break;\n case \"pattern_complete\":\n handlePatternComplete(event);\n break;\n default:\n // Other events are recorded as span events on the active agent span\n if (event.agentId) {\n const found = findActiveSpan(\"agent\", event.agentId);\n if (found) {\n addEventTracked(found.entry, event.type, {\n \"event.id\": event.id,\n \"event.timestamp\": event.timestamp,\n });\n }\n }\n }\n }\n\n function handleAgentStart(event: AgentStartEvent): void {\n // Agent span is a child of the active pattern span (top of stack)\n const parentEntry =\n patternStack.length > 0 ? patternStack[patternStack.length - 1]! : null;\n\n const { entry } = startSpan(\n `${prefix}.agent.run`,\n {\n \"directive.service\": config.serviceName,\n \"directive.agent.name\": event.agentId,\n \"directive.agent.input_length\": event.inputLength,\n // GenAI semantic conventions\n \"gen_ai.operation.name\": \"agent.run\",\n \"gen_ai.agent.name\": event.agentId,\n },\n parentEntry,\n );\n\n const key = makeSpanKey(\"agent\", event.agentId);\n registerSpan(\"agent\", event.agentId, key, entry);\n }\n\n function handleAgentComplete(event: AgentCompleteEvent): void {\n const found = findActiveSpan(\"agent\", event.agentId);\n if (found) {\n setAttributeTracked(\n found.entry,\n \"directive.agent.output_length\",\n event.outputLength,\n );\n setAttributeTracked(\n found.entry,\n \"directive.agent.total_tokens\",\n event.totalTokens,\n );\n setAttributeTracked(\n found.entry,\n \"directive.agent.duration_ms\",\n event.durationMs,\n );\n // GenAI semantic conventions\n setAttributeTracked(\n found.entry,\n \"gen_ai.usage.total_tokens\",\n event.totalTokens,\n );\n\n setStatusTracked(found.entry, { code: OtelStatusCode.OK });\n endSpan(found.entry);\n removeSpan(found.key);\n }\n }\n\n function handleAgentError(event: AgentErrorEvent): void {\n const found = findActiveSpan(\"agent\", event.agentId);\n if (found) {\n setAttributeTracked(\n found.entry,\n \"directive.agent.duration_ms\",\n event.durationMs,\n );\n setAttributeTracked(\n found.entry,\n \"directive.agent.error\",\n event.errorMessage,\n );\n // GenAI semantic conventions\n setAttributeTracked(\n found.entry,\n \"gen_ai.error.message\",\n event.errorMessage,\n );\n\n setStatusTracked(found.entry, {\n code: OtelStatusCode.ERROR,\n message: event.errorMessage,\n });\n endSpan(found.entry);\n removeSpan(found.key);\n }\n }\n\n function handleGuardrailCheck(event: GuardrailCheckEvent): void {\n // Guardrail span is a child of the active agent span for this event's agent\n const parentEntry = event.agentId\n ? (findActiveSpan(\"agent\", event.agentId)?.entry ?? null)\n : null;\n\n const { entry } = startSpan(\n `${prefix}.guardrail.check`,\n {\n \"directive.service\": config.serviceName,\n \"directive.guardrail.name\": event.guardrailName,\n \"directive.guardrail.type\": event.guardrailType,\n \"directive.guardrail.passed\": event.passed,\n \"directive.guardrail.duration_ms\": event.durationMs,\n // GenAI semantic conventions\n \"gen_ai.guardrail.name\": event.guardrailName,\n \"gen_ai.guardrail.type\": event.guardrailType,\n \"gen_ai.guardrail.passed\": event.passed,\n },\n parentEntry,\n );\n\n if (event.reason) {\n setAttributeTracked(entry, \"directive.guardrail.reason\", event.reason);\n }\n\n setStatusTracked(entry, {\n code: event.passed ? OtelStatusCode.OK : OtelStatusCode.ERROR,\n message: event.passed ? undefined : event.reason,\n });\n endSpan(entry);\n }\n\n function handleConstraintEvaluate(event: ConstraintEvaluateEvent): void {\n // Constraints are lightweight — record as events on the active agent span\n if (event.agentId) {\n const found = findActiveSpan(\"agent\", event.agentId);\n if (found) {\n addEventTracked(found.entry, \"constraint_evaluate\", {\n \"directive.constraint.id\": event.constraintId,\n \"directive.constraint.fired\": event.fired,\n });\n\n return;\n }\n }\n\n // No parent span — create a standalone span\n const { entry } = startSpan(\n `${prefix}.constraint.evaluate`,\n {\n \"directive.service\": config.serviceName,\n \"directive.constraint.id\": event.constraintId,\n \"directive.constraint.fired\": event.fired,\n },\n null,\n );\n setStatusTracked(entry, { code: OtelStatusCode.OK });\n endSpan(entry);\n }\n\n function handleResolverStart(event: ResolverStartEvent): void {\n // Resolver spans can be children of the active agent span\n const agentParent = event.agentId\n ? (findActiveSpan(\"agent\", event.agentId)?.entry ?? null)\n : null;\n // Or fall back to pattern span (top of stack)\n const parentEntry =\n agentParent ??\n (patternStack.length > 0 ? patternStack[patternStack.length - 1]! : null);\n\n const { entry } = startSpan(\n `${prefix}.resolver.execute`,\n {\n \"directive.service\": config.serviceName,\n \"directive.resolver.id\": event.resolverId,\n \"directive.resolver.requirement_type\": event.requirementType,\n },\n parentEntry,\n );\n\n const key = makeSpanKey(\"resolver\", event.resolverId);\n registerSpan(\"resolver\", event.resolverId, key, entry);\n }\n\n function handleResolverComplete(event: ResolverCompleteEvent): void {\n const found = findActiveSpan(\"resolver\", event.resolverId);\n if (found) {\n setAttributeTracked(\n found.entry,\n \"directive.resolver.duration_ms\",\n event.durationMs,\n );\n setStatusTracked(found.entry, { code: OtelStatusCode.OK });\n endSpan(found.entry);\n removeSpan(found.key);\n }\n }\n\n function handleResolverError(event: ResolverErrorEvent): void {\n const found = findActiveSpan(\"resolver\", event.resolverId);\n if (found) {\n setAttributeTracked(\n found.entry,\n \"directive.resolver.duration_ms\",\n event.durationMs,\n );\n setAttributeTracked(\n found.entry,\n \"directive.resolver.error\",\n event.errorMessage,\n );\n setStatusTracked(found.entry, {\n code: OtelStatusCode.ERROR,\n message: event.errorMessage,\n });\n endSpan(found.entry);\n removeSpan(found.key);\n }\n }\n\n function handlePatternStart(event: PatternStartEvent): void {\n const parentEntry =\n patternStack.length > 0 ? patternStack[patternStack.length - 1]! : null;\n const { entry } = startSpan(\n `${prefix}.pattern.${event.patternType}`,\n {\n \"directive.service\": config.serviceName,\n \"directive.pattern.id\": event.patternId,\n \"directive.pattern.type\": event.patternType,\n },\n parentEntry,\n );\n\n const key = makeSpanKey(\"pattern\", event.patternId);\n registerSpan(\"pattern\", event.patternId, key, entry);\n // A3: Cap pattern stack to prevent overflow\n if (patternStack.length < MAX_PATTERN_STACK) {\n patternStack.push(entry);\n }\n }\n\n function handlePatternComplete(event: PatternCompleteEvent): void {\n const found = findActiveSpan(\"pattern\", event.patternId);\n if (found) {\n setAttributeTracked(\n found.entry,\n \"directive.pattern.duration_ms\",\n event.durationMs,\n );\n if (event.error) {\n setAttributeTracked(\n found.entry,\n \"directive.pattern.error\",\n event.error,\n );\n setStatusTracked(found.entry, {\n code: OtelStatusCode.ERROR,\n message: event.error,\n });\n } else {\n setStatusTracked(found.entry, { code: OtelStatusCode.OK });\n }\n endSpan(found.entry);\n removeSpan(found.key);\n\n // Remove from pattern stack\n const idx = patternStack.indexOf(found.entry);\n if (idx !== -1) {\n patternStack.splice(idx, 1);\n }\n }\n }\n\n return {\n attach(timeline: DebugTimeline): () => void {\n // A7: Prevent attaching to multiple timelines simultaneously\n if (attachedTimeline && attachedTimeline !== timeline) {\n throw new Error(\n \"[Directive OTEL] Plugin already attached to a different timeline. Create a new plugin instance.\",\n );\n }\n\n attachedTimeline = timeline;\n const unsub = timeline.subscribe(handleEvent);\n const cleanupInterval = setInterval(\n cleanupStaleSpans,\n Math.min(spanTtlMs, 60_000),\n );\n\n return () => {\n unsub();\n clearInterval(cleanupInterval);\n attachedTimeline = null;\n\n // Cleanup: end all active spans on detach\n for (const [_key, entry] of activeSpans) {\n setAttributeTracked(entry, \"directive.detached\", true);\n setStatusTracked(entry, {\n code: OtelStatusCode.ERROR,\n message: \"Plugin detached while span was active\",\n });\n endSpan(entry);\n }\n activeSpans.clear();\n spanKeyIndex.clear();\n patternStack.length = 0;\n };\n },\n\n getSpans(): SpanData[] {\n if (collectorTracer) {\n return [...collectorTracer.spans];\n }\n\n if (!warnedExternalGetSpans) {\n warnedExternalGetSpans = true;\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\"\n ) {\n console.warn(\n \"[Directive OTEL] getSpans() returns [] when using an external tracer. \" +\n \"Use the onSpanEnd callback to collect span data instead.\",\n );\n }\n }\n\n return [];\n },\n\n clearSpans(): void {\n collectorTracer?.clear();\n },\n\n getTracer(): OtelTracer {\n return tracer;\n },\n\n getActiveSpanCount(): number {\n return activeSpans.size;\n },\n };\n}\n","/**\n * OTel × Sources — emit source-lifecycle spans from `system.observe()`\n *\n * The R5 observability reviewer found `@directive-run/ai/otel.ts`\n * subscribes only to the AI `DebugTimeline` event stream — so the four\n * `ObservationEvent.source.*` variants (`source.attach`,\n * `source.publish`, `source.detach`, `source.error`) shipped by the\n * source primitive never reach the OTel exporter. SREs running with\n * `createOtelPlugin` see agent spans but cannot answer \"which source\n * is publishing?\" or \"did source `mcp` error attach?\" from their\n * tracing backend.\n *\n * This module closes the gap as a focused helper (NOT a second OTel\n * plugin) so a single `OtelTracer` can carry both AI and core source\n * spans. Wire it once at `createSystem` time:\n *\n * @example Wire source events into the same OTel tracer as the AI plugin\n * ```ts\n * import { trace } from \"@opentelemetry/api\";\n * import { createSystem } from \"@directive-run/core\";\n * import { createOtelPlugin, attachSourcesToOtel } from \"@directive-run/ai\";\n *\n * const tracer = trace.getTracer(\"directive-app\");\n * const otel = createOtelPlugin({ serviceName: \"my-app\", tracer });\n *\n * const system = createSystem({ module });\n * otel.attach(orchestrator.timeline); // existing AI wiring\n * const unsub = attachSourcesToOtel(system, { // NEW — source.* spans\n * tracer,\n * serviceName: \"my-app\",\n * });\n *\n * system.start();\n *\n * // Later\n * unsub();\n * ```\n *\n * Spans emitted:\n *\n * - `directive.source.attach` — short-duration (start → end same tick)\n * span with attributes `source.id`, `source.module_id`, plus\n * `attached_at` timestamp.\n * - `directive.source.publish` — short-duration counter span (NOT a\n * per-publish full span; events of this kind are emitted as\n * span EVENTS on a long-lived per-source \"active\" span so cardinality\n * stays bounded).\n * - `directive.source.detach` — short-duration span, ends the matching\n * \"active\" parent.\n * - `directive.source.error` — error-status span carrying the phase\n * (`attach`/`cleanup`/`runtime` per RFC 0008) and the truncated\n * message from R6/R7.\n *\n * Cardinality budget: ONE active span per (sourceId, moduleId) at a\n * time. Publishes attach as span events (cheap), not as new spans. At\n * 10 sources × 100 publishes/sec the exporter sees 1000 events/sec on\n * 10 long-lived spans — well within typical OTel collector budgets.\n */\n\nimport type { OtelSpan, OtelTracer } from \"./otel.js\";\nimport { OtelStatusCode as StatusCodeValues } from \"./otel.js\";\n\ninterface ObservableLike {\n observe(observer: (event: ObservationEventCompat) => void): () => void;\n}\n\n// Mirror the subset of ObservationEvent we read. Cast to this from any\n// System<...> so the helper works regardless of the system's generic\n// schema shape.\ntype ObservationEventCompat =\n | { type: \"source.attach\"; id: string; moduleId: string }\n | { type: \"source.publish\"; id: string; moduleId: string; eventName: string }\n | { type: \"source.detach\"; id: string; moduleId: string }\n | {\n type: \"source.error\";\n id: string;\n moduleId: string;\n phase: \"attach\" | \"cleanup\" | \"runtime\";\n error: unknown;\n }\n | { type: string; [key: string]: unknown };\n\nexport interface SourcesOtelOptions {\n /** Tracer to emit spans through. */\n tracer: OtelTracer;\n /** Service name attribute for every span. */\n serviceName: string;\n /** Span name prefix. Default: `\"directive.source\"`. */\n spanPrefix?: string;\n /**\n * Optional sampling for publish events. Sources at very high publish\n * rate (price ticks, cursor moves) may want to drop most publish\n * events from the trace. Default: `1.0` (every publish recorded as\n * an event on the active span).\n */\n publishSampleRate?: number;\n}\n\ninterface ActiveSpan {\n span: OtelSpan;\n startedAt: number;\n}\n\n/**\n * Subscribe to a system's source-lifecycle events and emit OTel spans\n * for each. Returns an unsubscribe to detach.\n *\n * @returns a function that detaches the OTel wiring without affecting\n * other observers.\n */\nexport function attachSourcesToOtel(\n system: unknown,\n options: SourcesOtelOptions,\n): () => void {\n const {\n tracer,\n serviceName,\n spanPrefix = \"directive.source\",\n publishSampleRate = 1.0,\n } = options;\n\n const activeByKey = new Map<string, ActiveSpan>();\n\n function keyOf(id: string, moduleId: string): string {\n return `${moduleId}::${id}`;\n }\n\n function commonAttrs(\n id: string,\n moduleId: string,\n ): Record<string, string | number | boolean> {\n return {\n \"service.name\": serviceName,\n \"source.id\": id,\n \"source.module_id\": moduleId,\n };\n }\n\n function handle(event: ObservationEventCompat): void {\n switch (event.type) {\n case \"source.attach\": {\n const id = event.id as string;\n const moduleId = event.moduleId as string;\n const span = tracer.startSpan(`${spanPrefix}.attached`, {\n attributes: {\n ...commonAttrs(id, moduleId),\n \"directive.attached\": true,\n },\n });\n activeByKey.set(keyOf(id, moduleId), { span, startedAt: Date.now() });\n break;\n }\n\n case \"source.publish\": {\n if (publishSampleRate < 1.0 && Math.random() > publishSampleRate) {\n break;\n }\n const id = event.id as string;\n const moduleId = event.moduleId as string;\n const eventName = (event as { eventName: string }).eventName;\n const active = activeByKey.get(keyOf(id, moduleId));\n if (!active) break;\n active.span.addEvent(\"publish\", {\n \"source.event_name\": eventName,\n \"timestamp.ms\": Date.now(),\n });\n break;\n }\n\n case \"source.detach\": {\n const id = event.id as string;\n const moduleId = event.moduleId as string;\n const active = activeByKey.get(keyOf(id, moduleId));\n if (!active) break;\n active.span.setStatus({ code: StatusCodeValues.OK });\n active.span.end();\n activeByKey.delete(keyOf(id, moduleId));\n break;\n }\n\n case \"source.error\": {\n const id = event.id as string;\n const moduleId = event.moduleId as string;\n const phase = (event as { phase: string }).phase;\n const errVal = (event as { error: unknown }).error;\n const message =\n errVal instanceof Error\n ? errVal.message\n : typeof errVal === \"string\"\n ? errVal\n : String(errVal);\n const errorSpan = tracer.startSpan(`${spanPrefix}.error`, {\n attributes: {\n ...commonAttrs(id, moduleId),\n \"directive.phase\": phase,\n \"error.message\": message,\n },\n });\n errorSpan.setStatus({\n code: StatusCodeValues.ERROR,\n message,\n });\n errorSpan.end();\n // Also surface the error as an event on the active span (if any)\n // so a viewer correlating attach→error→detach can see them\n // linked in one trace.\n const active = activeByKey.get(keyOf(id, moduleId));\n if (active) {\n active.span.addEvent(\"error\", {\n \"directive.phase\": phase,\n \"error.message\": message,\n });\n }\n break;\n }\n\n default:\n break;\n }\n }\n\n const unobserve = (system as ObservableLike).observe(handle);\n\n return () => {\n unobserve();\n // End every active source span the consumer subscribed for. Without\n // this, calling `unsubscribe()` mid-stream leaks spans (they stay\n // \"in-flight\" forever in collectors that retain unfinished spans).\n // Status `OK` with a `directive.detached: true` attribute marks the\n // close as observer-initiated rather than a normal detach.\n for (const [, active] of activeByKey) {\n active.span.setAttribute(\"directive.detached\", true);\n active.span.setStatus({ code: StatusCodeValues.OK });\n active.span.end();\n }\n activeByKey.clear();\n };\n}\n"]}
|