@juspay/neurolink 9.59.3 → 9.59.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [9.59.5](https://github.com/juspay/neurolink/compare/v9.59.4...v9.59.5) (2026-04-29)
2
+
3
+ ### Bug Fixes
4
+
5
+ - **(routing):** dual-mode image text fallback + skip video-frame hijack on structured output ([97b2373](https://github.com/juspay/neurolink/commit/97b2373a793e56414a2ca41009efc72d9a574999))
6
+
7
+ ## [9.59.4](https://github.com/juspay/neurolink/compare/v9.59.3...v9.59.4) (2026-04-27)
8
+
9
+ ### Bug Fixes
10
+
11
+ - **(proxy):** replace blocking quiet-gate with best-effort wait for auto-updates ([defd6e0](https://github.com/juspay/neurolink/commit/defd6e0f177abea19e490ebe8bd8ea492f6bebca))
12
+
1
13
  ## [9.59.3](https://github.com/juspay/neurolink/compare/v9.59.2...v9.59.3) (2026-04-27)
2
14
 
3
15
  ### Bug Fixes
@@ -1123,7 +1123,7 @@ Reasoning: [Provide a detailed explanation of your evaluation, explaining why yo
1123
1123
  [... ${Math.max(0,l-Buffer.byteLength(h,"utf-8")-Buffer.byteLength(y,"utf-8"))} bytes omitted. Use ${BUt} tool to access full output ...]
1124
1124
 
1125
1125
  `;return{preview:h+T+y,truncated:!0,originalSize:l}}var BUt,q$=A(()=>{"use strict";BUt="retrieve_context"});var G$,ICe=A(()=>{"use strict";Tn();vo();z1();Ta();Ht();Q();DL();em();q$();G$=class{constructor(e,t,n,o){this.providerName=e;this.directTools=t;this.neurolink=n;this.utilities=o;this.mcpTools={}}mcpTools;customTools;toolExecutor;sessionId;userId;wrapExecuteWithTruncation(e,t){return async n=>{let o=await t(n);return this.truncateToolResult(e,o)}}truncateToolResult(e,t){if(t==null)return t;if(typeof t=="string"){let{preview:n,truncated:o,originalSize:s}=Rm(t);return o&&g.debug(`[ToolsManager] Truncated '${e}' string output: ${s} bytes \u2192 ${Buffer.byteLength(n,"utf-8")} bytes`),o?n:t}if(typeof t=="object"){let n=t,o=null;if(typeof n.content=="string"){let{preview:s,truncated:i,originalSize:a}=Rm(n.content);i&&(g.debug(`[ToolsManager] Truncated '${e}' content field: ${a} bytes \u2192 ${Buffer.byteLength(s,"utf-8")} bytes`),o={...o??n,content:s})}if(typeof n.data=="string"){let{preview:s,truncated:i,originalSize:a}=Rm(n.data);i&&(g.debug(`[ToolsManager] Truncated '${e}' data field: ${a} bytes \u2192 ${Buffer.byteLength(s,"utf-8")} bytes`),o={...o??n,data:s})}if(o)return o;try{let s=JSON.stringify(t);if(Buffer.byteLength(s,"utf-8")>51200){let{preview:i,truncated:a,originalSize:l}=Rm(s);if(a)return g.debug(`[ToolsManager] Truncated '${e}' JSON output: ${l} bytes \u2192 ${Buffer.byteLength(i,"utf-8")} bytes`),{_truncated:!0,_originalSize:l,_preview:i}}}catch{}}return t}setSessionContext(e,t){this.sessionId=e,this.userId=t}emitToolEvent(e,t,n){this.neurolink?.getEventEmitter&&this.neurolink.getEventEmitter().emit(e,om(t,n))}setupToolExecutor(e,t){let n=ye.sdk.startSpan("neurolink.tools.register",{attributes:{[me.NL_PROVIDER]:this.providerName,"tools.custom_count":e.customTools.size}});try{this.customTools=e.customTools,this.toolExecutor=e.executeTool.bind(e),g.debug(`[${t}] Setting up tool executor for provider`,{providerName:this.providerName,availableCustomTools:e.customTools.size,customToolsStored:!!this.customTools,toolExecutorStored:!!this.toolExecutor}),n.setStatus({code:be.OK})}catch(o){throw n.setStatus({code:be.ERROR,message:o instanceof Error?o.message:String(o)}),o instanceof Error&&n.recordException(o),o}finally{n.end()}}async getAllTools(){return Ie({name:"neurolink.tools.getAll",tracer:ye.sdk,attributes:{[me.NL_PROVIDER]:this.providerName}},async e=>{let t={};await this.processDirectTools(t);let n=Object.keys(t).length;e.setAttribute("tools.direct_count",n),g.debug(`[ToolsManager] getAllTools called for ${this.providerName}`,{directToolsCount:Hb(this.directTools)}),await this.processCustomTools(t);let o=Object.keys(t).length-n;e.setAttribute("tools.custom_count",o),await this.processExternalMCPTools(t);let s=Object.keys(t).length-n-o;e.setAttribute("tools.external_mcp_count",s),await this.processMCPTools(t);let i=Object.keys(t).length;e.setAttribute(me.NL_TOOL_COUNT,i);let a=Object.keys(t);return e.setAttribute("tools.names",a.slice(0,20).join(",")+(a.length>20?`...+${a.length-20}`:"")),g.debug(`[ToolsManager] getAllTools complete: ${a.length} tools available`,{provider:this.providerName,toolCount:a.length,toolNames:a.length<=10?a:[...a.slice(0,10),`... and ${a.length-10} more`]}),t})}getDirectTools(){return this.directTools}getMCPTools(){return this.mcpTools}getCustomTools(){return this.customTools}async processDirectTools(e){if(!(!this.directTools||Object.keys(this.directTools).length===0)){g.debug(`[ToolsManager] Loading ${Object.keys(this.directTools).length} direct tools`);for(let[t,n]of Object.entries(this.directTools))if(n&&typeof n=="object"&&"execute"in n){let o=n.execute,s=this.wrapExecuteWithTruncation(t,o);e[t]={...n,execute:async i=>{let a=Date.now();this.emitToolEvent("tool:start",t,{input:i});try{let l=await s(i);return this.emitToolEvent("tool:end",t,{result:l,success:!0,responseTime:Date.now()-a}),l}catch(l){let u=l instanceof Error?l.message:String(l);throw this.emitToolEvent("tool:end",t,{error:u,success:!1,responseTime:Date.now()-a}),l}}}}else e[t]=n}}async processCustomTools(e){if(!(!this.customTools||this.customTools.size===0)){g.debug(`[ToolsManager] Loading ${this.customTools.size} custom tools from setupToolExecutor`);for(let[t,n]of this.customTools.entries()){let o=n||{};if(o&&typeof o.execute=="function"){let s=await this.createCustomToolFromDefinition(t,o);if(s&&!e[t]){let i=s.execute;if(i){let a=this.wrapExecuteWithTruncation(t,i);s.execute=a}e[t]=s}}}}}async processMCPTools(e){if(this.mcpTools||(this.mcpTools={}),this.mcpTools)for(let[t,n]of Object.entries(this.mcpTools))e[t]||(e[t]=n)}async processExternalMCPTools(e){if(!(!this.neurolink||typeof this.neurolink.getExternalMCPTools!="function"))try{let t=await this.neurolink.getExternalMCPTools(),n=0;for(let o of t){let s=await this.createExternalMCPTool(o);s&&!e[o.name]&&(e[o.name]=s,n++)}g.debug("[ToolsManager] External MCP tools loaded",{found:t.length,added:n})}catch(t){g.error(`[ToolsManager] Failed to load external MCP tools for ${this.providerName}:`,t)}}async createCustomToolFromDefinition(e,t){try{let n,o;return t.parameters&&this.utilities?.isZodSchema?.(t.parameters)?n=t.parameters:t.inputSchema&&this.utilities?.isZodSchema?.(t.inputSchema)?n=t.inputSchema:t.inputSchema&&typeof t.inputSchema=="object"?(o=t.inputSchema,n=ga(o)):t.parameters&&typeof t.parameters=="object"?n=uxe(t.parameters):n=c.object({}),{description:t.description||`Tool ${e}`,inputSchema:n,execute:async s=>{let i=ye.sdk.startSpan("neurolink.tools.execute_custom",{attributes:{"tool.name":e,"tool.type":"custom","langfuse.internal":!0}}),a=Date.now(),l;try{if(this.toolExecutor){let f=t.timeoutMs,h=t.maxRetries,y=f!==void 0||h!==void 0,v=await this.toolExecutor(e,s,y?{...f!==void 0&&{timeout:f},...h!==void 0&&{maxRetries:h}}:void 0),b=this.utilities?.convertToolResult?await this.utilities.convertToolResult(v):v,w=Date.now();i.setAttribute("tool.duration_ms",w-a);let T;if(b&&typeof b=="object"&&"isError"in b&&b.isError)try{T=JSON.stringify(b)}catch(_){g.error(`Failed to serialize error result for ${e}`,_)}return i.setAttribute("tool.result.status",T?"error":"success"),T?i.setStatus({code:be.ERROR,message:`Tool ${e} returned isError: true`}):i.setStatus({code:be.OK}),b}this.neurolink?.emitToolStart&&(l=this.neurolink.emitToolStart(e,s,a));let u=await t.execute(s),d=this.utilities?.convertToolResult?await this.utilities.convertToolResult(u):u,p=Date.now(),m;if(d&&typeof d=="object"&&"isError"in d&&d.isError)try{m=JSON.stringify(d)}catch(f){g.error(`Failed to serialize error result for ${e}`,f)}return this.neurolink?.emitToolEnd&&this.neurolink.emitToolEnd(e,d,m,a,p,l),i.setAttribute("tool.duration_ms",p-a),i.setAttribute("tool.result.status",m?"error":"success"),m?i.setStatus({code:be.ERROR,message:`Tool ${e} returned isError: true`}):i.setStatus({code:be.OK}),d}catch(u){let d=Date.now(),p=u instanceof Error?u.message:String(u);throw!this.toolExecutor&&this.neurolink?.emitToolEnd&&(this.neurolink.emitToolEnd(e,void 0,p,a,d,l),g.debug(`Custom tool error: ${e} (${d-a}ms)`,{error:p})),i.setAttribute("tool.duration_ms",d-a),i.setAttribute("tool.result.status","error"),i.recordException(u instanceof Error?u:new Error(p)),i.setStatus({code:be.ERROR,message:p}),u}finally{i.end()}}}}catch(n){return g.error(`Failed to create tool: ${e}`,n),null}}async createExternalMCPTool(e){try{let t;if(e.inputSchema&&typeof e.inputSchema=="object"){let s=e.inputSchema,i=this.utilities?.fixSchemaForOpenAIStrictMode?this.utilities.fixSchemaForOpenAIStrictMode(s):s;t=ga(i)}else t=this.utilities?.createPermissiveZodSchema?this.utilities.createPermissiveZodSchema():c.object({});let n=async s=>{if(this.neurolink&&typeof this.neurolink.executeExternalMCPTool=="function")return this.neurolink.executeExternalMCPTool(e.serverId||"unknown",e.name,s);throw new Error("Cannot execute external MCP tool: NeuroLink executeExternalMCPTool not available")},o=this.wrapExecuteWithTruncation(e.name,n);return{description:e.description||`External MCP tool ${e.name}`,inputSchema:t,execute:async s=>{let i=Date.now();this.emitToolEvent("tool:start",e.name,{input:s});try{let a=await o(s);return this.emitToolEvent("tool:end",e.name,{result:a,success:!0,responseTime:Date.now()-i}),a}catch(a){let l=a instanceof Error?a.message:String(a);throw this.emitToolEvent("tool:end",e.name,{error:l,success:!1,responseTime:Date.now()-i}),g.error(`External MCP tool failed: ${e.name}`,{serverId:e.serverId,error:l}),a}}}}catch(t){return g.error(`Failed to create external MCP tool: ${e.name}`,t),null}}}});function lR(r,e,t){let n=Q3[r];if(!n)return g.warn(`Unknown provider ${r}, no token limits enforced`),t||void 0;let o;return e&&typeof n=="object"&&n[e]?o=n[e]:typeof n=="object"&&n.default?o=n.default:typeof n=="number"?o=n:o=Q3.default,t?t>o?(g.warn(`Requested maxTokens ${t} exceeds ${r}/${e} limit of ${o}. Using ${o} instead.`),o):t:o}var PCe=A(()=>{"use strict";Nd();Q()});var V$,MCe=A(()=>{"use strict";vo();Q();PCe();Qa();hg();Nd();V$=class{constructor(e,t,n=3e4,o){this.providerName=e;this.modelName=t;this.defaultTimeout=n;this.middlewareOptions=o}validateOptions(e){let t=FZ(e);if(!t.isValid){let n=gg(t);throw new Ct(`Text generation options validation failed: ${n}`,"options","VALIDATION_FAILED",t.suggestions)}if(t.warnings.length>0&&g.warn("Text generation options validation warnings:",t.warnings),e.maxSteps!==void 0&&(e.maxSteps<Do.min||e.maxSteps>Do.max))throw new Ct(`maxSteps must be between ${Do.min} and ${Do.max}`,"maxSteps","OUT_OF_RANGE",[`Use a value between ${Do.min} and ${Do.max} for optimal performance`])}validateStreamOptions(e){let t=rR(e);if(!t.isValid){let n=gg(t);throw new Ct(`Stream options validation failed: ${n}`,"options","VALIDATION_FAILED",t.suggestions)}if(t.warnings.length>0&&g.warn("Stream options validation warnings:",t.warnings),e.maxSteps!==void 0&&(e.maxSteps<Do.min||e.maxSteps>Do.max))throw new Ct(`maxSteps must be between ${Do.min} and ${Do.max}`,"maxSteps","OUT_OF_RANGE",[`Use a value between ${Do.min} and ${Do.max} for optimal performance`])}normalizeTextOptions(e){if(typeof e=="string"){let a=lR(this.providerName,this.modelName);return{prompt:e,provider:this.providerName,model:this.modelName,maxTokens:a}}let t=e.prompt||e.input?.text||"",n=e.model||this.modelName,o=e.provider||this.providerName,s=lR(o,n,e.maxTokens),i={...e,prompt:t,provider:o,model:n,maxTokens:s};return e.input&&(i.input={...e.input,text:t}),i}normalizeStreamOptions(e){if(typeof e=="string"){let s=lR(this.providerName,this.modelName);return{input:{text:e},provider:this.providerName,model:this.modelName,maxTokens:s}}let t=e.model||this.modelName,n=e.provider||this.providerName,o=lR(n,t,e.maxTokens);return{...e,provider:n,model:t,maxTokens:o}}getProviderInfo(){return{provider:this.providerName,model:this.modelName}}getTimeout(e){if(e.timeout!==void 0&&e.timeout!==null){let n=EL(e.timeout);if(n!==void 0)return n}return EL(qve(this.providerName,"generate"))??this.defaultTimeout}getContextAwareTimeout(e,t){let n=this.getTimeout(e);if(!t||t<=1e5)return n;let o=1+Math.floor((t-1)/1e5)*.5;return Math.round(n*Math.min(o,4))}isZodSchema(e){return typeof e=="object"&&e!==null&&typeof e.parse=="function"}async convertToolResult(e){if(e&&typeof e=="object"&&"success"in e){let t=e;if(t.success)return t.data!==void 0?t.data:e;{let n=typeof t.error=="string"?t.error:"Tool execution failed";return g.warn(`Tool execution failed: ${n}`),{isError:!0,error:n,content:[{type:"text",text:`Tool execution failed: ${n}`}]}}}return e}createPermissiveZodSchema(){return c.record(c.string(),c.unknown()).transform(e=>e)}fixSchemaForOpenAIStrictMode(e){let t=JSON.parse(JSON.stringify(e));if(t.type==="object"&&t.properties&&typeof t.properties=="object"){let n=Object.keys(t.properties);(!t.required||!Array.isArray(t.required))&&(t.required=[]),t.additionalProperties=!1;for(let o of n){let s=t.properties[o];s&&typeof s=="object"&&(s.type==="object"?t.properties[o]=this.fixSchemaForOpenAIStrictMode(s):s.type==="array"&&s.items&&typeof s.items=="object"&&(t.properties[o].items=this.fixSchemaForOpenAIStrictMode(s.items)))}}return t}extractMiddlewareOptions(e){let t=e.middleware??this.middlewareOptions;if(!t||typeof t!="object"||t===null||t instanceof Date||t instanceof RegExp)return null;let n=t,o=i=>Array.isArray(i)&&i.length>0;return!!n.middlewareConfig||o(n.enabledMiddleware)||o(n.disabledMiddleware)||!!n.preset||o(n.middleware)?{...n,global:{collectStats:!0,continueOnError:!0,...n.global||{}}}:null}handleCommonErrors(e){if(e instanceof zr)return new Error(`${this.providerName} request timed out after ${e.timeout}ms. Consider increasing timeout or using a lighter model.`);let t=e instanceof Error?e.message:String(e);return t.includes("API_KEY_INVALID")||t.includes("Invalid API key")||t.includes("authentication")||t.includes("unauthorized")?new Error(`Invalid API key for ${this.providerName}. Please check your API key environment variable.`):t.includes("rate limit")||t.includes("quota")||t.includes("429")?new Error(`Rate limit exceeded for ${this.providerName}. Please wait before making more requests.`):null}}});var NCe={};le(NCe,{createToolCallRepair:()=>jUt});function jUt(){return async({toolCall:r,tools:e,inputSchema:t,error:n})=>{let{NoSuchToolError:o,InvalidToolInputError:s}=await Promise.resolve().then(()=>(Tn(),HC));if(o.isInstance(n))return qUt(r,Object.keys(e));if(s.isInstance(n))try{let i=await t({toolName:r.toolName});return GUt(r,i)}catch{return null}return null}}function qUt(r,e){let t=r.toolName;if(!t||t.trim().length===0)return null;let n=e.find(l=>l.toLowerCase()===t.toLowerCase());if(n)return g.debug(`[ToolCallRepair] Name repair (case): "${t}" \u2192 "${n}"`),{...r,toolName:n};let o=t.toLowerCase(),s=e.filter(l=>{let u=l.toLowerCase();return u.includes(o)||o.includes(u)});if(s.length===1)return g.debug(`[ToolCallRepair] Name repair (substring): "${t}" \u2192 "${s[0]}"`),{...r,toolName:s[0]};let i=null,a=1/0;for(let l of e){let u=OCe(o,l.toLowerCase()),d=Math.max(t.length,l.length),p=d===0?0:u/d;p<.3&&p<a&&(a=p,i=l)}return i?(g.debug(`[ToolCallRepair] Name repair (levenshtein ${a.toFixed(2)}): "${t}" \u2192 "${i}"`),{...r,toolName:i}):(g.debug(`[ToolCallRepair] Could not repair tool name "${t}". Available: [${e.join(", ")}]`),null)}function GUt(r,e){let t;try{t=JSON.parse(r.input)}catch{return null}if(!t||typeof t!="object"||Array.isArray(t))return null;let n=e.properties;if(!n)return null;let o=Object.keys(n),s=t,i=Object.keys(s),a=Object.create(null),l=!1,u=e.additionalProperties===!1;for(let d of i){if(o.includes(d)){a[d]=s[d];continue}let p=VUt(d,o);if(p){if(Object.prototype.hasOwnProperty.call(a,p)){l=!0;continue}g.debug(`[ToolCallRepair] Param repair: "${d}" \u2192 "${p}" (tool: ${r.toolName})`),a[p]=s[d],l=!0}else u?(g.debug(`[ToolCallRepair] Dropping unmapped key "${d}" (additionalProperties: false, tool: ${r.toolName})`),l=!0):a[d]=s[d]}for(let d of Object.keys(a)){let p=n[d];if(!p)continue;let m=HUt(a[d],p);m!==a[d]&&(g.debug(`[ToolCallRepair] Type coercion on "${d}": ${typeof a[d]} \u2192 ${typeof m} (tool: ${r.toolName})`),a[d]=m,l=!0)}return l?{...r,input:JSON.stringify(a)}:null}function VUt(r,e){let t=r.toLowerCase(),n=e.find(i=>i.toLowerCase()===t);if(n)return n;let o=null,s=1/0;for(let i of e){let a=OCe(t,i.toLowerCase());a<=2&&a<s&&(s=a,o=i)}return o}function HUt(r,e){let t=e.type;if(!t||r===null||r===void 0)return r;if(t==="number"&&typeof r=="string"){let n=r.trim();if(n!==""){let o=Number(n);if(isFinite(o))return o}}if(t==="integer"&&typeof r=="string"){let n=r.trim();if(/^[+-]?\d+$/.test(n)){let o=Number(n);if(Number.isSafeInteger(o))return o}}if(t==="boolean"&&typeof r=="string"){if(r.toLowerCase()==="true")return!0;if(r.toLowerCase()==="false")return!1}if(t==="object"&&typeof r=="string")try{let n=JSON.parse(r);if(n&&typeof n=="object"&&!Array.isArray(n))return n}catch{}if(t==="array"&&typeof r=="string")try{let n=JSON.parse(r);if(Array.isArray(n))return n}catch{}return t==="array"&&!Array.isArray(r)&&typeof r!="string"?[r]:r}function OCe(r,e){if(r===e)return 0;if(r.length===0)return e.length;if(e.length===0)return r.length;r.length>e.length&&([r,e]=[e,r]);let t=r.length,n=e.length,o=new Array(t+1),s=new Array(t+1);for(let i=0;i<=t;i++)o[i]=i;for(let i=1;i<=n;i++){s[0]=i;for(let a=1;a<=t;a++){let l=r[a-1]===e[i-1]?0:1;s[a]=Math.min(o[a]+1,s[a-1]+1,o[a-1]+l)}[o,s]=[s,o]}return o[t]}var DCe=A(()=>{"use strict";Q()});var HZ={};le(HZ,{Agent:()=>M$t,BedrockClient:()=>KUt,BedrockRuntimeClient:()=>ZUt,Blob:()=>P$t,Client:()=>N$t,ConverseCommand:()=>XUt,ConverseStreamCommand:()=>YUt,Cron:()=>m$t,Dispatcher:()=>D$t,File:()=>I$t,FlowProducer:()=>p$t,FormData:()=>A$t,GoogleAuth:()=>uR,HTTPException:()=>b$t,Headers:()=>R$t,Hippocampus:()=>s$t,HippocampusConfig:()=>i$t,Hono:()=>v$t,ImageFormat:()=>QUt,InvokeEndpointCommand:()=>t$t,InvokeEndpointWithResponseStreamCommand:()=>r$t,Job:()=>u$t,ListFoundationModelsCommand:()=>JUt,MockAgent:()=>U$t,Pool:()=>O$t,Queue:()=>c$t,QueueScheduler:()=>d$t,Request:()=>C$t,Response:()=>k$t,SageMakerRuntimeClient:()=>e$t,TextToSpeechClient:()=>o$t,VertexAI:()=>n$t,Worker:()=>l$t,convertToHtml:()=>y$t,cors:()=>x$t,createClient:()=>a$t,default:()=>WUt,extractRawText:()=>h$t,fetch:()=>E$t,getGlobalDispatcher:()=>F$t,interceptors:()=>$$t,logger:()=>T$t,parseBuffer:()=>f$t,request:()=>z$t,secureHeaders:()=>S$t,selectCover:()=>g$t,setGlobalDispatcher:()=>L$t,streamSSE:()=>w$t,timeout:()=>_$t});var ES,$s,WUt,KUt,JUt,ZUt,XUt,YUt,QUt,e$t,t$t,r$t,uR,n$t,o$t,s$t,i$t,a$t,c$t,l$t,u$t,d$t,p$t,m$t,f$t,g$t,h$t,y$t,v$t,x$t,b$t,T$t,S$t,w$t,_$t,E$t,C$t,k$t,R$t,A$t,I$t,P$t,M$t,O$t,N$t,D$t,L$t,F$t,U$t,$$t,z$t,dR=A(()=>{ES={get(r,e){return e==="__esModule"?!0:e==="default"?new Proxy({},{get:ES.get}):new Proxy(function(...t){return new Proxy({},{get:ES.get})},{get:ES.get,apply(t,n,o){return new Proxy({},{get:ES.get})},construct(t,n){return new Proxy({},{get:ES.get})}})}},$s=new Proxy({},ES),WUt=$s,{BedrockClient:KUt,ListFoundationModelsCommand:JUt,BedrockRuntimeClient:ZUt,ConverseCommand:XUt,ConverseStreamCommand:YUt,ImageFormat:QUt}=$s,{SageMakerRuntimeClient:e$t,InvokeEndpointCommand:t$t,InvokeEndpointWithResponseStreamCommand:r$t}=$s,{GoogleAuth:uR,VertexAI:n$t,TextToSpeechClient:o$t}=$s,{Hippocampus:s$t,HippocampusConfig:i$t}=$s,{createClient:a$t}=$s,{Queue:c$t,Worker:l$t,Job:u$t,QueueScheduler:d$t,FlowProducer:p$t}=$s,{Cron:m$t}=$s,{parseBuffer:f$t,selectCover:g$t}=$s,{extractRawText:h$t,convertToHtml:y$t}=$s,{Hono:v$t}=$s,{cors:x$t,HTTPException:b$t,logger:T$t,secureHeaders:S$t,streamSSE:w$t,timeout:_$t}=$s,E$t=globalThis.fetch,C$t=globalThis.Request,k$t=globalThis.Response,R$t=globalThis.Headers,A$t=globalThis.FormData,I$t=globalThis.File,P$t=globalThis.Blob,M$t=$s.Agent,O$t=$s.Pool,N$t=$s.Client,D$t=$s.Dispatcher,L$t=()=>{},F$t=()=>$s,U$t=$s.MockAgent,$$t={redirect:()=>r=>r,retry:()=>r=>r},z$t=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 BCe={};le(BCe,{VIDEO_ERROR_CODES:()=>Et,VideoError:()=>Pt,generateTransitionWithVertex:()=>ZZ,generateVideoWithVertex:()=>JZ,isVertexVideoConfigured:()=>FCe});function FCe(){return!!(process.env.GOOGLE_APPLICATION_CREDENTIALS||process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK||process.env.GOOGLE_SERVICE_ACCOUNT_KEY||process.env.GOOGLE_AUTH_CLIENT_EMAIL&&process.env.GOOGLE_AUTH_PRIVATE_KEY)}async function UCe(){let r=process.env.GOOGLE_VERTEX_LOCATION||process.env.GOOGLE_CLOUD_LOCATION||j$t,e=process.env.GOOGLE_VERTEX_PROJECT||process.env.GOOGLE_CLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID||process.env.VERTEX_PROJECT_ID;if(!e&&process.env.GOOGLE_APPLICATION_CREDENTIALS)try{let t=JSON.parse(await Uo(process.env.GOOGLE_APPLICATION_CREDENTIALS,"utf-8"));e=t.quota_project_id||t.project_id}catch(t){g.debug("Failed to read project from credentials file",{error:t instanceof Error?t.message:String(t)})}if(!e)throw new Pt({code:Et.PROVIDER_NOT_CONFIGURED,message:"Google Cloud project not found. Set GOOGLE_VERTEX_PROJECT or GOOGLE_CLOUD_PROJECT environment variable, or ensure ADC credentials contain project_id",category:"configuration",severity:"high",retriable:!1,context:{missingVar:"GOOGLE_VERTEX_PROJECT",feature:"video-generation",checkedEnvVars:["GOOGLE_VERTEX_PROJECT","GOOGLE_CLOUD_PROJECT","GOOGLE_CLOUD_PROJECT_ID","VERTEX_PROJECT_ID"]}});return{project:e,location:r}}async function $Ce(){try{let r=await Promise.resolve().then(()=>(dR(),HZ)),e=new r.GoogleAuth({keyFilename:process.env.GOOGLE_APPLICATION_CREDENTIALS,scopes:["https://www.googleapis.com/auth/cloud-platform"]}),t=await Oe(e.getAccessToken(),JC.PROVIDER.AUTH_MS);if(!t)throw new Pt({code:Et.PROVIDER_NOT_CONFIGURED,message:"Failed to obtain access token from Google Cloud credentials",category:"configuration",severity:"high",retriable:!1,context:{provider:"vertex",feature:"video-generation"}});return t}catch(r){throw r instanceof Pt?r:new Pt({code:Et.PROVIDER_NOT_CONFIGURED,message:`Google Cloud authentication failed: ${r instanceof Error?r.message:String(r)}`,category:"configuration",severity:"high",retriable:!1,context:{provider:"vertex",feature:"video-generation"},originalError:r instanceof Error?r:void 0})}}function KZ(r){return r.length<4?(g.warn("Image buffer too small for format detection",{size:r.length}),"image/jpeg"):r[0]===255&&r[1]===216&&r[2]===255?"image/jpeg":r[0]===137&&r[1]===80&&r[2]===78&&r[3]===71?"image/png":r.length>=12&&r[0]===82&&r[1]===73&&r[2]===70&&r[3]===70&&r[8]===87&&r[9]===69&&r[10]===66&&r[11]===80?"image/webp":(g.warn("Unknown image format detected, defaulting to image/jpeg",{firstBytes:r.slice(0,12).toString("hex"),size:r.length}),"image/jpeg")}function q$t(r,e){return r==="1080p"?e==="9:16"?{width:1080,height:1920}:{width:1920,height:1080}:e==="9:16"?{width:720,height:1280}:{width:1280,height:720}}async function JZ(r,e,t={},n){let o=await UCe(),s=o.project,i=n||o.location,a=Date.now(),l=t.resolution||"720p",u=t.length||6,d=t.aspectRatio||"16:9",p=t.audio??!0;g.debug("Starting Vertex video generation",{project:s,location:i,model:H$,resolution:l,durationSeconds:u,aspectRatio:d,generateAudio:p,promptLength:e.length,imageSize:r.length});try{let m=r.toString("base64"),f=KZ(r),h=await $Ce(),v=`https://${i==="global"?"aiplatform.googleapis.com":`${i}-aiplatform.googleapis.com`}/v1/projects/${s}/locations/${i}/publishers/google/models/${H$}:predictLongRunning`,b={instances:[{prompt:e,image:{bytesBase64Encoded:m,mimeType:f}}],parameters:{sampleCount:1,durationSeconds:u,aspectRatio:d,resolution:l,generateAudio:p,resizeMode:"pad"}};g.debug("Sending video generation request",{endpoint:v});let w=new AbortController,T=setTimeout(()=>w.abort(),3e4),_;try{_=await fetch(v,{method:"POST",headers:{Authorization:`Bearer ${h}`,"Content-Type":"application/json; charset=utf-8"},body:JSON.stringify(b),signal:w.signal})}catch(O){throw clearTimeout(T),br(O)?new Pt({code:Et.GENERATION_FAILED,message:"Video generation request timed out after 30 seconds",category:"execution",severity:"high",retriable:!0,context:{provider:"vertex",endpoint:v,timeout:3e4}}):O}if(clearTimeout(T),!_.ok){let O=await _.text();throw new Pt({code:Et.GENERATION_FAILED,message:`Vertex API error: ${_.status} - ${O}`,category:"execution",severity:"high",retriable:_.status>=500,context:{status:_.status,error:O,provider:"vertex",endpoint:v}})}let k=await _.json(),R=k.name;if(!R)throw new Pt({code:Et.GENERATION_FAILED,message:"Vertex API did not return an operation name",category:"execution",severity:"high",retriable:!1,context:{response:k,provider:"vertex"}});g.debug("Video generation operation started",{operationName:R});let I=LCe-(Date.now()-a),C=await H$t(R,h,s,i,Math.max(1e3,I)),E=Date.now()-a,M=q$t(l,d);return g.info("Video generation complete",{processingTime:E,videoSizeKB:Math.round(C.length/1024),dimensions:M}),{data:C,mediaType:"video/mp4",metadata:{duration:u,dimensions:M,model:H$,provider:"vertex",aspectRatio:d,audioEnabled:p,processingTime:E}}}catch(m){throw m instanceof Pt?m:new Pt({code:Et.GENERATION_FAILED,message:`Video generation failed: ${m instanceof Error?m.message:String(m)}`,category:"execution",severity:"high",retriable:!0,context:{provider:"vertex"},originalError:m instanceof Error?m:void 0})}}function G$t(r,e){if(r.error)throw new Pt({code:Et.GENERATION_FAILED,message:`Video generation failed: ${r.error.message||JSON.stringify(r.error)}`,category:"execution",severity:"high",retriable:!1,context:{operationName:e,error:r.error,provider:"vertex"}});let t=r.response?.videos?.[0];if(!t)throw new Pt({code:Et.GENERATION_FAILED,message:"No video data in response from Vertex AI",category:"execution",severity:"high",retriable:!1,context:{operationName:e,response:r.response,provider:"vertex"}});if(t.gcsUri)throw new Pt({code:Et.GENERATION_FAILED,message:`Video stored at GCS: ${t.gcsUri}. GCS download not yet implemented.`,category:"execution",severity:"high",retriable:!1,context:{operationName:e,gcsUri:t.gcsUri,provider:"vertex",suggestion:"Do not set storageUri parameter to receive video as base64 inline"}});if(t.bytesBase64Encoded)return Buffer.from(t.bytesBase64Encoded,"base64");throw new Pt({code:Et.GENERATION_FAILED,message:"No video bytes in response - unexpected response format",category:"execution",severity:"high",retriable:!1,context:{operationName:e,videoData:t,provider:"vertex"}})}async function V$t(r,e,t,n=3e4){let o=new AbortController,s=setTimeout(()=>o.abort(),n),i;try{i=await fetch(r,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json; charset=utf-8"},body:JSON.stringify({operationName:e}),signal:o.signal})}catch(a){throw clearTimeout(s),br(a)?new Pt({code:Et.GENERATION_FAILED,message:`Poll request timed out after ${n}ms`,category:"execution",severity:"high",retriable:!0,context:{provider:"vertex",operationName:e,timeout:n}}):a}if(clearTimeout(s),!i.ok){let a=await i.text();throw new Pt({code:Et.GENERATION_FAILED,message:`Failed to poll video operation: ${i.status} - ${a}`,category:"execution",severity:"high",retriable:i.status>=500,context:{operationName:e,status:i.status,error:a,provider:"vertex"}})}return i.json()}async function H$t(r,e,t,n,o){return zCe(H$,r,e,t,n,o)}async function ZZ(r,e,t,n={},o=4,s){if(!FCe())throw new Pt({code:Et.PROVIDER_NOT_CONFIGURED,message:"Vertex AI credentials not configured for transition generation.",category:"configuration",severity:"high",retriable:!1});let i=await UCe(),a=i.project,l=s||i.location,u=Date.now(),d=n.aspectRatio||"16:9",p=n.resolution||"720p",m=n.audio??!0;g.debug("Starting transition clip generation",{model:WZ,durationSeconds:o,firstFrameSize:r.length,lastFrameSize:e.length,promptLength:t.length});try{let f=r.toString("base64"),h=e.toString("base64"),y=KZ(r),v=KZ(e),b=await $Ce(),w=`https://${l}-aiplatform.googleapis.com/v1/projects/${a}/locations/${l}/publishers/google/models/${WZ}:predictLongRunning`,T={instances:[{prompt:t,image:{bytesBase64Encoded:f,mimeType:y},lastFrame:{bytesBase64Encoded:h,mimeType:v}}],parameters:{sampleCount:1,durationSeconds:o,aspectRatio:d,resolution:p,generateAudio:m}},_=new AbortController,k=setTimeout(()=>_.abort(),3e4),R;try{R=await fetch(w,{method:"POST",headers:{Authorization:`Bearer ${b}`,"Content-Type":"application/json; charset=utf-8"},body:JSON.stringify(T),signal:_.signal})}catch(O){throw clearTimeout(k),br(O)?new Pt({code:Et.DIRECTOR_TRANSITION_FAILED,message:"Transition generation request timed out after 30 seconds",category:"execution",severity:"medium",retriable:!0}):O}if(clearTimeout(k),!R.ok){let O=await R.text();throw new Pt({code:Et.DIRECTOR_TRANSITION_FAILED,message:`Transition API error: ${R.status} - ${O}`,category:"execution",severity:"medium",retriable:R.status>=500,context:{status:R.status,error:O}})}let C=(await R.json()).name;if(!C)throw new Pt({code:Et.DIRECTOR_TRANSITION_FAILED,message:"Transition API did not return an operation name",category:"execution",severity:"medium",retriable:!1});let E=LCe-(Date.now()-u),M=await W$t(C,b,a,l,Math.max(1e3,E));return g.debug("Transition clip generated",{processingTime:Date.now()-u,videoSize:M.length}),M}catch(f){throw f instanceof Pt?f:new Pt({code:Et.DIRECTOR_TRANSITION_FAILED,message:`Transition generation failed: ${f instanceof Error?f.message:String(f)}`,category:"execution",severity:"medium",retriable:!0,originalError:f instanceof Error?f:void 0})}}async function zCe(r,e,t,n,o,s){let i=Date.now(),l=`https://${o==="global"?"aiplatform.googleapis.com":`${o}-aiplatform.googleapis.com`}/v1/projects/${n}/locations/${o}/publishers/google/models/${r}:fetchPredictOperation`;for(;Date.now()-i<s;){let u=await V$t(l,e,t);if(u.done)return G$t(u,e);g.debug("Polling operation...",{operationName:e,elapsed:Date.now()-i}),await new Promise(d=>setTimeout(d,B$t))}throw new Pt({code:Et.POLL_TIMEOUT,message:`Operation timed out after ${Math.round(s/1e3)}s`,category:"timeout",severity:"medium",retriable:!0,context:{operationName:e,timeoutMs:s}})}async function W$t(r,e,t,n,o){return zCe(WZ,r,e,t,n,o)}var Pt,LCe,B$t,H$,WZ,j$t,pR=A(()=>{"use strict";Qc();ZC();Ab();bt();Q();Pt=class extends Ve{constructor(e){super({code:e.code,message:e.message,category:e.category??"execution",severity:e.severity??"high",retriable:e.retriable??!1,context:e.context,originalError:e.originalError}),this.name="VideoError"}},LCe=18e4,B$t=5e3,H$="veo-3.1-generate-001",WZ="veo-3.1-fast-generate-001",j$t="us-central1"});var XZ,mR,jCe=A(()=>{XZ=class{value;next;constructor(e){this.value=e}},mR=class{#e;#t;#r;constructor(){this.clear()}enqueue(e){let t=new XZ(e);this.#e?(this.#t.next=t,this.#t=t):(this.#e=t,this.#t=t),this.#r++}dequeue(){let e=this.#e;if(e)return this.#e=this.#e.next,this.#r--,this.#e||(this.#t=void 0),e.value}peek(){if(this.#e)return this.#e.value}clear(){this.#e=void 0,this.#t=void 0,this.#r=0}get size(){return this.#r}*[Symbol.iterator](){let e=this.#e;for(;e;)yield e.value,e=e.next}*drain(){for(;this.#e;)yield this.dequeue()}}});function cp(r){let e=!1;if(typeof r=="object"&&({concurrency:r,rejectOnClear:e=!1}=r),qCe(r),typeof e!="boolean")throw new TypeError("Expected `rejectOnClear` to be a boolean");let t=new mR,n=0,o=()=>{n<r&&t.size>0&&(n++,t.dequeue().run())},s=()=>{n--,o()},i=async(u,d,p)=>{let m=(async()=>u(...p))();d(m);try{await m}catch{}s()},a=(u,d,p,m)=>{let f={reject:p};new Promise(h=>{f.run=h,t.enqueue(f)}).then(i.bind(void 0,u,d,m)),n<r&&o()},l=(u,...d)=>new Promise((p,m)=>{a(u,p,m,d)});return Object.defineProperties(l,{activeCount:{get:()=>n},pendingCount:{get:()=>t.size},clearQueue:{value(){if(!e){t.clear();return}let u=AbortSignal.abort().reason;for(;t.size>0;)t.dequeue().reject(u)}},concurrency:{get:()=>r,set(u){qCe(u),r=u,queueMicrotask(()=>{for(;n<r&&t.size>0;)o()})}},map:{async value(u,d){let p=Array.from(u,(m,f)=>this(d,m,f));return Promise.all(p)}}}),l}function qCe(r){if(!((Number.isInteger(r)||r===Number.POSITIVE_INFINITY)&&r>0))throw new TypeError("Expected `concurrency` to be a number from 1 and up")}var fR=A(()=>{jCe()});var gR,L9r,YZ,K$t,F9r,Ji,ll,Tg,lp,W$,VCe,HCe,WCe,KCe,hR,U9r,$9r,QZ,J$t,GCe,z9r,B9r,q9r,G9r,up=A(()=>{gR=()=>{},L9r=globalThis.crypto,YZ=()=>{throw new Error("[NeuroLink:browser] fs.appendFileSync is not supported in browser runtime \u2014 use server-side execution")},K$t=class{pipe(){return this}on(){return this}read(){return null}push(){}destroy(){}},F9r=globalThis.ReadableStream||class{},Ji=()=>!1,ll=()=>"",Tg=gR,lp=gR,W$=()=>({}),VCe=()=>[],HCe=gR,WCe=gR,KCe=gR,hR=()=>new K$t,U9r=globalThis.URL,$9r=globalThis.URLSearchParams,QZ=r=>{try{return JSON.stringify(r,null,2)}catch{return String(r)}};QZ.custom=Symbol.for("nodejs.util.inspect.custom");QZ.colors={};QZ.styles={};J$t=globalThis.TextDecoder,GCe=globalThis.TextEncoder,z9r=globalThis.performance||{now:()=>Date.now()},B9r=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 GCe().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 GCe().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 J$t().decode(this)}},q9r=globalThis.clearTimeout,G9r=globalThis.clearInterval});var K9r,J9r,ZCe,CS,Z9r,X9r,eX,Z$t,JCe,Y9r,Q9r,tZr,rZr,yR=A(()=>{K9r=globalThis.crypto,J9r=globalThis.ReadableStream||class{},ZCe=()=>"/",CS=()=>"/tmp",Z9r=globalThis.URL,X9r=globalThis.URLSearchParams,eX=r=>{try{return JSON.stringify(r,null,2)}catch{return String(r)}};eX.custom=Symbol.for("nodejs.util.inspect.custom");eX.colors={};eX.styles={};Z$t=globalThis.TextDecoder,JCe=globalThis.TextEncoder,Y9r=globalThis.performance||{now:()=>Date.now()},Q9r=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 JCe().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 JCe().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 Z$t().decode(this)}},tZr=globalThis.clearTimeout,rZr=globalThis.clearInterval});var nke={};le(nke,{AsyncLocalStorage:()=>y2t,Buffer:()=>sBt,Channel:()=>Kzt,DatabaseSync:()=>oBt,Duplex:()=>x2t,EventEmitter:()=>h2t,Http2ServerRequest:()=>uBt,Http2ServerResponse:()=>dBt,Interface:()=>nBt,MIMEType:()=>yBt,PassThrough:()=>b2t,PerformanceObserver:()=>Vzt,Readable:()=>YCe,ReadableStream:()=>T2t,Resolver:()=>qzt,TextDecoder:()=>tke,TextEncoder:()=>K$,Transform:()=>v2t,URL:()=>Izt,URLSearchParams:()=>Pzt,Worker:()=>Yzt,Writable:()=>QCe,access:()=>J2t,appendFile:()=>R2t,appendFileSync:()=>n2t,arch:()=>lzt,arrayBuffer:()=>pBt,basename:()=>l2t,builtinModules:()=>Czt,callbackify:()=>Uzt,channel:()=>Wzt,chmodSync:()=>k2t,clearInterval:()=>hBt,clearTimeout:()=>fBt,closeSync:()=>M2t,connect:()=>mzt,constants:()=>iBt,copyFileSync:()=>I2t,cpSync:()=>o2t,cpus:()=>szt,createConnection:()=>fzt,createGunzip:()=>Tzt,createGzip:()=>Szt,createHash:()=>XCe,createHmac:()=>Q$t,createInterface:()=>rBt,createReadStream:()=>j2t,createRequire:()=>Ezt,createServer:()=>s2t,createWriteStream:()=>B2t,debug:()=>Lzt,debuglog:()=>eke,default:()=>X$t,deflateSync:()=>hzt,deprecate:()=>Fzt,deserialize:()=>Xzt,dirname:()=>c2t,exec:()=>Y2t,execFile:()=>ezt,execFileSync:()=>ps,execSync:()=>Q2t,existsSync:()=>_2t,extname:()=>u2t,fileURLToPath:()=>Mzt,finished:()=>w2t,format:()=>Azt,freemem:()=>izt,fstatSync:()=>O2t,get:()=>pzt,gunzip:()=>bzt,gunzipSync:()=>yzt,gzip:()=>xzt,gzipSync:()=>vzt,hasSubscribers:()=>Jzt,homedir:()=>rzt,hostname:()=>ozt,inflateSync:()=>gzt,inherits:()=>Nzt,inspect:()=>J$,isAbsolute:()=>p2t,isBuiltin:()=>kzt,isDeepStrictEqual:()=>$zt,isIP:()=>lBt,isIPv4:()=>cBt,isIPv6:()=>aBt,isMainThread:()=>Qzt,join:()=>i2t,lookup:()=>jzt,mkdir:()=>V2t,mkdirSync:()=>N2t,monitorEventLoopDelay:()=>Hzt,normalize:()=>g2t,ok:()=>wzt,openSync:()=>P2t,parentPort:()=>eBt,parse:()=>Rzt,pathToFileURL:()=>Ozt,performance:()=>Gzt,pipeline:()=>S2t,platform:()=>tzt,posix:()=>f2t,promises:()=>Y$t,promisify:()=>Dzt,randomBytes:()=>e2t,randomUUID:()=>t2t,readFile:()=>q2t,readFileSync:()=>E2t,readdir:()=>W2t,readdirSync:()=>L2t,realpathSync:()=>A2t,relative:()=>d2t,release:()=>uzt,rename:()=>Z2t,renameSync:()=>U2t,request:()=>dzt,resolve:()=>a2t,rm:()=>X2t,rmSync:()=>z2t,rmdirSync:()=>$2t,sep:()=>m2t,serialize:()=>Zzt,setInterval:()=>gBt,setTimeout:()=>mBt,spawn:()=>tX,stat:()=>H2t,statSync:()=>D2t,strict:()=>_zt,tmpdir:()=>nzt,toUSVString:()=>zzt,totalmem:()=>azt,type:()=>czt,types:()=>Bzt,unlink:()=>K2t,unlinkSync:()=>F2t,webcrypto:()=>r2t,workerData:()=>tBt,writeFile:()=>G2t,writeFileSync:()=>C2t});var po,ds,X$t,Y$t,XCe,Q$t,e2t,t2t,r2t,n2t,o2t,s2t,i2t,a2t,c2t,l2t,u2t,d2t,p2t,m2t,f2t,g2t,h2t,y2t,YCe,QCe,v2t,x2t,b2t,T2t,S2t,w2t,_2t,E2t,C2t,k2t,R2t,A2t,I2t,P2t,M2t,O2t,N2t,D2t,L2t,F2t,U2t,$2t,z2t,B2t,j2t,q2t,G2t,V2t,H2t,W2t,K2t,J2t,Z2t,X2t,tX,Y2t,Q2t,ezt,ps,tzt,rzt,nzt,ozt,szt,izt,azt,czt,lzt,uzt,dzt,pzt,mzt,fzt,gzt,hzt,yzt,vzt,xzt,bzt,Tzt,Szt,wzt,_zt,Ezt,Czt,kzt,Rzt,Azt,Izt,Pzt,Mzt,Ozt,Nzt,Dzt,eke,Lzt,J$,Fzt,Uzt,$zt,zzt,Bzt,tke,K$,jzt,qzt,Gzt,Vzt,Hzt,Wzt,Kzt,Jzt,Zzt,Xzt,Yzt,Qzt,eBt,tBt,rBt,nBt,oBt,sBt,iBt,aBt,cBt,lBt,uBt,dBt,pBt,rke,mBt,fBt,gBt,hBt,yBt,kS=A(()=>{po=()=>{},ds=async()=>{},X$t={},Y$t={readFile:ds,writeFile:ds,mkdir:ds,stat:ds,readdir:ds,unlink:ds,access:ds,rm:ds,rename:ds},XCe=r=>{let e=[];return{update(t){return e.push(typeof t=="string"?new K$().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}}},Q$t=(r,e)=>XCe(r),e2t=r=>new Uint8Array(r||32),t2t=()=>globalThis.crypto?.randomUUID?.()||Math.random().toString(36),r2t=globalThis.crypto,n2t=()=>{throw new Error("[NeuroLink:browser] fs.appendFileSync is not supported in browser runtime \u2014 use server-side execution")},o2t=()=>{throw new Error("[NeuroLink:browser] fs.cpSync is not supported in browser runtime \u2014 use server-side execution")},s2t=()=>({listen:po,close:po,on:po}),i2t=(...r)=>r.join("/"),a2t=(...r)=>r.join("/"),c2t=r=>r||"",l2t=r=>r?.split?.("/")?.pop?.()||"",u2t=r=>{let e=r?.match?.(/\.[^.]+$/);return e?e[0]:""},d2t=(r,e)=>e||"",p2t=()=>!1,m2t="/",f2t={normalize:r=>r,join:(...r)=>r.join("/"),resolve:(...r)=>r.join("/"),sep:"/"},g2t=r=>r,h2t=class{on(){return this}off(){return this}emit(){return this}once(){return this}removeListener(){return this}addListener(){return this}},y2t=class{getStore(){}run(r,e,...t){return e(...t)}enterWith(){}disable(){}},YCe=class{pipe(){return this}on(){return this}read(){return null}push(){}destroy(){}},QCe=class{write(){return!0}end(){}on(){return this}destroy(){}},v2t=class{push(){}on(){return this}},x2t=class{on(){return this}},b2t=class{pipe(){return this}on(){return this}},T2t=globalThis.ReadableStream||class{},S2t=po,w2t=po,_2t=()=>!1,E2t=()=>"",C2t=po,k2t=po,R2t=ds,A2t=r=>r,I2t=po,P2t=()=>0,M2t=po,O2t=()=>({}),N2t=po,D2t=()=>({}),L2t=()=>[],F2t=po,U2t=po,$2t=po,z2t=po,B2t=()=>new QCe,j2t=()=>new YCe,q2t=ds,G2t=ds,V2t=ds,H2t=ds,W2t=ds,K2t=ds,J2t=ds,Z2t=ds,X2t=ds,tX=()=>({on:po,stdout:{on:po},stderr:{on:po},kill:po}),Y2t=(r,e)=>e?.(null,"",""),Q2t=()=>"",ezt=(r,e,t)=>{typeof e=="function"?e(null,"",""):t?.(null,"","")},ps=()=>"",tzt="browser",rzt=()=>"/",nzt=()=>"/tmp",ozt=()=>"browser",szt=()=>[{}],izt=()=>0,azt=()=>0,czt=()=>"Browser",lzt=()=>"wasm",uzt=()=>"0",dzt=()=>({}),pzt=()=>({}),mzt=()=>({}),fzt=()=>({}),gzt=()=>new Uint8Array,hzt=()=>new Uint8Array,yzt=()=>new Uint8Array,vzt=()=>new Uint8Array,xzt=(r,e)=>e?.(null,r),bzt=(r,e)=>e?.(null,r),Tzt=()=>({}),Szt=()=>({}),wzt=po,_zt={},Ezt=()=>()=>({}),Czt=[],kzt=()=>!1,Rzt=r=>({pathname:r||"",hostname:"",protocol:"",search:"",hash:""}),Azt=()=>"",Izt=globalThis.URL,Pzt=globalThis.URLSearchParams,Mzt=r=>typeof r=="string"?r.replace("file://",""):r,Ozt=r=>new globalThis.URL("file://"+r),Nzt=(r,e)=>{e&&(r.super_=e,Object.setPrototypeOf(r.prototype,e.prototype))},Dzt=r=>(...e)=>new Promise((t,n)=>r(...e,(o,s)=>o?n(o):t(s))),eke=r=>{let e=(...t)=>{};return e.enabled=!1,e},Lzt=eke,J$=r=>{try{return JSON.stringify(r,null,2)}catch{return String(r)}};J$.custom=Symbol.for("nodejs.util.inspect.custom");J$.colors={};J$.styles={};Fzt=r=>r,Uzt=r=>(...e)=>{let t=e.pop();r(...e).then(n=>t(null,n)).catch(t)},$zt=(r,e)=>JSON.stringify(r)===JSON.stringify(e),zzt=r=>String(r),Bzt={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},tke=globalThis.TextDecoder,K$=globalThis.TextEncoder,jzt=(r,e)=>e?.(null,"127.0.0.1",4),qzt=class{},Gzt=globalThis.performance||{now:()=>Date.now()},Vzt=class{observe(){}disconnect(){}},Hzt=()=>({enable:po,disable:po,percentile:()=>0}),Wzt=()=>({}),Kzt=class{},Jzt=()=>!1,Zzt=()=>new Uint8Array,Xzt=po,Yzt=class{},Qzt=!0,eBt=null,tBt=null,rBt=()=>({}),nBt=class{},oBt=class{},sBt=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 K$().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 K$().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 tke().decode(this)}},iBt={F_OK:0,R_OK:4,W_OK:2,X_OK:1},aBt=()=>!1,cBt=()=>!1,lBt=()=>0,uBt=class{},dBt=class{},pBt=async()=>new ArrayBuffer(0),rke=r=>({[Symbol.toPrimitive](){return r},ref(){return this},unref(){return this},hasRef(){return!1},refresh(){return this},close(){}}),mBt=(...r)=>rke(globalThis.setTimeout(...r)),fBt=globalThis.clearTimeout,gBt=(...r)=>rke(globalThis.setInterval(...r)),hBt=globalThis.clearInterval,yBt=class{constructor(r){this.type=r}toString(){return this.type}}});function bBt(){if(oke)return;oke=!0;let r=()=>{for(let e of Z$)try{let t=VCe(e);for(let n of t)try{HCe(Ln(e,n))}catch{}KCe(e)}catch{}Z$.clear()};process.on("exit",r)}async function X$(r){bBt();let e=Ln(CS(),`neurolink-${r}-${Xa()}`);return await tm(e,{recursive:!0}),Z$.add(e),e}async function Y$(r,...e){for(let t of e)try{await Ff(t)}catch(n){g.debug("Failed to clean up temp file",{path:t,error:n instanceof Error?n.message:String(n)})}try{await py(r,{recursive:!0,force:!0})}catch(t){g.debug("Failed to remove temp directory",{path:r,error:t instanceof Error?t.message:String(t)})}Z$.delete(r)}async function TBt(){if(Sg)return Sg;if(process.env.FFMPEG_PATH)return Sg=process.env.FFMPEG_PATH,Sg;try{let r=await Promise.resolve().then(()=>(X9(),Z9)),e=r.default??r;if(typeof e=="string"&&e.length>0)return Sg=e,Sg}catch{g.debug("ffmpeg-static not available, using system ffmpeg binary")}return Sg="ffmpeg",g.warn("Using system ffmpeg binary. If video operations fail with ENOENT, install ffmpeg-static or set FFMPEG_PATH."),Sg}async function vR(r,e={}){let{execFile:t}=await Promise.resolve().then(()=>(kS(),nke)),n=await TBt(),o=e.timeoutMs??rX,s=e.maxBuffer??nX;return new Promise((i,a)=>{t(n,r,{timeout:o,maxBuffer:s},(u,d,p)=>{u?a(u):i({stdout:d||"",stderr:p||""})}).on("error",a)})}function Q$(r){return r.length<vBt?!1:r.subarray(4,8).equals(xBt)}var rX,ske,nX,ike,oX,ake,vBt,xBt,Z$,oke,Sg,sX=A(()=>{"use strict";Ld();up();Qc();yR();oc();Q();rX=3e4,ske=12e4,nX=10*1024*1024,ike=50*1024*1024,oX="2",ake="0.5",vBt=12,xBt=Buffer.from([102,116,121,112]),Z$=new Set,oke=!1;Sg=null});function SBt(r,e){if(!Buffer.isBuffer(r)||r.length===0)throw new Pt({code:Et.DIRECTOR_FRAME_EXTRACTION_FAILED,message:`Cannot ${e}: video buffer is empty or not a Buffer`,category:"validation",severity:"high",retriable:!1,context:{operation:e,bufferSize:r?.length??0}});if(!Q$(r))throw new Pt({code:Et.DIRECTOR_FRAME_EXTRACTION_FAILED,message:`Cannot ${e}: buffer does not appear to be a valid MP4 (missing ftyp header)`,category:"validation",severity:"high",retriable:!1,context:{operation:e,bufferSize:r.length,headerHex:r.subarray(0,12).toString("hex")}})}async function cke(r,e){let t=Date.now();SBt(r,`extract ${e} frame`);let n=await X$("frame"),o=Ln(n,"input.mp4"),s=Ln(n,`${e}_frame.jpg`);try{await Vi(o,r);let i=e==="first"?["-y","-i",o,"-vframes","1","-q:v",oX,"-f","image2",s]:["-y","-sseof",`-${ake}`,"-i",o,"-update","1","-q:v",oX,"-f","image2",s];await vR(i,{timeoutMs:rX,maxBuffer:nX});let a=await Uo(s);return g.debug(`Extracted ${e} frame`,{inputSize:r.length,frameSize:a.length,elapsedMs:Date.now()-t}),a}catch(i){throw i instanceof Pt?i:new Pt({code:Et.DIRECTOR_FRAME_EXTRACTION_FAILED,message:`Failed to extract ${e} frame: ${i instanceof Error?i.message:String(i)}`,category:"execution",severity:"high",retriable:!1,context:{position:e,bufferSize:r.length},originalError:i instanceof Error?i:void 0})}finally{await Y$(n,o,s)}}async function lke(r){return cke(r,"first")}async function uke(r){return cke(r,"last")}var dke=A(()=>{"use strict";Q();sX();Ab();pR()});async function wBt(r,e,t){let n=[],o=[];for(let s=0;s<r.length;s++){let i=Ln(e,`clip_${s}.mp4`);await Vi(i,r[s]),n.push(i);let a=i.replace(/\\/g,"/").replace(/'/g,"'\\''");o.push(`file '${a}'`)}return await Vi(t,o.join(`
1126
- `)),n}async function _Bt(r,e){let t={timeoutMs:ske,maxBuffer:ike};try{await vR(["-y","-f","concat","-safe","0","-i",r,"-c","copy",e],t)}catch(n){g.warn("Lossless concat failed, falling back to H.264 re-encoding",{error:n instanceof Error?n.message:String(n)}),await vR(["-y","-f","concat","-safe","0","-i",r,"-c:v","libx264","-preset","fast","-crf","18","-c:a","aac","-b:a","192k","-movflags","+faststart",e],t)}}async function pke(r){if(r.length===0)throw new Pt({code:Et.DIRECTOR_MERGE_FAILED,message:"No video buffers provided to merge",category:"validation",severity:"high",retriable:!1});for(let i=0;i<r.length;i++)if(!Q$(r[i]))throw new Pt({code:Et.DIRECTOR_MERGE_FAILED,message:`Clip ${i} is not a valid MP4 buffer (missing ftyp header or too small)`,category:"validation",severity:"high",retriable:!1,context:{clipIndex:i,bufferSize:r[i].length,headerHex:r[i].subarray(0,12).toString("hex")}});if(r.length===1)return r[0];let e=Date.now(),t=await X$("merge"),n=Ln(t,"concat.txt"),o=Ln(t,"merged.mp4"),s=[];try{s=await wBt(r,t,n),await _Bt(n,o);let i=await Uo(o);return g.info("Video merge complete",{inputClips:r.length,totalInputSize:r.reduce((a,l)=>a+l.length,0),outputSize:i.length,elapsedMs:Date.now()-e}),i}catch(i){throw i instanceof Pt?i:new Pt({code:Et.DIRECTOR_MERGE_FAILED,message:`Video merge failed: ${i instanceof Error?i.message:String(i)}`,category:"execution",severity:"high",retriable:!1,context:{clipCount:r.length},originalError:i instanceof Error?i:void 0})}finally{await Y$(t,n,o,...s)}}var mke=A(()=>{"use strict";Q();sX();Ab();pR()});var vke={};le(vke,{DIRECTOR_PIPELINE_TIMEOUT_MS:()=>kBt,executeDirectorPipeline:()=>NBt});async function ABt(r,e){if(Buffer.isBuffer(r))return r;if(typeof r=="string")return r.startsWith("http://")||r.startsWith("https://")?fke(r,e):gke(r,e);if(typeof r=="object"&&"data"in r){let t=r.data;if(Buffer.isBuffer(t))return t;if(typeof t=="string"){if(t.startsWith("http://")||t.startsWith("https://"))return fke(t,e);if(t.startsWith("data:")){let n=t.match(/^data:[^;]+;base64,(.+)$/);if(n&&n[1])return Buffer.from(n[1],"base64");throw new Pt({code:Et.INVALID_INPUT,message:`Invalid data URI format for segment ${e}. Expected format: data:<mime>;base64,<data>`,category:"execution",severity:"high",retriable:!1,context:{segmentIndex:e,dataUriPrefix:t.substring(0,50)}})}try{return await gke(t,e)}catch(n){throw new Pt({code:Et.INVALID_INPUT,message:`Invalid image input for segment ${e}: not a valid URL, file path, or data URI`,category:"execution",severity:"high",retriable:!1,context:{segmentIndex:e,inputType:"string",inputPrefix:t.substring(0,50),fileError:n instanceof Error?n.message:String(n)},originalError:n instanceof Error?n:void 0})}}}throw new Pt({code:Et.INVALID_INPUT,message:`Invalid image type for segment ${e}`,category:"execution",severity:"high",retriable:!1,context:{segmentIndex:e}})}async function fke(r,e){let t=new AbortController,n=setTimeout(()=>t.abort(),EBt);try{let o=await fetch(r,{signal:t.signal});if(!o.ok)throw new Pt({code:Et.INVALID_INPUT,message:`Failed to fetch image for segment ${e}: HTTP ${o.status}`,category:"execution",severity:"high",retriable:o.status>=500,context:{segmentIndex:e,url:r.substring(0,100)}});return Buffer.from(await o.arrayBuffer())}catch(o){throw o instanceof Pt?o:new Pt({code:Et.INVALID_INPUT,message:`Failed to fetch image for segment ${e}: ${o instanceof Error?o.message:String(o)}`,category:"execution",severity:"high",retriable:!0,context:{segmentIndex:e},originalError:o instanceof Error?o:void 0})}finally{clearTimeout(n)}}async function gke(r,e){let{readFile:t}=await Promise.resolve().then(()=>(Qc(),yk));try{return await t(r)}catch(n){throw new Pt({code:Et.INVALID_INPUT,message:`Failed to read image file for segment ${e}: ${n instanceof Error?n.message:String(n)}`,category:"execution",severity:"high",retriable:!1,context:{segmentIndex:e,path:r},originalError:n instanceof Error?n:void 0})}}function hke(r){for(;r.nextExpectedIndex<r.completions.length;){let e=r.completions[r.nextExpectedIndex];if(e.status==="pending")break;e.status==="success"?r.consecutiveFailures=0:(r.consecutiveFailures++,r.consecutiveFailures>=iX&&(r.circuitOpen=!0,g.error(`Circuit breaker tripped after ${iX} consecutive clip failures`))),r.nextExpectedIndex++}}async function IBt(r,e,t,n,o){if(o.circuitOpen)throw new Pt({code:Et.DIRECTOR_CLIP_FAILED,message:`Clip ${e} skipped \u2014 circuit breaker open after ${iX} consecutive failures`,category:"execution",severity:"high",retriable:!0,context:{segmentIndex:e}});let s=Date.now();try{let i=await ABt(r.image,e),a=M$(i);if(a)throw new Pt({code:Et.INVALID_INPUT,message:`Segment ${e} image validation failed: ${a.message}`,category:"execution",severity:"high",retriable:!1,context:{segmentIndex:e,validation:a},originalError:a});let u={buffer:(await JZ(i,r.prompt,t,n)).data,processingTime:Date.now()-s};o.results[e]=u,o.completions[e]={status:"success",result:u},hke(o)}catch(i){let a=i instanceof Error?i:new Error(String(i));throw o.completions[e]={status:"failure",error:a},hke(o),new Pt({code:Et.DIRECTOR_CLIP_FAILED,message:`Clip ${e} generation failed: ${a.message}`,category:"execution",severity:"high",retriable:!0,context:{segmentIndex:e,consecutiveFailures:o.consecutiveFailures},originalError:a})}}async function PBt(r,e,t){let n=cp(e2),o={consecutiveFailures:0,circuitOpen:!1,results:new Array(r.length).fill(null),completions:new Array(r.length).fill({status:"pending"}),nextExpectedIndex:0},s=r.map((l,u)=>n(()=>IBt(l,u,e,t,o))),a=(await Promise.allSettled(s)).filter(l=>l.status==="rejected");if(a.length>0){let l=a[0].reason instanceof Error?a[0].reason:new Error(String(a[0].reason));throw new Pt({code:Et.DIRECTOR_CLIP_FAILED,message:`Director Mode: ${a.length}/${r.length} clip(s) failed. First: ${l.message}`,category:"execution",severity:"high",retriable:!0,context:{failedCount:a.length,totalSegments:r.length,circuitBreakerTripped:o.circuitOpen},originalError:l})}return g.info("All clips generated successfully",{clipCount:r.length,concurrency:e2}),o.results}async function MBt(r,e,t,n,o){let s=r.length-1;if(s===0)return[];let i=cp(e2),a=Array.from({length:s},(l,u)=>i(async()=>{let d=Date.now(),p=e[u]??CBt,m=t[u]??RBt;try{let f=await yke(r[u].buffer,"last",u),h=await yke(r[u+1].buffer,"first",u+1),y=await ZZ(f,h,p,{aspectRatio:n.aspectRatio,resolution:n.resolution,audio:n.audio},m,o);return g.debug(`Transition ${u}\u2192${u+1} generated`,{duration:m,size:y.length,elapsedMs:Date.now()-d}),{buffer:y,fromSegment:u,toSegment:u+1,duration:m,processingTime:Date.now()-d}}catch(f){return g.warn(`Transition ${u}\u2192${u+1} failed, falling back to hard cut`,{error:f instanceof Error?f.message:String(f)}),{buffer:null,fromSegment:u,toSegment:u+1,duration:0,processingTime:Date.now()-d}}}));return Promise.all(a)}async function yke(r,e,t){let n=e==="first"?lke:uke;try{return await n(r)}catch(o){return g.warn(`Frame extraction (${e}) failed for clip ${t}, retrying once`,{error:o instanceof Error?o.message:String(o)}),await n(r)}}async function OBt(r,e){let t=[],n=r.length,o=e.length;for(let s=0;s<n;s++)t.push(r[s].buffer),s<o&&e[s].buffer&&t.push(e[s].buffer);try{return await pke(t)}catch(s){throw new Pt({code:Et.DIRECTOR_MERGE_FAILED,message:`Director Mode merge failed: ${s instanceof Error?s.message:String(s)}`,category:"execution",severity:"high",retriable:!1,context:{clipCount:n,transitionCount:e.filter(i=>i.buffer).length},originalError:s instanceof Error?s:void 0})}}async function NBt(r,e={},t={},n){let o=Date.now(),s=r.length,i=s-1,a=e.length??6,l=t.transitionPrompts??[],u=t.transitionDurations??[];g.info("Starting Director Mode pipeline",{segmentCount:s,transitionCount:i,concurrency:e2,clipDuration:a,resolution:e.resolution??"720p"});let d=await PBt(r,e,n);g.info("Phase 1 complete \u2014 all clips generated",{clipCount:d.length,elapsedMs:Date.now()-o});let p=await MBt(d,l,u,e,n),m=p.filter(k=>k.buffer).length,f=i-m;f>0&&g.warn(`${f}/${i} transition(s) fell back to hard cut`),g.info("Phase 2 complete \u2014 transitions generated",{successful:m,hardCuts:f,elapsedMs:Date.now()-o});let h=await OBt(d,p),y=p.map(k=>k.duration),v=s*a+y.reduce((k,R)=>k+R,0),b=e.resolution??"720p",w=e.aspectRatio??"16:9",T=b==="1080p"?w==="9:16"?{width:1080,height:1920}:{width:1920,height:1080}:w==="9:16"?{width:720,height:1280}:{width:1280,height:720},_=Date.now()-o;return g.info("Director Mode pipeline complete",{totalDuration:v,segmentCount:s,transitionsGenerated:m,hardCuts:f,mergedSize:h.length,processingTime:_}),{data:h,mediaType:"video/mp4",metadata:{duration:v,dimensions:T,model:"veo-3.1-generate-001",provider:"vertex",aspectRatio:w,audioEnabled:e.audio??!0,processingTime:_,segmentCount:s,transitionCount:m,clipDuration:a,transitionDurations:y,segments:d.map((k,R)=>({index:R,duration:a,processingTime:k.processingTime})),transitions:p.map(k=>({fromSegment:k.fromSegment,toSegment:k.toSegment,duration:k.duration,processingTime:k.processingTime}))}}}var e2,iX,EBt,CBt,kBt,RBt,xke=A(()=>{"use strict";fR();Q();hg();Ab();dke();pR();mke();e2=2,iX=2,EBt=15e3,CBt="Smooth cinematic transition between scenes",kBt=6e5,RBt=4});var an,xc=A(()=>{"use strict";Ht();Tn();uD();Nd();H5();Ta();bt();Q();Qa();WC();DL();gk();Zbe();Qbe();xEe();DEe();ACe();ICe();MCe();an=class{modelName;providerName;defaultTimeout=3e4;middlewareOptions;directTools=Eb()?{}:_f;mcpTools;customTools;toolExecutor;sessionId;userId;neurolink;_traceContext=null;setTraceContext(e){this._traceContext=e}messageBuilder;streamHandler;generationHandler;telemetryHandler;utilities;toolsManager;constructor(e,t,n,o){this.modelName=e||this.getDefaultModel(),this.providerName=t||this.getProviderName(),this.neurolink=n,this.middlewareOptions=o,this.messageBuilder=new P$(this.providerName,this.modelName),this.streamHandler=new O$(this.providerName,this.modelName),this.telemetryHandler=new j$(this.providerName,this.modelName,this.neurolink),this.generationHandler=new q1(this.providerName,this.modelName,()=>this.supportsTools(),(s,i)=>this.telemetryHandler.getTelemetryConfig(s,i),(s,i,a,l)=>this.handleToolExecutionStorage(s,i,a,l),()=>this.neurolink?.getEventEmitter()),this.utilities=new V$(this.providerName,this.modelName,this.defaultTimeout,this.middlewareOptions),this.toolsManager=new G$(this.providerName,this.directTools,this.neurolink,{isZodSchema:s=>this.isZodSchema(s),convertToolResult:s=>this.convertToolResult(s),createPermissiveZodSchema:()=>this.createPermissiveZodSchema(),fixSchemaForOpenAIStrictMode:s=>this.fixSchemaForOpenAIStrictMode(s)})}supportsTools(){return!0}async stream(e,t){let n=this.normalizeStreamOptions(e);if(g.info("Starting stream",{provider:this.providerName,hasTools:!n.disableTools&&this.supportsTools(),disableTools:!!n.disableTools,supportsTools:this.supportsTools(),inputLength:n.input?.text?.length||0,maxTokens:n.maxTokens,temperature:n.temperature,timestamp:Date.now()}),!!n.input?.files?.length||!!n.input?.videoFiles?.length){let a=await this.buildMessagesForStream(n);if(I8(a))return g.info("Video frames detected in stream, using fake streaming for video analysis",{provider:this.providerName,model:this.modelName}),await this.executeFakeStreaming(n,t)}let s=Y3.some(a=>this.modelName.includes(a)),i=n.output?.format==="json"||n.output?.format==="structured"||n.output?.format==="text";if(s&&!i)return g.info("Image model detected, forcing fake streaming",{provider:this.providerName,model:this.modelName,reason:"Image generation requires fake streaming to yield image output"}),await this.executeFakeStreaming(n,t);if(!n.disableTools&&this.supportsTools()){let a=await this.getToolsForStream(n);n={...n,tools:a}}else n={...n,tools:{}};try{g.debug("Attempting real streaming",{provider:this.providerName,timestamp:Date.now()});let a=await this.executeStream(n,t);return g.info("Real streaming succeeded",{provider:this.providerName,timestamp:Date.now()}),a}catch(a){let l=a instanceof Error?a.message:String(a);if((a instanceof Error?a.name:"")==="AbortError"||l.includes("abort")||l.includes("timeout")||l.includes("401")||l.includes("403")||l.includes("quota")||l.includes("rate limit")||l.includes("authentication"))throw this.handleProviderError(a);if(g.warn(`Real streaming failed for ${this.providerName}, falling back to fake streaming:`,{error:l,timestamp:Date.now()}),!n.disableTools&&this.supportsTools())return await this.executeFakeStreaming(n,t);throw g.error(`Real streaming failed for ${this.providerName}:`,a),this.handleProviderError(a)}}async executeFakeStreaming(e,t){try{g.info("Starting fake streaming with tools",{provider:this.providerName,supportsTools:this.supportsTools(),timestamp:Date.now()});let n={prompt:e.input?.text||"",input:e.input,systemPrompt:e.systemPrompt,temperature:e.temperature,maxTokens:e.maxTokens,tools:e.tools,disableTools:!!e.disableTools,maxSteps:e.maxSteps||5,provider:e.provider,model:e.model,region:e.region,enableAnalytics:e.enableAnalytics,enableEvaluation:e.enableEvaluation,evaluationDomain:e.evaluationDomain,toolUsageContext:e.toolUsageContext,context:e.context,csvOptions:e.csvOptions,abortSignal:e.abortSignal,toolFilter:e.toolFilter,excludeTools:e.excludeTools,skipToolPromptInjection:e.skipToolPromptInjection,timeout:e.timeout};g.debug("Calling generate for fake streaming",{provider:this.providerName,maxSteps:n.maxSteps,disableTools:n.disableTools,timestamp:Date.now()});let o=await this.generate(n,t);return g.info("Generate completed for fake streaming",{provider:this.providerName,hasContent:!!o?.content,contentLength:o?.content?.length||0,toolsUsed:o?.toolsUsed?.length||0,hasImageOutput:!!o?.imageOutput,timestamp:Date.now()}),{stream:(async function*(){if(o?.content){let s=o.content.split(/(\s+)/),i="";for(let a=0;a<s.length;a++)i+=s[a],(a===s.length-1||i.length>50||/[.!?;,]\s*$/.test(i))&&i.trim()&&(yield{content:i},i="",await new Promise(u=>{setTimeout(u,Math.random()*9+1)}));i.trim()&&(yield{content:i})}o?.imageOutput&&(yield{type:"image",imageOutput:o.imageOutput})})(),usage:o?.usage,provider:o?.provider,model:o?.model,toolCalls:o?.toolCalls?.map(s=>({toolName:s.toolName,parameters:s.args,id:s.toolCallId})),toolResults:o?.toolResults?o.toolResults.map(s=>({toolName:s.toolName||"unknown",status:s.status==="error"?"failure":"success",result:s.result,error:s.error})):void 0,analytics:o?.analytics,evaluation:o?.evaluation}}catch(n){throw g.error(`Fake streaming fallback failed for ${this.providerName}:`,n),this.handleProviderError(n)}}applyToolFiltering(e,t){if((!t.toolFilter||t.toolFilter.length===0)&&(!t.excludeTools||t.excludeTools.length===0))return e;let n=Object.keys(e).length,o={...e};if(t.toolFilter&&t.toolFilter.length>0){let i=new Set(t.toolFilter),a={};for(let[l,u]of Object.entries(o))i.has(l)&&(a[l]=u);o=a}if(t.excludeTools&&t.excludeTools.length>0){let i=new Set(t.excludeTools);for(let a of Object.keys(o))i.has(a)&&delete o[a]}let s=Object.keys(o).length;return n!==s&&g.debug("Tool filtering applied",{provider:this.providerName,beforeCount:n,afterCount:s,toolFilter:t.toolFilter,excludeTools:t.excludeTools}),o}async prepareGenerationContext(e){let t=!e.disableTools&&this.supportsTools(),n=t?await this.getAllTools():{},o=t?{...n,...e.tools||{}}:{};o=this.applyToolFiltering(o,e),g.debug("Final tools prepared for AI",{provider:this.providerName,directTools:Hb(n),directToolNames:NL(n),externalTools:Hb(e.tools||{}),externalToolNames:NL(e.tools||{}),totalTools:Hb(o),totalToolNames:NL(o),shouldUseTools:t,timestamp:Date.now()});let s=await this.getAISDKModelWithMiddleware(e);return{tools:o,model:s}}async getToolsForStream(e){if(!(!e.disableTools&&this.supportsTools()))return{};let n=await this.getAllTools(),o=e.tools||{},s={...n,...o};return s=this.applyToolFiltering(s,e),g.debug("Tools prepared for streaming",{provider:this.providerName,baseToolCount:Object.keys(n).length,externalToolCount:Object.keys(o).length,totalToolCount:Object.keys(s).length}),s}async buildMessages(e){return this.messageBuilder.buildMessages(e)}async buildMessagesForStream(e){return this.messageBuilder.buildMessagesForStream(e)}async executeGeneration(e,t,n,o){return this.generationHandler.executeGeneration(e,t,n,o)}logGenerationComplete(e){this.generationHandler.logGenerationComplete(e)}async recordPerformanceMetrics(e,t){await this.telemetryHandler.recordPerformanceMetrics(e,t)}extractToolInformation(e){return this.generationHandler.extractToolInformation(e)}formatEnhancedResult(e,t,n,o,s){return this.generationHandler.formatEnhancedResult(e,t,n,o,s)}analyzeAIResponse(e){this.generationHandler.analyzeAIResponse(e)}async generate(e,t){let n=this.normalizeTextOptions(e);this.validateOptions(n);let o=Date.now(),s=ye.provider.startSpan("neurolink.provider.generate",{kind:er.CLIENT,attributes:{[me.GEN_AI_SYSTEM]:this.providerName||"unknown",[me.GEN_AI_MODEL]:this.modelName||n.model||"unknown",[me.GEN_AI_OPERATION]:"generate",[me.NL_PROVIDER]:this.providerName||"unknown"}}),i=st.setSpan(gr.active(),s),a={ended:!1};return await gr.with(i,async()=>this.runGenerateInActiveContext(n,o,s,a))}async gen(e,t){return this.generate(e,t)}async runGenerateInActiveContext(e,t,n,o){try{if(e.output?.mode==="video")return await this.handleVideoGeneration(e,t);let s=Y3.some(p=>this.modelName.includes(p)),i=e.output?.format==="json"||e.output?.format==="structured"||e.output?.format==="text";if(s&&!i){g.info("Image generation model detected, routing to executeImageGeneration",{provider:this.providerName,model:this.modelName});let p=await this.executeImageGeneration(e);return await this.enhanceResult(p,e,t)}if(e.tts?.enabled&&!e.tts?.useAiResponse)return this.handleDirectTTSSynthesis(e,t);let{tools:a,model:l}=await this.prepareGenerationContext(e),u=await this.buildMessages(e),d=await this.handleVideoFrameGeneration(e,u,l,t);return d||await this.executeStandardGenerateFlow(e,t,l,u,a)}catch(s){throw n.setStatus({code:be.ERROR,message:s instanceof Error?s.message:String(s)}),n.end(),o.ended=!0,br(s)?g.info(`Generate aborted for ${this.providerName}`,{error:s instanceof Error?s.message:String(s)}):g.error(`Generate failed for ${this.providerName}:`,s),this.handleProviderError(s)}finally{o.ended||(n.setStatus({code:be.OK}),n.end())}}async handleDirectTTSSynthesis(e,t){let n=e.prompt??e.input?.text??"",o={content:n,provider:e.provider??this.providerName,model:this.modelName,usage:{input:0,output:0,total:0}};try{if(!e.tts)return this.enhanceResult(o,e,t);o.audio=await dy.synthesize(n,e.provider??this.providerName,e.tts)}catch(s){g.error("TTS synthesis failed in Mode 1 (direct input synthesis):",s)}return this.enhanceResult(o,e,t)}async handleVideoFrameGeneration(e,t,n,o){if(!I8(t))return null;let s=await Jbe(t,{provider:e.provider,providerName:this.providerName,region:e.region}),i=t.filter(u=>u.role==="user").flatMap(u=>Array.isArray(u.content)?u.content.filter(d=>d.type==="text").map(d=>d.text):[typeof u.content=="string"?u.content:""]).filter(Boolean).join(`
1126
+ `)),n}async function _Bt(r,e){let t={timeoutMs:ske,maxBuffer:ike};try{await vR(["-y","-f","concat","-safe","0","-i",r,"-c","copy",e],t)}catch(n){g.warn("Lossless concat failed, falling back to H.264 re-encoding",{error:n instanceof Error?n.message:String(n)}),await vR(["-y","-f","concat","-safe","0","-i",r,"-c:v","libx264","-preset","fast","-crf","18","-c:a","aac","-b:a","192k","-movflags","+faststart",e],t)}}async function pke(r){if(r.length===0)throw new Pt({code:Et.DIRECTOR_MERGE_FAILED,message:"No video buffers provided to merge",category:"validation",severity:"high",retriable:!1});for(let i=0;i<r.length;i++)if(!Q$(r[i]))throw new Pt({code:Et.DIRECTOR_MERGE_FAILED,message:`Clip ${i} is not a valid MP4 buffer (missing ftyp header or too small)`,category:"validation",severity:"high",retriable:!1,context:{clipIndex:i,bufferSize:r[i].length,headerHex:r[i].subarray(0,12).toString("hex")}});if(r.length===1)return r[0];let e=Date.now(),t=await X$("merge"),n=Ln(t,"concat.txt"),o=Ln(t,"merged.mp4"),s=[];try{s=await wBt(r,t,n),await _Bt(n,o);let i=await Uo(o);return g.info("Video merge complete",{inputClips:r.length,totalInputSize:r.reduce((a,l)=>a+l.length,0),outputSize:i.length,elapsedMs:Date.now()-e}),i}catch(i){throw i instanceof Pt?i:new Pt({code:Et.DIRECTOR_MERGE_FAILED,message:`Video merge failed: ${i instanceof Error?i.message:String(i)}`,category:"execution",severity:"high",retriable:!1,context:{clipCount:r.length},originalError:i instanceof Error?i:void 0})}finally{await Y$(t,n,o,...s)}}var mke=A(()=>{"use strict";Q();sX();Ab();pR()});var vke={};le(vke,{DIRECTOR_PIPELINE_TIMEOUT_MS:()=>kBt,executeDirectorPipeline:()=>NBt});async function ABt(r,e){if(Buffer.isBuffer(r))return r;if(typeof r=="string")return r.startsWith("http://")||r.startsWith("https://")?fke(r,e):gke(r,e);if(typeof r=="object"&&"data"in r){let t=r.data;if(Buffer.isBuffer(t))return t;if(typeof t=="string"){if(t.startsWith("http://")||t.startsWith("https://"))return fke(t,e);if(t.startsWith("data:")){let n=t.match(/^data:[^;]+;base64,(.+)$/);if(n&&n[1])return Buffer.from(n[1],"base64");throw new Pt({code:Et.INVALID_INPUT,message:`Invalid data URI format for segment ${e}. Expected format: data:<mime>;base64,<data>`,category:"execution",severity:"high",retriable:!1,context:{segmentIndex:e,dataUriPrefix:t.substring(0,50)}})}try{return await gke(t,e)}catch(n){throw new Pt({code:Et.INVALID_INPUT,message:`Invalid image input for segment ${e}: not a valid URL, file path, or data URI`,category:"execution",severity:"high",retriable:!1,context:{segmentIndex:e,inputType:"string",inputPrefix:t.substring(0,50),fileError:n instanceof Error?n.message:String(n)},originalError:n instanceof Error?n:void 0})}}}throw new Pt({code:Et.INVALID_INPUT,message:`Invalid image type for segment ${e}`,category:"execution",severity:"high",retriable:!1,context:{segmentIndex:e}})}async function fke(r,e){let t=new AbortController,n=setTimeout(()=>t.abort(),EBt);try{let o=await fetch(r,{signal:t.signal});if(!o.ok)throw new Pt({code:Et.INVALID_INPUT,message:`Failed to fetch image for segment ${e}: HTTP ${o.status}`,category:"execution",severity:"high",retriable:o.status>=500,context:{segmentIndex:e,url:r.substring(0,100)}});return Buffer.from(await o.arrayBuffer())}catch(o){throw o instanceof Pt?o:new Pt({code:Et.INVALID_INPUT,message:`Failed to fetch image for segment ${e}: ${o instanceof Error?o.message:String(o)}`,category:"execution",severity:"high",retriable:!0,context:{segmentIndex:e},originalError:o instanceof Error?o:void 0})}finally{clearTimeout(n)}}async function gke(r,e){let{readFile:t}=await Promise.resolve().then(()=>(Qc(),yk));try{return await t(r)}catch(n){throw new Pt({code:Et.INVALID_INPUT,message:`Failed to read image file for segment ${e}: ${n instanceof Error?n.message:String(n)}`,category:"execution",severity:"high",retriable:!1,context:{segmentIndex:e,path:r},originalError:n instanceof Error?n:void 0})}}function hke(r){for(;r.nextExpectedIndex<r.completions.length;){let e=r.completions[r.nextExpectedIndex];if(e.status==="pending")break;e.status==="success"?r.consecutiveFailures=0:(r.consecutiveFailures++,r.consecutiveFailures>=iX&&(r.circuitOpen=!0,g.error(`Circuit breaker tripped after ${iX} consecutive clip failures`))),r.nextExpectedIndex++}}async function IBt(r,e,t,n,o){if(o.circuitOpen)throw new Pt({code:Et.DIRECTOR_CLIP_FAILED,message:`Clip ${e} skipped \u2014 circuit breaker open after ${iX} consecutive failures`,category:"execution",severity:"high",retriable:!0,context:{segmentIndex:e}});let s=Date.now();try{let i=await ABt(r.image,e),a=M$(i);if(a)throw new Pt({code:Et.INVALID_INPUT,message:`Segment ${e} image validation failed: ${a.message}`,category:"execution",severity:"high",retriable:!1,context:{segmentIndex:e,validation:a},originalError:a});let u={buffer:(await JZ(i,r.prompt,t,n)).data,processingTime:Date.now()-s};o.results[e]=u,o.completions[e]={status:"success",result:u},hke(o)}catch(i){let a=i instanceof Error?i:new Error(String(i));throw o.completions[e]={status:"failure",error:a},hke(o),new Pt({code:Et.DIRECTOR_CLIP_FAILED,message:`Clip ${e} generation failed: ${a.message}`,category:"execution",severity:"high",retriable:!0,context:{segmentIndex:e,consecutiveFailures:o.consecutiveFailures},originalError:a})}}async function PBt(r,e,t){let n=cp(e2),o={consecutiveFailures:0,circuitOpen:!1,results:new Array(r.length).fill(null),completions:new Array(r.length).fill({status:"pending"}),nextExpectedIndex:0},s=r.map((l,u)=>n(()=>IBt(l,u,e,t,o))),a=(await Promise.allSettled(s)).filter(l=>l.status==="rejected");if(a.length>0){let l=a[0].reason instanceof Error?a[0].reason:new Error(String(a[0].reason));throw new Pt({code:Et.DIRECTOR_CLIP_FAILED,message:`Director Mode: ${a.length}/${r.length} clip(s) failed. First: ${l.message}`,category:"execution",severity:"high",retriable:!0,context:{failedCount:a.length,totalSegments:r.length,circuitBreakerTripped:o.circuitOpen},originalError:l})}return g.info("All clips generated successfully",{clipCount:r.length,concurrency:e2}),o.results}async function MBt(r,e,t,n,o){let s=r.length-1;if(s===0)return[];let i=cp(e2),a=Array.from({length:s},(l,u)=>i(async()=>{let d=Date.now(),p=e[u]??CBt,m=t[u]??RBt;try{let f=await yke(r[u].buffer,"last",u),h=await yke(r[u+1].buffer,"first",u+1),y=await ZZ(f,h,p,{aspectRatio:n.aspectRatio,resolution:n.resolution,audio:n.audio},m,o);return g.debug(`Transition ${u}\u2192${u+1} generated`,{duration:m,size:y.length,elapsedMs:Date.now()-d}),{buffer:y,fromSegment:u,toSegment:u+1,duration:m,processingTime:Date.now()-d}}catch(f){return g.warn(`Transition ${u}\u2192${u+1} failed, falling back to hard cut`,{error:f instanceof Error?f.message:String(f)}),{buffer:null,fromSegment:u,toSegment:u+1,duration:0,processingTime:Date.now()-d}}}));return Promise.all(a)}async function yke(r,e,t){let n=e==="first"?lke:uke;try{return await n(r)}catch(o){return g.warn(`Frame extraction (${e}) failed for clip ${t}, retrying once`,{error:o instanceof Error?o.message:String(o)}),await n(r)}}async function OBt(r,e){let t=[],n=r.length,o=e.length;for(let s=0;s<n;s++)t.push(r[s].buffer),s<o&&e[s].buffer&&t.push(e[s].buffer);try{return await pke(t)}catch(s){throw new Pt({code:Et.DIRECTOR_MERGE_FAILED,message:`Director Mode merge failed: ${s instanceof Error?s.message:String(s)}`,category:"execution",severity:"high",retriable:!1,context:{clipCount:n,transitionCount:e.filter(i=>i.buffer).length},originalError:s instanceof Error?s:void 0})}}async function NBt(r,e={},t={},n){let o=Date.now(),s=r.length,i=s-1,a=e.length??6,l=t.transitionPrompts??[],u=t.transitionDurations??[];g.info("Starting Director Mode pipeline",{segmentCount:s,transitionCount:i,concurrency:e2,clipDuration:a,resolution:e.resolution??"720p"});let d=await PBt(r,e,n);g.info("Phase 1 complete \u2014 all clips generated",{clipCount:d.length,elapsedMs:Date.now()-o});let p=await MBt(d,l,u,e,n),m=p.filter(k=>k.buffer).length,f=i-m;f>0&&g.warn(`${f}/${i} transition(s) fell back to hard cut`),g.info("Phase 2 complete \u2014 transitions generated",{successful:m,hardCuts:f,elapsedMs:Date.now()-o});let h=await OBt(d,p),y=p.map(k=>k.duration),v=s*a+y.reduce((k,R)=>k+R,0),b=e.resolution??"720p",w=e.aspectRatio??"16:9",T=b==="1080p"?w==="9:16"?{width:1080,height:1920}:{width:1920,height:1080}:w==="9:16"?{width:720,height:1280}:{width:1280,height:720},_=Date.now()-o;return g.info("Director Mode pipeline complete",{totalDuration:v,segmentCount:s,transitionsGenerated:m,hardCuts:f,mergedSize:h.length,processingTime:_}),{data:h,mediaType:"video/mp4",metadata:{duration:v,dimensions:T,model:"veo-3.1-generate-001",provider:"vertex",aspectRatio:w,audioEnabled:e.audio??!0,processingTime:_,segmentCount:s,transitionCount:m,clipDuration:a,transitionDurations:y,segments:d.map((k,R)=>({index:R,duration:a,processingTime:k.processingTime})),transitions:p.map(k=>({fromSegment:k.fromSegment,toSegment:k.toSegment,duration:k.duration,processingTime:k.processingTime}))}}}var e2,iX,EBt,CBt,kBt,RBt,xke=A(()=>{"use strict";fR();Q();hg();Ab();dke();pR();mke();e2=2,iX=2,EBt=15e3,CBt="Smooth cinematic transition between scenes",kBt=6e5,RBt=4});var an,xc=A(()=>{"use strict";Ht();Tn();uD();Nd();H5();Ta();bt();Q();Qa();WC();DL();gk();Zbe();Qbe();xEe();DEe();ACe();ICe();MCe();an=class{modelName;providerName;defaultTimeout=3e4;middlewareOptions;directTools=Eb()?{}:_f;mcpTools;customTools;toolExecutor;sessionId;userId;neurolink;_traceContext=null;setTraceContext(e){this._traceContext=e}messageBuilder;streamHandler;generationHandler;telemetryHandler;utilities;toolsManager;constructor(e,t,n,o){this.modelName=e||this.getDefaultModel(),this.providerName=t||this.getProviderName(),this.neurolink=n,this.middlewareOptions=o,this.messageBuilder=new P$(this.providerName,this.modelName),this.streamHandler=new O$(this.providerName,this.modelName),this.telemetryHandler=new j$(this.providerName,this.modelName,this.neurolink),this.generationHandler=new q1(this.providerName,this.modelName,()=>this.supportsTools(),(s,i)=>this.telemetryHandler.getTelemetryConfig(s,i),(s,i,a,l)=>this.handleToolExecutionStorage(s,i,a,l),()=>this.neurolink?.getEventEmitter()),this.utilities=new V$(this.providerName,this.modelName,this.defaultTimeout,this.middlewareOptions),this.toolsManager=new G$(this.providerName,this.directTools,this.neurolink,{isZodSchema:s=>this.isZodSchema(s),convertToolResult:s=>this.convertToolResult(s),createPermissiveZodSchema:()=>this.createPermissiveZodSchema(),fixSchemaForOpenAIStrictMode:s=>this.fixSchemaForOpenAIStrictMode(s)})}supportsTools(){return!0}async stream(e,t){let n=this.normalizeStreamOptions(e);if(g.info("Starting stream",{provider:this.providerName,hasTools:!n.disableTools&&this.supportsTools(),disableTools:!!n.disableTools,supportsTools:this.supportsTools(),inputLength:n.input?.text?.length||0,maxTokens:n.maxTokens,temperature:n.temperature,timestamp:Date.now()}),!!n.input?.files?.length||!!n.input?.videoFiles?.length){let a=await this.buildMessagesForStream(n);if(I8(a))return g.info("Video frames detected in stream, using fake streaming for video analysis",{provider:this.providerName,model:this.modelName}),await this.executeFakeStreaming(n,t)}let s=Y3.some(a=>this.modelName.includes(a)),i=n.output?.format==="json"||n.output?.format==="structured"||n.output?.format==="text";if(s&&!i)return g.info("Image model detected, forcing fake streaming",{provider:this.providerName,model:this.modelName,reason:"Image generation requires fake streaming to yield image output"}),await this.executeFakeStreaming(n,t);if(!n.disableTools&&this.supportsTools()){let a=await this.getToolsForStream(n);n={...n,tools:a}}else n={...n,tools:{}};try{g.debug("Attempting real streaming",{provider:this.providerName,timestamp:Date.now()});let a=await this.executeStream(n,t);return g.info("Real streaming succeeded",{provider:this.providerName,timestamp:Date.now()}),a}catch(a){let l=a instanceof Error?a.message:String(a);if((a instanceof Error?a.name:"")==="AbortError"||l.includes("abort")||l.includes("timeout")||l.includes("401")||l.includes("403")||l.includes("quota")||l.includes("rate limit")||l.includes("authentication"))throw this.handleProviderError(a);if(g.warn(`Real streaming failed for ${this.providerName}, falling back to fake streaming:`,{error:l,timestamp:Date.now()}),!n.disableTools&&this.supportsTools())return await this.executeFakeStreaming(n,t);throw g.error(`Real streaming failed for ${this.providerName}:`,a),this.handleProviderError(a)}}async executeFakeStreaming(e,t){try{g.info("Starting fake streaming with tools",{provider:this.providerName,supportsTools:this.supportsTools(),timestamp:Date.now()});let n={prompt:e.input?.text||"",input:e.input,systemPrompt:e.systemPrompt,temperature:e.temperature,maxTokens:e.maxTokens,tools:e.tools,disableTools:!!e.disableTools,maxSteps:e.maxSteps||5,provider:e.provider,model:e.model,region:e.region,enableAnalytics:e.enableAnalytics,enableEvaluation:e.enableEvaluation,evaluationDomain:e.evaluationDomain,toolUsageContext:e.toolUsageContext,context:e.context,csvOptions:e.csvOptions,abortSignal:e.abortSignal,toolFilter:e.toolFilter,excludeTools:e.excludeTools,skipToolPromptInjection:e.skipToolPromptInjection,timeout:e.timeout};g.debug("Calling generate for fake streaming",{provider:this.providerName,maxSteps:n.maxSteps,disableTools:n.disableTools,timestamp:Date.now()});let o=await this.generate(n,t);return g.info("Generate completed for fake streaming",{provider:this.providerName,hasContent:!!o?.content,contentLength:o?.content?.length||0,toolsUsed:o?.toolsUsed?.length||0,hasImageOutput:!!o?.imageOutput,timestamp:Date.now()}),{stream:(async function*(){if(o?.content){let s=o.content.split(/(\s+)/),i="";for(let a=0;a<s.length;a++)i+=s[a],(a===s.length-1||i.length>50||/[.!?;,]\s*$/.test(i))&&i.trim()&&(yield{content:i},i="",await new Promise(u=>{setTimeout(u,Math.random()*9+1)}));i.trim()&&(yield{content:i})}o?.imageOutput&&(yield{type:"image",imageOutput:o.imageOutput})})(),usage:o?.usage,provider:o?.provider,model:o?.model,toolCalls:o?.toolCalls?.map(s=>({toolName:s.toolName,parameters:s.args,id:s.toolCallId})),toolResults:o?.toolResults?o.toolResults.map(s=>({toolName:s.toolName||"unknown",status:s.status==="error"?"failure":"success",result:s.result,error:s.error})):void 0,analytics:o?.analytics,evaluation:o?.evaluation}}catch(n){throw g.error(`Fake streaming fallback failed for ${this.providerName}:`,n),this.handleProviderError(n)}}applyToolFiltering(e,t){if((!t.toolFilter||t.toolFilter.length===0)&&(!t.excludeTools||t.excludeTools.length===0))return e;let n=Object.keys(e).length,o={...e};if(t.toolFilter&&t.toolFilter.length>0){let i=new Set(t.toolFilter),a={};for(let[l,u]of Object.entries(o))i.has(l)&&(a[l]=u);o=a}if(t.excludeTools&&t.excludeTools.length>0){let i=new Set(t.excludeTools);for(let a of Object.keys(o))i.has(a)&&delete o[a]}let s=Object.keys(o).length;return n!==s&&g.debug("Tool filtering applied",{provider:this.providerName,beforeCount:n,afterCount:s,toolFilter:t.toolFilter,excludeTools:t.excludeTools}),o}async prepareGenerationContext(e){let t=!e.disableTools&&this.supportsTools(),n=t?await this.getAllTools():{},o=t?{...n,...e.tools||{}}:{};o=this.applyToolFiltering(o,e),g.debug("Final tools prepared for AI",{provider:this.providerName,directTools:Hb(n),directToolNames:NL(n),externalTools:Hb(e.tools||{}),externalToolNames:NL(e.tools||{}),totalTools:Hb(o),totalToolNames:NL(o),shouldUseTools:t,timestamp:Date.now()});let s=await this.getAISDKModelWithMiddleware(e);return{tools:o,model:s}}async getToolsForStream(e){if(!(!e.disableTools&&this.supportsTools()))return{};let n=await this.getAllTools(),o=e.tools||{},s={...n,...o};return s=this.applyToolFiltering(s,e),g.debug("Tools prepared for streaming",{provider:this.providerName,baseToolCount:Object.keys(n).length,externalToolCount:Object.keys(o).length,totalToolCount:Object.keys(s).length}),s}async buildMessages(e){return this.messageBuilder.buildMessages(e)}async buildMessagesForStream(e){return this.messageBuilder.buildMessagesForStream(e)}async executeGeneration(e,t,n,o){return this.generationHandler.executeGeneration(e,t,n,o)}logGenerationComplete(e){this.generationHandler.logGenerationComplete(e)}async recordPerformanceMetrics(e,t){await this.telemetryHandler.recordPerformanceMetrics(e,t)}extractToolInformation(e){return this.generationHandler.extractToolInformation(e)}formatEnhancedResult(e,t,n,o,s){return this.generationHandler.formatEnhancedResult(e,t,n,o,s)}analyzeAIResponse(e){this.generationHandler.analyzeAIResponse(e)}async generate(e,t){let n=this.normalizeTextOptions(e);this.validateOptions(n);let o=Date.now(),s=ye.provider.startSpan("neurolink.provider.generate",{kind:er.CLIENT,attributes:{[me.GEN_AI_SYSTEM]:this.providerName||"unknown",[me.GEN_AI_MODEL]:this.modelName||n.model||"unknown",[me.GEN_AI_OPERATION]:"generate",[me.NL_PROVIDER]:this.providerName||"unknown"}}),i=st.setSpan(gr.active(),s),a={ended:!1};return await gr.with(i,async()=>this.runGenerateInActiveContext(n,o,s,a))}async gen(e,t){return this.generate(e,t)}async runGenerateInActiveContext(e,t,n,o){try{if(e.output?.mode==="video")return await this.handleVideoGeneration(e,t);let s=Y3.some(p=>this.modelName.includes(p)),i=e.output?.format==="json"||e.output?.format==="structured"||e.output?.format==="text";if(s&&!i){g.info("Image generation model detected, routing to executeImageGeneration",{provider:this.providerName,model:this.modelName});let p=await this.executeImageGeneration(e);return await this.enhanceResult(p,e,t)}if(e.tts?.enabled&&!e.tts?.useAiResponse)return this.handleDirectTTSSynthesis(e,t);let{tools:a,model:l}=await this.prepareGenerationContext(e),u=await this.buildMessages(e),d=await this.handleVideoFrameGeneration(e,u,l,t);return d||await this.executeStandardGenerateFlow(e,t,l,u,a)}catch(s){throw n.setStatus({code:be.ERROR,message:s instanceof Error?s.message:String(s)}),n.end(),o.ended=!0,br(s)?g.info(`Generate aborted for ${this.providerName}`,{error:s instanceof Error?s.message:String(s)}):g.error(`Generate failed for ${this.providerName}:`,s),this.handleProviderError(s)}finally{o.ended||(n.setStatus({code:be.OK}),n.end())}}async handleDirectTTSSynthesis(e,t){let n=e.prompt??e.input?.text??"",o={content:n,provider:e.provider??this.providerName,model:this.modelName,usage:{input:0,output:0,total:0}};try{if(!e.tts)return this.enhanceResult(o,e,t);o.audio=await dy.synthesize(n,e.provider??this.providerName,e.tts)}catch(s){g.error("TTS synthesis failed in Mode 1 (direct input synthesis):",s)}return this.enhanceResult(o,e,t)}async handleVideoFrameGeneration(e,t,n,o){if(!I8(t))return null;if(e.schema!==void 0||e.output?.format!==void 0)return g.info("[VideoFrameGen] Skipping video-frame analysis route; caller requested structured output",{provider:this.providerName,model:this.modelName,hasSchema:e.schema!==void 0,outputFormat:e.output?.format}),null;let s=await Jbe(t,{provider:e.provider,providerName:this.providerName,region:e.region}),i=t.filter(u=>u.role==="user").flatMap(u=>Array.isArray(u.content)?u.content.filter(d=>d.type==="text").map(d=>d.text):[typeof u.content=="string"?u.content:""]).filter(Boolean).join(`
1127
1127
  `).trim(),a=s,l={input:0,output:0,total:0};if(e.systemPrompt)try{let u=i?`The user asked: "${i}"
1128
1128
 
1129
1129
  Here is the video/image analysis result from the visual analysis system:
@@ -1911,7 +1911,7 @@ Troubleshooting:
1911
1911
  1. Check Google Cloud credentials and permissions
1912
1912
  2. Verify project ID and location settings
1913
1913
  3. Ensure Vertex AI API is enabled
1914
- 4. Check network connectivity`,this.providerName)}static evictLRUCacheEntries(e){if(e.size<=r.MAX_CACHE_SIZE)return;let t=e.size-r.MAX_CACHE_SIZE+5,n=0;for(let o of e.keys()){if(n>=t)break;e.delete(o),n++}g.debug("GoogleVertexProvider: Evicted LRU cache entries",{entriesRemoved:n,currentCacheSize:e.size})}static accessCacheEntry(e,t){let n=e.get(t);return n!==void 0&&(e.delete(t),e.set(t,n)),n}shouldSetMaxTokensCached(e){let t=Date.now();t-r.maxTokensCacheTime>r.CACHE_DURATION&&(r.maxTokensCache.clear(),r.maxTokensCacheTime=t);let n=r.accessCacheEntry(r.maxTokensCache,e);if(n!==void 0)return n;let o=!this.modelHasMaxTokensIssues(e);return r.maxTokensCache.set(e,o),r.evictLRUCacheEntries(r.maxTokensCache),o}modelHasMaxTokensIssues(e){let t=Date.now(),n="google-vertex-config";if(t-r.modelConfigCacheTime>r.CACHE_DURATION){r.modelConfigCache.clear();let a=yS.getInstance().getProviderConfiguration("google-vertex");r.modelConfigCache.set(n,a),r.modelConfigCacheTime=t}return(r.accessCacheEntry(r.modelConfigCache,n)?.modelBehavior?.maxTokensIssues||["gemini-2.5-flash","gemini-2.5-pro"]).some(i=>e.includes(i))}async hasAnthropicSupport(){return Kee()}resolveModelAlias(e){return DB[e]??e}async createAnthropicModel(e){let t=`anthropic-validation-${Date.now()}-${Math.random().toString(36).substring(2,11)}`;if(g.debug("[GoogleVertexProvider] \u{1F9E0} Starting comprehensive Anthropic model validation",{validationId:t,modelName:e,timestamp:new Date().toISOString()}),!Kee())return g.error("[GoogleVertexProvider] \u274C SDK module validation failed",{validationId:t,issue:"createVertexAnthropic function not available",solution:"Update @ai-sdk/google-vertex to latest version with Anthropic support",command:"npm install @ai-sdk/google-vertex@latest",documentation:"https://sdk.vercel.ai/providers/ai-sdk-providers/google-vertex#anthropic-models"}),null;let o=this.credentials&&(this.credentials.apiKey||this.credentials.clientEmail||this.credentials.privateKey||this.credentials.serviceAccountKey)?{isValid:!0,method:"per_request_credentials",issues:[]}:await this.validateVertexAuthentication();if(!o.isValid)return g.error("[GoogleVertexProvider] \u274C Authentication validation failed",{validationId:t,method:o.method,issues:o.issues,solutions:["Option 1: Set GOOGLE_APPLICATION_CREDENTIALS to valid service account OR ADC file","Option 2: Set individual env vars: GOOGLE_AUTH_CLIENT_EMAIL, GOOGLE_AUTH_PRIVATE_KEY","Option 3: Use gcloud auth application-default login for ADC","Documentation: https://cloud.google.com/docs/authentication/provide-credentials-adc"]}),null;let s=await this.validateVertexProjectConfiguration();if(!s.isValid)return g.error("[GoogleVertexProvider] \u274C Project configuration validation failed",{validationId:t,projectId:s.projectId,region:s.region,issues:s.issues,solutions:["Set GOOGLE_VERTEX_PROJECT or GOOGLE_CLOUD_PROJECT environment variable","Ensure project exists and has Vertex AI API enabled","Check: https://console.cloud.google.com/apis/library/aiplatform.googleapis.com"]}),null;await this.checkVertexRegionalSupport(s.region)||g.warn("[GoogleVertexProvider] \u26A0\uFE0F Regional support warning",{validationId:t,region:s.region,warning:"Anthropic models may not be available in this region",supportedRegions:["us-central1","us-east4","us-east5","us-west1","us-west4","europe-west1","europe-west4","asia-southeast1","asia-northeast1"],solution:"Set GOOGLE_CLOUD_LOCATION to a supported region"});let a=this.validateAnthropicModelName(e);if(!a.isValid)return g.error("[GoogleVertexProvider] \u274C Model name validation failed",{validationId:t,modelName:e,issue:a.issue,recommendedModels:["claude-sonnet-4-6","claude-opus-4-6","claude-sonnet-4-5@20250929","claude-opus-4@20250514","claude-3-5-sonnet-20241022"]}),null;try{g.debug("[GoogleVertexProvider] \u{1F527} Creating vertexAnthropic settings",{validationId:t,authMethod:o.method,projectId:s.projectId,region:s.region});let l=await C7t(this.location,this.credentials);if(!l.project||!l.location)return g.error("[GoogleVertexProvider] \u274C Settings validation failed",{validationId:t,hasProject:!!l.project,hasLocation:!!l.location,hasProxy:!!l.fetch,hasAuth:!!l.googleAuthOptions}),null;g.debug("[GoogleVertexProvider] \u2705 Creating vertexAnthropic instance",{validationId:t,modelName:e,project:l.project,location:l.location,hasProxy:!!l.fetch,hasAuth:!!l.googleAuthOptions});let d=lA(l)(e);return g.info("[GoogleVertexProvider] \u2705 Anthropic model created successfully",{validationId:t,modelName:e,hasModel:!!d,modelType:typeof d,authMethod:o.method,projectId:s.projectId,region:s.region,validationsPassed:["SDK_MODULE_AVAILABLE","AUTHENTICATION_VALID","PROJECT_CONFIGURED","MODEL_NAME_VALID","SETTINGS_CREATED","PROVIDER_INSTANCE_CREATED","MODEL_INSTANCE_CREATED"]}),d}catch(l){let u=this.analyzeAnthropicCreationError(l,{validationId:t,modelName:e,projectId:s.projectId,region:s.region,authMethod:o.method});return g.error("[GoogleVertexProvider] \u274C Anthropic model creation failed",{validationId:t,modelName:e,...u,detailedTroubleshooting:this.getAnthropicTroubleshootingSteps(u)}),null}}async validateVertexAuthentication(){let e={isValid:!1,method:"none",issues:[]};try{if(process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK||process.env.GOOGLE_APPLICATION_CREDENTIALS){let t=process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK?process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK:process.env.GOOGLE_APPLICATION_CREDENTIALS||"";try{if(xo.existsSync(t)){let n=xo.readFileSync(t,"utf8"),o=JSON.parse(n);if(o.type==="service_account"&&o.project_id&&o.client_email&&o.private_key)return e.isValid=!0,e.method="service_account_file",e;if(o.client_id&&o.client_secret&&o.refresh_token&&o.type!=="service_account")return e.isValid=!0,e.method="application_default_credentials",e;e.issues.push("Credentials file missing required fields (not service account or ADC format)")}else e.issues.push(`Service account file not found: ${t}`)}catch(n){e.issues.push(`Service account file validation failed: ${n}`)}}if(process.env.GOOGLE_AUTH_CLIENT_EMAIL&&process.env.GOOGLE_AUTH_PRIVATE_KEY){let t=process.env.GOOGLE_AUTH_CLIENT_EMAIL,n=process.env.GOOGLE_AUTH_PRIVATE_KEY;if(t.includes("@")&&n.includes("BEGIN PRIVATE KEY"))return e.isValid=!0,e.method="environment_variables",e;e.issues.push("Individual credentials format validation failed")}else e.issues.push("Missing individual credential environment variables");e.isValid||e.issues.push("No valid authentication method found")}catch(t){e.issues.push(`Authentication validation error: ${t}`)}return e}async validateVertexProjectConfiguration(){let e={isValid:!1,projectId:void 0,region:void 0,issues:[]},t=process.env.GOOGLE_VERTEX_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID||process.env.GOOGLE_PROJECT_ID||process.env.GOOGLE_CLOUD_PROJECT;t?(e.projectId=t,/^[a-z][a-z0-9-]{4,28}[a-z0-9]$/.test(t)?e.isValid=!0:e.issues.push(`Invalid project ID format: ${t}`)):e.issues.push("No project ID configured");let n=process.env.GOOGLE_CLOUD_LOCATION||process.env.VERTEX_LOCATION||process.env.GOOGLE_VERTEX_LOCATION||"us-central1";return e.region=n,/^([a-z]+-[a-z]+\d+|global)$/.test(n)||(e.issues.push(`Invalid region format: ${n} (expected format: 'us-central1' or 'global')`),e.isValid=!1),e}async checkVertexRegionalSupport(e="us-central1"){return["global","us-central1","us-east1","us-east4","us-east5","us-south1","us-west1","us-west4","northamerica-northeast1","northamerica-northeast2","europe-west1","europe-west2","europe-west3","europe-west4","europe-west6","europe-west8","europe-west9","europe-north1","europe-central2","europe-southwest1","asia-east1","asia-east2","asia-northeast1","asia-northeast2","asia-northeast3","asia-south1","asia-southeast1","asia-southeast2","australia-southeast1","australia-southeast2","me-west1","me-central1","africa-south1","southamerica-east1","southamerica-west1"].includes(e)}validateAnthropicModelName(e){return!e||typeof e!="string"?{isValid:!1,issue:"Model name is required and must be a string"}:e.toLowerCase().includes("claude")?[/^claude-opus-4-6$/,/^claude-sonnet-4-6$/,/^claude-sonnet-4@\d{8}$/,/^claude-sonnet-4-5@\d{8}$/,/^claude-opus-4@\d{8}$/,/^claude-opus-4-1@\d{8}$/,/^claude-opus-4-5@\d{8}$/,/^claude-haiku-4-5@\d{8}$/,/^claude-3-7-sonnet@\d{8}$/,/^claude-3-5-sonnet-\d{8}$/,/^claude-3-5-haiku-\d{8}$/,/^claude-3-sonnet-\d{8}$/,/^claude-3-haiku-\d{8}$/,/^claude-3-opus-\d{8}$/].some(o=>o.test(e))?{isValid:!0}:{isValid:!1,issue:'Model name format not recognized. Expected formats like "claude-3-5-sonnet-20241022" or "claude-sonnet-4@20250514"'}:{isValid:!1,issue:'Model name must be a Claude model (should contain "claude")'}}analyzeAnthropicCreationError(e,t){let n=e instanceof Error?e.message:String(e),o=e instanceof Error?e.name:"UnknownError",s={error:n,errorName:o,errorType:"UNKNOWN",isNetworkError:!1,isAuthError:!1,isConfigurationError:!1,isModelError:!1,isRegionalError:!1,specificIssue:"Unknown error occurred",errorStack:e instanceof Error?e.stack:void 0};return n.includes("ETIMEDOUT")||n.includes("ECONNREFUSED")||n.includes("ENOTFOUND")||n.includes("timeout")?(s.errorType="NETWORK",s.isNetworkError=!0,s.specificIssue="Network connectivity issue - cannot reach Google Cloud endpoints"):n.includes("PERMISSION_DENIED")||n.includes("401")||n.includes("403")||n.includes("Unauthorized")||n.includes("Forbidden")?(s.errorType="AUTHENTICATION",s.isAuthError=!0,s.specificIssue="Authentication failed - invalid credentials or insufficient permissions"):n.includes("NOT_FOUND")||n.includes("404")||n.includes("model")&&n.includes("not available")?(s.errorType="MODEL_AVAILABILITY",s.isModelError=!0,s.specificIssue=`Model "${t.modelName}" not available in region "${t.region}"`):n.includes("QUOTA_EXCEEDED")||n.includes("quota")||n.includes("limit")?(s.errorType="QUOTA",s.isRegionalError=!0,s.specificIssue="Quota exceeded or rate limit reached"):(n.includes("INVALID_ARGUMENT")||n.includes("BadRequest")||n.includes("400"))&&(s.errorType="CONFIGURATION",s.isConfigurationError=!0,s.specificIssue="Invalid configuration or request parameters"),s}getAnthropicTroubleshootingSteps(e){let t=[];switch(e.errorType){case"NETWORK":t.push("\u{1F310} Network Troubleshooting:","1. Check internet connectivity","2. Verify proxy configuration if behind corporate firewall","3. Ensure firewall allows HTTPS to *.googleapis.com","4. Try different network or wait for network issues to resolve","5. Check if using VPN that might block Google Cloud endpoints");break;case"AUTHENTICATION":t.push("\u{1F510} Authentication Troubleshooting:","1. Verify GOOGLE_APPLICATION_CREDENTIALS file exists and is valid","2. Check individual credentials: GOOGLE_AUTH_CLIENT_EMAIL, GOOGLE_AUTH_PRIVATE_KEY",'3. Ensure service account has "Vertex AI User" role',"4. Verify project ID matches the one in your credentials","5. Enable Vertex AI API: https://console.cloud.google.com/apis/library/aiplatform.googleapis.com");break;case"MODEL_AVAILABILITY":t.push("\u{1F916} Model Availability Troubleshooting:","1. Verify model name format and spelling","2. Check if Anthropic integration is enabled in your project","3. Enable Claude models: https://console.cloud.google.com/vertex-ai/publishers/anthropic","4. Try a different region if current region lacks Anthropic support","5. Accept Anthropic terms and conditions in Google Cloud Console");break;case"QUOTA":t.push("\u{1F4CA} Quota Troubleshooting:","1. Check Vertex AI quotas in Google Cloud Console","2. Request quota increase if needed","3. Try a different model with lower resource requirements","4. Wait before retrying if rate limited","5. Consider using a different region with available quota");break;case"CONFIGURATION":t.push("\u2699\uFE0F Configuration Troubleshooting:","1. Verify all required environment variables are set","2. Check project ID and region format","3. Ensure model name follows correct format","4. Verify request parameters are within model limits","5. Update @ai-sdk/google-vertex to latest version");break;default:t.push("\u{1F527} General Troubleshooting:","1. Update @ai-sdk/google-vertex to latest version","2. Check Google Cloud service status","3. Verify all authentication and configuration","4. Try with a simple Claude model like claude-3-haiku-20240307","5. Enable debug logging with NEUROLINK_DEBUG=true")}return t}registerTool(e,t,n,o){let s="GoogleVertexProvider.registerTool";try{let i={description:n,parameters:t,execute:async a=>{try{let l={...a,__context:this.toolContext};return await o(l)}catch(l){throw g.error(`${s}: Tool execution error`,{toolName:e,error:l instanceof Error?l.message:String(l)}),l}}};this.registeredTools.set(e,i),g.debug(`${s}: Tool registered`,{toolName:e,modelName:this.modelName})}catch(i){throw g.error(`${s}: Tool registration error`,{toolName:e,error:i instanceof Error?i.message:String(i)}),i}}setToolContext(e){this.toolContext={...this.toolContext,...e},g.debug("GoogleVertexProvider.setToolContext: Tool context set",{contextKeys:Object.keys(e)})}getToolContext(){return{...this.toolContext}}setToolExecutor(e){this.toolExecutor=e,g.debug("GoogleVertexProvider.setToolExecutor: Tool executor set",{hasExecutor:typeof e=="function"})}static clearCaches(){r.modelConfigCache.clear(),r.maxTokensCache.clear(),r.modelConfigCacheTime=0,r.maxTokensCacheTime=0,g.debug("GoogleVertexProvider: All caches cleared",{clearedAt:Date.now()})}static getCacheStats(){let e=Date.now();return{modelConfigCacheSize:r.modelConfigCache.size,maxTokensCacheSize:r.maxTokensCache.size,maxCacheSize:r.MAX_CACHE_SIZE,cacheAge:{modelConfig:e-r.modelConfigCacheTime,maxTokens:e-r.maxTokensCacheTime}}}detectImageType(e){return e.length>=8&&e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71?"image/png":e.length>=3&&e[0]===255&&e[1]===216&&e[2]===255?"image/jpeg":e.length>=12&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80?"image/webp":e.length>=6&&e[0]===71&&e[1]===73&&e[2]===70?"image/gif":"image/png"}estimateTokenCount(e){return fr(e,"vertex")}async getImageGenerationAccessToken(){let{GoogleAuth:o}=await Promise.resolve().then(()=>(dR(),HZ)),s=process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK||process.env.GOOGLE_APPLICATION_CREDENTIALS;for(let i=1;i<=3;i++){let a=new AbortController,l=setTimeout(()=>{a.abort(),g.warn(`[GoogleVertexProvider] Auth token refresh exceeded 15000ms timeout (attempt ${i}/3)`)},15e3);try{let p=await(await new o({...s&&{keyFilename:s},scopes:["https://www.googleapis.com/auth/cloud-platform"]}).getClient()).getAccessToken();if(!p.token)throw new kn("Failed to obtain access token from Google Auth",this.providerName);return p.token}catch(u){let d=u;if(!(a.signal.aborted||d?.code==="ECONNRESET"||d?.code==="ETIMEDOUT"||d?.code==="ENOTFOUND"||d?.message?.includes("socket hang up")||d?.message?.includes("network socket disconnected"))||i===3)throw u;let m=500*2**(i-1);g.warn(`[GoogleVertexProvider] Auth token transient error (${d?.code||d?.message}), retrying in ${m}ms (attempt ${i}/3)`),await new Promise(f=>setTimeout(f,m))}finally{clearTimeout(l)}}throw new kn("Failed to obtain access token after retries",this.providerName)}async buildImageGenerationParts(e,t,n){let o=[];e&&o.push({text:e});for(let s of t){let i;if(Buffer.isBuffer(s))i=s.toString("base64");else if(typeof s=="string")if(s.startsWith("/")||/^[a-zA-Z]:\\/.test(s)||s.startsWith("./")||s.startsWith("../")||s.startsWith("..\\")||s.startsWith(".\\")){let l=jc.resolve(s),u=process.cwd();if(!l.startsWith(u+jc.sep)&&l!==u)throw new ur("PDF file path must be within current directory for security",this.providerName);if(!xo.existsSync(l))throw new ur(`PDF file not found: ${l}`,this.providerName);i=xo.readFileSync(l).toString("base64")}else i=s;else{g.warn("Invalid PDF file format, skipping",{type:typeof s});continue}o.push({inlineData:{mimeType:"application/pdf",data:i}}),g.debug("Added PDF file to request",{dataLength:i.length})}for(let s=0;s<n.length;s++){let i=n[s],a,l;if(Buffer.isBuffer(i))a=i.toString("base64"),l=this.detectImageType(i);else if(typeof i=="string")if(i.startsWith("/")||/^[a-zA-Z]:\\/.test(i)||i.startsWith("./")||i.startsWith("../")||i.startsWith("..\\")||i.startsWith(".\\")){let d=jc.resolve(i);if(!xo.existsSync(d)){g.warn(`Image file not found: ${d}, skipping`);continue}let p=xo.readFileSync(d);a=p.toString("base64"),l=this.detectImageType(p)}else if(i.startsWith("data:")){let d=i.match(/^data:([^;]+);base64,(.+)$/);if(d)l=d[1],a=d[2];else{g.warn("Invalid data URL format, skipping image",{index:s});continue}}else if(i.startsWith("http://")||i.startsWith("https://"))try{let p=new URL(i).hostname;if(["localhost","127.0.0.1","0.0.0.0","[::1]"].some(v=>p===v)||/^(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.)/.test(p)){g.warn(`[GoogleVertexProvider] Blocked fetch to private/local URL: ${p}`,{index:s});continue}try{let{resolve4:v,resolve6:b}=RB.promises,w=[];try{w.push(...await v(p))}catch{}try{w.push(...await b(p))}catch{}if(w.length>0&&w.every(T=>w7t(T))){g.warn(`[GoogleVertexProvider] Blocked fetch: hostname ${p} resolves to private/loopback address`,{index:s,addresses:w});continue}}catch(v){g.warn(`[GoogleVertexProvider] DNS resolution failed for ${p}, blocking fetch`,{index:s,error:v instanceof Error?v.message:String(v)});continue}let f=await fetch(i,{signal:AbortSignal.timeout(15e3)});if(!f.ok){g.warn(`Failed to fetch image URL (${f.status}), skipping`,{index:s,url:i});continue}let h=f.headers.get("content-length");if(h&&Number(h)>OB){g.warn(`[GoogleVertexProvider] Image URL exceeds ${OB} byte limit (Content-Length: ${h}), skipping`,{index:s,url:i});continue}let y=Buffer.from(await f.arrayBuffer());if(y.byteLength>OB){g.warn(`[GoogleVertexProvider] Downloaded image exceeds ${OB} byte limit (${y.byteLength} bytes), skipping`,{index:s,url:i});continue}a=y.toString("base64"),l=this.detectImageType(y)}catch(d){g.warn(`Failed to download image from URL, skipping: ${d instanceof Error?d.message:String(d)}`,{index:s,url:i});continue}else{a=i;let d=Buffer.from(a,"base64");l=this.detectImageType(d)}else{g.warn("Invalid image format, skipping",{type:typeof i,index:s});continue}o.push({inlineData:{mimeType:l,data:a}}),g.debug("Added image to request",{index:s,mimeType:l,dataLength:a.length})}return o}parseImageGenerationResponse(e,t){let n=e.candidates?.[0];if(!n?.content?.parts)throw new ur("No content parts in Vertex AI response",this.providerName);let o=n.content.parts.find(a=>(a.inlineData||a.inline_data)&&(a.inlineData&&a.inlineData.mimeType||a.inline_data&&a.inline_data.mime_type)&&(a.inlineData&&a.inlineData.mimeType?.startsWith("image/")||a.inline_data&&a.inline_data.mime_type?.startsWith("image/")));if(!o){let a=n.content.parts.some(l=>l.text);throw new ur(a?`Image generation completed but model returned text instead of image data. Model: ${t}`:`Image generation completed but no image data was returned. Model: ${t}`,this.providerName)}let s=o.inlineData?.data||o.inline_data?.data,i=o.inlineData?.mimeType||o.inline_data?.mime_type||"image/png";if(!s)throw new ur("Image part found but no data available",this.providerName);return{imageData:s,mimeType:i}}async executeImageGeneration(e){let t=e.prompt||e.input?.text||"",n=e.input?.pdfFiles||[],o=e.input?.images||[],s=n.length>0,i=o.length>0;if(!t.trim()&&!s&&!i)throw new ur("Image generation requires either a prompt, PDF file, or image as input",this.providerName);let a=e.model||this.modelName||"gemini-3-pro-image-preview";s&&!a.includes("gemini-3-pro-image")&&(a="gemini-3-pro-image-preview");let l=process.env.GOOGLE_VERTEX_IMAGE_LOCATION||"global",d=Jfe.some(m=>a.includes(m)||m.includes(a))?l:this.location,p=Date.now();g.info("\u{1F3A8} Starting Vertex AI image generation (REST API)",{model:a,prompt:t.substring(0,100),provider:this.providerName,projectId:this.projectId,location:d,hasPdfInput:s,pdfCount:n.length,hasImageInput:i,imageCount:o.length});try{let m=await this.getImageGenerationAccessToken(),h={contents:[{role:"user",parts:await this.buildImageGenerationParts(t,n,o)}],generation_config:{response_modalities:["TEXT","IMAGE"],temperature:e.temperature||.7,candidate_count:1}},y;d==="global"?y=`https://aiplatform.googleapis.com/v1/projects/${this.projectId}/locations/global/publishers/google/models/${a}:generateContent`:y=`https://${d}-aiplatform.googleapis.com/v1/projects/${this.projectId}/locations/${d}/publishers/google/models/${a}:generateContent`,g.debug("Making REST API call to Vertex AI",{url:y,model:a,hasAccessToken:!0});let v=12e4,b=fetch(y,{method:"POST",headers:{Authorization:`Bearer ${m}`,"Content-Type":"application/json"},body:JSON.stringify(h)}),w=new Promise((C,E)=>{setTimeout(()=>{E(new zr(`Vertex AI image generation timed out after ${v}ms`,v))},v)}),T=await Promise.race([b,w]);if(!T.ok){let C=await T.text();throw new ur(`Vertex AI API error (${T.status}): ${C}`,this.providerName)}let _=await T.json(),{imageData:k,mimeType:R}=this.parseImageGenerationResponse(_,a);g.info("Image generation successful",{model:a,mimeType:R,dataLength:k.length,responseTime:Date.now()-p});let I={content:`Generated image using ${a} (${R})`,imageOutput:{base64:k},provider:this.providerName,model:a,usage:{input:this.estimateTokenCount(t),output:0,total:this.estimateTokenCount(t)}};return await this.enhanceResult(I,e,p)}catch(m){throw g.error("Image generation failed",{error:m instanceof Error?m.message:String(m),model:a,prompt:t.substring(0,100)}),this.handleProviderError(m)}}async embed(e,t){let n=t||"text-embedding-004";g.debug("Generating embedding",{provider:this.providerName,model:n,textLength:e.length});try{let o=await NB(this.location,this.credentials),i=NA(o).textEmbeddingModel(n),a=await Gh({model:i,value:e});return g.debug("Embedding generated successfully",{provider:this.providerName,model:n,embeddingDimension:a.embedding.length}),a.embedding}catch(o){throw g.error("Embedding generation failed",{error:o instanceof Error?o.message:String(o),model:n,textLength:e.length}),this.handleProviderError(o)}}async embedMany(e,t){let n=t||this.getDefaultEmbeddingModel()||"text-embedding-004";g.debug("Generating batch embeddings",{provider:this.providerName,model:n,count:e.length});try{let o=await NB(this.location,this.credentials),i=NA(o).textEmbeddingModel(n),a=await Vh({model:i,values:e});return g.debug("Batch embeddings generated successfully",{provider:this.providerName,model:n,count:a.embeddings.length,embeddingDimension:a.embeddings[0]?.length}),a.embeddings}catch(o){throw g.error("Batch embedding generation failed",{error:o instanceof Error?o.message:String(o),model:n,count:e.length}),this.handleProviderError(o)}}getModelSuggestions(e){let t={google:["gemini-3.1-pro-preview","gemini-3.1-flash-lite-preview","gemini-3-flash-preview","gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-2.0-flash-001","gemini-2.0-flash-lite","gemini-1.5-pro","gemini-1.5-flash"],claude:["claude-sonnet-4-5@20250929","claude-sonnet-4@20250514","claude-opus-4@20250514","claude-3-5-sonnet-20241022","claude-3-5-haiku-20241022","claude-3-sonnet-20240229","claude-3-haiku-20240307","claude-3-opus-20240229"]},n=`
1914
+ 4. Check network connectivity`,this.providerName)}static evictLRUCacheEntries(e){if(e.size<=r.MAX_CACHE_SIZE)return;let t=e.size-r.MAX_CACHE_SIZE+5,n=0;for(let o of e.keys()){if(n>=t)break;e.delete(o),n++}g.debug("GoogleVertexProvider: Evicted LRU cache entries",{entriesRemoved:n,currentCacheSize:e.size})}static accessCacheEntry(e,t){let n=e.get(t);return n!==void 0&&(e.delete(t),e.set(t,n)),n}shouldSetMaxTokensCached(e){let t=Date.now();t-r.maxTokensCacheTime>r.CACHE_DURATION&&(r.maxTokensCache.clear(),r.maxTokensCacheTime=t);let n=r.accessCacheEntry(r.maxTokensCache,e);if(n!==void 0)return n;let o=!this.modelHasMaxTokensIssues(e);return r.maxTokensCache.set(e,o),r.evictLRUCacheEntries(r.maxTokensCache),o}modelHasMaxTokensIssues(e){let t=Date.now(),n="google-vertex-config";if(t-r.modelConfigCacheTime>r.CACHE_DURATION){r.modelConfigCache.clear();let a=yS.getInstance().getProviderConfiguration("google-vertex");r.modelConfigCache.set(n,a),r.modelConfigCacheTime=t}return(r.accessCacheEntry(r.modelConfigCache,n)?.modelBehavior?.maxTokensIssues||["gemini-2.5-flash","gemini-2.5-pro"]).some(i=>e.includes(i))}async hasAnthropicSupport(){return Kee()}resolveModelAlias(e){return DB[e]??e}async createAnthropicModel(e){let t=`anthropic-validation-${Date.now()}-${Math.random().toString(36).substring(2,11)}`;if(g.debug("[GoogleVertexProvider] \u{1F9E0} Starting comprehensive Anthropic model validation",{validationId:t,modelName:e,timestamp:new Date().toISOString()}),!Kee())return g.error("[GoogleVertexProvider] \u274C SDK module validation failed",{validationId:t,issue:"createVertexAnthropic function not available",solution:"Update @ai-sdk/google-vertex to latest version with Anthropic support",command:"npm install @ai-sdk/google-vertex@latest",documentation:"https://sdk.vercel.ai/providers/ai-sdk-providers/google-vertex#anthropic-models"}),null;let o=this.credentials&&(this.credentials.apiKey||this.credentials.clientEmail||this.credentials.privateKey||this.credentials.serviceAccountKey)?{isValid:!0,method:"per_request_credentials",issues:[]}:await this.validateVertexAuthentication();if(!o.isValid)return g.error("[GoogleVertexProvider] \u274C Authentication validation failed",{validationId:t,method:o.method,issues:o.issues,solutions:["Option 1: Set GOOGLE_APPLICATION_CREDENTIALS to valid service account OR ADC file","Option 2: Set individual env vars: GOOGLE_AUTH_CLIENT_EMAIL, GOOGLE_AUTH_PRIVATE_KEY","Option 3: Use gcloud auth application-default login for ADC","Documentation: https://cloud.google.com/docs/authentication/provide-credentials-adc"]}),null;let s=await this.validateVertexProjectConfiguration();if(!s.isValid)return g.error("[GoogleVertexProvider] \u274C Project configuration validation failed",{validationId:t,projectId:s.projectId,region:s.region,issues:s.issues,solutions:["Set GOOGLE_VERTEX_PROJECT or GOOGLE_CLOUD_PROJECT environment variable","Ensure project exists and has Vertex AI API enabled","Check: https://console.cloud.google.com/apis/library/aiplatform.googleapis.com"]}),null;await this.checkVertexRegionalSupport(s.region)||g.warn("[GoogleVertexProvider] \u26A0\uFE0F Regional support warning",{validationId:t,region:s.region,warning:"Anthropic models may not be available in this region",supportedRegions:["us-central1","us-east4","us-east5","us-west1","us-west4","europe-west1","europe-west4","asia-southeast1","asia-northeast1"],solution:"Set GOOGLE_CLOUD_LOCATION to a supported region"});let a=this.validateAnthropicModelName(e);if(!a.isValid)return g.error("[GoogleVertexProvider] \u274C Model name validation failed",{validationId:t,modelName:e,issue:a.issue,recommendedModels:["claude-sonnet-4-6","claude-opus-4-6","claude-sonnet-4-5@20250929","claude-opus-4@20250514","claude-3-5-sonnet-20241022"]}),null;try{g.debug("[GoogleVertexProvider] \u{1F527} Creating vertexAnthropic settings",{validationId:t,authMethod:o.method,projectId:s.projectId,region:s.region});let l=await C7t(this.location,this.credentials);if(!l.project||!l.location)return g.error("[GoogleVertexProvider] \u274C Settings validation failed",{validationId:t,hasProject:!!l.project,hasLocation:!!l.location,hasProxy:!!l.fetch,hasAuth:!!l.googleAuthOptions}),null;g.debug("[GoogleVertexProvider] \u2705 Creating vertexAnthropic instance",{validationId:t,modelName:e,project:l.project,location:l.location,hasProxy:!!l.fetch,hasAuth:!!l.googleAuthOptions});let d=lA(l)(e);return g.info("[GoogleVertexProvider] \u2705 Anthropic model created successfully",{validationId:t,modelName:e,hasModel:!!d,modelType:typeof d,authMethod:o.method,projectId:s.projectId,region:s.region,validationsPassed:["SDK_MODULE_AVAILABLE","AUTHENTICATION_VALID","PROJECT_CONFIGURED","MODEL_NAME_VALID","SETTINGS_CREATED","PROVIDER_INSTANCE_CREATED","MODEL_INSTANCE_CREATED"]}),d}catch(l){let u=this.analyzeAnthropicCreationError(l,{validationId:t,modelName:e,projectId:s.projectId,region:s.region,authMethod:o.method});return g.error("[GoogleVertexProvider] \u274C Anthropic model creation failed",{validationId:t,modelName:e,...u,detailedTroubleshooting:this.getAnthropicTroubleshootingSteps(u)}),null}}async validateVertexAuthentication(){let e={isValid:!1,method:"none",issues:[]};try{if(process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK||process.env.GOOGLE_APPLICATION_CREDENTIALS){let t=process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK?process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK:process.env.GOOGLE_APPLICATION_CREDENTIALS||"";try{if(xo.existsSync(t)){let n=xo.readFileSync(t,"utf8"),o=JSON.parse(n);if(o.type==="service_account"&&o.project_id&&o.client_email&&o.private_key)return e.isValid=!0,e.method="service_account_file",e;if(o.client_id&&o.client_secret&&o.refresh_token&&o.type!=="service_account")return e.isValid=!0,e.method="application_default_credentials",e;e.issues.push("Credentials file missing required fields (not service account or ADC format)")}else e.issues.push(`Service account file not found: ${t}`)}catch(n){e.issues.push(`Service account file validation failed: ${n}`)}}if(process.env.GOOGLE_AUTH_CLIENT_EMAIL&&process.env.GOOGLE_AUTH_PRIVATE_KEY){let t=process.env.GOOGLE_AUTH_CLIENT_EMAIL,n=process.env.GOOGLE_AUTH_PRIVATE_KEY;if(t.includes("@")&&n.includes("BEGIN PRIVATE KEY"))return e.isValid=!0,e.method="environment_variables",e;e.issues.push("Individual credentials format validation failed")}else e.issues.push("Missing individual credential environment variables");e.isValid||e.issues.push("No valid authentication method found")}catch(t){e.issues.push(`Authentication validation error: ${t}`)}return e}async validateVertexProjectConfiguration(){let e={isValid:!1,projectId:void 0,region:void 0,issues:[]},t=process.env.GOOGLE_VERTEX_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID||process.env.GOOGLE_PROJECT_ID||process.env.GOOGLE_CLOUD_PROJECT;t?(e.projectId=t,/^[a-z][a-z0-9-]{4,28}[a-z0-9]$/.test(t)?e.isValid=!0:e.issues.push(`Invalid project ID format: ${t}`)):e.issues.push("No project ID configured");let n=process.env.GOOGLE_CLOUD_LOCATION||process.env.VERTEX_LOCATION||process.env.GOOGLE_VERTEX_LOCATION||"us-central1";return e.region=n,/^([a-z]+-[a-z]+\d+|global)$/.test(n)||(e.issues.push(`Invalid region format: ${n} (expected format: 'us-central1' or 'global')`),e.isValid=!1),e}async checkVertexRegionalSupport(e="us-central1"){return["global","us-central1","us-east1","us-east4","us-east5","us-south1","us-west1","us-west4","northamerica-northeast1","northamerica-northeast2","europe-west1","europe-west2","europe-west3","europe-west4","europe-west6","europe-west8","europe-west9","europe-north1","europe-central2","europe-southwest1","asia-east1","asia-east2","asia-northeast1","asia-northeast2","asia-northeast3","asia-south1","asia-southeast1","asia-southeast2","australia-southeast1","australia-southeast2","me-west1","me-central1","africa-south1","southamerica-east1","southamerica-west1"].includes(e)}validateAnthropicModelName(e){return!e||typeof e!="string"?{isValid:!1,issue:"Model name is required and must be a string"}:e.toLowerCase().includes("claude")?[/^claude-opus-4-6$/,/^claude-sonnet-4-6$/,/^claude-sonnet-4@\d{8}$/,/^claude-sonnet-4-5@\d{8}$/,/^claude-opus-4@\d{8}$/,/^claude-opus-4-1@\d{8}$/,/^claude-opus-4-5@\d{8}$/,/^claude-haiku-4-5@\d{8}$/,/^claude-3-7-sonnet@\d{8}$/,/^claude-3-5-sonnet-\d{8}$/,/^claude-3-5-haiku-\d{8}$/,/^claude-3-sonnet-\d{8}$/,/^claude-3-haiku-\d{8}$/,/^claude-3-opus-\d{8}$/].some(o=>o.test(e))?{isValid:!0}:{isValid:!1,issue:'Model name format not recognized. Expected formats like "claude-3-5-sonnet-20241022" or "claude-sonnet-4@20250514"'}:{isValid:!1,issue:'Model name must be a Claude model (should contain "claude")'}}analyzeAnthropicCreationError(e,t){let n=e instanceof Error?e.message:String(e),o=e instanceof Error?e.name:"UnknownError",s={error:n,errorName:o,errorType:"UNKNOWN",isNetworkError:!1,isAuthError:!1,isConfigurationError:!1,isModelError:!1,isRegionalError:!1,specificIssue:"Unknown error occurred",errorStack:e instanceof Error?e.stack:void 0};return n.includes("ETIMEDOUT")||n.includes("ECONNREFUSED")||n.includes("ENOTFOUND")||n.includes("timeout")?(s.errorType="NETWORK",s.isNetworkError=!0,s.specificIssue="Network connectivity issue - cannot reach Google Cloud endpoints"):n.includes("PERMISSION_DENIED")||n.includes("401")||n.includes("403")||n.includes("Unauthorized")||n.includes("Forbidden")?(s.errorType="AUTHENTICATION",s.isAuthError=!0,s.specificIssue="Authentication failed - invalid credentials or insufficient permissions"):n.includes("NOT_FOUND")||n.includes("404")||n.includes("model")&&n.includes("not available")?(s.errorType="MODEL_AVAILABILITY",s.isModelError=!0,s.specificIssue=`Model "${t.modelName}" not available in region "${t.region}"`):n.includes("QUOTA_EXCEEDED")||n.includes("quota")||n.includes("limit")?(s.errorType="QUOTA",s.isRegionalError=!0,s.specificIssue="Quota exceeded or rate limit reached"):(n.includes("INVALID_ARGUMENT")||n.includes("BadRequest")||n.includes("400"))&&(s.errorType="CONFIGURATION",s.isConfigurationError=!0,s.specificIssue="Invalid configuration or request parameters"),s}getAnthropicTroubleshootingSteps(e){let t=[];switch(e.errorType){case"NETWORK":t.push("\u{1F310} Network Troubleshooting:","1. Check internet connectivity","2. Verify proxy configuration if behind corporate firewall","3. Ensure firewall allows HTTPS to *.googleapis.com","4. Try different network or wait for network issues to resolve","5. Check if using VPN that might block Google Cloud endpoints");break;case"AUTHENTICATION":t.push("\u{1F510} Authentication Troubleshooting:","1. Verify GOOGLE_APPLICATION_CREDENTIALS file exists and is valid","2. Check individual credentials: GOOGLE_AUTH_CLIENT_EMAIL, GOOGLE_AUTH_PRIVATE_KEY",'3. Ensure service account has "Vertex AI User" role',"4. Verify project ID matches the one in your credentials","5. Enable Vertex AI API: https://console.cloud.google.com/apis/library/aiplatform.googleapis.com");break;case"MODEL_AVAILABILITY":t.push("\u{1F916} Model Availability Troubleshooting:","1. Verify model name format and spelling","2. Check if Anthropic integration is enabled in your project","3. Enable Claude models: https://console.cloud.google.com/vertex-ai/publishers/anthropic","4. Try a different region if current region lacks Anthropic support","5. Accept Anthropic terms and conditions in Google Cloud Console");break;case"QUOTA":t.push("\u{1F4CA} Quota Troubleshooting:","1. Check Vertex AI quotas in Google Cloud Console","2. Request quota increase if needed","3. Try a different model with lower resource requirements","4. Wait before retrying if rate limited","5. Consider using a different region with available quota");break;case"CONFIGURATION":t.push("\u2699\uFE0F Configuration Troubleshooting:","1. Verify all required environment variables are set","2. Check project ID and region format","3. Ensure model name follows correct format","4. Verify request parameters are within model limits","5. Update @ai-sdk/google-vertex to latest version");break;default:t.push("\u{1F527} General Troubleshooting:","1. Update @ai-sdk/google-vertex to latest version","2. Check Google Cloud service status","3. Verify all authentication and configuration","4. Try with a simple Claude model like claude-3-haiku-20240307","5. Enable debug logging with NEUROLINK_DEBUG=true")}return t}registerTool(e,t,n,o){let s="GoogleVertexProvider.registerTool";try{let i={description:n,parameters:t,execute:async a=>{try{let l={...a,__context:this.toolContext};return await o(l)}catch(l){throw g.error(`${s}: Tool execution error`,{toolName:e,error:l instanceof Error?l.message:String(l)}),l}}};this.registeredTools.set(e,i),g.debug(`${s}: Tool registered`,{toolName:e,modelName:this.modelName})}catch(i){throw g.error(`${s}: Tool registration error`,{toolName:e,error:i instanceof Error?i.message:String(i)}),i}}setToolContext(e){this.toolContext={...this.toolContext,...e},g.debug("GoogleVertexProvider.setToolContext: Tool context set",{contextKeys:Object.keys(e)})}getToolContext(){return{...this.toolContext}}setToolExecutor(e){this.toolExecutor=e,g.debug("GoogleVertexProvider.setToolExecutor: Tool executor set",{hasExecutor:typeof e=="function"})}static clearCaches(){r.modelConfigCache.clear(),r.maxTokensCache.clear(),r.modelConfigCacheTime=0,r.maxTokensCacheTime=0,g.debug("GoogleVertexProvider: All caches cleared",{clearedAt:Date.now()})}static getCacheStats(){let e=Date.now();return{modelConfigCacheSize:r.modelConfigCache.size,maxTokensCacheSize:r.maxTokensCache.size,maxCacheSize:r.MAX_CACHE_SIZE,cacheAge:{modelConfig:e-r.modelConfigCacheTime,maxTokens:e-r.maxTokensCacheTime}}}detectImageType(e){return e.length>=8&&e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71?"image/png":e.length>=3&&e[0]===255&&e[1]===216&&e[2]===255?"image/jpeg":e.length>=12&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80?"image/webp":e.length>=6&&e[0]===71&&e[1]===73&&e[2]===70?"image/gif":"image/png"}estimateTokenCount(e){return fr(e,"vertex")}async getImageGenerationAccessToken(){let{GoogleAuth:o}=await Promise.resolve().then(()=>(dR(),HZ)),s=process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK||process.env.GOOGLE_APPLICATION_CREDENTIALS;for(let i=1;i<=3;i++){let a=new AbortController,l=setTimeout(()=>{a.abort(),g.warn(`[GoogleVertexProvider] Auth token refresh exceeded 15000ms timeout (attempt ${i}/3)`)},15e3);try{let p=await(await new o({...s&&{keyFilename:s},scopes:["https://www.googleapis.com/auth/cloud-platform"]}).getClient()).getAccessToken();if(!p.token)throw new kn("Failed to obtain access token from Google Auth",this.providerName);return p.token}catch(u){let d=u;if(!(a.signal.aborted||d?.code==="ECONNRESET"||d?.code==="ETIMEDOUT"||d?.code==="ENOTFOUND"||d?.message?.includes("socket hang up")||d?.message?.includes("network socket disconnected"))||i===3)throw u;let m=500*2**(i-1);g.warn(`[GoogleVertexProvider] Auth token transient error (${d?.code||d?.message}), retrying in ${m}ms (attempt ${i}/3)`),await new Promise(f=>setTimeout(f,m))}finally{clearTimeout(l)}}throw new kn("Failed to obtain access token after retries",this.providerName)}async buildImageGenerationParts(e,t,n){let o=[];e&&o.push({text:e});for(let s of t){let i;if(Buffer.isBuffer(s))i=s.toString("base64");else if(typeof s=="string")if(s.startsWith("/")||/^[a-zA-Z]:\\/.test(s)||s.startsWith("./")||s.startsWith("../")||s.startsWith("..\\")||s.startsWith(".\\")){let l=jc.resolve(s),u=process.cwd();if(!l.startsWith(u+jc.sep)&&l!==u)throw new ur("PDF file path must be within current directory for security",this.providerName);if(!xo.existsSync(l))throw new ur(`PDF file not found: ${l}`,this.providerName);i=xo.readFileSync(l).toString("base64")}else i=s;else{g.warn("Invalid PDF file format, skipping",{type:typeof s});continue}o.push({inlineData:{mimeType:"application/pdf",data:i}}),g.debug("Added PDF file to request",{dataLength:i.length})}for(let s=0;s<n.length;s++){let i=n[s],a,l;if(Buffer.isBuffer(i))a=i.toString("base64"),l=this.detectImageType(i);else if(typeof i=="string")if(i.startsWith("/")||/^[a-zA-Z]:\\/.test(i)||i.startsWith("./")||i.startsWith("../")||i.startsWith("..\\")||i.startsWith(".\\")){let d=jc.resolve(i);if(!xo.existsSync(d)){g.warn(`Image file not found: ${d}, skipping`);continue}let p=xo.readFileSync(d);a=p.toString("base64"),l=this.detectImageType(p)}else if(i.startsWith("data:")){let d=i.match(/^data:([^;]+);base64,(.+)$/);if(d)l=d[1],a=d[2];else{g.warn("Invalid data URL format, skipping image",{index:s});continue}}else if(i.startsWith("http://")||i.startsWith("https://"))try{let p=new URL(i).hostname;if(["localhost","127.0.0.1","0.0.0.0","[::1]"].some(v=>p===v)||/^(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.)/.test(p)){g.warn(`[GoogleVertexProvider] Blocked fetch to private/local URL: ${p}`,{index:s});continue}try{let{resolve4:v,resolve6:b}=RB.promises,w=[];try{w.push(...await v(p))}catch{}try{w.push(...await b(p))}catch{}if(w.length>0&&w.every(T=>w7t(T))){g.warn(`[GoogleVertexProvider] Blocked fetch: hostname ${p} resolves to private/loopback address`,{index:s,addresses:w});continue}}catch(v){g.warn(`[GoogleVertexProvider] DNS resolution failed for ${p}, blocking fetch`,{index:s,error:v instanceof Error?v.message:String(v)});continue}let f=await fetch(i,{signal:AbortSignal.timeout(15e3)});if(!f.ok){g.warn(`Failed to fetch image URL (${f.status}), skipping`,{index:s,url:i});continue}let h=f.headers.get("content-length");if(h&&Number(h)>OB){g.warn(`[GoogleVertexProvider] Image URL exceeds ${OB} byte limit (Content-Length: ${h}), skipping`,{index:s,url:i});continue}let y=Buffer.from(await f.arrayBuffer());if(y.byteLength>OB){g.warn(`[GoogleVertexProvider] Downloaded image exceeds ${OB} byte limit (${y.byteLength} bytes), skipping`,{index:s,url:i});continue}a=y.toString("base64"),l=this.detectImageType(y)}catch(d){g.warn(`Failed to download image from URL, skipping: ${d instanceof Error?d.message:String(d)}`,{index:s,url:i});continue}else{a=i;let d=Buffer.from(a,"base64");l=this.detectImageType(d)}else{g.warn("Invalid image format, skipping",{type:typeof i,index:s});continue}o.push({inlineData:{mimeType:l,data:a}}),g.debug("Added image to request",{index:s,mimeType:l,dataLength:a.length})}return o}parseImageGenerationResponse(e,t){let n=e.candidates?.[0];if(!n?.content?.parts)throw new ur("No content parts in Vertex AI response",this.providerName);let o=n.content.parts.find(a=>(a.inlineData||a.inline_data)&&(a.inlineData&&a.inlineData.mimeType||a.inline_data&&a.inline_data.mime_type)&&(a.inlineData&&a.inlineData.mimeType?.startsWith("image/")||a.inline_data&&a.inline_data.mime_type?.startsWith("image/")));if(!o){let a=n.content.parts.map(l=>typeof l.text=="string"?l.text:"").filter(l=>l.trim().length>0);if(a.length>0)return{textFallback:a.join("")};throw new ur(`Image generation completed but no image data was returned. Model: ${t}`,this.providerName)}let s=o.inlineData?.data||o.inline_data?.data,i=o.inlineData?.mimeType||o.inline_data?.mime_type||"image/png";if(!s)throw new ur("Image part found but no data available",this.providerName);return{imageData:s,mimeType:i}}async executeImageGeneration(e){let t=e.prompt||e.input?.text||"",n=e.input?.pdfFiles||[],o=e.input?.images||[],s=n.length>0,i=o.length>0;if(!t.trim()&&!s&&!i)throw new ur("Image generation requires either a prompt, PDF file, or image as input",this.providerName);let a=e.model||this.modelName||"gemini-3-pro-image-preview";s&&!a.includes("gemini-3-pro-image")&&(a="gemini-3-pro-image-preview");let l=process.env.GOOGLE_VERTEX_IMAGE_LOCATION||"global",d=Jfe.some(m=>a.includes(m)||m.includes(a))?l:this.location,p=Date.now();g.info("\u{1F3A8} Starting Vertex AI image generation (REST API)",{model:a,prompt:t.substring(0,100),provider:this.providerName,projectId:this.projectId,location:d,hasPdfInput:s,pdfCount:n.length,hasImageInput:i,imageCount:o.length});try{let m=await this.getImageGenerationAccessToken(),h={contents:[{role:"user",parts:await this.buildImageGenerationParts(t,n,o)}],generation_config:{response_modalities:["TEXT","IMAGE"],temperature:e.temperature||.7,candidate_count:1}},y;d==="global"?y=`https://aiplatform.googleapis.com/v1/projects/${this.projectId}/locations/global/publishers/google/models/${a}:generateContent`:y=`https://${d}-aiplatform.googleapis.com/v1/projects/${this.projectId}/locations/${d}/publishers/google/models/${a}:generateContent`,g.debug("Making REST API call to Vertex AI",{url:y,model:a,hasAccessToken:!0});let v=12e4,b=fetch(y,{method:"POST",headers:{Authorization:`Bearer ${m}`,"Content-Type":"application/json"},body:JSON.stringify(h)}),w=new Promise((E,M)=>{setTimeout(()=>{M(new zr(`Vertex AI image generation timed out after ${v}ms`,v))},v)}),T=await Promise.race([b,w]);if(!T.ok){let E=await T.text();throw new ur(`Vertex AI API error (${T.status}): ${E}`,this.providerName)}let _=await T.json(),k=this.parseImageGenerationResponse(_,a);if("textFallback"in k){g.info("Dual-mode image model returned text; returning as text result",{model:a,textLength:k.textFallback.length,responseTime:Date.now()-p});let E=this.estimateTokenCount(t),M=this.estimateTokenCount(k.textFallback),O={content:k.textFallback,provider:this.providerName,model:a,usage:{input:E,output:M,total:E+M}};return await this.enhanceResult(O,e,p)}let{imageData:R,mimeType:I}=k;g.info("Image generation successful",{model:a,mimeType:I,dataLength:R.length,responseTime:Date.now()-p});let C={content:`Generated image using ${a} (${I})`,imageOutput:{base64:R},provider:this.providerName,model:a,usage:{input:this.estimateTokenCount(t),output:0,total:this.estimateTokenCount(t)}};return await this.enhanceResult(C,e,p)}catch(m){throw g.error("Image generation failed",{error:m instanceof Error?m.message:String(m),model:a,prompt:t.substring(0,100)}),this.handleProviderError(m)}}async embed(e,t){let n=t||"text-embedding-004";g.debug("Generating embedding",{provider:this.providerName,model:n,textLength:e.length});try{let o=await NB(this.location,this.credentials),i=NA(o).textEmbeddingModel(n),a=await Gh({model:i,value:e});return g.debug("Embedding generated successfully",{provider:this.providerName,model:n,embeddingDimension:a.embedding.length}),a.embedding}catch(o){throw g.error("Embedding generation failed",{error:o instanceof Error?o.message:String(o),model:n,textLength:e.length}),this.handleProviderError(o)}}async embedMany(e,t){let n=t||this.getDefaultEmbeddingModel()||"text-embedding-004";g.debug("Generating batch embeddings",{provider:this.providerName,model:n,count:e.length});try{let o=await NB(this.location,this.credentials),i=NA(o).textEmbeddingModel(n),a=await Vh({model:i,values:e});return g.debug("Batch embeddings generated successfully",{provider:this.providerName,model:n,count:a.embeddings.length,embeddingDimension:a.embeddings[0]?.length}),a.embeddings}catch(o){throw g.error("Batch embedding generation failed",{error:o instanceof Error?o.message:String(o),model:n,count:e.length}),this.handleProviderError(o)}}getModelSuggestions(e){let t={google:["gemini-3.1-pro-preview","gemini-3.1-flash-lite-preview","gemini-3-flash-preview","gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-2.0-flash-001","gemini-2.0-flash-lite","gemini-1.5-pro","gemini-1.5-flash"],claude:["claude-sonnet-4-5@20250929","claude-sonnet-4@20250514","claude-opus-4@20250514","claude-3-5-sonnet-20241022","claude-3-5-haiku-20241022","claude-3-sonnet-20240229","claude-3-haiku-20240307","claude-3-opus-20240229"]},n=`
1915
1915
  \u{1F916} Google Models (always available):
1916
1916
  `;return t.google.forEach(o=>{n+=` \u2022 ${o}
1917
1917
  `}),n+=`
@@ -1443,27 +1443,32 @@ export const proxyGuardCommand = {
1443
1443
  return;
1444
1444
  }
1445
1445
  logger.always(`[guard] update available: ${runningVersion} → ${result.latestVersion}`);
1446
- // 2. Wait for quiet traffic
1447
- const maxQuietWaitMs = 60 * 60 * 1000; // 1 hour max wait
1446
+ // 2. Best-effort quiet wait — try for a brief window, but proceed
1447
+ // regardless. The install (pnpm add -g) is non-disruptive; only the
1448
+ // restart causes a ~1-3s blip. Blocking updates for hours/days because
1449
+ // traffic never goes silent is worse than a brief interruption.
1450
+ const maxQuietWaitMs = 5 * 60 * 1000; // 5 minutes max, then proceed
1448
1451
  const quietPollMs = 10_000; // check every 10s
1449
1452
  const quietStart = Date.now();
1450
1453
  while (Date.now() - quietStart < maxQuietWaitMs) {
1451
- // Bail out if parent proxy died during the wait
1452
1454
  if (getProcessStatus(parentPid) === "not_running") {
1453
1455
  logger.always(`[guard] parent process died during quiet-wait, aborting update`);
1454
1456
  return;
1455
1457
  }
1456
1458
  const quietStatus = checkTrafficQuiet(QUIET_THRESHOLD_MS);
1457
1459
  if (quietStatus.isQuiet) {
1460
+ logger.always(`[guard] traffic quiet, proceeding with update`);
1458
1461
  break;
1459
1462
  }
1460
1463
  logger.debug(`[guard] traffic active (last activity ${Math.round(quietStatus.silenceDurationMs / 1000)}s ago), waiting...`);
1461
1464
  await new Promise((r) => setTimeout(r, quietPollMs));
1462
1465
  }
1466
+ // Proceed with install regardless — don't block updates indefinitely.
1467
+ // The install itself (pnpm add -g) doesn't affect the running process.
1468
+ // Only the restart afterwards causes a brief interruption.
1463
1469
  const finalQuiet = checkTrafficQuiet(QUIET_THRESHOLD_MS);
1464
1470
  if (!finalQuiet.isQuiet) {
1465
- logger.always(`[guard] traffic didn't quiet down within 1 hour, skipping update cycle`);
1466
- return;
1471
+ logger.always(`[guard] traffic still active after ${Math.round(maxQuietWaitMs / 1000)}s wait, proceeding with update anyway (restart will briefly interrupt in-flight requests)`);
1467
1472
  }
1468
1473
  // 3. Install update (validate version string before passing to shell)
1469
1474
  if (!/^\d+\.\d+\.\d+$/.test(result.latestVersion)) {
@@ -570,6 +570,19 @@ export class BaseProvider {
570
570
  if (!hasVideoFrames(messages)) {
571
571
  return null;
572
572
  }
573
+ // Bug 2 fix: callers requesting structured output (schema or explicit
574
+ // output.format) must NOT be hijacked into the prose-returning video
575
+ // analysis path. Without this gate, schema/format are silently dropped
576
+ // whenever messages contain >=3 image parts.
577
+ if (options.schema !== undefined || options.output?.format !== undefined) {
578
+ logger.info("[VideoFrameGen] Skipping video-frame analysis route; caller requested structured output", {
579
+ provider: this.providerName,
580
+ model: this.modelName,
581
+ hasSchema: options.schema !== undefined,
582
+ outputFormat: options.output?.format,
583
+ });
584
+ return null;
585
+ }
573
586
  const videoAnalysisResult = await executeVideoAnalysis(messages, {
574
587
  provider: options.provider,
575
588
  providerName: this.providerName,
@@ -570,6 +570,19 @@ export class BaseProvider {
570
570
  if (!hasVideoFrames(messages)) {
571
571
  return null;
572
572
  }
573
+ // Bug 2 fix: callers requesting structured output (schema or explicit
574
+ // output.format) must NOT be hijacked into the prose-returning video
575
+ // analysis path. Without this gate, schema/format are silently dropped
576
+ // whenever messages contain >=3 image parts.
577
+ if (options.schema !== undefined || options.output?.format !== undefined) {
578
+ logger.info("[VideoFrameGen] Skipping video-frame analysis route; caller requested structured output", {
579
+ provider: this.providerName,
580
+ model: this.modelName,
581
+ hasSchema: options.schema !== undefined,
582
+ outputFormat: options.output?.format,
583
+ });
584
+ return null;
585
+ }
573
586
  const videoAnalysisResult = await executeVideoAnalysis(messages, {
574
587
  provider: options.provider,
575
588
  providerName: this.providerName,
@@ -311,7 +311,14 @@ export declare class GoogleVertexProvider extends BaseProvider {
311
311
  */
312
312
  private buildImageGenerationParts;
313
313
  /**
314
- * Parse the Vertex AI image generation REST API response and extract image data.
314
+ * Parse the Vertex AI image generation REST API response.
315
+ *
316
+ * Dual-mode image models (gemini-3.1-flash-image-preview, gemini-2.5-flash-image,
317
+ * gemini-3-pro-image-preview) decide per-request whether to emit an image or text.
318
+ * When the response contains text parts but no image part, surface the text via
319
+ * `textFallback` so the caller can return a normal text result instead of throwing
320
+ * "model returned text instead of image data" and burning retries on a query that
321
+ * the model has already answered.
315
322
  */
316
323
  private parseImageGenerationResponse;
317
324
  /**
@@ -3015,7 +3015,14 @@ export class GoogleVertexProvider extends BaseProvider {
3015
3015
  return parts;
3016
3016
  }
3017
3017
  /**
3018
- * Parse the Vertex AI image generation REST API response and extract image data.
3018
+ * Parse the Vertex AI image generation REST API response.
3019
+ *
3020
+ * Dual-mode image models (gemini-3.1-flash-image-preview, gemini-2.5-flash-image,
3021
+ * gemini-3-pro-image-preview) decide per-request whether to emit an image or text.
3022
+ * When the response contains text parts but no image part, surface the text via
3023
+ * `textFallback` so the caller can return a normal text result instead of throwing
3024
+ * "model returned text instead of image data" and burning retries on a query that
3025
+ * the model has already answered.
3019
3026
  */
3020
3027
  parseImageGenerationResponse(data, imageModelName) {
3021
3028
  const candidate = data.candidates?.[0];
@@ -3030,10 +3037,15 @@ export class GoogleVertexProvider extends BaseProvider {
3030
3037
  (part.inline_data &&
3031
3038
  part.inline_data.mime_type?.startsWith("image/"))));
3032
3039
  if (!imagePart) {
3033
- const hasTextContent = candidate.content.parts.some((part) => part.text);
3034
- throw new ProviderError(hasTextContent
3035
- ? `Image generation completed but model returned text instead of image data. Model: ${imageModelName}`
3036
- : `Image generation completed but no image data was returned. Model: ${imageModelName}`, this.providerName);
3040
+ // Filter out empty/whitespace-only text parts so an effectively empty
3041
+ // response throws "no image data" instead of returning content: "".
3042
+ const textParts = candidate.content.parts
3043
+ .map((part) => (typeof part.text === "string" ? part.text : ""))
3044
+ .filter((text) => text.trim().length > 0);
3045
+ if (textParts.length > 0) {
3046
+ return { textFallback: textParts.join("") };
3047
+ }
3048
+ throw new ProviderError(`Image generation completed but no image data was returned. Model: ${imageModelName}`, this.providerName);
3037
3049
  }
3038
3050
  const imageData = imagePart.inlineData?.data || imagePart.inline_data?.data;
3039
3051
  const mimeType = imagePart.inlineData?.mimeType ||
@@ -3127,7 +3139,31 @@ export class GoogleVertexProvider extends BaseProvider {
3127
3139
  throw new ProviderError(`Vertex AI API error (${response.status}): ${errorText}`, this.providerName);
3128
3140
  }
3129
3141
  const data = (await response.json());
3130
- const { imageData, mimeType } = this.parseImageGenerationResponse(data, imageModelName);
3142
+ const parsed = this.parseImageGenerationResponse(data, imageModelName);
3143
+ // Dual-mode model decided to emit text instead of an image. Surface the
3144
+ // text as a normal text result instead of throwing — the model already
3145
+ // answered the user; failing here just burns retries.
3146
+ if ("textFallback" in parsed) {
3147
+ logger.info("Dual-mode image model returned text; returning as text result", {
3148
+ model: imageModelName,
3149
+ textLength: parsed.textFallback.length,
3150
+ responseTime: Date.now() - startTime,
3151
+ });
3152
+ const inputTokens = this.estimateTokenCount(prompt);
3153
+ const outputTokens = this.estimateTokenCount(parsed.textFallback);
3154
+ const textResult = {
3155
+ content: parsed.textFallback,
3156
+ provider: this.providerName,
3157
+ model: imageModelName,
3158
+ usage: {
3159
+ input: inputTokens,
3160
+ output: outputTokens,
3161
+ total: inputTokens + outputTokens,
3162
+ },
3163
+ };
3164
+ return await this.enhanceResult(textResult, options, startTime);
3165
+ }
3166
+ const { imageData, mimeType } = parsed;
3131
3167
  logger.info("Image generation successful", {
3132
3168
  model: imageModelName,
3133
3169
  mimeType,
@@ -311,7 +311,14 @@ export declare class GoogleVertexProvider extends BaseProvider {
311
311
  */
312
312
  private buildImageGenerationParts;
313
313
  /**
314
- * Parse the Vertex AI image generation REST API response and extract image data.
314
+ * Parse the Vertex AI image generation REST API response.
315
+ *
316
+ * Dual-mode image models (gemini-3.1-flash-image-preview, gemini-2.5-flash-image,
317
+ * gemini-3-pro-image-preview) decide per-request whether to emit an image or text.
318
+ * When the response contains text parts but no image part, surface the text via
319
+ * `textFallback` so the caller can return a normal text result instead of throwing
320
+ * "model returned text instead of image data" and burning retries on a query that
321
+ * the model has already answered.
315
322
  */
316
323
  private parseImageGenerationResponse;
317
324
  /**
@@ -3015,7 +3015,14 @@ export class GoogleVertexProvider extends BaseProvider {
3015
3015
  return parts;
3016
3016
  }
3017
3017
  /**
3018
- * Parse the Vertex AI image generation REST API response and extract image data.
3018
+ * Parse the Vertex AI image generation REST API response.
3019
+ *
3020
+ * Dual-mode image models (gemini-3.1-flash-image-preview, gemini-2.5-flash-image,
3021
+ * gemini-3-pro-image-preview) decide per-request whether to emit an image or text.
3022
+ * When the response contains text parts but no image part, surface the text via
3023
+ * `textFallback` so the caller can return a normal text result instead of throwing
3024
+ * "model returned text instead of image data" and burning retries on a query that
3025
+ * the model has already answered.
3019
3026
  */
3020
3027
  parseImageGenerationResponse(data, imageModelName) {
3021
3028
  const candidate = data.candidates?.[0];
@@ -3030,10 +3037,15 @@ export class GoogleVertexProvider extends BaseProvider {
3030
3037
  (part.inline_data &&
3031
3038
  part.inline_data.mime_type?.startsWith("image/"))));
3032
3039
  if (!imagePart) {
3033
- const hasTextContent = candidate.content.parts.some((part) => part.text);
3034
- throw new ProviderError(hasTextContent
3035
- ? `Image generation completed but model returned text instead of image data. Model: ${imageModelName}`
3036
- : `Image generation completed but no image data was returned. Model: ${imageModelName}`, this.providerName);
3040
+ // Filter out empty/whitespace-only text parts so an effectively empty
3041
+ // response throws "no image data" instead of returning content: "".
3042
+ const textParts = candidate.content.parts
3043
+ .map((part) => (typeof part.text === "string" ? part.text : ""))
3044
+ .filter((text) => text.trim().length > 0);
3045
+ if (textParts.length > 0) {
3046
+ return { textFallback: textParts.join("") };
3047
+ }
3048
+ throw new ProviderError(`Image generation completed but no image data was returned. Model: ${imageModelName}`, this.providerName);
3037
3049
  }
3038
3050
  const imageData = imagePart.inlineData?.data || imagePart.inline_data?.data;
3039
3051
  const mimeType = imagePart.inlineData?.mimeType ||
@@ -3127,7 +3139,31 @@ export class GoogleVertexProvider extends BaseProvider {
3127
3139
  throw new ProviderError(`Vertex AI API error (${response.status}): ${errorText}`, this.providerName);
3128
3140
  }
3129
3141
  const data = (await response.json());
3130
- const { imageData, mimeType } = this.parseImageGenerationResponse(data, imageModelName);
3142
+ const parsed = this.parseImageGenerationResponse(data, imageModelName);
3143
+ // Dual-mode model decided to emit text instead of an image. Surface the
3144
+ // text as a normal text result instead of throwing — the model already
3145
+ // answered the user; failing here just burns retries.
3146
+ if ("textFallback" in parsed) {
3147
+ logger.info("Dual-mode image model returned text; returning as text result", {
3148
+ model: imageModelName,
3149
+ textLength: parsed.textFallback.length,
3150
+ responseTime: Date.now() - startTime,
3151
+ });
3152
+ const inputTokens = this.estimateTokenCount(prompt);
3153
+ const outputTokens = this.estimateTokenCount(parsed.textFallback);
3154
+ const textResult = {
3155
+ content: parsed.textFallback,
3156
+ provider: this.providerName,
3157
+ model: imageModelName,
3158
+ usage: {
3159
+ input: inputTokens,
3160
+ output: outputTokens,
3161
+ total: inputTokens + outputTokens,
3162
+ },
3163
+ };
3164
+ return await this.enhanceResult(textResult, options, startTime);
3165
+ }
3166
+ const { imageData, mimeType } = parsed;
3131
3167
  logger.info("Image generation successful", {
3132
3168
  model: imageModelName,
3133
3169
  mimeType,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "9.59.3",
3
+ "version": "9.59.5",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 13 providers: OpenAI, Anthropic, Google AI, AWS Bedrock, Azure, Hugging Face, Ollama, and Mistral AI.",
6
6
  "author": {