@juspay/neurolink 9.86.2 β†’ 9.86.4

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,3 +1,15 @@
1
+ ## [9.86.4](https://github.com/juspay/neurolink/compare/v9.86.3...v9.86.4) (2026-07-11)
2
+
3
+ ### Bug Fixes
4
+
5
+ - **(generate):** stop treating ai@6 raw-text output echo as parsed schema output ([dc23936](https://github.com/juspay/neurolink/commit/dc23936d1feec5e4089ba5eb8338983b5a7ceee3))
6
+
7
+ ## [9.86.3](https://github.com/juspay/neurolink/compare/v9.86.2...v9.86.3) (2026-07-11)
8
+
9
+ ### Bug Fixes
10
+
11
+ - **(deps):** declare js-yaml + fast-xml-parser as runtime dependencies ([48f54d5](https://github.com/juspay/neurolink/commit/48f54d5d4085a4e77764a2fcab9e5b2c5fa1403f))
12
+
1
13
  ## [9.86.2](https://github.com/juspay/neurolink/compare/v9.86.1...v9.86.2) (2026-07-10)
2
14
 
3
15
  ### Bug Fixes
package/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # NeuroLink
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@juspay/neurolink?label=npm&color=blue)](https://www.npmjs.com/package/@juspay/neurolink)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@juspay/neurolink?label=downloads)](https://www.npmjs.com/package/@juspay/neurolink)
5
+ [![GitHub Stars](https://img.shields.io/github/stars/juspay/neurolink?style=flat)](https://github.com/juspay/neurolink/stargazers)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
7
+ [![CI](https://img.shields.io/github/actions/workflow/status/juspay/neurolink/ci.yml?label=CI)](https://github.com/juspay/neurolink/actions/workflows/ci.yml)
8
+
3
9
  **The pipe layer for the AI nervous system.**
4
10
 
5
11
  AI intelligence flows as streams β€” tokens, tool calls, memory, voice, documents.
@@ -26,9 +32,9 @@ for await (const chunk of result.stream) {
26
32
 
27
33
  ## 🧠 What is NeuroLink?
28
34
 
29
- **NeuroLink is the universal AI integration platform that unifies 21+ AI providers and 100+ models under one consistent API.**
35
+ **NeuroLink is the universal AI integration platform that unifies 24+ AI providers and 100+ models under one consistent API.**
30
36
 
31
- Extracted from production systems at Juspay and battle-tested at enterprise scale, NeuroLink provides a production-ready solution for integrating AI into any application. Whether you're building with OpenAI, Anthropic, Google, AWS Bedrock, Azure, or any of our 21+ supported providers, NeuroLink gives you a single, consistent interface that works everywhere.
37
+ Extracted from production systems at Juspay and battle-tested at enterprise scale, NeuroLink provides a production-ready solution for integrating AI into any application. Whether you're building with OpenAI, Anthropic, Google, AWS Bedrock, Azure, or any of our 24+ supported providers, NeuroLink gives you a single, consistent interface that works everywhere.
32
38
 
33
39
  **Why NeuroLink?** Switch providers with a single parameter change, leverage 64+ built-in tools and MCP servers, deploy with confidence using enterprise features like Redis memory and multi-provider failover, and optimize costs automatically with intelligent routing. Use it via our professional CLI or TypeScript SDKβ€”whichever fits your workflow.
34
40
 
@@ -220,7 +226,7 @@ npx @juspay/neurolink --help
220
226
 
221
227
  ### Configuration
222
228
 
223
- NeuroLink works with 21+ AI providers. You'll need at least one API key to get started:
229
+ NeuroLink works with 24+ AI providers. You'll need at least one API key to get started:
224
230
 
225
231
  **Option 1: Interactive Setup (Recommended)**
226
232
 
@@ -407,7 +413,7 @@ const result = await neurolink.generate({
407
413
  ### Next Steps
408
414
 
409
415
  - **[Complete Documentation](https://docs.neurolink.ink)** - Comprehensive guides and API reference
410
- - **[Provider Setup Guide](docs/getting-started/provider-setup.md)** - Configure all 33+ providers
416
+ - **[Provider Setup Guide](docs/getting-started/provider-setup.md)** - Configure all 24+ providers
411
417
  - **[SDK API Reference](docs/sdk/api-reference.md)** - Full TypeScript API documentation
412
418
  - **[CLI Command Reference](docs/cli/commands.md)** - Complete CLI documentation
413
419
  - **[Example Projects](docs/examples/index.md)** - Real-world integration examples
@@ -439,7 +445,7 @@ NeuroLink is a comprehensive AI development platform. Every feature below is pro
439
445
 
440
446
  ### πŸ€– AI Provider Integration
441
447
 
442
- **33+ providers unified under one API** - Switch providers with a single parameter change.
448
+ **24+ providers unified under one API** - Switch providers with a single parameter change.
443
449
 
444
450
  | Provider | Models | Free Tier | Tool Support | Status | Documentation |
445
451
  | --------------------- | -------------------------------------------------------------------------- | --------------- | ------------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------- |
@@ -455,7 +461,7 @@ NeuroLink is a comprehensive AI development platform. Every feature below is pro
455
461
  | **Hugging Face** | 100,000+ models | βœ… Free | ⚠️ Partial | βœ… Production | [Setup Guide](docs/getting-started/provider-setup.md#huggingface) |
456
462
  | **Ollama** | Local models (Llama, Mistral) | βœ… Free (Local) | ⚠️ Partial | βœ… Production | [Setup Guide](docs/getting-started/provider-setup.md#ollama) |
457
463
  | **OpenAI Compatible** | Any OpenAI-compatible endpoint | Varies | βœ… Full | βœ… Production | [Setup Guide](docs/getting-started/provider-setup.md#openai-compatible) |
458
- | **OpenRouter** | 200+ Models via OpenRouter | Varies | βœ… Full | βœ… Production | [Setup Guide](docs/getting-started/providers/openrouter.md) |
464
+ | **OpenRouter** | 300+ models via OpenRouter | Varies | βœ… Full | βœ… Production | [Setup Guide](docs/getting-started/providers/openrouter.md) |
459
465
  | **DeepSeek** | deepseek-chat (V3), deepseek-reasoner (R1) | ❌ | βœ… Full | βœ… Production | [Setup Guide](docs/getting-started/provider-setup.md#deepseek) |
460
466
  | **NVIDIA NIM** | Llama 3.3 70B, 400+ catalog models | ❌ | βœ… Full | βœ… Production | [Setup Guide](docs/getting-started/provider-setup.md#nvidia-nim) |
461
467
  | **LM Studio** | Any model loaded in LM Studio (local) | βœ… Free (Local) | βœ… Full | βœ… Production | [Setup Guide](docs/getting-started/provider-setup.md#lm-studio) |
@@ -466,7 +472,7 @@ NeuroLink is a comprehensive AI development platform. Every feature below is pro
466
472
  | **Azure Speech** | Azure Cognitive Services TTS + STT | ❌ | N/A | βœ… Production | [Setup Guide](docs/getting-started/provider-setup.md#azure-speech) |
467
473
 
468
474
  **[πŸ“– Provider Comparison Guide](docs/reference/provider-comparison.md)** - Detailed feature matrix and selection criteria
469
- **[πŸ”¬ Provider Feature Compatibility](docs/reference/provider-feature-compatibility.md)** - Test-based compatibility reference for all 19 features across 21+ providers
475
+ **[πŸ”¬ Provider Feature Compatibility](docs/reference/provider-feature-compatibility.md)** - Test-based compatibility reference for all 19 features across 24+ providers
470
476
 
471
477
  ---
472
478
 
@@ -622,7 +628,7 @@ const result = await neurolink.generate({
622
628
  - **ProcessorRegistry** - Priority-based processor selection with fallback
623
629
  - **OWASP Security** - HTML/SVG sanitization prevents XSS attacks
624
630
  - **Auto-detection** - FileDetector identifies file types by extension and content
625
- - **Provider-agnostic** - All processors work across all 21+ AI providers
631
+ - **Provider-agnostic** - All processors work across all 24+ AI providers
626
632
 
627
633
  **[πŸ“– File Processors Guide](docs/features/file-processors.md)** - Complete reference for all file types
628
634
 
@@ -752,7 +758,7 @@ node your-app.js
752
758
 
753
759
  ### πŸ€– GitHub Action
754
760
 
755
- Run AI-powered workflows directly in GitHub Actions with 21+ provider support and automatic PR/issue commenting.
761
+ Run AI-powered workflows directly in GitHub Actions with 24+ provider support and automatic PR/issue commenting.
756
762
 
757
763
  ```yaml
758
764
  - uses: juspay/neurolink@v1
@@ -764,7 +770,7 @@ Run AI-powered workflows directly in GitHub Actions with 21+ provider support an
764
770
 
765
771
  | Feature | Description |
766
772
  | ---------------------- | ----------------------------------------------------------------------------------------- |
767
- | **Multi-Provider** | 21+ providers with unified interface |
773
+ | **Multi-Provider** | 24+ providers with unified interface |
768
774
  | **PR/Issue Comments** | Auto-post AI responses with intelligent updates |
769
775
  | **Multimodal Support** | Attach images, PDFs, CSVs, Excel, Word, JSON, YAML, XML, HTML, SVG, code files to prompts |
770
776
  | **Cost Tracking** | Built-in analytics and quality evaluation |
@@ -957,7 +963,7 @@ Full command and API breakdown lives in [`docs/cli/commands.md`](docs/cli/comman
957
963
 
958
964
  | Capability | Highlights |
959
965
  | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
960
- | **Provider unification** | 21+ providers with automatic fallback, cost-aware routing, `providerFallback` policy, `modelChain` config. |
966
+ | **Provider unification** | 24+ providers with automatic fallback, cost-aware routing, `providerFallback` policy, `modelChain` config. |
961
967
  | **Multimodal pipeline** | Stream images + CSV data + PDF documents across providers with local/remote assets. Auto-detection for mixed file types. |
962
968
  | **Voice pipeline** | TTS (6 providers: Google, OpenAI, ElevenLabs, Azure, Fish Audio, Cartesia) + STT (4 providers) + realtime voice APIs (OpenAI Realtime, Gemini Live). |
963
969
  | **Quality & governance** | Auto-evaluation engine (14 scorers), guardrails middleware, HITL workflows, audit logging. |
@@ -1028,6 +1034,7 @@ Full command and API breakdown lives in [`docs/cli/commands.md`](docs/cli/comman
1028
1034
 
1029
1035
  ## Contributing & Support
1030
1036
 
1037
+ - Real-time chat and community β†’ [Discord](https://discord.gg/cZa8DrDhSR)
1031
1038
  - Bug reports and feature requests β†’ [GitHub Issues](https://github.com/juspay/neurolink/issues)
1032
1039
  - Questions and discussions β†’ [GitHub Discussions](https://github.com/juspay/neurolink/discussions)
1033
1040
  - Development workflow, testing, and pull request guidelines β†’ [`docs/development/contributing.md`](docs/development/contributing.md)
@@ -807,7 +807,7 @@ Ensure the final response is fully self-sufficient and does not reference extern
807
807
  ${t}
808
808
  ]`}function T(){let B=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,K=arguments.length>1&&arguments[1]!==void 0?arguments[1]:-1,re=r[e]==="\\";if(re&&(e++,re=!0),NP(r[e])){let W=ate(r[e])?ate:cte(r[e])?cte:ej(r[e])?ej:ite,me=e,De=t.length,ne='"';for(e++;;){if(e>=r.length){let Pe=I(e-1);return!B&&OP(r.charAt(Pe))?(e=me,t=t.substring(0,De),T(!0)):(ne=dd(ne,'"'),t+=ne,!0)}if(e===K)return ne=dd(ne,'"'),t+=ne,!0;if(W(r[e])){let Pe=e,ge=ne.length;if(ne+='"',e++,t+=ne,i(!1),B||e>=r.length||OP(r[e])||NP(r[e])||dy(r[e]))return w(),!0;let Ge=I(Pe-1),fe=r.charAt(Ge);if(fe===",")return e=me,t=t.substring(0,De),T(!1,Ge);if(OP(fe))return e=me,t=t.substring(0,De),T(!0);t=t.substring(0,De),e=Pe+1,ne=`${ne.substring(0,ge)}\\${ne.substring(ge)}`}else if(B&&ote(r[e])){if(r[e-1]===":"&&rte.test(r.substring(me+1,e+2)))for(;e<r.length&&nte.test(r[e]);)ne+=r[e],e++;return ne=dd(ne,'"'),t+=ne,w(),!0}else if(r[e]==="\\"){let Pe=r.charAt(e+1);if(JLt[Pe]!==void 0)ne+=r.slice(e,e+2),e+=2;else if(Pe==="u"){let Ge=2;for(;Ge<6&&YMe(r[e+Ge]);)Ge++;Ge===6?(ne+=r.slice(e,e+6),e+=6):e+Ge>=r.length?e=r.length:V()}else Pe===`
809
809
  `?(ne+="\\n",e+=2):(ne+=Pe,e+=2)}else{let Pe=r.charAt(e);Pe==='"'&&r[e-1]!=="\\"?(ne+=`\\${Pe}`,e++):ZMe(Pe)?(ne+=KLt[Pe],e++):(XMe(Pe)||F(Pe),ne+=Pe,e++)}re&&f()}}return!1}function w(){let B=!1;for(i();r[e]==="+";){B=!0,e++,i(),t=AE(t,'"',!0);let K=t.length;T()?t=tOe(t,K,1):t=dd(t,'"')}return B}function k(){let B=e;if(r[e]==="-"){if(e++,M())return O(B),!0;if(!dy(r[e]))return e=B,!1}for(;dy(r[e]);)e++;if(r[e]==="."){if(e++,M())return O(B),!0;if(!dy(r[e]))return e=B,!1;for(;dy(r[e]);)e++}if(r[e]==="e"||r[e]==="E"){if(e++,(r[e]==="-"||r[e]==="+")&&e++,M())return O(B),!0;if(!dy(r[e]))return e=B,!1;for(;dy(r[e]);)e++}if(!M())return e=B,!1;if(e>B){let K=r.slice(B,e),re=/^0\d/.test(K);return t+=re?`"${K}"`:K,!0}return!1}function C(){return R("true","true")||R("false","false")||R("null","null")||R("True","true")||R("False","false")||R("None","null")}function R(B,K){return r.slice(e,e+B.length)===B?(t+=K,e+=B.length,!0):!1}function P(B){let K=e;if(ete(r[e])){for(;e<r.length&&tte(r[e]);)e++;let re=e;for(;uy(r,re);)re++;if(r[re]==="(")return e=re+1,s(),r[e]===")"&&(e++,r[e]===";"&&e++),!0}for(;e<r.length&&!ote(r[e])&&!NP(r[e])&&(!B||r[e]!==":");)e++;if(r[e-1]===":"&&rte.test(r.substring(K,e+2)))for(;e<r.length&&nte.test(r[e]);)e++;if(e>K){for(;uy(r,e-1)&&e>0;)e--;let re=r.slice(K,e);return t+=re==="undefined"?"null":JSON.stringify(re),r[e]==='"'&&e++,!0}}function A(){if(r[e]==="/"){let B=e;for(e++;e<r.length&&(r[e]!=="/"||r[e-1]==="\\");)e++;return e++,t+=JSON.stringify(r.substring(B,e)),!0}}function I(B){let K=B;for(;K>0&&uy(r,K);)K--;return K}function M(){return e>=r.length||OP(r[e])||uy(r,e)}function O(B){t+=`${r.slice(B,e)}0`}function F(B){throw new Hf(`Invalid character ${JSON.stringify(B)}`,e)}function L(){throw new Hf(`Unexpected character ${JSON.stringify(r[e])}`,e)}function $(){throw new Hf("Unexpected end of json string",r.length)}function z(){throw new Hf("Object key expected",e)}function U(){throw new Hf("Colon expected",e)}function V(){let B=r.slice(e,e+6);throw new Hf(`Invalid unicode character "${B}"`,e)}}function YLt(r,e){return r[e]==="*"&&r[e+1]==="/"}var KLt,JLt,oOe=_(()=>{JMe();nOe();KLt={"\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r"," ":"\\t"},JLt={'"':'"',"\\":"\\","/":"/",b:"\b",f:"\f",n:`
810
- `,r:"\r",t:" "}});var sOe=_(()=>{oOe()});function ute(r,e=0){for(let t=e;t<r.length;t++){let n=r[t];if(n!=="{"&&n!=="[")continue;let o=n==="{"?"}":"]",s=0,i=!1,a=!1;for(let c=t;c<r.length;c++){let l=r[c];if(a){a=!1;continue}if(l==="\\"){a=!0;continue}if(l==='"'){i=!i;continue}if(!i){if(l===n)s++;else if(l===o&&(s--,s===0))return{span:r.substring(t,c+1),end:c+1}}}}return null}var iOe=_(()=>{"use strict"});function XLt(r){return typeof r.safeParse=="function"}function ZLt(r){try{return{value:JSON.parse(r),repaired:!1}}catch{}try{let e=lte(r),t=JSON.parse(e);return e!==r&&g.shouldLog("debug")&&g.debug("[coerceJsonToSchema] jsonrepair altered model output",{originalLength:r.length,repairedLength:e.length}),{value:t,repaired:e!==r}}catch{return}}function dte(r,e=0){if(e>QLt)return{value:r,changed:!1};if(typeof r=="string"){let t=r.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let o=JSON.parse(t);if(o!==null&&typeof o=="object")return{value:o,changed:!0}}catch{}return{value:r,changed:!1}}if(Array.isArray(r)){let t=!1,n=r.map(o=>{let s=dte(o,e+1);return s.changed&&(t=!0),s.value});return{value:t?n:r,changed:t}}if(r!==null&&typeof r=="object"){let t=!1,n={};for(let[o,s]of Object.entries(r)){let i=dte(s,e+1);i.changed&&(t=!0),n[o]=i.value}return{value:t?n:r,changed:t}}return{value:r,changed:!1}}function tj(r,e){if(typeof r!="string"||r.trim().length===0)return null;let t=[],n=0;for(;;){let h=ute(r,n);if(!h)break;t.push({text:h.span,truncated:!1}),n=h.end}let o=[r.indexOf("{"),r.indexOf("[")].filter(h=>h>=0),s=o.length>0?Math.min(...o):-1,i=Math.max(r.lastIndexOf("}"),r.lastIndexOf("]"));s>=0&&i>s&&t.push({text:r.slice(s,i+1),truncated:!1}),s>=0&&t.push({text:r.slice(s),truncated:!0});let a=r.trim();if(a.length>1&&a.startsWith('"')&&a.endsWith('"'))try{let h=JSON.parse(a);if(typeof h=="string"){let y=0;for(;;){let x=ute(h,y);if(!x)break;t.push({text:x.span,truncated:!1}),y=x.end}}}catch{}let c,l=[],u=!!(e&&XLt(e)),d=new Set;for(let h of t){if(d.has(h.text))continue;d.add(h.text);let y=ZLt(h.text);if(y===void 0||y.value===null||typeof y.value!="object")continue;let x={value:y.value,repaired:y.repaired,truncated:h.truncated};if(c===void 0&&(c=x),!u)break;let b=e;if(b.safeParse(y.value).success)l.push(x);else{let T=dte(y.value);T.changed&&T.value!==null&&typeof T.value=="object"&&b.safeParse(T.value).success&&l.push({value:T.value,repaired:!0,truncated:h.truncated})}}let f=(l.length>0?l.reduce((h,y)=>JSON.stringify(y.value).length>JSON.stringify(h.value).length?y:h):void 0)??c;return f===void 0?null:{content:JSON.stringify(f.value),structuredData:f.value,repaired:f.repaired,truncated:f.truncated}}var QLt,pte=_(()=>{"use strict";sOe();H();iOe();QLt=6});function aOe(r){let e=[],t=[];for(let n of r)n.role==="system"?e.push(n):t.push(n);return e.length===0||t.length===0?{system:void 0,messages:r}:{system:e,messages:t}}var cOe=_(()=>{"use strict"});function t1t(r){if(r===void 0)return"";try{return((typeof r=="string"?r:JSON.stringify(r))??"").substring(0,200)}catch{return"[unserializable]"}}var e1t,DP,lOe=_(()=>{"use strict";Dr();jMe();Vr();H();PP();gp();qMe();Xz();ga();Qz();pte();Tm();MI();Dv();cOe();e1t=_e.generation;DP=class{constructor(e,t,n,o,s,i){this.providerName=e;this.modelName=t;this.supportsToolsFn=n;this.getTelemetryConfigFn=o;this.handleToolStorageFn=s;this.getEmitterFn=i}providerName;modelName;supportsToolsFn;getTelemetryConfigFn;handleToolStorageFn;getEmitterFn;async callGenerateText(e,t,n,o,s,i){let a=this.providerName==="google-ai"||this.providerName==="vertex",c=this.providerName==="anthropic"||this.providerName==="bedrock"||this.providerName==="vertex"&&this.modelName?.startsWith("claude-"),u=i&&(!!o.schema||o.output?.format==="json"||o.output?.format==="structured")&&!HMe(this.providerName,this.modelName,s,Object.keys(n).length),d={...n};if(c&&s&&Object.keys(d).length>0){let y=Object.keys(d),x=y[y.length-1];if(x&&d[x]){let b=d[x];d[x]={...b,providerOptions:{...b.providerOptions??{},anthropic:{cacheControl:{type:"ephemeral"}}}}}}let m=o.prepareStep,{system:f,messages:h}=aOe(t);return await Nf({model:e,...f&&{system:f},messages:h,...s&&Object.keys(d).length>0&&{tools:d},stopWhen:II(o.maxSteps??Ss),...s&&o.toolChoice&&{toolChoice:o.toolChoice},...m&&{experimental_prepareStep:(y=>m({...y,maxSteps:o.maxSteps??Ss}))},temperature:o.temperature,maxOutputTokens:o.maxTokens,maxRetries:0,abortSignal:o.abortSignal,...u&&o.schema&&{experimental_output:l2.object({schema:o.schema})},...o.thinkingConfig?.enabled&&{...c&&o.thinkingConfig.budgetTokens&&!o.thinkingConfig.thinkingLevel&&{experimental_thinking:{type:"enabled",budgetTokens:o.thinkingConfig.budgetTokens}},...a&&{providerOptions:{google:{thinkingConfig:{...o.thinkingConfig.thinkingLevel&&{thinkingLevel:o.thinkingConfig.thinkingLevel},...o.thinkingConfig.budgetTokens&&!o.thinkingConfig.thinkingLevel&&{thinkingBudget:o.thinkingConfig.budgetTokens},includeThoughts:!0}}}}},experimental_telemetry:this.getTelemetryConfigFn(o,"generate"),onStepFinish:({toolCalls:y,toolResults:x})=>{g.info("Tool execution completed",{toolResults:x,toolCalls:y}),ly(this.getEmitterFn?.(),x),this.handleToolStorageFn(y,x,o,new Date).catch(b=>{g.warn("[GenerationHandler] Failed to store tool executions",{provider:this.providerName,error:b instanceof Error?b.message:String(b)})})}})}async executeGeneration(e,t,n,o){return e1t.startActiveSpan("neurolink.executeGeneration",{kind:Cr.INTERNAL},async s=>{let i=!o.disableTools&&this.supportsToolsFn(),a=Object.keys(n||{}).length,c=!!o.schema||o.output?.format==="json"||o.output?.format==="structured";s.setAttribute("gen_ai.system",this.providerName||"unknown"),s.setAttribute("neurolink.structured_output",c),s.setAttribute("neurolink.tool_count",a),s.setAttribute("neurolink.message_count",t.length),s.setAttribute("gen_ai.request.model",Wz(e,this.modelName||"unknown"));let l=o.requestId||o.context?.requestId||"unknown";if(g.info("[GenerationHandler] Calling generateText",{requestId:l,model:Wz(e),messageCount:t.length,toolCount:a,maxSteps:o.maxSteps,temperature:o.temperature}),g.shouldLog("debug"))try{g.debug("[Observability] Full generateText parameters",{requestId:l,model:Wz(e),messageCount:t.length,messages:t.map((d,m)=>({index:m,role:d.role,contentLength:typeof d.content=="string"?d.content.length:t1t(d.content).length,contentPreview:typeof d.content=="string"?d.content.substring(0,200):"[multimodal]"})),toolNames:Object.keys(n||{}),toolCount:a,maxSteps:o.maxSteps,temperature:o.temperature,maxTokens:o.maxTokens})}catch{}let u=Date.now();try{let d=await Yz(()=>this.callGenerateText(e,t,n,o,i,!0),s,"generateText");if(g.info("[GenerationHandler] generateText returned",{requestId:l,durationMs:Date.now()-u,finishReason:d.finishReason,steps:d.steps?.length||1,toolCallsTotal:d.toolCalls?.length||0,responseChars:d.text?.length||0}),g.shouldLog("debug")&&g.debug("[Observability] LLM response metadata",{requestId:l,responseLength:d.text?.length||0,hasToolCalls:!!(d.toolCalls&&d.toolCalls.length>0),toolCallCount:d.toolCalls?.length||0,toolNames:d.toolCalls?.map(m=>m.toolName),finishReason:d.finishReason,stepCount:d.steps?.length||0,steps:d.steps?.map((m,f)=>({stepIndex:f,stepType:m.stepType,textLength:m.text?.length||0,toolCallCount:m.toolCalls?.length||0,toolNames:m.toolCalls?.map(h=>h.toolName),toolResultCount:m.toolResults?.length||0,finishReason:m.finishReason})),usage:d.usage}),d.usage){s.setAttribute("gen_ai.usage.input_tokens",d.usage.inputTokens||0),s.setAttribute("gen_ai.usage.output_tokens",d.usage.outputTokens||0);let m=Uo(this.providerName,this.modelName,{input:d.usage.inputTokens||0,output:d.usage.outputTokens||0,total:(d.usage.inputTokens||0)+(d.usage.outputTokens||0)});s.setAttribute("neurolink.cost",m??0)}return d.finishReason&&s.setAttribute("gen_ai.response.finish_reason",d.finishReason),s.setStatus({code:Ie.OK}),d}catch(d){let m=c&&Zz(d);if(c&&(d instanceof fa||WMe(d)||m)){s.setAttribute("neurolink.has_fallback",!0),s.addEvent("retry.initial_failure",{"error.message":d instanceof Error?d.message:String(d),"retry.attempt":1,"retry.reason":d instanceof fa?"NoObjectGeneratedError_structured_output_fallback":m?"schema_complexity_structured_output_fallback":"tools_schema_conflict_structured_output_fallback"}),m?g.warn("[GenerationHandler] schema too complex for provider constrained decoding \u2014 retrying with prompt-based JSON",{provider:this.providerName,model:this.modelName,error:d instanceof Error?d.message:String(d)}):g.debug("[GenerationHandler] structured-output conflict caught - falling back to manual JSON extraction",{provider:this.providerName,model:this.modelName,error:d instanceof Error?d.message:String(d)});let h=await Yz(()=>this.callGenerateText(e,t,n,o,i,!1),s,"generateText(fallback)");if(s.addEvent("retry.recovered",{"retry.attempts":2,"retry.strategy":"structured_output_disabled"}),s.setAttribute("retry.count",1),g.info("[GenerationHandler] generateText returned (fallback)",{requestId:l,durationMs:Date.now()-u,finishReason:h.finishReason,steps:h.steps?.length||1,toolCallsTotal:h.toolCalls?.length||0,responseChars:h.text?.length||0}),h.usage){s.setAttribute("gen_ai.usage.input_tokens",h.usage.inputTokens||0),s.setAttribute("gen_ai.usage.output_tokens",h.usage.outputTokens||0);let y=Uo(this.providerName,this.modelName,{input:h.usage.inputTokens||0,output:h.usage.outputTokens||0,total:(h.usage.inputTokens||0)+(h.usage.outputTokens||0)});s.setAttribute("neurolink.cost",y??0)}return h.finishReason&&s.setAttribute("gen_ai.response.finish_reason",h.finishReason),s.setStatus({code:Ie.OK}),h}if(KMe(d)&&typeof o.temperature=="number"){s.setAttribute("neurolink.has_fallback",!0),s.addEvent("retry.initial_failure",{"error.message":d instanceof Error?d.message:String(d),"retry.attempt":1,"retry.reason":"temperature_deprecated"}),g.debug("[GenerationHandler] temperature-deprecated error caught - retrying without temperature",{provider:this.providerName,model:this.modelName,error:d instanceof Error?d.message:String(d)});let h=await Yz(()=>this.callGenerateText(e,t,n,{...o,temperature:void 0},i,!0),s,"generateText(no-temperature)");if(s.addEvent("retry.recovered",{"retry.attempts":2,"retry.strategy":"temperature_omitted"}),s.setAttribute("retry.count",1),h.usage){s.setAttribute("gen_ai.usage.input_tokens",h.usage.inputTokens||0),s.setAttribute("gen_ai.usage.output_tokens",h.usage.outputTokens||0);let y=Uo(this.providerName,this.modelName,{input:h.usage.inputTokens||0,output:h.usage.outputTokens||0,total:(h.usage.inputTokens||0)+(h.usage.outputTokens||0)});s.setAttribute("neurolink.cost",y??0)}return h.finishReason&&s.setAttribute("gen_ai.response.finish_reason",h.finishReason),s.setStatus({code:Ie.OK}),h}throw s.setStatus({code:Ie.ERROR,message:d instanceof Error?d.message:String(d)}),d}finally{s.end()}})}extractCacheMetricsFromProviderMetadata(e){let t=e.providerMetadata;if(!t)return{};let n=t.anthropic;if(n){let o=Jee(n),s=Yee(n);return{...o!==void 0&&{cacheCreationTokens:o},...s!==void 0&&{cacheReadTokens:s}}}return{}}logGenerationComplete(e){let t=this.extractCacheMetricsFromProviderMetadata(e);g.shouldLog("debug")&&g.debug("generateText completed",{provider:this.providerName,model:this.modelName,responseLength:e.text?.length||0,toolResultsCount:e.toolResults?.length||0,finishReason:e.finishReason,usage:e.usage,...t.cacheCreationTokens!==void 0&&{cacheCreationTokens:t.cacheCreationTokens},...t.cacheReadTokens!==void 0&&{cacheReadTokens:t.cacheReadTokens},timestamp:Date.now()})}extractToolInformation(e){let t=[],n=[];if(e.toolCalls&&e.toolCalls.length>0&&t.push(...e.toolCalls.map(o=>o.toolName||o.name||"unknown")),e.steps&&Array.isArray(e.steps)){let o=new Map;for(let s of e.steps||[]){if(s?.toolCalls&&Array.isArray(s.toolCalls))for(let i of s.toolCalls){let a=i,c=a.toolName||a.name||"unknown",l=a.toolCallId||a.id||c;t.push(c);let u={};a.args?u=a.args:a.arguments?u=a.arguments:a.parameters&&(u=a.parameters),o.set(l,u),o.set(c,u)}if(s?.toolResults&&Array.isArray(s.toolResults))for(let i of s.toolResults){let a=i,c=a.toolName||"unknown",l=a.toolCallId||a.id,u=a.args??a.arguments??a.parameters??a.input??o.get(l||c)??{};n.push({name:c,input:u,output:a.output??a.result??"success"})}}}return{toolsUsed:[...new Set(t)],toolExecutions:n}}formatEnhancedResult(e,t,n,o,s){let i=!!s.schema||s.output?.format==="json"||s.output?.format==="structured",a,c,l=!1,u=!1,d=x=>{let b=x.replace(/^```(?:json)?\s*\n?/i,"").replace(/\n?```\s*$/i,"").trim(),T=tj(b,s.schema);if(T)return c=T.structuredData,T.repaired&&(l=!0),T.truncated&&(u=!0),T.content;try{let w=JSON.parse(b);if(w!=null)return c=w,b}catch{}return g.warn("[GenerationHandler] schema requested but no JSON could be recovered from model text; returning raw text",{provider:this.providerName,model:this.modelName}),b};if(i)try{let x=e.experimental_output;x!==void 0?(c=x,a=JSON.stringify(x)):a=d(e.text||"")}catch(x){g.debug("[GenerationHandler] experimental_output threw, falling back to text parsing",{error:x instanceof Error?x.message:String(x)}),a=d(e.text||"")}else a=e.text;i&&e.finishReason==="length"&&(u=!0,g.warn("[GenerationHandler] Structured output truncated by token cap (finishReason=length); increase maxTokens",{provider:this.providerName,model:this.modelName}));let m=RE(e.usage);if(m.cacheCreationTokens===void 0||m.cacheReadTokens===void 0){let x=this.extractCacheMetricsFromProviderMetadata(e);if(m.cacheCreationTokens===void 0&&x.cacheCreationTokens!==void 0&&(m.cacheCreationTokens=x.cacheCreationTokens),m.cacheReadTokens===void 0&&x.cacheReadTokens!==void 0&&(m.cacheReadTokens=x.cacheReadTokens),m.cacheReadTokens!==void 0){let b=Xee(m.cacheReadTokens,m.input);b!==void 0&&(m.cacheSavingsPercent=b)}}let f=e.reasoning,h=f?typeof f=="string"?f:Array.isArray(f)?f.map(x=>typeof x=="string"?x:x.text??JSON.stringify(x)).join(`
810
+ `,r:"\r",t:" "}});var sOe=_(()=>{oOe()});function ute(r,e=0){for(let t=e;t<r.length;t++){let n=r[t];if(n!=="{"&&n!=="[")continue;let o=n==="{"?"}":"]",s=0,i=!1,a=!1;for(let c=t;c<r.length;c++){let l=r[c];if(a){a=!1;continue}if(l==="\\"){a=!0;continue}if(l==='"'){i=!i;continue}if(!i){if(l===n)s++;else if(l===o&&(s--,s===0))return{span:r.substring(t,c+1),end:c+1}}}}return null}var iOe=_(()=>{"use strict"});function XLt(r){return typeof r.safeParse=="function"}function ZLt(r){try{return{value:JSON.parse(r),repaired:!1}}catch{}try{let e=lte(r),t=JSON.parse(e);return e!==r&&g.shouldLog("debug")&&g.debug("[coerceJsonToSchema] jsonrepair altered model output",{originalLength:r.length,repairedLength:e.length}),{value:t,repaired:e!==r}}catch{return}}function dte(r,e=0){if(e>QLt)return{value:r,changed:!1};if(typeof r=="string"){let t=r.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let o=JSON.parse(t);if(o!==null&&typeof o=="object")return{value:o,changed:!0}}catch{}return{value:r,changed:!1}}if(Array.isArray(r)){let t=!1,n=r.map(o=>{let s=dte(o,e+1);return s.changed&&(t=!0),s.value});return{value:t?n:r,changed:t}}if(r!==null&&typeof r=="object"){let t=!1,n={};for(let[o,s]of Object.entries(r)){let i=dte(s,e+1);i.changed&&(t=!0),n[o]=i.value}return{value:t?n:r,changed:t}}return{value:r,changed:!1}}function tj(r,e){if(typeof r!="string"||r.trim().length===0)return null;let t=[],n=0;for(;;){let h=ute(r,n);if(!h)break;t.push({text:h.span,truncated:!1}),n=h.end}let o=[r.indexOf("{"),r.indexOf("[")].filter(h=>h>=0),s=o.length>0?Math.min(...o):-1,i=Math.max(r.lastIndexOf("}"),r.lastIndexOf("]"));s>=0&&i>s&&t.push({text:r.slice(s,i+1),truncated:!1}),s>=0&&t.push({text:r.slice(s),truncated:!0});let a=r.trim();if(a.length>1&&a.startsWith('"')&&a.endsWith('"'))try{let h=JSON.parse(a);if(typeof h=="string"){let y=0;for(;;){let x=ute(h,y);if(!x)break;t.push({text:x.span,truncated:!1}),y=x.end}}}catch{}let c,l=[],u=!!(e&&XLt(e)),d=new Set;for(let h of t){if(d.has(h.text))continue;d.add(h.text);let y=ZLt(h.text);if(y===void 0||y.value===null||typeof y.value!="object")continue;let x={value:y.value,repaired:y.repaired,truncated:h.truncated};if(c===void 0&&(c=x),!u)break;let b=e;if(b.safeParse(y.value).success)l.push(x);else{let T=dte(y.value);T.changed&&T.value!==null&&typeof T.value=="object"&&b.safeParse(T.value).success&&l.push({value:T.value,repaired:!0,truncated:h.truncated})}}let f=(l.length>0?l.reduce((h,y)=>JSON.stringify(y.value).length>JSON.stringify(h.value).length?y:h):void 0)??c;return f===void 0?null:{content:JSON.stringify(f.value),structuredData:f.value,repaired:f.repaired,truncated:f.truncated}}var QLt,pte=_(()=>{"use strict";sOe();H();iOe();QLt=6});function aOe(r){let e=[],t=[];for(let n of r)n.role==="system"?e.push(n):t.push(n);return e.length===0||t.length===0?{system:void 0,messages:r}:{system:e,messages:t}}var cOe=_(()=>{"use strict"});function t1t(r){if(r===void 0)return"";try{return((typeof r=="string"?r:JSON.stringify(r))??"").substring(0,200)}catch{return"[unserializable]"}}var e1t,DP,lOe=_(()=>{"use strict";Dr();jMe();Vr();H();PP();gp();qMe();Xz();ga();Qz();pte();Tm();MI();Dv();cOe();e1t=_e.generation;DP=class{constructor(e,t,n,o,s,i){this.providerName=e;this.modelName=t;this.supportsToolsFn=n;this.getTelemetryConfigFn=o;this.handleToolStorageFn=s;this.getEmitterFn=i}providerName;modelName;supportsToolsFn;getTelemetryConfigFn;handleToolStorageFn;getEmitterFn;async callGenerateText(e,t,n,o,s,i){let a=this.providerName==="google-ai"||this.providerName==="vertex",c=this.providerName==="anthropic"||this.providerName==="bedrock"||this.providerName==="vertex"&&this.modelName?.startsWith("claude-"),u=i&&(!!o.schema||o.output?.format==="json"||o.output?.format==="structured")&&!HMe(this.providerName,this.modelName,s,Object.keys(n).length),d={...n};if(c&&s&&Object.keys(d).length>0){let y=Object.keys(d),x=y[y.length-1];if(x&&d[x]){let b=d[x];d[x]={...b,providerOptions:{...b.providerOptions??{},anthropic:{cacheControl:{type:"ephemeral"}}}}}}let m=o.prepareStep,{system:f,messages:h}=aOe(t);return await Nf({model:e,...f&&{system:f},messages:h,...s&&Object.keys(d).length>0&&{tools:d},stopWhen:II(o.maxSteps??Ss),...s&&o.toolChoice&&{toolChoice:o.toolChoice},...m&&{experimental_prepareStep:(y=>m({...y,maxSteps:o.maxSteps??Ss}))},temperature:o.temperature,maxOutputTokens:o.maxTokens,maxRetries:0,abortSignal:o.abortSignal,...u&&o.schema&&{experimental_output:l2.object({schema:o.schema})},...o.thinkingConfig?.enabled&&{...c&&o.thinkingConfig.budgetTokens&&!o.thinkingConfig.thinkingLevel&&{experimental_thinking:{type:"enabled",budgetTokens:o.thinkingConfig.budgetTokens}},...a&&{providerOptions:{google:{thinkingConfig:{...o.thinkingConfig.thinkingLevel&&{thinkingLevel:o.thinkingConfig.thinkingLevel},...o.thinkingConfig.budgetTokens&&!o.thinkingConfig.thinkingLevel&&{thinkingBudget:o.thinkingConfig.budgetTokens},includeThoughts:!0}}}}},experimental_telemetry:this.getTelemetryConfigFn(o,"generate"),onStepFinish:({toolCalls:y,toolResults:x})=>{g.info("Tool execution completed",{toolResults:x,toolCalls:y}),ly(this.getEmitterFn?.(),x),this.handleToolStorageFn(y,x,o,new Date).catch(b=>{g.warn("[GenerationHandler] Failed to store tool executions",{provider:this.providerName,error:b instanceof Error?b.message:String(b)})})}})}async executeGeneration(e,t,n,o){return e1t.startActiveSpan("neurolink.executeGeneration",{kind:Cr.INTERNAL},async s=>{let i=!o.disableTools&&this.supportsToolsFn(),a=Object.keys(n||{}).length,c=!!o.schema||o.output?.format==="json"||o.output?.format==="structured";s.setAttribute("gen_ai.system",this.providerName||"unknown"),s.setAttribute("neurolink.structured_output",c),s.setAttribute("neurolink.tool_count",a),s.setAttribute("neurolink.message_count",t.length),s.setAttribute("gen_ai.request.model",Wz(e,this.modelName||"unknown"));let l=o.requestId||o.context?.requestId||"unknown";if(g.info("[GenerationHandler] Calling generateText",{requestId:l,model:Wz(e),messageCount:t.length,toolCount:a,maxSteps:o.maxSteps,temperature:o.temperature}),g.shouldLog("debug"))try{g.debug("[Observability] Full generateText parameters",{requestId:l,model:Wz(e),messageCount:t.length,messages:t.map((d,m)=>({index:m,role:d.role,contentLength:typeof d.content=="string"?d.content.length:t1t(d.content).length,contentPreview:typeof d.content=="string"?d.content.substring(0,200):"[multimodal]"})),toolNames:Object.keys(n||{}),toolCount:a,maxSteps:o.maxSteps,temperature:o.temperature,maxTokens:o.maxTokens})}catch{}let u=Date.now();try{let d=await Yz(()=>this.callGenerateText(e,t,n,o,i,!0),s,"generateText");if(g.info("[GenerationHandler] generateText returned",{requestId:l,durationMs:Date.now()-u,finishReason:d.finishReason,steps:d.steps?.length||1,toolCallsTotal:d.toolCalls?.length||0,responseChars:d.text?.length||0}),g.shouldLog("debug")&&g.debug("[Observability] LLM response metadata",{requestId:l,responseLength:d.text?.length||0,hasToolCalls:!!(d.toolCalls&&d.toolCalls.length>0),toolCallCount:d.toolCalls?.length||0,toolNames:d.toolCalls?.map(m=>m.toolName),finishReason:d.finishReason,stepCount:d.steps?.length||0,steps:d.steps?.map((m,f)=>({stepIndex:f,stepType:m.stepType,textLength:m.text?.length||0,toolCallCount:m.toolCalls?.length||0,toolNames:m.toolCalls?.map(h=>h.toolName),toolResultCount:m.toolResults?.length||0,finishReason:m.finishReason})),usage:d.usage}),d.usage){s.setAttribute("gen_ai.usage.input_tokens",d.usage.inputTokens||0),s.setAttribute("gen_ai.usage.output_tokens",d.usage.outputTokens||0);let m=Uo(this.providerName,this.modelName,{input:d.usage.inputTokens||0,output:d.usage.outputTokens||0,total:(d.usage.inputTokens||0)+(d.usage.outputTokens||0)});s.setAttribute("neurolink.cost",m??0)}return d.finishReason&&s.setAttribute("gen_ai.response.finish_reason",d.finishReason),s.setStatus({code:Ie.OK}),d}catch(d){let m=c&&Zz(d);if(c&&(d instanceof fa||WMe(d)||m)){s.setAttribute("neurolink.has_fallback",!0),s.addEvent("retry.initial_failure",{"error.message":d instanceof Error?d.message:String(d),"retry.attempt":1,"retry.reason":d instanceof fa?"NoObjectGeneratedError_structured_output_fallback":m?"schema_complexity_structured_output_fallback":"tools_schema_conflict_structured_output_fallback"}),m?g.warn("[GenerationHandler] schema too complex for provider constrained decoding \u2014 retrying with prompt-based JSON",{provider:this.providerName,model:this.modelName,error:d instanceof Error?d.message:String(d)}):g.debug("[GenerationHandler] structured-output conflict caught - falling back to manual JSON extraction",{provider:this.providerName,model:this.modelName,error:d instanceof Error?d.message:String(d)});let h=await Yz(()=>this.callGenerateText(e,t,n,o,i,!1),s,"generateText(fallback)");if(s.addEvent("retry.recovered",{"retry.attempts":2,"retry.strategy":"structured_output_disabled"}),s.setAttribute("retry.count",1),g.info("[GenerationHandler] generateText returned (fallback)",{requestId:l,durationMs:Date.now()-u,finishReason:h.finishReason,steps:h.steps?.length||1,toolCallsTotal:h.toolCalls?.length||0,responseChars:h.text?.length||0}),h.usage){s.setAttribute("gen_ai.usage.input_tokens",h.usage.inputTokens||0),s.setAttribute("gen_ai.usage.output_tokens",h.usage.outputTokens||0);let y=Uo(this.providerName,this.modelName,{input:h.usage.inputTokens||0,output:h.usage.outputTokens||0,total:(h.usage.inputTokens||0)+(h.usage.outputTokens||0)});s.setAttribute("neurolink.cost",y??0)}return h.finishReason&&s.setAttribute("gen_ai.response.finish_reason",h.finishReason),s.setStatus({code:Ie.OK}),h}if(KMe(d)&&typeof o.temperature=="number"){s.setAttribute("neurolink.has_fallback",!0),s.addEvent("retry.initial_failure",{"error.message":d instanceof Error?d.message:String(d),"retry.attempt":1,"retry.reason":"temperature_deprecated"}),g.debug("[GenerationHandler] temperature-deprecated error caught - retrying without temperature",{provider:this.providerName,model:this.modelName,error:d instanceof Error?d.message:String(d)});let h=await Yz(()=>this.callGenerateText(e,t,n,{...o,temperature:void 0},i,!0),s,"generateText(no-temperature)");if(s.addEvent("retry.recovered",{"retry.attempts":2,"retry.strategy":"temperature_omitted"}),s.setAttribute("retry.count",1),h.usage){s.setAttribute("gen_ai.usage.input_tokens",h.usage.inputTokens||0),s.setAttribute("gen_ai.usage.output_tokens",h.usage.outputTokens||0);let y=Uo(this.providerName,this.modelName,{input:h.usage.inputTokens||0,output:h.usage.outputTokens||0,total:(h.usage.inputTokens||0)+(h.usage.outputTokens||0)});s.setAttribute("neurolink.cost",y??0)}return h.finishReason&&s.setAttribute("gen_ai.response.finish_reason",h.finishReason),s.setStatus({code:Ie.OK}),h}throw s.setStatus({code:Ie.ERROR,message:d instanceof Error?d.message:String(d)}),d}finally{s.end()}})}extractCacheMetricsFromProviderMetadata(e){let t=e.providerMetadata;if(!t)return{};let n=t.anthropic;if(n){let o=Jee(n),s=Yee(n);return{...o!==void 0&&{cacheCreationTokens:o},...s!==void 0&&{cacheReadTokens:s}}}return{}}logGenerationComplete(e){let t=this.extractCacheMetricsFromProviderMetadata(e);g.shouldLog("debug")&&g.debug("generateText completed",{provider:this.providerName,model:this.modelName,responseLength:e.text?.length||0,toolResultsCount:e.toolResults?.length||0,finishReason:e.finishReason,usage:e.usage,...t.cacheCreationTokens!==void 0&&{cacheCreationTokens:t.cacheCreationTokens},...t.cacheReadTokens!==void 0&&{cacheReadTokens:t.cacheReadTokens},timestamp:Date.now()})}extractToolInformation(e){let t=[],n=[];if(e.toolCalls&&e.toolCalls.length>0&&t.push(...e.toolCalls.map(o=>o.toolName||o.name||"unknown")),e.steps&&Array.isArray(e.steps)){let o=new Map;for(let s of e.steps||[]){if(s?.toolCalls&&Array.isArray(s.toolCalls))for(let i of s.toolCalls){let a=i,c=a.toolName||a.name||"unknown",l=a.toolCallId||a.id||c;t.push(c);let u={};a.args?u=a.args:a.arguments?u=a.arguments:a.parameters&&(u=a.parameters),o.set(l,u),o.set(c,u)}if(s?.toolResults&&Array.isArray(s.toolResults))for(let i of s.toolResults){let a=i,c=a.toolName||"unknown",l=a.toolCallId||a.id,u=a.args??a.arguments??a.parameters??a.input??o.get(l||c)??{};n.push({name:c,input:u,output:a.output??a.result??"success"})}}}return{toolsUsed:[...new Set(t)],toolExecutions:n}}formatEnhancedResult(e,t,n,o,s){let i=!!s.schema||s.output?.format==="json"||s.output?.format==="structured",a,c,l=!1,u=!1,d=x=>{let b=x.replace(/^```(?:json)?\s*\n?/i,"").replace(/\n?```\s*$/i,"").trim(),T=tj(b,s.schema);if(T)return c=T.structuredData,T.repaired&&(l=!0),T.truncated&&(u=!0),T.content;try{let w=JSON.parse(b);if(w==="")return g.warn("[GenerationHandler] schema requested but the model returned an empty JSON string; normalizing to empty content",{provider:this.providerName,model:this.modelName}),"";if(w!=null)return c=w,b}catch{}return g.warn("[GenerationHandler] schema requested but no JSON could be recovered from model text; returning raw text",{provider:this.providerName,model:this.modelName}),b};if(i)try{let x=e.experimental_output,b=typeof x=="string"&&x===(e.text??"");x!==void 0&&!b?(c=x,a=JSON.stringify(x)):a=d(e.text||"")}catch(x){g.debug("[GenerationHandler] experimental_output threw, falling back to text parsing",{error:x instanceof Error?x.message:String(x)}),a=d(e.text||"")}else a=e.text;i&&e.finishReason==="length"&&(u=!0,g.warn("[GenerationHandler] Structured output truncated by token cap (finishReason=length); increase maxTokens",{provider:this.providerName,model:this.modelName}));let m=RE(e.usage);if(m.cacheCreationTokens===void 0||m.cacheReadTokens===void 0){let x=this.extractCacheMetricsFromProviderMetadata(e);if(m.cacheCreationTokens===void 0&&x.cacheCreationTokens!==void 0&&(m.cacheCreationTokens=x.cacheCreationTokens),m.cacheReadTokens===void 0&&x.cacheReadTokens!==void 0&&(m.cacheReadTokens=x.cacheReadTokens),m.cacheReadTokens!==void 0){let b=Xee(m.cacheReadTokens,m.input);b!==void 0&&(m.cacheSavingsPercent=b)}}let f=e.reasoning,h=f?typeof f=="string"?f:Array.isArray(f)?f.map(x=>typeof x=="string"?x:x.text??JSON.stringify(x)).join(`
811
811
  `):String(f):void 0,y=m.reasoning??void 0;return{content:a,structuredData:c,usage:m,finishReason:e.finishReason,jsonRepaired:l||void 0,jsonTruncated:u||void 0,provider:this.providerName,model:this.modelName,reasoning:h,reasoningTokens:y,toolCalls:e.toolCalls?e.toolCalls.map(x=>({toolCallId:x.toolCallId||"unknown",toolName:x.toolName||"unknown",args:x.args||{}})):[],toolResults:e.toolResults??[],toolsUsed:n,toolExecutions:o,availableTools:Object.keys(t).map(x=>{let b=t[x];return{name:x,description:b.description||"No description available",parameters:b.inputSchema||{},server:b.serverId||"direct"}})}}analyzeAIResponse(e){g.debug("NeuroLink Raw AI Response Analysis",{provider:this.providerName,model:this.modelName,responseTextLength:e.text?.length||0,responsePreview:e.text?.substring(0,500)??"",finishReason:e.finishReason,usage:e.usage});let t={hasToolCalls:!!e.toolCalls,toolCallsLength:e.toolCalls?.length||0,toolCalls:e.toolCalls?.map((n,o)=>{let s=n,i=s.toolName||s.name||"unknown";return{index:o+1,toolName:i,toolId:s.toolCallId||s.id||"none",hasArgs:!!s.args,argsKeys:s.args&&typeof s.args=="object"?Object.keys(s.args):[]}})||[]};g.debug("Tool Calls Analysis",t)}}});var gte={};ee(gte,{Agent:()=>fte,BedrockClient:()=>n1t,BedrockRuntimeClient:()=>s1t,Blob:()=>z1t,Client:()=>G1t,ConverseCommand:()=>i1t,ConverseStreamCommand:()=>a1t,Cron:()=>E1t,Dispatcher:()=>V1t,File:()=>B1t,FlowProducer:()=>w1t,FormData:()=>$1t,GoogleAuth:()=>p1t,HTTPException:()=>P1t,Headers:()=>F1t,Hippocampus:()=>h1t,HippocampusConfig:()=>y1t,Hono:()=>A1t,ImageFormat:()=>c1t,InvokeEndpointCommand:()=>u1t,InvokeEndpointWithResponseStreamCommand:()=>d1t,Job:()=>T1t,ListFoundationModelsCommand:()=>o1t,MockAgent:()=>H1t,Pool:()=>j1t,Queue:()=>v1t,QueueScheduler:()=>S1t,Request:()=>L1t,Response:()=>U1t,SageMakerRuntimeClient:()=>l1t,TextToSpeechClient:()=>f1t,VertexAI:()=>m1t,Webhook:()=>g1t,Worker:()=>b1t,convertToHtml:()=>R1t,cors:()=>I1t,createClient:()=>x1t,default:()=>r1t,extractRawText:()=>C1t,fetch:()=>mte,getGlobalDispatcher:()=>PE,interceptors:()=>ME,logger:()=>M1t,parseBuffer:()=>_1t,request:()=>OE,secureHeaders:()=>O1t,selectCover:()=>k1t,setGlobalDispatcher:()=>q1t,streamSSE:()=>N1t,timeout:()=>D1t});var IE,ui,r1t,n1t,o1t,s1t,i1t,a1t,c1t,l1t,u1t,d1t,p1t,m1t,f1t,g1t,h1t,y1t,x1t,v1t,b1t,T1t,S1t,w1t,E1t,_1t,k1t,C1t,R1t,A1t,I1t,P1t,M1t,O1t,N1t,D1t,mte,L1t,U1t,F1t,$1t,B1t,z1t,fte,j1t,G1t,V1t,q1t,PE,H1t,ME,OE,NE=_(()=>{IE={get(r,e){return e==="__esModule"?!0:e==="default"?new Proxy({},{get:IE.get}):new Proxy(function(...t){return new Proxy({},{get:IE.get})},{get:IE.get,apply(t,n,o){return new Proxy({},{get:IE.get})},construct(t,n){return new Proxy({},{get:IE.get})}})}},ui=new Proxy({},IE),r1t=ui,{BedrockClient:n1t,ListFoundationModelsCommand:o1t,BedrockRuntimeClient:s1t,ConverseCommand:i1t,ConverseStreamCommand:a1t,ImageFormat:c1t}=ui,{SageMakerRuntimeClient:l1t,InvokeEndpointCommand:u1t,InvokeEndpointWithResponseStreamCommand:d1t}=ui,{GoogleAuth:p1t,VertexAI:m1t,TextToSpeechClient:f1t}=ui,{Webhook:g1t}=ui,{Hippocampus:h1t,HippocampusConfig:y1t}=ui,{createClient:x1t}=ui,{Queue:v1t,Worker:b1t,Job:T1t,QueueScheduler:S1t,FlowProducer:w1t}=ui,{Cron:E1t}=ui,{parseBuffer:_1t,selectCover:k1t}=ui,{extractRawText:C1t,convertToHtml:R1t}=ui,{Hono:A1t}=ui,{cors:I1t,HTTPException:P1t,logger:M1t,secureHeaders:O1t,streamSSE:N1t,timeout:D1t}=ui,mte=globalThis.fetch,L1t=globalThis.Request,U1t=globalThis.Response,F1t=globalThis.Headers,$1t=globalThis.FormData,B1t=globalThis.File,z1t=globalThis.Blob,fte=ui.Agent,j1t=ui.Pool,G1t=ui.Client,V1t=ui.Dispatcher,q1t=()=>{},PE=()=>ui,H1t=ui.MockAgent,ME={redirect:()=>r=>r,retry:()=>r=>r},OE=async(r,e)=>{let t=await globalThis.fetch(r,e);return{statusCode:t.status,headers:Object.fromEntries(t.headers.entries()),body:{text:()=>t.text(),json:()=>t.json(),arrayBuffer:()=>t.arrayBuffer()}}}});var W1t,hte,uOe,dOe=_(()=>{"use strict";H();It();W1t={maxTokens:10,refillIntervalMs:1e3,tokensPerRefill:10,maxQueueSize:100,queueTimeoutMs:3e4},hte=class{tokens;config;queue=[];refillTimer=null;lastRefillTime;constructor(e={}){this.config={...W1t,...e},this.tokens=this.config.maxTokens,this.lastRefillTime=Date.now(),this.startRefillTimer()}startRefillTimer(){this.refillTimer||(this.refillTimer=setInterval(()=>{this.refillTokens(),this.processQueue()},this.config.refillIntervalMs),this.refillTimer.unref())}refillTokens(){let e=Date.now(),t=e-this.lastRefillTime,n=Math.floor(t/this.config.refillIntervalMs);if(n>0){let o=n*this.config.tokensPerRefill;this.tokens=Math.min(this.config.maxTokens,this.tokens+o),this.lastRefillTime=e}}processQueue(){let e=Date.now();for(;this.queue.length>0;){let t=this.queue[0];if(e-t.timestamp>this.config.queueTimeoutMs)this.queue.shift(),t.timeoutTimer&&clearTimeout(t.timeoutTimer),t.reject(pe.rateLimiterQueueTimeout(this.config.queueTimeoutMs));else break}for(;this.tokens>0&&this.queue.length>0;){let t=this.queue.shift();t&&(t.timeoutTimer&&clearTimeout(t.timeoutTimer),this.tokens--,t.resolve())}}async acquire(){if(this.refillTokens(),this.tokens>0){this.tokens--;return}if(this.queue.length>=this.config.maxQueueSize)throw g.warn(`Rate limiter queue full (${this.config.maxQueueSize} requests pending)`),pe.rateLimiterQueueFull(this.config.maxQueueSize);return new Promise((e,t)=>{let n=setTimeout(()=>{let o=this.queue.findIndex(s=>s.timeoutTimer===n);o!==-1&&(this.queue.splice(o,1),t(pe.rateLimiterQueueTimeout(this.config.queueTimeoutMs)))},this.config.queueTimeoutMs);this.queue.push({resolve:e,reject:t,timestamp:Date.now(),timeoutTimer:n})})}getStats(){return{availableTokens:this.tokens,queueLength:this.queue.length,maxTokens:this.config.maxTokens,maxQueueSize:this.config.maxQueueSize}}reset(){for(this.tokens=this.config.maxTokens,this.lastRefillTime=Date.now();this.queue.length>0;){let e=this.queue.shift();e&&(e.timeoutTimer&&clearTimeout(e.timeoutTimer),e.reject(pe.rateLimiterReset()))}}stop(){this.refillTimer&&(clearInterval(this.refillTimer),this.refillTimer=null),this.reset()}},uOe=new hte({maxTokens:10,refillIntervalMs:1e3,tokensPerRefill:10,maxQueueSize:100,queueTimeoutMs:3e4})});function pOe(r,e=ml.DEFAULT_INITIAL_DELAY,t=ml.DEFAULT_BACKOFF_MULTIPLIER,n=ml.DEFAULT_MAX_DELAY,o=!0){let s=e*Math.pow(t,r-1),i=Math.min(s,n),a=o?Math.random()*Math.min(i*.1,1e3):0;return i+a}function mOe(r){return new Promise(e=>setTimeout(e,r))}var yte,xte,IEn,vte,bte,Tte,PEn,MEn,OEn,fOe=_(()=>{"use strict";H();ga();yte=class extends Error{constructor(t,n){super(t);this.cause=n;this.name="NetworkError"}cause},xte=class extends Error{constructor(t,n){super(t);this.cause=n;this.name="TemporaryError"}cause},IEn={maxAttempts:ml.DEFAULT_RETRY_ATTEMPTS,initialDelay:ml.DEFAULT_INITIAL_DELAY,maxDelay:ml.DEFAULT_MAX_DELAY,backoffMultiplier:ml.DEFAULT_BACKOFF_MULTIPLIER,retryCondition:r=>{if(r instanceof yte||r instanceof xte||r&&typeof r=="object"&&(r.name==="TimeoutError"||r.code==="TIMEOUT")||r&&typeof r=="object"&&(r.code==="ECONNRESET"||r.code==="ENOTFOUND"||r.code==="ECONNREFUSED"||r.code==="ETIMEDOUT"))return!0;if(r&&typeof r=="object"&&r.status){let e=Number(r.status);return e>=500||e===429||e===408}return!1},onRetry:(r,e)=>{let t=e instanceof Error?e.message:String(e);g.warn(`\u26A0\uFE0F Retry attempt ${r}: ${t}`)}};vte=class{constructor(e=5,t=6e4,n=6e5){this.threshold=e;this.timeout=t;this.monitorWindow=n}threshold;timeout;monitorWindow;failures=0;lastFailureTime=0;state="closed";async execute(e){if(this.state==="open")if(Date.now()-this.lastFailureTime>this.timeout)this.state="half-open";else throw new Error("Circuit breaker is open - operation rejected");try{let t=await e();return this.onSuccess(),t}catch(t){throw this.onFailure(),t}}onSuccess(){this.failures=0,this.state="closed"}onFailure(){this.failures++,this.lastFailureTime=Date.now(),this.failures>=this.threshold&&(this.state="open")}getState(){return this.state}reset(){this.failures=0,this.lastFailureTime=0,this.state="closed"}},bte=class{constructor(e,t){this.maxRequests=e;this.windowMs=t}maxRequests;windowMs;requests=[];async acquire(){let e=Date.now();if(this.requests=this.requests.filter(t=>e-t<this.windowMs),this.requests.length>=this.maxRequests){let t=Math.min(...this.requests),n=this.windowMs-(e-t);if(n>0)return await mOe(n),this.acquire()}this.requests.push(e)}},Tte=class{operations=new Set;shutdownPromise=null;track(e){return this.operations.add(e),e.finally(()=>{this.operations.delete(e)}),e}async shutdown(e=3e4){return this.shutdownPromise?this.shutdownPromise:(this.shutdownPromise=this.performShutdown(e),this.shutdownPromise)}async performShutdown(e){g.debug(`\u{1F504} Graceful shutdown: waiting for ${this.operations.size} operations...`);try{await Promise.race([Promise.all(this.operations),mOe(e).then(()=>{throw new Error(`Shutdown timeout: ${this.operations.size} operations still running`)})]),g.debug("\u2705 Graceful shutdown completed")}catch(t){g.warn(`\u26A0\uFE0F Shutdown warning: ${t instanceof Error?t.message:String(t)}`)}}},PEn=new Tte,MEn=new vte(3,3e4),OEn=new bte(100,6e4)});var LP={};ee(LP,{AsyncLocalStorage:()=>dUt,Buffer:()=>t$t,Channel:()=>VFt,DatabaseSync:()=>e$t,Duplex:()=>mUt,EventEmitter:()=>uUt,Http2ServerRequest:()=>i$t,Http2ServerResponse:()=>a$t,Interface:()=>QFt,MIMEType:()=>m$t,PassThrough:()=>fUt,PerformanceObserver:()=>zFt,Readable:()=>gOe,ReadableStream:()=>gUt,Resolver:()=>$Ft,TextDecoder:()=>xOe,TextEncoder:()=>rj,Transform:()=>pUt,URL:()=>kFt,URLSearchParams:()=>CFt,Worker:()=>KFt,Writable:()=>hOe,access:()=>GUt,appendFile:()=>SUt,appendFileSync:()=>X1t,arch:()=>sFt,arrayBuffer:()=>c$t,basename:()=>nUt,builtinModules:()=>SFt,callbackify:()=>NFt,channel:()=>GFt,chmodSync:()=>TUt,clearInterval:()=>p$t,clearTimeout:()=>u$t,closeSync:()=>kUt,connect:()=>lFt,constants:()=>r$t,copyFileSync:()=>EUt,cpSync:()=>Z1t,cpus:()=>tFt,createConnection:()=>uFt,createGunzip:()=>yFt,createGzip:()=>xFt,createHash:()=>$c,createHmac:()=>Ste,createInterface:()=>ZFt,createReadStream:()=>LUt,createRequire:()=>TFt,createServer:()=>Q1t,createWriteStream:()=>DUt,debug:()=>MFt,debuglog:()=>yOe,default:()=>K1t,deflateSync:()=>pFt,deprecate:()=>OFt,deserialize:()=>WFt,dirname:()=>rUt,exec:()=>WUt,execFile:()=>JUt,execFileSync:()=>YUt,execSync:()=>KUt,existsSync:()=>xUt,extname:()=>oUt,fileURLToPath:()=>RFt,finished:()=>yUt,format:()=>_Ft,freemem:()=>rFt,fstatSync:()=>CUt,get:()=>cFt,gunzip:()=>hFt,gunzipSync:()=>mFt,gzip:()=>gFt,gzipSync:()=>fFt,hasSubscribers:()=>qFt,homedir:()=>ZUt,hostname:()=>eFt,inflateSync:()=>dFt,inherits:()=>IFt,inspect:()=>nj,isAbsolute:()=>iUt,isBuiltin:()=>wFt,isDeepStrictEqual:()=>DFt,isIP:()=>s$t,isIPv4:()=>o$t,isIPv6:()=>n$t,isMainThread:()=>JFt,join:()=>eUt,lookup:()=>FFt,mkdir:()=>$Ut,mkdirSync:()=>RUt,monitorEventLoopDelay:()=>jFt,normalize:()=>lUt,ok:()=>vFt,openSync:()=>_Ut,parentPort:()=>YFt,parse:()=>EFt,pathToFileURL:()=>AFt,performance:()=>BFt,pipeline:()=>hUt,platform:()=>XUt,posix:()=>cUt,promises:()=>J1t,promisify:()=>PFt,randomBytes:()=>Sm,randomUUID:()=>He,readFile:()=>UUt,readFileSync:()=>vUt,readdir:()=>zUt,readdirSync:()=>IUt,realpathSync:()=>wUt,relative:()=>sUt,release:()=>iFt,rename:()=>VUt,renameSync:()=>MUt,request:()=>aFt,resolve:()=>tUt,rm:()=>qUt,rmSync:()=>NUt,rmdirSync:()=>OUt,sep:()=>aUt,serialize:()=>HFt,setInterval:()=>d$t,setTimeout:()=>l$t,spawn:()=>HUt,stat:()=>BUt,statSync:()=>AUt,strict:()=>bFt,tmpdir:()=>QUt,toUSVString:()=>LFt,totalmem:()=>nFt,type:()=>oFt,types:()=>UFt,unlink:()=>jUt,unlinkSync:()=>PUt,webcrypto:()=>Y1t,workerData:()=>XFt,writeFile:()=>FUt,writeFileSync:()=>bUt});var rs,di,K1t,J1t,$c,Ste,Sm,He,Y1t,X1t,Z1t,Q1t,eUt,tUt,rUt,nUt,oUt,sUt,iUt,aUt,cUt,lUt,uUt,dUt,gOe,hOe,pUt,mUt,fUt,gUt,hUt,yUt,xUt,vUt,bUt,TUt,SUt,wUt,EUt,_Ut,kUt,CUt,RUt,AUt,IUt,PUt,MUt,OUt,NUt,DUt,LUt,UUt,FUt,$Ut,BUt,zUt,jUt,GUt,VUt,qUt,HUt,WUt,KUt,JUt,YUt,XUt,ZUt,QUt,eFt,tFt,rFt,nFt,oFt,sFt,iFt,aFt,cFt,lFt,uFt,dFt,pFt,mFt,fFt,gFt,hFt,yFt,xFt,vFt,bFt,TFt,SFt,wFt,EFt,_Ft,kFt,CFt,RFt,AFt,IFt,PFt,yOe,MFt,nj,OFt,NFt,DFt,LFt,UFt,xOe,rj,FFt,$Ft,BFt,zFt,jFt,GFt,VFt,qFt,HFt,WFt,KFt,JFt,YFt,XFt,ZFt,QFt,e$t,t$t,r$t,n$t,o$t,s$t,i$t,a$t,c$t,vOe,l$t,u$t,d$t,p$t,m$t,vr=_(()=>{rs=()=>{},di=async()=>{},K1t={},J1t={readFile:di,writeFile:di,mkdir:di,stat:di,readdir:di,unlink:di,access:di,rm:di,rename:di},$c=r=>{let e=[];return{update(t){return e.push(typeof t=="string"?new rj().encode(t):t),this},digest(t){let n=0;for(let s of e)for(let i=0;i<s.length;i++)n=(n<<5)-n+s[i]|0;let o=(n>>>0).toString(16).padStart(8,"0");return t==="hex"?o:t==="base64"?btoa(o):o}}},Ste=(r,e)=>$c(r),Sm=r=>new Uint8Array(r||32),He=()=>globalThis.crypto?.randomUUID?.()||Math.random().toString(36),Y1t=globalThis.crypto,X1t=()=>{throw new Error("[NeuroLink:browser] fs.appendFileSync is not supported in browser runtime \u2014 use server-side execution")},Z1t=()=>{throw new Error("[NeuroLink:browser] fs.cpSync is not supported in browser runtime \u2014 use server-side execution")},Q1t=()=>({listen:rs,close:rs,on:rs}),eUt=(...r)=>r.join("/"),tUt=(...r)=>r.join("/"),rUt=r=>r||"",nUt=r=>r?.split?.("/")?.pop?.()||"",oUt=r=>{let e=r?.match?.(/\.[^.]+$/);return e?e[0]:""},sUt=(r,e)=>e||"",iUt=()=>!1,aUt="/",cUt={normalize:r=>r,join:(...r)=>r.join("/"),resolve:(...r)=>r.join("/"),sep:"/"},lUt=r=>r,uUt=class{on(){return this}off(){return this}emit(){return this}once(){return this}removeListener(){return this}addListener(){return this}},dUt=class{getStore(){}run(r,e,...t){return e(...t)}enterWith(){}disable(){}},gOe=class{pipe(){return this}on(){return this}read(){return null}push(){}destroy(){}},hOe=class{write(){return!0}end(){}on(){return this}destroy(){}},pUt=class{push(){}on(){return this}},mUt=class{on(){return this}},fUt=class{pipe(){return this}on(){return this}},gUt=globalThis.ReadableStream||class{},hUt=rs,yUt=rs,xUt=()=>!1,vUt=()=>"",bUt=rs,TUt=rs,SUt=di,wUt=r=>r,EUt=rs,_Ut=()=>0,kUt=rs,CUt=()=>({}),RUt=rs,AUt=()=>({}),IUt=()=>[],PUt=rs,MUt=rs,OUt=rs,NUt=rs,DUt=()=>new hOe,LUt=()=>new gOe,UUt=di,FUt=di,$Ut=di,BUt=di,zUt=di,jUt=di,GUt=di,VUt=di,qUt=di,HUt=()=>({on:rs,stdout:{on:rs},stderr:{on:rs},kill:rs}),WUt=(r,e)=>e?.(null,"",""),KUt=()=>"",JUt=(r,e,t)=>{typeof e=="function"?e(null,"",""):t?.(null,"","")},YUt=()=>"",XUt="browser",ZUt=()=>"/",QUt=()=>"/tmp",eFt=()=>"browser",tFt=()=>[{}],rFt=()=>0,nFt=()=>0,oFt=()=>"Browser",sFt=()=>"wasm",iFt=()=>"0",aFt=()=>({}),cFt=()=>({}),lFt=()=>({}),uFt=()=>({}),dFt=()=>new Uint8Array,pFt=()=>new Uint8Array,mFt=()=>new Uint8Array,fFt=()=>new Uint8Array,gFt=(r,e)=>e?.(null,r),hFt=(r,e)=>e?.(null,r),yFt=()=>({}),xFt=()=>({}),vFt=rs,bFt={},TFt=()=>()=>({}),SFt=[],wFt=()=>!1,EFt=r=>({pathname:r||"",hostname:"",protocol:"",search:"",hash:""}),_Ft=()=>"",kFt=globalThis.URL,CFt=globalThis.URLSearchParams,RFt=r=>typeof r=="string"?r.replace("file://",""):r,AFt=r=>new globalThis.URL("file://"+r),IFt=(r,e)=>{e&&(r.super_=e,Object.setPrototypeOf(r.prototype,e.prototype))},PFt=r=>(...e)=>new Promise((t,n)=>r(...e,(o,s)=>o?n(o):t(s))),yOe=r=>{let e=(...t)=>{};return e.enabled=!1,e},MFt=yOe,nj=r=>{try{return JSON.stringify(r,null,2)}catch{return String(r)}};nj.custom=Symbol.for("nodejs.util.inspect.custom");nj.colors={};nj.styles={};OFt=r=>r,NFt=r=>(...e)=>{let t=e.pop();r(...e).then(n=>t(null,n)).catch(t)},DFt=(r,e)=>JSON.stringify(r)===JSON.stringify(e),LFt=r=>String(r),UFt={isPromise:r=>r instanceof Promise,isDate:r=>r instanceof Date,isRegExp:r=>r instanceof RegExp,isNativeError:r=>r instanceof Error,isArrayBuffer:r=>r instanceof ArrayBuffer,isTypedArray:r=>ArrayBuffer.isView(r),isUint8Array:r=>r instanceof Uint8Array,isProxy:()=>!1},xOe=globalThis.TextDecoder,rj=globalThis.TextEncoder,FFt=(r,e)=>e?.(null,"127.0.0.1",4),$Ft=class{},BFt=globalThis.performance||{now:()=>Date.now()},zFt=class{observe(){}disconnect(){}},jFt=()=>({enable:rs,disable:rs,percentile:()=>0}),GFt=()=>({}),VFt=class{},qFt=()=>!1,HFt=()=>new Uint8Array,WFt=rs,KFt=class{},JFt=!0,YFt=null,XFt=null,ZFt=()=>({}),QFt=class{},e$t=class{},t$t=globalThis.Buffer||class extends Uint8Array{static from(e,t){if(typeof e=="string"){let n=(t||"utf8").toLowerCase();if(n==="base64"){let o=atob(e),s=new Uint8Array(o.length);for(let i=0;i<o.length;i++)s[i]=o.charCodeAt(i);return s}if(n==="hex"){let o=new Uint8Array(e.length/2);for(let s=0;s<e.length;s+=2)o[s/2]=parseInt(e.substr(s,2),16);return o}return new rj().encode(e)}return new Uint8Array(e)}static alloc(e){return new Uint8Array(e)}static isBuffer(e){return e instanceof Uint8Array}static concat(e){let t=e.reduce((s,i)=>s+i.length,0),n=new Uint8Array(t),o=0;for(let s of e)n.set(s,o),o+=s.length;return n}static byteLength(e,t){return t==="base64"?Math.ceil(e.length*3/4):new rj().encode(e).length}toString(e){let t=(e||"utf8").toLowerCase();if(t==="hex")return Array.from(new Uint8Array(this.buffer,this.byteOffset,this.byteLength)).map(n=>n.toString(16).padStart(2,"0")).join("");if(t==="base64"){let n="";for(let o=0;o<this.length;o++)n+=String.fromCharCode(this[o]);return btoa(n)}return new xOe().decode(this)}},r$t={F_OK:0,R_OK:4,W_OK:2,X_OK:1},n$t=()=>!1,o$t=()=>!1,s$t=()=>0,i$t=class{},a$t=class{},c$t=async()=>new ArrayBuffer(0),vOe=r=>({[Symbol.toPrimitive](){return r},ref(){return this},unref(){return this},hasRef(){return!1},refresh(){return this},close(){}}),l$t=(...r)=>vOe(globalThis.setTimeout(...r)),u$t=globalThis.clearTimeout,d$t=(...r)=>vOe(globalThis.setInterval(...r)),p$t=globalThis.clearInterval,m$t=class{constructor(r){this.type=r}toString(){return this.type}}});function bOe(r){return wte||(wte=new Ete(r)),wte}var Ete,wte,TOe=_(()=>{"use strict";vr();H();Ete=class{cache=new Map;contentHashIndex=new Map;maxSize;ttlMs;maxImageSize;enabled;stats={hits:0,misses:0,evictions:0,expirations:0,totalRequests:0};constructor(e={}){let t=process.env.NEUROLINK_IMAGE_CACHE_ENABLED,n=process.env.NEUROLINK_IMAGE_CACHE_SIZE,o=process.env.NEUROLINK_IMAGE_CACHE_TTL_MS,s=process.env.NEUROLINK_IMAGE_MAX_SIZE;this.enabled=t!==void 0?t.toLowerCase()==="true":!1,this.maxSize=this.parseConfigValue(n,e.maxSize,100,1,1e3),this.ttlMs=this.parseConfigValue(o,e.ttlMs,1800*1e3,1e3,1440*60*1e3),this.maxImageSize=this.parseConfigValue(s,e.maxImageSize,10*1024*1024,1024,100*1024*1024),g.debug("ImageCache initialized",{enabled:this.enabled,maxSize:this.maxSize,ttlMs:this.ttlMs,maxImageSize:this.maxImageSize})}parseConfigValue(e,t,n,o,s){let i;if(e!==void 0){let a=parseInt(e,10);i=isNaN(a)?n:a}else t!==void 0?i=t:i=n;return i<o?(g.warn(`Cache config value ${i} below minimum ${o}, using min`),o):i>s?(g.warn(`Cache config value ${i} above maximum ${s}, using max`),s):i}normalizeUrl(e){try{let t=new URL(e);return["utm_source","utm_medium","utm_campaign","utm_term","utm_content","fbclid","gclid","_ga"].forEach(o=>t.searchParams.delete(o)),t.toString()}catch{return e}}generateContentHash(e){let t=typeof e=="string"?Buffer.from(e,"base64"):e;return $c("sha256").update(t).digest("hex").substring(0,16)}isExpired(e){return Date.now()-e.createdAt>this.ttlMs}isEnabled(){return this.enabled}get(e){if(!this.enabled)return null;this.stats.totalRequests++;let t=this.normalizeUrl(e),n=this.cache.get(t);return n?this.isExpired(n)?(this.stats.expirations++,this.delete(t),g.debug("Image cache entry expired",{url:t.substring(0,50)}),null):(n.lastAccessedAt=Date.now(),n.accessCount++,this.cache.delete(t),this.cache.set(t,n),this.stats.hits++,g.debug("Image cache hit",{url:t.substring(0,50),accessCount:n.accessCount}),n):(this.stats.misses++,g.debug("Image cache miss",{url:t.substring(0,50)}),null)}getByContentHash(e){let t=this.contentHashIndex.get(e);return t?this.get(t):null}set(e,t,n,o){if(!this.enabled){g.debug("Image caching disabled, skipping cache storage");return}let s=this.normalizeUrl(e),i=o.length;if(i>this.maxImageSize){g.debug("Image too large to cache",{url:s.substring(0,50),size:i,maxSize:this.maxImageSize});return}let a=this.generateContentHash(o),c=this.contentHashIndex.get(a);if(c&&c!==s){let d=this.cache.get(c);if(d&&!this.isExpired(d)){this.cache.set(s,{...d}),this.contentHashIndex.set(a,s),g.debug("Image cache dedup hit",{newUrl:s.substring(0,50),existingUrl:c.substring(0,50)});return}}for(;this.cache.size>=this.maxSize;)this.evictOldest();let l=Date.now(),u={dataUri:t,contentType:n,size:i,contentHash:a,createdAt:l,lastAccessedAt:l,accessCount:1};this.cache.set(s,u),this.contentHashIndex.set(a,s),g.debug("Image cached",{url:s.substring(0,50),size:i,contentHash:a.substring(0,8),cacheSize:this.cache.size})}delete(e){let t=this.normalizeUrl(e),n=this.cache.get(t);return n?(this.contentHashIndex.get(n.contentHash)===t&&this.contentHashIndex.delete(n.contentHash),this.cache.delete(t),!0):!1}evictOldest(){let e=this.cache.keys().next().value;if(e!==void 0){let t=this.cache.get(e);t&&this.contentHashIndex.get(t.contentHash)===e&&this.contentHashIndex.delete(t.contentHash),this.cache.delete(e),this.stats.evictions++,g.debug("Image cache eviction",{url:String(e).substring(0,50)})}}evictExpired(){let e=0,t=Date.now();for(let[n,o]of this.cache.entries())t-o.createdAt>this.ttlMs&&(this.delete(n),e++,this.stats.expirations++);return e>0&&g.debug(`Evicted ${e} expired image cache entries`),e}clear(){let e=this.cache.size;this.cache.clear(),this.contentHashIndex.clear(),g.debug(`Image cache cleared (${e} entries removed)`)}getStats(){let e=0;for(let n of this.cache.values())e+=n.size;let t=this.stats.totalRequests>0?Number((this.stats.hits/this.stats.totalRequests*100).toFixed(2)):0;return{...this.stats,size:this.cache.size,totalBytes:e,hitRate:t}}has(e){let t=this.normalizeUrl(e),n=this.cache.get(t);return n!=null&&!this.isExpired(n)}getSize(){return this.cache.size}getConfig(){return{enabled:this.enabled,maxSize:this.maxSize,ttlMs:this.ttlMs,maxImageSize:this.maxImageSize}}},wte=null});var DE,f$t,n_n,_te=_(()=>{"use strict";H();DE=class r{static async process(e,t){if(e.length===0)throw g.error("Empty buffer provided"),new Error("Invalid image processing: buffer is empty");let n=this.detectImageType(e),o=e.toString("base64"),s=`data:${n};base64,${o}`;return this.validateProcessOutput(s,o,n),{type:"image",content:s,mimeType:n,metadata:{confidence:100,size:e.length}}}static validateProcessOutput(e,t,n){if(t.length===0)throw g.error("Empty base64 content generated"),new Error("Invalid image processing: base64 content is empty");if(!/^data:[^;]+;base64,[A-Za-z0-9+/]*={0,2}$/.test(e))throw g.error("Invalid data URI format generated",{dataUri:e}),new Error("Invalid data URI format: must be data:{mimeType};base64,{content}");if(!this.validateImageFormat(n))throw g.error("Invalid MIME type generated",{mediaType:n}),new Error(`Invalid MIME type: ${n} is not in allowed list`)}static processImageForOpenAI(e){try{return typeof e=="string"?e.startsWith("http")||e.startsWith("data:")?e:`data:image/jpeg;base64,${e}`:`data:image/jpeg;base64,${e.toString("base64")}`}catch(t){throw g.error("Failed to process image for OpenAI:",t),new Error(`Image processing failed for OpenAI: ${t instanceof Error?t.message:"Unknown error"}`,{cause:t})}}static processImageForGoogle(e){try{let t,n="image/jpeg";if(typeof e=="string")if(e.startsWith("data:")){let o=e.match(/^data:([^;]+);base64,(.+)$/);o?(n=o[1],t=o[2]):t=e.split(",")[1]||e}else t=e;else t=e.toString("base64");return{mimeType:n,data:t}}catch(t){throw g.error("Failed to process image for Google AI:",t),new Error(`Image processing failed for Google AI: ${t instanceof Error?t.message:"Unknown error"}`,{cause:t})}}static processImageForAnthropic(e){try{let t,n="image/jpeg";if(typeof e=="string")if(e.startsWith("data:")){let o=e.match(/^data:([^;]+);base64,(.+)$/);o?(n=o[1],t=o[2]):t=e.split(",")[1]||e}else t=e;else t=e.toString("base64");return{mediaType:n,data:t}}catch(t){throw g.error("Failed to process image for Anthropic:",t),new Error(`Image processing failed for Anthropic: ${t instanceof Error?t.message:"Unknown error"}`,{cause:t})}}static processImageForVertex(e,t){try{return t.includes("gemini")?r.processImageForGoogle(e):t.includes("claude")?r.processImageForAnthropic(e):r.processImageForGoogle(e)}catch(n){throw g.error("Failed to process image for Vertex AI:",n),new Error(`Image processing failed for Vertex AI: ${n instanceof Error?n.message:"Unknown error"}`,{cause:n})}}static detectImageType(e){try{if(typeof e=="string"){if(e.startsWith("data:")){let o=e.match(/^data:([^;]+);/);return o?o[1]:"image/jpeg"}let t=e.toLowerCase().split(".").pop();return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",bmp:"image/bmp",tiff:"image/tiff",tif:"image/tiff",svg:"image/svg+xml",avif:"image/avif"}[t||""]||"image/jpeg"}if(e.length>=4){let t=e.subarray(0,4);if(t[0]===137&&t[1]===80&&t[2]===78&&t[3]===71)return"image/png";if(t[0]===255&&t[1]===216&&t[2]===255)return"image/jpeg";if(t[0]===71&&t[1]===73&&t[2]===70&&t[3]===56)return"image/gif";if(e.length>=12){let n=e.subarray(0,4),o=e.subarray(8,12);if(n.toString()==="RIFF"&&o.toString()==="WEBP")return"image/webp"}if(e.length>=4){let n=e.subarray(0,4).toString();if(n==="<svg"||n==="<?xm")return"image/svg+xml"}if(e.length>=12){let n=e.subarray(4,8).toString(),o=e.subarray(8,12).toString();if(n==="ftyp"&&o==="avif")return"image/avif"}}return"image/jpeg"}catch(t){return g.warn("Failed to detect image type, using default:",t),"image/jpeg"}}static validateImageSize(e,t=10*1024*1024){try{return(typeof e=="string"?Buffer.byteLength(e,"base64"):e.length)<=t}catch(n){return g.warn("Failed to validate image size:",n),!1}}static validateImageFormat(e){return["image/jpeg","image/png","image/gif","image/webp","image/bmp","image/tiff","image/svg+xml","image/avif"].includes(e.toLowerCase())}static getImageDimensions(e){try{if(e.length>=24&&e.subarray(0,8).toString("hex")==="89504e470d0a1a0a"){let t=e.readUInt32BE(16),n=e.readUInt32BE(20);return{width:t,height:n}}if(e.length>=4&&e[0]===255&&e[1]===216){let t=2;for(;t<e.length-1;){if(e[t]!==255){t++;continue}for(;t<e.length&&e[t]===255;)t++;if(t>=e.length)break;let n=e[t];if(t++,n===192||n===194){if(t+7>e.length)break;let s=e.readUInt16BE(t+3);return{width:e.readUInt16BE(t+5),height:s}}if(n===208||n===209||n===210||n===211||n===212||n===213||n===214||n===215||n===216||n===217||n===1)continue;if(t+2>e.length)break;let o=e.readUInt16BE(t);t+=o}return null}return null}catch(t){return g.warn("Failed to extract image dimensions:",t),null}}static processImage(e,t,n){try{let o=r.detectImageType(e),s=typeof e=="string"?Buffer.byteLength(e,"base64"):e.length,i,a;switch(t.toLowerCase()){case"openai":i=r.processImageForOpenAI(e),a="data_uri";break;case"google-ai":case"google":{i=r.processImageForGoogle(e).data,a="base64";break}case"anthropic":{i=r.processImageForAnthropic(e).data,a="base64";break}case"vertex":{i=r.processImageForVertex(e,n||"").data,a="base64";break}default:typeof e=="string"?i=e.startsWith("data:")&&e.split(",")[1]||e:i=e.toString("base64"),a="base64"}return{data:i,mediaType:o,size:s,format:a}}catch(o){throw g.error(`Failed to process image for ${t}:`,o),new Error(`Image processing failed: ${o instanceof Error?o.message:"Unknown error"}`,{cause:o})}}},f$t=["jpg","jpeg","png","gif","webp","bmp","tiff","tif","svg","avif","ico","heic","heif"],n_n=new Set(f$t)});function h$t(r){let e=r.toLowerCase();switch(e.replace(/[^a-z]/g,"")){case"lmstudio":return"lm-studio";case"llamacpp":return"llamacpp";case"nvidianim":return"nvidia-nim";case"googleaistudio":return"google-ai";case"or":return"openrouter";default:return e}}var py,UP,g$t,kte,LE,SOe=_(()=>{"use strict";_te();H();py=class{static logError(e,t,n){g.error(`Multimodal ${e} failed: ${t.message}`),process.env.NODE_ENV==="development"&&(g.error("Context:",JSON.stringify(n,null,2)),g.error("Stack:",t.stack))}},UP={openai:10,azure:10,"google-ai":16,google:16,anthropic:20,vertex:{claude:20,gemini:16,default:16},ollama:10,litellm:10,mistral:10,bedrock:20,openrouter:10},g$t=new Set(["litellm","openrouter"]);kte={openai:["gpt-5.4","gpt-5.4-mini","gpt-5.4-nano","gpt-5.4-pro","gpt-5.2","gpt-5.2-chat-latest","gpt-5.2-pro","gpt-5","gpt-5-2025-08-07","gpt-5-pro","gpt-5-mini","gpt-5-nano","gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","o3","o3-mini","o3-pro","o4","o4-mini","o4-mini-deep-research","gpt-4o","gpt-4o-mini","gpt-4-turbo","gpt-4-vision-preview"],"google-ai":["gemini-3.1-pro-preview","gemini-3.1-flash-lite-preview","gemini-3.1-flash-image-preview","gemini-3.1-pro-preview-customtools","gemini-3-flash-preview","gemini-3-pro-image-preview","gemini-3-pro-preview","gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-2.5-flash-image","gemini-2.0-flash","gemini-2.0-flash-001","gemini-2.0-flash-lite","gemini-2.0-flash-preview-image-generation","gemini-1.5-pro","gemini-1.5-flash","gemini-pro-vision"],anthropic:["claude-opus-4-6","claude-sonnet-4-6","claude-sonnet-4-5","claude-sonnet-4-5-20250929","claude-opus-4-5","claude-opus-4-5-20251101","claude-haiku-4-5","claude-haiku-4-5-20251001","claude-opus-4-1","claude-opus-4-1-20250805","claude-opus-4","claude-opus-4-20250514","claude-sonnet-4","claude-sonnet-4-20250514","claude-3-7-sonnet","claude-3-7-sonnet-20250219","claude-3-5-sonnet","claude-3-5-sonnet-20241022","claude-3-opus","claude-3-sonnet","claude-3-haiku"],azure:["gpt-5.1","gpt-5.1-chat","gpt-5.1-codex","gpt-5","gpt-5-pro","gpt-5-turbo","gpt-5-chat","gpt-5-mini","gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","o3","o3-mini","o3-pro","o4-mini","gpt-4o","gpt-4o-mini","gpt-4-turbo","gpt-4-vision-preview","gpt-4"],vertex:["gemini-3.1-pro-preview","gemini-3.1-flash-lite-preview","gemini-3.1-flash-image-preview","gemini-3.1-pro-preview-customtools","gemini-3-flash-preview","gemini-3-pro-image-preview","gemini-3-pro-preview","gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-2.5-flash-image","gemini-2.0-flash-001","gemini-2.0-flash-lite","gemini-2.0-flash","gemini-1.5-pro","gemini-1.5-flash","claude-sonnet-4-5@","claude-opus-4-5@","claude-haiku-4-5@","claude-haiku-4-5","claude-sonnet-4@","claude-opus-4@","claude-opus-4-1@","claude-3-7-sonnet@","claude-3-5-sonnet@","claude-opus-3@","claude-haiku-3@","claude-3-7-sonnet","claude-3-5-sonnet","claude-3-opus","claude-3-sonnet","claude-3-haiku","claude-sonnet-4","claude-sonnet-3","claude-opus-3","claude-haiku-3","claude-haiku-4","claude-3.5-sonnet","claude-3.5-haiku","claude-4.5-sonnet","claude-4.5-opus","claude-4.5-haiku","claude-haiku-4-5","claude-3.0-sonnet","claude-3.0-opus"],litellm:["openai/gpt-5","openai/gpt-4o","openai/gpt-4o-mini","openai/gpt-4-turbo","gpt-5","gpt-4o","gpt-4.1","anthropic/claude-sonnet-4-5-20250929","anthropic/claude-opus-4-1-20250805","anthropic/claude-3-5-sonnet-20240620","claude-sonnet-4-5","claude-sonnet-4-5-20250929","claude-opus-4-5","claude-opus-4-5-20251101","claude-haiku-4-5-20251001","claude-sonnet-4","claude-opus-4-1","vertex_ai/gemini-2.5-pro","gemini/gemini-2.5-pro","gemini/gemini-2.0-flash","gemini-3.1-pro-preview","gemini-3-flash-preview","gemini-2.5-pro","gemini-2.5-flash","gemini-2.0-flash-lite","groq/llama-3.2-11b-vision-preview"],openrouter:["anthropic/claude-3.7-sonnet","anthropic/claude-3-5-haiku","anthropic/claude-3-opus","anthropic/claude-3-sonnet","anthropic/claude-3-haiku","openai/gpt-4o","openai/gpt-4o-mini","openai/gpt-4-turbo","openai/gpt-4-vision-preview","google/gemini-2.5-pro","google/gemini-2.5-flash","google/gemini-2.0-flash","google/gemini-2.0-flash-001","google/gemini-1.5-pro","google/gemini-1.5-flash","google/gemini-pro-vision","meta-llama/llama-3.2-90b-vision-instruct","meta-llama/llama-3.2-11b-vision-instruct","mistralai/pixtral-12b","mistralai/pixtral-large","qwen/qwen-2-vl-72b-instruct","qwen/qwen-2-vl-7b-instruct"],mistral:["mistral-large-latest","mistral-large-2512","mistral-small","mistral-small-latest","mistral-small-3.2","mistral-small-2506","mistral-medium","mistral-medium-latest","mistral-medium-3.1","mistral-medium-2508","magistral-small","magistral-small-latest","magistral-medium","magistral-medium-latest","pixtral-12b","pixtral-12b-latest","pixtral-large","pixtral-large-latest","pixtral-large-2502"],ollama:["llama4:scout","llama4:maverick","llama4:latest","llama4","llama3.2-vision","llama3.2-vision:11b","llama3.2-vision:90b","gemma3","gemma3:4b","gemma3:12b","gemma3:27b","gemma3:latest","qwen2.5-vl","qwen2.5-vl:72b","qwen2.5-vl:32b","mistral-small3.1","mistral-small3.1:large","mistral-small3.1:medium","mistral-small3.1:small","llava","llava:7b","llava:13b","llava:34b","llava-llama3","llava-llama3:8b"],bedrock:["amazon.nova-premier","amazon.nova-premier-v1:0","amazon.nova-pro","amazon.nova-pro-v1:0","amazon.nova-lite","amazon.nova-lite-v1:0","amazon.nova-2-lite-v1:0","nova-premier","nova-pro","nova-lite","claude-sonnet-4-5","claude-sonnet-4.5","anthropic.claude-sonnet-4-5","anthropic.claude-sonnet-4-5-20250929-v1:0","claude-opus-4-5","claude-opus-4.5","anthropic.claude-opus-4-5","anthropic.claude-opus-4-5-20251124-v1:0","claude-haiku-4-5","claude-haiku-4.5","anthropic.claude-haiku-4-5","anthropic.claude-haiku-4-5-20251001-v1:0","claude-sonnet-4","claude-sonnet-4@","anthropic.claude-sonnet-4","anthropic.claude-sonnet-4-20250514-v1:0","claude-opus-4","claude-opus-4-1","claude-opus-4@","anthropic.claude-opus-4","anthropic.claude-opus-4-1-20250805-v1:0","claude-3-7-sonnet","claude-3.7-sonnet","anthropic.claude-3-7-sonnet","anthropic.claude-3-7-sonnet-20250219-v1:0","claude-3-5-sonnet","claude-3.5-sonnet","anthropic.claude-3-5-sonnet","anthropic.claude-3-5-sonnet-20241022-v1:0","claude-3-opus","anthropic.claude-3-opus","claude-3-sonnet","anthropic.claude-3-sonnet","claude-3-haiku","anthropic.claude-3-haiku","meta.llama4-maverick-17b-instruct-v1:0","meta.llama4-scout-17b-instruct-v1:0","meta.llama3-2-90b-instruct-v1:0","meta.llama3-2-11b-instruct-v1:0","mistral.pixtral-large-2502-v1:0","anthropic.claude"],huggingface:["Qwen/Qwen2.5-VL-32B-Instruct","Qwen/Qwen2.5-VL-7B-Instruct","microsoft/Phi-3-vision-128k-instruct","llava-hf/llava-1.5-7b-hf","llava-hf/llava-v1.6-mistral-7b-hf"],sagemaker:["meta-llama-4-maverick-17b-128e-instruct","meta-llama-4-scout-17b-16e-instruct"],deepseek:[],"nvidia-nim":["meta/llama-3.2-90b-vision-instruct","meta/llama-3.2-11b-vision-instruct"],"lm-studio":["llava","llama-3.2-11b-vision","llama-3.2-90b-vision","vision-instruct","qwen2-vl","qwen2.5-vl","phi-3-vision"],llamacpp:["llava","llama-3.2-11b-vision","llama-3.2-90b-vision","vision-instruct","qwen2-vl","phi-3-vision"],xai:["grok-2-vision-latest"],groq:["llama-3.2-90b-vision-preview","llama-3.2-11b-vision-preview"],cohere:[],"together-ai":[],fireworks:["accounts/fireworks/models/phi-3-vision-128k-instruct","accounts/fireworks/models/llama-v3p2-90b-vision-instruct","accounts/fireworks/models/llama-v3p2-11b-vision-instruct"],perplexity:[],cloudflare:["@cf/meta/llama-3.2-11b-vision-instruct"],replicate:["llava","llama-3.2-vision","moondream","qwen2-vl"],voyage:[],jina:[],stability:[],ideogram:[],recraft:[]},LE=class{static validateImageCount(e,t,n){let o=t.toLowerCase(),s;if(o==="vertex"&&n)n.includes("claude")?s=UP.vertex.claude:n.includes("gemini")?s=UP.vertex.gemini:s=UP.vertex.default;else{let a=o in UP?UP[o]:void 0;a===void 0?(s=10,g.warn(`Image count limit not defined for provider ${t}. Using conservative default of 10 images.`)):s=a}let i=Math.floor(s*.8);if(e===i&&g.warn(`Image count (${e}) is approaching the limit for ${t}. Maximum allowed: ${s}. Please reduce the number of images.`),e>s)throw new Error(`Image count (${e}) exceeds the maximum limit for ${t}. Maximum allowed: ${s}. Please reduce the number of images.`)}static convertToContent(e,t){let n=[{type:"text",text:e}];return t&&t.length>0&&t.forEach(o=>{let s=typeof o=="object"&&"data"in o&&!Buffer.isBuffer(o)?o.data:o,i=typeof o=="object"&&"data"in o&&!Buffer.isBuffer(o)?o.altText:void 0;n.push({type:"image",data:s,altText:i,mediaType:DE.detectImageType(s)})}),n}static supportsVision(e,t){try{let n=h$t(e),o=kte[n];if(!o||o.length===0)return!1;if(!t)return!0;let s=o.some(i=>t.toLowerCase().includes(i.toLowerCase()));return!s&&g$t.has(n)?!0:s}catch{return!1}}static getSupportedModels(e){let t=e.toLowerCase(),n=kte[t];return n?[...n]:[]}static getVisionProviders(){return Object.entries(kte).filter(([,e])=>e.length>0).map(([e])=>e)}static countImagesInMessage(e,t){return(e?.length||0)+(t??0)}static countImagesInPages(e){return!e||e.length===0?0:e.reduce((t,n)=>t+(n.pageCount??0),0)}}});function wOe(){return{enabled:process.env.NEUROLINK_MEMORY_ENABLED==="true",maxSessions:Number(process.env.NEUROLINK_MEMORY_MAX_SESSIONS)||50,enableSummarization:process.env.NEUROLINK_SUMMARIZATION_ENABLED!=="false",tokenThreshold:process.env.NEUROLINK_TOKEN_THRESHOLD?Number(process.env.NEUROLINK_TOKEN_THRESHOLD):void 0,summarizationProvider:process.env.NEUROLINK_SUMMARIZATION_PROVIDER||"vertex",summarizationModel:process.env.NEUROLINK_SUMMARIZATION_MODEL||"gemini-2.5-flash",maxTurnsPerSession:50}}var Cte,Rte,Ate=_(()=>{"use strict";Cte=`
812
812
 
813
813
  IMPORTANT: You are continuing an ongoing conversation. The previous messages in this conversation contain important context including:
@@ -2192,7 +2192,7 @@ ${f}`;i.prompt&&(i.prompt=h),i.input?.text&&(i.input.text=h)}}}catch(d){if(!(i.p
2192
2192
 
2193
2193
  ${t}`:a.text:t,u=this.finalizeGenerateRequestResult({generateSpan:n,options:e,textOptions:i,textResult:c,factoryResult:s,originalPrompt:l,startTime:o});return a&&(u.transcription=a),u}async maybeApplyGenerateOrchestration(e){if(!(!this.enableOrchestration||e.provider||e.model))try{let t=await this.applyOrchestration(e);g.debug("Orchestration applied",{originalProvider:e.provider||"auto",orchestratedProvider:t.provider,orchestratedModel:t.model,prompt:(e.input?.text??"").substring(0,100)}),Object.assign(e,t),t.model&&(e.model=qk(e.model,this.modelAliasConfig))}catch(t){g.warn("Orchestration failed, continuing with original options",{error:t instanceof Error?t.message:String(t),originalProvider:e.provider||"auto"})}}async applyRequestRouter(e,t,n,o,s){if(!this.requestRouter||e.context?.__classifierRouted||e.provider&&e.model)return;if(this.modelPool){g.debug("[NeuroLink] applyRequestRouter: skipped \u2014 modelPool takes precedence");return}let i={prompt:t,estimatedInputTokens:Math.ceil(t.length/4),hasTools:n,requiresVision:o,thinkingLevel:s};try{let a=await this.requestRouter(i);a.provider&&!e.provider?(e.provider=a.provider,a.model&&!e.model&&(e.model=a.model),a.region&&!e.region&&(e.region=a.region)):a.provider||(a.model&&!e.model&&(e.model=a.model),a.region&&!e.region&&(e.region=a.region)),a.reason&&g.debug("[NeuroLink] requestRouter decision",{reason:a.reason,provider:e.provider,model:e.model})}catch(a){g.warn("[NeuroLink] requestRouter threw \u2014 proceeding unrouted",{error:a instanceof Error?a.message:String(a)})}}async applyClassifierRouting(e,t,n,o,s){if(!this.classifierRouter)return;let i=e;if(i.context?.__classifierRouted||e.provider&&e.model)return;if(this.modelPool){g.debug("[NeuroLink] applyClassifierRouting: skipped \u2014 modelPool takes precedence");return}let a=typeof i.context?.sessionId=="string"?i.context.sessionId:void 0;try{let c=await this.classifierRouter.route({prompt:t,estimatedInputTokens:Math.ceil((t?.length??0)/4),hasTools:n,requiresVision:o,thinkingLevel:s,sessionId:a});if(!c)return;if(c.provider&&!e.provider?(e.provider=c.provider,c.model&&!e.model&&(e.model=c.model),c.region&&!e.region&&(e.region=c.region)):!c.provider&&c.model&&!e.model&&(e.model=c.model),!i.disableTools&&(c.excludeTools&&c.excludeTools.length>0&&(i.excludeTools=Array.from(new Set([...i.excludeTools??[],...c.excludeTools]))),c.toolFilter&&c.toolFilter.length>0)){let l=c.toolFilter;i.toolFilter=i.toolFilter&&i.toolFilter.length>0?i.toolFilter.filter(u=>l.includes(u)):[...l]}if(c.provider||c.model){let l=i.context??{};l.__classifierRouted=!0,i.context=l}c.reason&&g.debug("[NeuroLink] classifierRouter decision",{reason:c.reason,difficulty:c.difficulty,provider:e.provider,model:e.model})}catch(c){g.warn("[NeuroLink] classifierRouter threw \u2014 proceeding unrouted",{error:c instanceof Error?c.message:String(c)})}}async prepareGenerateAugmentations(e){if(e.rag?.files?.length)try{let{prepareRAGTool:n}=await Promise.resolve().then(()=>(rW(),Tpe)),o=await n(e.rag,e.provider);e.tools||(e.tools={}),e.tools[o.toolName]=o.tool,e.systemPrompt=(e.systemPrompt||"")+[`
2194
2194
 
2195
- IMPORTANT: You have a tool called "${o.toolName}" that searches through`,`${o.filesLoaded} loaded document(s) containing ${o.chunksIndexed} indexed chunks.`,`ALWAYS use the "${o.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(" "),g.info("[RAG] Tool injected into generate()",{toolName:o.toolName,filesLoaded:o.filesLoaded,chunksIndexed:o.chunksIndexed})}catch(n){g.warn("[RAG] Failed to prepare RAG tool, continuing without RAG",{error:n instanceof Error?n.message:String(n)})}if(await this.applySkillsAugmentation(e),!(e.output?.mode==="avatar"||e.output?.mode==="music"||e.output?.mode==="video"||e.output?.mode==="ppt"||!this.shouldReadMemory(e.memory,e.context?.userId)||!e.context?.userId))try{e.input&&(e.input.text=await this.retrieveMemory(e.input.text??"",e.context.userId,e.memory?.additionalUsers)),g.debug("Memory retrieval successful (generate)")}catch(n){g.warn("Memory retrieval failed (generate):",n)}}async buildGenerateTextOptions(e,t,n){let o={prompt:e.input?.text,provider:e.provider,model:e.model,temperature:e.temperature,maxTokens:e.maxTokens,systemPrompt:e.systemPrompt,schema:e.schema,output:e.output,tools:e.tools,disableTools:e.disableTools,toolFilter:e.toolFilter,excludeTools:e.excludeTools,maxSteps:e.maxSteps,toolChoice:e.toolChoice,prepareStep:e.prepareStep,enabledToolNames:e.enabledToolNames,enableAnalytics:e.enableAnalytics,enableEvaluation:e.enableEvaluation,context:e.context,evaluationDomain:e.evaluationDomain,toolUsageContext:e.toolUsageContext,input:e.input,region:e.region,tts:e.tts,stt:e.stt,fileRegistry:this.fileRegistry,timeout:e.timeout,turnTimeoutMs:e.turnTimeoutMs,stallTimeoutMs:e.stallTimeoutMs,wrapupTimeLeadMs:e.wrapupTimeLeadMs,toolTimeoutMs:e.toolTimeoutMs,abortSignal:e.abortSignal,skipToolPromptInjection:e.skipToolPromptInjection,middleware:e.middleware,conversationMessages:e.conversationMessages,credentials:e.credentials,onFinish:e.onFinish,onError:e.onError},s=e;(s.sessionId||s.userId)&&(o.context={...o.context,...s.sessionId&&!o.context?.sessionId?{sessionId:s.sessionId}:{},...s.userId&&!o.context?.userId?{userId:s.userId}:{}});let i=g3e(o,n);this.conversationMemory&&(i.conversationMemoryConfig=this.conversationMemory.config,i.originalPrompt=t);let{toolResults:a,enhancedPrompt:c}=await this.detectAndExecuteTools(i.prompt||e.input?.text||"",n.domainType);return c!==i.prompt&&(i.prompt=c,g.debug("Enhanced prompt with tool results",{originalLength:(e.input?.text??"").length,enhancedLength:c.length,toolResults:a.length})),i}finalizeGenerateRequestResult(e){let{generateSpan:t,options:n,textOptions:o,textResult:s,factoryResult:i,originalPrompt:a,startTime:c}=e;if(o.schema&&s.structuredData===void 0&&typeof s.content=="string"){let f=tj(s.content,o.schema);if(f)s.content=f.content,s.structuredData=f.structuredData,f.repaired&&(s.jsonRepaired=!0),f.truncated&&(s.jsonTruncated=!0);else try{let h=JSON.parse(s.content);h!=null&&(s.structuredData=h)}catch{g.warn("[NeuroLink] schema requested but no JSON could be recovered from model output; returning raw text",{provider:s.provider,model:s.model})}}o.schema&&(s.finishReason==="length"&&(s.jsonTruncated=!0),s.jsonTruncated&&g.warn("[NeuroLink] Structured output may be truncated (finishReason=length or unclosed JSON); increase maxTokens to fit the full response.",{provider:s.provider,model:s.model,finishReason:s.finishReason,outputTokens:s.usage?.output})),s._generationEndEmitted||this.emitter.emit("generation:end",{provider:s.provider,responseTime:Date.now()-c,toolsUsed:s.toolsUsed,timestamp:Date.now(),result:s,prompt:a||n.input?.text||n.prompt,temperature:o.temperature,maxTokens:o.maxTokens,pipelineAHandled:!0}),this.emitter.emit("response:end",s.content||""),this.emitter.emit("message",`Generation completed in ${Date.now()-c}ms`);let u={content:s.content,structuredData:s.structuredData,finishReason:s.finishReason,stopReason:s.stopReason,rawFinishReason:s.rawFinishReason,stepsUsed:s.stepsUsed,jsonRepaired:s.jsonRepaired,jsonTruncated:s.jsonTruncated,provider:s.provider,model:s.model,usage:s.usage?{input:s.usage.input||0,output:s.usage.output||0,total:s.usage.total||0}:void 0,responseTime:s.responseTime,toolsUsed:s.toolsUsed,toolExecutions:cd(s.toolExecutions),enhancedWithTools:s.enhancedWithTools,availableTools:oPe(s.availableTools),analytics:s.analytics,imageOutput:s.imageOutput,evaluation:s.evaluation?{...s.evaluation,isOffTopic:s.evaluation.isOffTopic??!1,alertSeverity:s.evaluation.alertSeverity??"none",reasoning:s.evaluation.reasoning??"No evaluation provided",evaluationModel:s.evaluation.evaluationModel??"unknown",evaluationTime:s.evaluation.evaluationTime??Date.now(),evaluationDomain:s.evaluation.evaluationDomain??o.evaluationDomain??i.domainType}:void 0,audio:s.audio,transcription:s.transcription,video:s.video,avatar:s.avatar,music:s.music,ppt:s.ppt,reasoning:s.reasoning,reasoningTokens:s.reasoningTokens,...s.retries&&{retries:s.retries}};if(n.responseValidation){let f=tpe(u.content??"",{minLength:n.responseValidation.minLength,maxLength:n.responseValidation.maxLength,requiredPhrases:n.responseValidation.requiredPhrases,forbiddenPhrases:n.responseValidation.forbiddenPhrases,jsonSchema:n.responseValidation.jsonSchema,customValidator:n.responseValidation.customValidator,truncationAction:n.responseValidation.truncationAction,truncationSuffix:n.responseValidation.truncationSuffix,retryOnFailure:n.responseValidation.retryOnFailure,maxRetries:n.responseValidation.maxRetries});if(f.action==="abort")throw new Error(f.feedback??`Response validation failed: ${f.issues.map(h=>h.message).join("; ")}`);f.text!==u.content&&(u.content=f.text)}u.analytics?.cost&&u.analytics.cost>0&&(this._sessionCostUsd+=u.analytics.cost),this.scheduleGenerateMemoryStorage(n,a,u),t.setAttribute("neurolink.output_length",u.content?.length||0),t.setAttribute("neurolink.tokens.input",u.usage?.input||0),t.setAttribute("neurolink.tokens.output",u.usage?.output||0),t.setAttribute("neurolink.finish_reason",u.finishReason||"unknown");let d=s?.steps?.length??1,m=n.maxSteps??200;return t.setAttribute("neurolink.step_count",d),t.setAttribute("neurolink.max_steps_reached",d>=m),t.setAttribute("neurolink.result_provider",u.provider||"unknown"),t.setAttribute("neurolink.result_model",u.model||"unknown"),t.setAttribute("generate.retry_count",u.retries?.count||0),t.setStatus({code:Ie.OK}),u}emitGenerateErrorEvent(e,t){let n=typeof e=="object"&&e.provider||"unknown",o=typeof e=="object"&&e.model||"unknown",s=Hr(t);try{this.emitter.emit("generation:end",{provider:n,model:o,responseTime:0,error:t instanceof Error?t.message:String(t),success:!1,aborted:s})}catch(i){}}scheduleGenerateMemoryStorage(e,t,n){this.shouldWriteMemory(e.memory,e.context?.userId,n.content)&&e.context?.userId&&this.storeMemoryInBackground(t??"",n.content.trim(),e.context.userId,e.memory?.additionalUsers,e.context)}async generateWithPPT(e){let t=Date.now(),{generatePresentation:n}=await q5e().then(()=>V5e),{extractPPTContext:o,getEffectivePPTProvider:s}=await Promise.resolve().then(()=>(lW(),i5e)),i=e.provider||"vertex",a=await dn.createProvider(i,e.model,!0,this,void 0,this.resolveCredentials(e.credentials)),c=await s(a,i,e.model||"default",this),l=o(e),u=await n({context:l,provider:c.provider,providerName:c.providerName,modelName:c.modelName,neurolink:this});return{content:`Presentation generated: ${u.filePath} (${u.totalSlides} slides)`,finishReason:"stop",provider:u.provider||i,model:u.model||e.model||"default",usage:void 0,responseTime:Date.now()-t,ppt:u}}async generateWithMusic(e,t){let n=Date.now(),o=e.output?.music;if(!o)throw new Error('output.mode="music" requires output.music with at least { provider, prompt }.');let s=o.provider;if(!s)throw new Error('output.music.provider is required (e.g. "beatoven", "elevenlabs-music", "lyria", "replicate").');let{MusicProcessor:i}=await Promise.resolve().then(()=>(of(),Vpe)),a=await i.generate(s,{...o,prompt:o.prompt??e.input?.text??""});return t.setAttribute("neurolink.music.provider",s),t.setAttribute("neurolink.music.bytes",a.size),t.setStatus({code:Ie.OK}),{content:`Music generated (${s}, ${a.size} bytes, ${a.format}).`,finishReason:"stop",provider:s,model:a.metadata?.model??s,usage:void 0,responseTime:Date.now()-n,music:a}}async generateWithAvatar(e,t){let n=Date.now(),o=e.output?.avatar;if(!o)throw new Error('output.mode="avatar" requires output.avatar with at least { provider, image, audio|text }.');let s=o.provider;if(!s)throw new Error('output.avatar.provider is required (e.g. "d-id", "heygen", "replicate").');let{AvatarProcessor:i}=await Promise.resolve().then(()=>(qg(),qpe)),a=await i.generate(s,o);return t.setAttribute("neurolink.avatar.provider",s),t.setAttribute("neurolink.avatar.bytes",a.size),t.setStatus({code:Ie.OK}),{content:`Avatar generated (${s}, ${a.size} bytes, ${a.format}).`,finishReason:"stop",provider:s,model:a.metadata?.model??s,usage:void 0,responseTime:Date.now()-n,avatar:a}}async generateWithWorkflow(e){let t=Date.now();g.debug("[NeuroLink] Executing workflow generation",{workflowId:e.workflow,hasInlineConfig:!!e.workflowConfig,prompt:(e.input?.text??"").substring(0,100),startTime:t});let n;if(e.workflowConfig)n=e.workflowConfig;else if(e.workflow){if(n=B3(e.workflow),!n)throw new Error(`Workflow '${e.workflow}' not found in registry`)}else throw new Error("Either workflow or workflowConfig must be provided");let o=await z3(n,{prompt:e.input?.text??"",conversationHistory:e.conversationMessages?.filter(i=>i.role==="user"||i.role==="assistant").map(i=>({role:i.role,content:jm(i.content)}))??e.conversationHistory,timeout:e.timeout,verbose:!1,metadata:e.context}),s={content:o.content,provider:o.selectedResponse?.provider||n.models[0]?.provider,model:o.selectedResponse?.model||n.models[0]?.model,usage:o.usage?{input:o.usage.totalInputTokens,output:o.usage.totalOutputTokens,total:o.usage.totalTokens}:void 0,responseTime:o.totalTime,workflow:{originalResponse:o.originalContent||o.content,processedResponse:o.content,ensembleResponses:o.ensembleResponses.map(i=>({provider:i.provider,model:i.model,content:i.content,responseTime:i.responseTime,status:i.status,error:i.error})),judgeScores:o.judgeScores?{scores:o.judgeScores.scores,reasoning:o.reasoning,selectedModel:`${o.selectedResponse?.provider}-${o.selectedResponse?.model}`}:void 0,selectedModel:`${o.selectedResponse?.provider}-${o.selectedResponse?.model}`,metrics:{totalTime:o.totalTime,ensembleTime:o.ensembleTime,judgeTime:o.judgeTime,conditioningTime:o.conditioningTime},workflowId:o.workflow,workflowName:o.workflowName}};return g.debug("[NeuroLink] Workflow generation complete",{workflowId:o.workflow,selectedModel:s.workflow?.selectedModel,score:o.score,totalTime:o.totalTime}),s}async streamWithWorkflow(e,t){g.debug("[NeuroLink] Executing workflow streaming (progressive)",{workflowId:e.workflow,hasInlineConfig:!!e.workflowConfig,prompt:(e.input?.text??"").substring(0,100)});let n;if(e.workflowConfig)n=e.workflowConfig;else if(e.workflow){if(n=B3(e.workflow),!n)throw new Error(`Workflow '${e.workflow}' not found in registry`)}else throw new Error("Either workflow or workflowConfig must be provided");let{runWorkflowWithStreaming:o}=await Promise.resolve().then(()=>(j3(),cWe)),s=o(n,{prompt:e.input?.text??"",conversationHistory:e.conversationMessages?.filter(d=>d.role==="user"||d.role==="assistant").map(d=>({role:d.role,content:jm(d.content)}))??e.conversationHistory,timeout:e.timeout,verbose:!1,metadata:e.context,streaming:!0}),i=null,a=0,l={stream:(async function*(){for await(let d of s)if(d.type==="preliminary")a=Date.now()-t,g.debug("[NeuroLink] Streaming preliminary response",{responseTime:a,contentLength:d.content.length}),yield{content:d.content,type:"preliminary"};else if(d.type==="final"){i=d.partialResult??null;let m=Date.now()-t;g.debug("[NeuroLink] Streaming final synthesis",{responseTime:m,contentLength:d.content.length}),yield{content:d.content,type:"final"}}})(),provider:n.models[0]?.provider,model:n.models[0]?.model,metadata:{streamId:`workflow-${n.id}-${Date.now()}`,startTime:t,responseTime:0}},u=l.stream;return l.stream=(async function*(){for await(let d of u)yield d;if(i){let d=i,m=Date.now()-t;d.usage&&(l.usage={input:d.usage.totalInputTokens,output:d.usage.totalOutputTokens,total:d.usage.totalTokens}),l.metadata={...l.metadata,totalChunks:2,responseTime:m,preliminaryTime:a};let f=d.ensembleResponses?.map(y=>({provider:y.provider,model:y.model,content:y.content,responseTime:y.responseTime,status:y.status,error:y.error}))??[],h=d.judgeScores?{scores:d.judgeScores.scores,reasoning:d.reasoning??"",selectedModel:d.selectedResponse?`${d.selectedResponse.provider}-${d.selectedResponse.model}`:"unknown"}:void 0;l.workflow={originalResponse:d.originalContent??d.content??"",processedResponse:d.content??"",ensembleResponses:f,judgeScores:h,selectedModel:d.selectedResponse?`${d.selectedResponse.provider}-${d.selectedResponse.model}`:"unknown",metrics:{totalTime:d.totalTime??m,ensembleTime:d.ensembleTime??0,judgeTime:d.judgeTime,conditioningTime:d.conditioningTime},workflowId:d.workflow??n.id,workflowName:d.workflowName??n.name}}})(),g.debug("[NeuroLink] Workflow streaming initialized",{workflowId:n.id}),l}async generateText(e){if(!e.prompt||typeof e.prompt!="string"||e.prompt.trim()==="")throw new Error("GenerateText options must include prompt as a non-empty string");return e.model=qk(e.model,this.modelAliasConfig),await this.generateTextInternal(e)}async generateTextInternal(e){return _e.sdk.startActiveSpan("neurolink.generateTextInternal",{kind:Cr.INTERNAL},t=>this.executeGenerateTextInternalWithSpan(e,t))}async executeGenerateTextInternalWithSpan(e,t){try{let n=this.initializeGenerateTextInternalContext(e);return t.setAttribute("neurolink.request_id",n.requestId),t.setAttribute("neurolink.has_conversation_memory",!!this.conversationMemory),t.setAttribute("neurolink.provider",e.provider||"auto"),t.setAttribute("neurolink.model",e.model||"default"),this.logGenerateTextInternalStart(n.generateInternalId,n.generateInternalStartTime,n.generateInternalHrTimeStart,e,n.functionTag),this.emitGenerationStartEvents(e),await this.runGenerateTextInternalFlow(e,t,n)}catch(n){throw Hr(n)?(t.setAttribute("ai.finishReason","aborted"),t.setAttribute("neurolink.aborted",!0)):(t.recordException(n instanceof Error?n:new Error(String(n))),t.setStatus({code:Ie.ERROR,message:n instanceof Error?n.message:String(n)})),n}finally{t.end()}}initializeGenerateTextInternalContext(e){let t=`generate-internal-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,n=e.context?.requestId,o=typeof n=="string"&&n?n:`req-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;return e.context={...e.context,requestId:o},{generateInternalId:t,generateInternalStartTime:Date.now(),generateInternalHrTimeStart:process.hrtime.bigint(),functionTag:"NeuroLink.generateTextInternal",requestId:o}}async runGenerateTextInternalFlow(e,t,n){try{await this.initializeConversationMemoryForGeneration(n.generateInternalId,n.generateInternalStartTime,n.generateInternalHrTimeStart);let o=await this.attemptMCPGeneration(e,n.generateInternalId,n.generateInternalStartTime,n.generateInternalHrTimeStart,n.functionTag);if(o)return this.finalizeGenerateTextInternalResult({path:"mcp",result:o,options:e,internalSpan:t,requestId:n.requestId,startTime:n.generateInternalStartTime});if(e.abortSignal?.aborted)throw new DOMException("The operation was aborted","AbortError");await this.captureOriginalConversationMessagesForRecovery(e);let s=await this.directProviderGeneration(e);return g.debug(`[${n.functionTag}] Direct generation successful`),this.finalizeGenerateTextInternalResult({path:"direct",result:s,options:e,internalSpan:t,requestId:n.requestId,startTime:n.generateInternalStartTime})}catch(o){let s=await this.handleGenerateTextInternalFailure(e,n,o);if(s)return s;throw Hr(o)&&!(o instanceof Fe)?pe.aborted(o instanceof Error?o:new Error(String(o))):o}}async captureOriginalConversationMessagesForRecovery(e){if(!this.conversationMemory)return;let t=await Mg(this.conversationMemory,e);e._originalConversationMessages=t?[...t]:void 0}async finalizeGenerateTextInternalResult(e){let{path:t,result:n,options:o,internalSpan:s,requestId:i,startTime:a}=e;g.info(`[NeuroLink.generateTextInternal] generate() - COMPLETE SUCCESS${t==="mcp"?" (MCP path)":""}`,{provider:n.provider,model:n.model,responseTimeMs:Date.now()-a,tokensUsed:n.usage?.total||0,toolsUsed:n.toolsUsed?.length||0,...n.usage?.cacheCreationTokens!==void 0&&{cacheCreationTokens:n.usage.cacheCreationTokens},...n.usage?.cacheReadTokens!==void 0&&{cacheReadTokens:n.usage.cacheReadTokens},...n.usage?.cacheSavingsPercent!==void 0&&{cacheSavingsPercent:n.usage.cacheSavingsPercent}});let c=Date.now();try{await jGe(this.conversationMemory,o,n,new Date(a),i,this.drainPendingSkillMessages(o.context?.sessionId)),this.recordMemorySpan("memory.store",{"memory.operation":"store","memory.path":t},Date.now()-c,1)}catch(l){this.recordMemorySpan("memory.store",{"memory.operation":"store","memory.path":t},Date.now()-c,2,l instanceof Error?l.message:String(l))}return this.emitter.emit("response:end",n.content||""),t==="direct"&&this.emitter.emit("message","Text generation completed successfully"),s.setAttribute("neurolink.path",t),s.setAttribute("neurolink.tokens.input",n.usage?.input||0),s.setAttribute("neurolink.tokens.output",n.usage?.output||0),s.setAttribute("neurolink.result_provider",n.provider||"unknown"),s.setStatus({code:Ie.OK}),n}async handleGenerateTextInternalFailure(e,t,n){let o=await this.tryRecoverGenerateTextOverflow(e,t.functionTag,n,t.generateInternalStartTime);return o||(Hr(n)?g.info(`[${t.functionTag}] Generation aborted \u2014 skipping memory write (aborts must not pollute conversation history)`,{hasMemory:!!this.conversationMemory,memoryType:this.conversationMemory?.constructor?.name||"NONE",sessionId:e.context?.sessionId||"unknown"}):g.error(`[${t.functionTag}] All generation methods failed`,{error:n instanceof Error?n.message:String(n)}),this.emitter.emit("response:end",""),this.emitter.listenerCount("error")>0&&this.emitter.emit("error",n instanceof Error?n:new Error(String(n))),null)}async tryRecoverGenerateTextOverflow(e,t,n,o){if(!_ce(n))return null;let s=e._originalConversationMessages,i=e.conversationMessages;if(!this.conversationMemory&&!s&&!i)return null;g.warn(`[${t}] Context overflow detected by provider, attempting smart recovery`,{error:n instanceof Error?n.message:String(n),overflowProvider:KGe(n)});try{let a=JGe(n),c=s??i??(this.conversationMemory?await Mg(this.conversationMemory,e):[]),l=Xc({provider:e.provider||"openai",model:e.model,maxTokens:e.maxTokens,currentPrompt:e.prompt,systemPrompt:e.systemPrompt}),u=a?.actualTokens??l.estimatedInputTokens,d=a?.budgetTokens??l.availableInputTokens,m=Math.floor(d*.7),f=u>0?(u-m)/u:.5,h=[Math.min(.9,f+.15),.5,.75,.9],y=null,x=c,b=null,T=-1;for(let k=0;k<h.length;k++){let C=h[k],P=await new fx({enableSummarize:!1,enablePrune:!0,enableDeduplicate:!0,enableTruncate:!0,truncationFraction:C}).compact(c,m,void 0,e.context?.requestId);if(!P.compacted)continue;y=P;let A=uk(P.messages),I=Xc({provider:e.provider||"openai",model:e.model,maxTokens:e.maxTokens,systemPrompt:e.systemPrompt,currentPrompt:e.prompt,conversationMessages:A.messages});if(I.withinBudget){x=A.messages,b=I,T=C;break}b=I}if(!y){try{this.emitter.emit("compaction.insufficient",{stagesAttempted:[],finalTokens:u,budget:d,provider:e.provider||"openai",model:e.model,phase:"post-provider-recovery-no-compaction",fractionsTried:h,timestamp:Date.now()})}catch{}throw new Vl(`Context overflow recovery: no compaction stage was able to reduce conversation messages. Provider rejected at ~${u} tokens; budget is ${d} tokens.`,{estimatedTokens:u,availableTokens:d,stagesUsed:[],breakdown:{}})}if(!b?.withinBudget){g.error(`[${t}] Recovery compaction insufficient after escalation, aborting retry`,{estimatedTokens:b?.estimatedInputTokens,availableTokens:b?.availableInputTokens,stagesAttempted:y.stagesUsed,fractionsTried:h});try{this.emitter.emit("compaction.insufficient",{stagesAttempted:y.stagesUsed,finalTokens:b?.estimatedInputTokens,budget:b?.availableInputTokens,provider:e.provider||"openai",model:e.model,phase:"post-provider-recovery",fractionsTried:h,timestamp:Date.now()})}catch{}throw new Vl(`Context overflow recovery failed. Provider rejected at ~${u} tokens, recovery compaction achieved ${y.tokensAfter} tokens but budget is ${d} tokens (after escalation through ${h.length} fractions).`,{estimatedTokens:y.tokensAfter,availableTokens:d,stagesUsed:y.stagesUsed,breakdown:b?.breakdown??{}})}let w=e.turnTimeoutMs;if(typeof e.turnTimeoutMs=="number"&&Number.isFinite(e.turnTimeoutMs)&&o!==void 0){let k=Date.now()-o;w=Math.max(e.turnTimeoutMs-k,Math.min(dX,e.turnTimeoutMs))}return g.info(`[${t}] Smart recovery verified, retrying generation`,{tokensSaved:y.tokensSaved,compactionTarget:m,verifiedTokens:b.estimatedInputTokens,verifiedBudget:b.availableInputTokens,recoveredFraction:T,retryTurnTimeoutMs:w}),this.directProviderGeneration({...e,conversationMessages:x,...w!==void 0&&{turnTimeoutMs:w}})}catch(a){if(a instanceof Vl)throw a;return g.error(`[${t}] Recovery attempt failed`,{error:a instanceof Error?a.message:String(a)}),null}}logGenerateTextInternalStart(e,t,n,o,s){g.debug(`[${s}] Starting generation`,{provider:o.provider||"auto",promptLength:o.prompt?.length||0,hasConversationMemory:!!this.conversationMemory})}emitGenerationStartEvents(e){this.emitter.emit("response:start"),this.emitter.emit("message",`Starting ${e.provider||"auto"} text generation (internal)...`)}async initializeConversationMemoryForGeneration(e,t,n){let o=process.hrtime.bigint();if(this.conversationMemoryNeedsInit&&this.conversationMemoryConfig&&await this.lazyInitializeConversationMemory(e,t,n),this.conversationMemory){g.debug("[NeuroLink] \u{1F9E0} LOG_POINT_G003_CONVERSATION_MEMORY_INIT_START",{logPoint:"G003_CONVERSATION_MEMORY_INIT_START",generateInternalId:e,timestamp:new Date().toISOString(),elapsedMs:Date.now()-t,elapsedNs:(process.hrtime.bigint()-n).toString(),message:"Starting conversation memory initialization"});try{await this.conversationMemory.initialize()}catch(a){g.warn("[NEUROLINK] Redis memory init failed, falling back to in-memory",{error:a instanceof Error?a.message:String(a),generateInternalId:e});let c=this.conversationMemoryConfig?.conversationMemory;this.conversationMemory=new kT({enabled:!0,maxSessions:c?.maxSessions??100,maxTurnsPerSession:c?.maxTurnsPerSession??50}),await this.conversationMemory.initialize()}let i=process.hrtime.bigint()-o;g.debug("[NeuroLink] \u2705 LOG_POINT_G004_CONVERSATION_MEMORY_INIT_SUCCESS",{logPoint:"G004_CONVERSATION_MEMORY_INIT_SUCCESS",generateInternalId:e,timestamp:new Date().toISOString(),elapsedMs:Date.now()-t,elapsedNs:(process.hrtime.bigint()-n).toString(),conversationMemoryDurationNs:i.toString(),conversationMemoryDurationMs:Number(i)/sp,message:"Conversation memory initialization completed successfully"})}}async attemptMCPGeneration(e,t,n,o,s){return!e.disableTools&&!(e.tts?.enabled&&!e.tts?.useAiResponse)?await this.performMCPGenerationRetries(e,t,n,o,s):null}static isNonRetryableToolError(e){if(e instanceof Error&&(Pv.isInstance(e)||Ov.isInstance(e)))return!0;let t=e,n=t&&typeof t.name=="string"?t.name:"",o=t&&typeof t.message=="string"?t.message:String(e??"");return n==="AI_NoSuchToolError"||n==="AI_InvalidToolInputError"||n==="AI_InvalidToolArgumentsError"||o.includes("NoSuchToolError")||o.includes("InvalidToolInputError")||o.includes("InvalidToolArgumentsError")||o.includes("Model tried to call unavailable tool")}async performMCPGenerationRetries(e,t,n,o,s){let i=Jo.QUICK,a=e.timeout!==void 0,c=[],l=0,u=i+1;for(let d=1;d<=u;d++){if(e.abortSignal?.aborted)throw g.debug(`[${s}] Abort signal already fired before attempt ${d}, stopping retries`),new DOMException("The operation was aborted","AbortError");try{g.debug(`[${s}] Attempting MCP generation (attempt ${d}/${u})...`);let m=await this.tryMCPGeneration(e);if(m&&(m.content||m.toolExecutions&&m.toolExecutions.length>0))return g.debug(`[${s}] MCP generation successful on attempt ${d}`,{contentLength:m.content?.length||0,toolsUsed:m.toolsUsed?.length||0,toolExecutions:m.toolExecutions?.length||0,retryCount:l}),l>0&&(m.retries={count:l,errors:c}),m;g.debug(`[${s}] MCP generation returned empty result on attempt ${d}`,{hasResult:!!m,hasContent:!!(m&&m.content),contentLength:m?.content?.length||0,toolExecutions:m?.toolExecutions?.length||0})}catch(m){if(Hr(m))throw g.debug(`[${s}] AbortError detected on attempt ${d}, stopping retries`),m;if(a&&m instanceof Error&&m.name==="TimeoutError")throw g.warn(`[${s}] Per-step timeout (${String(e.timeout)}) exhausted on attempt ${d} \u2014 surfacing instead of retrying with the same budget`),m;l++;let f=m instanceof Error?m.message:String(m),h=m instanceof Fe?m.code:m instanceof Error?m.name:"UNKNOWN";c.push({code:h,message:f.substring(0,500)}),g.debug(`[${s}] MCP generation failed on attempt ${d}/${u}`,{error:f,willRetry:d<u,retryCount:l});let y=r.isNonRetryableToolError(m);if(_ce(m)||y||_W(m)||m instanceof Error&&m.isRetryable===!1||m instanceof Error&&m.statusCode===400){g.debug(`[${s}] Non-retryable error detected, skipping remaining retries`);break}if(d>=u){g.debug(`[${s}] All MCP attempts exhausted, falling back to direct generation`);break}if(await new Promise(b=>{let T=setTimeout(b,500);if(e.abortSignal){let w=()=>{clearTimeout(T),b()};e.abortSignal.addEventListener("abort",w,{once:!0})}}),e.abortSignal?.aborted)throw new DOMException("The operation was aborted","AbortError")}}return null}async tryMCPGeneration(e){if(e.abortSignal?.aborted)throw new DOMException("The operation was aborted","AbortError");let t=e.context?.requestId||"unknown",n=`try-mcp-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,o=Date.now(),s=process.hrtime.bigint(),i="NeuroLink.tryMCPGeneration";try{let a=await this.prepareMCPGenerationContext(e,t,n,o,s);if(!a)return null;let c=await this.ensureMCPGenerationBudget(e,t,a.providerName,a.enhancedSystemPrompt,a.availableTools,a.conversationMessages);return this.generateWithMCPProvider({options:e,requestId:t,functionTag:i,tryMCPStartTime:o,providerName:a.providerName,availableTools:a.availableTools,enhancedSystemPrompt:a.enhancedSystemPrompt,conversationMessages:c})}catch(a){if(Hr(a))throw ie.debug(`[${i}] AbortError detected, rethrowing`),a;if(r.isNonRetryableToolError(a))throw ie.warn(`[${i}] Non-retryable tool error, rethrowing`,{error:a instanceof Error?a.message:String(a)}),a;return ie.warn(`[${i}] MCP generation failed`,{error:a instanceof Error?a.message:String(a)}),null}}async prepareMCPGenerationContext(e,t,n,o,s){if(await this.initializeMCP(),!this.mcpInitialized)return g.warn("[NeuroLink] \u26A0\uFE0F LOG_POINT_T004_MCP_NOT_AVAILABLE",{logPoint:"T004_MCP_NOT_AVAILABLE",tryMCPId:n,timestamp:new Date().toISOString(),elapsedMs:Date.now()-o,elapsedNs:(process.hrtime.bigint()-s).toString(),mcpInitialized:this.mcpInitialized,mcpComponents:{hasExternalServerManager:!!this.externalServerManager,hasToolRegistry:!!this.toolRegistry,hasProviderRegistry:!!dn},fallbackReason:"MCP_NOT_INITIALIZED",message:"MCP not available - returning null for fallback to direct generation"}),null;let i=e.provider==="auto"||!e.provider?await Rx():e.provider,a=await this.getAllAvailableTools(),{tools:c,unavailableTools:l}=this.toolRegistry.getAvailableTools(this.toolCircuitBreakers),u=new Set(c.map(y=>y.name));a=a.filter(y=>u.has(y.name)),a=this.applyToolInfoFiltering(a,e);let d=a.find(y=>y.name.includes("SuccessRateSRByTime")||y.name.includes("juspay-analytics"));g.debug("Available tools for AI prompt generation",{toolsCount:a.length,toolNames:a.map(y=>y.name),unavailableToolsCount:l.length,unavailableTools:l,hasTargetTool:!!d,targetToolDetails:d?{name:d.name,description:d.description,server:d.server}:null});let m=l.length>0?`
2195
+ IMPORTANT: You have a tool called "${o.toolName}" that searches through`,`${o.filesLoaded} loaded document(s) containing ${o.chunksIndexed} indexed chunks.`,`ALWAYS use the "${o.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(" "),g.info("[RAG] Tool injected into generate()",{toolName:o.toolName,filesLoaded:o.filesLoaded,chunksIndexed:o.chunksIndexed})}catch(n){g.warn("[RAG] Failed to prepare RAG tool, continuing without RAG",{error:n instanceof Error?n.message:String(n)})}if(await this.applySkillsAugmentation(e),!(e.output?.mode==="avatar"||e.output?.mode==="music"||e.output?.mode==="video"||e.output?.mode==="ppt"||!this.shouldReadMemory(e.memory,e.context?.userId)||!e.context?.userId))try{e.input&&(e.input.text=await this.retrieveMemory(e.input.text??"",e.context.userId,e.memory?.additionalUsers)),g.debug("Memory retrieval successful (generate)")}catch(n){g.warn("Memory retrieval failed (generate):",n)}}async buildGenerateTextOptions(e,t,n){let o={prompt:e.input?.text,provider:e.provider,model:e.model,temperature:e.temperature,maxTokens:e.maxTokens,systemPrompt:e.systemPrompt,schema:e.schema,output:e.output,tools:e.tools,disableTools:e.disableTools,toolFilter:e.toolFilter,excludeTools:e.excludeTools,maxSteps:e.maxSteps,toolChoice:e.toolChoice,prepareStep:e.prepareStep,enabledToolNames:e.enabledToolNames,enableAnalytics:e.enableAnalytics,enableEvaluation:e.enableEvaluation,context:e.context,evaluationDomain:e.evaluationDomain,toolUsageContext:e.toolUsageContext,input:e.input,region:e.region,tts:e.tts,stt:e.stt,fileRegistry:this.fileRegistry,timeout:e.timeout,turnTimeoutMs:e.turnTimeoutMs,stallTimeoutMs:e.stallTimeoutMs,wrapupTimeLeadMs:e.wrapupTimeLeadMs,toolTimeoutMs:e.toolTimeoutMs,abortSignal:e.abortSignal,skipToolPromptInjection:e.skipToolPromptInjection,middleware:e.middleware,conversationMessages:e.conversationMessages,credentials:e.credentials,onFinish:e.onFinish,onError:e.onError},s=e;(s.sessionId||s.userId)&&(o.context={...o.context,...s.sessionId&&!o.context?.sessionId?{sessionId:s.sessionId}:{},...s.userId&&!o.context?.userId?{userId:s.userId}:{}});let i=g3e(o,n);this.conversationMemory&&(i.conversationMemoryConfig=this.conversationMemory.config,i.originalPrompt=t);let{toolResults:a,enhancedPrompt:c}=await this.detectAndExecuteTools(i.prompt||e.input?.text||"",n.domainType);return c!==i.prompt&&(i.prompt=c,g.debug("Enhanced prompt with tool results",{originalLength:(e.input?.text??"").length,enhancedLength:c.length,toolResults:a.length})),i}finalizeGenerateRequestResult(e){let{generateSpan:t,options:n,textOptions:o,textResult:s,factoryResult:i,originalPrompt:a,startTime:c}=e;if(o.schema&&s.structuredData===void 0&&typeof s.content=="string"){let f=tj(s.content,o.schema);if(f)s.content=f.content,s.structuredData=f.structuredData,f.repaired&&(s.jsonRepaired=!0),f.truncated&&(s.jsonTruncated=!0);else try{let h=JSON.parse(s.content);h===""?(s.content="",g.warn("[NeuroLink] schema requested but the model returned an empty JSON string; normalizing to empty content",{provider:s.provider,model:s.model})):h!=null&&(s.structuredData=h)}catch{g.warn("[NeuroLink] schema requested but no JSON could be recovered from model output; returning raw text",{provider:s.provider,model:s.model})}}o.schema&&(s.finishReason==="length"&&(s.jsonTruncated=!0),s.jsonTruncated&&g.warn("[NeuroLink] Structured output may be truncated (finishReason=length or unclosed JSON); increase maxTokens to fit the full response.",{provider:s.provider,model:s.model,finishReason:s.finishReason,outputTokens:s.usage?.output})),s._generationEndEmitted||this.emitter.emit("generation:end",{provider:s.provider,responseTime:Date.now()-c,toolsUsed:s.toolsUsed,timestamp:Date.now(),result:s,prompt:a||n.input?.text||n.prompt,temperature:o.temperature,maxTokens:o.maxTokens,pipelineAHandled:!0}),this.emitter.emit("response:end",s.content||""),this.emitter.emit("message",`Generation completed in ${Date.now()-c}ms`);let u={content:s.content,structuredData:s.structuredData,finishReason:s.finishReason,stopReason:s.stopReason,rawFinishReason:s.rawFinishReason,stepsUsed:s.stepsUsed,jsonRepaired:s.jsonRepaired,jsonTruncated:s.jsonTruncated,provider:s.provider,model:s.model,usage:s.usage?{input:s.usage.input||0,output:s.usage.output||0,total:s.usage.total||0}:void 0,responseTime:s.responseTime,toolsUsed:s.toolsUsed,toolExecutions:cd(s.toolExecutions),enhancedWithTools:s.enhancedWithTools,availableTools:oPe(s.availableTools),analytics:s.analytics,imageOutput:s.imageOutput,evaluation:s.evaluation?{...s.evaluation,isOffTopic:s.evaluation.isOffTopic??!1,alertSeverity:s.evaluation.alertSeverity??"none",reasoning:s.evaluation.reasoning??"No evaluation provided",evaluationModel:s.evaluation.evaluationModel??"unknown",evaluationTime:s.evaluation.evaluationTime??Date.now(),evaluationDomain:s.evaluation.evaluationDomain??o.evaluationDomain??i.domainType}:void 0,audio:s.audio,transcription:s.transcription,video:s.video,avatar:s.avatar,music:s.music,ppt:s.ppt,reasoning:s.reasoning,reasoningTokens:s.reasoningTokens,...s.retries&&{retries:s.retries}};if(n.responseValidation){let f=tpe(u.content??"",{minLength:n.responseValidation.minLength,maxLength:n.responseValidation.maxLength,requiredPhrases:n.responseValidation.requiredPhrases,forbiddenPhrases:n.responseValidation.forbiddenPhrases,jsonSchema:n.responseValidation.jsonSchema,customValidator:n.responseValidation.customValidator,truncationAction:n.responseValidation.truncationAction,truncationSuffix:n.responseValidation.truncationSuffix,retryOnFailure:n.responseValidation.retryOnFailure,maxRetries:n.responseValidation.maxRetries});if(f.action==="abort")throw new Error(f.feedback??`Response validation failed: ${f.issues.map(h=>h.message).join("; ")}`);f.text!==u.content&&(u.content=f.text)}u.analytics?.cost&&u.analytics.cost>0&&(this._sessionCostUsd+=u.analytics.cost),this.scheduleGenerateMemoryStorage(n,a,u),t.setAttribute("neurolink.output_length",u.content?.length||0),t.setAttribute("neurolink.tokens.input",u.usage?.input||0),t.setAttribute("neurolink.tokens.output",u.usage?.output||0),t.setAttribute("neurolink.finish_reason",u.finishReason||"unknown");let d=s?.steps?.length??1,m=n.maxSteps??200;return t.setAttribute("neurolink.step_count",d),t.setAttribute("neurolink.max_steps_reached",d>=m),t.setAttribute("neurolink.result_provider",u.provider||"unknown"),t.setAttribute("neurolink.result_model",u.model||"unknown"),t.setAttribute("generate.retry_count",u.retries?.count||0),t.setStatus({code:Ie.OK}),u}emitGenerateErrorEvent(e,t){let n=typeof e=="object"&&e.provider||"unknown",o=typeof e=="object"&&e.model||"unknown",s=Hr(t);try{this.emitter.emit("generation:end",{provider:n,model:o,responseTime:0,error:t instanceof Error?t.message:String(t),success:!1,aborted:s})}catch(i){}}scheduleGenerateMemoryStorage(e,t,n){this.shouldWriteMemory(e.memory,e.context?.userId,n.content)&&e.context?.userId&&this.storeMemoryInBackground(t??"",n.content.trim(),e.context.userId,e.memory?.additionalUsers,e.context)}async generateWithPPT(e){let t=Date.now(),{generatePresentation:n}=await q5e().then(()=>V5e),{extractPPTContext:o,getEffectivePPTProvider:s}=await Promise.resolve().then(()=>(lW(),i5e)),i=e.provider||"vertex",a=await dn.createProvider(i,e.model,!0,this,void 0,this.resolveCredentials(e.credentials)),c=await s(a,i,e.model||"default",this),l=o(e),u=await n({context:l,provider:c.provider,providerName:c.providerName,modelName:c.modelName,neurolink:this});return{content:`Presentation generated: ${u.filePath} (${u.totalSlides} slides)`,finishReason:"stop",provider:u.provider||i,model:u.model||e.model||"default",usage:void 0,responseTime:Date.now()-t,ppt:u}}async generateWithMusic(e,t){let n=Date.now(),o=e.output?.music;if(!o)throw new Error('output.mode="music" requires output.music with at least { provider, prompt }.');let s=o.provider;if(!s)throw new Error('output.music.provider is required (e.g. "beatoven", "elevenlabs-music", "lyria", "replicate").');let{MusicProcessor:i}=await Promise.resolve().then(()=>(of(),Vpe)),a=await i.generate(s,{...o,prompt:o.prompt??e.input?.text??""});return t.setAttribute("neurolink.music.provider",s),t.setAttribute("neurolink.music.bytes",a.size),t.setStatus({code:Ie.OK}),{content:`Music generated (${s}, ${a.size} bytes, ${a.format}).`,finishReason:"stop",provider:s,model:a.metadata?.model??s,usage:void 0,responseTime:Date.now()-n,music:a}}async generateWithAvatar(e,t){let n=Date.now(),o=e.output?.avatar;if(!o)throw new Error('output.mode="avatar" requires output.avatar with at least { provider, image, audio|text }.');let s=o.provider;if(!s)throw new Error('output.avatar.provider is required (e.g. "d-id", "heygen", "replicate").');let{AvatarProcessor:i}=await Promise.resolve().then(()=>(qg(),qpe)),a=await i.generate(s,o);return t.setAttribute("neurolink.avatar.provider",s),t.setAttribute("neurolink.avatar.bytes",a.size),t.setStatus({code:Ie.OK}),{content:`Avatar generated (${s}, ${a.size} bytes, ${a.format}).`,finishReason:"stop",provider:s,model:a.metadata?.model??s,usage:void 0,responseTime:Date.now()-n,avatar:a}}async generateWithWorkflow(e){let t=Date.now();g.debug("[NeuroLink] Executing workflow generation",{workflowId:e.workflow,hasInlineConfig:!!e.workflowConfig,prompt:(e.input?.text??"").substring(0,100),startTime:t});let n;if(e.workflowConfig)n=e.workflowConfig;else if(e.workflow){if(n=B3(e.workflow),!n)throw new Error(`Workflow '${e.workflow}' not found in registry`)}else throw new Error("Either workflow or workflowConfig must be provided");let o=await z3(n,{prompt:e.input?.text??"",conversationHistory:e.conversationMessages?.filter(i=>i.role==="user"||i.role==="assistant").map(i=>({role:i.role,content:jm(i.content)}))??e.conversationHistory,timeout:e.timeout,verbose:!1,metadata:e.context}),s={content:o.content,provider:o.selectedResponse?.provider||n.models[0]?.provider,model:o.selectedResponse?.model||n.models[0]?.model,usage:o.usage?{input:o.usage.totalInputTokens,output:o.usage.totalOutputTokens,total:o.usage.totalTokens}:void 0,responseTime:o.totalTime,workflow:{originalResponse:o.originalContent||o.content,processedResponse:o.content,ensembleResponses:o.ensembleResponses.map(i=>({provider:i.provider,model:i.model,content:i.content,responseTime:i.responseTime,status:i.status,error:i.error})),judgeScores:o.judgeScores?{scores:o.judgeScores.scores,reasoning:o.reasoning,selectedModel:`${o.selectedResponse?.provider}-${o.selectedResponse?.model}`}:void 0,selectedModel:`${o.selectedResponse?.provider}-${o.selectedResponse?.model}`,metrics:{totalTime:o.totalTime,ensembleTime:o.ensembleTime,judgeTime:o.judgeTime,conditioningTime:o.conditioningTime},workflowId:o.workflow,workflowName:o.workflowName}};return g.debug("[NeuroLink] Workflow generation complete",{workflowId:o.workflow,selectedModel:s.workflow?.selectedModel,score:o.score,totalTime:o.totalTime}),s}async streamWithWorkflow(e,t){g.debug("[NeuroLink] Executing workflow streaming (progressive)",{workflowId:e.workflow,hasInlineConfig:!!e.workflowConfig,prompt:(e.input?.text??"").substring(0,100)});let n;if(e.workflowConfig)n=e.workflowConfig;else if(e.workflow){if(n=B3(e.workflow),!n)throw new Error(`Workflow '${e.workflow}' not found in registry`)}else throw new Error("Either workflow or workflowConfig must be provided");let{runWorkflowWithStreaming:o}=await Promise.resolve().then(()=>(j3(),cWe)),s=o(n,{prompt:e.input?.text??"",conversationHistory:e.conversationMessages?.filter(d=>d.role==="user"||d.role==="assistant").map(d=>({role:d.role,content:jm(d.content)}))??e.conversationHistory,timeout:e.timeout,verbose:!1,metadata:e.context,streaming:!0}),i=null,a=0,l={stream:(async function*(){for await(let d of s)if(d.type==="preliminary")a=Date.now()-t,g.debug("[NeuroLink] Streaming preliminary response",{responseTime:a,contentLength:d.content.length}),yield{content:d.content,type:"preliminary"};else if(d.type==="final"){i=d.partialResult??null;let m=Date.now()-t;g.debug("[NeuroLink] Streaming final synthesis",{responseTime:m,contentLength:d.content.length}),yield{content:d.content,type:"final"}}})(),provider:n.models[0]?.provider,model:n.models[0]?.model,metadata:{streamId:`workflow-${n.id}-${Date.now()}`,startTime:t,responseTime:0}},u=l.stream;return l.stream=(async function*(){for await(let d of u)yield d;if(i){let d=i,m=Date.now()-t;d.usage&&(l.usage={input:d.usage.totalInputTokens,output:d.usage.totalOutputTokens,total:d.usage.totalTokens}),l.metadata={...l.metadata,totalChunks:2,responseTime:m,preliminaryTime:a};let f=d.ensembleResponses?.map(y=>({provider:y.provider,model:y.model,content:y.content,responseTime:y.responseTime,status:y.status,error:y.error}))??[],h=d.judgeScores?{scores:d.judgeScores.scores,reasoning:d.reasoning??"",selectedModel:d.selectedResponse?`${d.selectedResponse.provider}-${d.selectedResponse.model}`:"unknown"}:void 0;l.workflow={originalResponse:d.originalContent??d.content??"",processedResponse:d.content??"",ensembleResponses:f,judgeScores:h,selectedModel:d.selectedResponse?`${d.selectedResponse.provider}-${d.selectedResponse.model}`:"unknown",metrics:{totalTime:d.totalTime??m,ensembleTime:d.ensembleTime??0,judgeTime:d.judgeTime,conditioningTime:d.conditioningTime},workflowId:d.workflow??n.id,workflowName:d.workflowName??n.name}}})(),g.debug("[NeuroLink] Workflow streaming initialized",{workflowId:n.id}),l}async generateText(e){if(!e.prompt||typeof e.prompt!="string"||e.prompt.trim()==="")throw new Error("GenerateText options must include prompt as a non-empty string");return e.model=qk(e.model,this.modelAliasConfig),await this.generateTextInternal(e)}async generateTextInternal(e){return _e.sdk.startActiveSpan("neurolink.generateTextInternal",{kind:Cr.INTERNAL},t=>this.executeGenerateTextInternalWithSpan(e,t))}async executeGenerateTextInternalWithSpan(e,t){try{let n=this.initializeGenerateTextInternalContext(e);return t.setAttribute("neurolink.request_id",n.requestId),t.setAttribute("neurolink.has_conversation_memory",!!this.conversationMemory),t.setAttribute("neurolink.provider",e.provider||"auto"),t.setAttribute("neurolink.model",e.model||"default"),this.logGenerateTextInternalStart(n.generateInternalId,n.generateInternalStartTime,n.generateInternalHrTimeStart,e,n.functionTag),this.emitGenerationStartEvents(e),await this.runGenerateTextInternalFlow(e,t,n)}catch(n){throw Hr(n)?(t.setAttribute("ai.finishReason","aborted"),t.setAttribute("neurolink.aborted",!0)):(t.recordException(n instanceof Error?n:new Error(String(n))),t.setStatus({code:Ie.ERROR,message:n instanceof Error?n.message:String(n)})),n}finally{t.end()}}initializeGenerateTextInternalContext(e){let t=`generate-internal-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,n=e.context?.requestId,o=typeof n=="string"&&n?n:`req-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;return e.context={...e.context,requestId:o},{generateInternalId:t,generateInternalStartTime:Date.now(),generateInternalHrTimeStart:process.hrtime.bigint(),functionTag:"NeuroLink.generateTextInternal",requestId:o}}async runGenerateTextInternalFlow(e,t,n){try{await this.initializeConversationMemoryForGeneration(n.generateInternalId,n.generateInternalStartTime,n.generateInternalHrTimeStart);let o=await this.attemptMCPGeneration(e,n.generateInternalId,n.generateInternalStartTime,n.generateInternalHrTimeStart,n.functionTag);if(o)return this.finalizeGenerateTextInternalResult({path:"mcp",result:o,options:e,internalSpan:t,requestId:n.requestId,startTime:n.generateInternalStartTime});if(e.abortSignal?.aborted)throw new DOMException("The operation was aborted","AbortError");await this.captureOriginalConversationMessagesForRecovery(e);let s=await this.directProviderGeneration(e);return g.debug(`[${n.functionTag}] Direct generation successful`),this.finalizeGenerateTextInternalResult({path:"direct",result:s,options:e,internalSpan:t,requestId:n.requestId,startTime:n.generateInternalStartTime})}catch(o){let s=await this.handleGenerateTextInternalFailure(e,n,o);if(s)return s;throw Hr(o)&&!(o instanceof Fe)?pe.aborted(o instanceof Error?o:new Error(String(o))):o}}async captureOriginalConversationMessagesForRecovery(e){if(!this.conversationMemory)return;let t=await Mg(this.conversationMemory,e);e._originalConversationMessages=t?[...t]:void 0}async finalizeGenerateTextInternalResult(e){let{path:t,result:n,options:o,internalSpan:s,requestId:i,startTime:a}=e;g.info(`[NeuroLink.generateTextInternal] generate() - COMPLETE SUCCESS${t==="mcp"?" (MCP path)":""}`,{provider:n.provider,model:n.model,responseTimeMs:Date.now()-a,tokensUsed:n.usage?.total||0,toolsUsed:n.toolsUsed?.length||0,...n.usage?.cacheCreationTokens!==void 0&&{cacheCreationTokens:n.usage.cacheCreationTokens},...n.usage?.cacheReadTokens!==void 0&&{cacheReadTokens:n.usage.cacheReadTokens},...n.usage?.cacheSavingsPercent!==void 0&&{cacheSavingsPercent:n.usage.cacheSavingsPercent}});let c=Date.now();try{await jGe(this.conversationMemory,o,n,new Date(a),i,this.drainPendingSkillMessages(o.context?.sessionId)),this.recordMemorySpan("memory.store",{"memory.operation":"store","memory.path":t},Date.now()-c,1)}catch(l){this.recordMemorySpan("memory.store",{"memory.operation":"store","memory.path":t},Date.now()-c,2,l instanceof Error?l.message:String(l))}return this.emitter.emit("response:end",n.content||""),t==="direct"&&this.emitter.emit("message","Text generation completed successfully"),s.setAttribute("neurolink.path",t),s.setAttribute("neurolink.tokens.input",n.usage?.input||0),s.setAttribute("neurolink.tokens.output",n.usage?.output||0),s.setAttribute("neurolink.result_provider",n.provider||"unknown"),s.setStatus({code:Ie.OK}),n}async handleGenerateTextInternalFailure(e,t,n){let o=await this.tryRecoverGenerateTextOverflow(e,t.functionTag,n,t.generateInternalStartTime);return o||(Hr(n)?g.info(`[${t.functionTag}] Generation aborted \u2014 skipping memory write (aborts must not pollute conversation history)`,{hasMemory:!!this.conversationMemory,memoryType:this.conversationMemory?.constructor?.name||"NONE",sessionId:e.context?.sessionId||"unknown"}):g.error(`[${t.functionTag}] All generation methods failed`,{error:n instanceof Error?n.message:String(n)}),this.emitter.emit("response:end",""),this.emitter.listenerCount("error")>0&&this.emitter.emit("error",n instanceof Error?n:new Error(String(n))),null)}async tryRecoverGenerateTextOverflow(e,t,n,o){if(!_ce(n))return null;let s=e._originalConversationMessages,i=e.conversationMessages;if(!this.conversationMemory&&!s&&!i)return null;g.warn(`[${t}] Context overflow detected by provider, attempting smart recovery`,{error:n instanceof Error?n.message:String(n),overflowProvider:KGe(n)});try{let a=JGe(n),c=s??i??(this.conversationMemory?await Mg(this.conversationMemory,e):[]),l=Xc({provider:e.provider||"openai",model:e.model,maxTokens:e.maxTokens,currentPrompt:e.prompt,systemPrompt:e.systemPrompt}),u=a?.actualTokens??l.estimatedInputTokens,d=a?.budgetTokens??l.availableInputTokens,m=Math.floor(d*.7),f=u>0?(u-m)/u:.5,h=[Math.min(.9,f+.15),.5,.75,.9],y=null,x=c,b=null,T=-1;for(let k=0;k<h.length;k++){let C=h[k],P=await new fx({enableSummarize:!1,enablePrune:!0,enableDeduplicate:!0,enableTruncate:!0,truncationFraction:C}).compact(c,m,void 0,e.context?.requestId);if(!P.compacted)continue;y=P;let A=uk(P.messages),I=Xc({provider:e.provider||"openai",model:e.model,maxTokens:e.maxTokens,systemPrompt:e.systemPrompt,currentPrompt:e.prompt,conversationMessages:A.messages});if(I.withinBudget){x=A.messages,b=I,T=C;break}b=I}if(!y){try{this.emitter.emit("compaction.insufficient",{stagesAttempted:[],finalTokens:u,budget:d,provider:e.provider||"openai",model:e.model,phase:"post-provider-recovery-no-compaction",fractionsTried:h,timestamp:Date.now()})}catch{}throw new Vl(`Context overflow recovery: no compaction stage was able to reduce conversation messages. Provider rejected at ~${u} tokens; budget is ${d} tokens.`,{estimatedTokens:u,availableTokens:d,stagesUsed:[],breakdown:{}})}if(!b?.withinBudget){g.error(`[${t}] Recovery compaction insufficient after escalation, aborting retry`,{estimatedTokens:b?.estimatedInputTokens,availableTokens:b?.availableInputTokens,stagesAttempted:y.stagesUsed,fractionsTried:h});try{this.emitter.emit("compaction.insufficient",{stagesAttempted:y.stagesUsed,finalTokens:b?.estimatedInputTokens,budget:b?.availableInputTokens,provider:e.provider||"openai",model:e.model,phase:"post-provider-recovery",fractionsTried:h,timestamp:Date.now()})}catch{}throw new Vl(`Context overflow recovery failed. Provider rejected at ~${u} tokens, recovery compaction achieved ${y.tokensAfter} tokens but budget is ${d} tokens (after escalation through ${h.length} fractions).`,{estimatedTokens:y.tokensAfter,availableTokens:d,stagesUsed:y.stagesUsed,breakdown:b?.breakdown??{}})}let w=e.turnTimeoutMs;if(typeof e.turnTimeoutMs=="number"&&Number.isFinite(e.turnTimeoutMs)&&o!==void 0){let k=Date.now()-o;w=Math.max(e.turnTimeoutMs-k,Math.min(dX,e.turnTimeoutMs))}return g.info(`[${t}] Smart recovery verified, retrying generation`,{tokensSaved:y.tokensSaved,compactionTarget:m,verifiedTokens:b.estimatedInputTokens,verifiedBudget:b.availableInputTokens,recoveredFraction:T,retryTurnTimeoutMs:w}),this.directProviderGeneration({...e,conversationMessages:x,...w!==void 0&&{turnTimeoutMs:w}})}catch(a){if(a instanceof Vl)throw a;return g.error(`[${t}] Recovery attempt failed`,{error:a instanceof Error?a.message:String(a)}),null}}logGenerateTextInternalStart(e,t,n,o,s){g.debug(`[${s}] Starting generation`,{provider:o.provider||"auto",promptLength:o.prompt?.length||0,hasConversationMemory:!!this.conversationMemory})}emitGenerationStartEvents(e){this.emitter.emit("response:start"),this.emitter.emit("message",`Starting ${e.provider||"auto"} text generation (internal)...`)}async initializeConversationMemoryForGeneration(e,t,n){let o=process.hrtime.bigint();if(this.conversationMemoryNeedsInit&&this.conversationMemoryConfig&&await this.lazyInitializeConversationMemory(e,t,n),this.conversationMemory){g.debug("[NeuroLink] \u{1F9E0} LOG_POINT_G003_CONVERSATION_MEMORY_INIT_START",{logPoint:"G003_CONVERSATION_MEMORY_INIT_START",generateInternalId:e,timestamp:new Date().toISOString(),elapsedMs:Date.now()-t,elapsedNs:(process.hrtime.bigint()-n).toString(),message:"Starting conversation memory initialization"});try{await this.conversationMemory.initialize()}catch(a){g.warn("[NEUROLINK] Redis memory init failed, falling back to in-memory",{error:a instanceof Error?a.message:String(a),generateInternalId:e});let c=this.conversationMemoryConfig?.conversationMemory;this.conversationMemory=new kT({enabled:!0,maxSessions:c?.maxSessions??100,maxTurnsPerSession:c?.maxTurnsPerSession??50}),await this.conversationMemory.initialize()}let i=process.hrtime.bigint()-o;g.debug("[NeuroLink] \u2705 LOG_POINT_G004_CONVERSATION_MEMORY_INIT_SUCCESS",{logPoint:"G004_CONVERSATION_MEMORY_INIT_SUCCESS",generateInternalId:e,timestamp:new Date().toISOString(),elapsedMs:Date.now()-t,elapsedNs:(process.hrtime.bigint()-n).toString(),conversationMemoryDurationNs:i.toString(),conversationMemoryDurationMs:Number(i)/sp,message:"Conversation memory initialization completed successfully"})}}async attemptMCPGeneration(e,t,n,o,s){return!e.disableTools&&!(e.tts?.enabled&&!e.tts?.useAiResponse)?await this.performMCPGenerationRetries(e,t,n,o,s):null}static isNonRetryableToolError(e){if(e instanceof Error&&(Pv.isInstance(e)||Ov.isInstance(e)))return!0;let t=e,n=t&&typeof t.name=="string"?t.name:"",o=t&&typeof t.message=="string"?t.message:String(e??"");return n==="AI_NoSuchToolError"||n==="AI_InvalidToolInputError"||n==="AI_InvalidToolArgumentsError"||o.includes("NoSuchToolError")||o.includes("InvalidToolInputError")||o.includes("InvalidToolArgumentsError")||o.includes("Model tried to call unavailable tool")}async performMCPGenerationRetries(e,t,n,o,s){let i=Jo.QUICK,a=e.timeout!==void 0,c=[],l=0,u=i+1;for(let d=1;d<=u;d++){if(e.abortSignal?.aborted)throw g.debug(`[${s}] Abort signal already fired before attempt ${d}, stopping retries`),new DOMException("The operation was aborted","AbortError");try{g.debug(`[${s}] Attempting MCP generation (attempt ${d}/${u})...`);let m=await this.tryMCPGeneration(e);if(m&&(m.content||m.toolExecutions&&m.toolExecutions.length>0))return g.debug(`[${s}] MCP generation successful on attempt ${d}`,{contentLength:m.content?.length||0,toolsUsed:m.toolsUsed?.length||0,toolExecutions:m.toolExecutions?.length||0,retryCount:l}),l>0&&(m.retries={count:l,errors:c}),m;g.debug(`[${s}] MCP generation returned empty result on attempt ${d}`,{hasResult:!!m,hasContent:!!(m&&m.content),contentLength:m?.content?.length||0,toolExecutions:m?.toolExecutions?.length||0})}catch(m){if(Hr(m))throw g.debug(`[${s}] AbortError detected on attempt ${d}, stopping retries`),m;if(a&&m instanceof Error&&m.name==="TimeoutError")throw g.warn(`[${s}] Per-step timeout (${String(e.timeout)}) exhausted on attempt ${d} \u2014 surfacing instead of retrying with the same budget`),m;l++;let f=m instanceof Error?m.message:String(m),h=m instanceof Fe?m.code:m instanceof Error?m.name:"UNKNOWN";c.push({code:h,message:f.substring(0,500)}),g.debug(`[${s}] MCP generation failed on attempt ${d}/${u}`,{error:f,willRetry:d<u,retryCount:l});let y=r.isNonRetryableToolError(m);if(_ce(m)||y||_W(m)||m instanceof Error&&m.isRetryable===!1||m instanceof Error&&m.statusCode===400){g.debug(`[${s}] Non-retryable error detected, skipping remaining retries`);break}if(d>=u){g.debug(`[${s}] All MCP attempts exhausted, falling back to direct generation`);break}if(await new Promise(b=>{let T=setTimeout(b,500);if(e.abortSignal){let w=()=>{clearTimeout(T),b()};e.abortSignal.addEventListener("abort",w,{once:!0})}}),e.abortSignal?.aborted)throw new DOMException("The operation was aborted","AbortError")}}return null}async tryMCPGeneration(e){if(e.abortSignal?.aborted)throw new DOMException("The operation was aborted","AbortError");let t=e.context?.requestId||"unknown",n=`try-mcp-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,o=Date.now(),s=process.hrtime.bigint(),i="NeuroLink.tryMCPGeneration";try{let a=await this.prepareMCPGenerationContext(e,t,n,o,s);if(!a)return null;let c=await this.ensureMCPGenerationBudget(e,t,a.providerName,a.enhancedSystemPrompt,a.availableTools,a.conversationMessages);return this.generateWithMCPProvider({options:e,requestId:t,functionTag:i,tryMCPStartTime:o,providerName:a.providerName,availableTools:a.availableTools,enhancedSystemPrompt:a.enhancedSystemPrompt,conversationMessages:c})}catch(a){if(Hr(a))throw ie.debug(`[${i}] AbortError detected, rethrowing`),a;if(r.isNonRetryableToolError(a))throw ie.warn(`[${i}] Non-retryable tool error, rethrowing`,{error:a instanceof Error?a.message:String(a)}),a;return ie.warn(`[${i}] MCP generation failed`,{error:a instanceof Error?a.message:String(a)}),null}}async prepareMCPGenerationContext(e,t,n,o,s){if(await this.initializeMCP(),!this.mcpInitialized)return g.warn("[NeuroLink] \u26A0\uFE0F LOG_POINT_T004_MCP_NOT_AVAILABLE",{logPoint:"T004_MCP_NOT_AVAILABLE",tryMCPId:n,timestamp:new Date().toISOString(),elapsedMs:Date.now()-o,elapsedNs:(process.hrtime.bigint()-s).toString(),mcpInitialized:this.mcpInitialized,mcpComponents:{hasExternalServerManager:!!this.externalServerManager,hasToolRegistry:!!this.toolRegistry,hasProviderRegistry:!!dn},fallbackReason:"MCP_NOT_INITIALIZED",message:"MCP not available - returning null for fallback to direct generation"}),null;let i=e.provider==="auto"||!e.provider?await Rx():e.provider,a=await this.getAllAvailableTools(),{tools:c,unavailableTools:l}=this.toolRegistry.getAvailableTools(this.toolCircuitBreakers),u=new Set(c.map(y=>y.name));a=a.filter(y=>u.has(y.name)),a=this.applyToolInfoFiltering(a,e);let d=a.find(y=>y.name.includes("SuccessRateSRByTime")||y.name.includes("juspay-analytics"));g.debug("Available tools for AI prompt generation",{toolsCount:a.length,toolNames:a.map(y=>y.name),unavailableToolsCount:l.length,unavailableTools:l,hasTargetTool:!!d,targetToolDetails:d?{name:d.name,description:d.description,server:d.server}:null});let m=l.length>0?`
2196
2196
 
2197
2197
  NOTE: The following tools are temporarily unavailable due to repeated failures: ${l.join(", ")}. Do not attempt to call these tools.`:"",f=e.skipToolPromptInjection?(e.systemPrompt||"")+m:this.createToolAwareSystemPrompt(e.systemPrompt,a)+m;g.debug("Tool-aware system prompt created",{requestId:t,originalPromptLength:e.systemPrompt?.length||0,enhancedPromptLength:f.length,skippedToolInjection:!!e.skipToolPromptInjection,enhancedPromptPreview:f.substring(0,80)+"..."}),g.debug("[Observability] System prompt metadata",{requestId:t,systemPromptLength:f.length,systemPromptHash:f.length>0?`sha256:${f.slice(0,8)}...`:"empty",hasCustomSystemPrompt:!!e.systemPrompt});let h=await Mg(this.conversationMemory,e);return this.logMCPConversationSummary(t,h),g.debug("[Observability] Available tools for LLM",{requestId:t,toolCount:a.length,toolNames:a.map(y=>y.name)}),{providerName:i,availableTools:a,enhancedSystemPrompt:f,conversationMessages:h}}logMCPConversationSummary(e,t){if(g.shouldLog("debug"))try{g.debug("[Observability] Conversation history summary",{requestId:e,messageCount:t.length,messages:t.map((n,o)=>{let s;if(typeof n.content=="string")s=n.content.length;else try{s=JSON.stringify(n.content).length}catch{s=0}return{index:o,role:n.role,contentLength:s,contentPreview:typeof n.content=="string"?n.content.substring(0,200):"[multimodal]"}})})}catch{}}async ensureMCPGenerationBudget(e,t,n,o,s,i){let a=Xc({provider:n,model:e.model,maxTokens:e.maxTokens,systemPrompt:o,conversationMessages:i,currentPrompt:e.prompt,toolDefinitions:s});if(g.info("[TokenBudget] Token breakdown",{requestId:t,system:a.breakdown?.systemPrompt||0,history:a.breakdown?.conversationHistory||0,tools:a.breakdown?.toolDefinitions||0,currentPrompt:a.breakdown?.currentPrompt||0,files:a.breakdown?.fileAttachments||0,total:a.estimatedInputTokens,budget:a.availableInputTokens,usagePercent:Math.round(a.usageRatio*1e3)/10,conversationMessageCount:i.length,shouldCompact:a.shouldCompact}),e.timeout===void 0&&a.estimatedInputTokens>1e5){let u=1+Math.floor((a.estimatedInputTokens-1)/1e5)*.5,d=Math.round(6e4*Math.min(u,4));e.timeout=d,g.info("[TokenBudget] Scaled timeout for large context",{requestId:t,estimatedTokens:a.estimatedInputTokens,scaledTimeoutMs:d})}let c=this.getCompactionSessionId(e),l=this.lastCompactionMessageCount.get(c)??0;return!a.shouldCompact||!this.conversationMemory||i.length<=l?i:this.compactMCPConversationForBudget({options:e,requestId:t,providerName:n,enhancedSystemPrompt:o,availableTools:s,conversationMessages:i,availableInputTokens:a.availableInputTokens,usageRatio:a.usageRatio,estimatedInputTokens:a.estimatedInputTokens,compactionSessionId:c})}async compactMCPConversationForBudget(e){let{options:t,requestId:n,providerName:o,enhancedSystemPrompt:s,availableTools:i,conversationMessages:a,availableInputTokens:c,usageRatio:l,estimatedInputTokens:u,compactionSessionId:d}=e;g.info("[NeuroLink] Context budget exceeded, triggering auto-compaction",{usageRatio:l,estimatedTokens:u,availableTokens:c});let f=await new fx({provider:o,summarizationProvider:this.conversationMemoryConfig?.conversationMemory?.summarizationProvider,summarizationModel:this.conversationMemoryConfig?.conversationMemory?.summarizationModel}).compact(a,c,this.conversationMemoryConfig?.conversationMemory,n),h=a;f.compacted&&(h=uk(f.messages).messages,this.lastCompactionMessageCount.set(d,h.length),g.info("[NeuroLink] Context compacted successfully",{stagesUsed:f.stagesUsed,tokensSaved:f.tokensSaved}));let y=Xc({provider:o,model:t.model,maxTokens:t.maxTokens,systemPrompt:s,conversationMessages:h,currentPrompt:t.prompt,toolDefinitions:i});if(y.withinBudget)return h;let x=y.usageRatio-1;g.warn("[NeuroLink] Post-compaction still over budget, attempting emergency content truncation",{requestId:n,estimatedTokens:y.estimatedInputTokens,availableTokens:y.availableInputTokens,overagePercent:Math.round(x*100),stagesUsedInCompaction:f.stagesUsed}),h=oH(h,y.availableInputTokens,y.breakdown,o);let b=Xc({provider:o,model:t.model,maxTokens:t.maxTokens,systemPrompt:s,conversationMessages:h,currentPrompt:t.prompt,toolDefinitions:i});if(!b.withinBudget)throw this.lastCompactionMessageCount.delete(d),new Vl(`Context exceeds model budget after all compaction stages. Estimated: ${b.estimatedInputTokens} tokens, Budget: ${b.availableInputTokens} tokens. Conversation is too large to fit in the model's context window.`,{estimatedTokens:b.estimatedInputTokens,availableTokens:b.availableInputTokens,stagesUsed:f.stagesUsed,breakdown:b.breakdown});return h}async generateWithMCPProvider(e){let{options:t,requestId:n,functionTag:o,tryMCPStartTime:s,providerName:i,availableTools:a,enhancedSystemPrompt:c,conversationMessages:l}=e,u=await dn.createProvider(i,t.model,!t.disableTools,this,t.region,this.resolveCredentials(t.credentials));u.setTraceContext(this._metricsTraceContext),this.emitter.emit("connected"),this.emitter.emit("message",`${i} provider initialized successfully`),u.setupToolExecutor({customTools:this.getCustomTools(),executeTool:(x,b)=>this.executeTool(x,b,{disableToolCache:t.disableToolCache})},o),g.debug("[Observability] User input to LLM",{requestId:n,promptPreview:t.prompt?.substring(0,200),promptLength:t.prompt?.length||0,model:t.model,maxTokens:t.maxTokens,temperature:t.temperature,maxSteps:t.maxSteps,skipToolPromptInjection:t.skipToolPromptInjection});let d=await u.generate({...t,systemPrompt:c,conversationMessages:l}),m=Date.now()-s,f=!!(d?.content&&d.content.trim().length>0),h=!!(d?.toolExecutions&&d.toolExecutions.length>0);if(ie.debug(`[${o}] Result validation:`,{hasResult:!!d,hasContent:f,hasToolExecutions:h,contentLength:d?.content?.length||0,toolExecutionsCount:d?.toolExecutions?.length||0,toolsUsedCount:d?.toolsUsed?.length||0}),!f&&!h)return ie.debug(`[${o}] Result rejected: no content and no tool executions`),null;let y=nPe(d.toolExecutions);return ie.debug(`[${o}] Tool execution transformation:`,{originalCount:d?.toolExecutions?.length||0,transformedCount:y.length,transformedTools:y.map(x=>x.toolName)}),{content:d.content||"",provider:i,model:d.model,usage:d.usage,responseTime:m,finishReason:d.finishReason,stopReason:d.stopReason,rawFinishReason:d.rawFinishReason,stepsUsed:d.stepsUsed,toolsUsed:d.toolsUsed||[],toolExecutions:y,enhancedWithTools:!!h,availableTools:sPe(iPe(a)),audio:d.audio,video:d.video,avatar:d.avatar,music:d.music,ppt:d.ppt,imageOutput:d.imageOutput,analytics:d.analytics,evaluation:d.evaluation,reasoning:d.reasoning,reasoningTokens:d.reasoningTokens,_generationEndEmitted:d._generationEndEmitted}}async directProviderGeneration(e){let t=Date.now(),n="NeuroLink.directProviderGeneration",o=["openai","vertex","bedrock","anthropic","azure","google-ai","huggingface","ollama"],s=e.provider==="auto"?void 0:e.provider,i=e.context&&typeof e.context=="object"&&"__orchestratedPreferredProvider"in e.context?e.context.__orchestratedPreferredProvider:void 0,a=i?[i,...o.filter(u=>u!==i)]:s?[s]:o;if(g.debug(`[${n}] Starting direct generation`,{requestedProvider:s||"auto",preferredOrchestrated:i||"none",tryProviders:a,allowFallback:!s||!!i}),this.modelPool){let u=this.modelPool,d=u.maxAttempts,m=new Set,f=null;for(let y=0;y<d;y++){if(e.abortSignal?.aborted)throw new DOMException("The operation was aborted","AbortError");let x=u.selectNext(m);if(!x)break;m.add(u.memberKey(x));let b=e.provider,T=e.model,w=e.region;e.provider=x.provider,e.model=x.model??void 0,e.region=x.region??void 0;let k=x.provider;g.debug(`[${n}] ModelPool: attempting member`,{provider:k,model:x.model??e.model,attempt:y});try{let C=e,R=C.conversationMessages?.length?C.conversationMessages:await Mg(this.conversationMemory,e),P=await dn.createProvider(k,e.model,!e.disableTools,this,e.region,this.resolveCredentials(e.credentials));P.setTraceContext(this._metricsTraceContext),P.setupToolExecutor({customTools:this.getCustomTools(),executeTool:(M,O)=>this.executeTool(M,O,{disableToolCache:e.disableToolCache})},n);let A=await P.generate({...e,conversationMessages:R});if(!A)throw new Error(`ModelPool: provider ${k} returned null result`);u.recordSuccess(x);let I=Date.now()-t;return e.provider=b,e.model=T,e.region=w,{content:A.content||"",provider:k,model:A.model,usage:A.usage,responseTime:I,finishReason:A.finishReason,stopReason:A.stopReason,rawFinishReason:A.rawFinishReason,stepsUsed:A.stepsUsed,toolsUsed:A.toolsUsed||[],toolExecutions:A.toolExecutions?.map(M=>{let O=M;return{...M,toolName:M.name,executionTime:typeof O.executionTime=="number"?O.executionTime:typeof O.duration=="number"?O.duration:0,success:typeof O.success=="boolean"?O.success:O.status==="success"}}),enhancedWithTools:!!A.toolExecutions?.length,analytics:A.analytics,evaluation:A.evaluation,audio:A.audio,video:A.video,avatar:A.avatar,music:A.music,ppt:A.ppt,imageOutput:A.imageOutput,reasoning:A.reasoning,reasoningTokens:A.reasoningTokens,_generationEndEmitted:A._generationEndEmitted}}catch(C){if(e.provider=b,e.model=T,e.region=w,Hr(C))throw C;if(_W(C)){let R=C instanceof Error?C.message:String(C);throw g.warn(`[${n}] ModelPool: non-retryable error from ${k}, stopping pool`,{error:R}),u.recordFailure(x,Px(C)),new Error(`[ModelPool] non-retryable: ${R}`,{cause:C})}u.recordFailure(x,Px(C)),f=C instanceof Error?C:new Error(String(C)),g.warn(`[${n}] ModelPool: member ${k} failed`,{error:f.message})}}let h=Date.now()-t;throw g.error(`[${n}] ModelPool: all members failed`,{triedKeys:Array.from(m),lastError:f?.message,responseTime:h}),new Error(`[ModelPool] all members failed: ${f?.message??"no members available"}`)}let c=null;for(let u of a){if(e.abortSignal?.aborted)throw new DOMException("The operation was aborted","AbortError");try{g.debug(`[${n}] Attempting provider: ${u}`);let d=e,m=d.conversationMessages?.length?d.conversationMessages:await Mg(this.conversationMemory,e),f=Xc({provider:u,model:e.model,maxTokens:e.maxTokens,systemPrompt:e.systemPrompt,conversationMessages:m,currentPrompt:e.prompt,toolDefinitions:e.tools?Object.values(e.tools):void 0}),h=m?.length||0,y=this.getCompactionSessionId(e),x=!!d.conversationMessages?.length,b=h>0;if(!f.withinBudget&&!b){try{this.emitter.emit("compaction.insufficient",{stagesAttempted:["pre-dispatch hard cap"],finalTokens:f.estimatedInputTokens,budget:f.availableInputTokens,provider:u,model:e.model,phase:"pre-dispatch-no-recovery",timestamp:Date.now()})}catch{}throw new Vl(`Context exceeds model budget and no compaction is possible (no conversationMemory, no inline conversationMessages \u2014 only prompt + tools). Estimated: ${f.estimatedInputTokens} tokens, budget: ${f.availableInputTokens} tokens. Reduce prompt or tool-definition size, or trim the request.`,{estimatedTokens:f.estimatedInputTokens,availableTokens:f.availableInputTokens,stagesUsed:[],breakdown:f.breakdown})}if(f.shouldCompact&&(this.conversationMemory||x)&&h>(this.lastCompactionMessageCount.get(y)??0)){let R=await new fx({provider:u,summarizationProvider:this.conversationMemoryConfig?.conversationMemory?.summarizationProvider,summarizationModel:this.conversationMemoryConfig?.conversationMemory?.summarizationModel}).compact(m,f.availableInputTokens,this.conversationMemoryConfig?.conversationMemory,e.context?.requestId);R.compacted&&(m=uk(R.messages).messages,this.lastCompactionMessageCount.set(y,m.length));let P=Xc({provider:u,model:e.model,maxTokens:e.maxTokens,systemPrompt:e.systemPrompt,conversationMessages:m,currentPrompt:e.prompt,toolDefinitions:e.tools?Object.values(e.tools):void 0});if(!P.withinBudget){g.warn("[NeuroLink] directProviderGeneration: post-compaction still over budget, emergency truncation",{estimatedTokens:P.estimatedInputTokens,availableTokens:P.availableInputTokens,overagePercent:Math.round((P.usageRatio-1)*100)});try{this.emitter.emit("compaction.insufficient",{stagesAttempted:R.stagesUsed,finalTokens:P.estimatedInputTokens,budget:P.availableInputTokens,provider:u,model:e.model,phase:"mid-compaction",willEmergencyTruncate:!0,timestamp:Date.now()})}catch{}m=oH(m,P.availableInputTokens,P.breakdown,u);let A=Xc({provider:u,model:e.model,maxTokens:e.maxTokens,systemPrompt:e.systemPrompt,conversationMessages:m,currentPrompt:e.prompt,toolDefinitions:e.tools?Object.values(e.tools):void 0});if(!A.withinBudget){this.lastCompactionMessageCount.delete(y);try{this.emitter.emit("compaction.insufficient",{stagesAttempted:R.stagesUsed,finalTokens:A.estimatedInputTokens,budget:A.availableInputTokens,provider:u,model:e.model,phase:"post-emergency-truncation",timestamp:Date.now()})}catch{}throw new Vl(`Context exceeds model budget after all compaction stages. Estimated: ${A.estimatedInputTokens} tokens, Budget: ${A.availableInputTokens} tokens.`,{estimatedTokens:A.estimatedInputTokens,availableTokens:A.availableInputTokens,stagesUsed:R.stagesUsed,breakdown:A.breakdown})}}}let T=await dn.createProvider(u,e.model,!e.disableTools,this,e.region,this.resolveCredentials(e.credentials));T.setTraceContext(this._metricsTraceContext),this.emitter.emit("connected"),this.emitter.emit("message",`${u} provider initialized successfully`),T.setupToolExecutor({customTools:this.getCustomTools(),executeTool:(C,R)=>this.executeTool(C,R,{disableToolCache:e.disableToolCache})},n);let w=await T.generate({...e,conversationMessages:m}),k=Date.now()-t;if(!w)throw new Error(`Provider ${u} returned null result`);return g.debug(`[${n}] Provider ${u} succeeded`,{responseTime:k,contentLength:w.content?.length||0}),{content:w.content||"",provider:u,model:w.model,usage:w.usage,responseTime:k,finishReason:w.finishReason,stopReason:w.stopReason,rawFinishReason:w.rawFinishReason,stepsUsed:w.stepsUsed,toolsUsed:w.toolsUsed||[],toolExecutions:w.toolExecutions?.map(C=>{let R=C;return{...C,toolName:C.name,executionTime:typeof R.executionTime=="number"?R.executionTime:typeof R.duration=="number"?R.duration:0,success:typeof R.success=="boolean"?R.success:R.status==="success"}}),enhancedWithTools:!!w.toolExecutions?.length,analytics:w.analytics,evaluation:w.evaluation,audio:w.audio,video:w.video,avatar:w.avatar,music:w.music,ppt:w.ppt,imageOutput:w.imageOutput,reasoning:w.reasoning,reasoningTokens:w.reasoningTokens,_generationEndEmitted:w._generationEndEmitted}}catch(d){if(Hr(d))throw g.debug(`[${n}] AbortError detected on provider ${u}, stopping fallback`),d;if(_W(d))throw g.warn(`[${n}] Non-retryable error from provider ${u}, stopping fallback chain`,{error:d instanceof Error?d.message:String(d),errorType:d instanceof Error?d.constructor.name:typeof d}),d instanceof Error?d:new Error(String(d));c=d instanceof Error?d:new Error(String(d)),g.warn(`[${n}] Provider ${u} failed`,{error:c.message})}}let l=Date.now()-t;throw g.error(`[${n}] All providers failed`,{triedProviders:a,lastError:c?.message,responseTime:l}),c instanceof Vl?c:new Error(`Failed to generate text with all providers. Last error: ${c?.message||"Unknown error"}`)}applyToolInfoFiltering(e,t){let n=[...t.toolFilter??[],...t.enabledToolNames??[]];if(n.length===0&&(!t.excludeTools||t.excludeTools.length===0))return e;let o=e;if(n.length>0){let s=new Set(n);o=o.filter(i=>s.has(i.name))}if(t.excludeTools&&t.excludeTools.length>0){let s=new Set(t.excludeTools);o=o.filter(i=>!s.has(i.name))}return o.length!==e.length&&g.debug("Tool info filtering applied for system prompt",{beforeCount:e.length,afterCount:o.length,toolFilter:t.toolFilter,excludeTools:t.excludeTools}),o}createToolAwareSystemPrompt(e,t){let n={originalPromptLength:e?.length||0,availableToolsCount:t.length,hasOriginalPrompt:!!e};if(g.debug("AI prompt generation with tool schemas",n),t.length===0)return g.debug("No tools available - returning original prompt"),e||"";let o=cPe(t.map(l=>({name:l.name,description:l.description??"",server:l.serverId??"unknown",inputSchema:l.inputSchema}))),s={toolDescriptionsLength:o.length,toolDescriptionsCharCount:o.length,hasDescriptions:o.length>0};g.debug("Tool descriptions transformation completed",s);let i=`
2198
2198
 
@@ -566,6 +566,14 @@ export class GenerationHandler {
566
566
  }
567
567
  try {
568
568
  const scalar = JSON.parse(strippedText);
569
+ if (scalar === "") {
570
+ // A JSON-encoded empty string is an EMPTY completion, not a
571
+ // recovered scalar β€” normalize to a true empty ('' content, no
572
+ // structuredData) so callers' empty-response handling fires
573
+ // instead of a literal '""' reaching the user.
574
+ logger.warn("[GenerationHandler] schema requested but the model returned an empty JSON string; normalizing to empty content", { provider: this.providerName, model: this.modelName });
575
+ return "";
576
+ }
569
577
  if (scalar !== null && scalar !== undefined) {
570
578
  structuredData = scalar;
571
579
  return strippedText;
@@ -580,7 +588,17 @@ export class GenerationHandler {
580
588
  if (useStructuredOutput) {
581
589
  try {
582
590
  const experimentalOutput = generateResult.experimental_output;
583
- if (experimentalOutput !== undefined) {
591
+ // ai@6 generateText resolves `output ?? text()` internally, so a
592
+ // result produced WITHOUT an output spec β€” the structured-output
593
+ // fallback retry, or the tools↔schema exclusion path β€” no longer
594
+ // throws here: `experimental_output` echoes the RAW MODEL TEXT.
595
+ // Treating that echo as parsed schema output double-encodes the
596
+ // content (JSON.stringify of a string) and, for an empty
597
+ // completion, turns '' into the literal '""'. Detect the echo
598
+ // (a string identical to the step text) and coerce it instead.
599
+ const rawTextEcho = typeof experimentalOutput === "string" &&
600
+ experimentalOutput === (generateResult.text ?? "");
601
+ if (experimentalOutput !== undefined && !rawTextEcho) {
584
602
  // AI-SDK already parsed + schema-validated the object. Expose it
585
603
  // directly and serialise canonically β€” no hand-parsing needed.
586
604
  structuredData = experimentalOutput;
@@ -566,6 +566,14 @@ export class GenerationHandler {
566
566
  }
567
567
  try {
568
568
  const scalar = JSON.parse(strippedText);
569
+ if (scalar === "") {
570
+ // A JSON-encoded empty string is an EMPTY completion, not a
571
+ // recovered scalar β€” normalize to a true empty ('' content, no
572
+ // structuredData) so callers' empty-response handling fires
573
+ // instead of a literal '""' reaching the user.
574
+ logger.warn("[GenerationHandler] schema requested but the model returned an empty JSON string; normalizing to empty content", { provider: this.providerName, model: this.modelName });
575
+ return "";
576
+ }
569
577
  if (scalar !== null && scalar !== undefined) {
570
578
  structuredData = scalar;
571
579
  return strippedText;
@@ -580,7 +588,17 @@ export class GenerationHandler {
580
588
  if (useStructuredOutput) {
581
589
  try {
582
590
  const experimentalOutput = generateResult.experimental_output;
583
- if (experimentalOutput !== undefined) {
591
+ // ai@6 generateText resolves `output ?? text()` internally, so a
592
+ // result produced WITHOUT an output spec β€” the structured-output
593
+ // fallback retry, or the tools↔schema exclusion path β€” no longer
594
+ // throws here: `experimental_output` echoes the RAW MODEL TEXT.
595
+ // Treating that echo as parsed schema output double-encodes the
596
+ // content (JSON.stringify of a string) and, for an empty
597
+ // completion, turns '' into the literal '""'. Detect the echo
598
+ // (a string identical to the step text) and coerce it instead.
599
+ const rawTextEcho = typeof experimentalOutput === "string" &&
600
+ experimentalOutput === (generateResult.text ?? "");
601
+ if (experimentalOutput !== undefined && !rawTextEcho) {
584
602
  // AI-SDK already parsed + schema-validated the object. Expose it
585
603
  // directly and serialise canonically β€” no hand-parsing needed.
586
604
  structuredData = experimentalOutput;
@@ -3858,7 +3858,15 @@ Current user's request: ${currentInput}`;
3858
3858
  else {
3859
3859
  try {
3860
3860
  const scalar = JSON.parse(textResult.content);
3861
- if (scalar !== null && scalar !== undefined) {
3861
+ if (scalar === "") {
3862
+ // A JSON-encoded empty string is an EMPTY completion, not a
3863
+ // recovered scalar β€” normalize to a true empty so callers'
3864
+ // empty-response handling fires instead of a literal '""'
3865
+ // reaching the user. `structuredData` stays undefined.
3866
+ textResult.content = "";
3867
+ logger.warn("[NeuroLink] schema requested but the model returned an empty JSON string; normalizing to empty content", { provider: textResult.provider, model: textResult.model });
3868
+ }
3869
+ else if (scalar !== null && scalar !== undefined) {
3862
3870
  textResult.structuredData = scalar;
3863
3871
  }
3864
3872
  }
package/dist/neurolink.js CHANGED
@@ -3858,7 +3858,15 @@ Current user's request: ${currentInput}`;
3858
3858
  else {
3859
3859
  try {
3860
3860
  const scalar = JSON.parse(textResult.content);
3861
- if (scalar !== null && scalar !== undefined) {
3861
+ if (scalar === "") {
3862
+ // A JSON-encoded empty string is an EMPTY completion, not a
3863
+ // recovered scalar β€” normalize to a true empty so callers'
3864
+ // empty-response handling fires instead of a literal '""'
3865
+ // reaching the user. `structuredData` stays undefined.
3866
+ textResult.content = "";
3867
+ logger.warn("[NeuroLink] schema requested but the model returned an empty JSON string; normalizing to empty content", { provider: textResult.provider, model: textResult.model });
3868
+ }
3869
+ else if (scalar !== null && scalar !== undefined) {
3862
3870
  textResult.structuredData = scalar;
3863
3871
  }
3864
3872
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "9.86.2",
3
+ "version": "9.86.4",
4
4
  "packageManager": "pnpm@10.15.1",
5
- "description": "Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applications with 21+ providers: OpenAI, Anthropic, Google AI Studio, Google Vertex, AWS Bedrock, Azure OpenAI, Mistral, LiteLLM, SageMaker, Hugging Face, Ollama, OpenAI-compatible, OpenRouter, DeepSeek, NVIDIA NIM, LM Studio, llama.cpp, plus voice (OpenAI TTS, ElevenLabs, Deepgram, Azure Speech).",
5
+ "description": "TypeScript AI SDK with 24+ LLM providers behind one consistent API. MCP-native (58+ servers), voice TTS/STT/realtime, RAG, agents, memory, context compaction. OpenAI Β· Anthropic Β· Gemini Β· Bedrock Β· Azure Β· Ollama Β· DeepSeek Β· NVIDIA NIM and more.",
6
6
  "author": {
7
7
  "name": "Juspay Technologies",
8
8
  "email": "support@juspay.in",
@@ -359,10 +359,12 @@
359
359
  "csv-parser": "^3.2.0",
360
360
  "dotenv": "^17.3.1",
361
361
  "eventsource-parser": "^3.0.8",
362
+ "fast-xml-parser": "^5.7.0",
362
363
  "google-auth-library": "^10.6.1",
363
364
  "hono": "^4.12.21",
364
365
  "inquirer": "^13.3.0",
365
366
  "jose": "^6.1.3",
367
+ "js-yaml": "^4.2.0",
366
368
  "json-schema-to-zod": "^2.7.0",
367
369
  "jsonrepair": "^3.14.0",
368
370
  "nanoid": "^5.1.5",
@@ -478,7 +480,6 @@
478
480
  "esbuild": "^0.28.1",
479
481
  "eslint": "^10.0.2",
480
482
  "husky": "^9.1.7",
481
- "js-yaml": "^4.2.0",
482
483
  "lint-staged": "^16.3.0",
483
484
  "playwright": "^1.58.2",
484
485
  "prettier": "^3.8.1",