@juspay/neurolink 12.44.4 → 12.44.5
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/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
## [12.44.
|
|
1
|
+
## [12.44.5](https://github.com/juspay/neurolink/compare/v12.44.4...v12.44.5) (2026-10-02)
|
|
2
2
|
|
|
3
3
|
### Bug Fixes
|
|
4
4
|
|
|
5
|
-
- **(
|
|
5
|
+
- **(decide):** classify the image-wording over-length 400 as max_tokens_exceeded and record the measured limits ([4605bba](https://github.com/juspay/neurolink/commit/4605bba765fc39d8a1c0942c72e487193e59f930))
|
|
6
6
|
|
|
7
7
|
## [11.2.3](https://github.com/juspay/neurolink/compare/v11.2.2...v11.2.3) (2026-08-19)
|
|
8
8
|
|
package/README.md
CHANGED
|
@@ -390,8 +390,8 @@ Measured against TypeSafe's live API — don't extrapolate past these:
|
|
|
390
390
|
|
|
391
391
|
The figures above are TypeSafe's. Perplexity's Decisions API, measured on a real account in October 2026:
|
|
392
392
|
|
|
393
|
-
- Up to 128 questions and 8 images per request. The server reads under 262,144 input tokens (the state and the
|
|
394
|
-
- Latency grows faster than linearly with input: 3.9 s at 65,000 tokens, 10 s at 146,000, 22.9 s at 251,000 (about 17,000, 15,000 and 11,000 tokens per second). An image costs about one input token per 32 × 32 tile plus about 95
|
|
393
|
+
- Up to 128 questions and 8 images per request. The server reads under 262,144 input tokens (the state, the questions and the images all count; an image counts one token per 32 × 32 tile, measured) and refuses more with an explicit 400; it never cuts a state off silently.
|
|
394
|
+
- Latency grows faster than linearly with input: 3.9 s at 65,000 tokens, 10 s at 146,000, 22.9 s at 251,000 (about 17,000, 15,000 and 11,000 tokens per second). An image costs about one input token per 32 × 32 tile, plus about 95 to 103 tokens that look like fixed request overhead.
|
|
395
395
|
- 10 requests per second on the account tested; a 429 carries `Retry-After`, which NeuroLink honours.
|
|
396
396
|
- NeuroLink's own state window is 100,000 estimated tokens, a deliberate local limit and not the server's. The price, $0.04 per million input tokens (image tokens included, output free), is Perplexity's documented figure.
|
|
397
397
|
|
|
@@ -2154,7 +2154,7 @@ ${r}`:r}async retrieveKnowledgeGrounding(t){const r=this.knowledgeGroundingEngin
|
|
|
2154
2154
|
|
|
2155
2155
|
IMPORTANT: You have a tool called "${c.toolName}" that searches through`,`${c.filesLoaded} loaded document(s) containing ${c.chunksIndexed} indexed chunks.`,`ALWAYS use the "${c.toolName}" tool FIRST to answer the user's question before using any other tools.`,"This tool searches your local knowledge base of pre-loaded documents and is the primary source of truth.","Do NOT use websearchGrounding or any web search tools when the answer can be found in the loaded documents."].join(" ");t.systemPrompt=(t.systemPrompt||"")+l,m.info("[RAG] Tool injected into stream()",{toolName:c.toolName,filesLoaded:c.filesLoaded,chunksIndexed:c.chunksIndexed})}catch(a){m.warn("[RAG] Failed to prepare RAG tool, continuing without RAG",{error:a instanceof Error?a.message:String(a)})}const s=Hen(t),i=Wen(t);if(t.input?.text){const{toolResults:a,enhancedPrompt:c}=await this.detectAndExecuteTools(t.input.text,void 0);c!==t.input.text&&(i.input.text=c)}return{enhancedOptions:i,factoryResult:s}}async autoDisableOllamaStreamTools(t){if((t.provider==="ollama"||t.provider?.toLowerCase().includes("ollama"))&&!t.disableTools){const{ModelConfigurationManager:r}=await Promise.resolve().then(()=>(uf(),RHe)),s=r.getInstance().getProviderConfiguration("ollama")?.modelBehavior?.toolCapableModels||[],i=t.model;s.length>0&&i&&(s.some(c=>i.toLowerCase().includes(c.toLowerCase()))||(t.disableTools=!0,m.debug("Auto-disabled tools for Ollama model that doesn't support them (stream)",{model:t.model,toolCapableModels:s.slice(0,3)})))}}setupStreamEventListeners(){const t=[];let r=0;const n=(d,p)=>{t.push({type:d,seq:r++,timestamp:Date.now(),...p&&typeof p=="object"?p:{data:p}})},o=(...d)=>{const p=d[0];n("response:chunk",{content:p})},s=(...d)=>{const p=d[0];n("tool:start",{...p,toolName:p.toolName??p.tool})},i=(...d)=>{const p=d[0],h=p.toolName??p.tool,f=p.responseTime??p.duration,g=p.success??(p.error!==void 0?!1:void 0),y={...p,toolName:h,...f!==void 0?{responseTime:f}:{},...g!==void 0?{success:g}:{},...p.error!==void 0?{error:p.error}:{}};n("tool:end",y),y.result&&y.result.uiComponent===!0&&n("ui-component",{toolName:h,componentData:y.result,timestamp:Date.now(),...g!==void 0?{success:g}:{},...f!==void 0?{responseTime:f}:{}})},a=(...d)=>{n("ui-component",d[0])},c=(...d)=>{n("hitl:confirmation-request",d[0])},l=(...d)=>{n("hitl:confirmation-response",d[0])};return this.emitter.on("response:chunk",o),this.emitter.on("tool:start",s),this.emitter.on("tool:end",i),this.emitter.on("ui-component",a),this.emitter.on("hitl:confirmation-request",c),this.emitter.on("hitl:confirmation-response",l),{eventSequence:t,cleanup:()=>{this.emitter.off("response:chunk",o),this.emitter.off("tool:start",s),this.emitter.off("tool:end",i),this.emitter.off("ui-component",a),this.emitter.off("hitl:confirmation-request",c),this.emitter.off("hitl:confirmation-response",l)}}}async*handleStreamFallback(t,r,n,o,s,i){t.fallbackAttempted=!0;const a="Stream completed with 0 chunks (possible guardrails block)";t.error=a;try{const f=this._metricsTraceContext;let g=Pe.createGenerationSpan({provider:s,model:o.model||"unknown",name:`gen_ai.${s}.stream.failed`,traceId:f?.traceId,parentSpanId:f?.parentSpanId});g=Pe.endSpan(g,2),g.statusMessage=a,g.durationMs=0,this.metricsAggregator.recordSpan(g),ot().recordSpan(g)}catch{}const c=o.fallbackProvider?.trim()||void 0,l=o.fallbackModel?.trim()||void 0,u=process.env.FALLBACK_PROVIDER?.trim()||void 0,d=process.env.FALLBACK_MODEL?.trim()||void 0,p=YL.getFallbackRoute(n||o.input.text||"",{provider:s,model:o.model||"gpt-4o",reasoning:"primary failed",confidence:.5},{fallbackStrategy:"auto"}),h={...p,provider:c??u??p.provider,model:l??d??p.model};m.warn("Retrying with fallback provider",{originalProvider:s,fallbackProvider:h.provider,fallbackModel:h.model,fallbackSource:c||l?"options":u||d?"env":"model_config",reason:a});try{const f=await Un.createProvider(h.provider,h.model,!0,void 0,void 0,this.resolveCredentials(o.credentials));f.setupToolExecutor({customTools:this.getCustomTools(),executeTool:(x,k)=>this.executeTool(x,k,{disableToolCache:o.disableToolCache})},"NeuroLink.fallbackStream");const g=o.conversationMessages!==void 0?o.conversationMessages:await Rm(this.conversationMemory,{prompt:o.input.text,context:o.context});f.setFileToolRootPolicy?.(this.fileToolRootsFor(o));const y=await f.stream({...this.deferProviderStreamTTS(o),model:h.model,conversationMessages:g}),v=y.toolCalls??[],T=y.toolResults??[];(v.length>0||T.length>0)&&(r.toolCalls=v,r.toolResults=T,r.finishReason=y.finishReason??r.finishReason);let b=0,_=0;for await(const x of y.stream){b++;const k=x!==null&&typeof x=="object"&&"metadata"in x&&x.metadata?.noOutput===!0,A=x&&"content"in x&&typeof x.content=="string"&&x.content.length>0,R=x!==null&&typeof x=="object"&&"type"in x&&(x.type==="audio"||x.type==="tts_audio"||x.type==="image");!k&&(A||R)&&_++,x&&"content"in x&&typeof x.content=="string"&&(i(x.content),this.emitter.emit("response:chunk",x.content)),yield x}if(_===0&&v.length===0&&T.length===0)throw new Error(`Fallback provider ${h.provider} also returned 0 real output chunks (chunkCount=${b}, sentinel-only or empty)`);t.fallbackProvider=h.provider,t.fallbackModel=h.model,t.guardrailsBlocked=!0}catch(f){const g=f instanceof Error?f.message:String(f);throw t.error=`${a}; Fallback failed: ${g}`,m.error("Fallback provider failed",{fallbackProvider:h.provider,error:g}),f}}async storeStreamConversationMemory(t){const{enhancedOptions:r,providerName:n,originalPrompt:o,accumulatedContent:s,startTime:i,eventSequence:a}=t;m.shouldLog("debug")&&m.debug("[NeuroLink.stream] Preparing to store conversation turn in memory",{options:XR(ZR(r)),sessionId:r.context?.sessionId});const c=a.some(l=>l.type==="tool:start"||l.type==="tool:end");if(!s.trim()&&!c){m.warn("[NeuroLink.stream] Skipping conversation turn storage \u2014 no text content or tool activity",{sessionId:r.context?.sessionId});return}if(m.shouldLog("debug")&&m.debug("[NeuroLink.stream] Storing conversation turn in memory",{options:XR(ZR(r)),sessionId:r.context?.sessionId,conversationMemoryExists:!!this.conversationMemory}),this.conversationMemory&&r.context?.sessionId){const l=r.context?.sessionId,u=r.context?.userId;let d;r.model&&(d={provider:n,model:r.model});const p=Date.now();try{const h=this.drainPendingSkillMessages(l);await this.conversationMemory.storeConversationTurn({sessionId:l,userId:u,userMessage:o??"",aiResponse:s,startTimeStamp:new Date(i),providerDetails:d,enableSummarization:r.enableSummarization,events:a.length>0?a:void 0,requestId:r.context?.requestId,...h.length>0?{skillMessages:h}:{}}),this.recordMemorySpan("memory.store",{"memory.operation":"store","memory.path":"stream"},Date.now()-p,1),m.debug("[NeuroLink.stream] Stored conversation turn with events",{sessionId:l,eventCount:a.length,eventTypes:[...new Set(a.map(f=>f.type))]})}catch(h){this.recordMemorySpan("memory.store",{"memory.operation":"store","memory.path":"stream"},Date.now()-p,2,h instanceof Error?h.message:String(h)),m.warn("Failed to store stream conversation turn",{error:h instanceof Error?h.message:String(h)})}}this.shouldWriteMemory(r.memory,r.context?.userId,s)&&this.storeMemoryInBackground(o??"",s.trim(),r.context?.userId,r.memory?.additionalUsers,r.context)}async validateStreamInput(t){const r=process.hrtime.bigint();m.debug("[NeuroLink] \u{1F3AF} LOG_POINT_003_VALIDATION_START",{logPoint:"003_VALIDATION_START",validationStartTimeNs:r.toString(),message:"Starting comprehensive input validation process"});const n=typeof t?.input?.text=="string"&&t.input.text.trim().length>0,o=!!(t?.input?.audio&&t.input.audio.frames&&typeof t.input.audio.frames[Symbol.asyncIterator]=="function"),s=!!(t?.stt?.enabled&&t?.stt?.audio);if(!n&&!o&&!s)throw new Error("Stream options must include either input.text, input.audio, or stt.audio")}emitStreamStartEvents(t,r){this.emitter.emit("stream:start",{provider:t.provider||"auto",timestamp:r}),this.emitter.emit("response:start"),this.emitter.emit("message",`Starting ${t.provider||"auto"} stream...`)}async createMCPStream(t){const r=await Rw(t.provider),n=await Un.createProvider(r,t.model,!t.disableTools,this,t.region,this.resolveCredentials(t.credentials));await n.ensureModelLimits?.(),n.setTraceContext(this._metricsTraceContext),n.setupToolExecutor({customTools:this.getCustomTools(),executeTool:(f,g)=>this.executeTool(f,g,{disableToolCache:t.disableToolCache})},"NeuroLink.createMCPStream");let o=await this.getAllAvailableTools();o=this.applyToolInfoFiltering(o,t),Sr.getDescriptor(r)?.toolSupport==="none"&&(o=[]);const s=t.skipToolPromptInjection?t.systemPrompt||"":this.createToolAwareSystemPrompt(t.systemPrompt,o,n.supportsTools?.()??!0),i=t.conversationMessages!==void 0,a=i?t.conversationMessages:await Rm(this.conversationMemory,{...t,prompt:t.input.text,context:t.context});t.conversationMessages=a;let c=a;const l=Ji({provider:r,model:t.model,maxTokens:t.maxTokens,systemPrompt:s,conversationMessages:c,currentPrompt:t.input.text,toolDefinitions:o,compactionThreshold:t.compactionThreshold}),u=c?.length||0,d=this.getCompactionSessionId(t),p=u>0;if(!l.withinBudget&&!p){try{this.emitter.emit("compaction.insufficient",{stagesAttempted:["pre-dispatch hard cap"],finalTokens:l.estimatedInputTokens,budget:l.availableInputTokens,provider:r,model:t.model,phase:"pre-dispatch-no-recovery",timestamp:Date.now()})}catch{}throw new ba(`Stream context exceeds model budget and no compaction is possible (no conversationMemory, no inline conversationMessages \u2014 only prompt + tools). Estimated: ${l.estimatedInputTokens} tokens, budget: ${l.availableInputTokens} tokens. Reduce prompt or tool-definition size, or trim the request.`,{estimatedTokens:l.estimatedInputTokens,availableTokens:l.availableInputTokens,stagesUsed:[],breakdown:l.breakdown})}if(l.shouldCompact&&(i||this.conversationMemory)&&u>(this.lastCompactionMessageCount.get(d)??0)){const g=await new rw({provider:r,summarizationProvider:this.conversationMemoryConfig?.conversationMemory?.summarizationProvider,summarizationModel:this.conversationMemoryConfig?.conversationMemory?.summarizationModel},this.contextCompactorDeps()).compact(c,ZD(l,t.compactionThreshold),this.conversationMemoryConfig?.conversationMemory,t.context?.requestId,{currentRequest:t.input.text});g.compacted&&(c=ew(g.messages).messages,t.conversationMessages=c,this.lastCompactionMessageCount.set(d,c.length));const y=Ji({provider:r,model:t.model,maxTokens:t.maxTokens,systemPrompt:s,conversationMessages:c,currentPrompt:t.input.text,toolDefinitions:o});if(!y.withinBudget){m.warn("[NeuroLink] Stream: post-compaction still over budget, emergency truncation",{estimatedTokens:y.estimatedInputTokens,availableTokens:y.availableInputTokens,overagePercent:Math.round((y.usageRatio-1)*100)});try{this.emitter.emit("compaction.insufficient",{stagesAttempted:g.stagesUsed,finalTokens:y.estimatedInputTokens,budget:y.availableInputTokens,provider:r,model:t.model,phase:"mid-compaction",willEmergencyTruncate:!0,timestamp:Date.now()})}catch{}c=ate(c,y.availableInputTokens,y.breakdown,r),t.conversationMessages=c;const v=Ji({provider:r,model:t.model,maxTokens:t.maxTokens,systemPrompt:s,conversationMessages:c,currentPrompt:t.input.text,toolDefinitions:o});if(!v.withinBudget){this.lastCompactionMessageCount.delete(d);try{this.emitter.emit("compaction.insufficient",{stagesAttempted:g.stagesUsed,finalTokens:v.estimatedInputTokens,budget:v.availableInputTokens,provider:r,model:t.model,phase:"post-emergency-truncation",timestamp:Date.now()})}catch{}throw new ba(`Stream context exceeds model budget after all compaction stages. Estimated: ${v.estimatedInputTokens} tokens, Budget: ${v.availableInputTokens} tokens.`,{estimatedTokens:v.estimatedInputTokens,availableTokens:v.availableInputTokens,stagesUsed:g.stagesUsed,breakdown:v.breakdown})}}}if(this.modelPool){const f=this.modelPool,g=f.maxAttempts,y=new Set;let v=null;for(let T=0;T<g;T++){if(t.abortSignal?.aborted)throw new DOMException("The operation was aborted","AbortError");const b=f.selectNext(y);if(!b)break;y.add(f.memberKey(b));const _=b.provider,x=b.model??void 0,k=b.region??void 0;m.debug(`[createMCPStream] ModelPool: attempting member ${_}`,{model:x,attempt:T});try{const A=await Un.createProvider(_,x,!t.disableTools,this,k,this.resolveCredentials(t.credentials));A.setTraceContext(this._metricsTraceContext),A.setupToolExecutor({customTools:this.getCustomTools(),executeTool:(O,B)=>this.executeTool(O,B,{disableToolCache:t.disableToolCache})},"NeuroLink.createMCPStream"),A.setFileToolRootPolicy?.(this.fileToolRootsFor(t));const R=await A.stream({...this.deferProviderStreamTTS(t),provider:_,model:x,region:k,systemPrompt:s,conversationMessages:c});m.debug("[createMCPStream] ModelPool stream handle obtained",{provider:_});const I=b,M=(async function*(){try{yield*R.stream,f.recordSuccess(I)}catch(O){throw f.recordFailure(I,Mw(O)),O}})();return H2(R,{...R,stream:M,provider:_,model:R.model||x,toolCalls:R.toolCalls??[],toolResults:R.toolResults??[]})}catch(A){if(cr(A))throw A;if(cae(A)){const R=A instanceof Error?A.message:String(A);throw f.recordFailure(b,Mw(A)),new Error(`[ModelPool] non-retryable: ${R}`,{cause:A})}f.recordFailure(b,Mw(A)),v=A instanceof Error?A:new Error(String(A)),m.warn(`[createMCPStream] ModelPool: member ${_} failed`,{error:v.message})}}throw new Error(`[ModelPool] all stream members failed: ${v?.message??"no stream members available"}`)}n.setFileToolRootPolicy?.(this.fileToolRootsFor(t));const h=await n.stream({...this.deferProviderStreamTTS(t),systemPrompt:s,conversationMessages:c});return m.debug("[createMCPStream] Stream created successfully",{provider:r,systemPromptPassedLength:s.length}),H2(h,{...h,provider:r,model:h.model||t.model,toolCalls:h.toolCalls??[],toolResults:h.toolResults??[]})}async processStreamResult(t,r,n){return{content:"",usage:void 0,finishReason:"stop",toolCalls:[],toolResults:[],analytics:void 0,evaluation:void 0}}emitStreamEndEvents(t){this.emitter.emit("stream:end",{responseTime:Date.now(),timestamp:Date.now()}),this.emitter.emit("response:end",t.content||"")}createStreamResponse(t,r,n){const o=n.sourceResult,s={streamId:n.streamId,startTime:n.startTime,responseTime:n.responseTime,fallback:n.fallback||!1,guardrailsBlocked:n.guardrailsBlocked,error:n.error},i={...o??{},stream:r,provider:o?.provider??n.providerName,model:o?.model??n.options.model,usage:t.usage,finishReason:t.finishReason,analytics:t.analytics,evaluation:t.evaluation,events:n.events&&n.events.length>0?n.events:void 0,metadata:o?void 0:Object.assign({},s)},a=Object.getOwnPropertyDescriptor(t,"toolCalls");a&&Object.defineProperty(i,"toolCalls",a);const c=Object.getOwnPropertyDescriptor(t,"toolResults");if(c&&Object.defineProperty(i,"toolResults",c),!o)return i;const l=new Set(["finishReason","stopReason","rawFinishReason","toolCalls","toolResults"]);for(const u of Object.getOwnPropertyNames(o)){const d=Object.getOwnPropertyDescriptor(o,u);!l.has(u)&&d&&typeof d.get=="function"&&Object.defineProperty(i,u,d)}return Object.defineProperty(i,"metadata",{enumerable:!0,configurable:!0,get:()=>(o.metadata===void 0&&(o.metadata={}),Object.assign(o.metadata,s)),set:u=>{o.metadata=u}}),i}async handleStreamError(t,r,n,o,s,i){if(t instanceof ba)throw t;m.error("Stream generation failed, attempting fallback",{error:t instanceof Error?t.message:String(t)});try{this.emitter.emit("stream:error",{content:t instanceof Error?t.message:String(t),metadata:{errorName:t instanceof Error?t.name:"UnknownError",durationMs:Date.now()-n,chunkCount:0},provider:r.provider||"unknown",model:r.model||"unknown"})}catch{}const a=r.input.text,c=Date.now()-n,l=await Rw(r.provider),u=await Un.createProvider(l,r.model,!0,void 0,void 0,this.resolveCredentials(r.credentials));u.setFileToolRootPolicy?.(this.fileToolRootsFor(r));const d=await u.stream({input:{text:r.input.text},model:r.model,temperature:r.temperature,maxTokens:r.maxTokens,conversationMessages:r.conversationMessages});let p="";return{stream:(async function*(f){try{for await(const g of d.stream)g&&"content"in g&&typeof g.content=="string"&&(p+=g.content,f.emitter.emit("response:chunk",g.content)),yield g}finally{if(p.trim()){m.info("[NeuroLink.handleStreamError] stream() - COMPLETE SUCCESS (fallback)",{provider:l,model:r.model,responseTimeMs:Date.now()-n,contentLength:p.length});try{const g=r.model||"unknown",y=Date.now()-n;f.emitter.emit("stream:complete",{content:p,provider:l,model:g,finishReason:"stop",metadata:{durationMs:y,chunkCount:0,totalLength:p.length,isFallback:!0,finishReason:"stop"}}),f.emitter.emit("generation:end",{provider:l,model:g,responseTime:y,timestamp:Date.now(),result:{content:p,usage:{input:0,output:0,total:0},model:g,provider:l,finishReason:"stop"},success:!0,pipelineAHandled:!0})}catch{}}if(f.conversationMemory&&s?.context?.sessionId&&p.trim()){const g=s?.context?.sessionId,y=s?.context?.userId;let v;r.model&&(v={provider:l,model:r.model});const T=Date.now();try{const b=g||r.context?.sessionId,_=f.drainPendingSkillMessages(b);await f.conversationMemory.storeConversationTurn({sessionId:b,userId:y||r.context?.userId,userMessage:a??"",aiResponse:p,startTimeStamp:new Date(n),providerDetails:v,enableSummarization:s?.enableSummarization,requestId:s?.context?.requestId||r.context?.requestId,..._.length>0?{skillMessages:_}:{}}),f.recordMemorySpan("memory.store",{"memory.operation":"store","memory.path":"fallback-stream"},Date.now()-T,1)}catch(b){f.recordMemorySpan("memory.store",{"memory.operation":"store","memory.path":"fallback-stream"},Date.now()-T,2,b instanceof Error?b.message:String(b)),m.warn("Failed to store fallback stream conversation turn",{error:b instanceof Error?b.message:String(b)})}}}})(this),provider:l,model:r.model,usage:d.usage,finishReason:d.finishReason||"stop",toolCalls:d.toolCalls||[],toolResults:d.toolResults||[],analytics:d.analytics,evaluation:d.evaluation,metadata:{streamId:o,startTime:n,responseTime:c,fallback:!0}}}getEventEmitter(){return this.emitter}hasPendingHITLConfirmation(t){return this.hitlManager?.hasPendingConfirmation(t)??!1}getToolDedupConfig(){return this.toolDedupConfig}fileToolRootsFor(t){return F7(t)??this.resolveFileToolRoots(t.toolRoots)}workerToolsConfig(t){const r=this.toolsConfig?.fileRoots;if(t?.fileRoots===void 0)return r===void 0?t:{...t,fileRoots:r};const n=Y4({perCall:t.fileRoots,instance:r}).roots;return{...t,fileRoots:n?[...n]:[]}}resolveFileToolRoots(t){return Y4({perCall:t,instance:this.toolsConfig?.fileRoots})}getToolsConfig(){return this.toolsConfig}getDiscoveryPins(t){const r=this.discoveryPins.get(t);return r?(this.discoveryPins.delete(t),this.discoveryPins.set(t,r),r):new Set}pinDiscoveredTools(t,r){let n=this.discoveryPins.get(t);n?this.discoveryPins.delete(t):n=new Set,this.discoveryPins.set(t,n);for(const o of r)n.add(o);if(this.discoveryPins.size>1e3){const o=this.discoveryPins.keys().next().value;o!==void 0&&this.discoveryPins.delete(o)}}async checkCredentials(t){const{provider:r,model:n}=t,o="ping";try{return await this.generate({provider:r,...n&&{model:n},input:{text:o},maxTokens:16,disableTools:!0}),{provider:r,status:"ok",detail:"credentials valid"}}catch(s){const i=s instanceof Error?s.message:String(s),a=i.toLowerCase();return s instanceof M0?{provider:r,status:"denied",detail:i}:a.includes("authentication")||a.includes("401")||a.includes("invalid api key")||a.includes("incorrect api key")||a.includes("api_key_invalid")||a.includes("token has expired")||a.includes("expired credentials")?{provider:r,status:"expired",detail:i}:a.includes("not configured")||a.includes("missing api")||a.includes("api key is required")||a.includes("no api key")||a.includes("application default credentials")||a.includes("google_application_credentials")||a.includes("project_id")||a.includes("default credentials")||a.includes("service account")?{provider:r,status:"missing",detail:i}:a.includes("econnrefused")||a.includes("enotfound")||a.includes("could not resolve")||a.includes("timeout")||a.includes("network")||a.includes("cannot connect")?{provider:r,status:"network",detail:i}:{provider:r,status:"unknown",detail:i}}}emitToolStart(t,r,n=Date.now()){const o=`${t}-${n}-${Math.random().toString(36).substr(2,9)}`,s={executionId:o,tool:t,startTime:n,metadata:{inputType:typeof r,hasInput:r!=null}};return this.activeToolExecutions.set(o,s),this.currentStreamToolExecutions.push(s),this.emitter.emit("tool:start",dv(t,{input:r,timestamp:n,executionId:o})),m.debug(`tool:start emitted for ${t}`,{toolName:t,executionId:o,timestamp:n,inputProvided:r!==void 0}),o}emitToolEnd(t,r,n,o,s=Date.now(),i){const a=o||s-1e3,c=s-a,l=!n;let u;i?u=this.activeToolExecutions.get(i):u=Array.from(this.activeToolExecutions.values()).find(h=>h.tool===t&&!h.endTime);const d=i||u?.executionId||`${t}-${a}-fallback-${Math.random().toString(36).substr(2,9)}`;u&&(u.endTime=s,u.result=r,u.error=n,this.activeToolExecutions.delete(u.executionId));const p={tool:t,startTime:a,endTime:s,duration:c,success:l,result:r,error:n,executionId:d,metadata:{toolCategory:"custom"}};this.toolExecutionHistory.push(p),this.emitter.emit("tool:end",dv(t,{result:r,error:n,success:l,responseTime:c,timestamp:s,duration:c,executionId:d})),m.debug(`tool:end emitted for ${t}`,{toolName:t,executionId:d,duration:c,success:l,hasResult:r!==void 0,hasError:!!n})}getCurrentToolExecutions(){return[...this.currentStreamToolExecutions]}getToolExecutionHistory(){return[...this.toolExecutionHistory]}clearCurrentStreamExecutions(){this.currentStreamToolExecutions=[]}registerTool(t,r,n){this.invalidateToolCache(),this.emitter.emit("tools-register:start",{toolName:t,timestamp:Date.now()});try{if(!t||typeof t!="string")throw new Error("Invalid tool name");if(!r||typeof r!="object")throw new Error(`Invalid tool object provided for tool: ${t}`);if(typeof r.execute!="function")throw new Error(`Tool '${t}' must have an execute method.`);if(t.trim()==="")throw new Error("Tool name cannot be empty");if(t.length>100)throw new Error("Tool name is too long (maximum 100 characters)");if(/[\x00-\x1F\x7F]/.test(t))throw new Error("Tool name contains invalid control characters");const o={name:r.name||t,description:r.description||t,execute:r.execute,inputSchema:"parameters"in r&&r.parameters&&(oH(r.parameters)||typeof r.parameters=="object")?r.parameters:r.inputSchema||{}};if(n?.timeout!==void 0&&n.timeout>0&&Number.isFinite(n.timeout)&&typeof o.execute=="function"){const i=o.execute,a=n.timeout,c=t;o.execute=async(...l)=>{const u=AbortSignal.timeout(a),d=l[1],p=d?.abortSignal,h=p?AbortSignal.any([p,u]):u,f={...d,abortSignal:h};return Promise.race([i(l[0],f),new Promise((g,y)=>{h.addEventListener("abort",()=>{u.aborted?y(he.toolTimeout(c,a)):y(new DOMException("The operation was aborted","AbortError"))},{once:!0})})])}}const s=XYr(t,o,n?.timeout,n?.maxRetries,n?.totalTimeoutMs);this.toolRegistry.registerServer(s),n?.cacheable===!1?this.uncacheableTools.add(t):this.uncacheableTools.delete(t),this.emitter.emit("tools-register:end",{toolName:t,success:!0,timestamp:Date.now(),timeoutMs:n?.timeout})}catch(o){throw m.error(`Failed to register tool ${t}:`,o),o}}setToolContext(t){this.toolExecutionContext={...t},m.debug("Tool execution context updated",{sessionId:t.sessionId,contextKeys:Object.keys(t),hasJuspayToken:!!t.juspayToken,hasShopId:!!t.shopId})}getToolContext(){return this.toolExecutionContext?{...this.toolExecutionContext}:void 0}clearToolContext(){this.toolExecutionContext=void 0,m.debug("Tool execution context cleared")}registerTools(t){if(Array.isArray(t))for(const{name:r,tool:n}of t)this.registerTool(r,n);else for(const[r,n]of Object.entries(t))this.registerTool(r,n)}unregisterTool(t){this.invalidateToolCache();const r=`custom-tool-${t}`,n=this.toolRegistry.unregisterServer(r);return n&&(this.uncacheableTools.delete(t),m.info(`Unregistered custom tool: ${t}`)),n}useToolMiddleware(t){return this.mcpToolMiddlewares.push(t),m.debug(`[NeuroLink] Registered tool middleware (total: ${this.mcpToolMiddlewares.length})`),this}getToolMiddlewares(){return[...this.mcpToolMiddlewares]}async flushToolBatch(){this.mcpToolBatcher&&await this.mcpToolBatcher.flush()}getMCPEnhancementsConfig(){return this.mcpEnhancementsConfig}async updateAgenticLoopReport(t,r,n){if(!this.conversationMemory)throw new Fa("Conversation memory is not initialized. Enable conversationMemory in NeuroLink options.","CONFIG_ERROR");if(!("updateAgenticLoopReport"in this.conversationMemory)||typeof this.conversationMemory.updateAgenticLoopReport!="function")throw new Fa("updateAgenticLoopReport is only supported with Redis conversation memory.","CONFIG_ERROR");await ze(this.conversationMemory.updateAgenticLoopReport(t,n,r),5e3)}getCustomTools(){const t=this.toolRegistry.getToolsByCategory(Yi({isCustomTool:!0})),r=new Map;for(const o of t){const s=o.inputSchema||o.parameters;m.debug("Processing tool schema for Claude",{toolName:o.name,hasDescription:!!o.description,description:o.description,hasParameters:!!o.parameters,parametersType:typeof o.parameters,parametersKeys:o.parameters&&typeof o.parameters=="object"?Object.keys(o.parameters):"NOT_OBJECT",hasInputSchema:!!o.inputSchema,inputSchemaType:typeof o.inputSchema,inputSchemaKeys:o.inputSchema&&typeof o.inputSchema=="object"?Object.keys(o.inputSchema):"NOT_OBJECT",hasEffectiveSchema:!!s,effectiveSchemaType:typeof s,effectiveSchemaHasProperties:!!s?.properties,effectiveSchemaHasRequired:!!s?.required,originalInputSchema:o.inputSchema,phase:"AFTER_SCHEMA_FIX",timestamp:Date.now()}),r.set(o.name,{name:o.name,description:o.description||"",inputSchema:typeof o.inputSchema=="object"&&o.inputSchema!==null?o.inputSchema:typeof o.parameters=="object"&&o.parameters!==null?o.parameters:{},execute:async(i,a)=>{const c=this.toolExecutionContext||{},l=a&&Qt(a)?a:{},u={...c,...l,sessionId:l.sessionId||c.sessionId||`fallback-${Date.now()}`};return m.debug("Tool execution context merged",{toolName:o.name,storedContextKeys:Object.keys(c),runtimeContextKeys:Object.keys(l),finalContextKeys:Object.keys(u),hasJuspayToken:!!u.juspayToken,hasShopId:!!u.shopId,sessionId:u.sessionId}),await this.toolRegistry.executeTool(o.name,i,u)}})}this.cachedFileTools||(this.cachedFileTools=uFt(this.fileRegistry));const n=this.cachedFileTools;for(const[o,s]of Object.entries(n))if(!r.has(o)){const i=s,a=i.inputSchema??i.parameters;r.set(o,{name:o,description:s.description||`File tool: ${o}`,inputSchema:typeof a=="object"&&a!==null?a:{type:"object",properties:{}},execute:async c=>await s.execute(c,{toolCallId:`file-tool-${Date.now()}`,messages:[]})})}return r}async addInMemoryMCPServer(t,r){this.invalidateToolCache();try{re.debug(`[NeuroLink] Registering in-memory MCP server: ${t}`),r.tools||(r.tools=[]),await this.toolRegistry.registerServer(r),re.info(`[NeuroLink] Successfully registered in-memory server: ${t}`,{category:r.metadata?.category,provider:r.metadata?.provider,version:r.metadata?.version})}catch(n){throw re.error(`[NeuroLink] Failed to register in-memory server ${t}:`,n),n}}getInMemoryServers(){const t=this.getInMemoryServerInfos(),r=new Map;for(const n of t)r.set(n.id,n);return r}getInMemoryServerInfos(){return this.toolRegistry.getBuiltInServerInfos().filter(r=>Yi({existingCategory:r.metadata?.category,serverId:r.id})==="in-memory")}getAutoDiscoveredServerInfos(){return this.autoDiscoveredServerInfos}async executeTool(t,r={},n){if(this.mcpToolBatcher&&!n?.bypassBatcher)return this.mcpToolBatcher.execute(t,r);const o=this.createToolExecutionContext(t,r,n);return Be.mcp.startActiveSpan("neurolink.tool.execute",{attributes:{"tool.name":t,"tool.type":o.toolType,"tool.input_size":o.inputSize,"tool.input_preview":o.truncatedInput}},s=>this.executeToolWithSpan(t,r,n,o,s))}createToolExecutionContext(t,r,n){const o=this.externalServerManager.getAllTools().find(l=>l.name===t),s=o?"mcp":this.getCustomTools().has(t)?"custom":"external",i=r?ay(r):"",a=Date.now(),c=`${t}-${a}-${Math.random().toString(36).slice(2,11)}`;return{functionTag:"NeuroLink.executeTool",executionStartTime:a,executionId:c,externalTool:o,toolType:s,inputSize:i.length,truncatedInput:i.length>2048?i.substring(0,2048):i,options:n,hitlState:{triggered:!1}}}async executeToolWithSpan(t,r,n,o,s){try{const i=await this.prepareToolExecutionState(t,r,n,o);return await this.runPreparedToolExecution(t,r,i,o,s)}catch(i){if(!(i instanceof Oe)){const a=i instanceof Error?i.message:String(i);s.recordException(i instanceof Error?i:new Error(a)),s.setStatus({code:Ue.ERROR,message:a})}throw i}finally{s.end()}}async prepareToolExecutionState(t,r,n,o){m.debug(`[${o.functionTag}] Tool execution requested:`,{toolName:t,params:Qt(r)?LWe(r):r,hasExternalManager:!!this.externalServerManager}),m.debug("Tool execution detailed analysis",{toolName:t,executionStartTime:o.executionStartTime,paramsAnalysis:{type:typeof r,isNull:r===null,isUndefined:r===void 0,isEmpty:r&&typeof r=="object"&&Object.keys(r).length===0,keys:r&&typeof r=="object"?Object.keys(r):"NOT_OBJECT",keysLength:r&&typeof r=="object"?Object.keys(r).length:0},isTargetTool:t==="juspay-analytics_SuccessRateSRByTime",options:n,hasExternalManager:!!this.externalServerManager}),this.emitter.emit("tool:start",dv(t,{timestamp:o.executionStartTime,input:r,executionId:o.executionId}));const s=this.toolRegistry.getToolInfo(t),i=n?.timeout??s?.tool?.timeoutMs??fc.EXECUTION_BATCH_MS,a=n?.maxRetries??s?.tool?.maxRetries??ts.DEFAULT,c=n?.retryDelayMs||Gn.BASE_MS,l={timeout:i,maxRetries:a,totalTimeout:n?.totalTimeoutMs??s?.tool?.totalTimeoutMs??i*(a+1)+c*a,retryDelayMs:c,authContext:n?.authContext,disableToolCache:n?.disableToolCache},{MemoryManager:u}=await Promise.resolve().then(()=>(x1(),Dw)),d=u.getMemoryUsageMB(),h=`${o.externalTool?.serverId||s?.tool?.serverId||"unknown"}.${t}`;let f=this.toolCircuitBreakers.get(h);f||(f=new KR(WC.FAILURE_THRESHOLD,K$),this.toolCircuitBreakers.set(h,f));let g=this.toolExecutionMetrics.get(t);return g||(g={totalExecutions:0,successfulExecutions:0,failedExecutions:0,averageExecutionTime:0,lastExecutionTime:0,errorCategories:{}},this.toolExecutionMetrics.set(t,g)),g.totalExecutions++,{finalOptions:l,startMemory:d,circuitBreaker:f,breakerKey:h,metrics:g}}async runPreparedToolExecution(t,r,n,o,s){let i=0;try{re.debug(`[${o.functionTag}] Executing tool: ${t}`,{toolName:t,params:r,options:n.finalOptions,circuitBreakerState:n.circuitBreaker.getState()});const a=n.finalOptions.maxRetries+1,c=n.finalOptions.totalTimeout,l=Date.now(),u=l+c;let d=0;const p=await n.circuitBreaker.execute(async()=>GTe(async()=>{d++;const h=u-Date.now();if(h<=0)throw he.toolTimeout(t,c,void 0,{attempt:d,maxAttempts:a,attemptTimeoutMs:n.finalOptions.timeout,totalTimeoutMs:c,elapsedMs:Date.now()-l,exhausted:!0});const f=Math.min(n.finalOptions.timeout,h);return ze(this.executeToolInternal(t,r,n.finalOptions,o.hitlState),f,he.toolTimeout(t,f,void 0,{attempt:d,maxAttempts:a,attemptTimeoutMs:n.finalOptions.timeout,totalTimeoutMs:c,elapsedMs:Date.now()-l}))},{maxAttempts:a,delayMs:n.finalOptions.retryDelayMs,isRetriable:h=>Date.now()+n.finalOptions.retryDelayMs<u&&k8(h),onRetry:(h,f)=>{i=h,re.warn(`[${o.functionTag}] Retrying tool execution (attempt ${h})`,{toolName:t,error:f.message,attempt:h})}}));return s.setAttribute("tool.retry_count",i),await this.handleSuccessfulToolExecution(t,p,n,o,s)}catch(a){return s.setAttribute("tool.retry_count",i),this.handleFailedToolExecution(t,r,a,n,o,s)}}async handleSuccessfulToolExecution(t,r,n,o,s){const i=Date.now()-o.executionStartTime;n.metrics.successfulExecutions++,n.metrics.lastExecutionTime=i,n.metrics.averageExecutionTime=(n.metrics.averageExecutionTime*(n.metrics.successfulExecutions-1)+i)/n.metrics.successfulExecutions;const{MemoryManager:a}=await Promise.resolve().then(()=>(x1(),Dw)),l=a.getMemoryUsageMB().heapUsed-n.startMemory.heapUsed;l>20&&re.warn(`Tool '${t}' used excessive memory: ${l}MB`,{toolName:t,memoryDelta:l,executionTime:i}),re.debug(`[${o.functionTag}] Tool executed successfully`,{toolName:t,executionTime:i,memoryDelta:l,circuitBreakerState:n.circuitBreaker.getState()});const u=r&&typeof r=="object"?r:void 0,d=u&&"isError"in u&&u.isError===!0||u&&"success"in u&&u.success===!1,p=d?u?.content:void 0,h=d?p?.filter(f=>f.type==="text"&&f.text).map(f=>f.text).join(" ")||(typeof u?.error=="string"?u.error:"Unknown error"):void 0;if(d){try{await n.circuitBreaker.execute(async()=>{throw new Error(`Tool ${t} returned isError:true`)})}catch{}re.debug(`[${o.functionTag}] Circuit breaker failure recorded for isError result`,{toolName:t,circuitBreakerState:n.circuitBreaker.getState(),circuitBreakerFailures:n.circuitBreaker.getFailureCount()});const f=Knn(h??"Unknown error"),g=`[TOOL_ERROR: ${t} failed (${f})] `;if(u&&Array.isArray(p)){const T=p.map(b=>({...b}));for(const b of T)if(b.type==="text"&&b.text){b.text=g+b.text;break}u.content=T}s.setAttribute("tool.error.message",(h??"Unknown error").substring(0,500)),s.setAttribute("tool.error.category",f),s.setStatus({code:Ue.ERROR,message:`MCP tool returned isError: ${(h??"Unknown error").substring(0,200)}`}),n.metrics.failedExecutions++;const y=n.metrics.successfulExecutions;n.metrics.successfulExecutions=Math.max(0,n.metrics.successfulExecutions-1),n.metrics.averageExecutionTime=y>1?(n.metrics.averageExecutionTime*y-i)/(y-1):0;const v=Jnn(f);n.metrics.errorCategories[v]=(n.metrics.errorCategories[v]||0)+1}return this.emitToolEndEvent(t,o.executionStartTime,!d,r,d&&h?new Error(h):void 0,o.executionId),s.setAttribute("tool.result.status",d?"error":"success"),s.setAttribute("tool.duration_ms",i),r}async handleFailedToolExecution(t,r,n,o,s,i){o.metrics.failedExecutions++;const a=Date.now()-s.executionStartTime;if(n instanceof Ip)return re.warn(`[${s.functionTag}] Tool blocked by circuit breaker: ${t}`,{toolName:t,breakerState:n.breakerState,retryAfter:n.retryAfter,retryAfterMs:n.retryAfterMs,failureCount:n.failureCount,executionTime:a}),o.metrics.errorCategories.execution=(o.metrics.errorCategories.execution||0)+1,this.emitToolEndEvent(t,s.executionStartTime,!1,void 0,new Error(`Circuit breaker open for ${t} (state=${n.breakerState}, failures=${n.failureCount})`),s.executionId),i.setAttribute("tool.result.status","circuit_breaker_open"),i.setAttribute("tool.duration_ms",a),i.setAttribute("tool.circuit_breaker.state",n.breakerState),i.setAttribute("tool.circuit_breaker.retry_after_ms",n.retryAfterMs),i.setAttribute("tool.circuit_breaker.failure_count",n.failureCount),i.setStatus({code:Ue.ERROR,message:`Circuit breaker open for ${t}: ${n.message}`}),{isError:!0,content:[{type:"text",text:`TOOL TEMPORARILY UNAVAILABLE: "${t}" has been disabled after ${n.failureCount} failures. This is a circuit breaker protection \u2014 do NOT retry this tool. It will become available again after ${Math.ceil(n.retryAfterMs/1e3)} seconds (at ${n.retryAfter}). Instead, inform the user that the operation failed and suggest trying again later.`}]};let c;if(n instanceof Oe)c=n;else if(n instanceof Error)if(n.message.includes("timeout"))c=he.toolTimeout(t,o.finalOptions.timeout);else if(n.message.includes("not found")){const u=await this.getAllAvailableTools();c=he.toolNotFound(t,d6r(u.map(d=>({name:d.name}))))}else n.message.includes("validation")||n.message.includes("parameter")?c=he.invalidParameters(t,n,r):n.message.includes("network")||n.message.includes("connection")?c=he.networkError(t,n):c=he.toolExecutionFailed(t,n);else c=he.toolExecutionFailed(t,new Error(String(n)));const l=c.category||"execution";throw o.metrics.errorCategories[l]=(o.metrics.errorCategories[l]||0)+1,this.emitToolEndEvent(t,s.executionStartTime,!1,void 0,c,s.executionId),this.emitter.listenerCount("error")>0&&this.emitter.emit("error",c),c=new Oe({...c,context:{...c.context,executionTime:a,params:r,options:o.finalOptions,circuitBreakerState:o.circuitBreaker.getState(),circuitBreakerFailures:o.circuitBreaker.getFailureCount(),metrics:{...o.metrics}}}),qTe(c),i.setAttribute("tool.result.status","error"),i.setAttribute("tool.duration_ms",a),i.recordException(c),i.setStatus({code:Ue.ERROR,message:c.message}),c}toolCacheRepeatKey(t,r){try{return`${t}:${JSON.stringify(r)??""}`}catch{return}}async executeToolInternal(t,r,n,o){const s="NeuroLink.executeToolInternal",i=this.getToolAnnotationsForExecution(t),a=this.mcpToolResultCache&&!n.disableToolCache&&!this._disableToolCacheForCurrentRequest&&!this.uncacheableTools.has(t)&&!i?.destructiveHint,c=this.mcpToolResultCache,l=n.authContext||this.toolExecutionContext?{__args:r,__ctx:n.authContext??this.toolExecutionContext}:r,u=this._generationTurnActive?this.toolCacheRepeatKey(t,l):void 0,d=u!==void 0&&this._toolCacheKeysServedThisRequest.has(u);if(u!==void 0&&this._toolCacheKeysServedThisRequest.add(u),a&&c&&!d){const f=c.getCachedResult(t,l);if(f!==void 0)return m.debug(`[${s}] Cache HIT for tool: ${t}`),f}else d&&m.debug(`[${s}] Repeat call within this request \u2014 bypassing tool cache for: ${t}`);const p=async f=>{if(this.mcpToolMiddlewares.length===0)return f();let g=0;const y=async()=>{if(g<this.mcpToolMiddlewares.length){const v=this.mcpToolMiddlewares[g++];return v({name:t,description:"",inputSchema:{},annotations:i,execute:async()=>({})},r,{toolMeta:{name:t,annotations:i}},y)}return f()};return await y()},h=async()=>{const f=this.externalServerManager.getAllTools(),g=f.filter(v=>v.name===t&&v.isAvailable);let y;if(g.length>1&&this.mcpToolRouter)try{const v={name:t,description:g[0].description??"",serverId:g[0].serverId,inputSchema:{}},T=this.mcpToolRouter.route(v);y=g.find(b=>b.serverId===T.serverId)||g[0],m.debug(`[${s}] Router selected server: ${T.serverId}`,{strategy:T.strategy,confidence:T.confidence})}catch(v){m.warn(`[${s}] Router failed, falling back to first match`,{error:v}),y=g[0]}else y=g[0];if(m.debug(`[${s}] External MCP tool search:`,{toolName:t,externalToolsCount:f.length,foundTool:!!y,isAvailable:y?.isAvailable,serverId:y?.serverId}),y&&y.isAvailable)try{re.debug(`[${s}] Executing external MCP tool: ${t} from ${y.serverId}`);const v=await this.externalServerManager.executeTool(y.serverId,t,r,{timeout:n.timeout});return m.debug(`[${s}] External MCP tool execution successful:`,{toolName:t,serverId:y.serverId,resultType:typeof v}),v}catch(v){throw m.error(`[${s}] External MCP tool execution failed:`,{toolName:t,serverId:y.serverId,error:v instanceof Error?v.message:String(v)}),he.toolExecutionFailed(t,v instanceof Error?v:new Error(String(v)),y.serverId)}try{const v=this.toolExecutionContext||{},T=n.authContext||{},b=wS({...v,...T,hitlState:o},this.resolveFileToolRoots(void 0));m.debug("[Using merged context for unified registry tool:",{toolName:t,storedContextKeys:Object.keys(v),finalContextKeys:Object.keys(b)});const _=await this.toolRegistry.executeTool(t,r,b);if(_&&typeof _=="object"&&"success"in _&&_.success===!1){const x=_.error||"Tool execution failed",k=new Error(x);this.emitter.listenerCount("error")>0&&this.emitter.emit("error",k)}return _}catch(v){const T=v instanceof Error?v:new Error(String(v));if(this.emitter.listenerCount("error")>0&&this.emitter.emit("error",T),v instanceof Error&&v.message.includes("not found")){const b=await this.getAllAvailableTools();throw he.toolNotFound(t,b.map(_=>_.name))}throw he.toolExecutionFailed(t,v instanceof Error?v:new Error(String(v)))}};try{const f=await p(h);return a&&c&&f!==void 0&&(c.cacheResult(t,l,f),m.debug(`[${s}] Cached result for tool: ${t}`)),f}catch(f){const g=i?{name:t,description:"",annotations:i,execute:async()=>({})}:void 0;if(g&&oX(g)&&f instanceof Error&&k8(f)){m.debug(`[${s}] Tool ${t} is safe to retry, attempting once more`);try{const y=await p(h);return a&&c&&y!==void 0&&c.cacheResult(t,l,y),y}catch{}}throw f}}getToolAnnotationsForExecution(t){if(this.toolCache?.tools){const r=this.toolCache.tools.find(n=>n.name===t);if(r?.annotations)return r.annotations}if(this.mcpEnhancementsConfig?.annotations?.autoInfer!==!1)return Bd({name:t,description:""})}invalidateToolCache(){this.toolCache=null,m.debug("Tool cache invalidated")}async getAllAvailableTools(){if(this.toolCache&&Date.now()-this.toolCache.timestamp<this.toolCacheDuration)return m.debug("Returning available tools from cache"),this.toolCache.tools;const t=`get-all-tools-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,r=Date.now(),n=process.hrtime.bigint();m.debug("[NeuroLink] \u{1F6E0}\uFE0F LOG_POINT_A001_GET_ALL_TOOLS_START",{logPoint:"A001_GET_ALL_TOOLS_START",getAllToolsId:t,timestamp:new Date().toISOString(),getAllToolsStartTime:r,getAllToolsHrTimeStart:n.toString(),toolRegistryState:{hasToolRegistry:!!this.toolRegistry,toolRegistrySize:0,toolRegistryType:this.toolRegistry?.constructor?.name||"NOT_SET",hasExternalServerManager:!!this.externalServerManager,externalServerManagerType:this.externalServerManager?.constructor?.name||"NOT_SET"},mcpState:{mcpInitialized:this.mcpInitialized,hasProviderRegistry:!!Un,providerRegistrySize:0},message:"Starting comprehensive tool discovery across all sources"});const{MemoryManager:o}=await Promise.resolve().then(()=>(x1(),Dw)),s=o.getMemoryUsageMB();try{const i=new Map,a=await this.toolRegistry.listTools();for(const g of a)if(!i.has(g.name)){const y=QM(g,{serverId:g.serverId==="direct"?"neurolink-direct":g.serverId});i.set(g.name,y)}const c=this.toolRegistry.getToolsByCategory(Yi({isCustomTool:!0}));for(const g of c)if(!i.has(g.name)){const y=QM(g,{description:"Custom tool",serverId:`custom-tool-${g.name}`,category:Yi({isCustomTool:!0,serverId:g.serverId}),inputSchema:{}});i.set(g.name,y)}const l=this.toolRegistry.getToolsByCategory("in-memory");for(const g of l)if(!i.has(g.name)){const y=QM(g,{description:"In-memory MCP tool",serverId:"unknown",category:"in-memory",inputSchema:{}});i.set(g.name,y)}const u=this.externalServerManager.getAllTools();for(const g of u)if(!i.has(g.name)){const y=QM(g,{category:Yi({existingCategory:typeof g.metadata?.category=="string"?g.metadata.category:void 0,isExternal:!0,serverId:g.serverId}),inputSchema:{}});i.set(g.name,y)}const d=Array.from(i.values());re.debug("Tool discovery results",{mcpTools:a.length,customTools:c.length,inMemoryTools:l.length,externalMCPTools:u.length,total:d.length});const h=o.getMemoryUsageMB().heapUsed-s.heapUsed;if(h>Mp.LOW_USAGE_MB&&(re.debug(`\u{1F50D} Tool listing used ${h}MB memory (large tool registry detected)`),d.length>Uge.LARGE_TOOL_COLLECTION&&re.debug("\u{1F4A1} Tool collection optimized for large sets. Memory usage reduced through efficient object reuse.")),this.mcpEnhancementsConfig?.annotations?.autoInfer!==!1)for(const g of d)g.annotations||(g.annotations=Bd({name:g.name,description:g.description||""}));const f=d.sort((g,y)=>g.name<y.name?-1:g.name>y.name?1:0);return this.toolCache={tools:f,timestamp:Date.now()},f}catch(i){return re.error("Failed to list available tools",{error:i}),[]}}async getProviderStatus(t){const{MemoryManager:r}=await Promise.resolve().then(()=>(x1(),Dw)),n=r.getMemoryUsageMB();t?.quiet||re.debug("\u{1F50D} DEBUG: Initializing MCP for provider status..."),await this.initializeMCP(),t?.quiet||re.debug("\u{1F50D} DEBUG: MCP initialized:",this.mcpInitialized);const{AIProviderFactory:o}=await Promise.resolve().then(()=>(Ca(),rA)),{hasProviderEnvVars:s}=await Promise.resolve().then(()=>(zm(),S1)),i=Sr.getAllDescriptors().map(p=>p.name),a=gf(da.DEFAULT_CONCURRENCY_LIMIT),c=i.map(p=>a(async()=>{const h=Date.now();try{if(!await this.hasProviderEnvVars(p)&&p!=="ollama")return{provider:p,status:"not-configured",configured:!1,authenticated:!1,error:"Missing required environment variables",responseTime:Date.now()-h};if(p==="ollama")try{const _=await fetch("http://localhost:11434/api/tags",{method:"GET",signal:AbortSignal.timeout(gc.AUTH_MS)});if(!_.ok)throw new Error("Ollama service not responding");const x=await _.json(),k=x?.models;if(!Array.isArray(k))throw m.warn("Ollama API returned invalid models format in testProvider",{responseData:x,modelsType:typeof k}),new Error("Invalid models format from Ollama API");const A=k.filter(R=>R&&typeof R=="object"&&typeof R.name=="string");return A.length>0?{provider:p,status:"working",configured:!0,authenticated:!0,responseTime:Date.now()-h,model:A[0].name}:{provider:p,status:"failed",configured:!0,authenticated:!1,error:"Ollama service running but no models installed",responseTime:Date.now()-h}}catch(_){return{provider:p,status:"failed",configured:!1,authenticated:!1,error:_ instanceof Error?_.message:"Ollama service not running",responseTime:Date.now()-h}}const g=5e3,y=new AbortController,v=this.testProviderConnection(p,y.signal);let T;const b=new Promise((_,x)=>{T=setTimeout(()=>{x(new Error("Provider test timeout (5s)"))},g)});try{await Promise.race([v,b])}finally{clearTimeout(T),v.catch(()=>{}),y.abort()}return{provider:p,status:"working",configured:!0,authenticated:!0,responseTime:Date.now()-h}}catch(f){const g=f instanceof Error?f.message:String(f);return{provider:p,status:"failed",configured:!0,authenticated:!1,error:g,responseTime:Date.now()-h}}})),l=await Promise.all(c),d=r.getMemoryUsageMB().heapUsed-n.heapUsed;return!t?.quiet&&d>20&&re.debug(`\u{1F50D} Memory usage: +${d}MB (consider cleanup for large operations)`),d>50&&r.forceGC(),l}async testProvider(t){try{return await this.testProviderConnection(t),!0}catch{return!1}}async testProviderConnection(t,r){const{AIProviderFactory:n}=await Promise.resolve().then(()=>(Ca(),rA));await(await n.createProvider(t,null)).generate({prompt:"test",maxTokens:1,disableTools:!0,abortSignal:r})}async getBestProvider(t){const{getBestProvider:r}=await Promise.resolve().then(()=>(zm(),S1));return r(t)}async getAvailableProviders(){const{getAvailableProviders:t}=await Promise.resolve().then(()=>(zm(),S1));return t()}async isValidProvider(t){const{isValidProvider:r}=await Promise.resolve().then(()=>(zm(),S1));return r(t)}async getMCPStatus(){try{await this.initializeMCP();const t=await this.toolRegistry.listTools(),r=this.externalServerManager.getStatistics(),n=this.externalServerManager.listServers(),o=this.getInMemoryServerInfos(),s=this.toolRegistry.getBuiltInServerInfos(),i=this.getAutoDiscoveredServerInfos(),a=n.length+o.length+s.length+i.length,c=r.connectedServers+o.length+s.length,l=t.length+r.totalTools;return{mcpInitialized:this.mcpInitialized,totalServers:a,availableServers:c,autoDiscoveredCount:i.length,totalTools:l,autoDiscoveredServers:i,customToolsCount:this.toolRegistry.getToolsByCategory(Yi({isCustomTool:!0})).length,inMemoryServersCount:o.length,externalMCPServersCount:n.length,externalMCPConnectedCount:r.connectedServers,externalMCPFailedCount:r.failedServers,externalMCPServers:n}}catch(t){return{mcpInitialized:!1,totalServers:0,availableServers:0,autoDiscoveredCount:0,totalTools:0,autoDiscoveredServers:[],customToolsCount:this.toolRegistry.getToolsByCategory(Yi({isCustomTool:!0})).length,inMemoryServersCount:0,externalMCPServersCount:0,externalMCPConnectedCount:0,externalMCPFailedCount:0,externalMCPServers:[],error:t instanceof Error?t.message:String(t)}}}async listMCPServers(){return[...this.externalServerManager.listServers(),...this.getInMemoryServerInfos(),...this.toolRegistry.getBuiltInServerInfos(),...this.getAutoDiscoveredServerInfos()]}async testMCPServer(t){try{if(t==="neurolink-direct")return(await this.toolRegistry.listTools()).length>0;const r=this.getInMemoryServers();if(r.has(t)){const o=r.get(t);return!!(o?.tools&&o.tools.length>0)}const n=this.externalServerManager.getServer(t);return n?n.status==="connected"&&n.client!==null:!1}catch(r){return re.error(`[NeuroLink] Error testing MCP server ${t}:`,r),!1}}async hasProviderEnvVars(t){const{ProviderHealthChecker:r}=await Promise.resolve().then(()=>(Gg(),Cw));try{const n=await r.checkProviderHealth(t,{includeConnectivityTest:!1,cacheResults:!1});return n.isConfigured&&n.hasApiKey}catch(n){return m.warn(`Provider env var check failed for ${t}`,{error:n instanceof Error?n.message:String(n)}),!1}}async checkProviderHealth(t,r={}){const{ProviderHealthChecker:n}=await Promise.resolve().then(()=>(Gg(),Cw)),o=await n.checkProviderHealth(t,r);return{provider:o.provider,isHealthy:o.isHealthy,isConfigured:o.isConfigured,hasApiKey:o.hasApiKey,lastChecked:o.lastChecked,error:o.error,warning:o.warning,responseTime:o.responseTime,configurationIssues:o.configurationIssues,recommendations:o.recommendations}}async checkAllProvidersHealth(t={}){const{ProviderHealthChecker:r}=await Promise.resolve().then(()=>(Gg(),Cw));return(await r.checkAllProvidersHealth(t)).map(o=>({provider:o.provider,isHealthy:o.isHealthy,isConfigured:o.isConfigured,hasApiKey:o.hasApiKey,lastChecked:o.lastChecked,error:o.error,warning:o.warning,responseTime:o.responseTime,configurationIssues:o.configurationIssues,recommendations:o.recommendations}))}async getProviderHealthSummary(){const{ProviderHealthChecker:t}=await Promise.resolve().then(()=>(Gg(),Cw)),r=await t.checkAllProvidersHealth({cacheResults:!0,includeConnectivityTest:!1}),n=t.getHealthSummary(r),o=[];return n.healthy===0?o.push("No providers are healthy. Check your environment configuration."):n.healthy<2&&o.push("Consider configuring additional providers for better reliability."),n.hasIssues>0&&o.push("Some providers have configuration issues. Run checkAllProvidersHealth() for details."),{...n,recommendations:o}}async clearProviderHealthCache(t){const{ProviderHealthChecker:r}=await Promise.resolve().then(()=>(Gg(),Cw));r.clearHealthCache(t)}getToolExecutionMetrics(){const t={};for(const[r,n]of this.toolExecutionMetrics.entries())t[r]={...n,errorCategories:{...n.errorCategories},successRate:n.totalExecutions>0?n.successfulExecutions/n.totalExecutions:0};return t}setModelAliasConfig(t){this.modelAliasConfig=t,m.info(`[ModelAlias] Configured ${Object.keys(t.aliases).length} model aliases`)}getToolCircuitBreakerStatus(){const t={};for(const[r,n]of this.toolCircuitBreakers.entries())t[r]={state:n.getState(),failureCount:n.getFailureCount(),isHealthy:n.getState()==="closed"};return t}resetToolCircuitBreaker(t){this.toolCircuitBreakers.has(t)&&(this.toolCircuitBreakers.set(t,new KR(WC.FAILURE_THRESHOLD,K$)),re.info(`Circuit breaker reset for tool: ${t}`))}clearToolExecutionMetrics(){this.toolExecutionMetrics.clear(),re.info("All tool execution metrics cleared")}async getToolHealthReport(){const t={};let r=0;const n=await this.toolRegistry.listTools(),o=new Set(n.map(i=>i.name)),s=new Map;for(const i of n)s.has(i.name)||s.set(i.name,i.serverId||"unknown");for(const i of o){const a=this.toolExecutionMetrics.get(i),c=`${s.get(i)||"unknown"}.${i}`,l=this.toolCircuitBreakers.get(c),u=a&&a.totalExecutions>0?a.successfulExecutions/a.totalExecutions:0,d=(!l||l.getState()==="closed")&&u>=.8;d&&r++;const p=[],h=[];if(l&&l.getState()==="open"&&(p.push("Circuit breaker is open due to repeated failures"),h.push("Check tool implementation and fix underlying issues")),u<.8&&a&&a.totalExecutions>0&&(p.push(`Low success rate: ${(u*100).toFixed(1)}%`),h.push("Review error logs and improve tool reliability")),a&&a.averageExecutionTime>1e4&&(p.push("High average execution time"),h.push("Optimize tool performance or increase timeout")),a&&a.errorCategories){const f=a.errorCategories;f.timeout>0&&(p.push(`Timeout errors: ${f.timeout}`),h.push("Consider increasing the tool timeout configuration")),f.validation>0&&(p.push(`Validation errors: ${f.validation}`),h.push("Review input schemas and parameter validation")),f.network>0&&(p.push(`Network errors: ${f.network}`),h.push("Check network connectivity and endpoint availability"))}t[i]={name:i,isHealthy:d,metrics:{totalExecutions:a?.totalExecutions||0,successRate:u,averageExecutionTime:a?.averageExecutionTime||0,lastExecutionTime:a?.lastExecutionTime||0,errorCategories:a?.errorCategories?{...a.errorCategories}:{}},circuitBreaker:{state:l?.getState()||"closed",failureCount:l?.getFailureCount()||0},issues:p,recommendations:h}}return{totalTools:o.size,healthyTools:r,unhealthyTools:o.size-r,tools:t}}async ensureConversationMemoryInitialized(){try{const t=`manual-init-${Date.now()}`;return await this.initializeConversationMemoryForGeneration(t,Date.now(),process.hrtime.bigint()),!!this.conversationMemory}catch(t){return m.error("Failed to initialize conversation memory",{error:t instanceof Error?t.message:String(t)}),!1}}async getConversationStats(){const t=`stats-init-${Date.now()}`;if(await this.initializeConversationMemoryForGeneration(t,Date.now(),process.hrtime.bigint()),!this.conversationMemory)throw new Oe({code:He.MISSING_CONFIGURATION,message:"Conversation memory is not enabled",category:"validation",severity:"high",retriable:!1});return await this.conversationMemory.getStats()}async getConversationHistory(t){const r=`history-init-${Date.now()}`;if(await this.initializeConversationMemoryForGeneration(r,Date.now(),process.hrtime.bigint()),!this.conversationMemory)throw new Oe({code:He.MISSING_CONFIGURATION,message:"Conversation memory is not enabled",category:"validation",severity:"high",retriable:!1});if(!t||typeof t!="string")throw new Oe({code:He.INVALID_PARAMETERS,message:"Session ID must be a non-empty string",category:"validation",severity:"medium",retriable:!1,context:{sessionId:t}});try{const n=await this.conversationMemory.buildContextMessages(t);return m.debug("Retrieved conversation history",{sessionId:t,messageCount:n.length,turnCount:n.length/2}),n}catch(n){return m.error("Failed to retrieve conversation history",{sessionId:t,error:n instanceof Error?n.message:String(n)}),[]}}async clearConversationSession(t){const r=`clear-session-init-${Date.now()}`;if(await this.initializeConversationMemoryForGeneration(r,Date.now(),process.hrtime.bigint()),!this.conversationMemory)throw new Oe({code:He.MISSING_CONFIGURATION,message:"Conversation memory is not enabled",category:"validation",severity:"high",retriable:!1});return this.lastCompactionMessageCount.delete(t),await this.conversationMemory.clearSession(t)}async clearAllConversations(){const t=`clear-all-init-${Date.now()}`;if(await this.initializeConversationMemoryForGeneration(t,Date.now(),process.hrtime.bigint()),!this.conversationMemory)throw new Oe({code:He.MISSING_CONFIGURATION,message:"Conversation memory is not enabled",category:"validation",severity:"high",retriable:!1});this.lastCompactionMessageCount.clear(),await this.conversationMemory.clearAllSessions()}async listSessions(t){const r=`list-sessions-init-${Date.now()}`;if(await this.initializeConversationMemoryForGeneration(r,Date.now(),process.hrtime.bigint()),!this.conversationMemory)throw new Error("Conversation memory is not enabled");if(!this.conversationMemory.listSessions)return m.warn("listSessions not available on current memory manager"),[];const n=3e4;try{const o=await ze(this.conversationMemory.listSessions(t),n,new Error("listSessions operation timed out after 30s"));return m.debug("Listed conversation sessions",{userId:t,sessionCount:o.length}),o}catch(o){return m.error("Failed to list conversation sessions",{userId:t,error:o instanceof Error?o.message:String(o)}),[]}}async exportSession(t,r={}){const n=`export-session-init-${Date.now()}`;if(await this.initializeConversationMemoryForGeneration(n,Date.now(),process.hrtime.bigint()),!this.conversationMemory)throw new Error("Conversation memory is not enabled");if(!t||typeof t!="string")throw new Error("Session ID must be a non-empty string");const o=3e4;try{const s=await ze(this.conversationMemory.buildContextMessages(t),o,new Error("buildContextMessages operation timed out after 30s"));if(s.length===0)return m.debug("No messages found for session export",{sessionId:t}),null;const i=this.conversationMemory.getSession(t),a=await ze(i instanceof Promise?i:Promise.resolve(i),o,new Error("getSession operation timed out after 30s")),c=new Date().toISOString(),l={sessionId:t,title:t,userId:a?.userId,createdAt:a?.createdAt?new Date(a.createdAt).toISOString():c,updatedAt:a?.lastActivity?new Date(a.lastActivity).toISOString():c,messages:s};return r.includeMetadata&&(l.exportMetadata={exportedAt:c,exportFormat:r.format||"json"}),m.debug("Exported conversation session",{sessionId:t,messageCount:s.length}),l}catch(s){return m.error("Failed to export conversation session",{sessionId:t,error:s instanceof Error?s.message:String(s)}),null}}async exportAllSessions(t,r={}){const n=`export-all-init-${Date.now()}`;if(await this.initializeConversationMemoryForGeneration(n,Date.now(),process.hrtime.bigint()),!this.conversationMemory)throw new Error("Conversation memory is not enabled");const o=3e4,s=6e4;try{const i=await ze(this.listSessions(t),o,new Error("listSessions operation timed out after 30s")),a=[];for(const c of i){const l=await ze(this.exportSession(c.id,r),s,new Error(`exportSession operation timed out after 60s for session ${c.id}`));l&&a.push(l)}return m.debug("Exported all conversation sessions",{userId:t,sessionCount:a.length}),a}catch(i){return m.error("Failed to export all conversation sessions",{userId:t,error:i instanceof Error?i.message:String(i)}),[]}}async storeToolExecutions(t,r,n,o,s){const i=n&&n.length>0||o&&o.length>0;if(!i){m.debug("Tool execution storage skipped",{hasToolData:i,toolCallsCount:n?.length||0,toolResultsCount:o?.length||0});return}const a=this.conversationMemory;if(!a?.storeToolExecution){m.debug("Tool execution storage not supported by this memory backend");return}try{await a.storeToolExecution(t,r,n,o,s)}catch(c){m.warn("Failed to store tool executions",{sessionId:t,userId:r,error:c instanceof Error?c.message:String(c)})}}isToolExecutionStorageAvailable(){return typeof this.conversationMemory?.storeToolExecution=="function"}async getSessionMessages(t,r){const n=`get-msgs-init-${Date.now()}`;if(await this.initializeConversationMemoryForGeneration(n,Date.now(),process.hrtime.bigint()),!this.conversationMemory)throw new Oe({code:He.MISSING_CONFIGURATION,message:"Conversation memory is not enabled",category:"validation",severity:"high",retriable:!1});if(!t||typeof t!="string")throw new Oe({code:He.INVALID_PARAMETERS,message:"Session ID must be a non-empty string",category:"validation",severity:"medium",retriable:!1,context:{sessionId:t}});return await this.conversationMemory.getSessionMessages(t,r)}async setSessionMessages(t,r,n){const o=`set-msgs-init-${Date.now()}`;if(await this.initializeConversationMemoryForGeneration(o,Date.now(),process.hrtime.bigint()),!this.conversationMemory)throw new Oe({code:He.MISSING_CONFIGURATION,message:"Conversation memory is not enabled",category:"validation",severity:"high",retriable:!1});if(!t||typeof t!="string")throw new Oe({code:He.INVALID_PARAMETERS,message:"Session ID must be a non-empty string",category:"validation",severity:"medium",retriable:!1,context:{sessionId:t}});await this.conversationMemory.setSessionMessages(t,r,n)}async modifyLastAssistantMessage(t,r,n){const o=await this.getSessionMessages(t,n);for(let s=o.length-1;s>=0;s--)if(o[s].role==="assistant")return o[s]={...o[s],content:r(o[s].content)},await this.setSessionMessages(t,o,n),!0;return!1}async addExternalMCPServer(t,r){this.invalidateToolCache();try{re.info(`[NeuroLink] Adding external MCP server: ${t}`,{command:r.command,transport:r.transport});const n=await this.externalServerManager.addServer(t,r);if(n.success){if(re.info(`[NeuroLink] External MCP server added successfully: ${t}`,{toolsDiscovered:n.metadata?.toolsDiscovered||0,duration:n.duration}),this.mcpEnhancementsConfig?.router?.enabled!==!1){const o=this.externalServerManager.listServers();if(o.length>=2&&!this.mcpToolRouter){this.mcpToolRouter=new EL({strategy:this.mcpEnhancementsConfig?.router?.strategy??"least-loaded",enableAffinity:this.mcpEnhancementsConfig?.router?.enableAffinity??!1});for(const s of o)this.mcpToolRouter.registerServer(s.id||t);m.debug("[NeuroLink] ToolRouter auto-initialized (2+ external servers)")}else this.mcpToolRouter&&this.mcpToolRouter.registerServer(t)}this.emitter.emit("externalMCP:serverAdded",{serverId:t,serverName:r.name||t,config:r,toolCount:n.metadata?.toolsDiscovered||0,timestamp:Date.now()})}else re.error(`[NeuroLink] Failed to add external MCP server: ${t}`,{error:n.error,transport:r.transport,command:r.command,url:r.url?Fo(r.url):void 0});return n}catch(n){throw re.error(`[NeuroLink] Error adding external MCP server: ${t}`,n),n}}async removeExternalMCPServer(t){this.invalidateToolCache();try{re.info(`[NeuroLink] Removing external MCP server: ${t}`);const r=this.externalServerManager.getServerName(t),n=await this.externalServerManager.removeServer(t);return n.success?(re.info(`[NeuroLink] External MCP server removed successfully: ${t}`),this.emitter.emit("externalMCP:serverRemoved",{serverId:t,serverName:r,timestamp:Date.now()})):n.error?.includes("not found")?re.debug(`[NeuroLink] Remove skipped \u2014 external MCP server not registered: ${t}`):re.error(`[NeuroLink] Failed to remove external MCP server: ${t}`,{error:n.error}),n}catch(r){throw re.error(`[NeuroLink] Error removing external MCP server: ${t}`,r),r}}listExternalMCPServers(){const t=this.externalServerManager.getServerStatuses(),r=this.externalServerManager.listServers();return t.map(n=>{const o=r.find(s=>s.id===n.serverId);return{serverId:n.serverId,status:n.status,toolCount:n.toolCount,uptime:n.performance.uptime,isHealthy:n.isHealthy,config:o||{}}})}getExternalMCPServer(t){return this.externalServerManager.getServer(t)}async executeExternalMCPTool(t,r,n,o){let s=r;try{s=this.resolveDirectMcpToolName(t,r),re.debug(`[NeuroLink] Executing external MCP tool: ${s} on ${t}`);const i=this.getToolAnnotationsForExecution(s),a=!!this.mcpToolResultCache&&!this._disableToolCacheForCurrentRequest&&!i?.destructiveHint,c={__serverId:t,__args:n,...this.toolExecutionContext?{__ctx:this.toolExecutionContext}:{}},l=this._generationTurnActive?this.toolCacheRepeatKey(s,c):void 0,u=l!==void 0&&this._toolCacheKeysServedThisRequest.has(l);if(l!==void 0&&this._toolCacheKeysServedThisRequest.add(l),a&&this.mcpToolResultCache&&!u){const f=this.mcpToolResultCache.getCachedResult(s,c);if(f!==void 0)return re.debug(`[NeuroLink] Tool result cache HIT: ${s} on ${t}`),f}const d=await this.externalServerManager.executeTool(t,s,n,o),p=d&&typeof d=="object"?d:void 0,h=!!(p&&"isError"in p&&p.isError===!0||p&&"success"in p&&p.success===!1);return a&&this.mcpToolResultCache&&!h&&d!==void 0&&this.mcpToolResultCache.cacheResult(s,c,d),re.debug(`[NeuroLink] External MCP tool ${h?"returned error":"executed successfully"}: ${s}`),d}catch(i){throw re.error(`[NeuroLink] External MCP tool execution failed: ${s}`,i),i}}resolveDirectMcpToolName(t,r){const n=this.getExternalMCPServer(t);if(!n||n.status!=="connected"||!n.client)return r;const o=this.getExternalMCPServerTools(t).map(i=>i.name);if(o.includes(r))return r;const s=EY(r,o);if(!s)throw new _Y(r,t,Uxt(r,o));return Be.mcp.startActiveSpan("neurolink.mcp.toolNameRepair",{attributes:{"mcp.server_id":t,"mcp.tool_name.requested":r,"mcp.tool_name.resolved":s.name,"mcp.tool_name.repair_strategy":s.strategy,...s.score!==void 0?{"mcp.tool_name.repair_score":s.score}:{}}},i=>i.end()),re.info(`[NeuroLink] Repaired external MCP tool name at direct execution boundary: "${r}" \u2192 "${s.name}" (${s.strategy}) on server '${t}'`),s.name}getExternalMCPTools(){return this.externalServerManager.getAllTools()}getExternalMCPServerTools(t){return this.externalServerManager.getServerTools(t)}async testExternalMCPConnection(t){try{const{MCPClientFactory:r}=await ze(Promise.resolve().then(()=>(one(),aUt)),1e4),n=await r.testConnection(t,1e4);return{success:n.success,error:n.error,toolCount:n.capabilities?1:0}}catch(r){return{success:!1,error:r instanceof Error?r.message:String(r)}}}getExternalMCPStatistics(){return this.externalServerManager.getStatistics()}async shutdownExternalMCPServers(){try{re.info("[NeuroLink] Shutting down all external MCP servers..."),this.unregisterAllExternalMCPToolsFromRegistry(),await this.externalServerManager.shutdown(),re.info("[NeuroLink] All external MCP servers shut down successfully")}catch(t){throw re.error("[NeuroLink] Error shutting down external MCP servers:",t),t}}async getElicitationManager(){return(await ze(Promise.resolve().then(()=>(fjt(),hjt)),1e4)).globalElicitationManager}async registerElicitationHandler(t){(await this.getElicitationManager()).registerHandler(t)}async getMultiServerManager(){return(await ze(Promise.resolve().then(()=>(Xte(),wFt)),1e4)).globalMultiServerManager}async getEnhancedToolDiscovery(){const t=await ze(Promise.resolve().then(()=>(Zte(),TFt)),1e4);return new t.EnhancedToolDiscovery(this.toolRegistry)}async getMCPRegistryClient(){return(await ze(Promise.resolve().then(()=>(wjt(),gjt)),1e4)).globalMCPRegistryClient}async exposeAgentAsTool(t,r){return(await ze(Promise.resolve().then(()=>(Wie(),jie)),1e4)).exposeAgentAsTool(t,r)}async exposeWorkflowAsTool(t,r){return(await ze(Promise.resolve().then(()=>(Wie(),jie)),1e4)).exposeWorkflowAsTool(t,r)}async getToolIntegrationManager(){return(await ze(Promise.resolve().then(()=>(xjt(),Ejt)),1e4)).globalToolIntegrationManager}async convertToolsToMCPFormat(t,r={}){const n=await ze(Promise.resolve().then(()=>(uO(),sX)),1e4),o=t.map(s=>({...s,execute:s.execute??(async()=>({success:!1,error:"No execute function provided"}))}));return n.batchConvertToMCP(o,r)}async convertToolsFromMCPFormat(t,r={}){return(await ze(Promise.resolve().then(()=>(uO(),sX)),1e4)).batchConvertToNeuroLink(t,r)}async getToolAnnotations(t){const{inferAnnotations:r,mergeAnnotations:n,getAnnotationSummary:o}=await ze(Promise.resolve().then(()=>(yk(),iAt)),1e4),s=this.toolRegistry.getToolInfo(t);if(!s)return null;const i=s.tool.annotations,a=r({name:s.tool.name,description:s.tool.description??""}),c=n(a,i);return{annotations:c,summary:o(c)}}convertExternalMCPToolsToAISDKFormat(){const t=this.externalServerManager.getAllTools(),r={};for(const n of t)if(n.isAvailable){const o={description:n.description,execute:async s=>{try{re.debug(`[NeuroLink] Executing external MCP tool via AI SDK: ${n.name}`,{params:s});const i=await this.externalServerManager.executeTool(n.serverId,n.name,s,{timeout:3e4});return re.debug(`[NeuroLink] External MCP tool execution result: ${n.name}`,{success:!!i,hasData:!!(i&&typeof i=="object"&&"content"in i)}),i}catch(i){throw re.error(`[NeuroLink] External MCP tool execution failed: ${n.name}`,i),i}}};r[n.name]=o,re.debug(`[NeuroLink] Converted external MCP tool to AI SDK format: ${n.name} from server ${n.serverId}`)}return re.info(`[NeuroLink] Converted ${Object.keys(r).length} external MCP tools to AI SDK format`),r}convertJSONSchemaToAISDKFormat(t){}unregisterExternalMCPToolsFromRegistry(t){try{const r=this.externalServerManager.getServerTools(t);for(const n of r)this.toolRegistry.removeTool(n.name),re.debug(`[NeuroLink] Unregistered external MCP tool from main registry: ${n.name}`)}catch(r){re.error(`[NeuroLink] Failed to unregister external MCP tools from registry for server ${t}:`,r)}}unregisterExternalMCPToolFromRegistry(t){try{this.toolRegistry.removeTool(t),re.debug(`[NeuroLink] Unregistered external MCP tool from main registry: ${t}`)}catch(r){re.error(`[NeuroLink] Failed to unregister external MCP tool ${t} from registry:`,r)}}async lazyInitializeConversationMemory(t,r,n){try{const{initializeConversationMemory:o}=await Vnn().then(()=>Ijt),s=await o(this.conversationMemoryConfig);this.conversationMemory=s,this.conversationMemoryNeedsInit=!1}catch(o){throw m.error("[NeuroLink] \u274C LOG_POINT_G005_MEMORY_LAZY_INIT_ERROR",{logPoint:"G005_MEMORY_LAZY_INIT_ERROR",generateInternalId:t,timestamp:new Date().toISOString(),elapsedMs:Date.now()-r,elapsedNs:(process.hrtime.bigint()-n).toString(),error:o instanceof Error?o.message:String(o),errorName:o instanceof Error?o.name:"UnknownError",errorStack:o instanceof Error?o.stack:void 0,message:"Lazy conversation memory initialization failed"}),o}}unregisterAllExternalMCPToolsFromRegistry(){try{const t=this.externalServerManager.getAllTools();for(const r of t)this.toolRegistry.removeTool(r.name);re.debug(`[NeuroLink] Unregistered ${t.length} external MCP tools from main registry`)}catch(t){re.error("[NeuroLink] Failed to unregister all external MCP tools from registry:",t)}}async createEvaluationPipeline(t){const{EvaluationPipeline:r,getPreset:n}=await ze(Promise.resolve().then(()=>(HS(),jS)),1e4,he.evaluationTimeout("evaluation module load",1e4));let o;typeof t=="string"?o=n(t):o=t;const s=new r(o);return await ze(s.initialize(),3e4,he.evaluationTimeout("pipeline initialization",3e4)),m.debug(`[NeuroLink] Created evaluation pipeline: ${o.name??"custom"}`),s}async decide(t){const r=t.provider??LE(this.resolveCredentials(t.credentials));if(!r)throw new Error(`No decision provider is configured. Set ${jCr()} (in the environment or in \`credentials\`), or pass \`provider\` explicitly.`);const n=Object.keys(t.questions).length;return pt({name:`gen_ai.${r}.decide`,tracer:Be.decision,attributes:{"gen_ai.system":r,"gen_ai.operation.name":"decide","ai.provider":r,"decision.question_count":n,"decision.images.count":t.images?.length??0}},async o=>{const{traceId:s,parentSpanId:i}=Yh(),a=Date.now();let c=Pe.createSpan("model.decision",`decision.${r}`,{"ai.provider":r,"ai.model":t.model??"","decision.question_count":n,"decision.images.count":t.images?.length??0},i,s);try{const l=await Un.createProvider(r,t.model,!1,this,void 0,this.resolveCredentials(t.credentials));if(typeof l.decide!="function")throw new Error(`Provider "${r}" does not serve the decide inference type.`);const u=await l.decide({state:t.state,questions:t.questions,images:t.images,video:t.video,model:t.model,signal:t.signal,timeoutMs:t.timeoutMs}),d=Object.keys(u.answers).length,p=Si(r,u.model,{input:u.usage.inputTokens,output:u.usage.outputTokens,total:u.usage.inputTokens+u.usage.outputTokens});o.setAttribute("gen_ai.response.model",u.model),o.setAttribute("gen_ai.usage.input_tokens",u.usage.inputTokens),o.setAttribute("gen_ai.usage.output_tokens",u.usage.outputTokens),o.setAttribute("decision.answer_count",d),o.setAttribute("decision.media.bytes",u.mediaBytes??0),o.setAttribute("ai.cost.total",p),u.upstreamMs!==void 0&&o.setAttribute("decision.upstream_ms",u.upstreamMs),u.requestId&&o.setAttribute("gen_ai.response.id",u.requestId),c.durationMs=Date.now()-a,c=Pe.updateAttributes(c,{"ai.model":u.model,"ai.tokens.input":u.usage.inputTokens,"ai.tokens.output":u.usage.outputTokens,"ai.cost.input":p,"ai.cost.output":0,"ai.cost.total":p,"decision.answer_count":d,"decision.media.bytes":u.mediaBytes??0,"decision.latency_ms":u.latencyMs,...u.upstreamMs!==void 0?{"decision.upstream_ms":u.upstreamMs}:{}});const h=Pe.endSpan(c,1);return this.metricsAggregator.recordSpan(h),ot().recordSpan(h),u}catch(l){c.durationMs=Date.now()-a;const u=Pe.endSpan(c,2,l instanceof Error?l.message:String(l));throw this.metricsAggregator.recordSpan(u),ot().recordSpan(u),l}})}async tryDecide(t){try{const r=await this.decideInBatches(t);return m.shouldLog("debug")&&m.debug(`decide: ${Object.keys(r.answers).length} answers in ${r.latencyMs}ms`+(r.upstreamMs?` (upstream ${r.upstreamMs}ms)`:""),{provider:r.provider,model:r.model,requestId:r.requestId,usage:r.usage}),r}catch(r){return m.debug(`decide unavailable: ${r instanceof Error?r.message:String(r)} \u2014 falling back`),null}}async decideInBatches(t){const r=t.provider??LE(this.resolveCredentials(t.credentials)),n=r?qp.get(r.toLowerCase()):void 0,o=n?mr.get(n)?.decisionLimits?.maxQuestions:void 0,s=IHr(t,o);if(s.length===1)return this.decide(t);const i=[];let a;for(let u=0;u<s.length;u+=qte){const d=await Promise.allSettled(s.slice(u,u+qte).map(p=>this.decide(p)));for(const p of d)p.status==="fulfilled"?i.push(p.value):a??=p.reason}const[c,...l]=i;if(c===void 0)throw a instanceof Error?a:new Error(String(a));return l.length+1<s.length&&m.debug(`decide: ${s.length-i.length} of ${s.length} batches failed; using the answers of the rest`),RHr([c,...l])}async evaluate(t,r){const{EvaluationPipeline:n,getPreset:o}=await ze(Promise.resolve().then(()=>(HS(),jS)),1e4,he.evaluationTimeout("evaluation module load",1e4));let s;if(r?.pipeline&&r?.scorers)throw new Error("Cannot specify both 'pipeline' and 'scorers' options. Use one or the other.");if(r?.scorers&&r.scorers.length===0)throw new Error("The 'scorers' array must not be empty. Provide at least one scorer ID or omit the option to use the default 'quality' preset.");r?.pipeline?s={...o(r.pipeline)}:r?.scorers&&r.scorers.length>0?s={name:"SDK Evaluation",description:"Evaluation from NeuroLink SDK",scorers:r.scorers.map(l=>({id:l})),executionMode:r.executionMode??"parallel",passThreshold:r.passThreshold??.7}:s=o("quality"),r?.passThreshold!==void 0&&(s.passThreshold=r.passThreshold),r?.executionMode!==void 0&&(s.executionMode=r.executionMode);const i=new n(s);await ze(i.initialize(),3e4,he.evaluationTimeout("pipeline initialization",3e4));const a=r?.timeoutMs??6e4,c=await ze(i.execute(t,{correlationId:r?.correlationId}),a,he.evaluationTimeout("pipeline execution",a));return m.debug("[NeuroLink] Evaluation completed",{pipeline:s.name,overallScore:c.overallScore,passed:c.passed,scorerCount:c.scores.length}),c}async score(t,r,n){const{ScorerRegistry:o}=await ze(Promise.resolve().then(()=>(GV(),zV)),1e4,he.evaluationTimeout("scorer module load",1e4));await ze(o.registerBuiltInScorers(),3e4,he.evaluationTimeout("scorer bootstrap",3e4));const s=await ze(o.getScorer(t,n),3e4,he.evaluationTimeout(`scorer load: ${t}`,3e4));if(!s)throw he.scorerNotFound(t);const i=s.validateInput(r);if(!i.valid)throw he.evaluationValidationFailed(t,i.errors);const a=await ze(s.score(r),6e4,he.evaluationTimeout("scorer execution",6e4));return m.debug("[NeuroLink] Scoring completed",{scorerId:t,score:a.score,passed:a.passed,computeTime:a.computeTime}),a}async getAvailableScorers(t){const{ScorerRegistry:r}=await ze(Promise.resolve().then(()=>(GV(),zV)),1e4,he.evaluationTimeout("scorer module load",1e4));await ze(r.registerBuiltInScorers(),3e4,he.evaluationTimeout("scorer bootstrap",3e4));let n=r.list();return t?.category&&(n=n.filter(o=>o.category===t.category)),t?.type&&(n=n.filter(o=>o.type===t.type)),n}async getEvaluationPresets(){const{getPresetNames:t}=await ze(Promise.resolve().then(()=>(HS(),jS)),1e4,he.evaluationTimeout("evaluation module load",1e4));return t()}async getEvaluationPreset(t){const{getPreset:r}=await ze(Promise.resolve().then(()=>(HS(),jS)),1e4,he.evaluationTimeout("evaluation module load",1e4));return r(t)}async createAgent(t){const{Agent:r}=await Promise.resolve().then(()=>(Qie(),Rjt));return m.debug("[NeuroLink] Creating agent",{id:t.id,name:t.name,tools:t.tools?.length||0}),new r(t,this)}async createNetwork(t){const{AgentNetwork:r}=await Promise.resolve().then(()=>(Pjt(),Mjt));return m.debug("[NeuroLink] Creating agent network",{name:t.name,agentCount:t.agents.length,workflowCount:t.workflows?.length||0,toolCount:t.tools?.length||0}),new r(t,this)}createWorkerInstance(t){const r=t?.logTag??"worker",n=this.emitter,o=t?.config??{},s={...this.credentials?{credentials:this.credentials}:{},...o,conversationMemory:{enabled:!1},enableOrchestration:!1,observability:{...this.observabilityConfig??{},langfuse:{...this.observabilityConfig?.langfuse??{},autoDetectExternalProvider:!0,skipLangfuseSpanProcessor:!0}},...t?.shareToolRegistry!==!1&&{toolRegistry:this.toolRegistry}},i=this.workerToolsConfig(o.tools),a=new X6(i?{...s,tools:i}:s);if(t?.shareToolRegistry!==!1)for(const c of this.uncacheableTools)a.uncacheableTools.add(c);if(m.setEventEmitter(n),t?.onLog){const c=t.onLog,l=f=>{try{const g=f??{};c({tag:r,level:String(g.level??"info"),message:String(g.message??""),timestamp:typeof g.timestamp=="number"?g.timestamp:Date.now(),data:g.data})}catch{}},u={emit:(f,...g)=>(f==="log-event"&&l(g[0]),!0)},d=a.logInstanceId;m.addScopedEventEmitter(d,u);const p=()=>{m.removeScopedEventEmitter(d,u),this.ownedWorkerLogBridgeDetachers.delete(p)};this.ownedWorkerLogBridgeDetachers.add(p);const h=a.dispose.bind(a);a.dispose=async()=>{p(),await h()}}return m.debug("[NeuroLink] Created worker instance",{tag:r,sharedToolRegistry:t?.shareToolRegistry!==!1}),a}async runIsolatedAgent(t,r,n){const{runIsolatedAgent:o}=await Promise.resolve().then(()=>(p1(),CL));return o(this,t,r,n)}async continueAgent(t,r){const{continueIsolatedAgent:n}=await Promise.resolve().then(()=>(p1(),CL));return n(this,t,r)}async stopAgent(t){const{stopIsolatedAgent:r}=await Promise.resolve().then(()=>(p1(),CL));return r(this,t)}async registerAgentTool(t,r){const{registerAgentTool:n}=await Promise.resolve().then(()=>(h1(),PL)),o=n(this,t,r);return this.hasAgentTools=!0,o}registerTaskTools(){if(this.hasTaskChecklistTools)return;const t=CZr(this);for(const[r,n]of Object.entries(t))this.registerTool(r,n,{cacheable:!1});this.hasTaskChecklistTools=!0,m.info(`[NeuroLink] Registered ${Object.keys(t).length} task checklist tools`)}getTaskState(t){return _Zr(t??Zo(this))}clearTaskState(t){return kZr(t??Zo(this))}registerDelegationTools(t){if(WZr(this,t),this.hasBackgroundDelegationTools)return;const r=nQr(this);for(const[n,o]of Object.entries(r))this.registerTool(n,o,{cacheable:!1});this.hasBackgroundDelegationTools=!0,m.info(`[NeuroLink] Registered ${Object.keys(r).length} background delegation tools`)}async spawnDelegate(t){return i9t(this,t)}async collectDelegates(t){return c9t(this,t)}async cancelDelegates(t){return Xoe(this,t)}getArtifactStore(){return this.mcpArtifactStore||(this.mcpArtifactStore=this.createConfiguredArtifactStore()),this.registerMemoryRetrievalTools(),this.mcpArtifactStore}setArtifactStore(t){const r=this.mcpArtifactStore;r!==t&&(r&&(m.warn("[NeuroLink] Artifact store replaced \u2014 artifacts already written to the previous store will not resolve through this instance"),this.ownsArtifactStore&&r.close&&r.close().catch(n=>{m.warn("[NeuroLink] Previous artifact store close failed",{error:n instanceof Error?n.message:String(n)})})),this.mcpArtifactStore=t,this.ownsArtifactStore=!1,this.installOutputNormalizer(t),this.registerMemoryRetrievalTools())}createConfiguredArtifactStore(){const t=this.artifactsConfig?.store!==void 0,r=ZBt(this.artifactsConfig,this.conversationMemoryConfig?.conversationMemory?.redisConfig);return this.ownsArtifactStore=!t,m.debug("[NeuroLink] Artifact store initialized",{backend:t?"custom":Lne(this.artifactsConfig)}),r}installOutputNormalizer(t){this.mcpOutputNormalizerConfig&&(this.externalServerManager.setOutputNormalizer(new LUt(this.mcpOutputNormalizerConfig,t)),m.debug("[NeuroLink] MCP output normalizer initialized",{...this.mcpOutputNormalizerConfig,hasArtifactStore:t!==void 0}))}async bankArtifact(t,r){return vXr(this,t,r)}async readArtifact(t,r){return wXr(this,t,r)}registerBackgroundCommandTools(t){if(h9t(this,t),this.hasBackgroundCommandTools)return;const r=pQr(this);for(const[n,o]of Object.entries(r))this.registerTool(n,o,{cacheable:!1});this.hasBackgroundCommandTools=!0,m.info(`[NeuroLink] Registered ${Object.keys(r).length} background command tools`)}setBackgroundCommandPolicy(t){h9t(this,t)}async startBackgroundCommand(t,r){return E9t(this,t,r)}getBackgroundCommandStatus(t){return S9t(this,t)}async awaitBackgroundCommand(t,r){return use(this,t,r)}async killBackgroundCommand(t,r){return _9t(this,t,r)}async readBackgroundCommandOutput(t,r){return zL(this,t,r)}registerGitTools(t){if(mQr(this,t),this.hasGitTools)return;const r=TQr(this);for(const[n,o]of Object.entries(r))this.registerTool(n,o,{cacheable:!1});this.hasGitTools=!0,m.info(`[NeuroLink] Registered ${Object.keys(r).length} read-only git tools`)}async runGitCommand(t,r){return F9t(this,t,r)}async executeNetwork(t,r,n){return m.debug("[NeuroLink] Executing agent network",{networkId:t.id,networkName:t.name,hasContext:!!r.context}),t.execute(r,n)}async*streamNetwork(t,r,n){m.debug("[NeuroLink] Streaming agent network",{networkId:t.id,networkName:t.name,hasContext:!!r.context}),yield*t.stream(r,n)}async createOrchestrator(t){const{NetworkOrchestrator:r}=await Promise.resolve().then(()=>(Ljt(),Njt));return m.debug("[NeuroLink] Creating network orchestrator",{maxConcurrentExecutions:t?.maxConcurrentExecutions,defaultMode:t?.defaultMode}),new r(this,t)}async createCoordinator(t){const{AgentCoordinator:r}=await Promise.resolve().then(()=>($jt(),Fjt));return m.debug("[NeuroLink] Creating agent coordinator",{strategy:t?.strategy,maxConcurrency:t?.maxConcurrency}),new r(t)}async createMessageBus(t){const{MessageBus:r}=await Promise.resolve().then(()=>(Bjt(),Ujt));return m.debug("[NeuroLink] Creating message bus",{maxHistorySize:t?.maxHistorySize}),new r(t)}async dispose(){m.debug("[NeuroLink] Starting disposal of resources..."),this.lastCompactionMessageCount.clear();const t=[];try{try{await k9t(this),await Xoe(this)}catch(r){const n=r instanceof Error?r:new Error(`Background work cleanup error: ${String(r)}`);t.push(n),m.warn("[NeuroLink] Error stopping background work:",r)}try{m.debug("[NeuroLink] Flushing and shutting down OpenTelemetry..."),await N2(),await L2(),m.debug("[NeuroLink] OpenTelemetry shutdown successfully")}catch(r){const n=r instanceof Error?r:new Error(`OpenTelemetry shutdown error: ${String(r)}`);t.push(n),m.warn("[NeuroLink] Error shutting down OpenTelemetry:",r)}if(this.externalServerManager)try{m.debug("[NeuroLink] Shutting down external MCP servers..."),await this.externalServerManager.shutdown(),m.debug("[NeuroLink] External MCP servers shutdown successfully")}catch(r){const n=r instanceof Error?r:new Error(`External server shutdown error: ${String(r)}`);t.push(n),m.warn("[NeuroLink] Error shutting down external MCP servers:",r)}if(this.ownsArtifactStore&&this.mcpArtifactStore?.close)try{await this.mcpArtifactStore.close(),m.debug("[NeuroLink] Artifact store closed")}catch(r){const n=r instanceof Error?r:new Error(`Artifact store close error: ${String(r)}`);t.push(n),m.warn("[NeuroLink] Error closing artifact store:",r)}if(this.emitter)try{m.debug("[NeuroLink] Removing all event listeners..."),this.emitter.removeAllListeners(),m.clearEventEmitter(this.emitter),m.clearScopedEventEmitters(this.logInstanceId),m.debug("[NeuroLink] Event listeners removed successfully")}catch(r){const n=r instanceof Error?r:new Error(`Event emitter cleanup error: ${String(r)}`);t.push(n),m.warn("[NeuroLink] Error removing event listeners:",r)}if(this.ownedWorkerLogBridgeDetachers.size>0)try{const r=this.ownedWorkerLogBridgeDetachers.size;for(const n of[...this.ownedWorkerLogBridgeDetachers])n();m.debug(`[NeuroLink] Detached ${r} undisposed worker log bridge(s)`)}catch(r){const n=r instanceof Error?r:new Error(`Worker log bridge cleanup error: ${String(r)}`);t.push(n),m.warn("[NeuroLink] Error detaching worker log bridges:",r)}if(this.toolCircuitBreakers&&this.toolCircuitBreakers.size>0)try{m.debug(`[NeuroLink] Clearing ${this.toolCircuitBreakers.size} circuit breakers...`),this.toolCircuitBreakers.clear(),m.debug("[NeuroLink] Circuit breakers cleared successfully")}catch(r){const n=r instanceof Error?r:new Error(`Circuit breaker cleanup error: ${String(r)}`);t.push(n),m.warn("[NeuroLink] Error clearing circuit breakers:",r)}try{m.debug("[NeuroLink] Clearing maps and caches..."),this.toolExecutionMetrics&&this.toolExecutionMetrics.clear(),this.activeToolExecutions&&this.activeToolExecutions.clear(),this.currentStreamToolExecutions&&(this.currentStreamToolExecutions.length=0),this.toolExecutionHistory&&(this.toolExecutionHistory.length=0),this.toolCache&&(this.toolCache.tools=[],this.toolCache.timestamp=0),this.mcpToolResultCache?.destroy(),this.mcpToolRouter?.destroy(),this.mcpToolBatcher?.destroy(),this.mcpToolResultCache=void 0,this.mcpToolRouter=void 0,this.mcpToolBatcher=void 0,this.mcpEnhancedDiscovery=void 0,this.mcpToolMiddlewares=[],m.debug("[NeuroLink] Maps and caches cleared successfully")}catch(r){const n=r instanceof Error?r:new Error(`Cache cleanup error: ${String(r)}`);t.push(n),m.warn("[NeuroLink] Error clearing caches:",r)}if(this._taskManager)try{m.debug("[NeuroLink] Shutting down TaskManager..."),await ze(this._taskManager.shutdown(),5e3,new Error("TaskManager shutdown timed out"))}catch(r){m.warn("[NeuroLink] TaskManager shutdown error:",r)}finally{this._taskManager=void 0}try{m.debug("[NeuroLink] Resetting initialization state..."),this.mcpInitialized=!1,this.mcpInitPromise=null,this.conversationMemoryNeedsInit=!1,this.credentials=void 0,m.debug("[NeuroLink] Initialization state reset successfully")}catch(r){const n=r instanceof Error?r:new Error(`State reset error: ${String(r)}`);t.push(n),m.warn("[NeuroLink] Error resetting state:",r)}t.length===0?m.debug("[NeuroLink] \u2705 Resource disposal completed successfully"):m.warn(`[NeuroLink] \u26A0\uFE0F Resource disposal completed with ${t.length} errors`,{errors:t.map(r=>r.message)})}catch(r){throw m.error("[NeuroLink] Critical error during disposal:",r),r}}getToolRegistry(){return this.toolRegistry}async compactSession(t,r){if(!this.conversationMemory)return null;const n=await this.conversationMemory.buildContextMessages(t);if(!n||n.length===0)return null;const o=new rw({...r,summarizationProvider:r?.summarizationProvider??this.conversationMemoryConfig?.conversationMemory?.summarizationProvider,summarizationModel:r?.summarizationModel??this.conversationMemoryConfig?.conversationMemory?.summarizationModel},this.contextCompactorDeps()),s=Ji({provider:r?.provider||"openai",conversationMessages:n}),i=Math.floor(s.availableInputTokens*.6),a=await o.compact(n,i,this.conversationMemoryConfig?.conversationMemory);return a.compacted&&ew(a.messages),a}async getContextStats(t,r,n){if(!this.conversationMemory)return null;const o=await this.conversationMemory.buildContextMessages(t);if(!o||o.length===0)return null;const s=Ji({provider:r||"openai",model:n,conversationMessages:o});return{estimatedInputTokens:s.estimatedInputTokens,availableInputTokens:s.availableInputTokens,usageRatio:s.usageRatio,shouldCompact:s.shouldCompact,messageCount:o.length}}needsCompaction(t,r,n){if(!this.conversationMemory)return!1;const o=this.conversationMemory.getSession?.(t);return o?Ji({provider:r||"openai",model:n,conversationMessages:o.messages}).shouldCompact:!1}async setAuthProvider(t){this.authInitPromise=void 0,await this.initializeAuthProviderFromConfig(t)}async initializeAuthProviderFromConfig(t){let r,n;if("authenticateToken"in t&&typeof t.authenticateToken=="function")r=t,n=r.type;else if("provider"in t)r=t.provider,n=r.type;else{const o=t,{AuthProviderFactory:s}=await Promise.resolve().then(()=>(I3(),zjt));r=await s.createProvider(o.type,o.config),n=o.type}this.authProvider=r,m.info(`Auth provider set: ${n}`),this.emitter.emit("auth:provider:set",{type:r.type,timestamp:Date.now()})}getAuthProvider(){return this.authProvider}async ensureAuthProvider(){if(this.authProvider||!this.pendingAuthConfig)return;const t=this.pendingAuthConfig;this.authInitPromise??=(async()=>{try{await this.initializeAuthProviderFromConfig(t),this.pendingAuthConfig=void 0}finally{this.authInitPromise&&(this.pendingAuthConfig===void 0||this.pendingAuthConfig===t)&&(this.authInitPromise=void 0)}})(),await this.authInitPromise}async setAuthContext(t){const{globalAuthContext:r}=await Promise.resolve().then(()=>(Jx(),aL));r.set(t),m.debug("Auth context set",{userId:t.user.id,provider:t.provider,sessionId:t.session?.id})}async getAuthContext(){const{getAuthContext:t}=await Promise.resolve().then(()=>(Jx(),aL));return t()}async clearAuthContext(){const{globalAuthContext:t}=await Promise.resolve().then(()=>(Jx(),aL)),r=t.get()?.user.id;t.clear(),r&&m.debug(`Auth context cleared for user: ${r}`)}getExternalServerManager(){return this.externalServerManager}buildResolutionContext(t,r){return{requestContext:r||{},signal:t}}async resolveDynamicOptions(t){const r=["model","provider","temperature","maxTokens","systemPrompt","timeout","thinkingLevel","disableTools","enableAnalytics","enableEvaluation"];if(!(r.some(s=>typeof t[s]=="function")||typeof t.tools=="function"))return;const o=t.dynamicContext;await this.resolveDynamicFields(t,r,o)}async resolveDynamicFields(t,r,n){const o=this.buildResolutionContext(t.abortSignal,n);if(m.debug("[NeuroLink] Resolving dynamic arguments"),await Promise.all(r.map(async s=>{if(typeof t[s]=="function"){const i=await zne(t[s],o);t[s]=i.value,m.debug(`[NeuroLink] Resolved dynamic ${s}: ${i.resolutionType}`)}})),typeof t.tools=="function"){const s=await zne(t.tools,o);if(!Array.isArray(s.value))throw new TypeError(`Dynamic tools resolver must return string[] (tool names), got ${typeof s.value=="object"?"object":typeof s.value}`);t.enabledToolNames=s.value,delete t.tools}}},lae=new Qw,jjt=lae}});function Hjt(e,t,r,n){const o=typeof e=="object"&&e!==null?e.data:void 0;if(!Array.isArray(o)||o.length===0)throw n(`${r} embeddings response missing data`);if(o.length!==t)throw n(`${r} embeddings response count mismatch: expected ${t}, got ${o.length}`);const s=o.findIndex(a=>!Wjt(a));if(s!==-1)throw n(`${r} embeddings response entry ${s} is not an {index, embedding: number[]} object`);const i=o.slice().sort((a,c)=>a.index-c.index);for(let a=0;a<i.length;a++)if(i[a].index!==a)throw n(`${r} embeddings response has unexpected index ordering: position ${a} has index ${i[a].index}`);return i.map(a=>a.embedding)}var Wjt,Kjt=S({"src/lib/providers/embeddingResponseParsing.ts"(){"use strict";Wjt=e=>{if(typeof e!="object"||e===null)return!1;const{embedding:t,index:r}=e;return Number.isInteger(r)&&Array.isArray(t)&&t.every(n=>typeof n=="number"&&Number.isFinite(n))}}}),Jjt={};Z(Jjt,{VoyageProvider:()=>Zjt});var Yjt,uae,Xjt,M3,Zjt,Qnn=S({async"src/lib/providers/voyage.ts"(){"use strict";Ya(),await Ul(),Kjt(),Fn(),dt(),et(),z(),$o(),Yjt="https://api.voyageai.com/v1",uae=6e4,Xjt=()=>ua(PCr()),M3=()=>zs("VOYAGE_MODEL","voyage-3.5"),Zjt=class extends va{apiKey;baseURL;proxyFetch;constructor(e,t,r,n){const o=Hm(t)?t:void 0;super(e,"voyage",o);const s=n?.apiKey?.trim();this.apiKey=s&&s.length>0?s:Xjt(),this.baseURL=n?.baseURL??process.env.VOYAGE_BASE_URL??Yjt,this.proxyFetch=Pt(),m.debug("Voyage Provider initialized (embeddings only)",{modelName:this.modelName,baseURL:this.baseURL})}getProviderName(){return this.providerName}getDefaultModel(){return M3()}supportsTools(){return!1}getDefaultEmbeddingModel(){return M3()}getAISDKModel(){throw new it("Voyage AI is an embedding-only provider; chat completions are not available. Use `embed()` or `embedMany()` instead, or pick a different provider for `generate()` / `stream()`.","voyage")}async executeStream(e,t){throw new it("Voyage AI is an embedding-only provider; streaming chat is not available. Use `embed()` / `embedMany()`, or pick another provider for `stream()`.","voyage")}formatProviderError(e){const t=e instanceof Error?e.message:typeof e=="string"?e:"Unknown error";return t.includes("401")||t.toLowerCase().includes("unauthorized")||t.includes("invalid_api_key")?new Dr("Invalid Voyage AI API key. Get one at https://dash.voyageai.com/api-keys","voyage"):t.includes("429")||t.toLowerCase().includes("rate limit")?new Us("Voyage AI rate limit exceeded. Back off and retry.","voyage"):t.includes("404")||t.toLowerCase().includes("model_not_found")?new No(`Voyage AI model '${this.modelName}' not found. Browse https://docs.voyageai.com/docs/embeddings`,"voyage"):new it(`Voyage AI error: ${t}`,"voyage")}async embed(e,t){if(typeof e!="string"&&e.image)throw new it(`${this.providerName} does not support image embeddings; provide text input`,this.providerName);const r=typeof e=="string"?e:e.text??"",n=await this.callEmbeddings([r],t);if(!n[0])throw new it("Voyage AI returned no embedding for the provided text","voyage");return n[0]}async embedMany(e,t){if(e.length===0)return[];const r=128,n=[];for(let o=0;o<e.length;o+=r){const s=e.slice(o,o+r),i=await this.callEmbeddings(s,t);n.push(...i)}return n}async callEmbeddings(e,t){const r=t??this.modelName;let n;try{n=await ze(this.proxyFetch(`${this.baseURL}/embeddings`,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},body:JSON.stringify({input:e,model:r})}),uae,new it(`Voyage embeddings request timed out after ${uae/1e3}s`,"voyage"))}catch(s){throw s instanceof it?s:this.formatProviderError(s)}if(!n.ok){const s=await n.text();throw this.formatProviderError(new Error(`Voyage embeddings failed: ${n.status} \u2014 ${s}`))}const o=await n.json();return Hjt(o,e.length,"Voyage",s=>new it(s,"voyage"))}async validateConfiguration(){return typeof this.apiKey=="string"&&this.apiKey.trim().length>0}getConfiguration(){return{provider:this.providerName,model:this.modelName,defaultModel:M3(),baseURL:this.baseURL}}}}}),Qjt={};Z(Qjt,{JinaProvider:()=>rHt});var eHt,U1,tHt,P3,rHt,eon=S({async"src/lib/providers/jina.ts"(){"use strict";Ya(),await Ul(),Kjt(),Fn(),dt(),z(),$o(),eHt="https://api.jina.ai/v1",U1=6e4,tHt=()=>ua(OCr()),P3=()=>zs("JINA_MODEL","jina-embeddings-v3"),rHt=class extends va{apiKey;baseURL;proxyFetch;constructor(e,t,r,n){const o=Hm(t)?t:void 0;super(e,"jina",o);const s=n?.apiKey?.trim();this.apiKey=s&&s.length>0?s:tHt(),this.baseURL=n?.baseURL??process.env.JINA_BASE_URL??eHt,this.proxyFetch=Pt(),m.debug("Jina Provider initialized (embeddings + reranking)",{modelName:this.modelName,baseURL:this.baseURL})}getProviderName(){return this.providerName}getDefaultModel(){return P3()}supportsTools(){return!1}getDefaultEmbeddingModel(){return P3()}getAISDKModel(){throw new Error("Jina AI is an embeddings + reranking provider; chat completions are not available. Use `embed()` / `embedMany()` / `rerank()`.")}async executeStream(e,t){throw new Error("Jina AI is an embeddings + reranking provider; streaming chat is not available.")}formatProviderError(e){const t=e instanceof Error?e.message:typeof e=="string"?e:"Unknown error";return t.includes("401")||t.toLowerCase().includes("unauthorized")?new Dr("Invalid Jina AI API key. Get one at https://jina.ai/?sui=apikey","jina"):t.includes("429")||t.toLowerCase().includes("rate limit")?new Us("Jina AI rate limit exceeded. Back off and retry.","jina"):t.includes("404")||t.toLowerCase().includes("model_not_found")?new No(`Jina AI model '${this.modelName}' not found. See https://jina.ai/embeddings/`,"jina"):new it(`Jina AI error: ${t}`,"jina")}async embed(e,t){if(typeof e!="string"&&e.image)throw new it(`${this.providerName} does not support image embeddings; provide text input`,this.providerName);const r=typeof e=="string"?e:e.text??"",n=await this.callEmbeddings([r],t);if(!n[0])throw new Error("Jina AI returned no embedding for the provided text");return n[0]}async embedMany(e,t){return e.length===0?[]:this.callEmbeddings(e,t)}async rerank(e,t,r={}){if(t.length===0)return[];const n=r.model??"jina-reranker-v2-base-multilingual",o=r.credentials,s=o?.apiKey?.trim()||this.apiKey,i=o?.baseURL||this.baseURL,a=new AbortController,c=setTimeout(()=>a.abort(),U1);let l;try{l=await this.proxyFetch(`${i}/rerank`,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify({model:n,query:e,documents:t,top_n:r.topN??t.length}),signal:a.signal})}catch(d){throw d instanceof Error&&d.name==="AbortError"?this.formatProviderError(new Error(`Jina rerank request timed out after ${U1/1e3}s`)):this.formatProviderError(d)}finally{clearTimeout(c)}if(!l.ok){const d=await l.text();throw this.formatProviderError(new Error(`Jina rerank failed: ${l.status} \u2014 ${d}`))}return((await l.json()).results??[]).map(d=>({index:d.index,score:d.relevance_score,document:t[d.index]??d.document?.text??""}))}async callEmbeddings(e,t,r){const n=t??this.modelName,o=r?.apiKey?.trim()||this.apiKey,s=r?.baseURL||this.baseURL,i=new AbortController,a=setTimeout(()=>i.abort(),U1);let c;try{c=await this.proxyFetch(`${s}/embeddings`,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},body:JSON.stringify({input:e,model:n}),signal:i.signal})}catch(u){throw u instanceof Error&&u.name==="AbortError"?this.formatProviderError(new Error(`Jina embeddings request timed out after ${U1/1e3}s`)):this.formatProviderError(u)}finally{clearTimeout(a)}if(!c.ok){const u=await c.text();throw this.formatProviderError(new Error(`Jina embeddings failed: ${c.status} \u2014 ${u}`))}const l=await c.json();return Hjt(l,e.length,"Jina",u=>new Error(u))}async validateConfiguration(){return typeof this.apiKey=="string"&&this.apiKey.trim().length>0}getConfiguration(){return{provider:this.providerName,model:this.modelName,defaultModel:P3(),baseURL:this.baseURL}}}}}),nHt={};Z(nHt,{StabilityProvider:()=>mae,default:()=>iHt});var oHt,dae,sHt,pae,mae,iHt,ton=S({async"src/lib/providers/stability.ts"(){"use strict";Ya(),await Ul(),Fn(),dt(),z(),$o(),oHt="https://api.stability.ai",dae=12e4,sHt=()=>(process.env.STABILITY_API_KEY??process.env.STABILITY_AI_API_KEY??"").trim()||void 0,pae=()=>zs("STABILITY_MODEL","stable-image-ultra"),mae=class extends va{apiKey;baseURL;proxyFetch;constructor(e,t,r,n){const o=Hm(t)?t:void 0;super(e,"stability",o);const s=n?.apiKey?.trim();this.apiKey=s&&s.length>0?s:sHt(),this.baseURL=n?.baseURL??process.env.STABILITY_BASE_URL??oHt,this.proxyFetch=Pt(),m.debug("Stability AI Provider initialized (image-gen only)",{modelName:this.modelName,baseURL:this.baseURL})}getProviderName(){return this.providerName}getDefaultModel(){return pae()}supportsTools(){return!1}getAISDKModel(){throw new Error("Stability AI is an image-generation-only provider; chat completions are not available.")}async executeStream(e,t){throw new Error("Stability AI is an image-generation-only provider; streaming chat is not available. Use generate({output:{format:'binary'}}) with a Stable Image / SD 3.5 model.")}formatProviderError(e){const t=e instanceof Error?e.message:typeof e=="string"?e:"Unknown error";return t.includes("401")||t.toLowerCase().includes("unauthorized")?new Dr("Invalid Stability AI API key. Get one at https://platform.stability.ai/account/keys","stability"):t.includes("429")||t.toLowerCase().includes("rate limit")?new Us("Stability AI rate limit exceeded. Back off and retry.","stability"):t.includes("content_filtered")||t.includes("CONTENT_FILTERED")?new it("Stability AI declined the request due to content policy. Adjust the prompt and retry.","stability"):t.includes("404")?new No(`Stability AI model '${this.modelName}' not found. Use stable-image-ultra, stable-image-core, sd3.5-large, sd3.5-large-turbo, or sd3.5-medium.`,"stability"):new it(`Stability AI error: ${t}`,"stability")}async executeImageGeneration(e){const t=Date.now(),r=e.credentials?.stability,n=r?.apiKey?.trim()||this.apiKey;if(!n)throw new Error("Stability AI API key is required. Set STABILITY_API_KEY or pass credentials.stability.apiKey per-call.");const o=n,s=r?.baseURL||this.baseURL,i=e.prompt??e.input?.text??"";if(!i.trim())throw new Error("Stability AI image generation requires a prompt (input.text or prompt)");const a=this.modelName.startsWith("sd3.5-")?"sd3":this.modelName==="stable-image-ultra"?"ultra":this.modelName==="stable-image-core"?"core":this.modelName,c=e,l=new FormData;l.append("prompt",i),l.append("output_format","png"),c.aspectRatio&&l.append("aspect_ratio",String(c.aspectRatio)),c.negativePrompt&&l.append("negative_prompt",c.negativePrompt),this.modelName.startsWith("sd3.5-")&&l.append("model",this.modelName),c.seed!==void 0&&l.append("seed",String(c.seed));const u=new AbortController,d=setTimeout(()=>u.abort(),dae);let p;try{p=await this.proxyFetch(`${s}/v2beta/stable-image/generate/${a}`,{method:"POST",headers:{Authorization:`Bearer ${o}`,Accept:"application/json"},body:l,signal:u.signal})}catch(g){throw g instanceof Error&&g.name==="AbortError"?this.formatProviderError(new Error(`Stability image-gen request timed out after ${dae/1e3}s`)):this.formatProviderError(g)}finally{clearTimeout(d)}if(!p.ok){const g=await p.text();throw this.formatProviderError(new Error(`Stability image-gen failed: ${p.status} \u2014 ${g}`))}const h=await p.json();if(!h.image)throw new Error(`Stability AI returned no image (finish_reason: ${h.finish_reason??"unknown"})`);const f=Date.now()-t;return m.info(`[StabilityProvider] Generated image (${h.image.length} base64 chars) in ${f}ms \u2014 model ${this.modelName}`),{content:i,provider:this.providerName,model:this.modelName,usage:{input:0,output:1e3,total:1e3},imageOutput:{base64:h.image}}}async validateConfiguration(){return this.apiKey!==void 0&&this.apiKey.trim().length>0}getConfiguration(){return{provider:this.providerName,model:this.modelName,defaultModel:pae(),baseURL:this.baseURL}}},iHt=mae}}),aHt={};Z(aHt,{IdeogramProvider:()=>gae,default:()=>uHt});var cHt,hae,lHt,fae,gae,uHt,ron=S({async"src/lib/providers/ideogram.ts"(){"use strict";Ya(),await Ul(),Fn(),dt(),z(),$o(),wa(),Tm(),cHt="https://api.ideogram.ai",hae=12e4,lHt=()=>ua(DCr()),fae=()=>zs("IDEOGRAM_MODEL","V_3"),gae=class extends va{apiKey;baseURL;proxyFetch;constructor(e,t,r,n){const o=Hm(t)?t:void 0;super(e,"ideogram",o);const s=n?.apiKey?.trim();this.apiKey=s&&s.length>0?s:lHt(),this.baseURL=n?.baseURL??process.env.IDEOGRAM_BASE_URL??cHt,this.proxyFetch=Pt(),m.debug("Ideogram Provider initialized (image-gen only)",{modelName:this.modelName,baseURL:this.baseURL})}getProviderName(){return this.providerName}getDefaultModel(){return fae()}supportsTools(){return!1}getAISDKModel(){throw new Error("Ideogram is an image-generation-only provider; chat completions are not available.")}async executeStream(e,t){throw new Error("Ideogram is an image-generation-only provider; streaming chat is not available.")}formatProviderError(e){const t=e instanceof Error?e.message:typeof e=="string"?e:"Unknown error";return t.includes("401")||t.toLowerCase().includes("unauthorized")?new Dr("Invalid Ideogram API key. Get one at https://developer.ideogram.ai/","ideogram"):t.includes("429")||t.toLowerCase().includes("rate limit")?new Us("Ideogram rate limit exceeded. Back off and retry.","ideogram"):t.includes("safety")||t.includes("is_image_safe")?new it("Ideogram declined the request due to safety filters. Adjust the prompt and retry.","ideogram"):new it(`Ideogram error: ${t}`,"ideogram")}async executeImageGeneration(e){const t=Date.now(),r=e.credentials?.ideogram,n=r?.apiKey?.trim()||this.apiKey,o=r?.baseURL||this.baseURL,s=e.prompt??e.input?.text??"";if(!s.trim())throw new Error("Ideogram image generation requires a prompt (input.text or prompt)");const i=e,a={prompt:s,model:this.modelName,magic_prompt:i.magicPrompt??"AUTO"};i.aspectRatio&&(a.aspect_ratio=i.aspectRatio),i.negativePrompt&&(a.negative_prompt=i.negativePrompt),i.seed!==void 0&&(a.seed=i.seed),i.style&&(a.style_type=i.style);const c=new AbortController,l=setTimeout(()=>c.abort(),hae);let u;try{u=await this.proxyFetch(`${o}/v1/ideogram-v3/generate`,{method:"POST",headers:{"Api-Key":n,"Content-Type":"application/json"},body:JSON.stringify(a),signal:c.signal})}catch(b){throw b instanceof Error&&b.name==="AbortError"?this.formatProviderError(new Error(`Ideogram image-gen request timed out after ${hae/1e3}s`)):this.formatProviderError(b)}finally{clearTimeout(l)}if(!u.ok){const b=await u.text();throw this.formatProviderError(new Error(`Ideogram image-gen failed: ${u.status} \u2014 ${b}`))}const p=(await u.json()).data?.[0]?.url;if(!p)throw new Error("Ideogram returned no image URL");await wm(p);const h=new AbortController,f=setTimeout(()=>h.abort(),6e4);let g;try{g=await this.proxyFetch(p,{signal:h.signal})}catch(b){throw b instanceof Error&&b.name==="AbortError"?new Error("Ideogram image download timed out after 60s",{cause:b}):b}finally{clearTimeout(f)}if(!g.ok)throw new Error(`Failed to download Ideogram image: ${g.status}`);const y=await Cu(g,vm,"Ideogram image"),v=y.toString("base64"),T=Date.now()-t;return m.info(`[IdeogramProvider] Generated image (${y.length} bytes) in ${T}ms \u2014 model ${this.modelName}`),{content:s,provider:this.providerName,model:this.modelName,usage:{input:0,output:1e3,total:1e3},imageOutput:{base64:v}}}async validateConfiguration(){return typeof this.apiKey=="string"&&this.apiKey.trim().length>0}getConfiguration(){return{provider:this.providerName,model:this.modelName,defaultModel:fae(),baseURL:this.baseURL}}},uHt=gae}}),dHt={};Z(dHt,{ReplicateProvider:()=>pHt});function non(e){const t=e,r=t.prompt??t.input?.text??"",n=t.systemPrompt;return n?`${n}
|
|
2156
2156
|
|
|
2157
|
-
${r}`:r}function oon(e){return typeof e=="string"?e:Array.isArray(e)?e.map(t=>typeof t=="string"?t:"").join(""):""}function yae(e){const t=e?.apiKey?.trim()||e?.apiToken?.trim(),r=e?.baseURL||e?.baseUrl;return{apiToken:t,baseUrl:r}}var vae,pHt,son=S({async"src/lib/providers/replicate.ts"(){"use strict";Ya(),af(),m3(),f3(),wa(),await Ul(),z(),et(),$o(),vae=()=>zs("REPLICATE_MODEL","meta/meta-llama-3-70b-instruct"),pHt=class extends va{apiToken;baseURL;constructor(e,t,r,n){const o=Hm(t)?t:void 0;super(e,"replicate",o);const{apiToken:s,baseUrl:i}=yae(n);this.apiToken=s&&s.length>0?s:ua(MCr()),this.baseURL=i,m.debug("Replicate Provider initialized",{modelName:this.modelName,baseURL:this.baseURL})}getProviderName(){return this.providerName}getDefaultModel(){return vae()}supportsTools(){return!1}getAISDKModel(){throw new Error("Replicate routes through the predictions API, not the AI SDK chat models. Streaming uses the predict-then-stream path inside executeStream.")}async generate(e,t){const r=typeof e=="string"?{prompt:e}:e,n=bd(r,this.modelName);if(n==="video"||n==="avatar"||n==="music"||n==="image")return super.generate(r,t);if(r.output?.format==="json"||r.output?.format==="structured"||t!=null)throw new Oe({code:He.PROVIDER_NOT_AVAILABLE,message:"Replicate models do not support structured-output / JSON schema. Remove output.format or _analysisSchema, or use a provider that implements the OpenAI chat-completions contract (e.g. openai, anthropic).",category:"validation",severity:"medium",retriable:!1});const o=r.prompt??r.input?.text??"",s=Date.now(),i=await this.executeStream({input:{text:o},systemPrompt:r.systemPrompt,maxTokens:r.maxTokens,temperature:r.temperature,abortSignal:r.abortSignal,timeout:r.timeout});let a="";for await(const l of i.stream)"content"in l&&typeof l.content=="string"&&(a+=l.content);const c={content:a,provider:this.providerName,model:this.modelName,usage:{input:0,output:0,total:0}};return m.info(`[ReplicateProvider] generate() complete in ${Date.now()-s}ms \u2014 ${a.length} chars`),c}async executeStream(e,t){const r=Date.now(),n=e.credentials?.replicate,o=yae(n),s=o.apiToken||this.apiToken,i=o.baseUrl||this.baseURL,a=Vm({apiToken:s,baseUrl:i});if(!a)throw new Oe({code:He.MISSING_CONFIGURATION,message:"Replicate auth could not be resolved (REPLICATE_API_TOKEN missing).",category:"configuration",severity:"high",retriable:!1});const c=non(e);if(!c.trim())throw new Oe({code:He.INVALID_PARAMETERS,message:"Replicate predictions require a prompt (input.text or prompt)",category:"validation",severity:"medium",retriable:!1});const l={prompt:c,...e.maxTokens!==void 0&&{max_new_tokens:e.maxTokens},temperature:e.temperature,top_p:1};let u;try{u=await L1(a,{model:this.modelName,input:l},{abortSignal:e.abortSignal})}catch(h){throw this.handleProviderError(h)}const d=oon(u.output);if(!d)throw new Error(`Replicate prediction ${u.id} returned empty output`);const p={async*[Symbol.asyncIterator](){yield{content:d}}};return m.info(`[ReplicateProvider] Generated ${d.length} chars in ${Date.now()-r}ms \u2014 model ${this.modelName} (prediction ${u.id})`),{stream:p,provider:this.providerName,model:this.modelName,finishReason:"stop",metadata:{startTime:r,streamId:`replicate-${u.id}`}}}async executeImageGeneration(e){const t=Date.now(),r=e.credentials?.replicate,n=yae(r),o=n.apiToken||this.apiToken,s=n.baseUrl||this.baseURL,i=Vm({apiToken:o,baseUrl:s});if(!i)throw new Oe({code:He.MISSING_CONFIGURATION,message:"Replicate auth could not be resolved (REPLICATE_API_TOKEN missing).",category:"configuration",severity:"high",retriable:!1});const a=e.prompt??e.input?.text??"";if(!a.trim())throw new Oe({code:He.INVALID_PARAMETERS,message:"Replicate image-gen requires a prompt",category:"validation",severity:"medium",retriable:!1});const c=e,l={prompt:a,output_format:"png"};c.aspectRatio&&(l.aspect_ratio=c.aspectRatio),c.negativePrompt&&(l.negative_prompt=c.negativePrompt),c.seed!==void 0&&(l.seed=c.seed);let u;try{u=await L1(i,{model:this.modelName,input:l},{abortSignal:e.abortSignal})}catch(h){throw this.handleProviderError(h)}let d;try{d=await h3(u,vm)}catch(h){throw this.handleProviderError(h)}const p=d.toString("base64");return m.info(`[ReplicateProvider] Generated image (${d.length} bytes) in ${Date.now()-t}ms \u2014 model ${this.modelName}`),{content:a,provider:this.providerName,model:this.modelName,usage:{input:0,output:0,total:0},imageOutput:{base64:p}}}formatProviderError(e){const t=e instanceof Error?e.message:typeof e=="string"?e:"Unknown error",r=e instanceof Error?e:void 0;return t.includes("401")||t.toLowerCase().includes("unauthorized")||t.toLowerCase().includes("invalid token")?new Oe({code:He.PROVIDER_AUTH_FAILED,message:"Invalid Replicate API token. Get one at https://replicate.com/account/api-tokens",category:"configuration",severity:"high",retriable:!1,context:{provider:"replicate"},originalError:r}):t.includes("402")||t.toLowerCase().includes("insufficient credit")?new Oe({code:He.PROVIDER_QUOTA_EXCEEDED,message:"Replicate insufficient credit. Top up at https://replicate.com/account/billing \u2014 most image/music models require a paid balance.",category:"resource",severity:"high",retriable:!1,context:{provider:"replicate"},originalError:r}):t.includes("429")||t.toLowerCase().includes("rate limit")?new Oe({code:He.PROVIDER_QUOTA_EXCEEDED,message:"Replicate rate limit exceeded. Back off and retry.",category:"resource",severity:"high",retriable:!0,context:{provider:"replicate"},originalError:r}):t.toLowerCase().includes("not found")||t.includes("404")?new Oe({code:He.PROVIDER_NOT_AVAILABLE,message:`Replicate model '${this.modelName}' not found. Use owner/name or owner/name:version format. Browse https://replicate.com/explore`,category:"validation",severity:"medium",retriable:!1,context:{provider:"replicate",model:this.modelName},originalError:r}):new Oe({code:He.PROVIDER_NOT_AVAILABLE,message:`Replicate error: ${t}`,category:"execution",severity:"high",retriable:!1,context:{provider:"replicate"},originalError:r})}async validateConfiguration(){return typeof this.apiToken=="string"&&this.apiToken.trim().length>0}getConfiguration(){return{provider:this.providerName,model:this.modelName,defaultModel:vae(),baseURL:this.baseURL}}}}}),mHt={};Z(mHt,{RecraftProvider:()=>bae,default:()=>gHt});var hHt,wae,fHt,Tae,bae,gHt,ion=S({async"src/lib/providers/recraft.ts"(){"use strict";Ya(),await Ul(),Fn(),dt(),z(),$o(),wa(),Tm(),Zv(),hHt="https://external.api.recraft.ai/v1",wae=12e4,fHt=()=>ua(NCr()),Tae=()=>zs("RECRAFT_MODEL","recraftv3"),bae=class extends va{apiKey;baseURL;proxyFetch;constructor(e,t,r,n){const o=Hm(t)?t:void 0;super(e,"recraft",o);const s=n?.apiKey?.trim();this.apiKey=s&&s.length>0?s:fHt(),this.baseURL=n?.baseURL??process.env.RECRAFT_BASE_URL??hHt,this.proxyFetch=Pt(),m.debug("Recraft Provider initialized (image-gen only)",{modelName:this.modelName,baseURL:this.baseURL})}getProviderName(){return this.providerName}getDefaultModel(){return Tae()}supportsTools(){return!1}getAISDKModel(){throw new Error("Recraft is an image-generation-only provider; chat completions are not available.")}async executeStream(e,t){throw new Error("Recraft is an image-generation-only provider; streaming chat is not available.")}formatProviderError(e){const t=e instanceof Error?e.message:typeof e=="string"?e:"Unknown error";return t.includes("401")||t.toLowerCase().includes("unauthorized")?new Dr("Invalid Recraft API key. Get one at https://www.recraft.ai/api","recraft"):t.includes("429")||t.toLowerCase().includes("rate limit")?new Us("Recraft rate limit exceeded. Back off and retry.","recraft"):t.includes("404")||t.includes("model_not_found")?new No(`Recraft model '${this.modelName}' not found. Use recraftv3, recraftv3-svg, or recraftv2.`,"recraft"):new it(`Recraft error: ${t}`,"recraft")}async executeImageGeneration(e){const t=Date.now(),r=e.credentials?.recraft,n=r?.apiKey?.trim()||this.apiKey,o=r?.baseURL||this.baseURL,s=e.prompt??e.input?.text??"";if(!s.trim())throw new Error("Recraft image generation requires a prompt (input.text or prompt)");const i=e,a={model:e.model??this.modelName,prompt:s,n:1,response_format:"b64_json"};i.negativePrompt&&(a.negative_prompt=i.negativePrompt),i.style&&(a.style=i.style),i.styleId&&(a.style_id=i.styleId),i.size&&(a.size=i.size);const c=new AbortController,l=setTimeout(()=>c.abort(),wae);let u;try{u=await this.proxyFetch(`${o}/images/generations`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify(a),signal:c.signal})}catch(g){throw g instanceof Error&&g.name==="AbortError"?this.formatProviderError(new Error(`Recraft image-gen request timed out after ${wae/1e3}s`)):this.formatProviderError(g)}finally{clearTimeout(l)}if(!u.ok){const g=await u.text();throw this.formatProviderError(new Error(`Recraft image-gen failed: ${u.status} \u2014 ${g}`))}const p=(await u.json()).data?.[0];if(!p)throw new Error("Recraft returned no image data");let h;if(p.b64_json)h=p.b64_json;else if(p.url){await wm(p.url);const g=new AbortController,y=setTimeout(()=>g.abort(),6e4);let v;try{v=await this.proxyFetch(p.url,{signal:g.signal})}catch(b){throw b instanceof Error&&b.name==="AbortError"?new Error("Recraft image download timed out after 60s",{cause:b}):b}finally{clearTimeout(y)}if(!v.ok)throw new Error(`Failed to download Recraft image: ${v.status}`);h=(await Cu(v,vm,"Recraft image")).toString("base64")}else throw new Error("Recraft response missing both b64_json and url");const f=Date.now()-t;return m.info(`[RecraftProvider] Generated image (${h.length} base64 chars) in ${f}ms \u2014 model ${this.modelName}`),{content:s,provider:this.providerName,model:this.modelName,usage:{input:0,output:1e3,total:1e3},imageOutput:{base64:h,mimeType:yx(Buffer.from(h.slice(0,64),"base64"))}}}async validateConfiguration(){return typeof this.apiKey=="string"&&this.apiKey.trim().length>0}getConfiguration(){return{provider:this.providerName,model:this.modelName,defaultModel:Tae(),baseURL:this.baseURL}}},gHt=bae}});function aon(e){return A_(e)&&pP(e)===null?"video/mp4":SHt.every((t,r)=>e[r]===t)?"video/webm":null}function yHt(e,t,r){const n=t==="image"?gx(e):aon(e);return n===null?{status:"error",message:`${r} ${_Ht[t]}.`}:{status:"ok",dataUrl:`data:${n};base64,${e.toString("base64")}`}}function Eae(e){return e.length<=bHt?`(${e})`:`(a ${e.length}-character string)`}async function con(e,t,r){try{const n=await d4.stat(e);return n.isFile()?n.size>r?{status:"error",message:`${t} ${Eae(e)} is ${n.size} bytes; a request may carry at most ${r}.`}:{status:"ok",buffer:await d4.readFile(e)}:{status:"error",message:`${t} ${Eae(e)} is not a file.`}}catch(n){const o=n instanceof Error&&"code"in n?String(n.code):"unreadable";return{status:"error",message:`Could not read ${t} ${Eae(e)}: ${o}.`}}}async function vHt(e,t,r,n){if(typeof e!="string")return e.length===0?{status:"error",message:`${r} is an empty Buffer.`}:yHt(e,t,r);const o=e.trim();if(o==="")return{status:"error",message:`${r} is an empty string.`};if(wHt.test(o))return{status:"error",message:`${r} is a remote URL. Media is not fetched for you; pass a Buffer, a file path or a data: URL.`};if(/^data:/i.test(o))return EHt[t].test(o)?{status:"ok",dataUrl:o}:{status:"error",message:`${r} is a data: URL that is not base64 ${t} content.`};if(THt.test(o))return{status:"error",message:`${r} uses an unsupported URL scheme. Pass a Buffer, a file path or a data: URL.`};const s=await con(o,r,n);return s.status==="ok"?yHt(s.buffer,t,r):s}async function lon(e,t,r,n){const o=e.images??[];if(o.length===0&&e.video===void 0)return{status:"prepared",media:void 0};if(!t){const c=n.length>0?` Use a decision provider that does: ${n.join(", ")}.`:"";return{status:"refused",message:`${r} does not accept images or video.${c}`}}if(o.length>t.maxImages)return{status:"refused",message:`${r} accepts at most ${t.maxImages} images per request; this one has ${o.length}.`};if(e.video!==void 0&&!t.video)return{status:"refused",message:`${r} does not accept video.`};const s=[];for(const[c,l]of o.entries()){const u=await vHt(l,"image",`Image ${c+1}`,t.maxRequestBytes);if(u.status==="error")return{status:"refused",message:u.message};s.push(u.dataUrl)}let i;if(e.video!==void 0){const c=await vHt(e.video,"video","The video",t.maxRequestBytes);if(c.status==="error")return{status:"refused",message:c.message};i=c.dataUrl}const a=s.reduce((c,l)=>c+l.length,i?.length??0);return{status:"prepared",media:{images:s,...i?{video:i}:{},bytes:a}}}var wHt,THt,bHt,EHt,SHt,_Ht,uon=S({"src/lib/utils/decisionMedia.ts"(){"use strict";dn(),Zv(),mP(),wHt=/^https?:\/\//i,THt=/^[a-z][a-z0-9+.-]*:\/\//i,bHt=200,EHt={image:/^data:image\/[a-z0-9.+-]+;base64,/i,video:/^data:video\/[a-z0-9.+-]+;base64,/i},SHt=[26,69,223,163],_Ht={image:"is not a recognised image format",video:"is not a recognised video format (MP4, MOV or WebM)"}}});function kHt(e){const t=Object.values(e);return t.length>0?Math.max(...t):0}function don(e,t){if(!kn(e))return null;switch(e.type){case"noul":case"boolean":{const r=Vc(e.noul)??Vc(e.probability);return r===void 0?null:{type:"boolean",probability:r}}case"choice":{const r=kae(e.probabilities);return typeof e.choice!="string"||!r?null:{type:"choice",choice:e.choice,confidence:Vc(e.confidence)??t??kHt(r),probabilities:r}}case"score":{const r=Vc(e.score),n=AHt(e.legend),o=kae(e.probabilities);return r===void 0||!n||!o?null:{type:"score",score:r,confidence:Vc(e.confidence)??t??kHt(o),legend:n,probabilities:o}}default:return null}}function Sae(e){return e.filter(kn).map(r=>{const n=Array.isArray(r.loc)?r.loc.filter(s=>typeof s=="string"||typeof s=="number").join("."):"",o=typeof r.msg=="string"?r.msg:"invalid";return n?`${n}: ${o}`:o}).slice(0,5).join("; ")||"unspecified field"}function O3(e,t){return(t?e.split(t).join("[redacted]"):e).replace(/\.?\s*Received API Key\s*=[\s\S]*$/,"").replace(/\bsk-[A-Za-z0-9._-]+/g,"[redacted]").replace(/\b[0-9a-f]{32,}\b/gi,"[redacted]").replace(/data:[a-z]+\/[a-z0-9.+-]+;base64,[A-Za-z0-9+/=]+/gi,"[media]").trim()}function pon(e,t){if(t===void 0)return qt(e);const r=[...e],n=i=>(i.codePointAt(0)??0)<=127,o=r.filter(n).join(""),s=r.length-o.length;return qt(o)+Math.ceil(s*t)}var _ae,xHt,kn,Vc,kae,AHt,xae,B1,D3=S({async"src/lib/providers/systemOneDecision.ts"(){"use strict";Ya(),bc(),await Ul(),Fn(),dt(),uon(),z(),Nt(),Xo(),_ae=5e3,xHt=1,kn=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),Vc=e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,kae=e=>{if(!kn(e))return;const t={};for(const[r,n]of Object.entries(e)){const o=Vc(n);if(o===void 0)return;t[r]=o}return t},AHt=e=>{if(!kn(e))return;const t={};for(const[r,n]of Object.entries(e)){if(typeof n!="string")return;t[r]=n}return t},xae=(e,t)=>new Promise((r,n)=>{if(t?.aborted){n(t.reason);return}const o=setTimeout(()=>{t?.removeEventListener("abort",s),r()},e);function s(){clearTimeout(o),n(t?.reason)}t?.addEventListener("abort",s,{once:!0})}),B1=class extends va{proxyFetch;maxRetries;authFailed=!1;constructor(e,t,r){super(e,t,Hm(r)?r:void 0),this.proxyFetch=Pt(),this.maxRetries=xHt}missingConfigMessage(){}encodeQuestion(e){return e.type==="boolean"?{type:"noul",instructions:e.instructions,...e.criteria?{criteria:e.criteria}:{}}:e}readRetryAfterMs(e){}defaultTimeoutMs(e){return this.getDescriptorDecideMs()}reportedConfidence(e){return{}}resolveResponseModel(e,t){return typeof e.model=="string"?e.model:t}diagnosticContext(){return{}}getProviderName(){return this.providerName}getDefaultDecisionModel(){return this.getDefaultModel()}supportsTools(){return!1}getAISDKModel(){throw new it(`${this.vendorDisplayName()} is a decision-only provider; it generates no text, so chat completions are not available. Use \`decide()\` instead, or pick a different provider for \`generate()\` / \`stream()\`.`,this.providerName)}async executeStream(e,t){throw new it(`${this.vendorDisplayName()} is a decision-only provider; streaming is not available. Use \`decide()\`, or pick another provider for \`stream()\`.`,this.providerName)}formatProviderError(e){if(e instanceof it)return e;const t=e instanceof Error?e.message:String(e);return new it(`${this.vendorLabel()} request failed: ${t}`,this.providerName)}async decide(e){const t=this.vendorLabel();if(!this.decisionApiKey())throw this.decisionError({kind:"authentication",message:this.missingKeyMessage(),retryable:!1});const r=this.missingConfigMessage();if(r)throw this.decisionError({kind:"invalid_request",message:r,retryable:!1});if(this.authFailed)throw this.decisionError({kind:"authentication",message:`${t} rejected this API key earlier; not retrying. Fix the key and construct a new provider.`,retryable:!1});const n=Object.entries(e.questions);if(n.length===0)throw this.decisionError({kind:"invalid_request",message:"At least one question is required.",retryable:!1});const o=e.model??this.modelName??this.getDefaultModel();this.assertWithinDecisionLimits(e,o,n.length);const s=Object.fromEntries(n.map(([u,d])=>[u,this.encodeQuestion(d)])),i=await this.prepareMedia(e),a=JSON.stringify(this.buildDecisionBody(e.state,s,o,i));this.assertWithinRequestBytes(a);const c=e.timeoutMs??this.defaultTimeoutMs(n.length)??this.defaultTimeout??_ae;let l;for(let u=0;u<=this.maxRetries;u++){const d=Date.now();try{const p=AbortSignal.timeout(c),h=e.signal?AbortSignal.any([e.signal,p]):p,f=await this.proxyFetch(this.decisionEndpoint(),{method:"POST",headers:this.decisionHeaders(),body:a,signal:h}),g=Date.now()-d,y=this.readRequestId(f.headers),v=Number(f.headers.get("x-envoy-upstream-service-time"))||void 0,T=await f.json().catch(()=>null);if(!f.ok){if(l=this.parseDecisionError(f.status,T,y),l.kind==="authentication"&&(this.authFailed=!0,m.warn(`${t}: credential not accepted \u2014 disabling this provider instance. ${l.message}`,{status:l.status,...this.diagnosticContext(),requestId:y})),!l.retryable||u===this.maxRetries)throw this.decisionError(l);const k=this.readRetryAfterMs(f.headers);if(k!==void 0&&k>c-(Date.now()-d))throw this.decisionError(l);await xae(k??2**u*250+Math.random()*250,e.signal);continue}if(!kn(T)||!kn(T.answers))throw this.decisionError({kind:"server",message:`${t} returned a response without an answers map.`,status:f.status,requestId:y,retryable:!1});const b=this.reportedConfidence(T),_={};for(const[k,A]of Object.entries(T.answers)){const R=don(A,b[k]);R?_[k]=R:m.warn(`${t}: dropped unparseable answer "${k}"`,{requestId:y})}const x=kn(T.usage)?T.usage:{};return{model:this.resolveResponseModel(T,o),provider:this.providerName,answers:_,usage:{inputTokens:Vc(x.input_tokens)??Vc(x.inputTokens)??0,outputTokens:Vc(x.output_tokens)??Vc(x.outputTokens)??0},requestId:y,latencyMs:g,upstreamMs:v,...i?{mediaBytes:i.bytes}:{}}}catch(p){if(p instanceof it)throw p;const h=e.signal?.aborted===!0,f=p instanceof Error&&p.name==="TimeoutError";if(l={kind:h?"network":f?"timeout":"network",message:O3(NE(p instanceof Error?p.message:String(p)),this.decisionApiKey()),retryable:!h},h||u===this.maxRetries)throw this.decisionError(l);await xae(2**u*250+Math.random()*250)}}throw this.decisionError(l??{kind:"network",message:`${t} request failed.`,retryable:!1})}async prepareMedia(e){const t=mr.get(this.providerName)?.decisionLimits,r=await lon(e,t?.media,this.vendorLabel(),VCr({video:e.video!==void 0}));if(r.status==="refused")throw this.decisionError({kind:"invalid_request",message:r.message,retryable:!1});return r.media}assertWithinRequestBytes(e){const t=mr.get(this.providerName)?.decisionLimits?.media?.maxRequestBytes;if(t===void 0)return;const r=Buffer.byteLength(e);if(r>t)throw this.decisionError({kind:"invalid_request",message:`The request is ${r} bytes; ${this.vendorLabel()} accepts at most ${t}. Send fewer or smaller images, or a shorter video.`,retryable:!1})}assertWithinDecisionLimits(e,t,r){const n=mr.get(this.providerName)?.decisionLimits;if(!n)return;const o=this.vendorLabel();if(n.maxQuestions!==void 0&&r>n.maxQuestions)throw this.decisionError({kind:"max_tokens_exceeded",message:`${o} accepts at most ${n.maxQuestions} questions per request; this one has ${r}. Ask fewer, or use a decision provider without this cap.`,retryable:!1});const s=n.models?.[t],i=s?.maxStateTokens??n.maxStateTokens,a=pon(J_(e.state),s?.nonAsciiTokensPerChar??n.nonAsciiTokensPerChar);if(a>i)throw this.decisionError({kind:"max_tokens_exceeded",message:`The state is ~${a} tokens; ${o}'s "${t}" model reads at most ${i}. Shorten the state, or use a decision provider with a larger window.`,retryable:!1})}decisionError(e){const t=new it(e.message,this.providerName);return Object.defineProperty(t,"cause",{value:e,enumerable:!1,writable:!0,configurable:!0}),t}}}}),CHt={};Z(CHt,{TYPESAFE_MAX_REQUEST_TOKENS:()=>L3,TYPESAFE_MAX_STATE_TOKENS:()=>N3,TypeSafeProvider:()=>LHt});function mon(e){if(!kn(e)||!kn(e.providerMetadata))return{};const t=e.providerMetadata.typesafe;if(!kn(t)||!kn(t.confidence))return{};const r={};for(const[n,o]of Object.entries(t.confidence)){const s=Vc(o);s!==void 0&&(r[n]=s)}return r}function hon(e,t,r,n){const o=typeof t.type=="string"?t.type:void 0,s=(o?NHt[o]:void 0)??(e===401||e===403?"authentication":e===429?"rate_limit":e>=500?"server":"invalid_request"),i=typeof t.message=="string"&&t.message.length>0?t.message:o??`AI Gateway request failed with HTTP ${e}`;return{kind:s,message:i,status:e,requestId:r,retryable:n}}function IHt(e,t,r){const n=e===429||e===529||e>=500,o=kn(t)&&kn(t.error)?t.error:void 0;if(o)return hon(e,o,r,n);const s=kn(t)?t.detail:void 0;if(Array.isArray(s))return{kind:"invalid_request",message:`Request failed validation \u2014 ${Sae(s)}`,status:e,requestId:r,retryable:!1};const i=kn(s)&&typeof s.error_type=="string"?s.error_type:void 0,a=i==="max_tokens_exceeded"?"max_tokens_exceeded":e===401||e===403?"authentication":e===429?"rate_limit":e===529?"overloaded":e>=500?"server":"invalid_request",c=a==="max_tokens_exceeded"?`State plus questions exceeded the model's input limit: keep state plus the longest single question under ~${N3} tokens, and state plus all questions under ~${L3}.`:i??`TypeSafe request failed with HTTP ${e}`,l=kn(s)&&typeof s.message=="string"?s.message:c;return{kind:a,message:l,status:e,requestId:r,retryable:n}}var RHt,MHt,PHt,OHt,DHt,N3,L3,NHt,LHt,FHt=S({async"src/lib/providers/typesafe.ts"(){"use strict";z(),Nt(),$o(),await D3(),RHt="https://api.typesafe.ai",MHt="https://ai-gateway.vercel.sh/v4/ai/evaluation-model",PHt="typesafe-ai/jev",OHt="0.0.1",DHt="4",N3=33e3,L3=64e3,NHt={authentication_error:"authentication",customer_verification_required:"authentication",invalid_request_error:"invalid_request",rate_limit_exceeded:"rate_limit",internal_server_error:"server"},LHt=class extends B1{apiKey;baseURL;gatewayURL;transport;constructor(e,t,r,n){super(e,"typesafe",t);const o=n?.apiKey?.trim()||(process.env.TYPESAFE_API_KEY?.trim()??""),s=n?.gatewayApiKey?.trim()||(process.env.AI_GATEWAY_API_KEY?.trim()??""),i=n?.transport??process.env.TYPESAFE_TRANSPORT?.trim();this.transport=i==="gateway"||i==="direct"?i:!o&&s?"gateway":"direct",this.apiKey=this.transport==="gateway"?s:o,this.baseURL=(n?.baseURL??process.env.TYPESAFE_BASE_URL??RHt).replace(/\/+$/,""),this.gatewayURL=(n?.gatewayURL?.trim()||process.env.TYPESAFE_GATEWAY_URL?.trim()||MHt).replace(/\/+$/,""),m.debug("TypeSafe Provider initialized (decide only)",{modelName:this.modelName,transport:this.transport,baseURL:Yt(this.transport==="gateway"?this.gatewayURL:this.baseURL)})}getDefaultModel(){return zs("TYPESAFE_MODEL","jev-latest")}vendorLabel(){return"TypeSafe"}vendorDisplayName(){return"TypeSafe (Jev)"}decisionApiKey(){return this.apiKey}missingKeyMessage(){return this.transport==="gateway"?"The TypeSafe gateway transport requires a Vercel AI Gateway key. Set AI_GATEWAY_API_KEY or pass credentials.typesafe.gatewayApiKey.":"TypeSafe requires an API key. Set TYPESAFE_API_KEY or pass credentials.typesafe.apiKey."}encodeQuestion(e){return this.transport==="gateway"?e:super.encodeQuestion(e)}buildDecisionBody(e,t,r){return this.transport==="gateway"?{state:e,questions:t}:{model:r,state:e,questions:t}}parseDecisionError(e,t,r){return IHt(e,t,r)}reportedConfidence(e){return mon(e)}readRequestId(e){return e.get("x-typesafe-request-id")??void 0}diagnosticContext(){return{transport:this.transport}}decisionEndpoint(){return this.transport==="gateway"?this.gatewayURL:`${this.baseURL}/v1/systemone`}decisionHeaders(){const e={Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"};return this.transport==="gateway"?{...e,"ai-gateway-auth-method":"api-key","ai-gateway-protocol-version":OHt,"ai-model-id":PHt,"ai-evaluation-model-specification-version":DHt}:e}getDecisionTransport(){return this.transport}async listDecisionModels(){if(this.transport==="gateway")throw this.decisionError({kind:"invalid_request",message:"Model listing is a TypeSafe API operation; the gateway transport has no equivalent endpoint.",retryable:!1});const e=await this.proxyFetch(`${this.baseURL}/v1/models`,{headers:{Authorization:`Bearer ${this.apiKey}`},signal:AbortSignal.timeout(this.defaultTimeout??_ae)}),t=await e.json().catch(()=>null);if(!e.ok)throw this.decisionError(IHt(e.status,t,e.headers.get("x-typesafe-request-id")??void 0));return(kn(t)&&Array.isArray(t.models)?t.models:[]).filter(kn).map(n=>({name:typeof n.name=="string"?n.name:"",description:typeof n.description=="string"?n.description:"",releaseDate:typeof n.release_date=="string"?n.release_date:""}))}}}}),$Ht={};Z($Ht,{LayaProvider:()=>UHt});function fon(e,t,r){const n=e===429||e>=500,o=e===401||e===403?"authentication":e===413?"max_tokens_exceeded":e===429?"rate_limit":e===503?"overloaded":e>=500?"server":"invalid_request",s=kn(t)&&kn(t.error)?t.error:void 0;if(s&&typeof s.message=="string"&&s.message.length>0)return{kind:o,message:s.message,status:e,requestId:r,retryable:n};const i=kn(t)?t.detail:void 0;return Array.isArray(i)?{kind:"invalid_request",message:`Request failed validation \u2014 ${Sae(i)}`,status:e,requestId:r,retryable:!1}:typeof i=="string"&&i.length>0?{kind:o,message:i,status:e,requestId:r,retryable:n}:{kind:o,message:`Laya request failed with HTTP ${e}`,status:e,requestId:r,retryable:n}}var UHt,gon=S({async"src/lib/providers/laya.ts"(){"use strict";z(),Nt(),$o(),await D3(),UHt=class extends B1{apiKey;baseURL;constructor(e,t,r,n){super(e,"laya",t),this.apiKey=n?.apiKey?.trim()||(process.env.LAYA_API_KEY?.trim()??""),this.baseURL=(n?.baseURL?.trim()||process.env.LAYA_BASE_URL?.trim()||"").replace(/\/+$/,""),m.debug("Laya Provider initialized (decide only)",{modelName:this.modelName,baseURL:this.baseURL?Yt(this.baseURL):"(not set)"})}getDefaultModel(){return zs("LAYA_MODEL","typed-decisions")}vendorLabel(){return"Laya"}vendorDisplayName(){return"Laya"}decisionApiKey(){return this.apiKey}missingKeyMessage(){return"Laya requires an API key. Set LAYA_API_KEY or pass credentials.laya.apiKey."}missingConfigMessage(){return this.baseURL?void 0:"Laya requires a base URL. Set LAYA_BASE_URL or pass credentials.laya.baseURL."}decisionEndpoint(){return`${this.baseURL}/predict`}decisionHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"}}buildDecisionBody(e,t,r){return r==="auto"?{state:e,questions:t}:{model:r,state:e,questions:t}}parseDecisionError(e,t,r){const n=fon(e,t,r),o=O3(n.message,this.apiKey);return{...n,message:o||`Laya request failed with HTTP ${e}`}}readRequestId(e){return e.get("x-litellm-call-id")??void 0}resolveResponseModel(e,t){const r=e.routing;return kn(r)&&typeof r.model=="string"?r.model:super.resolveResponseModel(e,t)}}}}),BHt={};Z(BHt,{XorProvider:()=>qHt});function yon(e){return e.replace(/\/+$/,"").replace(/\/v1$/i,"")}function von(e){const t="Set XOR_BASE_URL or pass credentials.xor.baseURL to the origin, and give the key through XOR_API_KEY or credentials.xor.apiKey.";try{const r=new URL(e);return r.protocol!=="https:"&&r.protocol!=="http:"?`The XOR base URL must start with https:// or http://. ${t}`:r.username||r.password||r.search||r.hash?`The XOR base URL must not carry credentials, a query string or a fragment. ${t}`:void 0}catch{return`The XOR base URL is not a valid absolute URL. ${t}`}}function won(e,t){return e===401?"authentication":e===413?"max_tokens_exceeded":e===429?"rate_limit":e===503?"overloaded":e>=500?GHt.test(t)?"max_tokens_exceeded":"server":"invalid_request"}function Ton(e){if(!kn(e))return;const{error:t,detail:r}=e;return kn(t)&&typeof t.message=="string"&&t.message.length>0?t.message:typeof t=="string"&&t.length>0?t:Array.isArray(r)?`Request failed validation \u2014 ${Sae(r)}`:typeof r=="string"&&r.length>0?r:void 0}var zHt,GHt,qHt,bon=S({async"src/lib/providers/xor.ts"(){"use strict";z(),Nt(),$o(),await D3(),zHt="/v1/systemone",GHt=/(context|prefill|prompt).{0,40}(length|limit|too long|exceed)|(too long|exceeds?).{0,40}(context|tokens)/i,qHt=class extends B1{apiKey;baseURL;constructor(e,t,r,n){super(e,"xor",t),this.apiKey=n?.apiKey?.trim()||(process.env.XOR_API_KEY?.trim()??""),this.baseURL=yon(n?.baseURL?.trim()||process.env.XOR_BASE_URL?.trim()||""),m.debug("XOR Provider initialized (decide only)",{modelName:this.modelName,baseURL:this.baseURL?Yt(this.baseURL):"(not set)"})}getDefaultModel(){return zs("XOR_MODEL","xor-1.1")}vendorLabel(){return"XOR"}vendorDisplayName(){return"XOR"}decisionApiKey(){return this.apiKey}missingKeyMessage(){return"XOR requires an API key. Set XOR_API_KEY or pass credentials.xor.apiKey."}missingConfigMessage(){return this.baseURL?von(this.baseURL):"XOR requires a base URL. Set XOR_BASE_URL or pass credentials.xor.baseURL."}decisionEndpoint(){return`${this.baseURL}${zHt}`}decisionHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"}}buildDecisionBody(e,t,r,n){return{model:r,state:e,questions:t,...n&&n.images.length>0?{images:n.images}:{},...n?.video?{video:n.video}:{}}}parseDecisionError(e,t,r){const n=`XOR request failed with HTTP ${e}`,o=O3(Ton(t)??n,this.apiKey)||n,s=won(e,o);return{kind:s,message:o,status:e,requestId:r,retryable:s==="rate_limit"||s==="overloaded"||s==="server"}}readRequestId(e){return e.get("x-request-id")??e.get("x-typesafe-request-id")??e.get("x-litellm-call-id")??void 0}}}}),VHt={};Z(VHt,{PerplexityDeciderProvider:()=>QHt});function Eon(e){return e.replace(/\/+$/,"").replace(/\/v1$/i,"")}function jHt(e){const t=`Set PERPLEXITY_DECIDER_BASE_URL or pass credentials.perplexityDecider.baseURL to an origin, or leave both unset to use ${Aae}.`;try{const r=new URL(e);return r.protocol!=="https:"&&r.protocol!=="http:"?`The Perplexity base URL must start with https:// or http://. ${t}`:r.username||r.password||r.search||r.hash?`The Perplexity base URL must not carry credentials, a query string or a fragment. ${t}`:void 0}catch{return`The Perplexity base URL is not a valid absolute URL. ${t}`}}function Son(e){try{return new URL(e).hostname===KHt}catch{return!1}}function _on(e,t){return e===401?"authentication":e===413||e===400&&ZHt.test(t)?"max_tokens_exceeded":e===429?"rate_limit":e===503?"overloaded":e>=500?"server":"invalid_request"}function kon(e){if(!kn(e)||!kn(e.error))return;const{message:t,param:r}=e.error;if(!(typeof t!="string"||t.length===0))return typeof r=="string"&&r!==""&&!t.includes(r)?`${t} (field: ${r})`:t}function xon(e){return e.length>=24&&e.toString("ascii",12,16)==="IHDR"?{width:e.readUInt32BE(16),height:e.readUInt32BE(20)}:void 0}function Aon(e){let t=2;for(;t+4<=e.length;){if(e[t]!==255)return;const r=e[t+1];if(r===255)t+=1;else if(r===1||r>=208&&r<=216)t+=2;else{if(r===217||r===218)return;if(r>=192&&r<=207&&r!==196&&r!==200&&r!==204)return t+9<=e.length?{height:e.readUInt16BE(t+5),width:e.readUInt16BE(t+7)}:void 0;t+=2+e.readUInt16BE(t+2)}}}function Con(e){if(!(e.length<30))switch(e.toString("ascii",12,16)){case"VP8X":return{width:1+e.readUIntLE(24,3),height:1+e.readUIntLE(27,3)};case"VP8L":{const t=e.readUInt32LE(21);return e[20]===47?{width:(t&16383)+1,height:(t>>>14&16383)+1}:void 0}case"VP8 ":return{width:e.readUInt16LE(26)&16383,height:e.readUInt16LE(28)&16383};default:return}}function Ion(e){switch(gx(e)){case"image/png":return xon(e);case"image/jpeg":return Aon(e);case"image/webp":return Con(e);default:return}}function Ron(e,t){const r=/^data:([a-z]+\/[a-z0-9.+-]+);base64,/i.exec(e);if(!r||!YHt.has(r[1].toLowerCase()))return`Image ${t} is not a PNG, JPEG or WebP image, the only formats Perplexity reads.`;const n=Ion(Buffer.from(e.slice(r[0].length),"base64"));return n&&Math.round(n.width/z1)*Math.round(n.height/z1)>Cae?`Image ${t} is ${n.width}x${n.height} pixels; Perplexity reads at most ${Cae} tiles of ${z1}x${z1} pixels per image (1440x1440 and 2048x1024 fit), and a larger one stalls until the request times out. Resize it first.`:void 0}function HHt(e){return typeof e=="number"||typeof e=="boolean"?String(e):e}var Aae,WHt,KHt,JHt,YHt,z1,Cae,XHt,ZHt,QHt,Mon=S({async"src/lib/providers/perplexityDecider.ts"(){"use strict";Zv(),z(),Nt(),$o(),await D3(),Aae="https://api.perplexity.ai",WHt="/v1/decisions",KHt="api.perplexity.ai",JHt="neurolink",YHt=new Set(["image/png","image/jpeg","image/webp"]),z1=32,Cae=2048,XHt=100,ZHt=/exceeds or equals model's maximum context length/i,QHt=class extends B1{apiKey;baseURL;constructor(e,t,r,n){super(e,"perplexity-decider",t),this.apiKey=n?.apiKey?.trim()||(process.env.PERPLEXITY_API_KEY?.trim()??""),this.baseURL=Eon(n?.baseURL?.trim()||process.env.PERPLEXITY_DECIDER_BASE_URL?.trim()||Aae),m.debug("Perplexity decision provider initialized (decide only)",{modelName:this.modelName,baseURL:jHt(this.baseURL)?"(invalid)":Yt(this.baseURL)})}getDefaultModel(){return zs("PERPLEXITY_DECIDER_MODEL","pplx-decider-v1-27b")}vendorLabel(){return"Perplexity"}vendorDisplayName(){return"Perplexity Decisions"}decisionApiKey(){return this.apiKey}missingKeyMessage(){return"Perplexity requires an API key. Set PERPLEXITY_API_KEY or pass credentials.perplexityDecider.apiKey."}missingConfigMessage(){return jHt(this.baseURL)}decisionEndpoint(){return`${this.baseURL}${WHt}`}decisionHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json",...Son(this.baseURL)?{"X-Pplx-Integration":JHt}:{}}}buildDecisionBody(e,t,r,n){const o=n?.images??[];if(o.length===0)return{model:r,state:HHt(e),questions:t};o.forEach((i,a)=>{const c=Ron(i,a+1);if(c)throw this.decisionError({kind:"invalid_request",message:c,retryable:!1})});const s=Array.isArray(e)?e:e===""?[]:[HHt(e)];return{model:r,state:[...s,...o.map(i=>({type:"image_url",image_url:{url:i}}))],questions:t}}parseDecisionError(e,t,r){const n=`Perplexity request failed with HTTP ${e}`,o=O3(kon(t)??n,this.apiKey).replace(/\bpplx-[A-Za-z0-9_-]{30,}/g,"[redacted]").trim()||n,s=_on(e,o);return{kind:s,message:o,status:e,requestId:r,retryable:s==="rate_limit"||s==="overloaded"||s==="server"}}readRequestId(e){return e.get("x-request-id")??void 0}defaultTimeoutMs(e){const t=this.getDescriptorDecideMs();return t===void 0?void 0:t+e*XHt}readRetryAfterMs(e){const t=e.get("retry-after")?.trim();if(!t)return;const r=/^\d+$/.test(t)?Number(t)*1e3:Date.parse(t)-Date.now();return Number.isFinite(r)&&r>0?Math.ceil(r):void 0}}}}),eWt={};Z(eWt,{Agent:()=>qWt,BedrockClient:()=>rWt,BedrockRuntimeClient:()=>oWt,Blob:()=>GWt,Client:()=>jWt,ConverseCommand:()=>sWt,ConverseStreamCommand:()=>iWt,Cron:()=>_Wt,Dispatcher:()=>HWt,File:()=>zWt,FlowProducer:()=>SWt,FormData:()=>BWt,GoogleAuth:()=>pWt,HTTPException:()=>MWt,Headers:()=>UWt,Hippocampus:()=>gWt,HippocampusConfig:()=>yWt,Hono:()=>IWt,ImageFormat:()=>aWt,InvokeEndpointCommand:()=>uWt,InvokeEndpointWithResponseStreamCommand:()=>dWt,InvokeModelCommand:()=>cWt,Job:()=>bWt,ListFoundationModelsCommand:()=>nWt,MockAgent:()=>JWt,Pool:()=>VWt,Queue:()=>wWt,QueueScheduler:()=>EWt,Request:()=>FWt,Response:()=>$Wt,SageMakerRuntimeClient:()=>lWt,TextToSpeechClient:()=>hWt,VertexAI:()=>mWt,Webhook:()=>fWt,Worker:()=>TWt,convertToHtml:()=>CWt,cors:()=>RWt,createClient:()=>vWt,default:()=>tWt,extractRawText:()=>AWt,fetch:()=>LWt,getGlobalDispatcher:()=>KWt,interceptors:()=>YWt,logger:()=>PWt,parseBuffer:()=>kWt,request:()=>XWt,secureHeaders:()=>OWt,selectCover:()=>xWt,setGlobalDispatcher:()=>WWt,streamSSE:()=>DWt,timeout:()=>NWt});var Kg,gs,tWt,rWt,nWt,oWt,sWt,iWt,aWt,cWt,lWt,uWt,dWt,pWt,mWt,hWt,fWt,gWt,yWt,vWt,wWt,TWt,bWt,EWt,SWt,_Wt,kWt,xWt,AWt,CWt,IWt,RWt,MWt,PWt,OWt,DWt,NWt,LWt,FWt,$Wt,UWt,BWt,zWt,GWt,qWt,VWt,jWt,HWt,WWt,KWt,JWt,YWt,XWt,Pon=S({"npm-stub:@google-cloud/text-to-speech"(){Kg={get(e,t){return t==="__esModule"?!0:t==="default"?new Proxy({},{get:Kg.get}):new Proxy(function(...r){return new Proxy({},{get:Kg.get})},{get:Kg.get,apply(r,n,o){return new Proxy({},{get:Kg.get})},construct(r,n){return new Proxy({},{get:Kg.get})}})}},gs=new Proxy({},Kg),tWt=gs,{BedrockClient:rWt,ListFoundationModelsCommand:nWt,BedrockRuntimeClient:oWt,ConverseCommand:sWt,ConverseStreamCommand:iWt,ImageFormat:aWt,InvokeModelCommand:cWt}=gs,{SageMakerRuntimeClient:lWt,InvokeEndpointCommand:uWt,InvokeEndpointWithResponseStreamCommand:dWt}=gs,{GoogleAuth:pWt,VertexAI:mWt,TextToSpeechClient:hWt}=gs,{Webhook:fWt}=gs,{Hippocampus:gWt,HippocampusConfig:yWt}=gs,{createClient:vWt}=gs,{Queue:wWt,Worker:TWt,Job:bWt,QueueScheduler:EWt,FlowProducer:SWt}=gs,{Cron:_Wt}=gs,{parseBuffer:kWt,selectCover:xWt}=gs,{extractRawText:AWt,convertToHtml:CWt}=gs,{Hono:IWt}=gs,{cors:RWt,HTTPException:MWt,logger:PWt,secureHeaders:OWt,streamSSE:DWt,timeout:NWt}=gs,LWt=globalThis.fetch,FWt=globalThis.Request,$Wt=globalThis.Response,UWt=globalThis.Headers,BWt=globalThis.FormData,zWt=globalThis.File,GWt=globalThis.Blob,qWt=gs.Agent,VWt=gs.Pool,jWt=gs.Client,HWt=gs.Dispatcher,WWt=()=>{},KWt=()=>gs,JWt=gs.MockAgent,YWt={redirect:()=>e=>e,retry:()=>e=>e},XWt=async(e,t)=>{const r=await globalThis.fetch(e,t);return{statusCode:r.status,headers:Object.fromEntries(r.headers.entries()),body:{text:()=>r.text(),json:()=>r.json(),arrayBuffer:()=>r.arrayBuffer()}}}}}),F3,ZWt=S({"src/lib/adapters/tts/googleTTSHandler.ts"(){"use strict";_c(),z(),$y(),Eo(),F3=class Qu{client=null;voicesCache=null;static CACHE_TTL_MS=300*1e3;static DEFAULT_MAX_TEXT_LENGTH=5e3;static DEFAULT_API_TIMEOUT_MS=30*1e3;maxTextLength=Qu.DEFAULT_MAX_TEXT_LENGTH;credentialsPath;constructor(t){this.credentialsPath=t??process.env.GOOGLE_APPLICATION_CREDENTIALS}isConfigured(){return this.credentialsPath!==void 0}async getClient(){if(!this.client){const{TextToSpeechClient:t}=await Promise.resolve().then(()=>(Pon(),eWt));this.client=new t({keyFilename:this.credentialsPath})}return this.client}async getVoices(t){if(!this.isConfigured())throw new Et({code:At.PROVIDER_NOT_CONFIGURED,message:"Google Cloud TTS client not initialized. Set GOOGLE_APPLICATION_CREDENTIALS or pass credentials path.",category:"configuration",severity:"high",retriable:!1});const r=await this.getClient(),n=Pe.createSpan("tts","tts.google.listVoices",{"tts.operation":"listVoices","tts.provider":"google"});try{if(this.voicesCache&&Date.now()-this.voicesCache.timestamp<Qu.CACHE_TTL_MS&&!t){const a=Pe.endSpan(n,1);return ot().recordSpan(a),this.voicesCache.voices}const[o]=await r.listVoices(t?{languageCode:t}:{});if(!o.voices||o.voices.length===0){m.warn("Google Cloud TTS returned no voices");const a=Pe.endSpan(n,1);return ot().recordSpan(a),[]}const s=[];for(const a of o.voices??[]){if(!a.name||!Array.isArray(a.languageCodes)||a.languageCodes.length===0){m.warn("Skipping voice with missing required fields",{name:a.name,languageCodesCount:a.languageCodes?.length});continue}const c=a.name,l=a.languageCodes,u=l[0],d=this.detectVoiceType(c),p=a.ssmlGender==="MALE"?"male":a.ssmlGender==="FEMALE"?"female":"neutral";s.push({id:c,name:c,languageCode:u,languageCodes:l,gender:p,type:d,naturalSampleRateHertz:a.naturalSampleRateHertz??void 0})}t||(this.voicesCache={voices:s,timestamp:Date.now()});const i=Pe.endSpan(n,1);return ot().recordSpan(i),s}catch(o){const s=Pe.endSpan(n,2,o instanceof Error?o.message:"Unknown error");ot().recordSpan(s);const i=o instanceof Error?o.message:"Unknown error";return m.error(`Failed to fetch Google TTS voices: ${i}`),[]}}async synthesize(t,r){if(!this.isConfigured())throw new Et({code:At.PROVIDER_NOT_CONFIGURED,message:"Google Cloud TTS client not initialized. Set GOOGLE_APPLICATION_CREDENTIALS or pass credentials path.",category:"configuration",severity:"high",retriable:!1});const n=await this.getClient(),o=r.voice??"en-US-Neural2-C",s=Pe.createSpan("tts","tts.google.synthesize",{"tts.operation":"synthesize","tts.provider":"google","tts.voice":o,"tts.format":r.format??"mp3"}),i=Date.now();try{const a=t.startsWith("<speak>")&&t.endsWith("</speak>");if(t.startsWith("<speak>")&&!t.endsWith("</speak>")||!t.startsWith("<speak>")&&t.endsWith("</speak>"))throw new Et({code:At.INVALID_INPUT,message:"Malformed SSML: missing opening <speak> or closing </speak> tag.",category:"validation",severity:"medium",retriable:!1});const c=this.extractLanguageCode(o),l=this.mapFormat(r.format??"mp3"),u={input:a?{ssml:t}:{text:t},voice:{name:o,languageCode:c},audioConfig:{audioEncoding:l,speakingRate:r.speed??1,pitch:r.pitch??0,volumeGainDb:r.volumeGainDb??0}},[d]=await n.synthesizeSpeech(u,{timeout:Qu.DEFAULT_API_TIMEOUT_MS}),p=d.audioContent;if(!p)throw new Et({code:At.SYNTHESIS_FAILED,message:"Google TTS returned empty audio content",category:"execution",severity:"high",retriable:!0});const h=p instanceof Uint8Array?Buffer.from(p):typeof p=="string"?Buffer.from(p,"base64"):(()=>{throw new Et({code:At.SYNTHESIS_FAILED,message:"Unsupported audioContent type returned by Google TTS",category:"execution",severity:"high",retriable:!0,context:{type:typeof p}})})(),f=Date.now()-i,g=Pe.endSpan(s,1);return ot().recordSpan(g),{buffer:h,format:r.format??"mp3",size:h.length,voice:o,metadata:{latency:f,provider:"google-ai"}}}catch(a){const c=Pe.endSpan(s,2,a instanceof Error?a.message:String(a));if(ot().recordSpan(c),a instanceof Et)throw a;const l=Date.now()-i,u=a instanceof Error?a.message:"Unknown error";throw new Et({code:At.SYNTHESIS_FAILED,message:`Google TTS failed after ${l}ms: ${u}`,category:"execution",severity:"high",retriable:!0,context:{latency:l},originalError:a instanceof Error?a:void 0})}}static STREAMING_VOICE_PATTERN=/^[a-z]{2,3}-[A-Z]{2}-(?:Chirp3-HD|Chirp-HD|Journey)-/;static STREAMING_SAMPLE_RATE_HZ=24e3;static STREAMING_IDLE_TIMEOUT_MS=30*1e3;static mapStreamingFormat(t){switch(t){case"pcm16":return"PCM";case"ogg":case"opus":return"OGG_OPUS";default:return}}static streamedAudio(t){if(t===null||typeof t!="object")return;const r=t.audioContent;if(r instanceof Uint8Array)return r.byteLength>0?Buffer.from(r.buffer,r.byteOffset,r.byteLength):void 0;if(typeof r=="string"&&r.length>0){const n=Buffer.from(r,"base64");return n.length>0?n:void 0}}synthesizeStream(t,r={}){const n=r.voice;if(n===void 0||!Qu.STREAMING_VOICE_PATTERN.test(n))return;const o=r.format??"mp3",s=Qu.mapStreamingFormat(o);if(s===void 0||t.trimStart().startsWith("<speak"))return;const i=this.extractLanguageCode(n),a=Qu.STREAMING_SAMPLE_RATE_HZ,c=this;let l,u=!1,d=!1;const p=(async function*(){const h=await c.getClient();if(u)return;const f=Date.now(),g=h.streamingSynthesize();l=g;let y;const v=()=>{clearTimeout(y),y=setTimeout(()=>{d=!0,g.cancel()},Qu.STREAMING_IDLE_TIMEOUT_MS)};let T=0,b=0;try{g.write({streamingConfig:{voice:{name:n,languageCode:i},streamingAudioConfig:{audioEncoding:s,sampleRateHertz:a,speakingRate:r.speed??1}}}),g.write({input:{text:t}}),g.end(),v();for await(const _ of g){clearTimeout(y);const x=Qu.streamedAudio(_);if(x===void 0){v();continue}b+=x.length,yield{data:x,format:o,index:T++,isFinal:!1,cumulativeSize:b,voice:n,sampleRate:a},v()}m.debug(`[GoogleTTSHandler] Streamed ${b} bytes in ${Date.now()-f}ms`)}catch(_){if(u)return;if(_ instanceof Et)throw _;const x=_ instanceof Error?_.message:"Unknown error";throw new Et({code:At.SYNTHESIS_FAILED,message:d?`Google TTS streaming synthesis stalled for ${Qu.STREAMING_IDLE_TIMEOUT_MS}ms`:`Google TTS streaming synthesis failed: ${x}`,category:d?"network":"execution",severity:"high",retriable:!0,context:{voice:n,audioEncoding:s},originalError:_ instanceof Error?_:void 0})}finally{clearTimeout(y),l=void 0,g.cancel()}})();return n_(p,()=>{u=!0,l?.cancel()})}extractLanguageCode(t){const r=t.split("-");if(r.length>=2)return`${r[0]}-${r[1]}`;throw new Et({code:At.INVALID_INPUT,message:`Invalid Google TTS voiceId format: "${t}". Expected format like "en-US-Neural2-C".`,category:"validation",severity:"medium",retriable:!1,context:{voiceId:t}})}mapFormat(t){switch(t.toLowerCase()){case"mp3":return"MP3";case"wav":return"LINEAR16";case"ogg":case"opus":return"OGG_OPUS";case"pcm16":throw new Et({code:At.INVALID_INPUT,message:"Google Cloud TTS's buffered synthesis does not support pcm16 output. pcm16 is only delivered via native streaming, which requires a Chirp3-HD, Chirp-HD, or Journey voice and plain (non-SSML) text \u2014 check that both conditions hold, or request a different format.",category:"validation",severity:"medium",retriable:!1,context:{format:t}});default:throw new Et({code:At.INVALID_INPUT,message:`Unsupported audio format: ${t}`,category:"validation",severity:"medium",retriable:!1,context:{format:t}})}}detectVoiceType(t){const r=t.toLowerCase().split("-");return r.some(n=>n.startsWith("chirp"))?"chirp":r.includes("neural2")?"neural":r.includes("wavenet")?"wavenet":r.includes("standard")?"standard":"unknown"}}}}),eT,G1,$3=S({"src/lib/voice/RealtimeVoiceAPI.ts"(){"use strict";z(),Rd(),dt(),Ly(),eT=class{static registry=new df("RealtimeProcessor");static sessions=new Map;static registerHandler(e,t){const r=e&&e.toLowerCase();this.registry.register(e,t),m.debug(`[RealtimeProcessor] Registered Realtime handler for provider: ${r}`)}static getHandler(e){return this.registry.get(e)}static supports(e){return this.registry.supports(e)}static getProviders(){return this.registry.list()}static async connect(e,t,r){const n=this.getHandler(e);if(!n)throw er.providerNotSupported(e,this.registry.list());if(!n.isConfigured())throw er.providerNotConfigured(e);if(n.isConnected())throw er.sessionAlreadyActive(e);const o={...zR,...t};r&&n.on(r);try{m.debug(`[RealtimeProcessor] Connecting to provider: ${e}`);const s=await n.connect(o);return this.sessions.set(e.toLowerCase(),s),m.info(`[RealtimeProcessor] Connected to ${e} session: ${s.id}`),s}catch(s){if(r&&n.off(),s instanceof er)throw s;const i=s instanceof Error?s.message:String(s||"Unknown error");throw er.connectionFailed(i,e,s instanceof Error?s:void 0)}}static async disconnect(e){const t=this.getHandler(e);if(!t)throw er.providerNotSupported(e,this.registry.list());if(!t.isConnected()){m.warn(`[RealtimeProcessor] No active session for provider: ${e}`);return}try{await t.disconnect(),this.sessions.delete(e.toLowerCase()),t.off(),m.info(`[RealtimeProcessor] Disconnected from ${e}`)}catch(r){if(r instanceof er)throw r;const n=r instanceof Error?r.message:String(r||"Unknown error");throw er.protocolError(`Disconnect failed: ${n}`,e,r instanceof Error?r:void 0)}}static async sendAudio(e,t){const r=this.getHandler(e);if(!r)throw er.providerNotSupported(e,this.registry.list());if(!r.isConnected())throw er.sessionNotActive(e);try{await r.sendAudio(t)}catch(n){if(n instanceof er)throw n;const o=n instanceof Error?n.message:String(n||"Unknown error");throw er.audioStreamError(o,e)}}static async sendText(e,t){const r=this.getHandler(e);if(!r)throw er.providerNotSupported(e,this.registry.list());if(!r.isConnected())throw er.sessionNotActive(e);if(!r.sendText)throw new er({code:Bs.PROTOCOL_ERROR,message:`Provider "${e}" does not support text input`,category:"validation",severity:"medium",context:{provider:e}});try{await r.sendText(t)}catch(n){throw n instanceof er?n:new er({code:Bs.PROTOCOL_ERROR,message:`sendText failed: ${n instanceof Error?n.message:String(n)}`,category:"network",severity:"medium",retriable:!0,context:{provider:e},originalError:n instanceof Error?n:void 0})}}static async triggerResponse(e){const t=this.getHandler(e);if(!t)throw er.providerNotSupported(e,this.registry.list());if(!t.isConnected())throw er.sessionNotActive(e);if(t.triggerResponse)try{await t.triggerResponse()}catch(r){throw r instanceof er?r:new er({code:Bs.PROTOCOL_ERROR,message:`triggerResponse failed: ${r instanceof Error?r.message:String(r)}`,category:"network",severity:"medium",retriable:!0,context:{provider:e},originalError:r instanceof Error?r:void 0})}}static async cancelResponse(e){const t=this.getHandler(e);if(!t)throw er.providerNotSupported(e,this.registry.list());if(t.isConnected()&&t.cancelResponse)try{await t.cancelResponse()}catch(r){throw r instanceof er?r:new er({code:Bs.PROTOCOL_ERROR,message:`cancelResponse failed: ${r instanceof Error?r.message:String(r)}`,category:"network",severity:"medium",retriable:!0,context:{provider:e},originalError:r instanceof Error?r:void 0})}}static getSession(e){return this.getHandler(e)?.getSession()??null}static isConnected(e){return this.getHandler(e)?.isConnected()??!1}static getSupportedFormats(e){return this.getHandler(e)?.getSupportedFormats()??[]}static clearHandlers(){for(const[e]of this.sessions){const t=this.registry.get(e);t?.isConnected()&&t.disconnect().catch(()=>{})}this.sessions.clear(),this.registry.clear(),m.debug("[RealtimeProcessor] Cleared all handlers and sessions")}},G1=class{session=null;eventHandlers=null;state="disconnected";isConnected(){return this.state==="connected"}getSession(){return this.session}on(e){this.eventHandlers=e}off(){this.eventHandlers=null}emitStateChange(e){this.state=e,this.session&&(this.session.state=e,this.session.lastActivityAt=new Date),this.eventHandlers?.onStateChange?.(e)}emitAudio(e){this.eventHandlers?.onAudio?.(e)}emitTranscript(e,t){this.eventHandlers?.onTranscript?.(e,t)}emitText(e,t){this.eventHandlers?.onText?.(e,t)}async emitFunctionCall(e,t){if(this.eventHandlers?.onFunctionCall)return this.eventHandlers.onFunctionCall(e,t)}emitError(e){this.eventHandlers?.onError?.(e)}emitTurnStart(){this.eventHandlers?.onTurnStart?.()}emitTurnEnd(){this.eventHandlers?.onTurnEnd?.()}createSession(e,t){return{id:e,state:"connected",provider:this.name,model:t.model,createdAt:new Date,lastActivityAt:new Date,config:t}}}}});function QWt(e){if(e.length<12)return null;if(e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===65&&e[10]===86&&e[11]===69)return"wav";if(e[0]===73&&e[1]===68&&e[2]===51||e[0]===255&&(e[1]&224)===224)return"mp3";if(e[0]===79&&e[1]===103&&e[2]===103&&e[3]===83){const t=e.indexOf("OpusHead");return t!==-1&&t<200?"opus":"ogg"}return null}function Oon(e){return EE[e]?.mimeType??"application/octet-stream"}function Don(e){return EE[e]?.extension??".bin"}function Non(e,t,r){const n=t??QWt(e);if(n)try{switch(n){case"wav":return Lon(e);case"mp3":return Fon(e);case"ogg":case"opus":return $on(e);default:return r?e.length/(r*2):void 0}}catch(o){m.debug(`[audio-utils] Failed to calculate duration: ${o instanceof Error?o.message:String(o)}`);return}}function Lon(e){if(e.length<44)return;let t=12;for(;t<e.length-8;){const r=e.toString("ascii",t,t+4),n=e.readUInt32LE(t+4);if(r==="fmt "){const o=e.readUInt16LE(t+10),s=e.readUInt32LE(t+12),i=e.readUInt16LE(t+22);let a=t+8+n+n%2;for(;a<e.length-8;){const c=e.toString("ascii",a,a+4),l=e.readUInt32LE(a+4);if(c==="data"){const u=i/8*o;return l/u/s}a+=8+l+l%2}}t+=8+n+n%2}}function Fon(e){let t=0;for(e[0]===73&&e[1]===68&&e[2]===51&&(t=10+((e[6]&127)<<21|(e[7]&127)<<14|(e[8]&127)<<7|e[9]&127));t<e.length-4;){if(e[t]===255&&(e[t+1]&224)===224){const r=e[t+1]>>3&3,n=e[t+1]>>1&3,o=e[t+2]>>4&15,s=e[t+2]>>2&3,a={3:[44100,48e3,32e3],2:[22050,24e3,16e3],0:[11025,12e3,8e3]}[r]?.[s],l=[0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0][o];if(a&&l)return(e.length-t)*8/(l*1e3);break}t++}return e.length*8/128e3}function $on(e){return e.length*8/64e3}async function Uon(e,t,r,n={}){if(t===r)return e;throw m.warn(`[audio-utils] Audio format conversion from ${t} to ${r} is not implemented.`),new Error(`Audio format conversion from ${t} to ${r} is not implemented. Convert with ffmpeg before passing to NeuroLink.`)}function Bon(e,t=16e3,r=16){const n=r/8,o=Buffer.alloc(e.length*n);for(let s=0;s<e.length;s++){const i=Math.max(-1,Math.min(1,e[s])),a=s*n;switch(r){case 8:o.writeUInt8(Math.round((i+1)*127.5),a);break;case 16:o.writeInt16LE(Math.round(i*32767),a);break;case 24:{const c=Math.round(i*8388607);o.writeUInt8(c&255,a),o.writeUInt8(c>>8&255,a+1),o.writeUInt8(c>>16&255,a+2);break}case 32:o.writeInt32LE(Math.round(i*2147483647),a);break}}return o}function zon(e,t=16){const r=t/8,n=Math.floor(e.length/r),o=[];for(let s=0;s<n;s++){const i=s*r;switch(t){case 8:o.push(e.readUInt8(i)/127.5-1);break;case 16:o.push(e.readInt16LE(i)/32767);break;case 24:{const a=e.readUInt8(i)|e.readUInt8(i+1)<<8|e.readUInt8(i+2)<<16;o.push((a>8388607?a-16777216:a)/8388607);break}case 32:o.push(e.readInt32LE(i)/2147483647);break}}return o}function Gon(e,t,r){if(t<=0||r<=0||t===r)return e;const n=t/r,o=Math.round(e.length/n),s=[];for(let i=0;i<o;i++){const a=i*n,c=Math.floor(a),l=Math.min(c+1,e.length-1),u=a-c,d=e[c]*(1-u)+e[l]*u;s.push(d)}return s}function qon(e,t=.95){if(e.length===0)return e;let r=0;for(const o of e)r=Math.max(r,Math.abs(o));if(r===0)return e;const n=t/r;return e.map(o=>o*n)}function eKt(e,t=16e3,r=1,n=16){const o=Buffer.alloc(44),s=t*r*(n/8),i=r*(n/8);return o.write("RIFF",0),o.writeUInt32LE(36+e,4),o.write("WAVE",8),o.write("fmt ",12),o.writeUInt32LE(16,16),o.writeUInt16LE(1,20),o.writeUInt16LE(r,22),o.writeUInt32LE(t,24),o.writeUInt32LE(s,28),o.writeUInt16LE(i,32),o.writeUInt16LE(n,34),o.write("data",36),o.writeUInt32LE(e,40),o}function Von(e,t=16e3,r=1,n=16){const o=eKt(e.length,t,r,n);return Buffer.concat([o,e])}function jon(e,t,r=16e3,n=2){if(t<=0||r<=0||n<=0)return[e];const o=r*n/1e3,s=Math.round(t*o);if(s<=0)return[e];const i=[];for(let a=0;a<e.length;a+=s){const c=Math.min(a+s,e.length);i.push(e.subarray(a,c))}return i}var tKt,rKt,Hon=S({"src/lib/voice/audio-utils.ts"(){"use strict";dt(),z(),tKt={wav:Buffer.from([82,73,70,70]),mp3:{id3:Buffer.from([73,68,51]),frameSync:Buffer.from([255,224])},ogg:Buffer.from([79,103,103,83])},rKt={wav:"audio/wav",mp3:"audio/mpeg",ogg:"audio/ogg",opus:"audio/opus"}}});function Won(e){return{[Symbol.asyncIterator](){const t=[];let r=null,n=null,o=!1,s=null;const i=u=>{r?(r({value:u,done:!1}),r=null,n=null):t.push(u)},a=()=>{o=!0,r&&(r({value:void 0,done:!0}),r=null,n=null)},c=u=>{s=u,n&&(n(u),r=null,n=null)};e.on("chunk",i),e.on("end",a),e.on("error",c);const l=()=>{e.off("chunk",i),e.off("end",a),e.off("error",c)};return{async next(){if(s)throw s;if(t.length>0){const u=t.shift();if(u!==void 0)return{value:u,done:!1}}return o?{value:void 0,done:!0}:new Promise((u,d)=>{r=u,n=d})},async return(){return l(),o=!0,{value:void 0,done:!0}}}}}}async function Kon(e,t={}){const r=new tT(t);return(async()=>{try{for await(const n of e)r.write(n)||await new Promise(s=>r.once("drain",s));r.end()}catch(n){r.emit("error",n instanceof Error?n:new Error(String(n)))}})(),r}var Iae,tT,nKt,oKt,Jon=S({"src/lib/voice/stream-handler.ts"(){"use strict";Dn(),z(),Iae={chunkDurationMs:100,sampleRate:16e3,bytesPerSample:2,format:"wav",highWaterMark:64*1024,bufferTimeoutMs:5e3},tT=class extends Yr{config;chunkSize;buffer;chunkIndex;timestampMs;isPaused;isEnded;pendingData;bufferTimeout;constructor(e={}){if(super(),this.config={...Iae,...e},this.config.sampleRate<=0)throw new Error("Invalid stream configuration: sampleRate must be positive");if(this.config.bytesPerSample<=0)throw new Error("Invalid stream configuration: bytesPerSample must be positive");const t=this.config.sampleRate*this.config.bytesPerSample/1e3;if(this.chunkSize=Math.round(this.config.chunkDurationMs*t),this.chunkSize<=0)throw new Error("Invalid stream configuration: chunkSize must be positive (check chunkDurationMs, sampleRate, bytesPerSample)");this.buffer=Buffer.alloc(0),this.chunkIndex=0,this.timestampMs=0,this.isPaused=!1,this.isEnded=!1,this.pendingData=[],this.bufferTimeout=null}write(e){if(this.isEnded)throw new Error("Cannot write to ended stream");return this.buffer.length+e.length>this.config.highWaterMark?(this.isPaused||(this.isPaused=!0,this.emit("pause")),this.pendingData.push(e),!1):(this.processData(e),!0)}processData(e){for(this.buffer=Buffer.concat([this.buffer,e]),this.resetBufferTimeout();this.buffer.length>=this.chunkSize;){const t=this.buffer.subarray(0,this.chunkSize);this.buffer=this.buffer.subarray(this.chunkSize);const r={data:t,index:this.chunkIndex++,isFinal:!1,format:this.config.format,sampleRate:this.config.sampleRate,timestampMs:this.timestampMs,durationMs:this.config.chunkDurationMs};this.timestampMs+=this.config.chunkDurationMs,this.emit("chunk",r)}if(this.isPaused&&this.buffer.length<this.config.highWaterMark/2)for(this.isPaused=!1,this.emit("resume"),this.emit("drain");this.pendingData.length>0&&!this.isPaused;){const t=this.pendingData.shift();if(t===void 0||!this.write(t))break}}end(){if(!this.isEnded){this.isEnded=!0,this.clearBufferTimeout();for(const e of this.pendingData)this.buffer=Buffer.concat([this.buffer,e]);if(this.pendingData=[],this.buffer.length>0){const e=this.buffer.length/this.config.bytesPerSample/this.config.sampleRate*1e3,t={data:this.buffer,index:this.chunkIndex++,isFinal:!0,format:this.config.format,sampleRate:this.config.sampleRate,timestampMs:this.timestampMs,durationMs:e};this.emit("chunk",t)}else{const e={data:Buffer.alloc(0),index:this.chunkIndex,isFinal:!0,format:this.config.format,sampleRate:this.config.sampleRate,timestampMs:this.timestampMs,durationMs:0};this.emit("chunk",e)}this.emit("end"),this.cleanup()}}resetBufferTimeout(){this.clearBufferTimeout(),this.bufferTimeout=setTimeout(()=>{this.buffer.length>0&&!this.isEnded&&(m.warn(`[ChunkedAudioStream] Buffer timeout, forcing flush of ${this.buffer.length} bytes`),this.end())},this.config.bufferTimeoutMs)}clearBufferTimeout(){this.bufferTimeout&&(clearTimeout(this.bufferTimeout),this.bufferTimeout=null)}cleanup(){this.clearBufferTimeout(),this.buffer=Buffer.alloc(0),this.pendingData=[]}getStats(){return{chunksEmitted:this.chunkIndex,bufferedBytes:this.buffer.length,pendingChunks:this.pendingData.length,totalDurationMs:this.timestampMs,isPaused:this.isPaused,isEnded:this.isEnded}}},nKt=class extends Yr{streams;config;constructor(e={}){super(),this.streams=new Map,this.config={...Iae,...e}}addStream(e){if(this.streams.has(e))throw new Error(`Stream ${e} already exists`);const t=new tT(this.config);return t.on("chunk",r=>{this.emit("chunk",{id:e,chunk:r})}),t.on("end",()=>{this.emit("streamEnd",e),this.streams.delete(e),this.streams.size===0&&this.emit("end")}),t.on("error",r=>{this.emit("error",{id:e,error:r})}),this.streams.set(e,t),t}removeStream(e){const t=this.streams.get(e);t&&(t.end(),this.streams.delete(e))}write(e,t){const r=this.streams.get(e);if(!r)throw new Error(`Stream ${e} not found`);return r.write(t)}endAll(){for(const e of this.streams.values())e.end()}get activeStreams(){return this.streams.size}},oKt=class extends Yr{consumers;input;constructor(e={}){super(),this.consumers=new Map,this.input=new tT(e),this.input.on("chunk",t=>{for(const[r,n]of this.consumers)try{n(t)}catch(o){this.emit("error",{consumerId:r,error:o instanceof Error?o:new Error(String(o))})}}),this.input.on("end",()=>{this.emit("end")}),this.input.on("error",t=>{this.emit("error",{error:t})})}write(e){return this.input.write(e)}end(){this.input.end()}addConsumer(e,t){if(this.consumers.has(e))throw new Error(`Consumer ${e} already exists`);this.consumers.set(e,t)}removeConsumer(e){this.consumers.delete(e)}get consumerCount(){return this.consumers.size}}}}),rT,sKt=S({"src/lib/voice/providers/AzureTTS.ts"(){"use strict";z(),_c(),rT=class zTr{apiKey;region;voicesCache=null;static CACHE_TTL_MS=1800*1e3;maxTextLength=1e4;constructor(t,r){const n=(t??process.env.AZURE_SPEECH_KEY??"").trim();this.apiKey=n.length>0?n:null;const o=(r??process.env.AZURE_SPEECH_REGION??"").trim();this.region=o.length>0?o:"eastus"}isConfigured(){return this.apiKey!==null&&this.region.length>0}async getVoices(t){if(!this.apiKey)throw new Et({code:At.PROVIDER_NOT_CONFIGURED,message:"Azure Speech key not configured",category:"configuration",severity:"high",retriable:!1});if(this.voicesCache&&Date.now()-this.voicesCache.timestamp<zTr.CACHE_TTL_MS&&!t)return this.voicesCache.voices;try{const r=new AbortController,n=setTimeout(()=>r.abort(),3e4);let o;try{o=await fetch(`https://${this.region}.tts.speech.microsoft.com/cognitiveservices/voices/list`,{method:"GET",headers:{"Ocp-Apim-Subscription-Key":this.apiKey},signal:r.signal})}catch(a){throw a instanceof Error&&a.name==="AbortError"?new Et({code:At.SYNTHESIS_FAILED,message:"Azure TTS voices request timed out after 30 seconds",category:"network",severity:"medium",retriable:!0,originalError:a}):a}finally{clearTimeout(n)}if(!o.ok)throw new Error(`HTTP ${o.status}`);let i=(await o.json()).map(a=>({id:a.ShortName,name:a.DisplayName,languageCode:a.Locale,languageCodes:[a.Locale],gender:this.mapGender(a.Gender),type:a.VoiceType.toLowerCase().includes("neural")?"neural":"standard",description:a.LocaleName}));return t&&(i=i.filter(a=>a.languageCode.toLowerCase().startsWith(t.toLowerCase())||a.languageCode.toLowerCase()===t.toLowerCase())),t||(this.voicesCache={voices:i,timestamp:Date.now()}),i}catch(r){if(r instanceof Et)throw r;const n=r instanceof Error?r.message:String(r||"Unknown error");throw m.error(`[AzureTTSHandler] Failed to get voices: ${n}`),new Et({code:At.SYNTHESIS_FAILED,message:`Failed to get voices: ${n}`,category:"network",severity:"medium",retriable:!0,originalError:r instanceof Error?r:void 0})}}async synthesize(t,r={}){if(!this.apiKey)throw new Et({code:At.PROVIDER_NOT_CONFIGURED,message:"Azure Speech key not configured",category:"configuration",severity:"high",retriable:!1});const n=Date.now(),o=r;try{const s=r.voice??"en-US-JennyNeural",i=o.outputFormat??this.mapFormat(r.format??"mp3"),a=this.buildSSML(t,s,r),c=new AbortController,l=setTimeout(()=>c.abort(),3e4);let u;try{u=await fetch(`https://${this.region}.tts.speech.microsoft.com/cognitiveservices/v1`,{method:"POST",headers:{"Ocp-Apim-Subscription-Key":this.apiKey,"Content-Type":"application/ssml+xml","X-Microsoft-OutputFormat":i},body:a,signal:c.signal})}catch(g){throw g instanceof Error&&g.name==="AbortError"?new Et({code:At.SYNTHESIS_FAILED,message:"Azure TTS request timed out after 30 seconds",category:"network",severity:"high",retriable:!0,originalError:g}):g}finally{clearTimeout(l)}if(!u.ok){const g=await u.text();throw new Error(`HTTP ${u.status}: ${g}`)}const d=Date.now()-n,p=await u.arrayBuffer(),h=Buffer.from(p),f={buffer:h,format:this.effectiveFormat(i),size:h.length,voice:s,sampleRate:this.getSampleRate(i),metadata:{latency:d,provider:"azure-tts",requestedFormat:r.format,outputFormat:i,region:this.region}};return m.info(`[AzureTTSHandler] Synthesized ${h.length} bytes in ${d}ms`),f}catch(s){if(s instanceof Et)throw s;const i=s instanceof Error?s.message:String(s||"Unknown error");throw m.error(`[AzureTTSHandler] Synthesis failed: ${i}`),new Et({code:At.SYNTHESIS_FAILED,message:`Synthesis failed: ${i}`,category:"execution",severity:"high",retriable:!0,context:{textLength:t.length},originalError:s instanceof Error?s:void 0})}}buildSSML(t,r,n){const o=n;if(o.ssmlTemplate)return o.ssmlTemplate.replace("{text}",this.escapeXml(t)).replace("{voice}",this.escapeXml(r));if(o.allowRawSSML&&t.trim().startsWith("<speak"))return t;const s=n.speed?`${Math.round((n.speed-1)*100)}%`:"0%",i=n.pitch??0,a=i>=0?`+${Math.round(i)}st`:`${Math.round(i)}st`;return`<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="${this.escapeXml(this.extractLanguage(r))}">
|
|
2157
|
+
${r}`:r}function oon(e){return typeof e=="string"?e:Array.isArray(e)?e.map(t=>typeof t=="string"?t:"").join(""):""}function yae(e){const t=e?.apiKey?.trim()||e?.apiToken?.trim(),r=e?.baseURL||e?.baseUrl;return{apiToken:t,baseUrl:r}}var vae,pHt,son=S({async"src/lib/providers/replicate.ts"(){"use strict";Ya(),af(),m3(),f3(),wa(),await Ul(),z(),et(),$o(),vae=()=>zs("REPLICATE_MODEL","meta/meta-llama-3-70b-instruct"),pHt=class extends va{apiToken;baseURL;constructor(e,t,r,n){const o=Hm(t)?t:void 0;super(e,"replicate",o);const{apiToken:s,baseUrl:i}=yae(n);this.apiToken=s&&s.length>0?s:ua(MCr()),this.baseURL=i,m.debug("Replicate Provider initialized",{modelName:this.modelName,baseURL:this.baseURL})}getProviderName(){return this.providerName}getDefaultModel(){return vae()}supportsTools(){return!1}getAISDKModel(){throw new Error("Replicate routes through the predictions API, not the AI SDK chat models. Streaming uses the predict-then-stream path inside executeStream.")}async generate(e,t){const r=typeof e=="string"?{prompt:e}:e,n=bd(r,this.modelName);if(n==="video"||n==="avatar"||n==="music"||n==="image")return super.generate(r,t);if(r.output?.format==="json"||r.output?.format==="structured"||t!=null)throw new Oe({code:He.PROVIDER_NOT_AVAILABLE,message:"Replicate models do not support structured-output / JSON schema. Remove output.format or _analysisSchema, or use a provider that implements the OpenAI chat-completions contract (e.g. openai, anthropic).",category:"validation",severity:"medium",retriable:!1});const o=r.prompt??r.input?.text??"",s=Date.now(),i=await this.executeStream({input:{text:o},systemPrompt:r.systemPrompt,maxTokens:r.maxTokens,temperature:r.temperature,abortSignal:r.abortSignal,timeout:r.timeout});let a="";for await(const l of i.stream)"content"in l&&typeof l.content=="string"&&(a+=l.content);const c={content:a,provider:this.providerName,model:this.modelName,usage:{input:0,output:0,total:0}};return m.info(`[ReplicateProvider] generate() complete in ${Date.now()-s}ms \u2014 ${a.length} chars`),c}async executeStream(e,t){const r=Date.now(),n=e.credentials?.replicate,o=yae(n),s=o.apiToken||this.apiToken,i=o.baseUrl||this.baseURL,a=Vm({apiToken:s,baseUrl:i});if(!a)throw new Oe({code:He.MISSING_CONFIGURATION,message:"Replicate auth could not be resolved (REPLICATE_API_TOKEN missing).",category:"configuration",severity:"high",retriable:!1});const c=non(e);if(!c.trim())throw new Oe({code:He.INVALID_PARAMETERS,message:"Replicate predictions require a prompt (input.text or prompt)",category:"validation",severity:"medium",retriable:!1});const l={prompt:c,...e.maxTokens!==void 0&&{max_new_tokens:e.maxTokens},temperature:e.temperature,top_p:1};let u;try{u=await L1(a,{model:this.modelName,input:l},{abortSignal:e.abortSignal})}catch(h){throw this.handleProviderError(h)}const d=oon(u.output);if(!d)throw new Error(`Replicate prediction ${u.id} returned empty output`);const p={async*[Symbol.asyncIterator](){yield{content:d}}};return m.info(`[ReplicateProvider] Generated ${d.length} chars in ${Date.now()-r}ms \u2014 model ${this.modelName} (prediction ${u.id})`),{stream:p,provider:this.providerName,model:this.modelName,finishReason:"stop",metadata:{startTime:r,streamId:`replicate-${u.id}`}}}async executeImageGeneration(e){const t=Date.now(),r=e.credentials?.replicate,n=yae(r),o=n.apiToken||this.apiToken,s=n.baseUrl||this.baseURL,i=Vm({apiToken:o,baseUrl:s});if(!i)throw new Oe({code:He.MISSING_CONFIGURATION,message:"Replicate auth could not be resolved (REPLICATE_API_TOKEN missing).",category:"configuration",severity:"high",retriable:!1});const a=e.prompt??e.input?.text??"";if(!a.trim())throw new Oe({code:He.INVALID_PARAMETERS,message:"Replicate image-gen requires a prompt",category:"validation",severity:"medium",retriable:!1});const c=e,l={prompt:a,output_format:"png"};c.aspectRatio&&(l.aspect_ratio=c.aspectRatio),c.negativePrompt&&(l.negative_prompt=c.negativePrompt),c.seed!==void 0&&(l.seed=c.seed);let u;try{u=await L1(i,{model:this.modelName,input:l},{abortSignal:e.abortSignal})}catch(h){throw this.handleProviderError(h)}let d;try{d=await h3(u,vm)}catch(h){throw this.handleProviderError(h)}const p=d.toString("base64");return m.info(`[ReplicateProvider] Generated image (${d.length} bytes) in ${Date.now()-t}ms \u2014 model ${this.modelName}`),{content:a,provider:this.providerName,model:this.modelName,usage:{input:0,output:0,total:0},imageOutput:{base64:p}}}formatProviderError(e){const t=e instanceof Error?e.message:typeof e=="string"?e:"Unknown error",r=e instanceof Error?e:void 0;return t.includes("401")||t.toLowerCase().includes("unauthorized")||t.toLowerCase().includes("invalid token")?new Oe({code:He.PROVIDER_AUTH_FAILED,message:"Invalid Replicate API token. Get one at https://replicate.com/account/api-tokens",category:"configuration",severity:"high",retriable:!1,context:{provider:"replicate"},originalError:r}):t.includes("402")||t.toLowerCase().includes("insufficient credit")?new Oe({code:He.PROVIDER_QUOTA_EXCEEDED,message:"Replicate insufficient credit. Top up at https://replicate.com/account/billing \u2014 most image/music models require a paid balance.",category:"resource",severity:"high",retriable:!1,context:{provider:"replicate"},originalError:r}):t.includes("429")||t.toLowerCase().includes("rate limit")?new Oe({code:He.PROVIDER_QUOTA_EXCEEDED,message:"Replicate rate limit exceeded. Back off and retry.",category:"resource",severity:"high",retriable:!0,context:{provider:"replicate"},originalError:r}):t.toLowerCase().includes("not found")||t.includes("404")?new Oe({code:He.PROVIDER_NOT_AVAILABLE,message:`Replicate model '${this.modelName}' not found. Use owner/name or owner/name:version format. Browse https://replicate.com/explore`,category:"validation",severity:"medium",retriable:!1,context:{provider:"replicate",model:this.modelName},originalError:r}):new Oe({code:He.PROVIDER_NOT_AVAILABLE,message:`Replicate error: ${t}`,category:"execution",severity:"high",retriable:!1,context:{provider:"replicate"},originalError:r})}async validateConfiguration(){return typeof this.apiToken=="string"&&this.apiToken.trim().length>0}getConfiguration(){return{provider:this.providerName,model:this.modelName,defaultModel:vae(),baseURL:this.baseURL}}}}}),mHt={};Z(mHt,{RecraftProvider:()=>bae,default:()=>gHt});var hHt,wae,fHt,Tae,bae,gHt,ion=S({async"src/lib/providers/recraft.ts"(){"use strict";Ya(),await Ul(),Fn(),dt(),z(),$o(),wa(),Tm(),Zv(),hHt="https://external.api.recraft.ai/v1",wae=12e4,fHt=()=>ua(NCr()),Tae=()=>zs("RECRAFT_MODEL","recraftv3"),bae=class extends va{apiKey;baseURL;proxyFetch;constructor(e,t,r,n){const o=Hm(t)?t:void 0;super(e,"recraft",o);const s=n?.apiKey?.trim();this.apiKey=s&&s.length>0?s:fHt(),this.baseURL=n?.baseURL??process.env.RECRAFT_BASE_URL??hHt,this.proxyFetch=Pt(),m.debug("Recraft Provider initialized (image-gen only)",{modelName:this.modelName,baseURL:this.baseURL})}getProviderName(){return this.providerName}getDefaultModel(){return Tae()}supportsTools(){return!1}getAISDKModel(){throw new Error("Recraft is an image-generation-only provider; chat completions are not available.")}async executeStream(e,t){throw new Error("Recraft is an image-generation-only provider; streaming chat is not available.")}formatProviderError(e){const t=e instanceof Error?e.message:typeof e=="string"?e:"Unknown error";return t.includes("401")||t.toLowerCase().includes("unauthorized")?new Dr("Invalid Recraft API key. Get one at https://www.recraft.ai/api","recraft"):t.includes("429")||t.toLowerCase().includes("rate limit")?new Us("Recraft rate limit exceeded. Back off and retry.","recraft"):t.includes("404")||t.includes("model_not_found")?new No(`Recraft model '${this.modelName}' not found. Use recraftv3, recraftv3-svg, or recraftv2.`,"recraft"):new it(`Recraft error: ${t}`,"recraft")}async executeImageGeneration(e){const t=Date.now(),r=e.credentials?.recraft,n=r?.apiKey?.trim()||this.apiKey,o=r?.baseURL||this.baseURL,s=e.prompt??e.input?.text??"";if(!s.trim())throw new Error("Recraft image generation requires a prompt (input.text or prompt)");const i=e,a={model:e.model??this.modelName,prompt:s,n:1,response_format:"b64_json"};i.negativePrompt&&(a.negative_prompt=i.negativePrompt),i.style&&(a.style=i.style),i.styleId&&(a.style_id=i.styleId),i.size&&(a.size=i.size);const c=new AbortController,l=setTimeout(()=>c.abort(),wae);let u;try{u=await this.proxyFetch(`${o}/images/generations`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify(a),signal:c.signal})}catch(g){throw g instanceof Error&&g.name==="AbortError"?this.formatProviderError(new Error(`Recraft image-gen request timed out after ${wae/1e3}s`)):this.formatProviderError(g)}finally{clearTimeout(l)}if(!u.ok){const g=await u.text();throw this.formatProviderError(new Error(`Recraft image-gen failed: ${u.status} \u2014 ${g}`))}const p=(await u.json()).data?.[0];if(!p)throw new Error("Recraft returned no image data");let h;if(p.b64_json)h=p.b64_json;else if(p.url){await wm(p.url);const g=new AbortController,y=setTimeout(()=>g.abort(),6e4);let v;try{v=await this.proxyFetch(p.url,{signal:g.signal})}catch(b){throw b instanceof Error&&b.name==="AbortError"?new Error("Recraft image download timed out after 60s",{cause:b}):b}finally{clearTimeout(y)}if(!v.ok)throw new Error(`Failed to download Recraft image: ${v.status}`);h=(await Cu(v,vm,"Recraft image")).toString("base64")}else throw new Error("Recraft response missing both b64_json and url");const f=Date.now()-t;return m.info(`[RecraftProvider] Generated image (${h.length} base64 chars) in ${f}ms \u2014 model ${this.modelName}`),{content:s,provider:this.providerName,model:this.modelName,usage:{input:0,output:1e3,total:1e3},imageOutput:{base64:h,mimeType:yx(Buffer.from(h.slice(0,64),"base64"))}}}async validateConfiguration(){return typeof this.apiKey=="string"&&this.apiKey.trim().length>0}getConfiguration(){return{provider:this.providerName,model:this.modelName,defaultModel:Tae(),baseURL:this.baseURL}}},gHt=bae}});function aon(e){return A_(e)&&pP(e)===null?"video/mp4":SHt.every((t,r)=>e[r]===t)?"video/webm":null}function yHt(e,t,r){const n=t==="image"?gx(e):aon(e);return n===null?{status:"error",message:`${r} ${_Ht[t]}.`}:{status:"ok",dataUrl:`data:${n};base64,${e.toString("base64")}`}}function Eae(e){return e.length<=bHt?`(${e})`:`(a ${e.length}-character string)`}async function con(e,t,r){try{const n=await d4.stat(e);return n.isFile()?n.size>r?{status:"error",message:`${t} ${Eae(e)} is ${n.size} bytes; a request may carry at most ${r}.`}:{status:"ok",buffer:await d4.readFile(e)}:{status:"error",message:`${t} ${Eae(e)} is not a file.`}}catch(n){const o=n instanceof Error&&"code"in n?String(n.code):"unreadable";return{status:"error",message:`Could not read ${t} ${Eae(e)}: ${o}.`}}}async function vHt(e,t,r,n){if(typeof e!="string")return e.length===0?{status:"error",message:`${r} is an empty Buffer.`}:yHt(e,t,r);const o=e.trim();if(o==="")return{status:"error",message:`${r} is an empty string.`};if(wHt.test(o))return{status:"error",message:`${r} is a remote URL. Media is not fetched for you; pass a Buffer, a file path or a data: URL.`};if(/^data:/i.test(o))return EHt[t].test(o)?{status:"ok",dataUrl:o}:{status:"error",message:`${r} is a data: URL that is not base64 ${t} content.`};if(THt.test(o))return{status:"error",message:`${r} uses an unsupported URL scheme. Pass a Buffer, a file path or a data: URL.`};const s=await con(o,r,n);return s.status==="ok"?yHt(s.buffer,t,r):s}async function lon(e,t,r,n){const o=e.images??[];if(o.length===0&&e.video===void 0)return{status:"prepared",media:void 0};if(!t){const c=n.length>0?` Use a decision provider that does: ${n.join(", ")}.`:"";return{status:"refused",message:`${r} does not accept images or video.${c}`}}if(o.length>t.maxImages)return{status:"refused",message:`${r} accepts at most ${t.maxImages} images per request; this one has ${o.length}.`};if(e.video!==void 0&&!t.video)return{status:"refused",message:`${r} does not accept video.`};const s=[];for(const[c,l]of o.entries()){const u=await vHt(l,"image",`Image ${c+1}`,t.maxRequestBytes);if(u.status==="error")return{status:"refused",message:u.message};s.push(u.dataUrl)}let i;if(e.video!==void 0){const c=await vHt(e.video,"video","The video",t.maxRequestBytes);if(c.status==="error")return{status:"refused",message:c.message};i=c.dataUrl}const a=s.reduce((c,l)=>c+l.length,i?.length??0);return{status:"prepared",media:{images:s,...i?{video:i}:{},bytes:a}}}var wHt,THt,bHt,EHt,SHt,_Ht,uon=S({"src/lib/utils/decisionMedia.ts"(){"use strict";dn(),Zv(),mP(),wHt=/^https?:\/\//i,THt=/^[a-z][a-z0-9+.-]*:\/\//i,bHt=200,EHt={image:/^data:image\/[a-z0-9.+-]+;base64,/i,video:/^data:video\/[a-z0-9.+-]+;base64,/i},SHt=[26,69,223,163],_Ht={image:"is not a recognised image format",video:"is not a recognised video format (MP4, MOV or WebM)"}}});function kHt(e){const t=Object.values(e);return t.length>0?Math.max(...t):0}function don(e,t){if(!kn(e))return null;switch(e.type){case"noul":case"boolean":{const r=Vc(e.noul)??Vc(e.probability);return r===void 0?null:{type:"boolean",probability:r}}case"choice":{const r=kae(e.probabilities);return typeof e.choice!="string"||!r?null:{type:"choice",choice:e.choice,confidence:Vc(e.confidence)??t??kHt(r),probabilities:r}}case"score":{const r=Vc(e.score),n=AHt(e.legend),o=kae(e.probabilities);return r===void 0||!n||!o?null:{type:"score",score:r,confidence:Vc(e.confidence)??t??kHt(o),legend:n,probabilities:o}}default:return null}}function Sae(e){return e.filter(kn).map(r=>{const n=Array.isArray(r.loc)?r.loc.filter(s=>typeof s=="string"||typeof s=="number").join("."):"",o=typeof r.msg=="string"?r.msg:"invalid";return n?`${n}: ${o}`:o}).slice(0,5).join("; ")||"unspecified field"}function O3(e,t){return(t?e.split(t).join("[redacted]"):e).replace(/\.?\s*Received API Key\s*=[\s\S]*$/,"").replace(/\bsk-[A-Za-z0-9._-]+/g,"[redacted]").replace(/\b[0-9a-f]{32,}\b/gi,"[redacted]").replace(/data:[a-z]+\/[a-z0-9.+-]+;base64,[A-Za-z0-9+/=]+/gi,"[media]").trim()}function pon(e,t){if(t===void 0)return qt(e);const r=[...e],n=i=>(i.codePointAt(0)??0)<=127,o=r.filter(n).join(""),s=r.length-o.length;return qt(o)+Math.ceil(s*t)}var _ae,xHt,kn,Vc,kae,AHt,xae,B1,D3=S({async"src/lib/providers/systemOneDecision.ts"(){"use strict";Ya(),bc(),await Ul(),Fn(),dt(),uon(),z(),Nt(),Xo(),_ae=5e3,xHt=1,kn=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),Vc=e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,kae=e=>{if(!kn(e))return;const t={};for(const[r,n]of Object.entries(e)){const o=Vc(n);if(o===void 0)return;t[r]=o}return t},AHt=e=>{if(!kn(e))return;const t={};for(const[r,n]of Object.entries(e)){if(typeof n!="string")return;t[r]=n}return t},xae=(e,t)=>new Promise((r,n)=>{if(t?.aborted){n(t.reason);return}const o=setTimeout(()=>{t?.removeEventListener("abort",s),r()},e);function s(){clearTimeout(o),n(t?.reason)}t?.addEventListener("abort",s,{once:!0})}),B1=class extends va{proxyFetch;maxRetries;authFailed=!1;constructor(e,t,r){super(e,t,Hm(r)?r:void 0),this.proxyFetch=Pt(),this.maxRetries=xHt}missingConfigMessage(){}encodeQuestion(e){return e.type==="boolean"?{type:"noul",instructions:e.instructions,...e.criteria?{criteria:e.criteria}:{}}:e}readRetryAfterMs(e){}defaultTimeoutMs(e){return this.getDescriptorDecideMs()}reportedConfidence(e){return{}}resolveResponseModel(e,t){return typeof e.model=="string"?e.model:t}diagnosticContext(){return{}}getProviderName(){return this.providerName}getDefaultDecisionModel(){return this.getDefaultModel()}supportsTools(){return!1}getAISDKModel(){throw new it(`${this.vendorDisplayName()} is a decision-only provider; it generates no text, so chat completions are not available. Use \`decide()\` instead, or pick a different provider for \`generate()\` / \`stream()\`.`,this.providerName)}async executeStream(e,t){throw new it(`${this.vendorDisplayName()} is a decision-only provider; streaming is not available. Use \`decide()\`, or pick another provider for \`stream()\`.`,this.providerName)}formatProviderError(e){if(e instanceof it)return e;const t=e instanceof Error?e.message:String(e);return new it(`${this.vendorLabel()} request failed: ${t}`,this.providerName)}async decide(e){const t=this.vendorLabel();if(!this.decisionApiKey())throw this.decisionError({kind:"authentication",message:this.missingKeyMessage(),retryable:!1});const r=this.missingConfigMessage();if(r)throw this.decisionError({kind:"invalid_request",message:r,retryable:!1});if(this.authFailed)throw this.decisionError({kind:"authentication",message:`${t} rejected this API key earlier; not retrying. Fix the key and construct a new provider.`,retryable:!1});const n=Object.entries(e.questions);if(n.length===0)throw this.decisionError({kind:"invalid_request",message:"At least one question is required.",retryable:!1});const o=e.model??this.modelName??this.getDefaultModel();this.assertWithinDecisionLimits(e,o,n.length);const s=Object.fromEntries(n.map(([u,d])=>[u,this.encodeQuestion(d)])),i=await this.prepareMedia(e),a=JSON.stringify(this.buildDecisionBody(e.state,s,o,i));this.assertWithinRequestBytes(a);const c=e.timeoutMs??this.defaultTimeoutMs(n.length)??this.defaultTimeout??_ae;let l;for(let u=0;u<=this.maxRetries;u++){const d=Date.now();try{const p=AbortSignal.timeout(c),h=e.signal?AbortSignal.any([e.signal,p]):p,f=await this.proxyFetch(this.decisionEndpoint(),{method:"POST",headers:this.decisionHeaders(),body:a,signal:h}),g=Date.now()-d,y=this.readRequestId(f.headers),v=Number(f.headers.get("x-envoy-upstream-service-time"))||void 0,T=await f.json().catch(()=>null);if(!f.ok){if(l=this.parseDecisionError(f.status,T,y),l.kind==="authentication"&&(this.authFailed=!0,m.warn(`${t}: credential not accepted \u2014 disabling this provider instance. ${l.message}`,{status:l.status,...this.diagnosticContext(),requestId:y})),!l.retryable||u===this.maxRetries)throw this.decisionError(l);const k=this.readRetryAfterMs(f.headers);if(k!==void 0&&k>c-(Date.now()-d))throw this.decisionError(l);await xae(k??2**u*250+Math.random()*250,e.signal);continue}if(!kn(T)||!kn(T.answers))throw this.decisionError({kind:"server",message:`${t} returned a response without an answers map.`,status:f.status,requestId:y,retryable:!1});const b=this.reportedConfidence(T),_={};for(const[k,A]of Object.entries(T.answers)){const R=don(A,b[k]);R?_[k]=R:m.warn(`${t}: dropped unparseable answer "${k}"`,{requestId:y})}const x=kn(T.usage)?T.usage:{};return{model:this.resolveResponseModel(T,o),provider:this.providerName,answers:_,usage:{inputTokens:Vc(x.input_tokens)??Vc(x.inputTokens)??0,outputTokens:Vc(x.output_tokens)??Vc(x.outputTokens)??0},requestId:y,latencyMs:g,upstreamMs:v,...i?{mediaBytes:i.bytes}:{}}}catch(p){if(p instanceof it)throw p;const h=e.signal?.aborted===!0,f=p instanceof Error&&p.name==="TimeoutError";if(l={kind:h?"network":f?"timeout":"network",message:O3(NE(p instanceof Error?p.message:String(p)),this.decisionApiKey()),retryable:!h},h||u===this.maxRetries)throw this.decisionError(l);await xae(2**u*250+Math.random()*250)}}throw this.decisionError(l??{kind:"network",message:`${t} request failed.`,retryable:!1})}async prepareMedia(e){const t=mr.get(this.providerName)?.decisionLimits,r=await lon(e,t?.media,this.vendorLabel(),VCr({video:e.video!==void 0}));if(r.status==="refused")throw this.decisionError({kind:"invalid_request",message:r.message,retryable:!1});return r.media}assertWithinRequestBytes(e){const t=mr.get(this.providerName)?.decisionLimits?.media?.maxRequestBytes;if(t===void 0)return;const r=Buffer.byteLength(e);if(r>t)throw this.decisionError({kind:"invalid_request",message:`The request is ${r} bytes; ${this.vendorLabel()} accepts at most ${t}. Send fewer or smaller images, or a shorter video.`,retryable:!1})}assertWithinDecisionLimits(e,t,r){const n=mr.get(this.providerName)?.decisionLimits;if(!n)return;const o=this.vendorLabel();if(n.maxQuestions!==void 0&&r>n.maxQuestions)throw this.decisionError({kind:"max_tokens_exceeded",message:`${o} accepts at most ${n.maxQuestions} questions per request; this one has ${r}. Ask fewer, or use a decision provider without this cap.`,retryable:!1});const s=n.models?.[t],i=s?.maxStateTokens??n.maxStateTokens,a=pon(J_(e.state),s?.nonAsciiTokensPerChar??n.nonAsciiTokensPerChar);if(a>i)throw this.decisionError({kind:"max_tokens_exceeded",message:`The state is ~${a} tokens; ${o}'s "${t}" model reads at most ${i}. Shorten the state, or use a decision provider with a larger window.`,retryable:!1})}decisionError(e){const t=new it(e.message,this.providerName);return Object.defineProperty(t,"cause",{value:e,enumerable:!1,writable:!0,configurable:!0}),t}}}}),CHt={};Z(CHt,{TYPESAFE_MAX_REQUEST_TOKENS:()=>L3,TYPESAFE_MAX_STATE_TOKENS:()=>N3,TypeSafeProvider:()=>LHt});function mon(e){if(!kn(e)||!kn(e.providerMetadata))return{};const t=e.providerMetadata.typesafe;if(!kn(t)||!kn(t.confidence))return{};const r={};for(const[n,o]of Object.entries(t.confidence)){const s=Vc(o);s!==void 0&&(r[n]=s)}return r}function hon(e,t,r,n){const o=typeof t.type=="string"?t.type:void 0,s=(o?NHt[o]:void 0)??(e===401||e===403?"authentication":e===429?"rate_limit":e>=500?"server":"invalid_request"),i=typeof t.message=="string"&&t.message.length>0?t.message:o??`AI Gateway request failed with HTTP ${e}`;return{kind:s,message:i,status:e,requestId:r,retryable:n}}function IHt(e,t,r){const n=e===429||e===529||e>=500,o=kn(t)&&kn(t.error)?t.error:void 0;if(o)return hon(e,o,r,n);const s=kn(t)?t.detail:void 0;if(Array.isArray(s))return{kind:"invalid_request",message:`Request failed validation \u2014 ${Sae(s)}`,status:e,requestId:r,retryable:!1};const i=kn(s)&&typeof s.error_type=="string"?s.error_type:void 0,a=i==="max_tokens_exceeded"?"max_tokens_exceeded":e===401||e===403?"authentication":e===429?"rate_limit":e===529?"overloaded":e>=500?"server":"invalid_request",c=a==="max_tokens_exceeded"?`State plus questions exceeded the model's input limit: keep state plus the longest single question under ~${N3} tokens, and state plus all questions under ~${L3}.`:i??`TypeSafe request failed with HTTP ${e}`,l=kn(s)&&typeof s.message=="string"?s.message:c;return{kind:a,message:l,status:e,requestId:r,retryable:n}}var RHt,MHt,PHt,OHt,DHt,N3,L3,NHt,LHt,FHt=S({async"src/lib/providers/typesafe.ts"(){"use strict";z(),Nt(),$o(),await D3(),RHt="https://api.typesafe.ai",MHt="https://ai-gateway.vercel.sh/v4/ai/evaluation-model",PHt="typesafe-ai/jev",OHt="0.0.1",DHt="4",N3=33e3,L3=64e3,NHt={authentication_error:"authentication",customer_verification_required:"authentication",invalid_request_error:"invalid_request",rate_limit_exceeded:"rate_limit",internal_server_error:"server"},LHt=class extends B1{apiKey;baseURL;gatewayURL;transport;constructor(e,t,r,n){super(e,"typesafe",t);const o=n?.apiKey?.trim()||(process.env.TYPESAFE_API_KEY?.trim()??""),s=n?.gatewayApiKey?.trim()||(process.env.AI_GATEWAY_API_KEY?.trim()??""),i=n?.transport??process.env.TYPESAFE_TRANSPORT?.trim();this.transport=i==="gateway"||i==="direct"?i:!o&&s?"gateway":"direct",this.apiKey=this.transport==="gateway"?s:o,this.baseURL=(n?.baseURL??process.env.TYPESAFE_BASE_URL??RHt).replace(/\/+$/,""),this.gatewayURL=(n?.gatewayURL?.trim()||process.env.TYPESAFE_GATEWAY_URL?.trim()||MHt).replace(/\/+$/,""),m.debug("TypeSafe Provider initialized (decide only)",{modelName:this.modelName,transport:this.transport,baseURL:Yt(this.transport==="gateway"?this.gatewayURL:this.baseURL)})}getDefaultModel(){return zs("TYPESAFE_MODEL","jev-latest")}vendorLabel(){return"TypeSafe"}vendorDisplayName(){return"TypeSafe (Jev)"}decisionApiKey(){return this.apiKey}missingKeyMessage(){return this.transport==="gateway"?"The TypeSafe gateway transport requires a Vercel AI Gateway key. Set AI_GATEWAY_API_KEY or pass credentials.typesafe.gatewayApiKey.":"TypeSafe requires an API key. Set TYPESAFE_API_KEY or pass credentials.typesafe.apiKey."}encodeQuestion(e){return this.transport==="gateway"?e:super.encodeQuestion(e)}buildDecisionBody(e,t,r){return this.transport==="gateway"?{state:e,questions:t}:{model:r,state:e,questions:t}}parseDecisionError(e,t,r){return IHt(e,t,r)}reportedConfidence(e){return mon(e)}readRequestId(e){return e.get("x-typesafe-request-id")??void 0}diagnosticContext(){return{transport:this.transport}}decisionEndpoint(){return this.transport==="gateway"?this.gatewayURL:`${this.baseURL}/v1/systemone`}decisionHeaders(){const e={Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"};return this.transport==="gateway"?{...e,"ai-gateway-auth-method":"api-key","ai-gateway-protocol-version":OHt,"ai-model-id":PHt,"ai-evaluation-model-specification-version":DHt}:e}getDecisionTransport(){return this.transport}async listDecisionModels(){if(this.transport==="gateway")throw this.decisionError({kind:"invalid_request",message:"Model listing is a TypeSafe API operation; the gateway transport has no equivalent endpoint.",retryable:!1});const e=await this.proxyFetch(`${this.baseURL}/v1/models`,{headers:{Authorization:`Bearer ${this.apiKey}`},signal:AbortSignal.timeout(this.defaultTimeout??_ae)}),t=await e.json().catch(()=>null);if(!e.ok)throw this.decisionError(IHt(e.status,t,e.headers.get("x-typesafe-request-id")??void 0));return(kn(t)&&Array.isArray(t.models)?t.models:[]).filter(kn).map(n=>({name:typeof n.name=="string"?n.name:"",description:typeof n.description=="string"?n.description:"",releaseDate:typeof n.release_date=="string"?n.release_date:""}))}}}}),$Ht={};Z($Ht,{LayaProvider:()=>UHt});function fon(e,t,r){const n=e===429||e>=500,o=e===401||e===403?"authentication":e===413?"max_tokens_exceeded":e===429?"rate_limit":e===503?"overloaded":e>=500?"server":"invalid_request",s=kn(t)&&kn(t.error)?t.error:void 0;if(s&&typeof s.message=="string"&&s.message.length>0)return{kind:o,message:s.message,status:e,requestId:r,retryable:n};const i=kn(t)?t.detail:void 0;return Array.isArray(i)?{kind:"invalid_request",message:`Request failed validation \u2014 ${Sae(i)}`,status:e,requestId:r,retryable:!1}:typeof i=="string"&&i.length>0?{kind:o,message:i,status:e,requestId:r,retryable:n}:{kind:o,message:`Laya request failed with HTTP ${e}`,status:e,requestId:r,retryable:n}}var UHt,gon=S({async"src/lib/providers/laya.ts"(){"use strict";z(),Nt(),$o(),await D3(),UHt=class extends B1{apiKey;baseURL;constructor(e,t,r,n){super(e,"laya",t),this.apiKey=n?.apiKey?.trim()||(process.env.LAYA_API_KEY?.trim()??""),this.baseURL=(n?.baseURL?.trim()||process.env.LAYA_BASE_URL?.trim()||"").replace(/\/+$/,""),m.debug("Laya Provider initialized (decide only)",{modelName:this.modelName,baseURL:this.baseURL?Yt(this.baseURL):"(not set)"})}getDefaultModel(){return zs("LAYA_MODEL","typed-decisions")}vendorLabel(){return"Laya"}vendorDisplayName(){return"Laya"}decisionApiKey(){return this.apiKey}missingKeyMessage(){return"Laya requires an API key. Set LAYA_API_KEY or pass credentials.laya.apiKey."}missingConfigMessage(){return this.baseURL?void 0:"Laya requires a base URL. Set LAYA_BASE_URL or pass credentials.laya.baseURL."}decisionEndpoint(){return`${this.baseURL}/predict`}decisionHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"}}buildDecisionBody(e,t,r){return r==="auto"?{state:e,questions:t}:{model:r,state:e,questions:t}}parseDecisionError(e,t,r){const n=fon(e,t,r),o=O3(n.message,this.apiKey);return{...n,message:o||`Laya request failed with HTTP ${e}`}}readRequestId(e){return e.get("x-litellm-call-id")??void 0}resolveResponseModel(e,t){const r=e.routing;return kn(r)&&typeof r.model=="string"?r.model:super.resolveResponseModel(e,t)}}}}),BHt={};Z(BHt,{XorProvider:()=>qHt});function yon(e){return e.replace(/\/+$/,"").replace(/\/v1$/i,"")}function von(e){const t="Set XOR_BASE_URL or pass credentials.xor.baseURL to the origin, and give the key through XOR_API_KEY or credentials.xor.apiKey.";try{const r=new URL(e);return r.protocol!=="https:"&&r.protocol!=="http:"?`The XOR base URL must start with https:// or http://. ${t}`:r.username||r.password||r.search||r.hash?`The XOR base URL must not carry credentials, a query string or a fragment. ${t}`:void 0}catch{return`The XOR base URL is not a valid absolute URL. ${t}`}}function won(e,t){return e===401?"authentication":e===413?"max_tokens_exceeded":e===429?"rate_limit":e===503?"overloaded":e>=500?GHt.test(t)?"max_tokens_exceeded":"server":"invalid_request"}function Ton(e){if(!kn(e))return;const{error:t,detail:r}=e;return kn(t)&&typeof t.message=="string"&&t.message.length>0?t.message:typeof t=="string"&&t.length>0?t:Array.isArray(r)?`Request failed validation \u2014 ${Sae(r)}`:typeof r=="string"&&r.length>0?r:void 0}var zHt,GHt,qHt,bon=S({async"src/lib/providers/xor.ts"(){"use strict";z(),Nt(),$o(),await D3(),zHt="/v1/systemone",GHt=/(context|prefill|prompt).{0,40}(length|limit|too long|exceed)|(too long|exceeds?).{0,40}(context|tokens)/i,qHt=class extends B1{apiKey;baseURL;constructor(e,t,r,n){super(e,"xor",t),this.apiKey=n?.apiKey?.trim()||(process.env.XOR_API_KEY?.trim()??""),this.baseURL=yon(n?.baseURL?.trim()||process.env.XOR_BASE_URL?.trim()||""),m.debug("XOR Provider initialized (decide only)",{modelName:this.modelName,baseURL:this.baseURL?Yt(this.baseURL):"(not set)"})}getDefaultModel(){return zs("XOR_MODEL","xor-1.1")}vendorLabel(){return"XOR"}vendorDisplayName(){return"XOR"}decisionApiKey(){return this.apiKey}missingKeyMessage(){return"XOR requires an API key. Set XOR_API_KEY or pass credentials.xor.apiKey."}missingConfigMessage(){return this.baseURL?von(this.baseURL):"XOR requires a base URL. Set XOR_BASE_URL or pass credentials.xor.baseURL."}decisionEndpoint(){return`${this.baseURL}${zHt}`}decisionHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"}}buildDecisionBody(e,t,r,n){return{model:r,state:e,questions:t,...n&&n.images.length>0?{images:n.images}:{},...n?.video?{video:n.video}:{}}}parseDecisionError(e,t,r){const n=`XOR request failed with HTTP ${e}`,o=O3(Ton(t)??n,this.apiKey)||n,s=won(e,o);return{kind:s,message:o,status:e,requestId:r,retryable:s==="rate_limit"||s==="overloaded"||s==="server"}}readRequestId(e){return e.get("x-request-id")??e.get("x-typesafe-request-id")??e.get("x-litellm-call-id")??void 0}}}}),VHt={};Z(VHt,{PerplexityDeciderProvider:()=>QHt});function Eon(e){return e.replace(/\/+$/,"").replace(/\/v1$/i,"")}function jHt(e){const t=`Set PERPLEXITY_DECIDER_BASE_URL or pass credentials.perplexityDecider.baseURL to an origin, or leave both unset to use ${Aae}.`;try{const r=new URL(e);return r.protocol!=="https:"&&r.protocol!=="http:"?`The Perplexity base URL must start with https:// or http://. ${t}`:r.username||r.password||r.search||r.hash?`The Perplexity base URL must not carry credentials, a query string or a fragment. ${t}`:void 0}catch{return`The Perplexity base URL is not a valid absolute URL. ${t}`}}function Son(e){try{return new URL(e).hostname===KHt}catch{return!1}}function _on(e,t){return e===401?"authentication":e===413||e===400&&ZHt.test(t)?"max_tokens_exceeded":e===429?"rate_limit":e===503?"overloaded":e>=500?"server":"invalid_request"}function kon(e){if(!kn(e)||!kn(e.error))return;const{message:t,param:r}=e.error;if(!(typeof t!="string"||t.length===0))return typeof r=="string"&&r!==""&&!t.includes(r)?`${t} (field: ${r})`:t}function xon(e){return e.length>=24&&e.toString("ascii",12,16)==="IHDR"?{width:e.readUInt32BE(16),height:e.readUInt32BE(20)}:void 0}function Aon(e){let t=2;for(;t+4<=e.length;){if(e[t]!==255)return;const r=e[t+1];if(r===255)t+=1;else if(r===1||r>=208&&r<=216)t+=2;else{if(r===217||r===218)return;if(r>=192&&r<=207&&r!==196&&r!==200&&r!==204)return t+9<=e.length?{height:e.readUInt16BE(t+5),width:e.readUInt16BE(t+7)}:void 0;t+=2+e.readUInt16BE(t+2)}}}function Con(e){if(!(e.length<30))switch(e.toString("ascii",12,16)){case"VP8X":return{width:1+e.readUIntLE(24,3),height:1+e.readUIntLE(27,3)};case"VP8L":{const t=e.readUInt32LE(21);return e[20]===47?{width:(t&16383)+1,height:(t>>>14&16383)+1}:void 0}case"VP8 ":return{width:e.readUInt16LE(26)&16383,height:e.readUInt16LE(28)&16383};default:return}}function Ion(e){switch(gx(e)){case"image/png":return xon(e);case"image/jpeg":return Aon(e);case"image/webp":return Con(e);default:return}}function Ron(e,t){const r=/^data:([a-z]+\/[a-z0-9.+-]+);base64,/i.exec(e);if(!r||!YHt.has(r[1].toLowerCase()))return`Image ${t} is not a PNG, JPEG or WebP image, the only formats Perplexity reads.`;const n=Ion(Buffer.from(e.slice(r[0].length),"base64"));return n&&Math.round(n.width/z1)*Math.round(n.height/z1)>Cae?`Image ${t} is ${n.width}x${n.height} pixels; Perplexity reads at most ${Cae} tiles of ${z1}x${z1} pixels per image (1440x1440 and 2048x1024 fit), and a larger one stalls until the request times out. Resize it first.`:void 0}function HHt(e){return typeof e=="number"||typeof e=="boolean"?String(e):e}var Aae,WHt,KHt,JHt,YHt,z1,Cae,XHt,ZHt,QHt,Mon=S({async"src/lib/providers/perplexityDecider.ts"(){"use strict";Zv(),z(),Nt(),$o(),await D3(),Aae="https://api.perplexity.ai",WHt="/v1/decisions",KHt="api.perplexity.ai",JHt="neurolink",YHt=new Set(["image/png","image/jpeg","image/webp"]),z1=32,Cae=2048,XHt=100,ZHt=/exceeds(?: or equals)?(?: model's)? maximum context length/i,QHt=class extends B1{apiKey;baseURL;constructor(e,t,r,n){super(e,"perplexity-decider",t),this.apiKey=n?.apiKey?.trim()||(process.env.PERPLEXITY_API_KEY?.trim()??""),this.baseURL=Eon(n?.baseURL?.trim()||process.env.PERPLEXITY_DECIDER_BASE_URL?.trim()||Aae),m.debug("Perplexity decision provider initialized (decide only)",{modelName:this.modelName,baseURL:jHt(this.baseURL)?"(invalid)":Yt(this.baseURL)})}getDefaultModel(){return zs("PERPLEXITY_DECIDER_MODEL","pplx-decider-v1-27b")}vendorLabel(){return"Perplexity"}vendorDisplayName(){return"Perplexity Decisions"}decisionApiKey(){return this.apiKey}missingKeyMessage(){return"Perplexity requires an API key. Set PERPLEXITY_API_KEY or pass credentials.perplexityDecider.apiKey."}missingConfigMessage(){return jHt(this.baseURL)}decisionEndpoint(){return`${this.baseURL}${WHt}`}decisionHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json",...Son(this.baseURL)?{"X-Pplx-Integration":JHt}:{}}}buildDecisionBody(e,t,r,n){const o=n?.images??[];if(o.length===0)return{model:r,state:HHt(e),questions:t};o.forEach((i,a)=>{const c=Ron(i,a+1);if(c)throw this.decisionError({kind:"invalid_request",message:c,retryable:!1})});const s=Array.isArray(e)?e:e===""?[]:[HHt(e)];return{model:r,state:[...s,...o.map(i=>({type:"image_url",image_url:{url:i}}))],questions:t}}parseDecisionError(e,t,r){const n=`Perplexity request failed with HTTP ${e}`,o=O3(kon(t)??n,this.apiKey).replace(/\bpplx-[A-Za-z0-9_-]{30,}/g,"[redacted]").trim()||n,s=_on(e,o);return{kind:s,message:o,status:e,requestId:r,retryable:s==="rate_limit"||s==="overloaded"||s==="server"}}readRequestId(e){return e.get("x-request-id")??void 0}defaultTimeoutMs(e){const t=this.getDescriptorDecideMs();return t===void 0?void 0:t+e*XHt}readRetryAfterMs(e){const t=e.get("retry-after")?.trim();if(!t)return;const r=/^\d+$/.test(t)?Number(t)*1e3:Date.parse(t)-Date.now();return Number.isFinite(r)&&r>0?Math.ceil(r):void 0}}}}),eWt={};Z(eWt,{Agent:()=>qWt,BedrockClient:()=>rWt,BedrockRuntimeClient:()=>oWt,Blob:()=>GWt,Client:()=>jWt,ConverseCommand:()=>sWt,ConverseStreamCommand:()=>iWt,Cron:()=>_Wt,Dispatcher:()=>HWt,File:()=>zWt,FlowProducer:()=>SWt,FormData:()=>BWt,GoogleAuth:()=>pWt,HTTPException:()=>MWt,Headers:()=>UWt,Hippocampus:()=>gWt,HippocampusConfig:()=>yWt,Hono:()=>IWt,ImageFormat:()=>aWt,InvokeEndpointCommand:()=>uWt,InvokeEndpointWithResponseStreamCommand:()=>dWt,InvokeModelCommand:()=>cWt,Job:()=>bWt,ListFoundationModelsCommand:()=>nWt,MockAgent:()=>JWt,Pool:()=>VWt,Queue:()=>wWt,QueueScheduler:()=>EWt,Request:()=>FWt,Response:()=>$Wt,SageMakerRuntimeClient:()=>lWt,TextToSpeechClient:()=>hWt,VertexAI:()=>mWt,Webhook:()=>fWt,Worker:()=>TWt,convertToHtml:()=>CWt,cors:()=>RWt,createClient:()=>vWt,default:()=>tWt,extractRawText:()=>AWt,fetch:()=>LWt,getGlobalDispatcher:()=>KWt,interceptors:()=>YWt,logger:()=>PWt,parseBuffer:()=>kWt,request:()=>XWt,secureHeaders:()=>OWt,selectCover:()=>xWt,setGlobalDispatcher:()=>WWt,streamSSE:()=>DWt,timeout:()=>NWt});var Kg,gs,tWt,rWt,nWt,oWt,sWt,iWt,aWt,cWt,lWt,uWt,dWt,pWt,mWt,hWt,fWt,gWt,yWt,vWt,wWt,TWt,bWt,EWt,SWt,_Wt,kWt,xWt,AWt,CWt,IWt,RWt,MWt,PWt,OWt,DWt,NWt,LWt,FWt,$Wt,UWt,BWt,zWt,GWt,qWt,VWt,jWt,HWt,WWt,KWt,JWt,YWt,XWt,Pon=S({"npm-stub:@google-cloud/text-to-speech"(){Kg={get(e,t){return t==="__esModule"?!0:t==="default"?new Proxy({},{get:Kg.get}):new Proxy(function(...r){return new Proxy({},{get:Kg.get})},{get:Kg.get,apply(r,n,o){return new Proxy({},{get:Kg.get})},construct(r,n){return new Proxy({},{get:Kg.get})}})}},gs=new Proxy({},Kg),tWt=gs,{BedrockClient:rWt,ListFoundationModelsCommand:nWt,BedrockRuntimeClient:oWt,ConverseCommand:sWt,ConverseStreamCommand:iWt,ImageFormat:aWt,InvokeModelCommand:cWt}=gs,{SageMakerRuntimeClient:lWt,InvokeEndpointCommand:uWt,InvokeEndpointWithResponseStreamCommand:dWt}=gs,{GoogleAuth:pWt,VertexAI:mWt,TextToSpeechClient:hWt}=gs,{Webhook:fWt}=gs,{Hippocampus:gWt,HippocampusConfig:yWt}=gs,{createClient:vWt}=gs,{Queue:wWt,Worker:TWt,Job:bWt,QueueScheduler:EWt,FlowProducer:SWt}=gs,{Cron:_Wt}=gs,{parseBuffer:kWt,selectCover:xWt}=gs,{extractRawText:AWt,convertToHtml:CWt}=gs,{Hono:IWt}=gs,{cors:RWt,HTTPException:MWt,logger:PWt,secureHeaders:OWt,streamSSE:DWt,timeout:NWt}=gs,LWt=globalThis.fetch,FWt=globalThis.Request,$Wt=globalThis.Response,UWt=globalThis.Headers,BWt=globalThis.FormData,zWt=globalThis.File,GWt=globalThis.Blob,qWt=gs.Agent,VWt=gs.Pool,jWt=gs.Client,HWt=gs.Dispatcher,WWt=()=>{},KWt=()=>gs,JWt=gs.MockAgent,YWt={redirect:()=>e=>e,retry:()=>e=>e},XWt=async(e,t)=>{const r=await globalThis.fetch(e,t);return{statusCode:r.status,headers:Object.fromEntries(r.headers.entries()),body:{text:()=>r.text(),json:()=>r.json(),arrayBuffer:()=>r.arrayBuffer()}}}}}),F3,ZWt=S({"src/lib/adapters/tts/googleTTSHandler.ts"(){"use strict";_c(),z(),$y(),Eo(),F3=class Qu{client=null;voicesCache=null;static CACHE_TTL_MS=300*1e3;static DEFAULT_MAX_TEXT_LENGTH=5e3;static DEFAULT_API_TIMEOUT_MS=30*1e3;maxTextLength=Qu.DEFAULT_MAX_TEXT_LENGTH;credentialsPath;constructor(t){this.credentialsPath=t??process.env.GOOGLE_APPLICATION_CREDENTIALS}isConfigured(){return this.credentialsPath!==void 0}async getClient(){if(!this.client){const{TextToSpeechClient:t}=await Promise.resolve().then(()=>(Pon(),eWt));this.client=new t({keyFilename:this.credentialsPath})}return this.client}async getVoices(t){if(!this.isConfigured())throw new Et({code:At.PROVIDER_NOT_CONFIGURED,message:"Google Cloud TTS client not initialized. Set GOOGLE_APPLICATION_CREDENTIALS or pass credentials path.",category:"configuration",severity:"high",retriable:!1});const r=await this.getClient(),n=Pe.createSpan("tts","tts.google.listVoices",{"tts.operation":"listVoices","tts.provider":"google"});try{if(this.voicesCache&&Date.now()-this.voicesCache.timestamp<Qu.CACHE_TTL_MS&&!t){const a=Pe.endSpan(n,1);return ot().recordSpan(a),this.voicesCache.voices}const[o]=await r.listVoices(t?{languageCode:t}:{});if(!o.voices||o.voices.length===0){m.warn("Google Cloud TTS returned no voices");const a=Pe.endSpan(n,1);return ot().recordSpan(a),[]}const s=[];for(const a of o.voices??[]){if(!a.name||!Array.isArray(a.languageCodes)||a.languageCodes.length===0){m.warn("Skipping voice with missing required fields",{name:a.name,languageCodesCount:a.languageCodes?.length});continue}const c=a.name,l=a.languageCodes,u=l[0],d=this.detectVoiceType(c),p=a.ssmlGender==="MALE"?"male":a.ssmlGender==="FEMALE"?"female":"neutral";s.push({id:c,name:c,languageCode:u,languageCodes:l,gender:p,type:d,naturalSampleRateHertz:a.naturalSampleRateHertz??void 0})}t||(this.voicesCache={voices:s,timestamp:Date.now()});const i=Pe.endSpan(n,1);return ot().recordSpan(i),s}catch(o){const s=Pe.endSpan(n,2,o instanceof Error?o.message:"Unknown error");ot().recordSpan(s);const i=o instanceof Error?o.message:"Unknown error";return m.error(`Failed to fetch Google TTS voices: ${i}`),[]}}async synthesize(t,r){if(!this.isConfigured())throw new Et({code:At.PROVIDER_NOT_CONFIGURED,message:"Google Cloud TTS client not initialized. Set GOOGLE_APPLICATION_CREDENTIALS or pass credentials path.",category:"configuration",severity:"high",retriable:!1});const n=await this.getClient(),o=r.voice??"en-US-Neural2-C",s=Pe.createSpan("tts","tts.google.synthesize",{"tts.operation":"synthesize","tts.provider":"google","tts.voice":o,"tts.format":r.format??"mp3"}),i=Date.now();try{const a=t.startsWith("<speak>")&&t.endsWith("</speak>");if(t.startsWith("<speak>")&&!t.endsWith("</speak>")||!t.startsWith("<speak>")&&t.endsWith("</speak>"))throw new Et({code:At.INVALID_INPUT,message:"Malformed SSML: missing opening <speak> or closing </speak> tag.",category:"validation",severity:"medium",retriable:!1});const c=this.extractLanguageCode(o),l=this.mapFormat(r.format??"mp3"),u={input:a?{ssml:t}:{text:t},voice:{name:o,languageCode:c},audioConfig:{audioEncoding:l,speakingRate:r.speed??1,pitch:r.pitch??0,volumeGainDb:r.volumeGainDb??0}},[d]=await n.synthesizeSpeech(u,{timeout:Qu.DEFAULT_API_TIMEOUT_MS}),p=d.audioContent;if(!p)throw new Et({code:At.SYNTHESIS_FAILED,message:"Google TTS returned empty audio content",category:"execution",severity:"high",retriable:!0});const h=p instanceof Uint8Array?Buffer.from(p):typeof p=="string"?Buffer.from(p,"base64"):(()=>{throw new Et({code:At.SYNTHESIS_FAILED,message:"Unsupported audioContent type returned by Google TTS",category:"execution",severity:"high",retriable:!0,context:{type:typeof p}})})(),f=Date.now()-i,g=Pe.endSpan(s,1);return ot().recordSpan(g),{buffer:h,format:r.format??"mp3",size:h.length,voice:o,metadata:{latency:f,provider:"google-ai"}}}catch(a){const c=Pe.endSpan(s,2,a instanceof Error?a.message:String(a));if(ot().recordSpan(c),a instanceof Et)throw a;const l=Date.now()-i,u=a instanceof Error?a.message:"Unknown error";throw new Et({code:At.SYNTHESIS_FAILED,message:`Google TTS failed after ${l}ms: ${u}`,category:"execution",severity:"high",retriable:!0,context:{latency:l},originalError:a instanceof Error?a:void 0})}}static STREAMING_VOICE_PATTERN=/^[a-z]{2,3}-[A-Z]{2}-(?:Chirp3-HD|Chirp-HD|Journey)-/;static STREAMING_SAMPLE_RATE_HZ=24e3;static STREAMING_IDLE_TIMEOUT_MS=30*1e3;static mapStreamingFormat(t){switch(t){case"pcm16":return"PCM";case"ogg":case"opus":return"OGG_OPUS";default:return}}static streamedAudio(t){if(t===null||typeof t!="object")return;const r=t.audioContent;if(r instanceof Uint8Array)return r.byteLength>0?Buffer.from(r.buffer,r.byteOffset,r.byteLength):void 0;if(typeof r=="string"&&r.length>0){const n=Buffer.from(r,"base64");return n.length>0?n:void 0}}synthesizeStream(t,r={}){const n=r.voice;if(n===void 0||!Qu.STREAMING_VOICE_PATTERN.test(n))return;const o=r.format??"mp3",s=Qu.mapStreamingFormat(o);if(s===void 0||t.trimStart().startsWith("<speak"))return;const i=this.extractLanguageCode(n),a=Qu.STREAMING_SAMPLE_RATE_HZ,c=this;let l,u=!1,d=!1;const p=(async function*(){const h=await c.getClient();if(u)return;const f=Date.now(),g=h.streamingSynthesize();l=g;let y;const v=()=>{clearTimeout(y),y=setTimeout(()=>{d=!0,g.cancel()},Qu.STREAMING_IDLE_TIMEOUT_MS)};let T=0,b=0;try{g.write({streamingConfig:{voice:{name:n,languageCode:i},streamingAudioConfig:{audioEncoding:s,sampleRateHertz:a,speakingRate:r.speed??1}}}),g.write({input:{text:t}}),g.end(),v();for await(const _ of g){clearTimeout(y);const x=Qu.streamedAudio(_);if(x===void 0){v();continue}b+=x.length,yield{data:x,format:o,index:T++,isFinal:!1,cumulativeSize:b,voice:n,sampleRate:a},v()}m.debug(`[GoogleTTSHandler] Streamed ${b} bytes in ${Date.now()-f}ms`)}catch(_){if(u)return;if(_ instanceof Et)throw _;const x=_ instanceof Error?_.message:"Unknown error";throw new Et({code:At.SYNTHESIS_FAILED,message:d?`Google TTS streaming synthesis stalled for ${Qu.STREAMING_IDLE_TIMEOUT_MS}ms`:`Google TTS streaming synthesis failed: ${x}`,category:d?"network":"execution",severity:"high",retriable:!0,context:{voice:n,audioEncoding:s},originalError:_ instanceof Error?_:void 0})}finally{clearTimeout(y),l=void 0,g.cancel()}})();return n_(p,()=>{u=!0,l?.cancel()})}extractLanguageCode(t){const r=t.split("-");if(r.length>=2)return`${r[0]}-${r[1]}`;throw new Et({code:At.INVALID_INPUT,message:`Invalid Google TTS voiceId format: "${t}". Expected format like "en-US-Neural2-C".`,category:"validation",severity:"medium",retriable:!1,context:{voiceId:t}})}mapFormat(t){switch(t.toLowerCase()){case"mp3":return"MP3";case"wav":return"LINEAR16";case"ogg":case"opus":return"OGG_OPUS";case"pcm16":throw new Et({code:At.INVALID_INPUT,message:"Google Cloud TTS's buffered synthesis does not support pcm16 output. pcm16 is only delivered via native streaming, which requires a Chirp3-HD, Chirp-HD, or Journey voice and plain (non-SSML) text \u2014 check that both conditions hold, or request a different format.",category:"validation",severity:"medium",retriable:!1,context:{format:t}});default:throw new Et({code:At.INVALID_INPUT,message:`Unsupported audio format: ${t}`,category:"validation",severity:"medium",retriable:!1,context:{format:t}})}}detectVoiceType(t){const r=t.toLowerCase().split("-");return r.some(n=>n.startsWith("chirp"))?"chirp":r.includes("neural2")?"neural":r.includes("wavenet")?"wavenet":r.includes("standard")?"standard":"unknown"}}}}),eT,G1,$3=S({"src/lib/voice/RealtimeVoiceAPI.ts"(){"use strict";z(),Rd(),dt(),Ly(),eT=class{static registry=new df("RealtimeProcessor");static sessions=new Map;static registerHandler(e,t){const r=e&&e.toLowerCase();this.registry.register(e,t),m.debug(`[RealtimeProcessor] Registered Realtime handler for provider: ${r}`)}static getHandler(e){return this.registry.get(e)}static supports(e){return this.registry.supports(e)}static getProviders(){return this.registry.list()}static async connect(e,t,r){const n=this.getHandler(e);if(!n)throw er.providerNotSupported(e,this.registry.list());if(!n.isConfigured())throw er.providerNotConfigured(e);if(n.isConnected())throw er.sessionAlreadyActive(e);const o={...zR,...t};r&&n.on(r);try{m.debug(`[RealtimeProcessor] Connecting to provider: ${e}`);const s=await n.connect(o);return this.sessions.set(e.toLowerCase(),s),m.info(`[RealtimeProcessor] Connected to ${e} session: ${s.id}`),s}catch(s){if(r&&n.off(),s instanceof er)throw s;const i=s instanceof Error?s.message:String(s||"Unknown error");throw er.connectionFailed(i,e,s instanceof Error?s:void 0)}}static async disconnect(e){const t=this.getHandler(e);if(!t)throw er.providerNotSupported(e,this.registry.list());if(!t.isConnected()){m.warn(`[RealtimeProcessor] No active session for provider: ${e}`);return}try{await t.disconnect(),this.sessions.delete(e.toLowerCase()),t.off(),m.info(`[RealtimeProcessor] Disconnected from ${e}`)}catch(r){if(r instanceof er)throw r;const n=r instanceof Error?r.message:String(r||"Unknown error");throw er.protocolError(`Disconnect failed: ${n}`,e,r instanceof Error?r:void 0)}}static async sendAudio(e,t){const r=this.getHandler(e);if(!r)throw er.providerNotSupported(e,this.registry.list());if(!r.isConnected())throw er.sessionNotActive(e);try{await r.sendAudio(t)}catch(n){if(n instanceof er)throw n;const o=n instanceof Error?n.message:String(n||"Unknown error");throw er.audioStreamError(o,e)}}static async sendText(e,t){const r=this.getHandler(e);if(!r)throw er.providerNotSupported(e,this.registry.list());if(!r.isConnected())throw er.sessionNotActive(e);if(!r.sendText)throw new er({code:Bs.PROTOCOL_ERROR,message:`Provider "${e}" does not support text input`,category:"validation",severity:"medium",context:{provider:e}});try{await r.sendText(t)}catch(n){throw n instanceof er?n:new er({code:Bs.PROTOCOL_ERROR,message:`sendText failed: ${n instanceof Error?n.message:String(n)}`,category:"network",severity:"medium",retriable:!0,context:{provider:e},originalError:n instanceof Error?n:void 0})}}static async triggerResponse(e){const t=this.getHandler(e);if(!t)throw er.providerNotSupported(e,this.registry.list());if(!t.isConnected())throw er.sessionNotActive(e);if(t.triggerResponse)try{await t.triggerResponse()}catch(r){throw r instanceof er?r:new er({code:Bs.PROTOCOL_ERROR,message:`triggerResponse failed: ${r instanceof Error?r.message:String(r)}`,category:"network",severity:"medium",retriable:!0,context:{provider:e},originalError:r instanceof Error?r:void 0})}}static async cancelResponse(e){const t=this.getHandler(e);if(!t)throw er.providerNotSupported(e,this.registry.list());if(t.isConnected()&&t.cancelResponse)try{await t.cancelResponse()}catch(r){throw r instanceof er?r:new er({code:Bs.PROTOCOL_ERROR,message:`cancelResponse failed: ${r instanceof Error?r.message:String(r)}`,category:"network",severity:"medium",retriable:!0,context:{provider:e},originalError:r instanceof Error?r:void 0})}}static getSession(e){return this.getHandler(e)?.getSession()??null}static isConnected(e){return this.getHandler(e)?.isConnected()??!1}static getSupportedFormats(e){return this.getHandler(e)?.getSupportedFormats()??[]}static clearHandlers(){for(const[e]of this.sessions){const t=this.registry.get(e);t?.isConnected()&&t.disconnect().catch(()=>{})}this.sessions.clear(),this.registry.clear(),m.debug("[RealtimeProcessor] Cleared all handlers and sessions")}},G1=class{session=null;eventHandlers=null;state="disconnected";isConnected(){return this.state==="connected"}getSession(){return this.session}on(e){this.eventHandlers=e}off(){this.eventHandlers=null}emitStateChange(e){this.state=e,this.session&&(this.session.state=e,this.session.lastActivityAt=new Date),this.eventHandlers?.onStateChange?.(e)}emitAudio(e){this.eventHandlers?.onAudio?.(e)}emitTranscript(e,t){this.eventHandlers?.onTranscript?.(e,t)}emitText(e,t){this.eventHandlers?.onText?.(e,t)}async emitFunctionCall(e,t){if(this.eventHandlers?.onFunctionCall)return this.eventHandlers.onFunctionCall(e,t)}emitError(e){this.eventHandlers?.onError?.(e)}emitTurnStart(){this.eventHandlers?.onTurnStart?.()}emitTurnEnd(){this.eventHandlers?.onTurnEnd?.()}createSession(e,t){return{id:e,state:"connected",provider:this.name,model:t.model,createdAt:new Date,lastActivityAt:new Date,config:t}}}}});function QWt(e){if(e.length<12)return null;if(e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===65&&e[10]===86&&e[11]===69)return"wav";if(e[0]===73&&e[1]===68&&e[2]===51||e[0]===255&&(e[1]&224)===224)return"mp3";if(e[0]===79&&e[1]===103&&e[2]===103&&e[3]===83){const t=e.indexOf("OpusHead");return t!==-1&&t<200?"opus":"ogg"}return null}function Oon(e){return EE[e]?.mimeType??"application/octet-stream"}function Don(e){return EE[e]?.extension??".bin"}function Non(e,t,r){const n=t??QWt(e);if(n)try{switch(n){case"wav":return Lon(e);case"mp3":return Fon(e);case"ogg":case"opus":return $on(e);default:return r?e.length/(r*2):void 0}}catch(o){m.debug(`[audio-utils] Failed to calculate duration: ${o instanceof Error?o.message:String(o)}`);return}}function Lon(e){if(e.length<44)return;let t=12;for(;t<e.length-8;){const r=e.toString("ascii",t,t+4),n=e.readUInt32LE(t+4);if(r==="fmt "){const o=e.readUInt16LE(t+10),s=e.readUInt32LE(t+12),i=e.readUInt16LE(t+22);let a=t+8+n+n%2;for(;a<e.length-8;){const c=e.toString("ascii",a,a+4),l=e.readUInt32LE(a+4);if(c==="data"){const u=i/8*o;return l/u/s}a+=8+l+l%2}}t+=8+n+n%2}}function Fon(e){let t=0;for(e[0]===73&&e[1]===68&&e[2]===51&&(t=10+((e[6]&127)<<21|(e[7]&127)<<14|(e[8]&127)<<7|e[9]&127));t<e.length-4;){if(e[t]===255&&(e[t+1]&224)===224){const r=e[t+1]>>3&3,n=e[t+1]>>1&3,o=e[t+2]>>4&15,s=e[t+2]>>2&3,a={3:[44100,48e3,32e3],2:[22050,24e3,16e3],0:[11025,12e3,8e3]}[r]?.[s],l=[0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0][o];if(a&&l)return(e.length-t)*8/(l*1e3);break}t++}return e.length*8/128e3}function $on(e){return e.length*8/64e3}async function Uon(e,t,r,n={}){if(t===r)return e;throw m.warn(`[audio-utils] Audio format conversion from ${t} to ${r} is not implemented.`),new Error(`Audio format conversion from ${t} to ${r} is not implemented. Convert with ffmpeg before passing to NeuroLink.`)}function Bon(e,t=16e3,r=16){const n=r/8,o=Buffer.alloc(e.length*n);for(let s=0;s<e.length;s++){const i=Math.max(-1,Math.min(1,e[s])),a=s*n;switch(r){case 8:o.writeUInt8(Math.round((i+1)*127.5),a);break;case 16:o.writeInt16LE(Math.round(i*32767),a);break;case 24:{const c=Math.round(i*8388607);o.writeUInt8(c&255,a),o.writeUInt8(c>>8&255,a+1),o.writeUInt8(c>>16&255,a+2);break}case 32:o.writeInt32LE(Math.round(i*2147483647),a);break}}return o}function zon(e,t=16){const r=t/8,n=Math.floor(e.length/r),o=[];for(let s=0;s<n;s++){const i=s*r;switch(t){case 8:o.push(e.readUInt8(i)/127.5-1);break;case 16:o.push(e.readInt16LE(i)/32767);break;case 24:{const a=e.readUInt8(i)|e.readUInt8(i+1)<<8|e.readUInt8(i+2)<<16;o.push((a>8388607?a-16777216:a)/8388607);break}case 32:o.push(e.readInt32LE(i)/2147483647);break}}return o}function Gon(e,t,r){if(t<=0||r<=0||t===r)return e;const n=t/r,o=Math.round(e.length/n),s=[];for(let i=0;i<o;i++){const a=i*n,c=Math.floor(a),l=Math.min(c+1,e.length-1),u=a-c,d=e[c]*(1-u)+e[l]*u;s.push(d)}return s}function qon(e,t=.95){if(e.length===0)return e;let r=0;for(const o of e)r=Math.max(r,Math.abs(o));if(r===0)return e;const n=t/r;return e.map(o=>o*n)}function eKt(e,t=16e3,r=1,n=16){const o=Buffer.alloc(44),s=t*r*(n/8),i=r*(n/8);return o.write("RIFF",0),o.writeUInt32LE(36+e,4),o.write("WAVE",8),o.write("fmt ",12),o.writeUInt32LE(16,16),o.writeUInt16LE(1,20),o.writeUInt16LE(r,22),o.writeUInt32LE(t,24),o.writeUInt32LE(s,28),o.writeUInt16LE(i,32),o.writeUInt16LE(n,34),o.write("data",36),o.writeUInt32LE(e,40),o}function Von(e,t=16e3,r=1,n=16){const o=eKt(e.length,t,r,n);return Buffer.concat([o,e])}function jon(e,t,r=16e3,n=2){if(t<=0||r<=0||n<=0)return[e];const o=r*n/1e3,s=Math.round(t*o);if(s<=0)return[e];const i=[];for(let a=0;a<e.length;a+=s){const c=Math.min(a+s,e.length);i.push(e.subarray(a,c))}return i}var tKt,rKt,Hon=S({"src/lib/voice/audio-utils.ts"(){"use strict";dt(),z(),tKt={wav:Buffer.from([82,73,70,70]),mp3:{id3:Buffer.from([73,68,51]),frameSync:Buffer.from([255,224])},ogg:Buffer.from([79,103,103,83])},rKt={wav:"audio/wav",mp3:"audio/mpeg",ogg:"audio/ogg",opus:"audio/opus"}}});function Won(e){return{[Symbol.asyncIterator](){const t=[];let r=null,n=null,o=!1,s=null;const i=u=>{r?(r({value:u,done:!1}),r=null,n=null):t.push(u)},a=()=>{o=!0,r&&(r({value:void 0,done:!0}),r=null,n=null)},c=u=>{s=u,n&&(n(u),r=null,n=null)};e.on("chunk",i),e.on("end",a),e.on("error",c);const l=()=>{e.off("chunk",i),e.off("end",a),e.off("error",c)};return{async next(){if(s)throw s;if(t.length>0){const u=t.shift();if(u!==void 0)return{value:u,done:!1}}return o?{value:void 0,done:!0}:new Promise((u,d)=>{r=u,n=d})},async return(){return l(),o=!0,{value:void 0,done:!0}}}}}}async function Kon(e,t={}){const r=new tT(t);return(async()=>{try{for await(const n of e)r.write(n)||await new Promise(s=>r.once("drain",s));r.end()}catch(n){r.emit("error",n instanceof Error?n:new Error(String(n)))}})(),r}var Iae,tT,nKt,oKt,Jon=S({"src/lib/voice/stream-handler.ts"(){"use strict";Dn(),z(),Iae={chunkDurationMs:100,sampleRate:16e3,bytesPerSample:2,format:"wav",highWaterMark:64*1024,bufferTimeoutMs:5e3},tT=class extends Yr{config;chunkSize;buffer;chunkIndex;timestampMs;isPaused;isEnded;pendingData;bufferTimeout;constructor(e={}){if(super(),this.config={...Iae,...e},this.config.sampleRate<=0)throw new Error("Invalid stream configuration: sampleRate must be positive");if(this.config.bytesPerSample<=0)throw new Error("Invalid stream configuration: bytesPerSample must be positive");const t=this.config.sampleRate*this.config.bytesPerSample/1e3;if(this.chunkSize=Math.round(this.config.chunkDurationMs*t),this.chunkSize<=0)throw new Error("Invalid stream configuration: chunkSize must be positive (check chunkDurationMs, sampleRate, bytesPerSample)");this.buffer=Buffer.alloc(0),this.chunkIndex=0,this.timestampMs=0,this.isPaused=!1,this.isEnded=!1,this.pendingData=[],this.bufferTimeout=null}write(e){if(this.isEnded)throw new Error("Cannot write to ended stream");return this.buffer.length+e.length>this.config.highWaterMark?(this.isPaused||(this.isPaused=!0,this.emit("pause")),this.pendingData.push(e),!1):(this.processData(e),!0)}processData(e){for(this.buffer=Buffer.concat([this.buffer,e]),this.resetBufferTimeout();this.buffer.length>=this.chunkSize;){const t=this.buffer.subarray(0,this.chunkSize);this.buffer=this.buffer.subarray(this.chunkSize);const r={data:t,index:this.chunkIndex++,isFinal:!1,format:this.config.format,sampleRate:this.config.sampleRate,timestampMs:this.timestampMs,durationMs:this.config.chunkDurationMs};this.timestampMs+=this.config.chunkDurationMs,this.emit("chunk",r)}if(this.isPaused&&this.buffer.length<this.config.highWaterMark/2)for(this.isPaused=!1,this.emit("resume"),this.emit("drain");this.pendingData.length>0&&!this.isPaused;){const t=this.pendingData.shift();if(t===void 0||!this.write(t))break}}end(){if(!this.isEnded){this.isEnded=!0,this.clearBufferTimeout();for(const e of this.pendingData)this.buffer=Buffer.concat([this.buffer,e]);if(this.pendingData=[],this.buffer.length>0){const e=this.buffer.length/this.config.bytesPerSample/this.config.sampleRate*1e3,t={data:this.buffer,index:this.chunkIndex++,isFinal:!0,format:this.config.format,sampleRate:this.config.sampleRate,timestampMs:this.timestampMs,durationMs:e};this.emit("chunk",t)}else{const e={data:Buffer.alloc(0),index:this.chunkIndex,isFinal:!0,format:this.config.format,sampleRate:this.config.sampleRate,timestampMs:this.timestampMs,durationMs:0};this.emit("chunk",e)}this.emit("end"),this.cleanup()}}resetBufferTimeout(){this.clearBufferTimeout(),this.bufferTimeout=setTimeout(()=>{this.buffer.length>0&&!this.isEnded&&(m.warn(`[ChunkedAudioStream] Buffer timeout, forcing flush of ${this.buffer.length} bytes`),this.end())},this.config.bufferTimeoutMs)}clearBufferTimeout(){this.bufferTimeout&&(clearTimeout(this.bufferTimeout),this.bufferTimeout=null)}cleanup(){this.clearBufferTimeout(),this.buffer=Buffer.alloc(0),this.pendingData=[]}getStats(){return{chunksEmitted:this.chunkIndex,bufferedBytes:this.buffer.length,pendingChunks:this.pendingData.length,totalDurationMs:this.timestampMs,isPaused:this.isPaused,isEnded:this.isEnded}}},nKt=class extends Yr{streams;config;constructor(e={}){super(),this.streams=new Map,this.config={...Iae,...e}}addStream(e){if(this.streams.has(e))throw new Error(`Stream ${e} already exists`);const t=new tT(this.config);return t.on("chunk",r=>{this.emit("chunk",{id:e,chunk:r})}),t.on("end",()=>{this.emit("streamEnd",e),this.streams.delete(e),this.streams.size===0&&this.emit("end")}),t.on("error",r=>{this.emit("error",{id:e,error:r})}),this.streams.set(e,t),t}removeStream(e){const t=this.streams.get(e);t&&(t.end(),this.streams.delete(e))}write(e,t){const r=this.streams.get(e);if(!r)throw new Error(`Stream ${e} not found`);return r.write(t)}endAll(){for(const e of this.streams.values())e.end()}get activeStreams(){return this.streams.size}},oKt=class extends Yr{consumers;input;constructor(e={}){super(),this.consumers=new Map,this.input=new tT(e),this.input.on("chunk",t=>{for(const[r,n]of this.consumers)try{n(t)}catch(o){this.emit("error",{consumerId:r,error:o instanceof Error?o:new Error(String(o))})}}),this.input.on("end",()=>{this.emit("end")}),this.input.on("error",t=>{this.emit("error",{error:t})})}write(e){return this.input.write(e)}end(){this.input.end()}addConsumer(e,t){if(this.consumers.has(e))throw new Error(`Consumer ${e} already exists`);this.consumers.set(e,t)}removeConsumer(e){this.consumers.delete(e)}get consumerCount(){return this.consumers.size}}}}),rT,sKt=S({"src/lib/voice/providers/AzureTTS.ts"(){"use strict";z(),_c(),rT=class zTr{apiKey;region;voicesCache=null;static CACHE_TTL_MS=1800*1e3;maxTextLength=1e4;constructor(t,r){const n=(t??process.env.AZURE_SPEECH_KEY??"").trim();this.apiKey=n.length>0?n:null;const o=(r??process.env.AZURE_SPEECH_REGION??"").trim();this.region=o.length>0?o:"eastus"}isConfigured(){return this.apiKey!==null&&this.region.length>0}async getVoices(t){if(!this.apiKey)throw new Et({code:At.PROVIDER_NOT_CONFIGURED,message:"Azure Speech key not configured",category:"configuration",severity:"high",retriable:!1});if(this.voicesCache&&Date.now()-this.voicesCache.timestamp<zTr.CACHE_TTL_MS&&!t)return this.voicesCache.voices;try{const r=new AbortController,n=setTimeout(()=>r.abort(),3e4);let o;try{o=await fetch(`https://${this.region}.tts.speech.microsoft.com/cognitiveservices/voices/list`,{method:"GET",headers:{"Ocp-Apim-Subscription-Key":this.apiKey},signal:r.signal})}catch(a){throw a instanceof Error&&a.name==="AbortError"?new Et({code:At.SYNTHESIS_FAILED,message:"Azure TTS voices request timed out after 30 seconds",category:"network",severity:"medium",retriable:!0,originalError:a}):a}finally{clearTimeout(n)}if(!o.ok)throw new Error(`HTTP ${o.status}`);let i=(await o.json()).map(a=>({id:a.ShortName,name:a.DisplayName,languageCode:a.Locale,languageCodes:[a.Locale],gender:this.mapGender(a.Gender),type:a.VoiceType.toLowerCase().includes("neural")?"neural":"standard",description:a.LocaleName}));return t&&(i=i.filter(a=>a.languageCode.toLowerCase().startsWith(t.toLowerCase())||a.languageCode.toLowerCase()===t.toLowerCase())),t||(this.voicesCache={voices:i,timestamp:Date.now()}),i}catch(r){if(r instanceof Et)throw r;const n=r instanceof Error?r.message:String(r||"Unknown error");throw m.error(`[AzureTTSHandler] Failed to get voices: ${n}`),new Et({code:At.SYNTHESIS_FAILED,message:`Failed to get voices: ${n}`,category:"network",severity:"medium",retriable:!0,originalError:r instanceof Error?r:void 0})}}async synthesize(t,r={}){if(!this.apiKey)throw new Et({code:At.PROVIDER_NOT_CONFIGURED,message:"Azure Speech key not configured",category:"configuration",severity:"high",retriable:!1});const n=Date.now(),o=r;try{const s=r.voice??"en-US-JennyNeural",i=o.outputFormat??this.mapFormat(r.format??"mp3"),a=this.buildSSML(t,s,r),c=new AbortController,l=setTimeout(()=>c.abort(),3e4);let u;try{u=await fetch(`https://${this.region}.tts.speech.microsoft.com/cognitiveservices/v1`,{method:"POST",headers:{"Ocp-Apim-Subscription-Key":this.apiKey,"Content-Type":"application/ssml+xml","X-Microsoft-OutputFormat":i},body:a,signal:c.signal})}catch(g){throw g instanceof Error&&g.name==="AbortError"?new Et({code:At.SYNTHESIS_FAILED,message:"Azure TTS request timed out after 30 seconds",category:"network",severity:"high",retriable:!0,originalError:g}):g}finally{clearTimeout(l)}if(!u.ok){const g=await u.text();throw new Error(`HTTP ${u.status}: ${g}`)}const d=Date.now()-n,p=await u.arrayBuffer(),h=Buffer.from(p),f={buffer:h,format:this.effectiveFormat(i),size:h.length,voice:s,sampleRate:this.getSampleRate(i),metadata:{latency:d,provider:"azure-tts",requestedFormat:r.format,outputFormat:i,region:this.region}};return m.info(`[AzureTTSHandler] Synthesized ${h.length} bytes in ${d}ms`),f}catch(s){if(s instanceof Et)throw s;const i=s instanceof Error?s.message:String(s||"Unknown error");throw m.error(`[AzureTTSHandler] Synthesis failed: ${i}`),new Et({code:At.SYNTHESIS_FAILED,message:`Synthesis failed: ${i}`,category:"execution",severity:"high",retriable:!0,context:{textLength:t.length},originalError:s instanceof Error?s:void 0})}}buildSSML(t,r,n){const o=n;if(o.ssmlTemplate)return o.ssmlTemplate.replace("{text}",this.escapeXml(t)).replace("{voice}",this.escapeXml(r));if(o.allowRawSSML&&t.trim().startsWith("<speak"))return t;const s=n.speed?`${Math.round((n.speed-1)*100)}%`:"0%",i=n.pitch??0,a=i>=0?`+${Math.round(i)}st`:`${Math.round(i)}st`;return`<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="${this.escapeXml(this.extractLanguage(r))}">
|
|
2158
2158
|
<voice name="${this.escapeXml(r)}">
|
|
2159
2159
|
<prosody rate="${s}" pitch="${a}">
|
|
2160
2160
|
${this.escapeXml(t)}
|
|
@@ -579,9 +579,9 @@ const HAND_DESCRIPTORS = [
|
|
|
579
579
|
// `timeoutMs`.
|
|
580
580
|
timeouts: { decideMs: 10_000 },
|
|
581
581
|
// The server reads 262,144 input tokens in all and answers an over-long
|
|
582
|
-
// request with an explicit 400, never a silent truncation. The state
|
|
583
|
-
// questions were measured to count toward it
|
|
584
|
-
//
|
|
582
|
+
// request with an explicit 400, never a silent truncation. The state, the
|
|
583
|
+
// questions and the images were all measured to count toward it, an image at
|
|
584
|
+
// one token for each 32 x 32 tile. The window below is deliberately lower: a
|
|
585
585
|
// state of 100,000 tokens takes about 7s of the 10s above (interpolated from
|
|
586
586
|
// those points), and a much larger one would outlast it and be retried into
|
|
587
587
|
// the same wait. The estimate is about four characters per token. Measured
|
|
@@ -70,8 +70,14 @@ function isPerplexityApiHost(baseURL) {
|
|
|
70
70
|
* The model server answers input past its limit with a 400, not the 413 the
|
|
71
71
|
* gateway documents, so the kind comes from the text. `error.code` cannot be
|
|
72
72
|
* used: it is a string, a number or null depending on which layer answered.
|
|
73
|
+
*
|
|
74
|
+
* The wording depends on what was sent. Text alone is refused with "Input
|
|
75
|
+
* length (262144) exceeds or equals model's maximum context length (262144)",
|
|
76
|
+
* the figure in brackets being the limit and not the size sent; a request with
|
|
77
|
+
* images is refused with "Total input tokens (A text + B vision = C) exceeds
|
|
78
|
+
* maximum context length (262144)". Both are matched.
|
|
73
79
|
*/
|
|
74
|
-
const OVER_LENGTH_MESSAGE = /exceeds or equals model's maximum context length/i;
|
|
80
|
+
const OVER_LENGTH_MESSAGE = /exceeds(?: or equals)?(?: model's)? maximum context length/i;
|
|
75
81
|
/**
|
|
76
82
|
* Only 401 is `authentication`, and so only 401 trips the breaker. Every other
|
|
77
83
|
* 4xx is something the caller or an account owner can fix without restarting
|
|
@@ -3369,7 +3369,7 @@
|
|
|
3369
3369
|
{"objectID":"ac97e63916f0ffdf1d9befada357186f236753d40ea1f0e97bcab715e54fa7cd","title":"Relevance-driven compaction","url":"/docs/features/decide-inference-type#relevance-driven-compaction","content":"Before the existing positional compaction stages run, an optional Stage 0\nasks, per eligible message, whether the current request still needs it — at\n~400 ms for the whole batch regardless of message count (on TypeSafe;\nperplexity-decider differs, taking about 0.3 to 1.1 s for one question and about\n65 ms for each further one, plus an input time that grows faster than linearly\nwith size).\nOnly plain user/assistant text is eligible, the most recent messages are never\ntouched, and a message is dropped only on a confident \"no.\"\n\n| | Positional stages (1–4) | Stage 0 (relevance) |\n| ----------------- | ---------------------------------- | ------------------------------------------------------------ |\n| Basis for keeping | position (recency) | relevance to the current request |\n| Drop granularity | whole messages / summarized ranges | whole messages |\n| Runs when | always, once over budget | decision provider configured, request known, and over budget |\n\nSee relevance-driven compaction for\nthe eligibility rules, the drop cap, and the separate summary-quality gate on\nStage 3.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Relevance-driven compaction","lvl3":""}},
|
|
3370
3370
|
{"objectID":"451d199b91f25696bed61dedb5ebc0465143dbf3bc350ca8a3943e622f9aedf8","title":"Tool / MCP routing","url":"/docs/features/decide-inference-type#tool-mcp-routing","content":"The shipped tool router asks a generative model for {servers: string[]} on\na 15-second budget — a shape that cannot express uncertainty. A decision\nmodel instead asks one yes/no question per server, answered with a probability,\nand a server is excluded only on a confident \"no\" (minDropConfidence default\n0.6), because dropping a needed server breaks the turn while keeping an unneeded\none only costs a few tokens.\n\nA measured wording change moved unrelated servers from a mean probability of\n0.31 (dropping 12 of 39 unneeded servers) to a mean of 0.03 (dropping 37 of\n39, with zero wrong drops) — seen in\ntool / MCP routing by decision model,\nwhich also covers the exact question shape and its size guards.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Tool / MCP routing","lvl3":""}},
|
|
3371
3371
|
{"objectID":"b35e1ab2390a7b132037c293ecaf436f9ff9498591ccdd47b58ee0a6a95e7616","title":"RAG retrieval planning","url":"/docs/features/decide-inference-type#rag-retrieval-planning","content":"RAGPipelineConfig.decide lets each RAG query get its own topK/hybrid/\ngraph/rerank plan instead of one fixed configuration for every query. An\nexplicit per-call QueryOptions field always wins over the plan, and a\ncapability the pipeline wasn't configured with can never be switched on by\nit.\n\nSee per-query RAG retrieval planning\nfor the breadth rubric and why its confidence bar is deliberately lower than\ntool routing's or compaction's.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"RAG retrieval planning","lvl3":""}},
|
|
3372
|
-
{"objectID":"6c0dd418b9f61219911960f90d1003a6c00c2e2cb81399ced3c885fd8209bc6e","title":"Limits and gotchas","url":"/docs/features/decide-inference-type#limits-and-gotchas","content":"Laya reads far less than Jev. About 768 tokens of state on\ntyped-decisions and multilingual, and 320 on english, auto or an\nunrecognised model name, against Jev's ~33,000. Laya's server does not refuse a\nlonger state; it answers from the first 1,024 tokens (512 on english). So the\nprovider estimates the state's size — counting non-Latin characters at a rate\nmeasured per checkpoint — and refuses anything over the limit locally with\nmax_tokens_exceeded, before any network call. The estimate errs toward\nrefusing.\n\nXOR shares one prefill between the state, the questions and any media.\nNeuroLink allows about 200,000 estimated tokens of state (about four characters\nper token for ASCII, one token per character for other scripts) and refuses more\nlocally with max_tokens_exceeded. That figure is a conservative default under\nthe deployment's 250,000-token prefill, which the questions and any images or\nvideo also draw on; it has not been measured against a live deployment. A\nrequest that passes the local check can therefore still be refused by the\nserver as too long. That arrives as max_tokens_exceeded (not retried) when\nthe status is 413 or the message says the context was too long, and otherwise as\nserver, retried once. XOR has no question cap in NeuroLink, and its server takes 2 to 255\noptions on a choice or score.\n\nPerplexity's input ceiling covers more than the state. Measured on a real\naccount in October 2026: the server reads under 262,144 input tokens per request,\ncounted over the state and the
|
|
3372
|
+
{"objectID":"6c0dd418b9f61219911960f90d1003a6c00c2e2cb81399ced3c885fd8209bc6e","title":"Limits and gotchas","url":"/docs/features/decide-inference-type#limits-and-gotchas","content":"Laya reads far less than Jev. About 768 tokens of state on\ntyped-decisions and multilingual, and 320 on english, auto or an\nunrecognised model name, against Jev's ~33,000. Laya's server does not refuse a\nlonger state; it answers from the first 1,024 tokens (512 on english). So the\nprovider estimates the state's size — counting non-Latin characters at a rate\nmeasured per checkpoint — and refuses anything over the limit locally with\nmax_tokens_exceeded, before any network call. The estimate errs toward\nrefusing.\n\nXOR shares one prefill between the state, the questions and any media.\nNeuroLink allows about 200,000 estimated tokens of state (about four characters\nper token for ASCII, one token per character for other scripts) and refuses more\nlocally with max_tokens_exceeded. That figure is a conservative default under\nthe deployment's 250,000-token prefill, which the questions and any images or\nvideo also draw on; it has not been measured against a live deployment. A\nrequest that passes the local check can therefore still be refused by the\nserver as too long. That arrives as max_tokens_exceeded (not retried) when\nthe status is 413 or the message says the context was too long, and otherwise as\nserver, retried once. XOR has no question cap in NeuroLink, and its server takes 2 to 255\noptions on a choice or score.\n\nPerplexity's input ceiling covers more than the state. Measured on a real\naccount in October 2026: the server reads under 262,144 input tokens per request,\ncounted over the state, the questions and the images, and refuses input of\n262,144 tokens or more with an explicit 400 instead of cutting the state off.\nImages are billed as input tokens, about one for each 32 × 32 tile plus 95 to\n103 more in the single-image requests measured, which looks like fixed request\noverhead and not a charge per image. They count toward the ceiling at one token\nfor each tile: eight 2,048-tile images added 16,384 to a request that was then\nrefused. It takes at most 128 questions and 8","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Limits and gotchas","lvl3":""}},
|
|
3373
3373
|
{"objectID":"f6543a204326fbf7f27ac5c61c2f10b76f0541f3acb61eec93291921404e1a37","title":"What it is bad at","url":"/docs/features/decide-inference-type#what-it-is-bad-at","content":"\"Cannot hallucinate\" is a claim about output shape, not answer\ncorrectness: a decision model cannot return malformed JSON or an option you\ndid not offer, but it can still be wrong. TypeSafe reports ~68% accuracy on its\nown 711-case benchmark, against ~73% for a frontier model. It wins cost and\nlatency on every row and loses accuracy on every row — so it is right for\ndecisions that are gated and reversible, and wrong for final answers.\nIt reads literally. It answers the question you wrote, not the one you\n meant. Split an ambiguous question into two and combine them in code.\nAsk about the act, not the subject. \"This task touches money\" scores high\n on ordinary code that merely concerns money. The risk question in\n classifyJev is worded to exclude writing and testing such code, precisely\n because the naive phrasing escalated everything.\nIt is not a calculator. Counting, arithmetic and date comparison are\n unreliable — dates are read as text, not ordered quantities. A score is for\n thresholding and ranking, not for reading an exact magnitude off.\nIrrelevant state costs accuracy. Filter before sending.\nIt never explains itself. No rationale field exists, which rules it out\n where a decision must be auditable.\nOption order can matter. Test with reordered criteria if a call is close.\nDon't invert criteria. A boolean whose true description means \"no\"\n performs measurably worse.\n\nTune thresholds on your own labelled data if the decision matters, and once you\nhave, pin TYPESAFE_MODEL to a version id such as jev-1.13.0 — jev-latest\nis an alias and can move under you, invalidating a tuned threshold silently.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"What it is bad at","lvl3":""}},
|
|
3374
3374
|
{"objectID":"f51228c123e6f86e1889f9990b2592debd24cc90c1584ad7d35d1f9a7aac8b82","title":"Adding another decision provider","url":"/docs/features/decide-inference-type#adding-another-decision-provider","content":"The decide inference type is provider-neutral by construction. Another\ndecision model needs:\nAn AIProviderName member and a <Name>Models enum\n (src/lib/constants/enums.ts, outside the generated regions).\nA provider class extending SystemOneDecisionProvider\n (src/lib/providers/systemOneDecision.ts), which owns the request loop,\n retries, the auth circuit breaker and answer parsing, and supplies the\n throwing getAISDKModel() / executeStream() stubs, the same shape the\n embedding-only providers (voyage.ts, jina.ts) use. The class supplies\n its endpoint, headers, body, error parsing and messages.\nA descriptor with inferenceKinds: [\"decide\"], no auto-select ranks, and\n healthCheck: \"env-only\". That one field is what keeps a text-less model out\n of every generation fallback chain; nothing else needs to know the provider\n by name. A provider that reads images or video also declares\n decisionLimits.media; without it, a request that carries media is refused\n before any network call.\nA registration block, a credentials slice, a manifest, and the usual Tier-3\n onboarding artifacts — pnpm run verify:provider-onboarding enumerates them.\n\nThe Tier-2 catalog JSON path cannot be used: its schema pins tier: 2, accepts\nonly an 8-flag text-generation capability vocabulary, and requires\ndefaultMaxOutputTokens and pricingPerMTok.output — none of which a model\nthat emits no text can honestly supply.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Adding another decision provider","lvl3":""}},
|
|
3375
3375
|
{"objectID":"31d00aee561a454dc5082ad8002f9dbc0e33f15463cfee1636497043c8f9ee55","title":"Testing","url":"/docs/features/decide-inference-type#testing","content":"The suite drives dist/index.js only. Live tests skip without\nTYPESAFE_API_KEY; the degradation and discriminator tests run unconditionally,\nbecause \"behaves correctly with no key\" and \"a text-less provider is unreachable\nfrom generation\" are the contracts that matter most.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Testing","lvl3":""}},
|
|
@@ -6873,24 +6873,24 @@
|
|
|
6873
6873
|
{"objectID":"106d04b8baec018f872ce608c3b0dd33f8b3d43ada85072831a2e9ab9c64c46b","title":"Verification status","url":"/docs/getting-started/providers/pareto-inference#verification-status","content":"Tier-2 onboarding requires evidence before a provider is accepted, and\npnpm run verify:provider-onboarding gates it in CI. This is what the\ncatalog records for Pareto Inference — and, just as importantly, what it\ndoes not yet record:\n\n| Probe | Result |\n| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Roster | unauthenticated GET /v1/models, HTTP 200, 1 model (z-ai/glm-5.3-flash), 2026-09-28. No API key was used or required for this call. |\n| Auth rejection | Not probed. Would require a POST with an invalid key, which this credential-free onboarding pass does not send. Pareto's docs describe 401 as \"the chat API key is missing, invalid, or no longer active,\" with no example error body. |\n| Live capability sweep | Not run. evidence.liveMatrix is null. capabilities.tools and .thinking are set from the v","hierarchy":{"lvl0":"Getting Started","lvl1":"Pareto Inference Provider Guide","lvl2":"Verification status","lvl3":""}},
|
|
6874
6874
|
{"objectID":"b844edaf09c93fb3089bbf0a71254c5039dedf111e2b59563321484496862aa4","title":"Troubleshooting","url":"/docs/getting-started/providers/pareto-inference#troubleshooting","content":"| Symptom | Cause | Fix |\n| --------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |\n| Invalid Pareto Inference API key | PARETO_INFERENCE_API_KEY unset, wrong, or expired | Pareto documents 401 as \"the chat API key is missing, invalid, or no longer active\" — check or replace the key in the dashboard |\n| 429 with credit_exhausted | Prepaid balance is empty | Buy more prepaid credits |\n| 429 with credit_insufficient | Held credits (reserved for max_tokens) are below what's needed | Lower max_tokens, or buy more credits |\n| 429 with model_capacity | The model itself is at capacity — not an account-level limit | Honor the Retry-After header and retry |\n| 502 mid-stream | The model request failed after the stream started | Retry the request; check whether a tool call already ran before retrying |\n| 503 | Temporary Pareto-side failure (e.g. maintenance, GPU outage) | Wait and retry; Retry-After gives the delay in seconds |\n| No context-window figure in the catalog | Pareto does no","hierarchy":{"lvl0":"Getting Started","lvl1":"Pareto Inference Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
|
|
6875
6875
|
{"objectID":"57b8457eff592f229d3c0f0fb7c73148341ecffd72bb29c15d73f1471b1fd886","title":"See also","url":"/docs/getting-started/providers/pareto-inference#see-also","content":"Provider setup overview\nAll providers\nTier-2 onboarding — how this provider's JSON becomes a working integration\nProvider feature compatibility","hierarchy":{"lvl0":"Getting Started","lvl1":"Pareto Inference Provider Guide","lvl2":"See also","lvl3":""}},
|
|
6876
|
-
{"objectID":"daf00919862e4bbed4b3fc1082bea17843a987e5e3970cefed2c95537b22cceb","title":"Perplexity Decisions Provider Guide","url":"/docs/getting-started/providers/perplexity-decider","content":"Perplexity Decisions Provider Guide\n\nA provider of decide — the same typed boolean / choice / score\nanswers as TypeSafe's Jev, Laya and XOR,\nfrom Perplexity's hosted Decisions API, and it also reads images. It emits no\ntext at all.\n\nThis is not the Perplexity text provider (perplexity, the\nSonar models), which serves generate() and stream(). The two share one API\nkey, which has a consequence worth reading before you set it. See\nWhat is sent to Perplexity and\nOne key, two providers.\n\nOverview\n\npplx-decider-v1-27b is Perplexity's decision model. You send one state\nplus named, typed questions, and optionally images. The model answers every\nquestion in a single batched pass and returns a typed answer for each, with a\nprobability instead of a sentence. NeuroLink calls Perplexity's public endpoint,\nso a key alone configures it: there is no base URL to set.\n\nKey Facts\n\n| | |\n| ------------------------ | ----------------------------------------------------------------------------------------------------------------- |\n| Provider id | perplexity-decider (no aliases) — distinct from perplexity, the Sonar text provider |\n| Inference type | decide only |\n| Model | pplx-decider-v1-27b; the API answers 400 to a missing or unknown model. PERPLEXITY_DECIDER_MODEL sets it |\n| Key | PERPLEXITY_API_KEY, shared with the Perplexity text provider, or credentials.perplexityDecider.apiKey |\n| Endpoint | https://api.perplexity.ai/v1/decisions; PERPLEXITY_DECIDER_BASE_URL can name another origin |\n| Media | images (PNG, JPEG or WebP), up to 8 per request; no video |\n| Questions per request | up to 128 |\n| Server input ceiling | under 262,144 tokens (state and
|
|
6876
|
+
{"objectID":"daf00919862e4bbed4b3fc1082bea17843a987e5e3970cefed2c95537b22cceb","title":"Perplexity Decisions Provider Guide","url":"/docs/getting-started/providers/perplexity-decider","content":"Perplexity Decisions Provider Guide\n\nA provider of decide — the same typed boolean / choice / score\nanswers as TypeSafe's Jev, Laya and XOR,\nfrom Perplexity's hosted Decisions API, and it also reads images. It emits no\ntext at all.\n\nThis is not the Perplexity text provider (perplexity, the\nSonar models), which serves generate() and stream(). The two share one API\nkey, which has a consequence worth reading before you set it. See\nWhat is sent to Perplexity and\nOne key, two providers.\n\nOverview\n\npplx-decider-v1-27b is Perplexity's decision model. You send one state\nplus named, typed questions, and optionally images. The model answers every\nquestion in a single batched pass and returns a typed answer for each, with a\nprobability instead of a sentence. NeuroLink calls Perplexity's public endpoint,\nso a key alone configures it: there is no base URL to set.\n\nKey Facts\n\n| | |\n| ------------------------ | ----------------------------------------------------------------------------------------------------------------- |\n| Provider id | perplexity-decider (no aliases) — distinct from perplexity, the Sonar text provider |\n| Inference type | decide only |\n| Model | pplx-decider-v1-27b; the API answers 400 to a missing or unknown model. PERPLEXITY_DECIDER_MODEL sets it |\n| Key | PERPLEXITY_API_KEY, shared with the Perplexity text provider, or credentials.perplexityDecider.apiKey |\n| Endpoint | https://api.perplexity.ai/v1/decisions; PERPLEXITY_DECIDER_BASE_URL can name another origin |\n| Media | images (PNG, JPEG or WebP), up to 8 per request; no video |\n| Questions per request | up to 128 |\n| Server input ceiling | under 262,144 tokens (state, questions and images); more is refused with an explicit 400, never cut off silently |\n| Images and that ceiling | billed as input tokens, and counted toward the ceiling at one token per 32 × 32 tile (measured) |\n| NeuroLink's state window | 100,000 estimated tokens: a deliberate local limit, not the server's |\n| Cost | $0.04 per million input tokens (image tokens included); output tokens are free. Perplexity's documented price |\n| Default timeout | 10 seconds plus 100 ms for each question (10.1 s for one, 22.8 s for 128); timeoutMs or --timeout replaces it |\n| Precedence | used automatically when TypeSafe, Laya and XOR are not configured |\n\nEach limit, token rate and latency in this guide is either measured on a real\naccount in October 2026 or taken from Perplexity's documentation, and says\nwhich where it appears. Measured: the 128-question and 8-image caps, the\n262,144-token input ceiling for the state, the questions and the images (nothing\nis cut off silently), characters per token for each kind of text, latency by\ninput size and by question count, what an image costs, which image sizes stall\n(the 2,048-tile rule, checked at its edge: see Images), and how the\nAPI answers a burst of requests. Documented and not tested: the 32 MiB request\nbody, the price, and the option and level counts. Perplexity documents a limit of\n10 requests per second for the account's tier (every organization, on every\nplan, with a token limit on large bursts), and a burst test on the one account\ntested saw the request limit act.\n\nQuick Start\nGet a key\n\nCreate one in the Perplexity console. Any\nPerplexity API key works.\nConfigure\n\nSet the key in the environment:\n\nor in the config passed to the SDK, exactly as for any other provider. Values\npassed per call override the constructor's, which override the environment:\n\ncredentials.perplexityDecider is its own slice. A key passed as\ncredentials.perplexity belongs to the text provider and does not configure\nthis one. PERPLEXITY_BASE_URL, which moves the text provider, is not read here;\nthe override for this provider is PERPLEXITY_DECIDER_BASE_URL, and a trailing\n/v1 on it is accepted.\nUse it\n\nNeuroLink's boolean question is sent to the API as its noul type, and the\nanswer is read back as a boolean. A boolean answer carries a probability and\nno confidence of its own; a choice or score answer carries the confidence the\nAPI reports, which Perplexity describes as the model's own certainty estimate,\nnot the top probability. Perplexity's API reference and quickstart do not call\nthat confidence calibrated, and NeuroLink did not measure whether it is, so tune\na t","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"","lvl3":""}},
|
|
6877
6877
|
{"objectID":"cd579839c9ecb7a84dee24ccd591e76f90eb1f05b384a35488c7603f72178d38","title":"Perplexity Decisions Provider Guide","url":"/docs/getting-started/providers/perplexity-decider#perplexity-decisions-provider-guide","content":"A provider of decide — the same typed boolean / choice / score\nanswers as TypeSafe's Jev, Laya and XOR,\nfrom Perplexity's hosted Decisions API, and it also reads images. It emits no\ntext at all.\n\nThis is not the Perplexity text provider (perplexity, the\nSonar models), which serves generate() and stream(). The two share one API\nkey, which has a consequence worth reading before you set it. See\nWhat is sent to Perplexity and\nOne key, two providers.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Perplexity Decisions Provider Guide","lvl3":""}},
|
|
6878
6878
|
{"objectID":"0d2eec9390e1cc5078e5419138c190cc8dc524c5ebd8972a9c7afa9625dae43a","title":"Overview","url":"/docs/getting-started/providers/perplexity-decider#overview","content":"pplx-decider-v1-27b is Perplexity's decision model. You send one state\nplus named, typed questions, and optionally images. The model answers every\nquestion in a single batched pass and returns a typed answer for each, with a\nprobability instead of a sentence. NeuroLink calls Perplexity's public endpoint,\nso a key alone configures it: there is no base URL to set.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Overview","lvl3":""}},
|
|
6879
|
-
{"objectID":"c9690ba724ce4205d66ac4d75981884b735170b152767047afcc0d406d5e7c8d","title":"Key Facts","url":"/docs/getting-started/providers/perplexity-decider#key-facts","content":"| | |\n| ------------------------ | ----------------------------------------------------------------------------------------------------------------- |\n| Provider id | perplexity-decider (no aliases) — distinct from perplexity, the Sonar text provider |\n| Inference type | decide only |\n| Model | pplx-decider-v1-27b; the API answers 400 to a missing or unknown model. PERPLEXITY_DECIDER_MODEL sets it |\n| Key | PERPLEXITY_API_KEY, shared with the Perplexity text provider, or credentials.perplexityDecider.apiKey |\n| Endpoint | https://api.perplexity.ai/v1/decisions; PERPLEXITY_DECIDER_BASE_URL can name another origin |\n| Media | images (PNG, JPEG or WebP), up to 8 per request; no video |\n| Questions per request | up to 128 |\n| Server input ceiling | under 262,144 tokens (state and
|
|
6879
|
+
{"objectID":"c9690ba724ce4205d66ac4d75981884b735170b152767047afcc0d406d5e7c8d","title":"Key Facts","url":"/docs/getting-started/providers/perplexity-decider#key-facts","content":"| | |\n| ------------------------ | ----------------------------------------------------------------------------------------------------------------- |\n| Provider id | perplexity-decider (no aliases) — distinct from perplexity, the Sonar text provider |\n| Inference type | decide only |\n| Model | pplx-decider-v1-27b; the API answers 400 to a missing or unknown model. PERPLEXITY_DECIDER_MODEL sets it |\n| Key | PERPLEXITY_API_KEY, shared with the Perplexity text provider, or credentials.perplexityDecider.apiKey |\n| Endpoint | https://api.perplexity.ai/v1/decisions; PERPLEXITY_DECIDER_BASE_URL can name another origin |\n| Media | images (PNG, JPEG or WebP), up to 8 per request; no video |\n| Questions per request | up to 128 |\n| Server input ceiling | under 262,144 tokens (state, questions and images); more is refused with an explicit 400, never cut off silently |\n| Images and that ceiling | billed as input tokens, and counted toward the ceiling at one token per 32 × 32 tile (measured) |\n| NeuroLink's state window | 100,000 estimated tokens: a deliberate local limit, not the server's |\n| Cost | $0.04 per million input tokens (image tokens included); output tokens are free. Perplexity's documented price |\n| Default timeout | 10 seconds plus 100 ms for each question (10.1 s for one, 22.8 s for 128); timeoutMs or --timeout replac","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Key Facts","lvl3":""}},
|
|
6880
6880
|
{"objectID":"467fb7efd250abc71afba6a9535ee164e671526dc06ff59407a827bda872b268","title":"1. Get a key","url":"/docs/getting-started/providers/perplexity-decider#1-get-a-key","content":"Create one in the Perplexity console. Any\nPerplexity API key works.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"1. Get a key","lvl3":""}},
|
|
6881
6881
|
{"objectID":"bd7509f708e016023be201690ca4cc963bc77551d7152b34c636ae628ea5e497","title":"2. Configure","url":"/docs/getting-started/providers/perplexity-decider#2-configure","content":"Set the key in the environment:\n\nor in the config passed to the SDK, exactly as for any other provider. Values\npassed per call override the constructor's, which override the environment:\n\ncredentials.perplexityDecider is its own slice. A key passed as\ncredentials.perplexity belongs to the text provider and does not configure\nthis one. PERPLEXITY_BASE_URL, which moves the text provider, is not read here;\nthe override for this provider is PERPLEXITY_DECIDER_BASE_URL, and a trailing\n/v1 on it is accepted.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"2. Configure","lvl3":""}},
|
|
6882
6882
|
{"objectID":"c3dbe3c712926dfb07b0d907370532df8bc3c98a5e81f4b46784a037ac0f1e0b","title":"3. Use it","url":"/docs/getting-started/providers/perplexity-decider#3-use-it","content":"NeuroLink's boolean question is sent to the API as its noul type, and the\nanswer is read back as a boolean. A boolean answer carries a probability and\nno confidence of its own; a choice or score answer carries the confidence the\nAPI reports, which Perplexity describes as the model's own certainty estimate,\nnot the top probability. Perplexity's API reference and quickstart do not call\nthat confidence calibrated, and NeuroLink did not measure whether it is, so tune\na threshold on it against your own labelled data. (The Hugging Face model card\nfor the open-weights model describes its output as calibrated probabilities.)\nPerplexity also notes that identical requests occasionally differ in the second\ndecimal place. Repeating a request returned the same numbers in NeuroLink's\nprobe, but leave some margin when you set a threshold anyway.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"3. Use it","lvl3":""}},
|
|
6883
6883
|
{"objectID":"6f3f0a67d6c85ce65d1d7d95a7016987ad0423b545c9f849bcde853edd0dd20f","title":"From the CLI","url":"/docs/getting-started/providers/perplexity-decider#from-the-cli","content":"The CLI reads the same environment variables:\n\nThe text output ends with a Cost: line, priced from the input tokens the API\nreports.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"From the CLI","lvl3":""}},
|
|
6884
|
-
{"objectID":"e1b9161659de68a10277e69ce53077f2aed241892d783054f01471fb793024bd","title":"Images","url":"/docs/getting-started/providers/perplexity-decider#images","content":"Perplexity reads images alongside the state. TypeSafe and Laya do not read\nmedia. XOR reads images and a video; Perplexity reads images only. In the probe\nthe model did read an image: asked red versus blue about one, it answered\ncorrectly at about 0.98 confidence.\n\nFrom the CLI, pass --image <path>, repeated for several:\n\nOn the wire the images go inside state: NeuroLink sends state as an array,\nyour state first and then one OpenAI-style image_url part per image, each a\nbase64 data URL. The API has no separate images field and rejects unknown\nfields. An image can also be the whole input (an image-only state was\naccepted in the probe); from the SDK, pass an empty string as state with\nimages. The CLI always needs a state.\n\nThe rules:\nUp to 8 images per request. Measured: 8 images with three questions were\n accepted, and 9 images with one question were refused with a 400 whose message\n words the cap as \"per question\". NeuroLink applies the 8 to the request as a\n whole.\nPNG, JPEG or WebP only. The type comes from the bytes, not the file\n extension. A GIF, or a data: URL of another type, is refused before any\n request, as a non-retryable invalid_request. The API refuses a GIF with a 400\n too.\nEach is a Buffer, a local file path or a data: URL. An http(s) URL is\n refused locally and never fetched. The API does not fetch URLs either: an\n https image URL returned a 400 in the probe.\nEach image may be at most 2,048 tiles of 32 × 32 pixels. Round the width\n and the height to the nearest multiple of 32 and keep (width / 32) ×\n (height / 32) at or under 2,048: by that count 1440 × 1440 (2,025 tiles) and\n 2048 × 1024 (2,048) fit, and 1600 × 1310 (2,050) does not. Perplexity documents\n this rule
|
|
6884
|
+
{"objectID":"e1b9161659de68a10277e69ce53077f2aed241892d783054f01471fb793024bd","title":"Images","url":"/docs/getting-started/providers/perplexity-decider#images","content":"Perplexity reads images alongside the state. TypeSafe and Laya do not read\nmedia. XOR reads images and a video; Perplexity reads images only. In the probe\nthe model did read an image: asked red versus blue about one, it answered\ncorrectly at about 0.98 confidence.\n\nFrom the CLI, pass --image <path>, repeated for several:\n\nOn the wire the images go inside state: NeuroLink sends state as an array,\nyour state first and then one OpenAI-style image_url part per image, each a\nbase64 data URL. The API has no separate images field and rejects unknown\nfields. An image can also be the whole input (an image-only state was\naccepted in the probe); from the SDK, pass an empty string as state with\nimages. The CLI always needs a state.\n\nThe rules:\nUp to 8 images per request. Measured: 8 images with three questions were\n accepted, and 9 images with one question were refused with a 400 whose message\n words the cap as \"per question\". NeuroLink applies the 8 to the request as a\n whole.\nPNG, JPEG or WebP only. The type comes from the bytes, not the file\n extension. A GIF, or a data: URL of another type, is refused before any\n request, as a non-retryable invalid_request. The API refuses a GIF with a 400\n too.\nEach is a Buffer, a local file path or a data: URL. An http(s) URL is\n refused locally and never fetched. The API does not fetch URLs either: an\n https image URL returned a 400 in the probe.\nEach image may be at most 2,048 tiles of 32 × 32 pixels. Round the width\n and the height to the nearest multiple of 32 and keep (width / 32) ×\n (height / 32) at or under 2,048: by that count 1440 × 1440 (2,025 tiles) and\n 2048 × 1024 (2,048) fit, and 1600 × 1310 (2,050) does not. Perplexity documents\n this rule, and it was checked at its edge. Fitting sizes were answered in\n about a second: 1920 × 1080 (2,040 tiles) in 1.1 seconds, 2048 × 1024 (2,048,\n exactly the cap) in 1.3 and 1450 × 1450 in 1.1. That last one rounds to 45 tiles\n a side (45.3), 2,025 in all, where rounding up (","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Images","lvl3":""}},
|
|
6885
6885
|
{"objectID":"8ad813ca01099f441bbc2db40ee064d9a0294d269166c42a6f87fce2a1c1330f","title":"When NeuroLink uses it","url":"/docs/getting-started/providers/perplexity-decider#when-neurolink-uses-it","content":"Every built-in consumer of decide asks for the default decision provider. That\nis the first one that is configured, in the environment or in the credentials\npassed to the SDK, in the order TypeSafe, Laya, XOR, Perplexity. TypeSafe counts\nwith either of its keys, TYPESAFE_API_KEY or AI_GATEWAY_API_KEY. Laya and XOR\neach count only with both their key and their base URL. Perplexity counts with\nits key alone, a non-blank PERPLEXITY_API_KEY or\ncredentials.perplexityDecider.apiKey. A caller can always name it with\nprovider: \"perplexity-decider\". So:\nOnly a Perplexity key: built-in features use Perplexity.\nA Perplexity key, plus TypeSafe's key, or Laya's or XOR's key and base\n URL: built-in features use TypeSafe, Laya or XOR, in that order, whichever\n is configured. Perplexity runs only where a caller asks for\n provider: \"perplexity-decider\".\nA key for the text provider only: the same as the first case. The key is\n shared, so the text provider's key also configures this one. See\n One key, two providers.\nNone of TypeSafe, Laya, XOR or Perplexity configured: everything behaves\n exactly as it did without a decision model.\n\nThe classifier router's auto gate reads the credentials given to the\nNeuroLink constructor and the environment, not credentials passed on a single\ncall, so a per-call credentials.perplexityDecider does not influence it. The\nother consumers NeuroLink wires itself (compaction and tool routing) call\ntryDecide without credentials too.\n\nWhere the built-in consumers use the default provider (what each one sends is\nlisted in What is sent to Perplexity):\n\n| Area | What the decision replaces |\n| ---------------------------------------------------------------- | --------------------------------------------------------------- |\n| Model routing | difficulty + capabilities + risk + model pick in one round trip |\n| Model catalogue | one choice over the registry ","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"When NeuroLink uses it","lvl3":""}},
|
|
6886
6886
|
{"objectID":"9545ac1f3da9bfc59774adf1978baa598ba4fc65670b5d0d4c96f7c10e2a1c3c","title":"What is sent to Perplexity","url":"/docs/getting-started/providers/perplexity-decider#what-is-sent-to-perplexity","content":"Perplexity receives the state and the questions of every decision made on\nyour behalf. The questions are NeuroLink's fixed wording, plus text from your own\nconversation where a consumer quotes it; the state is where your text goes.\nThis is what each built-in consumer sends and what turns it on, read from the\ncode:\nModel routing. One request behind the router, the model catalogue and the\n per-request context budget.\nSends: the first 8,000 characters of the prompt of the call being routed,\n plus whether tools are available, whether the request includes images, the\n estimated input tokens, the requested thinking level, whether a session is\n bound and how many prior messages the caller passed in. When the pool has\n more than one model, the questions carry the ids and descriptions of the\n models in it. The images, the session id and the conversation itself are not\n sent.\nTurned on by: classifierRouter.enabled with a pool: an opt-in. With\n the default classifier: \"auto\", a configured decision provider selects the\n decision strategy. classifier: \"heuristic\" or \"llm\" never calls a\n decision provider. A call that pins both provider and model is not\n routed.\nRelevance compaction. Stage 0 of context compaction.\nSends: the current request (first 4,000 characters) and, for each earlier\n user or assistant message that is plain text (not a tool call or result, a\n summary or a pinned skill), its role and its first 1,200 characters. That\n text travels twice, once in the state and once in the message's question. By\n default the six most recent messages are never sent\n (contextRelevance.protectRecent), and at most 300 are asked about.\nTurned on by: nothing beyond a configured decision provider. It runs\n inside context compaction, which starts when a conversation outgrows its\n context budget.\nSummary-quality gate. Guards the summarization stage of compaction.\nSends: the generated summary (first 12,000 characters) and the last 60\n m","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"What is sent to Perplexity","lvl3":""}},
|
|
6887
6887
|
{"objectID":"01342235e59d6796c886025eea6c3dbdefc5f4420f47123db9b23eacc22955d3","title":"One key, two providers","url":"/docs/getting-started/providers/perplexity-decider#one-key-two-providers","content":"PERPLEXITY_API_KEY is the variable the\nPerplexity text provider reads to serve generate() and\nstream(). It is also the variable that configures this provider. Nothing else\nneeds to be set, so a host that set the key only to use Sonar has also\nconfigured decide:\nWith none of TypeSafe, Laya or XOR configured, the texts listed in\n What is sent to Perplexity go to Perplexity's\n Decisions API. Context compaction needs no other opt-in, so a host with long\n conversations starts sending conversation text the first time one outgrows its\n budget. Model routing, tool routing and RAG planning do so only where you have\n turned them on. No code changes: the key is the switch.\nIt is fail-open, and TypeSafe, Laya and XOR take precedence. If you have\n configured any of them, the shared key changes nothing for the built-in\n consumers, and a Perplexity failure leaves behaviour as it was.\nWith no decision provider configured at all, nothing is sent.\n\nAn unedited copy of .env.example does not set the key, because its\nPERPLEXITY_API_KEY line is commented out.\n\nA key in a .env file counts as a key in the environment. Importing the SDK\nloads the .env in the current working directory, and the CLI does the same at\nstart; when DOTENV_CONFIG_PATH is set, that file is loaded instead. A key that\nsits in .env therefore configures decide exactly as one exported in the\nshell does.\n\nTo keep a key that was set for Sonar from activating decisions, use one of\nthese:\nHand the key to the text provider through the SDK, not the environment, and\n keep it out of .env.\n new NeuroLink({ credentials: { perplexity: { apiKey } } }) configures the\n text provider and not this one, because NeuroLink looks for this provider's\n key in PERPLEXITY_API_KEY and in credentials.perplexityDecider, never in\n credentials.perplexity. The key must also be absent from .env: remove the\n PERPLEXITY_API_KEY line from that file as well as from the shell, or point\n DOTENV_CONFIG_PATH at a file that does not have i","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"One key, two providers","lvl3":""}},
|
|
6888
|
-
{"objectID":"2c9da95e9403e04ac92a64727b9b098a3b1e626742b59f4ffebc6e24914ec316","title":"Measured on a real account, October 2026","url":"/docs/getting-started/providers/perplexity-decider#measured-on-a-real-account-october-2026","content":"NeuroLink probed the live API from an account limited to 10 requests per second.\nThese figures were observed, not taken from Perplexity's documentation:\n\n| What | Measured
|
|
6888
|
+
{"objectID":"2c9da95e9403e04ac92a64727b9b098a3b1e626742b59f4ffebc6e24914ec316","title":"Measured on a real account, October 2026","url":"/docs/getting-started/providers/perplexity-decider#measured-on-a-real-account-october-2026","content":"NeuroLink probed the live API from an account limited to 10 requests per second.\nThese figures were observed, not taken from Perplexity's documentation:\n\n| What | Measured |\n| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| Questions per request | 128 accepted (128 answers in 8.9 s, 11,904 input tokens); 129 is refused with a 400. An extra minimal question adds about 92 input tokens, and a one-character state with one question bills 116. ","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Measured on a real account, October 2026","lvl3":""}},
|
|
6889
6889
|
{"objectID":"bb716df9ef27b597327dd3b40f9b5429c5e7d66e789cc5d677574fa3f3fea651","title":"What Perplexity documents and the probe did not check","url":"/docs/getting-started/providers/perplexity-decider#what-perplexity-documents-and-the-probe-did-not-check","content":"The request body: 32 MiB, refused with a 413.\nNames, options and levels: every question needs a non-empty name; 1 to 255\n options on a choice; 1 to 10 levels on a score.\nThe price: $0.04 per million input tokens, image tokens included, output\n free.\nThe rate: 10 requests per second for the account's tier, and a token limit\n that also applies to large bursts; either answers 429. The burst test above saw\n the request limit act on the one account tested, and the token limit was not\n tested.\nNot verified: the status the API returns for an account with no credit. A\n key with no balance could not be created for the probe. Whatever comes back is\n classified by the table under Errors: a 401 disables the provider\n instance, a 429 is retried once, and any other 4xx is an invalid_request.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"What Perplexity documents and the probe did not check","lvl3":""}},
|
|
6890
6890
|
{"objectID":"12d235ff87ac1a95fdf64d56f736e5bd5c986e271ceb4dfd014e03572ee1290c","title":"What NeuroLink refuses before any request","url":"/docs/getting-started/providers/perplexity-decider#what-neurolink-refuses-before-any-request","content":"These are NeuroLink's own limits, set from the measurements above. A request\nover any of them fails locally, with no network call, and every built-in\nconsumer treats that as \"carry on as before\".\nA state estimated above 100,000 tokens is refused with\n max_tokens_exceeded. The window is a deliberate local limit, not a server\n limit: the server reads up to 262,144 tokens in all. It is set lower because\n latency grows faster than linearly with input (3.9 s at 65,000 tokens, 10 s at\n 146,000), so a state of 100,000 tokens takes about 7 seconds of the 10-second\n allowance, an interpolation between those two measurements and not a\n measurement of its own, and a much larger one would likely time out and be\n retried into the same wait. The estimate is 3.81 characters per token for\n ASCII text (four, with a 5% margin), which is about 381,000 characters at the\n window, and half a token per non-ASCII character, near the measured rate for\n CJK (about 0.46) and Devanagari (0.44). It covers the text of the state only,\n not the questions or the images.\nThe estimate is a guard, not a promise of acceptance. Against the measured\n characters per token, it over-counts English prose (4.34) and is close for\n TypeScript (3.84). It under-counts minified JSON (3.36) by about 13%, which\n does not matter at the window: 380,000 characters of JSON, estimated at 100,000\n tokens, are about 113,000 real tokens, far under the 262,144 the server reads.\n Log lines (1.35) are under-counted by about 2.8 times and arrays of integers\n (1.16) by about 3.3 times, and a state of either kind can pass the window and\n still be refused by the server for being over its ceiling: 380,000 characters\n of log lines are about 281,000 real tokens, and of integer arrays about\n 328,000. Text that is mostly emoji (2.6 tokens per code point, against the half\n token it charges) can be refused the same way. That refusal is reported as\n max_tokens_exceeded too, and is not retried.\nA state estimated above","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"What NeuroLink refuses before any request","lvl3":""}},
|
|
6891
6891
|
{"objectID":"8e97b6f8092812014ba072ae65457308bc11e5c8b5349d31ff466c7db1f9cb39","title":"Latency and the timeout","url":"/docs/getting-started/providers/perplexity-decider#latency-and-the-timeout","content":"The default timeout is 10 seconds plus 100 ms for each question: 10.1\nseconds for one question and 22.8 seconds for the 128-question maximum. A\ntimeoutMs you pass, or --timeout on the CLI, is used exactly as given, with\nnothing added. The 10 seconds are the allowance for reading the input. Latency\ngrows faster than linearly with input (3.9 s at 65,000 tokens, 10 s at 146,000\nand 22.9 s at 251,000), so a state of 100,000 tokens takes about 7 s, an\ninterpolation between the 65,000- and 146,000-token measurements, and a larger\none needs a larger timeoutMs. The 100 ms follows what a question costs: each\none after the first added about 65 ms, and 128 minimal questions took 8.9 s on\n11,904 input tokens, so a flat 10 seconds would have been nearly spent on the\nquestions alone. Images count as input tokens too (see Images).\n\nA timeout is retried once, so a request that stalls can take about twice the\ntimeout plus a quarter to half a second before it fails: about 20 seconds at the\ndefault for one question. Pass a larger timeoutMs for a state of more than\nabout 100,000 real tokens, which log lines and arrays of numbers reach well\ninside the window (see\nWhat NeuroLink refuses). A model\nthat does not answer in time returns an HTML 504 after about a minute;\nNeuroLink's shorter timeout fires first, so it arrives as timeout, retried\nonce.\n\nEach built-in consumer takes its timeout from where it is configured:\nModel routing (with the model catalogue and the context budget, which share\n its request): classifierRouter.timeoutMs in the NeuroLink config, passed to\n the decision request when set.\nRelevance compaction: contextRelevance.timeoutMs in the NeuroLink\n config.\nSummary-quality gate: no setting. The NeuroLink config has none for it.\nTool / MCP routing: no setting for the decision request.\n toolRouting.timeoutMs bounds the generative router only.\nRAG planning: no setting in the pipeline config. The pipeline calls the\n decide function you give it, so set timeoutMs in the call ","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Latency and the timeout","lvl3":""}},
|
|
6892
6892
|
{"objectID":"e0c0e895220d617b9c97e379206986672c638c01de25fb9e0b52fa7c04bf0ca1","title":"Rate limits","url":"/docs/getting-started/providers/perplexity-decider#rate-limits","content":"The account measured allows 10 requests per second. A 429 is retried once, after\nthe wait its Retry-After header asks for. NeuroLink honours that header on any\nretried reply that carries it, and only as a whole number of seconds above zero\nor as an HTTP date in the future; anything else (zero, a negative number, a hex\nor exponent spelling, a fraction, a date already past) is ignored, and the\ndefault backoff of a quarter to half a second is used instead. A wait longer\nthan what is left of the attempt's timeout is not taken: the error is thrown at\nonce so a fail-open consumer is not held for the length of a cooldown, and a\ncaller's abort signal ends a wait immediately.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Rate limits","lvl3":""}},
|
|
6893
|
-
{"objectID":"f40b2da5feaf02bc4eaf5102d75c33ce6fc9f979f7106853002b142aad4fd67f","title":"Errors","url":"/docs/getting-started/providers/perplexity-decider#errors","content":"| Reply
|
|
6893
|
+
{"objectID":"f40b2da5feaf02bc4eaf5102d75c33ce6fc9f979f7106853002b142aad4fd67f","title":"Errors","url":"/docs/getting-started/providers/perplexity-decider#errors","content":"| Reply | Kind | Retried |\n| -------------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------ |\n| 401 | authentication — the provider instance stops retrying | no |\n| 413 | max_tokens_exceeded (the body is over 32 MiB) | no |\n| 400 saying the input exceeds the model's maximum context length | max_tokens_exceeded | no |\n| any other 4xx (for example another 400, 403, 404) | invalid_request, with Perplexity's own message | no |\n| 429 | rate_limit | yes, once, after Retry-After |\n| 503 | overloaded | yes, once |\n| other 5xx (500, 502, 504) | server | yes, once |\n| no response within the timeout | timeout | yes, once |\n| the request fails before any reply (connection refused, DNS failure) | network | yes, once |\n| the caller's own signal aborts the request | network | no |\n| state or questions over the limit (local) ","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Errors","lvl3":""}},
|
|
6894
6894
|
{"objectID":"a812289efc882316bb62c31aea533cd0a0e8e219eeea12289b4503450b4dd9a5","title":"Troubleshooting","url":"/docs/getting-started/providers/perplexity-decider#troubleshooting","content":"Perplexity requires an API key — set PERPLEXITY_API_KEY, or pass\n credentials.perplexityDecider.apiKey. A key passed as\n credentials.perplexity does not count.\nA 401, Invalid API key provided — Perplexity rejected the key, and it\n checks the key before anything else. The provider instance stops retrying\n after a rejection, so fix the key and construct a new one.\nA 400 naming the model — PERPLEXITY_DECIDER_MODEL, or a per-call\n model, names something other than pplx-decider-v1-27b.\nThe Perplexity base URL must not carry credentials… — the override has a\n user name, a password, a query string or a fragment. Set it to the origin only,\n or leave it unset for https://api.perplexity.ai.\nThe Perplexity base URL must start with https:// or http:// — the value\n parses as a URL with another scheme: an explicit one such as ftp://, or a host\n name and port with no scheme, such as localhost:8080, which reads as the\n scheme localhost:. Put https:// or http:// in front.\nThe Perplexity base URL is not a valid absolute URL — the value does not\n parse as a URL at all: a bare host name such as api.perplexity.ai (the likely\n mistake), an IP address and port such as 127.0.0.1:8080, a path, or a scheme\n with no host. Write the origin with its scheme.\nA refused base URL in the debug log — it is not there. A base URL that\n NeuroLink refuses (credentials, a query string, a fragment, a scheme other than\n http or https, or not a URL at all) is never written to the debug log: the line\n shows (invalid) in its place, because such a value can carry a secret.\nImage N is not a PNG, JPEG or WebP image — Perplexity reads only those\n three. Convert the image first.\nImage N is … pixels; Perplexity reads at most 2048 tiles — resize the\n image to fit, for example 1440 × 1440 or 2048 × 1024.\nA request with an image stalls until it times out, or fails as server with\n HTTP 504 when the timeout is longer than a minute — an image over the tile\n cap does this. NeuroLink refuses those before","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
|
|
6895
6895
|
{"objectID":"6d580e7ffb3867905a72879cdccbab76b5df280677e9d18b0029fd5bc5092025","title":"See also","url":"/docs/getting-started/providers/perplexity-decider#see-also","content":"The decide inference type\nTypeSafe (Jev) Provider Guide\nLaya Provider Guide\nXOR Provider Guide\nPerplexity text provider\nPerplexity Decisions API reference","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"See also","lvl3":""}},
|
|
6896
6896
|
{"objectID":"6d55ee7ec0f21369a70b421eaeaddf6b44fe88746beb28c252588d42d97048b7","title":"Perplexity Provider Guide","url":"/docs/getting-started/providers/perplexity","content":"Perplexity Provider Guide\n\nWeb-search-augmented generation via Perplexity's Sonar models\n\nOverview\n\nPerplexity hosts a family of LLMs (Sonar,\nSonar Pro, Sonar Reasoning) that pair the model with a live web search\nbackend; responses include citations to the documents the model relied on.\n\nKey Facts\nProtocol: OpenAI-compatible (/chat/completions)\nDefault base URL: https://api.perplexity.ai\nDefault model: sonar\nCitations: Returned via citations field on the response\nStreaming: Yes\nTool calling: No\n\nQuick Start\nGet an API Key\n\nhttps://www.perplexity.ai/settings/api\nConfigure\n\nPERPLEXITY_API_KEY also configures decisions. The same variable configures\nthe Perplexity Decisions provider (perplexity-decider,\nwhich serves decide()). So setting it for Sonar also lets NeuroLink's built-in\nfeatures send decision requests to Perplexity when no TypeSafe, Laya or XOR\nprovider is configured, and context compaction needs no other opt-in to do so.\nTo avoid that, pass the key through the SDK as credentials.perplexity.apiKey\ninstead of the environment, and keep it out of .env too: the SDK and the CLI\nload that file into the environment, so a PERPLEXITY_API_KEY line like the one\nabove would still configure decisions. (That the text provider reads this slice\nis taken from the code and has not been run against the live API.) See\nWhat is sent to Perplexity\nand One key, two providers.\nGenerate\n\nSupported Models\n\n| Model ID | Notes |\n| ----------------- | ----------------------------------- |\n| sonar | Default; fast search-augmented chat |\n| sonar-pro | Larger context, deeper search |\n| sonar-reasoning | Chain-of-thought reasoning |\n\nCLI Usage\n\nProvider Aliases\n\n| Alias | Example |\n| ------------ | ----------------------- |\n| perplexity | --provider perplexity |\n\nConfiguration Reference\n\n| Environment Variable | Required | Default |\n| --------------------- | -------- | --------------------------- |\n| PERPLEXITY_API_KEY | Yes | — |\n| PERPLEXITY_MODEL | No | sonar |\n| PERPLEXITY_BASE_URL | No | https://api.perplexity.ai |\n\nFeature Support Matrix\n\n| Feature | Support |\n| ----------------- | ------------ |\n| Text generation | Yes |\n| Streaming | Yes |\n| Tool calling | No |\n| Structured output | Limited |\n| Web search | Yes (native) |\n| Citations | Yes |\n\nSee Also\nPerplexity Decisions Provider — typed, calibrated decide() judgments on the same key\nAnthropic Provider — web-search via the web_search tool\nVertex Provider — Google search grounding","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Provider Guide","lvl2":"","lvl3":""}},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "12.44.
|
|
3
|
+
"version": "12.44.5",
|
|
4
4
|
"packageManager": "pnpm@10.15.1",
|
|
5
5
|
"description": "The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002/call) for routing, tool selection and context budgeting. MCP-native (4 transports), voice TTS/STT/realtime, RAG, agents, memory, compaction, 9 observability exporters. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · TypeSafe Jev and more.",
|
|
6
6
|
"author": {
|