flujo-ai 3.45.1 → 3.45.2
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +37 -37
- package/.next/build-manifest.json +3 -3
- package/.next/react-loadable-manifest.json +2 -2
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/api/telemetry/daily-active/route.js +1 -1
- package/.next/server/app/automation/triggers.html +1 -1
- package/.next/server/app/automation/triggers.rsc +1 -1
- package/.next/server/app/automation/triggers.segments/_full.segment.rsc +1 -1
- package/.next/server/app/automation/triggers.segments/_head.segment.rsc +1 -1
- package/.next/server/app/automation/triggers.segments/_index.segment.rsc +1 -1
- package/.next/server/app/automation/triggers.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/automation/triggers.segments/automation/triggers/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/automation/triggers.segments/automation/triggers.segment.rsc +1 -1
- package/.next/server/app/automation/triggers.segments/automation.segment.rsc +1 -1
- package/.next/server/app/automation/waves.html +1 -1
- package/.next/server/app/automation/waves.rsc +1 -1
- package/.next/server/app/automation/waves.segments/_full.segment.rsc +1 -1
- package/.next/server/app/automation/waves.segments/_head.segment.rsc +1 -1
- package/.next/server/app/automation/waves.segments/_index.segment.rsc +1 -1
- package/.next/server/app/automation/waves.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/automation/waves.segments/automation/waves/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/automation/waves.segments/automation/waves.segment.rsc +1 -1
- package/.next/server/app/automation/waves.segments/automation.segment.rsc +1 -1
- package/.next/server/app/chain-chat.html +1 -1
- package/.next/server/app/chain-chat.rsc +1 -1
- package/.next/server/app/chain-chat.segments/_full.segment.rsc +1 -1
- package/.next/server/app/chain-chat.segments/_head.segment.rsc +1 -1
- package/.next/server/app/chain-chat.segments/_index.segment.rsc +1 -1
- package/.next/server/app/chain-chat.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/chain-chat.segments/chain-chat/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/chain-chat.segments/chain-chat.segment.rsc +1 -1
- package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/chat.html +1 -1
- package/.next/server/app/chat.rsc +2 -2
- package/.next/server/app/chat.segments/_full.segment.rsc +2 -2
- package/.next/server/app/chat.segments/_head.segment.rsc +1 -1
- package/.next/server/app/chat.segments/_index.segment.rsc +1 -1
- package/.next/server/app/chat.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/chat.segments/chat.segment.rsc +1 -1
- package/.next/server/app/docs.html +1 -1
- package/.next/server/app/docs.rsc +1 -1
- package/.next/server/app/docs.segments/_full.segment.rsc +1 -1
- package/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/docs.segments/_index.segment.rsc +1 -1
- package/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/.next/server/app/executions.html +1 -1
- package/.next/server/app/executions.rsc +1 -1
- package/.next/server/app/executions.segments/_full.segment.rsc +1 -1
- package/.next/server/app/executions.segments/_head.segment.rsc +1 -1
- package/.next/server/app/executions.segments/_index.segment.rsc +1 -1
- package/.next/server/app/executions.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/executions.segments/executions/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/executions.segments/executions.segment.rsc +1 -1
- package/.next/server/app/flows/page_client-reference-manifest.js +1 -1
- package/.next/server/app/flows.html +1 -1
- package/.next/server/app/flows.rsc +2 -2
- package/.next/server/app/flows.segments/_full.segment.rsc +2 -2
- package/.next/server/app/flows.segments/_head.segment.rsc +1 -1
- package/.next/server/app/flows.segments/_index.segment.rsc +1 -1
- package/.next/server/app/flows.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/flows.segments/flows/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/flows.segments/flows.segment.rsc +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +1 -1
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/mcp/page_client-reference-manifest.js +1 -1
- package/.next/server/app/mcp-flows/route.js +1 -1
- package/.next/server/app/mcp-proxy/[server]/route.js +1 -1
- package/.next/server/app/mcp.html +1 -1
- package/.next/server/app/mcp.rsc +2 -2
- package/.next/server/app/mcp.segments/_full.segment.rsc +2 -2
- package/.next/server/app/mcp.segments/_head.segment.rsc +1 -1
- package/.next/server/app/mcp.segments/_index.segment.rsc +1 -1
- package/.next/server/app/mcp.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/mcp.segments/mcp/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/mcp.segments/mcp.segment.rsc +1 -1
- package/.next/server/app/meetings.html +1 -1
- package/.next/server/app/meetings.rsc +1 -1
- package/.next/server/app/meetings.segments/_full.segment.rsc +1 -1
- package/.next/server/app/meetings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/meetings.segments/_index.segment.rsc +1 -1
- package/.next/server/app/meetings.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/meetings.segments/meetings/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/meetings.segments/meetings.segment.rsc +1 -1
- package/.next/server/app/packages.html +1 -1
- package/.next/server/app/packages.rsc +1 -1
- package/.next/server/app/packages.segments/_full.segment.rsc +1 -1
- package/.next/server/app/packages.segments/_head.segment.rsc +1 -1
- package/.next/server/app/packages.segments/_index.segment.rsc +1 -1
- package/.next/server/app/packages.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/packages.segments/packages/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/packages.segments/packages.segment.rsc +1 -1
- package/.next/server/app/personas.html +1 -1
- package/.next/server/app/personas.rsc +1 -1
- package/.next/server/app/personas.segments/_full.segment.rsc +1 -1
- package/.next/server/app/personas.segments/_head.segment.rsc +1 -1
- package/.next/server/app/personas.segments/_index.segment.rsc +1 -1
- package/.next/server/app/personas.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/personas.segments/personas/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/personas.segments/personas.segment.rsc +1 -1
- package/.next/server/app/roles/new.html +1 -1
- package/.next/server/app/roles/new.rsc +1 -1
- package/.next/server/app/roles/new.segments/_full.segment.rsc +1 -1
- package/.next/server/app/roles/new.segments/_head.segment.rsc +1 -1
- package/.next/server/app/roles/new.segments/_index.segment.rsc +1 -1
- package/.next/server/app/roles/new.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/roles/new.segments/roles/new/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/roles/new.segments/roles/new.segment.rsc +1 -1
- package/.next/server/app/roles/new.segments/roles.segment.rsc +1 -1
- package/.next/server/app/roles.html +1 -1
- package/.next/server/app/roles.rsc +1 -1
- package/.next/server/app/roles.segments/_full.segment.rsc +1 -1
- package/.next/server/app/roles.segments/_head.segment.rsc +1 -1
- package/.next/server/app/roles.segments/_index.segment.rsc +1 -1
- package/.next/server/app/roles.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/roles.segments/roles/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/roles.segments/roles.segment.rsc +1 -1
- package/.next/server/app/settings.html +1 -1
- package/.next/server/app/settings.rsc +1 -1
- package/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/server/app/statistics.html +1 -1
- package/.next/server/app/statistics.rsc +1 -1
- package/.next/server/app/statistics.segments/_full.segment.rsc +1 -1
- package/.next/server/app/statistics.segments/_head.segment.rsc +1 -1
- package/.next/server/app/statistics.segments/_index.segment.rsc +1 -1
- package/.next/server/app/statistics.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/statistics.segments/statistics/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/statistics.segments/statistics.segment.rsc +1 -1
- package/.next/server/app/waves.html +1 -1
- package/.next/server/app/waves.rsc +1 -1
- package/.next/server/app/waves.segments/_full.segment.rsc +1 -1
- package/.next/server/app/waves.segments/_head.segment.rsc +1 -1
- package/.next/server/app/waves.segments/_index.segment.rsc +1 -1
- package/.next/server/app/waves.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/waves.segments/waves/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/waves.segments/waves.segment.rsc +1 -1
- package/.next/server/app-paths-manifest.json +37 -37
- package/.next/server/chunks/1475.js +1 -1
- package/.next/server/chunks/1914.js +1 -1
- package/.next/server/chunks/2887.js +1 -1
- package/.next/server/chunks/3686.js +1 -1
- package/.next/server/chunks/5189.js +1 -1
- package/.next/server/chunks/5399.js +1 -1
- package/.next/server/chunks/5560.js +2 -2
- package/.next/server/chunks/7570.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{7208-5af7190dbc0e142b.js → 7208-714230aba8f0df89.js} +1 -1
- package/.next/static/chunks/webpack-f1c3062d7039f0c7.js +1 -0
- package/.next/trace +118 -118
- package/.next/trace-build +1 -1
- package/README.md +1 -1
- package/mcp-servers/bash/package.json +1 -1
- package/mcp-servers/browser/package.json +1 -1
- package/mcp-servers/filesystem/package.json +1 -1
- package/mcp-servers/flujo/package.json +1 -1
- package/package.json +5 -5
- package/.next/static/chunks/webpack-489c70bebf5a4745.js +0 -1
- /package/.next/static/{PEARC3s6DHN81nwlN8qpZ → 21CjEbc0FIa9X6No7R5M-}/_buildManifest.js +0 -0
- /package/.next/static/{PEARC3s6DHN81nwlN8qpZ → 21CjEbc0FIa9X6No7R5M-}/_ssgManifest.js +0 -0
|
@@ -10,7 +10,7 @@ ${k}`:`[↩ ${o}${n} finished and returned control to you with no output. Contin
|
|
|
10
10
|
|
|
11
11
|
${n}`:`[↩ ${c} finished and returned control to you with no output. Continue your task; do not wait for further output from it.]`,id:crypto.randomUUID(),timestamp:Date.now(),processNodeId:e?.id,...j.length>0?{media:j}:{}};d.messages.push(f)}d.lastResponse=n;let r=e?.properties?.captureVariable?.trim();r&&(d.variables=d.variables??{},d.variables[r]=n,D.info("Captured subflow output into run variable",{captureVariable:r,nodeId:e?.id}));let s=e?.properties?.captureResource?.trim();if(s&&d.conversationId&&!d.ephemeral)try{await (0,l.Gi)(d,async()=>{let a=await (0,m.tm)({conversationId:d.conversationId,name:s,mimeType:"text/markdown",kind:"text",data:{text:n},producedBy:{source:"capture",nodeId:e?.id,nodeName:e?.properties?.name}});"skipped"in a?D.warn("captureResource skipped by store cap",{captureResource:s,reason:a.skipped}):(d.emit?.({type:"resource:write",node:{nodeId:e?.id??"unknown",nodeName:e?.properties?.name,nodeType:"subflow"},server:"flujo",uri:a.uri,name:s,mimeType:a.mimeType,size:a.size,source:"capture"}),D.info("Captured subflow output into run resource",{captureResource:s,uri:a.uri,nodeId:e?.id}))})}catch(a){(0,l.Vj)(a),D.error("captureResource failed; continuing run",a)}let t=e?.properties?.captureKv?.trim();if(t)try{let a;try{if(d.flowSnapshot)a=d.flowSnapshot.folder;else{let{flowService:b}=await Promise.resolve().then(c.bind(c,5385));a=(await b.getFlow(d.flowId))?.folder}}catch{}let b=await (0,k.H3)(t,n,{flowId:d.flowId,folder:a,executionAuthority:d.executionAuthority,personaAttribution:d.personaAttribution});"skipped"in b?D.warn("captureKv skipped",{captureKv:t,reason:b.skipped}):D.info("Captured subflow output into persistent kv",{captureKv:t,nodeId:e?.id})}catch(a){(0,l.Vj)(a),D.error("captureKv failed; continuing run",a)}if(h){let a=Date.now();h.status="folded",h.foldedAt=a,h.updatedAt=a,d.activeSubflowInvocationByNode?.[h.parentNodeId]===h.id&&delete d.activeSubflowInvocationByNode[h.parentNodeId],await (0,q.f6)(d)}return this.continuationAction(d,e)}continuationAction(a,b){let c=this.successors instanceof Map?Array.from(this.successors.keys()):Object.keys(this.successors||{});if(c.length>0){let a=c[0];return D.info(`post() completed, handing off via action: ${a}`),a}return b?.id&&a.pendingSubflowReturn?.subflowNodeId===b.id?(D.info("post() completed, terminal sub-agent returning to its Process caller",{callerNodeId:a.pendingSubflowReturn.callerNodeId}),f.V8):(D.info("post() completed, no successor → FINAL_RESPONSE_ACTION"),f.g4)}_clone(){return new P}}async function Q(a,b,d,e){let f=a.lanes??[],g=f.length,h=Math.max(1,a.concurrencyLimit??4),i=a.joinSeparator??"\n\n",j=a.errorStrategy??"collect-all",{FlowExecutor:k}=await Promise.resolve().then(c.bind(c,84901)),l=a.parentRunId?k.conversationStates.get(a.parentRunId):void 0,m=a.invocationId&&l?l.subflowInvocations?.[a.invocationId]:void 0,{ModelHandler:o}=await Promise.resolve().then(c.bind(c,77380)),p=await o.isSubflowSessionsEnabled();!p&&a.sessionScope&&"per-visit"!==a.sessionScope&&D.debug("Subflow sessionScope is configured but experimental.subflowSessions is disabled; falling back to per-visit",{nodeId:a.nodeId,sessionScope:a.sessionScope}),D.info("runSubflowLanes() running queued subflow jobs",{laneCount:g,concurrencyLimit:h,errorStrategy:j,depth:a.depth});let s=Array(g),t=0,u=!1,v=()=>(0,n.isCancelledByAncestry)(a.parentRunId,k.conversationStates),w=async c=>{let h=f[c],i=h.laneId&&m?m.lanes.find(a=>a.id===h.laneId):void 0,k=p&&a.persistConversation?(0,r.bS)(l?.logicalRunId??a.parentRunId,a.nodeId,a.sessionScope,h.sessionKey):void 0,n=k?await (0,r.PL)(k):void 0;try{let f,n,o;if(v()){u=!0;return}let p=!1,t=k&&l?.subflowSessions?.[k]?structuredClone(l.subflowSessions[k]):void 0;if(a.persistConversation){let b=(0,r.xB)(l,k,a.nodeId,h.sessionKey);f=b.conversationId,p=b.resumedVisit,n=i?.sessionVisit??b.sessionVisit,k||(f=h.conversationId??i?.conversationId??f)}if(p&&f){let b=await C({conversationId:f,childFlowId:h.subflowId,inputMode:a.sessionInputMode,sessionTurnCap:a.sessionTurnCap,nodeId:a.nodeId,executionAuthority:a.executionAuthority});"recovery"===b.kind?(k&&l&&t&&(l.subflowSessions??={},l.subflowSessions[k]=t),f=o=crypto.randomUUID(),p=!1,D.warn("Recovering unusable Subflow child session with a fresh conversation",{sessionIdentity:k,reason:b.reason,detail:b.detail})):(b.summarized||b.trimmedTurns>0)&&D.info("Prepared resumed Subflow transcript",{sessionIdentity:k,summarized:b.summarized,trimmedTurns:b.trimmedTurns})}i&&k&&(i.conversationId=f,i.sessionIdentity=k,i.sessionKey=h.sessionKey,i.resumedVisit=p,i.sessionVisit=n);let w=h.laneTitle??h.subflowName,x=O(a.emit,a.showSteps,d,h.subflowId,h.subflowName,{index:h.itemIndex??c,count:h.itemCount??g,title:w,conversationId:f,...void 0!==n&&h.sessionKey?{sessionKey:h.sessionKey}:{},...void 0!==n?{sessionVisit:n}:{}});if(i){if("completed"!==i.status&&(!p||i.attempt>0)&&await (0,q.XJ)(i)&&l&&(m.updatedAt=Date.now(),await (0,q.f6)(l)),"completed"===i.status){x?.({type:"run:start",flowId:h.subflowId}),x?.({type:"run:done",status:"completed"}),s[c]={subflowId:h.subflowId,success:!0,outputText:i.outputText,outputMedia:i.outputMedia,laneId:i.id,conversationId:i.conversationId,sessionKey:i.sessionKey};return}i.status="running",i.attempt+=1,i.error=void 0,i.updatedAt=Date.now(),m.status="running",m.updatedAt=Date.now(),l&&await (0,q.f6)(l)}try{let d=p?function(a){var b;if("prompt"in a)return{prompt:a.prompt};let c=[...a.messages].reverse().find(a=>("user"===a.role||"assistant"===a.role)&&(E(a.content)||(a.media?.length??0)>0));return c?{messages:[{role:"user",content:(b=c.content,"string"==typeof b?b:Array.isArray(b)?b.map(a=>a&&"object"==typeof a?"string"==typeof a.text?a.text:"string"==typeof a.refusal?a.refusal:"":"").join(""):""),id:crypto.randomUUID(),timestamp:Date.now(),...c.media?.length?{media:structuredClone(c.media)}:{}}]}:{prompt:""}}(h.input??e):h.input??e,j=await b({flowId:h.subflowId,...d,source:"subflow",mode:a.persistConversation?"conversation":"ephemeral",...f?{conversationId:f}:{},...p?{resumeAsNewTurn:!0}:{},...a.persistConversation&&w?{title:w}:{},flujo:!0,requireApproval:!1,debug:!1,depth:a.depth,chainDepth:a.chainDepth,parentRunId:a.parentRunId,lane:{laneIndex:h.itemIndex??c,laneCount:h.itemCount??g,...w?{laneTitle:w}:{},...f?{conversationId:f}:{},...a.invocationId?{invocationId:a.invocationId}:{},...h.laneId?{laneId:h.laneId}:{},...a.nodeId?{parentNodeId:a.nodeId}:{},...void 0!==n&&k?{sessionIdentity:k}:{},...void 0!==n&&h.sessionKey?{sessionKey:h.sessionKey}:{},...void 0!==n?{sessionVisit:n}:{}},...a.plannedExecutionId?{plannedExecutionId:a.plannedExecutionId}:{},...a.personaAttribution?{personaAttribution:a.personaAttribution}:{},...a.executionAuthority?{executionAuthority:a.executionAuthority}:{},...x?{emit:x}:{}});o&&k&&l&&j.sharedState?.conversationId===o&&(l.subflowSessions??={},l.subflowSessions[k]={version:1,conversationId:o,nodeId:a.nodeId,sessionKey:(0,r.dd)(h.sessionKey),visits:t?.visits??0,lastUsedAt:Date.now(),status:"running"},i&&(i.conversationId=o));let u=!!(j.sharedState?.isCancelled||j.sharedState?.recovery?.classification==="cancelled"),v=j.outputText?.trim()||j.outputMedia?.length?j.outputText:function(a){if(!a)return"";for(let b=a.length-1;b>=0;b--){let c=a[b];if("assistant"!==c.role||c.tool_calls?.length)continue;let d=H(c.content).trim();if(d)return d}return""}(j.messages);s[c]="error"===j.status?{subflowId:h.subflowId,subflowName:h.subflowName,success:!1,error:j.error?.message||"Subflow execution failed",laneTitle:h.laneTitle,laneId:h.laneId,conversationId:f,sessionKey:h.sessionKey}:{subflowId:h.subflowId,subflowName:h.subflowName,success:!0,outputText:v,outputMedia:j.outputMedia,laneTitle:h.laneTitle,laneId:h.laneId,conversationId:f,sessionKey:h.sessionKey},i&&(i.status="error"===j.status?u?"cancelled":"error":"completed",i.outputText="error"===j.status?void 0:v,i.outputMedia="error"===j.status?void 0:j.outputMedia,i.error="error"===j.status?j.error?.message||"Subflow execution failed":void 0,i.updatedAt=Date.now(),m.updatedAt=Date.now(),l&&await (0,q.f6)(l)),(0,r.ND)(l,k,i?i.status:"error"===j.status?"error":"completed")}catch(a){s[c]={subflowId:h.subflowId,subflowName:h.subflowName,success:!1,error:a instanceof Error?a.message:String(a),laneTitle:h.laneTitle,laneId:h.laneId,conversationId:f,sessionKey:h.sessionKey},i&&(i.status="error",i.outputText=void 0,i.outputMedia=void 0,i.error=a instanceof Error?a.message:String(a),i.updatedAt=Date.now(),m.updatedAt=Date.now(),l&&await (0,q.f6)(l)),(0,r.ND)(l,k,"error"),x?.({type:"run:done",status:"error"})}s[c].success||"fail-fast"!==j||(u=!0)}finally{n?.()}},x=new Map;f.forEach((b,c)=>{let d=(p&&a.persistConversation?(0,r.bS)(l?.logicalRunId??a.parentRunId,a.nodeId,a.sessionScope,b.sessionKey):void 0)??`per-visit:${c}`,e=x.get(d)??[];e.push(c),x.set(d,e)});let y=[...x.values()],z=async()=>{for(;;){if(u)return;if(v()){u=!0;return}let a=y[t++];if(!a)return;for(let b of a){if(u||v()){u=!0;return}await w(b)}}},A=Math.min(h,y.length);await Promise.all(Array.from({length:A},()=>z()));let B=s.filter(a=>void 0!==a),F=B.filter(a=>a.success),G=B.filter(a=>!a.success),I=G.length>0,J=!!m?.lanes.some(a=>"cancelled"===a.status||"pending"===a.status||"running"===a.status);if(m&&l){let a="fail-fast"===j&&I||J||m.lanes.every(a=>"completed"!==a.status);m.status=a?"blocked":"ready",m.updatedAt=Date.now(),await (0,q.f6)(l)}if("fail-fast"===j&&I){let a=B.find(a=>!a.success);return{success:!1,error:a?.error||"A parallel subflow lane failed",subStatus:"error",lanes:B}}if(J)return{success:!1,error:"Subflow execution was cancelled before every queued job completed",subStatus:"error",lanes:B};if(0===F.length)return{success:!1,error:1===B.length?B[0]?.error||"Subflow execution failed":"All queued subflow jobs failed",subStatus:"error",lanes:B};let K=F.map(a=>a.outputText??"").join(i),L=F.flatMap(a=>a.outputMedia??[]);if(I){let a=G.map(a=>`- ${a.subflowId}: ${a.error??"unknown error"}`).join("\n");K+=`${i}[${G.length} queued subflow job(s) failed:
|
|
12
12
|
${a}]`}return{success:!0,outputText:K,outputMedia:L.length>0?L:void 0,subStatus:"completed",lanes:B,partial:I}}},8619:(a,b,c)=>{"use strict";let d;c.d(b,{It:()=>F,Ys:()=>G,bW:()=>H,fq:()=>C,j2:()=>D,k:()=>s,pZ:()=>z,z9:()=>A});var e=c(55511),f=c(29021),g=c(33873),h=c.n(g),i=c(65326),j=c(66844),k=c(65445),l=c(7986);let m=(0,j.h)("backend/services/statistics"),n=/^\d{4}-\d{2}-\d{2}$/,o=()=>d??h().join((0,l.getWorkspaceDataDir)(),"db","statistics"),p=new Map,q=new Map,r=new Map;function s(a){let b=(0,i.N5)({...a,schemaVersion:i.DO,eventId:(0,e.randomUUID)(),timestamp:a.timestamp??new Date().toISOString()});if(!b)throw TypeError("Invalid statistics event");return b}function t(a,b){if(!n.test(b))throw TypeError("Invalid statistics day");return h().join(a,`${b}.jsonl`)}function u(a,...b){return[h().resolve(a),...b].join("\0")}async function v(a,b){let c=u(a,"statistics-prune");if(r.get(c)===b)return;r.set(c,b);let d=Date.parse(`${b}T00:00:00.000Z`)-7776e6;try{let b=await f.promises.readdir(a,{withFileTypes:!0});await Promise.all(b.map(async b=>{if(!b.isFile()||!b.name.endsWith(".jsonl"))return;let c=b.name.slice(0,-6);n.test(c)&&Date.parse(`${c}T00:00:00.000Z`)<d&&await f.promises.unlink(h().join(a,b.name))}))}catch{}}function w(a,b,c){let d=u(a,"statistics",b),e=(p.get(d)??Promise.resolve()).catch(()=>void 0).then(c);return p.set(d,e),e.finally(()=>{p.get(d)===e&&p.delete(d)}).catch(()=>void 0),e}let x=/^[A-Za-z0-9_-]{1,64}$/;async function y(a,b,c){let d;try{d=await f.promises.readFile(t(a,b),"utf8")}catch(a){if("ENOENT"===a.code)return 0;throw a}let e=0,g=d.split("\n").map(a=>{let b;if(!a.trim())return a;try{b=JSON.parse(a)}catch{if(RegExp(`"personaAttribution"\\s*:\\s*\\{[^}\\r\\n]*"personaId"\\s*:\\s*"${c}"`).test(a))return e+=1,"";return a}if(!b||"object"!=typeof b||Array.isArray(b))return a;let d=b,f=d.personaAttribution;return!f||"object"!=typeof f||Array.isArray(f)||f.personaId!==c?a:(delete d.personaAttribution,e+=1,JSON.stringify((0,i.N5)(d)??d))}).join("\n");return e>0&&await (0,k.Zf)(t(a,b),g),e}async function z(a){let b;if(!x.test(a))throw TypeError("Invalid Persona id for statistics anonymization");let c=o();await B();try{b=await f.promises.readdir(c,{withFileTypes:!0})}catch(a){if("ENOENT"===a.code)return 0;throw a}let d=b.filter(a=>a.isFile()&&a.name.endsWith(".jsonl")).map(a=>a.name.slice(0,-6)).filter(a=>n.test(a));return(await Promise.all(d.map(b=>w(c,b,()=>y(c,b,a))))).reduce((a,b)=>a+b,0)}function A(a){(function(a){let b=(0,i.N5)(a);if(!b)return Promise.reject(TypeError("Invalid or unsupported statistics event"));let c=function(a){let b=a.slice(0,10);if(!n.test(b)||!Number.isFinite(Date.parse(`${b}T00:00:00.000Z`)))throw TypeError("Statistics event timestamp does not contain a valid UTC day");return b}(b.timestamp),d=o();return w(d,c,async()=>{await f.promises.mkdir(d,{recursive:!0}),await f.promises.appendFile(t(d,c),`${JSON.stringify(b)}
|
|
13
|
-
`,"utf8"),await v(d,c)})})(a).catch(()=>{m.warn("Statistics event append failed",{type:a.type})})}async function B(){for(;p.size>0;)await Promise.allSettled([...p.values()])}async function C(a){let b=o();try{let c=await f.promises.stat(t(b,a));return{day:a,exists:!0,mtimeMs:c.mtimeMs,size:c.size}}catch(b){if("ENOENT"===b.code)return{day:a,exists:!1};throw b}}async function D(a){let b,c=o();try{b=await f.promises.readFile(t(c,a),"utf8")}catch(a){if("ENOENT"===a.code)return[];throw a}let d=[],e=0;for(let a of b.split("\n"))if(a.trim())try{let b=(0,i.N5)(JSON.parse(a));b?d.push(b):e+=1}catch{e+=1}return e>0&&m.warn("Ignored invalid statistics records",{day:a,count:e}),d}async function E(a){let b=h().join(a,".installation-key");await f.promises.mkdir(a,{recursive:!0});try{return await f.promises.readFile(b)}catch(a){if("ENOENT"!==a.code)throw a}let c=(0,e.randomBytes)(32);try{return await f.promises.writeFile(b,c,{flag:"wx",mode:384}),c}catch(a){if("EEXIST"===a.code)return f.promises.readFile(b);throw a}}async function F(a){if(!a)return;let b=o(),c=u(b,"statistics-installation-key"),d=q.get(c);d||(d=E(b),q.set(c,d));let f=await d;return`cred_${(0,e.createHmac)("sha256",f).update(a).digest("base64url").slice(0,22)}`}function G(a){let b="object"==typeof a&&null!==a?String(a.code??a.type??""):"",c=a instanceof Error?a.name:"",d=`${b} ${c}`.toLowerCase();return/cancel|abort/.test(d)?"cancelled":/401|authenticat|api_key/.test(d)?"authentication":/403|permission|authoriz/.test(d)?"authorization":/429|rate.?limit/.test(d)?"rate_limit":/context|token.?limit/.test(d)?"context_limit":/timeout/.test(d)?"timeout":/network|fetch|socket|econn/.test(d)?"network":/config|model_not_found/.test(d)?"configuration":/valid|parse|schema/.test(d)?"validation":/provider|api_error/.test(d)?"provider":"unknown"}function H(a){let b=a.toLowerCase();return b.includes("disabled")?"disabled":b.includes("deleted")?"deleted":b.includes("encryption locked")?"encryption_locked":b.includes("queue full")||b.includes("queue cap")?"queue_full":b.includes("exclusive")?"exclusive_lock":b.includes("overlap")||b.includes("previous run")?"overlap":b.includes("pause")?"paused":b.includes("duplicate")?"duplicate":b.includes("ineligible")||b.includes("no longer")?"ineligible":"unknown"}},8677:(a,b,c)=>{"use strict";c.d(b,{AP:()=>m,JG:()=>l});var d=c(21627),e=c(75505),f=c(66844),g=c(62511);let h=(0,f.h)("backend/mcpApps/toolUi");function i(a){return!!a&&"object"==typeof a&&!Array.isArray(a)}async function j(a){try{let b=await d.mcpService.loadServerConfigs();if(!Array.isArray(b))return!1;let c=b.find(b=>b.name===a);return c?.source?.type==="marketplace"&&"@mario.andreschak/mcp-flujo"===c.source.id}catch(b){return h.warn(`Failed to verify FLUJO control server provenance for ${a}`,b),!1}}async function k(a,b,c,f){if(!(0,e.DG)(c))return;let i=(0,e.Gt)(f?._meta);i&&i!==c&&h.warn(`Ignoring MCP App result URI redirect for ${a}/${b}: ${i}`);let j=(0,g.AQ)(f),k={uri:c,serverName:a,toolName:b,...j?{toolOwnerScope:j}:{}};try{return await d.mcpService.isMcpAppAccessEnabled(a)?k:void 0}catch(b){h.warn(`resolveAdvertisedToolUiLink: failed to check MCP Apps opt-in for ${a}`,b);return}}async function l(a,b,c,f,g){if((0,e.DG)(c))return k(a,b,c,f);let l="call_mcp_tool"===b?function(a){if(!i(a))return;let b="string"==typeof a.server?a.server.trim():"",c="string"==typeof a.tool?a.tool.trim():"";if(b&&c)return{serverName:b,toolName:c,toolArgs:i(a.args)?a.args:{}}}(g):void 0;if(l&&await j(a))try{let{tools:a}=await d.mcpService.listServerTools(l.serverName,"model"),b=Array.isArray(a)?a.find(a=>a.name===l.toolName):void 0,c=(0,e.Gt)(b?._meta),g=await k(l.serverName,l.toolName,c,f);return g?{...g,toolArgs:JSON.stringify(l.toolArgs)}:void 0}catch(a){h.warn(`Failed to resolve forwarded MCP App for ${l.serverName}/${l.toolName}`,a);return}}function m(a){if(!a.success&&("cancelled"===a.errorType||"timeout"===a.errorType))return a.error??("timeout"===a.errorType?"Tool execution timed out.":"Tool call was cancelled.")}},10031:(a,b,c)=>{"use strict";c.d(b,{GG:()=>m,MM:()=>t,aC:()=>s,gw:()=>l,hk:()=>p,oV:()=>q,wL:()=>r});var d=c(55511),e=c(68751),f=c(74294),g=c(47570);let h=(0,d.randomUUID)(),i="A tool may have produced an external side effect before execution stopped. Automatic replay is disabled; restart the turn or confirm the effect before retrying.";function j(a){return"number"==typeof a&&Number.isFinite(a)?a:void 0}function k(a){return"string"==typeof a&&a.length>0?a:void 0}function l(a){let b=a&&"object"==typeof a?a:{},c=b.details&&"object"==typeof b.details?b.details:b.errorDetails&&"object"==typeof b.errorDetails?b.errorDetails:b,d=j(c.status)??j(c.statusCode),e=k(c.code)??k(c.type)??k(b.code),f=a instanceof Error?a.message:"string"==typeof a?a:"string"==typeof a?.message?a.message:"string"==typeof a?.error?a.error:"Execution failed.",h=`${e??""} ${f}`.toLowerCase(),i="unknown",l=!1;429===d||/rate.?limit|too many requests/.test(h)?(i="rate_limit",l=!0):/context.{0,12}(limit|length|window)|maximum context/.test(h)?i="context_limit":/input.{0,12}(limit|length|too large)|request.{0,12}too large/.test(h)?i="input_limit":/session.{0,12}(lost|expired|invalid)|thread.{0,12}(lost|expired|not found)/.test(h)?i="session_loss":/empty response|no response content|response was empty/.test(h)?(i="model_empty_response",l=!0):/truncated response|unexpected end|premature end/.test(h)?(i="model_truncated_response",l=!0):/tool/.test(h)?i="tool_failure":408===d||502===d||503===d||504===d||/timeout|timed out|econnreset|econnrefused|socket|network|fetch failed|connection closed/.test(h)?(i="transport_failure",l=!0):(void 0!==d||/provider|model|api/.test(h))&&(i="provider_failure",l=void 0===d||d>=500);let m=j(c.retryAfterMs)??(0,g.oR)(c.retryAfter);return{classification:l?"retryable_failure":"permanent_failure",failure:{category:i,message:f,code:e,status:d,retryable:l},retryAfterAt:void 0!==m?Date.now()+Math.max(0,m):void 0}}function m(a,b){let c=Date.now(),e=a.recovery;if(e?.runId===b)return e.classification="running",e.ownerId=h,e.ownerHeartbeatAt=c,e.updatedAt=c,e.terminalAt=void 0,e.failure=void 0,e.retryAfterAt=void 0,e.manualActionRequired=!1,e.sideEffectWarning=void 0,a.recovery=e,e;let f={version:1,runId:b,attemptId:(0,d.randomUUID)(),attempt:1,classification:"running",parentRunId:a.parentRunId,ownerId:h,ownerHeartbeatAt:c,startedAt:c,updatedAt:c};return a.recovery=f,f}function n(a,b){let c=(a.messages??[]).slice(-8).map(a=>({id:a.id,role:a.role,content:a.content,toolCalls:a.tool_calls,toolCallId:a.tool_call_id}));return(0,d.createHash)("sha256").update(JSON.stringify({flowId:a.flowId,nodeId:b,messages:c})).digest("hex")}async function o(a,b,c,d){d?(d(c),b.conversationId&&!b.ephemeral&&await (0,e.flushConversationLog)(b.conversationId)):await (0,e.appendRawForState)(b,[c]),await (0,f.persistConversationState)(a,b)}async function p(a,b,c,e){if(b.ephemeral)return;let f=b.recovery??m(b,b.logicalRunId??(0,d.randomUUID)()),g=Date.now(),j={id:(0,d.randomUUID)(),phase:c.phase,nodeId:c.nodeId,turnEntryNodeId:c.turnEntryNodeId??f.lastSafeCheckpoint?.turnEntryNodeId??c.nodeId,attempt:f.attempt,inputFingerprint:n(b,c.nodeId),safe:c.safe,effectStatus:c.effectStatus??"none",parentRunId:b.parentRunId,lane:f.lane,tools:c.tools,createdAt:g};return f.currentCheckpoint=j,j.safe&&(f.lastSafeCheckpoint=j),f.ownerId=h,f.ownerHeartbeatAt=g,f.updatedAt=g,j.safe||"unknown"!==j.effectStatus||(f.manualActionRequired=!0,f.sideEffectWarning=i),b.recovery=f,await o(a,b,{type:"recovery:checkpoint",checkpoint:j},e),j}async function q(a,b,c,d,e){let f=c.map(a=>{let c=b.toolNameMap?.[a.function.name],d=c?.annotations,e=d?.readOnlyHint===!0;return{toolCallId:a.id,name:a.function.name,readOnly:e,idempotent:e||d?.idempotentHint===!0,destructive:d?.destructiveHint}});f.some(a=>!a.readOnly)&&await p(a,b,{phase:"before"===d?"tool:before":"completed"===d?"tool:after":"tool:unknown",nodeId:b.currentNodeId,safe:"completed"===d,effectStatus:"before"===d?"pending":"completed"===d?"completed":"unknown",tools:f},e)}async function r(a,b,c,e={},f){let g=function(a,b,c={}){let e=a.recovery??m(a,a.logicalRunId??(0,d.randomUUID)()),f=Date.now();return e.classification=b,e.failure=c.failure,e.retryAfterAt=c.retryAfterAt,e.cancellationRequestedAt=c.cancellationRequestedAt??e.cancellationRequestedAt,e.manualActionRequired=c.manualActionRequired??e.manualActionRequired,e.sideEffectWarning=c.sideEffectWarning??e.sideEffectWarning,e.updatedAt=f,e.ownerHeartbeatAt=f,"running"!==b&&"paused"!==b&&(e.terminalAt=f),a.recovery=e,e}(b,c,e);return await o(a,b,{type:"recovery:transition",recovery:{...g}},f),g}async function s(a,b){let c=b.recovery;return"running"===b.status&&!!c?.ownerId&&c.ownerId!==h&&(b.status="error",b.isCancelled=!1,b.lastResponse={success:!1,error:"Execution was interrupted before it reached a terminal boundary."},await r(a,b,"interrupted",{failure:{category:"unclean_process_interruption",message:"The process that owned this run is no longer active.",retryable:!1},manualActionRequired:!0}),!0)}function t(a,b="interrupted"){let c=a.recovery??m(a,a.logicalRunId??(0,d.randomUUID)()),e=Date.now(),f={id:(0,d.randomUUID)(),phase:"tool:unknown",nodeId:a.currentNodeId,turnEntryNodeId:c.lastSafeCheckpoint?.turnEntryNodeId,attempt:c.attempt,inputFingerprint:n(a,a.currentNodeId),safe:!1,effectStatus:"unknown",parentRunId:a.parentRunId,lane:c.lane,createdAt:e};c.currentCheckpoint=f,c.classification=b,c.failure={category:"tool_failure",message:"A dangling tool call was repaired after interruption; its external effect is unknown.",retryable:!1},c.manualActionRequired=!0,c.sideEffectWarning=i,c.updatedAt=e,c.terminalAt="interrupted"===b?e:void 0,a.recovery=c}},10408:(a,b,c)=>{"use strict";c.d(b,{$X:()=>u,CW:()=>t,KO:()=>q,Mw:()=>x,lp:()=>v});var d=c(33873),e=c.n(d),f=c(29021),g=c(66844),h=c(7986),i=c(65445),j=c(20149),k=c(53506),l=c(1230);let m=(0,g.h)("backend/execution/flow/conversationSummaryStore");function n(){return e().join((0,h.getWorkspaceDataDir)(),"db","conversations")}function o(){return e().join((0,h.getWorkspaceDataDir)(),"db","conversation-summaries")}function p(a){return e().join(o(),`${a}.json`)}function q(a,b="Untitled Conversation"){if(!("schedule"===a.source||!a.source&&a.plannedExecutionId&&!a.parentConversationId))return a.title||b;if("completed"===a.status||"capped"===a.status){let b="string"==typeof a.lastResponse&&a.lastResponse.trim()?a.lastResponse:function(a){for(let b=a.messages.length-1;b>=0;b-=1){let c=a.messages[b];if("assistant"===c.role&&"string"==typeof c.content&&c.content.trim())return c.content}}(a);if(b)return(0,l.oO)(b)}let c=a.statisticsPlannedExecutionName?.trim();return c?(0,l.oO)(c):"Automation run"}function r(a,b){let c;return{id:a.conversationId||b,title:q(a),flowId:a.flowId||null,...a.status?{status:a.status}:{},createdAt:a.createdAt||0,updatedAt:a.updatedAt||0,...void 0!==a.lastUserMessageAt?{lastUserMessageAt:a.lastUserMessageAt}:{},...void 0!==a.plannedExecutionId?{plannedExecutionId:a.plannedExecutionId}:{},...void 0!==a.parentConversationId?{parentConversationId:a.parentConversationId}:{},...void 0!==a.rootConversationId?{rootConversationId:a.rootConversationId}:{},...a.subflowLane?.sessionKey?{sessionKey:a.subflowLane.sessionKey}:{},...a.subflowLane?.sessionIdentity?{sessionIdentity:a.subflowLane.sessionIdentity}:{},...a.recovery?{recovery:a.recovery}:{},...void 0!==a.source?{source:a.source}:{},...(0,k.g)(a)?{personaOwned:!0}:{},...a.personaArchived?{personaArchived:!0}:{},...a.personaAttribution?.personaId??a.personaTargetId?{personaId:a.personaAttribution?.personaId??a.personaTargetId}:{},...(a.personaAttribution?.personaId??a.personaTargetId)&&a.personaBehaviorSlotKey?{personaBehaviorSlotKey:a.personaBehaviorSlotKey}:{},...a.personaAttribution?.activityId?{activityId:a.personaAttribution.activityId}:{},...a.personaAttribution?.behaviorRevisionId?{behaviorRevisionId:a.personaAttribution.behaviorRevisionId}:{},..."error"===a.status&&(c=a.lastError??(0,j.Jj)(a.lastResponse))?{lastError:{message:c.message,...c.code?{code:c.code}:{},...c.errorClass?{errorClass:c.errorClass}:{}}}:{}}}async function s(a,b,c){if((0,i.ln)(a),b.personaAttribution&&!b.executionAuthority)throw Error("Persona-attributed conversation summaries require current execution authority.");let d=async()=>{let d=c??await f.promises.stat(e().join(n(),`${a}.json`)),g={version:9,...r(b,a),snapshotMtimeMs:d.mtimeMs,snapshotSize:d.size};await (0,i.l_)(`conversation-summaries/${a}`,()=>(0,i.Zf)(p(a),JSON.stringify(g,null,2)))};b.executionAuthority?.commitWhileCurrent?await b.executionAuthority.commitWhileCurrent(d):(await b.executionAuthority?.assertCurrent(),await d())}async function t(a,b){try{await s(a,b)}catch(b){m.warn(`Could not refresh conversation summary ${a}; it will be rebuilt on list.`,b)}}async function u(a,b){await s(a,b)}async function v(a){try{(0,i.ln)(a),await (0,i.l_)(`conversation-summaries/${a}`,async()=>{try{await f.promises.unlink(p(a))}catch(a){if("ENOENT"!==a.code)throw a}})}catch(b){m.warn(`Could not delete conversation summary ${a}.`,b)}}async function w(){let a;try{a=await f.promises.readdir(o())}catch(a){if("ENOENT"===a.code)return new Map;throw a}let b=new Map,c=0,d=async()=>{for(;;){let d=a[c++];if(!d)return;if(!(!d.endsWith(".json")||d.includes(".tmp.")||d.includes(".corrupted.")))try{let a=JSON.parse(await f.promises.readFile(e().join(o(),d),"utf8")),c=d.replace(/\.json$/,"");(0,i.ln)(c),9===a.version&&"string"==typeof a.id&&b.set(c,a)}catch(a){m.warn(`Skipping unreadable conversation summary ${d}; it will be rebuilt if needed.`,a)}}};return await Promise.all(Array.from({length:Math.min(32,Math.max(1,a.length))},()=>d())),b}async function x(){let a;try{a=(await f.promises.readdir(n())).filter(a=>a.endsWith(".json"))}catch(a){if("ENOENT"===a.code)return[];throw a}let b=await w(),c=Array(a.length).fill(null),d=0,g=async()=>{for(;;){let g=d++;if(g>=a.length)return;let h=a[g],j=h.replace(/\.json$/,"");try{(0,i.ln)(j);let a=e().join(n(),h),d=await f.promises.stat(a),k=b.get(j);if(k&&k.snapshotMtimeMs===d.mtimeMs&&k.snapshotSize===d.size){c[g]=function(a){let{version:b,snapshotMtimeMs:c,snapshotSize:d,...e}=a;return e}(k);continue}let l=JSON.parse(await f.promises.readFile(a,"utf8"));c[g]=r(l,j),await s(j,l,d)}catch(a){m.warn(`Skipping unreadable conversation snapshot ${h}.`,a)}}};return await Promise.all(Array.from({length:Math.min(32,Math.max(1,a.length))},()=>g())),c.filter(a=>null!==a)}},10837:(a,b,c)=>{"use strict";c.d(b,{E5:()=>j,Jp:()=>g,M6:()=>e,Ne:()=>d,O:()=>i,V8:()=>k,g4:()=>h,xg:()=>f});let d=["chat","api","schedule","trigger","subflow","mcp","internal","meeting"];function e(a){return"string"==typeof a&&d.includes(a)}function f(a){return"chat"!==a&&"api"!==a}let g="TOOL_CALL",h="FINAL_RESPONSE",i="ERROR",j="STAY_ON_NODE",k="IMPLICIT_SUBFLOW_RETURN"},12969:(a,b,c)=>{"use strict";c.d(b,{A:()=>d});let d=8},14671:(a,b,c)=>{"use strict";c.d(b,{Av:()=>g,By:()=>d,E9:()=>f,gP:()=>h});let d="call_subflow_";function e(a,b){let c=new Set,d=new Map;for(let e of a){if(d.has(e.id))continue;let a=function(a,b){let c=(a&&a.trim()||b&&b.trim()||"node").toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/_+/g,"_").replace(/^_+|_+$/g,"");return c.length>48&&(c=c.slice(0,48).replace(/_+$/g,"")),c||(c=b&&b.trim().toLowerCase().replace(/[^a-z0-9]+/g,"_")||"node"),c||"node"}(e.label,e.type),f=`${b}${a}`;if(c.has(f)){let d=2;for(;c.has(`${b}${a}_${d}`);)d++;f=`${b}${a}_${d}`}c.add(f),d.set(e.id,f)}return d}function f(a){return e(a,"handoff_to_")}function g(a){return e(a,d)}function h(a){return a.startsWith(d)}},17350:(a,b,c)=>{"use strict";c.d(b,{B1:()=>n,J2:()=>m,JM:()=>k,W5:()=>j,ll:()=>o,pb:()=>l});var d=c(66844),e=c(58253),f=c(47798),g=c(77823),h=c(49233);let i=(0,d.h)("backend/flow/execution/handlers/runResourceTools"),j="write_resource",k="read_resource";function l(a){return a===j||a===k}function m(){return{name:k,description:"Read resource content by URI or file path. Supports stored flujo://run/... resources, native MCP URIs, and paths readable by a bound filesystem MCP. Use list_mcp_resources to find native URIs. Large or binary resources may return a flujo://run/... URI.",inputSchema:{type:"object",properties:{uri:{type:"string",description:"A flujo://run/... URI, native MCP URI, file:// URI, or filesystem path."},max_chars:{type:"integer",minimum:1,maximum:2e5,description:"Optional bounded text limit. Visual archives default to 50,000 characters."},expected_sha256:{type:"string",pattern:"^[a-fA-F0-9]{64}$",description:"Optional SHA-256 to verify against the immutable stored payload."}},required:["uri"]}}}function n(a){let b=(a??[]).filter(a=>"produce"===a.role&&a.properties?.scope==="run"&&!!a.properties?.runName?.trim());if(0===b.length)return[];let c=Array.from(new Set(b.map(a=>a.properties.runName.trim()))),d=c.map(a=>`"${a}"`).join(", ");return[{name:j,description:`Produce/update a run artifact — a named data output of this flow run that later steps can read via \${res:NAME} and that appears in the run-data panel. Write the artifact's FULL content here rather than only describing it in your reply. This step is wired to produce: ${d}. Writing the same name again replaces the previous content (last write wins).`,inputSchema:{type:"object",properties:{name:{type:"string",description:`The artifact name to write. Use one of: ${c.join(", ")}.`},content:{type:"string",description:"The full content of the artifact (text/markdown)."}},required:["name","content"]}}]}async function o(a,b,c){if(a===k)return p(b,c);if(a!==j)return{success:!1,error:`Unknown run-resource tool: ${a}`};if(!c.conversationId||c.ephemeral)return{success:!1,error:"Run artifacts are not available in this run."};let d="string"==typeof b?.name?b.name.trim():"";if(!d)return{success:!1,error:'write_resource requires a non-empty "name".'};let g="string"==typeof b?.content?b.content:"";try{return await (0,e.Gi)(c,async()=>{let a=await (0,f.tm)({conversationId:c.conversationId,name:d,mimeType:"text/markdown",kind:"text",data:{text:g},producedBy:{source:"capture",nodeId:c.node?.nodeId,nodeName:c.node?.nodeName}});return"skipped"in a?(i.warn("write_resource skipped by store cap",{name:d,reason:a.skipped}),{success:!1,error:`Artifact not stored (${a.skipped}).`}):(c.emit?.({type:"resource:write",node:c.node,server:"flujo",uri:a.uri,name:d,mimeType:a.mimeType,size:a.size,source:"capture"}),i.info("write_resource stored run artifact",{name:d,uri:a.uri,size:a.size}),{success:!0,data:{written:!0,name:d,uri:a.uri,size:a.size}})})}catch(a){return(0,e.Vj)(a),i.error("write_resource failed",a),{success:!1,error:a instanceof Error?a.message:String(a)}}}async function p(a,b){let c="string"==typeof a?.uri?a.uri.trim():"";if(!c)return{success:!1,error:'read_resource requires a non-empty "uri".'};let d=(0,f.Ns)(c);if(!d)return c.startsWith(g.j0)?{success:!1,error:`Invalid run-resource URI: ${c}`}:b.mcpNodes&&b.mcpNodes.length>0?(0,h.Nl)(c,{conversationId:b.conversationId,nodeId:b.node?.nodeId,ephemeral:b.ephemeral,mcpNodes:b.mcpNodes,emit:b.emit,node:b.node,executionAuthority:b.executionAuthority,personaAttribution:b.personaAttribution}):{success:!1,error:`Not a run-resource URI: ${c}`};if(b.conversationId&&d.conversationId!==b.conversationId)return{success:!1,error:`Run resource ${c} is not part of this run.`};try{return await (0,e.Gi)(b,async()=>{let d="number"==typeof a?.max_chars&&Number.isFinite(a.max_chars)?Math.floor(a.max_chars):void 0,e="string"==typeof a?.expected_sha256?a.expected_sha256.trim():void 0,g={at:Date.now(),source:"tool-read",nodeId:b.node?.nodeId},h=void 0!==d||e?await (0,f.fg)(c,{maxChars:d,expectedSha256:e,access:g}):null,j=h?null:await (0,f.gy)(c,g);if(!h&&!j)return{success:!1,error:`Run resource not found: ${c}`};let k=h?.entry??j.entry,l=j?.contents;b.emit?.({type:"resource:read",node:b.node,server:"flujo",uri:k.uri,name:k.name,mimeType:k.mimeType,size:k.size,source:"tool-read"});let m=(l?.contents??[]).map(a=>"string"==typeof a.text?a.text:"").filter(a=>a.length>0),n=h?.content??(m.length>0?m.join("\n"):`[binary run resource ${k.mimeType??k.kind} (${k.size} bytes) at ${k.uri}]`),o="text"!==k.kind&&"link"!==k.kind?await (0,f.QT)(k.uri):null;return i.info("read_resource served run resource",{uri:k.uri,size:k.size}),{success:!0,data:{uri:k.uri,name:k.name,mimeType:k.mimeType,content:n,truncated:h?.truncated??!1,sha256:k.sha256,verification:h?.verification,...o?{localPath:o}:{}}}})}catch(a){return(0,e.Vj)(a),i.error("read_resource failed",a),{success:!1,error:a instanceof Error?a.message:String(a)}}}},17943:(a,b,c)=>{"use strict";c.d(b,{ND:()=>m,PL:()=>i,bS:()=>j,dd:()=>f,p:()=>g,p$:()=>d,xB:()=>l});let d=128,e=/\{\{[^{}]+\}\}|\$\{[^{}]+\}|@\{[^{}]+\}/;function f(a){if(null==a)return;let b=String(a).trim();if(!(!b||b.length>d||e.test(b)))return b}function g(a){if(null==a||""===a)return;let b="number"==typeof a?a:Number(a);return Number.isSafeInteger(b)&&b>0?b:void 0}let h=new Map;async function i(a){let b,c=h.get(a);c||(c={tail:Promise.resolve(),claims:0},h.set(a,c));let d=c.tail;c.tail=new Promise(a=>{b=a}),c.claims+=1,await d;let e=!1;return()=>{e||(e=!0,c.claims-=1,b(),0===c.claims&&h.get(a)===c&&h.delete(a))}}function j(a,b,c,d){if(!a||!b||!c||"per-visit"===c)return;if("per-run"===c)return`${a}::${b}::`;let e=f(d);if("per-key"===c&&e)return`${a}::${b}::${encodeURIComponent(e)}`}function k(a){return(Number.isFinite(a.visits)?Math.max(0,Math.floor(a.visits)):0)+1}function l(a,b,c,d){if(!b||!a)return{conversationId:crypto.randomUUID?crypto.randomUUID():n(),resumedVisit:!1};let e=a.subflowSessions?.[b];if(e&&e.conversationId)return e.lastUsedAt=Date.now(),e.status="running",{conversationId:e.conversationId,resumedVisit:!0,sessionVisit:k(e)};let g=crypto.randomUUID?crypto.randomUUID():n();return a.subflowSessions||(a.subflowSessions={}),a.subflowSessions[b]={version:1,conversationId:g,nodeId:c,sessionKey:f(d),visits:0,lastUsedAt:Date.now(),status:"running"},{conversationId:g,resumedVisit:!1,sessionVisit:k(a.subflowSessions[b])}}function m(a,b,c){if(!b||!a)return;let d=a.subflowSessions?.[b];d&&(d.visits+=1,d.lastUsedAt=Date.now(),d.status="completed"===c?"idle":"error"===c?"failed":"idle")}function n(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){let b=16*Math.random()|0;return("x"===a?b:3&b|8).toString(16)})}},18126:(a,b,c)=>{"use strict";function d(...a){let b=a.filter(a=>!!a);if(0===b.length)return;if(1===b.length)return b[0];let c=AbortSignal.any;if("function"==typeof c)return c(b);let e=new AbortController,f=b.find(a=>a.aborted);if(f)return e.abort(f.reason),e.signal;for(let a of b)a.addEventListener("abort",()=>e.abort(a.reason),{once:!0});return e.signal}c.d(b,{N:()=>d})},19031:(a,b,c)=>{"use strict";c.d(b,{E0:()=>t,J1:()=>m,Sy:()=>l,eK:()=>s,m7:()=>r});var d=c(77598),e=c(73024),f=c(48161),g=c.n(f),h=c(76760),i=c.n(h),j=c(18477),k=c(7986);let l="flujo-auth-source.json",m={version:1,source:"workspace"};function n(){return process.env.CODEX_HOME?.trim()||i().join(g().homedir(),".codex")}async function o(a){let b,c=i().join(a,"config.toml"),d=!1;try{let a=await e.promises.lstat(c);d=!0;let f=a.isSymbolicLink()?await e.promises.stat(c):a;if(!f.isFile()||f.size>1048576)throw Error();let g=await e.promises.readFile(c),h=await e.promises.stat(c);if(g.length>1048576||g.length!==f.size||f.ino!==h.ino||f.size!==h.size||f.mtimeMs!==h.mtimeMs)throw Error();b=(0,j.qg)(new TextDecoder("utf-8",{fatal:!0}).decode(g))}catch(a){if(!d&&"ENOENT"===a.code)return;throw Error("Could not verify the host Codex credential store. Repair or make its config.toml readable before using its login in FLUJO.")}let f=b.cli_auth_credentials_store;if(void 0!==f&&"file"!==f)throw Error('FLUJO requires file-backed Codex authentication. Configure cli_auth_credentials_store = "file" and sign in again; keyring and auto storage cannot identify the active login from auth.json.')}async function p(a){try{let b=JSON.parse(await e.promises.readFile(i().join(a,l),"utf8"));if(b?.version!==1||!["host","workspace"].includes(b.source))throw Error("Invalid FLUJO Codex authentication source.");return b}catch(a){if("ENOENT"===a.code)return;throw Error("Could not read FLUJO Codex authentication source.")}}async function q(a,b){let c=`${a}.${(0,d.randomUUID)()}.tmp`;try{await e.promises.writeFile(c,b,{mode:384,flag:"wx"}),await e.promises.rename(c,a),await e.promises.chmod(a,384)}finally{await e.promises.rm(c,{force:!0})}}async function r(a){let b,c=await p(a),f=i().join(a,"auth.json");if(c?.source==="workspace")return void await e.promises.access(f).catch(()=>{throw Error("The worker Codex login is missing. Sign in using its CODEX_HOME.")});let g=n();await o(g);let h=i().join(g,"auth.json");if(i().resolve(h)===i().resolve(f))return;try{b=await e.promises.readFile(h)}catch(b){if("ENOENT"!==b.code)throw Error("Could not read the host Codex login.");await e.promises.rm(f,{force:!0}),await e.promises.rm(i().join(a,l),{force:!0});return}let j=(0,d.createHash)("sha256").update(b).digest("hex"),k=await e.promises.access(f).then(()=>!0,()=>!1);c?.sourceHash===j&&k||(await q(f,b),await q(i().join(a,l),JSON.stringify({version:1,source:"host",sourceHash:j})))}function s(a){try{let b=JSON.parse(a.toString("utf8"));return(!b.auth_mode||"chatgpt"===b.auth_mode)&&!b.OPENAI_API_KEY&&"string"==typeof b.tokens?.access_token&&b.tokens.access_token.length>0&&"string"==typeof b.tokens?.refresh_token&&b.tokens.refresh_token.length>0}catch{return!1}}async function t(a){let b,c=i().join((0,k.getWorkspaceDataDir)(a),"db","codex-runtime"),f=await p(c),g=f?.source==="workspace"?c:n();f?.source!=="workspace"&&await o(g);let h=i().join(g,"auth.json");if(f?.source==="host"&&f.sourceHash){let a=await e.promises.readFile(h).catch(()=>void 0);if(a&&(0,d.createHash)("sha256").update(a).digest("hex")===f.sourceHash){let a=i().join(c,"auth.json");await e.promises.access(a).then(()=>!0,()=>!1)&&(h=a)}}try{let a=await e.promises.lstat(h);if(!a.isFile()||a.isSymbolicLink()||a.size>1048576)throw Error();b=await e.promises.readFile(h);let c=await e.promises.lstat(h);if(a.ino!==c.ino||a.size!==c.size||a.mtimeMs!==c.mtimeMs)throw Error()}catch{throw Error("A file-backed Codex ChatGPT login is required. Sign in with Codex using file credential storage before cloning.")}if(!s(b))throw Error("The Codex authentication cache is not a transferable ChatGPT login.");return b}},20149:(a,b,c)=>{"use strict";c.d(b,{G1:()=>m,Jj:()=>k,NS:()=>l,g9:()=>j});var d=c(8619);let e=/^(authorization|api[-_]?key|x-api-key|cookie|set-cookie|proxy-authorization|www-authenticate)$/i,f=/sk-[A-Za-z0-9_-]{8,}/g,g=/bearer\s+[A-Za-z0-9._.~+/=-]{8,}/gi;function h(a){return"string"==typeof a&&a.length>0?a:void 0}function i(a){return"number"==typeof a&&Number.isFinite(a)?a:void 0}function j(a,b){let c,j=a&&"object"==typeof a&&a.details&&"object"==typeof a.details?a.details:void 0;c=a instanceof Error?a.message||"An unknown error occurred.":"string"==typeof a&&a.length>0?a:a&&"object"==typeof a&&h(a.message)?a.message:null==a?"An unknown error occurred.":String(a);let k=h(j?.code)??(a&&"object"==typeof a?h(a.code):void 0),l=i(j?.status)??(a&&"object"==typeof a?i(a.status):void 0),m=h(j?.type)??(a instanceof Error?h(a.name):void 0),n=h(j?.retryAfter),o=j?.providerError!==void 0?function(a){let b;if(null==a)return;let c=function a(b,c){if(c>6)return"[REDACTED: max depth exceeded]";if("string"==typeof b)return b.replace(g,"Bearer [REDACTED]").replace(f,"[REDACTED]");if(Array.isArray(b))return b.map(b=>a(b,c+1));if(b&&"object"==typeof b){let d={};for(let[f,g]of Object.entries(b))d[f]=e.test(f)?"[REDACTED]":a(g,c+1);return d}return b}(a,0);try{b=JSON.stringify(c)??""}catch{return{note:"[REDACTED: unserializable provider error body]"}}if(b)return b.length>8192?{note:"[REDACTED: provider error body truncated]",truncated:b.slice(0,8192)}:c&&"object"==typeof c&&!Array.isArray(c)?c:{value:c}}(j.providerError):void 0;return{message:c,...k?{code:k}:{},...void 0!==l?{httpStatus:l}:{},...m?{providerType:m}:{},errorClass:(0,d.Ys)(a instanceof Error?Object.assign(Error(a.message),{name:a.name,code:k,type:m}):{code:k,type:m}),...b?.nodeId?{nodeId:b.nodeId}:{},...b?.nodeName?{nodeName:b.nodeName}:{},...n?{retryAfter:n}:{},occurredAt:Date.now(),...o?{details:o}:{}}}function k(a){if(null!=a){if("string"==typeof a)return a.length>0?j(Error(a)):void 0;if("object"==typeof a&&!1===a.success){let b=h(a.error)??"An unknown error occurred.",c=a.errorDetails&&"object"==typeof a.errorDetails?a.errorDetails:void 0;return j(Object.assign(Error(b),c?{details:c}:{}))}}}function l(a,b,c,d){return a.errorEventEmitted?a.lastError:m(a,b,j(c,d),d)}function m(a,b,c,d){return a.errorEventEmitted?a.lastError??c:(a.errorEventEmitted=!0,a.lastError=c,b?.({type:"error",node:d?.nodeId?{nodeId:d.nodeId}:void 0,message:c.message,error:c}),c)}},20228:(a,b,c)=>{"use strict";c.d(b,{Mv:()=>m,RZ:()=>j,Wg:()=>l,wC:()=>k});var d=c(66844),e=c(7986);let f=(0,d.h)("backend/services/questionRegistry"),g=globalThis,h=g.__flujoQuestionRegistry??(g.__flujoQuestionRegistry=new Map);function i(a,b){return(0,e.workspaceCacheKey)(a,b)}function j(a,b,c,d=3e5){let g=i(a,b);return new Promise(i=>{let j=setTimeout(()=>{h.has(g)&&(f.warn(`Question ${b} (conv ${a}) timed out after ${d}ms`),h.delete(g),i({action:"timeout"}))},d);h.set(g,{workspace:(0,e.getCurrentWorkspace)(),conversationId:a,questionId:b,questions:c,createdAt:Date.now(),resolve:i,timer:j})})}function k(a,b,c){let d=i(a,b),e=h.get(d);return!!e&&(clearTimeout(e.timer),h.delete(d),e.resolve({action:"answer",answers:c}),!0)}function l(a,b){let c=i(a,b),d=h.get(c);return!!d&&(clearTimeout(d.timer),h.delete(c),d.resolve({action:"decline"}),!0)}function m(){let a=(0,e.getCurrentWorkspace)();return Array.from(h.values()).filter(b=>b.workspace===a).map(a=>({conversationId:a.conversationId,questionId:a.questionId,questions:a.questions,createdAt:a.createdAt}))}},20593:(a,b,c)=>{"use strict";c.d(b,{ToolHandler:()=>l});var d=c(66844),e=c(63342),f=c(21627),g=c(65385),h=c(49233),i=c(75505),j=c(88022);let k=(0,d.h)("backend/flow/execution/handlers/ToolHandler");class l{static sanitizeSchema(a){if(!a||"object"!=typeof a||Array.isArray(a))return{};let b=JSON.parse(JSON.stringify(a));if("string"===b.type&&b.format&&"enum"!==b.format&&"date-time"!==b.format&&(b.description||(b.description=""),b.description+=` (format: ${b.format})`,delete b.format),b.properties){let a=b.properties;Object.keys(a).forEach(b=>{a[b]=l.sanitizeSchema(a[b])})}if(Array.isArray(b.required))if(b.properties){let a=new Set(Object.keys(b.properties));b.required=b.required.filter(b=>"string"==typeof b&&a.has(b)),0===b.required.length&&delete b.required}else delete b.required;return b.items&&(b.items=l.sanitizeSchema(b.items)),Array.isArray(b.oneOf)&&(b.oneOf=b.oneOf.map(a=>l.sanitizeSchema(a))),Array.isArray(b.anyOf)&&(b.anyOf=b.anyOf.map(a=>l.sanitizeSchema(a))),Array.isArray(b.allOf)&&(b.allOf=b.allOf.map(a=>l.sanitizeSchema(a))),b}static prepareTools(a){let{availableTools:b}=a;if(k.verbose("prepareTools input",JSON.stringify(a)),!b||0===b.length){let a={success:!0,value:{tools:[]}};return k.verbose("prepareTools empty result",JSON.stringify(a)),a}try{for(let a of b){if(!a.name)return{success:!1,error:(0,e.Po)("invalid_tool","Tool missing required 'name' property","unknown")};if(!a.inputSchema)return{success:!1,error:(0,e.Po)("invalid_tool",`Tool '${a.name}' missing required 'inputSchema' property`,a.name)}}let a=[...b].sort((a,b)=>a.name<b.name?-1:+(a.name>b.name)).map(a=>({type:"function",function:{name:a.name,description:a.description||`Tool: ${a.name}`,parameters:l.sanitizeSchema(a.inputSchema)}})),c={success:!0,value:{tools:a}};return k.verbose("prepareTools success result",JSON.stringify(c)),c}catch(b){let a={success:!1,error:(0,e.Po)("tool_preparation_failed",b instanceof Error?b.message:String(b),"unknown")};return k.verbose("prepareTools error result",JSON.stringify(a)),a}}static async processMCPNodes(a){let{mcpNodes:b}=a;if(k.verbose("processMCPNodes input",JSON.stringify(a)),!b||0===b.length){let a={success:!0,value:{availableTools:[]}};return k.verbose("processMCPNodes empty result",JSON.stringify(a)),a}try{let a=[],c=[];try{let a=await f.mcpService.loadServerConfigs?.();c=Array.isArray(a)?a:[]}catch(a){k.warn("Could not load server-wide tool parameter presets",a)}for(let d of b){let b=d.properties;if(b&&b.boundServer){let h=b.boundServer,k=b.enabledTools||[],l=b.toolTimeout,m=c.find(a=>a.name===h);f.mcpService.setNodeRoots(h,d.id,b.roots);let n=await f.mcpService.connectServer(h);if(!n.success)return{success:!1,error:(0,e.Fp)("server_connection_failed",`Failed to connect to MCP server '${h}': ${n.error}`,h,"connect")};let o=await f.mcpService.listServerTools(h);if(o.error)return{success:!1,error:(0,e.Fp)("list_tools_failed",`Failed to list tools for MCP server '${h}': ${o.error}`,h,"listTools")};for(let c of(o.tools||[]).filter(a=>k.includes(a.name)).map(a=>{let c=(0,j.Ge)(m?.toolParameterPresets,b.toolParameterPresets,a.name),e=(0,g.az)(a.inputSchema);return f.mcpService.setToolSchemaHash(h,a.name,e),{originalName:a.name,server:h,nodeId:d.id,name:(0,g.Y6)(h,a.name),timeout:l,description:a.description,inputSchema:(0,j.Qm)(a.inputSchema,c),...Object.keys(c).length>0?{presetArgs:c}:{},annotations:a.annotations,clientGeneration:f.mcpService.getClientGeneration(h),schemaHash:e,uiResourceUri:(0,i.Gt)(a._meta)}}))a.some(a=>a.name===c.name)||a.push(c)}}try{for(let c of(await (0,h.QH)(b)))a.some(a=>a.name===c.name)||a.push(c)}catch(a){k.warn("processMCPNodes: buildMCPResourceTools failed, skipping resource tool",{resourceErr:a})}let d={success:!0,value:{availableTools:a}};return k.verbose("processMCPNodes success result",JSON.stringify(d)),d}catch(b){let a={success:!1,error:(0,e.Fp)("mcp_processing_failed",b instanceof Error?b.message:String(b),"unknown","processMCPNodes")};return k.verbose("processMCPNodes error result",JSON.stringify(a)),a}}}},20616:(a,b,c)=>{"use strict";c.d(b,{l:()=>d});let d=18e6},21627:(a,b,c)=>{"use strict";c.r(b),c.d(b,{MCPService:()=>bT,mcpService:()=>bU});var d=c(78796),e=c(79748),f=c.n(e),g=c(33873),h=c.n(g),i=c(66844),j=c(7986),k=c(74164),l=c(94247),m=c(80244);let n=(0,i.h)("backend/services/mcp/lifecycleCoordinator");function o(){return global.__flujo_mcp_lifecycle||(global.__flujo_mcp_lifecycle=new Map),global.__flujo_mcp_lifecycle}function p(a,b=(0,j.getCurrentWorkspace)()){return`${b}\0${a}`}function q(a){let b=(0,j.getCurrentWorkspace)(),c=p(a,b),d=o().get(c);return d||(d={key:c,workspace:b,serverName:a,state:"cold",generation:0,retryAttempts:0,connectFailures:0,handshakeFailures:0,forcedKills:0,leases:0,pins:new Set,lastUsedAt:Date.now()},o().set(c,d)),d}function r(a){return o().get(p(a))}function s(){let a=(0,j.getCurrentWorkspace)();return Array.from(o().values()).filter(b=>b.workspace===a)}async function t(a,b){let c=q(a);c.teardownPromise&&await c.teardownPromise.catch(()=>void 0);let d=c.connectPromise;if(d)return n.debug(`beginConnect: reusing in-flight attempt for ${a}`),d;c.state="warm"===c.state?"warm":"starting";let e=(async()=>b(c))().finally(()=>{c.connectPromise===e&&(c.connectPromise=void 0)});return c.connectPromise=e,e}let u=(0,i.h)("backend/services/mcp/mcpLeasePool");function v(){let a=Number(process.env.FLUJO_MCP_IDLE_TTL_MS);return Number.isFinite(a)&&a>0?a:6e5}function w(){let a=Number(process.env.FLUJO_MCP_MAX_WARM_SERVERS);return Number.isFinite(a)&&a>0?Math.floor(a):8}function x(){let a=()=>({acquires:0,coalesced:0,connects:0,failures:0,idleClosures:0,lruEvictions:0}),b=(0,j.getCurrentWorkspace)();if(b===j.DEFAULT_WORKSPACE)return global.__flujo_mcp_pool_counters||(global.__flujo_mcp_pool_counters=a()),global.__flujo_mcp_pool_counters;let c=global.__flujo_mcp_pool_counters_by_workspace??=new Map,d=c.get(b);return d||(d=a(),c.set(b,d)),d}function y(a,b,c){let d,e=!1;return d=q(a),d.leases+=1,d.lastUsedAt=Date.now(),{serverName:a,generation:c,client:b,isStale(){let b=r(a);return!b||b.generation!==c},release(){if(!e){let b;e=!0,(b=q(a)).leases=Math.max(0,b.leases-1),b.lastUsedAt=Date.now()}}}}async function z(a,b){if(x().acquires+=1,await a.isServerDisabled(b))return{success:!1,error:`Server '${b}' is disabled. Enable it on the MCP page to use it.`};let c=a.getClient(b);if(c){x().coalesced+=1;let a=q(b);return{success:!0,lease:y(b,c,a.generation)}}x().connects+=1;let d=await a.connectServer(b),e=a.getClient(b);if(!d.success||!e)return x().failures+=1,{success:!1,error:d.error??`Could not establish an MCP connection to '${b}'.`};let f=q(b);return{success:!0,lease:y(b,e,f.generation)}}function A(a,b){q(a).pins.add(b)}async function B(a){let b=v(),c=Date.now(),d=[];for(let e of s())"warm"!==e.state||e.leases>0||e.pins.size>0||c-e.lastUsedAt<b||!function(a){let b=r(a);return!!b&&(b.leases>0||b.pins.size>0)}(e.serverName)&&(u.info(`sweepIdleServers: closing ${e.serverName} after ${Math.round((c-e.lastUsedAt)/1e3)}s idle`),await a.disconnectServer(e.serverName).catch(()=>void 0),x().idleClosures+=1,d.push(e.serverName));return d}async function C(a){let b=w(),c=[];for(;;){let d=s().filter(a=>"warm"===a.state);if(d.length<=b)break;let e=d.filter(a=>0===a.leases&&0===a.pins.size).sort((a,b)=>a.lastUsedAt-b.lastUsedAt)[0];if(!e)break;u.info(`enforceWarmCapacity: evicting idle LRU server ${e.serverName} (warm=${d.length}, limit=${b})`),await a.disconnectServer(e.serverName).catch(()=>void 0),x().lruEvictions+=1,c.push(e.serverName)}return c}var D=c(9901),E=c(18705),F=c(88152),G=c(1262),H=c(35617),I=c(65445),J=c(74755),K=c(91019),L=c(90945),M=c(1477),N=c(8476),O=c(41231),P=c(29021),Q=c(21820),R=c(55511),S=c(80531),T=c(78705),U=c(61240),V=c(34887);let W=new Set(["npx","bunx","uvx","pipx","dlx"]),X=new Set(["pnpm","yarn","bun","npm"]),Y=new Set(["dlx","exec","x"]);function Z(a,b=[]){let c=((a||"").split(/[\\/]/).filter(Boolean).pop()||"").toLowerCase().replace(/\.(cmd|exe|bat|ps1)$/i,"");if(W.has(c))return!0;if(X.has(c)){let a=(b[0]||"").toLowerCase();return Y.has(a)}return!1}let $=new Set(["node","npm","npx"]);var _=c(51539),aa=c(51969),ab=c(42740),ac=c(39536),ad=c(70087);let ae=(0,i.h)("backend/services/mcp/sampling");function af(a){return a.sampling}function ag(a){let b=af(a);return!!(b?.enabled&&b.modelId)}function ah(a){let b=[];return async c=>{let d=af(a);if(!d?.enabled||!d.modelId)throw new D.Nh(D.O4.InvalidRequest,"Sampling is not enabled for this server");let e=d.maxCallsPerMinute??10,f=Date.now(),g=f-6e4;for(;b.length>0&&b[0]<g;)b.shift();if(b.length>=e)throw ae.warn(`Sampling rate limit (${e}/min) hit for ${a.name}`),new D.Nh(D.O4.InvalidRequest,`Sampling rate limit of ${e}/min exceeded`);b.push(f);let h=await ab.modelService.getModel(d.modelId);if(!h)throw new D.Nh(D.O4.InternalError,`Sampling model not found: ${d.modelId}`);let i=await ab.modelService.resolveAndDecryptApiKey(h.ApiKey);if(!i)throw new D.Nh(D.O4.InternalError,"Could not resolve the sampling model API key");let j=c.params,k=function(a){let b=[];for(let c of(a.systemPrompt&&b.push({role:"system",content:a.systemPrompt}),a.messages||[])){let a=c.content,d=a?.type==="text"&&"string"==typeof a.text?a.text:`[unsupported ${a?.type||"non-text"} content omitted]`;b.push({role:c.role,content:d})}return b}(j),l="number"==typeof j.temperature?j.temperature:.7;ae.info(`Sampling for ${a.name} via model ${h.name} (${k.length} messages)`);let m=(0,ac.getCompletionAdapter)(h),n=d.maxTokens??(0,ad.normalizeMaxTokens)(h.maxTokens),{completion:o}=await m.createCompletion({model:h,apiKey:i,messages:k,temperature:l,maxTokens:n}),p=o.choices?.[0]?.message?.content;return{role:"assistant",content:{type:"text",text:"string"==typeof p?p:""},model:h.name,stopReason:"endTurn"}}}var ai=c(51459),aj=c(67274),ak=c(1934),al=c(45649),am=c(78893);let an=(0,i.h)("backend/services/mcp/externalAuthorization");({...am.XC});let ao=global.__mcp_external_authorization_status??(global.__mcp_external_authorization_status=new Map),ap=global.__mcp_external_authorization_sessions??(global.__mcp_external_authorization_sessions=new Map),aq=global.__mcp_stdio_oauth_clients??(global.__mcp_stdio_oauth_clients=new WeakMap);function ar(a){return(0,j.workspaceCacheKey)(a)}function as(a,b){return`${a}\0${b}`}function at(a){return as((0,j.getCurrentWorkspace)(),a)}function au(a,b,c){if(aq.has(a))return;let d=(0,al._V)({mcpClient:a,installElicitationHandler:!1,...c?{mrtrController:c}:{},onUrlElicitation:(0,j.bindToCurrentWorkspace)(async a=>await aC(b,{mode:a.mode,url:a.target.href,message:a.message})??{action:"cancel"})});aq.set(a,d),a.__flujoStdioOAuth=!0}function av(a){let b=aq.get(a);if(!b)throw Error("This MCP client did not negotiate mcp-stdio-oauth.");return b}function aw(a){if(!a)return!1;let b=!0===a.__flujoStdioOAuth,c=aq.get(a);return b&&!!c?.isSupported()}async function ax(a,b,c={}){if(!aw(a))return{supported:!1,authorizations:[]};let d=ar(b),e=ao.get(d);if(!c.force&&e&&Date.now()-e.timestamp<2e3)return e.value;let f=(await av(a).getStatus({timeout:8e3})).authorizations.map(a=>({id:a.id,...a.provider?{provider:a.provider}:{},label:a.label,state:a.state,blocksUnattendedUse:a.blocksUnattendedUse,...a.message?{message:a.message}:{}})),g={supported:!0,authorizations:f,blockingAuthorization:f.find(a=>a.blocksUnattendedUse&&"ready"!==a.state)};return ao.set(d,{value:g,timestamp:Date.now()}),g}function ay(a){ao.delete(ar(a))}function az(a){let b=(0,j.getCurrentWorkspace)();return Array.from(ap.values()).filter(c=>c.workspace===b&&c.serverName===a).sort((a,b)=>b.createdAt-a.createdAt)[0]}function aA(a){a.timer&&clearTimeout(a.timer),ap.delete(as(a.workspace,a.sessionId))}function aB(a,b){let c=b?ap.get(at(b)):az(a);if(!c||c.serverName!==a)return!1;if(c.resolveElicitation){let a=c.resolveElicitation;c.resolveElicitation=void 0,c.elicitationResponded=!0,a({action:"cancel"})}else c.elicitationResponded,c.abortController.abort();return c.rejectPrompt(Error("Authorization was cancelled.")),!0}async function aC(a,b){if("url"!==b.mode)return;let c=az(a);if("string"!=typeof b.url||0===b.url.length)return c&&(c.rejectPrompt(Error("The MCP server supplied a malformed authorization URL.")),c.abortController.abort()),{action:"cancel"};if(!c)return an.warn(`Rejected unsolicited URL elicitation from ${a}`),{action:"cancel"};if(c.abortController.signal.aborted)return an.warn(`Rejected URL elicitation from cancelled start on ${a}`),{action:"cancel"};if(c.resolveElicitation||c.elicitationResponded)return an.warn(`Rejected duplicate URL elicitation from ${a}`),{action:"cancel"};try{!function(a,b,c){if(a.prompt)return a.prompt;let d=(0,al.Z)(b),e={sessionId:a.sessionId,authorizationId:a.authorizationId,url:d.href,origin:d.origin,hasPunycode:d.hasPunycode,...c?{message:c}:{}};a.prompt=e,a.resolvePrompt(e)}(c,b.url,b.message)}catch(a){return c.rejectPrompt(a instanceof Error?a:Error(String(a))),c.abortController.abort(),{action:"cancel"}}return new Promise(a=>{c.resolveElicitation=a})}async function aD(a,b,c,d={}){let e,f,g;if(d.signal?.throwIfAborted(),!aw(a))throw Error("This MCP server did not negotiate external authorization support.");let h=(await ax(a,b,{force:!0})).authorizations.find(a=>a.id===c);if(!h)throw Error("The OAuth authorization is no longer available. Refresh and try again.");if("ready"===h.state)return{sessionId:crypto.randomUUID(),authorizationId:c,url:"",origin:"",hasPunycode:!1,alreadyReady:!0};let i=az(b);if(i&&(aB(b,i.sessionId),ap.has(as(i.workspace,i.sessionId))))throw Error("The previous authorization request is still closing. Try again in a moment.");d.signal?.throwIfAborted();let k=new Promise((a,b)=>{e=a,f=b}),l={workspace:(0,j.getCurrentWorkspace)(),sessionId:crypto.randomUUID(),serverName:b,authorizationId:c,createdAt:Date.now(),resolvePrompt:e,rejectPrompt:f,promptPromise:k,abortController:new AbortController};l.timer=setTimeout((0,j.bindToCurrentWorkspace)(()=>{let a=l.resolveElicitation;l.resolveElicitation=void 0,l.elicitationResponded=!0,a?.({action:"cancel"}),l.abortController.abort(),l.rejectPrompt(Error("Authorization request timed out."))}),3e5),ap.set(as(l.workspace,l.sessionId),l);let m=(0,j.bindToCurrentWorkspace)(()=>{aB(b,l.sessionId)});d.signal?.addEventListener("abort",m,{once:!0});let n=(0,j.bindToCurrentWorkspace)(async d=>{if(ay(b),"ready"===d.state){l.resolvePrompt({sessionId:l.sessionId,authorizationId:c,url:"",origin:"",hasPunycode:!1,alreadyReady:!0}),aA(l);return}let e=(await ax(a,b,{force:!0})).authorizations.find(a=>a.id===c);if(e?.state==="ready"){l.resolvePrompt({sessionId:l.sessionId,authorizationId:c,url:"",origin:"",hasPunycode:!1,alreadyReady:!0}),aA(l);return}l.rejectPrompt(Error("The MCP server completed OAuth start without URL elicitation or ready status.")),aA(l)}),o=(0,j.bindToCurrentWorkspace)(a=>{l.rejectPrompt(a instanceof Error?a:Error(String(a)))}),p=(0,j.bindToCurrentWorkspace)(()=>aA(l));av(a).start(c,{timeout:3e5,signal:l.abortController.signal}).then(n).catch(o).finally(p);try{return await Promise.race([k,new Promise((a,b)=>{g=setTimeout(()=>b(Error("The MCP server did not present an authorization URL in time.")),3e4)})])}catch(a){throw aB(b,l.sessionId),a}finally{g&&clearTimeout(g),d.signal?.removeEventListener("abort",m)}}let aE=(0,i.h)("backend/services/mcp/taskInputRegistry"),aF=globalThis,aG=aF.__flujoMcpTaskInputRegistry??(aF.__flujoMcpTaskInputRegistry=new Map);function aH(a,b){return(0,j.workspaceCacheKey)(a,b)}let aI=(0,i.h)("backend/services/mcp/elicitation");function aJ(a){return a.elicitation}function aK(a){let b=aJ(a);return!!b?.enabled}function aL(a){return(0,j.bindToCurrentWorkspace)(async b=>{var c,d,e;let f,g,h,i,j,k=b.params,l=(0,F.PJ)(k?._meta),m=await aC(a.name,k??{});if(m)return m;if(!aK(a))throw new D.Nh(D.O4.MethodNotFound,"Elicitation is not enabled for this server");let n=(0,aj.lx)(a.name);if(!n&&l&&aI.warn(`Task ${l} on ${a.name} requested input outside an attended run; auto-cancelling`),!n)return aI.warn(`Elicitation request from ${a.name} outside an active run; auto-cancelling`),{action:"cancel"};if(n.getUnattended())return aI.warn(`Elicitation request from ${a.name} in unattended run ${n.conversationId}; auto-cancelling`),{action:"cancel"};let o=k?.message??"Additional information required",p=k?.requestedSchema??{type:"object",properties:{}},q=crypto.randomUUID();aI.info(`Suspending for elicitation ${q} from ${a.name} in conv ${n.conversationId}`),l&&(c=a.name,f=aH(c,l),g=Date.now(),(h=aG.get(f)??{outstanding:new Set,answered:new Set,firstRequestedAt:g,lastRequestedAt:g}).answered.has(q)||(h.outstanding.add(q),h.lastRequestedAt=g,aG.set(f,h),aE.info(`Task ${l} on ${c} requested input (elicitation ${q}); outstanding=${h.outstanding.size}`))),ai.$.emitterFor(n.conversationId)({type:"run:awaiting_elicitation",elicitationId:q,message:o,requestedSchema:p});let r=await (0,ak.gV)(q);return aI.info(`Elicitation ${q} resolved with action=${r.action}`),l&&(d=a.name,e=r.action,i=aH(d,l),!(j=aG.get(i))||!j.outstanding.delete(q)&&j.answered.has(q)||(j.answered.add(q),aG.set(i,j),aE.info(`Task ${l} on ${d} input ${q} resolved with action=${e}; outstanding=${j.outstanding.size}`))),r})}var aM=c(71202),aN=c(85482),aO=c(62156);function aP(a){let b,c;return[(b=af(a),!b?.enabled?"":JSON.stringify({m:b.modelId,t:b.maxTokens,r:b.maxCallsPerMinute})),(c=aJ(a),c?.enabled?"e:1":""),!0===a.enableMcpApps?"mcp-apps:on":"mcp-apps:off",!0===a.enableMcpSkills?"mcp-skills:on":"mcp-skills:off"].join("|")}let aQ=(0,i.h)("backend/services/mcp/connection");async function aR(a){let b=a;if(a.env&&"object"==typeof a.env){let c={};for(let[b,d]of Object.entries(a.env)){if(!b)continue;let a=d&&"object"==typeof d&&"value"in d?d.value??"":d??"";if(!a||(0,aM.uh)(a))continue;let e=await (0,E.G)(a);e&&(c[b]=e)}b={...b,env:c}}if("streamable"!==a.transport&&"sse"!==a.transport||!a.headers||"object"!=typeof a.headers)return b;let c={};for(let[b,d]of Object.entries(a.headers)){if(!b)continue;let{value:a}=(0,aM.at)(d,b);if(!a||(0,aM.uh)(a))continue;let e=await (0,E.G)(a);e&&(c[b]=e)}return{...b,headers:c}}function aS(a){let b={};for(let[c,d]of Object.entries(a)){if(!c)continue;let{value:a}=(0,aM.at)(d,c);"string"==typeof a&&a.length>0&&(b[c]=a)}return b}function aT(a){let b={};if(a)for(let[c,d]of Object.entries(a))d&&"object"==typeof d&&"value"in d?b[c]=d.value:b[c]=d;return b}let aU=new Set(["path","pathext","home","userprofile","homedrive","homepath","appdata","localappdata","programdata","xdg_config_home","xdg_cache_home","xdg_data_home","xdg_state_home","xdg_runtime_dir","tmp","temp","tmpdir","shell","comspec","systemroot","windir","systemdrive","programfiles","programfiles(x86)","gh_config_dir"]);function aV(a,b,c){for(let c of Object.keys(a))c.toLowerCase()===b.toLowerCase()&&delete a[c];void 0!==c&&(a[b]=c)}function aW(a,b=!1){return JSON.stringify({command:a.command,args:a.args??[],env:aT(a.env),cwd:String(a.cwd??""),rootPath:a.rootPath??"",isolateRuntimeHome:b})}function aX(a){return JSON.stringify({transport:a.transport,url:a.serverUrl??"",headers:a.headers??{},requestInit:a.requestInit??{},eventSourceInit:a.eventSourceInit??{},reconnectionOptions:a.reconnectionOptions??{},sessionId:a.sessionId??"",oauthClientId:a.oauthClientId??"",oauthClientInformation:a.oauthClientInformation??{},oauthClientSecret:a.oauthClientSecret??"",oauthTokens:a.oauthTokens??{}})}function aY(a){aQ.debug("Entering createNewClient method");let b=ag(a),c=aK(a),d=!0===a.enableMcpApps,e="stdio"===a.transport,f=new K.K({name:`flujo-${a.name}-client`,version:"3.45.1"},{capabilities:{experimental:{},roots:{listChanged:!0},...b?{sampling:{}}:{},...e||c?{elicitation:{...e?{url:{}}:{},...c?{form:{}}:{}}}:{},extensions:{...e?{[am.OM]:am.XC}:{},...d?{[aN.OF]:{mimeTypes:[aN.cM]}}:{}}}});return(0,aa.FP)(f,a),b&&f.setRequestHandler(D.u9,ah(a)),(e||c)&&f.setRequestHandler(D.$9,aL(a)),f.__flujoCapKey=aP(a),f}function aZ(a,b){if(aQ.debug("Entering createTransport method"),"streamable"===a.transport){aQ.info(`Creating streamable http transport for server ${a.name} with URL ${a.serverUrl}`);let b={};if(a.requestInit&&"object"==typeof a.requestInit&&(b.requestInit=a.requestInit),a.reconnectionOptions&&"object"==typeof a.reconnectionOptions&&(b.reconnectionOptions=a.reconnectionOptions),"string"==typeof a.sessionId&&a.sessionId.length>0&&(b.sessionId=a.sessionId),a.headers&&"object"==typeof a.headers){let c=aS(a.headers);Object.keys(c).length>0&&(b.requestInit={...b.requestInit||{},headers:{...b.requestInit?.headers||{},...c}},aQ.info(`Applied ${Object.keys(c).length} custom header(s) for ${a.name}: ${Object.keys(c).join(", ")}`))}a.oauthClientId||a.oauthClientInformation?(aQ.info(`Setting up OAuth authentication for ${a.name}`),b.authProvider=(0,S.Cl)(a),a.oauthTokens?.access_token?(aQ.debug(`OAuth provider configured for ${a.name} with existing tokens`),aQ.debug(`Token expires in: ${a.oauthTokens.expires_in} seconds`)):aQ.debug(`OAuth provider configured for ${a.name} - will initiate OAuth flow if needed`)):aQ.debug(`No OAuth configuration found for ${a.name}`);let c=new N.j(new URL(a.serverUrl),b);return c.__flujoHttpKey=aX(a),c}if("sse"===a.transport){aQ.info(`Creating legacy sse transport for server ${a.name} with URL ${a.serverUrl}`);let b={};if(a.requestInit&&"object"==typeof a.requestInit&&(b.requestInit=a.requestInit),a.eventSourceInit&&"object"==typeof a.eventSourceInit&&(b.eventSourceInit=a.eventSourceInit),a.headers&&"object"==typeof a.headers){let c=aS(a.headers);Object.keys(c).length>0&&(b.requestInit={...b.requestInit||{},headers:{...b.requestInit?.headers||{},...c}},aQ.info(`Applied ${Object.keys(c).length} custom header(s) for ${a.name}: ${Object.keys(c).join(", ")}`))}let c=new O.A(new URL(a.serverUrl),b);return c.__flujoHttpKey=aX(a),c}return"websocket"===a.transport?(aQ.info(`Creating WebSocket transport for server ${a.name} with URL ${a.websocketUrl}`),new M.I(new URL(a.websocketUrl))):function(a,b){let c;if(aQ.debug("Entering createStdioTransport method"),"stdio"!==a.transport)throw Error("Cannot create stdio transport for non-stdio config");let{command:d,args:e,env:f,cwd:g}=a$(a,b),h=b?.enableRuntimeBroker&&!0===a.enableMcpApps?(0,aO.D9)(a.name):void 0;aQ.info(`Creating StdioClientTransport for ${a.name} with stderr: 'pipe'`);let i={command:d,args:e,env:h?{...f,...h.env}:f,cwd:g,stderr:"pipe"};try{c=new L.oQ(i)}catch(a){throw(0,aO.tS)(h?.leaseId),a}return h&&(c.__flujoRuntimeBrokerLeaseId=h.leaseId),c.__flujoStdioKey=aW(a,b?.isolateRuntimeHome===!0),c.stderr?aQ.info(`Stderr stream is available for ${a.name}`):aQ.warn(`Stderr stream is NOT available for ${a.name}`),c}(a,b)}function a$(a,b){let c=(0,_.AW)(a),d=!!c,e=c?.defaultName==="bash",f=a=>d?a:(0,j.remapLegacyDefaultWorkspaceReference)(a,"mcp-servers"),h=f(a.command),i=a.args?a.args.map(f):[],k=`${l.VL}/${a.name}`;aQ.info(`Creating stdio transport for server ${a.name}`),aQ.debug(`Original command: ${h}`),aQ.debug(`Original args: ${JSON.stringify(i)}`),aQ.debug(`Server directory: ${k}`);let m=!g.isAbsolute(h)&&(h.includes("/")||h.includes("\\")),n=!h.includes("/")&&!h.includes("\\");if(aQ.debug(`Is relative path: ${m}`),aQ.debug(`Is just filename: ${n}`),"win32"===Q.platform()&&h.toLowerCase().endsWith(".bat"))if(aQ.debug(`Detected .bat file on Windows: ${h}`),n){let a=g.join((0,j.getWorkspaceDataDir)(),k,h);aQ.debug(`Checking if file exists at: ${a}`);let b=P.existsSync(a);aQ.debug(`File exists: ${b}`),b?(aQ.debug(`Using full path to .bat file: ${a}`),i=["/c",a,...i]):(aQ.warn(`WARNING: .bat file not found at ${a}`),i=["/c",h,...i]),h="cmd.exe"}else aQ.debug(`Using cmd.exe with path as provided: ${h}`),i=["/c",h,...i],h="cmd.exe";let o=function(a,b){if(!a||!(!a.includes("/")&&!a.includes("\\")))return a;let c=a.toLowerCase();if(!$.has(c))return a;if("node"===c)return b.execPath||a;if(!b.execPath)return a;let d=b.dirname(b.execPath);for(let a of"win32"===b.platform?[`${c}.cmd`,`${c}.exe`,c]:[c]){let c=b.joinPath(d,a);if(b.fileExists(c))return c}return a}(h,{execPath:process.execPath,platform:Q.platform(),dirname:g.dirname,joinPath:g.join,fileExists:P.existsSync});o!==h&&(aQ.debug(`Resolved Node toolchain command "${h}" to absolute path: ${o}`),h=o),aQ.debug(`Final command: ${h}`),aQ.debug(`Final args: ${JSON.stringify(i)}`);let p=e||b?.isolateRuntimeHome!==!0?void 0:function(a){let b=(0,j.getWorkspaceDataDir)(),c=(0,R.createHash)("sha256").update(a,"utf8").digest("hex").slice(0,24),d=(a,b)=>{try{let c=P.lstatSync(a);if(!c.isDirectory()||c.isSymbolicLink())throw Error(`${b} must be a real directory: ${a}`)}catch(d){if("ENOENT"!==d.code)throw d;P.mkdirSync(a,{mode:448});let c=P.lstatSync(a);if(!c.isDirectory()||c.isSymbolicLink())throw Error(`${b} must be a real directory: ${a}`)}},e=P.lstatSync(b);if(!e.isDirectory()||e.isSymbolicLink())throw Error(`Workspace root must be a real directory: ${b}`);let f=b;for(let a of["userdata","mcp-runtime",c])d(f=g.join(f,a),"MCP runtime directory");let h=f,i=g.join(h,"home"),k=g.join(h,"cwd");d(i,"MCP runtime home"),d(k,"MCP runtime cwd");let l={appData:g.join(i,"AppData","Roaming"),localAppData:g.join(i,"AppData","Local"),config:g.join(i,".config"),cache:g.join(i,".cache"),data:g.join(i,".local","share"),state:g.join(i,".local","state"),runtime:g.join(i,".runtime"),temp:g.join(i,"tmp"),npm:g.join(i,".npm"),pip:g.join(i,".cache","pip"),uv:g.join(i,".cache","uv")};for(let a of Object.values(l)){let b=g.relative(i,a),c=i;for(let a of b.split(g.sep).filter(Boolean))d(c=g.join(c,a),"MCP runtime directory")}let m={HOME:i,USERPROFILE:i,APPDATA:l.appData,LOCALAPPDATA:l.localAppData,XDG_CONFIG_HOME:l.config,XDG_CACHE_HOME:l.cache,XDG_DATA_HOME:l.data,XDG_STATE_HOME:l.state,XDG_RUNTIME_DIR:l.runtime,TMPDIR:l.temp,TMP:l.temp,TEMP:l.temp,NPM_CONFIG_CACHE:l.npm,PIP_CACHE_DIR:l.pip,UV_CACHE_DIR:l.uv};if("win32"===process.platform){let a=g.parse(i);m.HOMEDRIVE=a.root.replace(/[\\/]$/,""),m.HOMEPATH=i.slice(a.root.length-1)}return{cwd:k,env:m}}(a.name),q=f(function({command:a,args:b=[],rootPath:c,cwd:d,serverName:e,defaultCwd:f,packageRunnerCwd:g}){let h=c||d||f;if(Z(a,b)&&g)return g;if(e&&Z(a,b)&&(h.split(/[\\/]/).filter(Boolean).pop()||"")===e){let a;return((a=h.match(/^(.*[\\/])[^\\/]+[\\/]*$/))?a[1].replace(/[\\/]+$/,""):"")||h}return h}({command:a.command,args:a.args,rootPath:a.rootPath,cwd:a.cwd,serverName:a.name,defaultCwd:`${l.VL}/${a.name}`,packageRunnerCwd:p?.cwd})),r=g.isAbsolute(q)?q:g.join((0,j.getWorkspaceDataDir)(),q);aQ.debug(`cwd: ${r}`),aQ.debug(`Environment variable names: ${JSON.stringify(Object.keys(a.env??{}))}`);let s=aT(a.env),t=e?function(a){let b={...a},c=Object.entries(process.env).filter(a=>"string"==typeof a[1]);for(let[a,d]of c)aV(b,a,d);for(let a of aU)c.find(([b])=>b.toLowerCase()===a)||aV(b,a,void 0);return b}(s):s;if(!d)for(let[a,b]of Object.entries(t))t[a]=f(b);p&&Object.assign(t,p.env),function(a){if("win32"!==process.platform)return;let b=(a,b)=>Object.entries(a).find(([a,c])=>a.toLowerCase()===b.toLowerCase()&&""!==(c??"").trim())?.[1],c=b(process.env,"SystemRoot")??b(process.env,"windir")??"C:\\Windows";for(let[d,e]of Object.entries({SystemRoot:c,windir:c,ComSpec:b(process.env,"ComSpec")??g.join(c,"System32","cmd.exe"),PATHEXT:b(process.env,"PATHEXT")??".COM;.EXE;.BAT;.CMD"}))if(void 0===b(a,d)){for(let b of Object.keys(a))b.toLowerCase()===d.toLowerCase()&&delete a[b];a[d]=e}}(t);let u=(0,V.ok)(),v=(0,j.getWorkspaceDataDir)();if(t.FLUJO_PARENT_DATA_DIR=u,t.FLUJO_DATA_DIR=v,t.FLUJO_WORKSPACE=(0,j.getCurrentWorkspace)(),c?.defaultName==="browser"){if(!t.PLAYWRIGHT_BROWSERS_PATH?.trim()){let a=(0,_.AI)(process.env);a&&(t.PLAYWRIGHT_BROWSERS_PATH=a)}t.FLUJO_BROWSER_PROFILE_DIR=g.join(v,"browser-profile","trusted"),t.FLUJO_BROWSER_SCREENSHOT_DIR=g.join(v,"screenshots","browser"),t.FLUJO_BROWSER_RECORD_DIR=g.join(v,"recordings","browser")}return aQ.verbose("Transformed environment variable names",JSON.stringify(Object.keys(t))),"1"===process.env.FLUJO_WORKER_MODE&&c?.defaultName==="flujo"&&(t.FLUJO_WORKER_MODE="1",process.env.FLUJO_SNAPSHOT_CONTROL_TOKEN&&(t.FLUJO_SNAPSHOT_CONTROL_TOKEN=process.env.FLUJO_SNAPSHOT_CONTROL_TOKEN)),{command:h,args:i,env:t,cwd:r}}async function a_(a,b,c,d){aQ.debug("Entering safelyCloseClient method");let e=Date.now(),f=d?.gracePeriodMs??15e3,g=d?.killEscalationMs??5e3,h=!0,i=!1,j=function(a){let b=a,c=new Set;for(;b&&"object"==typeof b&&!c.has(b);){c.add(b);let a=b.__flujoInnerTransport;if(!a)break;b=a}return b}(a.transport);try{let c=j?._process;if(c&&"function"==typeof c.kill&&null===c.exitCode&&null===c.signalCode){try{c.stdin&&!c.stdin.destroyed&&(c.stdin.end(),aQ.debug(`Closed stdin for graceful shutdown for ${b}`))}catch(a){aQ.warn(`Error closing stdin for ${b}:`,a)}if(h=await (null!==c.exitCode||null!==c.signalCode?Promise.resolve(!0):new Promise(a=>{let b=()=>{clearTimeout(d),a(!0)},d=setTimeout(()=>{c.removeListener("exit",b),a(!1)},f);d.unref?.(),c.once("exit",b)})))aQ.info(`Process exited gracefully for ${b}`);else{aQ.warn(`Process did not exit within ${f}ms after stdin close; escalating to a tree kill for ${b}`);let a=await (0,U.U)(c,{graceMs:g,finalWaitMs:g});h=a.exited,i=a.forced,h?aQ.warn(`Process tree for ${b} force-terminated after ${a.durationMs}ms`):aQ.error(`Process tree for ${b} (pid ${a.pid??"unknown"}) did not exit after forced escalation`)}}await a.close(),aQ.info(`Client closed successfully for ${b}`)}catch(a){aQ.warn(`Error closing client for ${b}:`,a)}finally{(0,aO.tS)(j?.__flujoRuntimeBrokerLeaseId)}return{exited:h,forced:i,durationMs:Date.now()-e}}var a0=c(4618);let a1=(0,i.h)("backend/services/mcp/betaClient");async function a2(){try{let a=await (0,I.loadItem)(J.Zg.SPEECH_SETTINGS,void 0);return!!a?.experimental?.mcpBetaProtocol}catch(a){return a1.warn("Failed to read mcpBetaProtocol setting; defaulting to disabled",{err:a}),!1}}function a3(a){return!0===a.__flujoBeta}function a4(a){let b=ag(a),c=aK(a),d=!0===a.enableMcpApps,e="stdio"===a.transport,f=new G.Kj({name:`flujo-${a.name}-client`,version:"3.45.1"},{capabilities:{roots:{listChanged:!0},...b?{sampling:{}}:{},...e||c?{elicitation:{...e?{url:{}}:{},...c?{form:{}}:{}}}:{},extensions:{...e?{[am.OM]:am.XC}:{},...d?{[aN.OF]:{mimeTypes:[aN.cM]}}:{}}},versionNegotiation:{mode:"auto"}});if(f.setRequestHandler("roots/list",(0,aa.sG)(a)),b){let b=ah(a);f.setRequestHandler("sampling/createMessage",async a=>b(a))}if(e||c){let b=aL(a);f.setRequestHandler("elicitation/create",async a=>b(a))}return f.__flujoBeta=!0,f.__flujoCapKey=aP(a),a1.info(`Created v2-beta MCP client for ${a.name} (version negotiation: auto)`),f}function a5(a){let b=a.requestInit&&"object"==typeof a.requestInit?a.requestInit:void 0;if(a.headers&&"object"==typeof a.headers){let c=aS(a.headers);Object.keys(c).length>0&&(b={...b||{},headers:{...b?.headers||{},...c}})}return b}function a6(a,b){let c;if("websocket"===a.transport)throw Error("The v2-beta MCP SDK has no websocket transport; use the v1 path");if("streamable"===a.transport){let b={},c=a5(a);c&&(b.requestInit=c),a.reconnectionOptions&&"object"==typeof a.reconnectionOptions&&(b.reconnectionOptions=a.reconnectionOptions),"string"==typeof a.sessionId&&a.sessionId.length>0&&(b.sessionId=a.sessionId),(a.oauthClientId||a.oauthClientInformation)&&(b.authProvider=(0,S.Cl)(a));let d=new G.jS(new URL(a.serverUrl),b);return d.__flujoHttpKey=aX(a),d.__flujoKind="streamable",a1.info(`Created v2-beta streamable transport for ${a.name}`),d}if("sse"===a.transport){let b={},c=a5(a);c&&(b.requestInit=c),a.eventSourceInit&&"object"==typeof a.eventSourceInit&&(b.eventSourceInit=a.eventSourceInit);let d=new G.Am(new URL(a.serverUrl),b);return d.__flujoHttpKey=aX(a),d.__flujoKind="sse",a1.info(`Created v2-beta SSE transport for ${a.name}`),d}let{command:d,args:e,env:f,cwd:g}=a$(a,b),h=b?.enableRuntimeBroker&&!0===a.enableMcpApps?(0,aO.D9)(a.name):void 0;try{c=new H.oQ({command:d,args:e,env:h?{...f,...h.env}:f,cwd:g,stderr:"pipe"})}catch(a){throw(0,aO.tS)(h?.leaseId),a}let i=c;return i.__flujoRuntimeBrokerLeaseId=h?.leaseId,i.__flujoStdioKey=aW(a,b?.isolateRuntimeHome===!0),i.__flujoKind="stdio",a7.set(c,new a0.$6),a1.info(`Created v2-beta stdio transport for ${a.name}`),c}let a7=new WeakMap;function a8(a){a7.get(a)?.attach(a)}var a9=c(2398),ba=c(44907),bb=c(86364);let bc=(0,i.h)("backend/services/mcp/clientTasks");function bd(a,b,c){return"completed"===a.status?{success:!0,data:c,progressToken:a.taskId}:"failed"===a.status?{success:!1,error:a.statusMessage??`Task ${a.taskId} failed`,errorType:"task-failed",progressToken:a.taskId,toolName:b}:{success:!1,error:a.statusMessage??`Tool '${b}' task ${a.taskId} was cancelled by the server.`,errorType:"cancelled",progressToken:a.taskId,toolName:b}}async function be(a){var b,c;let d,{client:e,serverName:f,serverIdentity:g,toolName:h,task:i,timeoutMs:j,signal:k,onProgress:l,ownership:m,persist:n}=a,o=await (0,bb.VX)(),p=Date.now(),q=(0,F.uY)(i.pollInterval,{minMs:o.minPollIntervalMs,maxMs:o.maxPollIntervalMs,defaultMs:o.defaultPollIntervalMs}),r=(0,F.on)(i,p,o.fallbackTtlMs);bc.info(`Tool ${h} on ${f} returned task ${i.taskId} (status=${i.status}, poll=${q}ms, expiresAt=${r??"none"})`),l?.({progress:0,message:`Task ${i.taskId} created (${i.status})`});let s=await (0,bb.Au)(f);if(!s)return bc.warn(`Refusing to poll task ${i.taskId}: poll concurrency limit reached for ${f}`),a.supportsCancel&&await (0,a9.O0)(e,i.taskId),{success:!1,error:`Too many concurrent MCP tasks are being polled; task ${i.taskId} was not started.`,errorType:"task-poll-limit",progressToken:i.taskId,toolName:h};let t=null;n&&(t=await (0,bb.ZN)({remoteTaskId:i.taskId,serverName:f,serverIdentity:g,toolName:h,args:a.args,ownership:m,status:i.status,statusMessage:i.statusMessage,pollIntervalMs:q,...void 0!==r?{expiresAt:r,ttlMs:r-p}:{}}));let u=async a=>{if(!t)return;let b=await (0,bb.Pi)(t.recordId,a);b&&(t=b)},v=b=>(d||(d=(async()=>(await u({cancelRequestedAt:Date.now(),...b?{diagnostic:b}:{}}),a.supportsCancel)?(0,a9.O0)(e,i.taskId):void bc.warn(`Server ${f} does not advertise tasks.cancel; skipping cancellation of ${i.taskId}`))()),d),w=()=>{v()};k?.addEventListener("abort",w,{once:!0});try{let a;if((0,F.gJ)(i.status))return await x(i);let c=i,d=0,g=q,m=0;for(;;){let i;if(k?.aborted)return await v(),await u({status:"cancelled"}),{success:!1,error:`Tool '${h}' task ${c.taskId} was cancelled.`,errorType:"cancelled",progressToken:c.taskId,toolName:h};let n=Date.now();if(void 0!==r&&n>=r)return await v("expired"),await u({status:"failed",diagnostic:"expired",errorMessage:"Remote MCP task expired before completing."}),{success:!1,error:`Task ${c.taskId} expired before completing.`,errorType:"task-expired",progressToken:c.taskId,toolName:h};if(n-p>=j){await v(),await u({status:"failed",errorMessage:"Caller timeout elapsed while polling the remote MCP task."});let a=Math.round(j/1e3);return{success:!1,error:`Tool execution timed out after ${a} seconds`,errorType:"timeout",timeout:a,statusCode:408,progressToken:c.taskId,toolName:h}}if(await (0,ba.y)(g),k?.aborted)continue;try{i=await (0,a9.k$)(e,c.taskId,{timeout:Math.min(4*g+1e4,j)}),d=0,g=q}catch(a){if(d++,await u({diagnostic:"transport-error",lastPolledAt:Date.now()}),d>=o.maxTransientPollFailures)return await v("transport-error"),await u({status:"failed",diagnostic:"transport-error",errorMessage:`tasks/get failed ${d} times: ${String(a)}`}),{success:!1,error:`Lost contact with '${f}' while polling task ${c.taskId}.`,errorType:"task-transport-error",progressToken:c.taskId,toolName:h};g=(0,F.uY)(2*g,{minMs:o.minPollIntervalMs,maxMs:o.maxPollIntervalMs,defaultMs:o.defaultPollIntervalMs}),bc.warn(`Transient tasks/get failure ${d}/${o.maxTransientPollFailures} for ${c.taskId}; backing off to ${g}ms`);continue}if(!i.ok)return await v("protocol-invalid"),await u({status:"failed",diagnostic:"protocol-invalid",errorMessage:`Invalid tasks/get result: ${i.reason}`}),{success:!1,error:`Server '${f}' returned an invalid task status: ${i.reason}`,errorType:"task-protocol-invalid",progressToken:c.taskId,toolName:h};c=i.task,m++;let s=Date.now()-p;if(await u({status:c.status,statusMessage:c.statusMessage,lastPolledAt:Date.now(),nextPollAt:Date.now()+g,pollCount:m,outstandingInputKeys:(b=c.taskId,[...aG.get(aH(f,b))?.outstanding??[]])}),l?.({progress:"completed"===c.status?100:Math.min(99,Math.round(s/1e3)),message:`Task ${c.taskId}: ${c.status}${c.statusMessage?` — ${c.statusMessage}`:""}`}),(0,F.gJ)(c.status))return await x(c);if("input_required"===c.status){a??=Date.now();let b=function(a,b,c,d,e=Date.now()){let f=(0,aj.lx)(a),g=aG.get(aH(a,b));return f?f.getUnattended()?{action:"abandon",error:`Task ${b} on '${a}' requires input, but the run is unattended.`,errorType:"task-input-required-unattended",diagnostic:"input-required-unattended"}:e-c>=d?{action:"abandon",error:`Task ${b} on '${a}' was waiting for input for longer than the configured window (${Math.round(d/1e3)}s)${g?`; ${g.outstanding.size} request(s) unanswered`:""}.`,errorType:"task-input-timeout",diagnostic:"input-required-unattended"}:{action:"wait"}:{action:"abandon",error:`Task ${b} on '${a}' requires input, but no attended run is available to answer it.`,errorType:"task-input-required-unattended",diagnostic:"input-required-unattended"}}(f,c.taskId,a,o.inputRequiredTimeoutMs);if("abandon"===b.action)return await v(b.diagnostic),await u({status:"failed",diagnostic:b.diagnostic,errorMessage:b.error}),{success:!1,error:b.error,errorType:b.errorType,progressToken:c.taskId,toolName:h}}else a=void 0}}finally{k?.removeEventListener("abort",w),s.release(),c=i.taskId,aG.delete(aH(f,c))}async function x(a){if("completed"!==a.status)return await u({status:a.status,statusMessage:a.statusMessage,..."failed"===a.status?{errorMessage:a.statusMessage??"Remote MCP task failed."}:{}}),bd(a,h);try{let b=await (0,a9.Yr)(e,a.taskId,{timeout:Math.min(6e4,j)});return await u({status:"completed",resultRetrieved:!0}),l?.({progress:100,message:`Task ${a.taskId}: completed`}),bd(a,h,b)}catch(b){return await u({status:"completed",resultRetrieved:!1,errorMessage:`tasks/result failed: ${String(b)}`}),{success:!1,error:`Task ${a.taskId} completed but its result could not be retrieved from '${f}'.`,errorType:"task-result-unavailable",progressToken:a.taskId,toolName:h}}}}var bf=c(62511);let bg=(0,i.h)("backend/services/mcp/tools"),bh=0x80000000-1;async function bi(a,b,c="model"){if(bg.debug("Entering listServerTools method"),!a)return bg.warn(`Server ${b} not connected`),{tools:[],error:"Server not connected"};try{bg.info(`Listing tools for server ${b}`);let d=await a.listTools();bg.verbose("Raw response from MCP server:",d);let e=(d.tools||[]).map(a=>({...a,description:a.description||"",inputSchema:a.inputSchema||{type:"object"}})),f=(0,aN.zm)(e,c);return bg.verbose(`Processed tools for ${c} audience:`,f),{tools:f}}catch(c){bg.warn(`Failed to list tools for server ${b}:`,c);let a=c instanceof Error?c.message:"Unknown error";return{tools:[],error:a.includes("Connection timeout")?a:`Failed to list tools: ${a}`}}}async function bj(a,b,c,d,e,f,g,h="host",i,j){if(bg.debug("Entering callTool method"),!a)return bg.warn(`Server ${b} not found`),{success:!1,error:`Server ${b} not found`,statusCode:404};let k=void 0!==e&&e>0?Math.min(1e3*e,bh):bh;try{if("app"===h||"model"===h){let d=await bi(a,b,"all");if(d.error)return{success:!1,error:`Could not verify MCP App access to tool '${c}' on '${b}': ${d.error}`,errorType:"tool-authorization-list",statusCode:502};let e=(0,aN.F)(d.tools,b,c,h);if(!e.allowed)return bg.warn(`Rejected ${h} tool call: ${e.error}`),{success:!1,error:e.error,statusCode:e.statusCode}}bg.debug(`Original args for tool ${c}:`,d);let e=await (0,E.resolveGlobalVars)(d),l=function(a,b){if(!a)return{};let c={};for(let d in a){let e=a[d];null==e?(bg.debug(`Normalizing undefined/null value for parameter '${d}' in tool '${b}'`),d.includes("number")||d.endsWith("Count")||d.endsWith("Id")||d.endsWith("Limit")?(c[d]=0,bg.debug(`Using default value 0 for likely number parameter: ${d}`)):d.includes("bool")||d.startsWith("is")||d.startsWith("has")||d.startsWith("should")?(c[d]=!1,bg.debug(`Using default value false for likely boolean parameter: ${d}`)):d.includes("array")||d.endsWith("s")||d.endsWith("List")||d.endsWith("Items")?(c[d]=[],bg.debug(`Using empty array for likely array parameter: ${d}`)):d.includes("object")||d.endsWith("Options")||d.endsWith("Config")||d.endsWith("Settings")?(c[d]={},bg.debug(`Using empty object for likely object parameter: ${d}`)):(c[d]="",bg.debug(`Using empty string for parameter with unknown type: ${d}`))):c[d]=e}return c}("object"==typeof e&&null!==e?e:{},c);bg.debug(`Normalized args for tool ${c}:`,l),bg.debug(`Calling tool ${c} with SDK timeout ${k}ms`);let m={timeout:k,resetTimeoutOnProgress:!0,...g?{signal:g}:{},onprogress:a=>{bg.debug(`Progress for tool ${c}: ${a.progress}${void 0!==a.total?`/${a.total}`:""}${a.message?` — ${a.message}`:""}`),f?.(a)}},n=await (0,a9.u2)(a,c);n.request&&bg.info(`Requesting task-augmented execution of ${c} on ${b} (${n.reason})`);let o={name:c,arguments:l,...n.request?(0,a9.E4)(n.ttlMs):{},...i||j?{_meta:{flujo:{...i?{callerNodeId:i}:{},...j?{ownerScope:j}:{}}}}:{}},p=a3(a)?await a.callTool.call(a,o,m):await a.callTool(o,void 0,m),q=(0,F.Qh)(p,{taskRequested:n.request});if("protocol-invalid"===q.kind)return bg.warn(`Server ${b} returned an invalid task result for ${c}: ${q.reason}`),{success:!1,error:`Server '${b}' returned an invalid MCP task result: ${q.reason}`,errorType:"task-protocol-invalid",statusCode:502,toolName:c};if("task"===q.kind){let d=(0,a9.rf)(),e=d?await (0,bb.kI)(b):"unnegotiated",m=await be({client:a,serverName:b,serverIdentity:e,toolName:c,args:l,task:q.task,timeoutMs:k,...g?{signal:g}:{},...f?{onProgress:f}:{},ownership:{...i?{nodeId:i}:{},...j?{ownerScope:j}:{},source:h},persist:d,supportsCancel:n.negotiation.supportsCancel||!n.negotiation.supported});return void 0===m.data?m:{...m,data:(0,bf.iL)(m.data,j)}}return{success:!0,data:(0,bf.iL)(p,j)}}catch(h){bg.warn(`Failed to call tool ${c} on server ${b}:`,h);let d=h instanceof Error?h.message:"Unknown error",e=500;if(g?.aborted)return{success:!1,error:`Tool '${c}' call was cancelled.`,errorType:"cancelled",toolName:c};if(h instanceof D.Nh&&h.code===D.O4.RequestTimeout){let a=Math.round(k/1e3);return bg.warn(`Tool ${c} execution timed out after ${a} seconds`),{success:!1,error:`Tool execution timed out after ${a} seconds`,errorType:"timeout",toolName:c,timeout:a,statusCode:408}}let f=aw(a)?(0,am.W2)(h):void 0;if(f){ay(b);try{await ax(a,b,{force:!0})}catch(a){bg.warn(`Failed to refresh mcp-stdio-oauth status after revocation on ${b}:`,a)}return{success:!1,error:f.message?f.message:"External account authorization is required. Open the MCP page to authenticate.",errorType:"stdio-oauth-required",statusCode:428,requiresAuthentication:!0}}if(d.includes("401")||d.includes("Unauthorized")||d.includes("invalid_token")||d.includes("token_expired"))return bg.info(`OAuth authentication error detected for tool ${c} on server ${b}`),{success:!1,error:"OAuth authentication failed or tokens have expired. Please re-authenticate the server.",statusCode:401,requiresAuthentication:!0};return(d.includes("404")||d.includes("Not Found"))&&(bg.info(`404 error detected for tool ${c} on server ${b} - may indicate OAuth issues`),e=404,d="Tool endpoint not found (404). This may indicate OAuth authentication issues or the server may not be properly configured."),h instanceof D.Nh?(d=`Failed to call tool: ${d} (Code: ${h.code})`,-32601===h.code?e=404:-32602===h.code?e=400:-32603===h.code&&(e=500)):d=`Failed to call tool: ${d}`,{success:!1,error:d,statusCode:e}}}let bk=(0,i.h)("backend/services/mcp/resources");async function bl(a,b){if(bk.debug("Entering listServerResources method"),!a)return bk.warn(`Server ${b} not connected`),{resources:[],error:"Server not connected"};try{bk.info(`Listing resources for server ${b}`);let c=(await a.listResources()).resources||[];return bk.verbose("Processed resources:",c),{resources:c}}catch(c){if(c instanceof D.Nh&&-32601===c.code)return bk.debug(`Server ${b} does not support resources/list`),{resources:[]};bk.warn(`Failed to list resources for server ${b}:`,c);let a=c instanceof Error?c.message:"Unknown error";return{resources:[],error:a.includes("Connection timeout")?a:`Failed to list resources: ${a}`}}}async function bm(a,b){if(bk.debug("Entering listServerResourceTemplates method"),!a)return bk.warn(`Server ${b} not connected`),{resourceTemplates:[],error:"Server not connected"};try{return bk.info(`Listing resource templates for server ${b}`),{resourceTemplates:(await a.listResourceTemplates()).resourceTemplates||[]}}catch(c){if(c instanceof D.Nh&&-32601===c.code)return bk.debug(`Server ${b} does not support resources/templates/list`),{resourceTemplates:[]};bk.warn(`Failed to list resource templates for server ${b}:`,c);let a=c instanceof Error?c.message:"Unknown error";return{resourceTemplates:[],error:a.includes("Connection timeout")?a:`Failed to list resource templates: ${a}`}}}async function bn(a,b,c){if(bk.debug("Entering readResource method"),!a)return bk.warn(`Server ${b} not found`),{success:!1,error:`Server ${b} not found`,statusCode:404};try{let d=await (0,E.resolveGlobalVars)(c);bk.info(`Reading resource ${d} from server ${b}`);let e=await a.readResource({uri:d});return{success:!0,data:e}}catch(e){bk.warn(`Failed to read resource ${c} on server ${b}:`,e);let a=e instanceof Error?e.message:"Unknown error",d=500;return e instanceof D.Nh?(a=`Failed to read resource: ${a} (Code: ${e.code})`,-32601===e.code?d=404:-32602===e.code&&(d=400)):a=`Failed to read resource: ${a}`,{success:!1,error:a,statusCode:d}}}let bo=(0,i.h)("backend/services/mcp/prompts");async function bp(a,b){if(bo.debug("Entering listServerPrompts method"),!a)return bo.warn(`Server ${b} not connected`),{prompts:[],error:"Server not connected"};try{return bo.info(`Listing prompts for server ${b}`),{prompts:(await a.listPrompts()).prompts||[]}}catch(c){if(c instanceof D.Nh&&-32601===c.code)return bo.debug(`Server ${b} does not support prompts/list`),{prompts:[]};bo.warn(`Failed to list prompts for server ${b}:`,c);let a=c instanceof Error?c.message:"Unknown error";return{prompts:[],error:a.includes("Connection timeout")?a:`Failed to list prompts: ${a}`}}}async function bq(a,b,c,d){if(bo.debug("Entering getPrompt method"),!a)return bo.warn(`Server ${b} not found`),{success:!1,error:`Server ${b} not found`,statusCode:404};try{let e;if(d&&Object.keys(d).length>0){let a=await (0,E.resolveGlobalVars)(d);e="object"==typeof a&&null!==a?a:void 0}bo.info(`Getting prompt ${c} from server ${b}`);let f=await a.getPrompt({name:c,arguments:e});return{success:!0,data:f}}catch(e){bo.warn(`Failed to get prompt ${c} on server ${b}:`,e);let a=e instanceof Error?e.message:"Unknown error",d=500;return e instanceof D.Nh?(a=`Failed to get prompt: ${a} (Code: ${e.code})`,-32601===e.code?d=404:-32602===e.code&&(d=400)):a=`Failed to get prompt: ${a}`,{success:!1,error:a,statusCode:d}}}var br=c(77598),bs=c(57975),bt=c(33225);class bu extends Error{constructor(a){super(`MCP Skills are unavailable: ${a}`),this.name="McpSkillsUnsupportedError",this.reason=a}}function bv(a,b){if(!b||!a)return;let c=a.getServerCapabilities();return(0,l.zT)(c?.extensions?.[l.ET])}function bw(a,b){if(!b)throw new bu("disabled");if(!a)throw new bu("extension-not-negotiated");let c=bv(a,b);if(!c)throw new bu("extension-not-negotiated");return{client:a,capability:c}}async function bx(a){try{return await a()}catch(a){if(a instanceof D.Nh&&-32601===a.code)throw new bu("method-not-found");throw a}}async function by(a,b,c){let d=bw(a,b);return bx(async()=>await d.client.request({method:"skills/list",params:void 0===c?{}:{cursor:c}},l.lX))}async function bz(a,b,c){let d=bw(a,b),e=(0,l.Bw)(c).normalizedUri;return bx(async()=>{let a=await d.client.request({method:"skills/get",params:{uri:e}},l.Kg);if(a.skill.uri!==e)throw Error("skills/get returned a different skill URI");return a})}async function bA(a,b,c,d){let e=bw(a,b);if(!0!==e.capability.directoryRead)throw new bu("directory-read-not-negotiated");let f=(0,l.sm)(c);return bx(async()=>await e.client.request({method:"resources/directory/read",params:{uri:f,...void 0===d?{}:{cursor:d}}},l.Pd))}async function bB(a,b,c,d){let e=bw(a,b),f=function(a,b){if("dynamic"===a.resources)throw Error("Dynamic MCP Skills cannot be integrity-verified");let c=(0,l.sm)(b),d=a.resources.find(a=>a.uri===c);if(!d)throw Error("Resource is not declared by the held MCP Skill entry");return d}(c,d),g=(await e.client.readResource({uri:f.uri})).contents;if(!Array.isArray(g)||1!==g.length)throw Error("MCP Skill resource read must return exactly one content item");let h=g[0];if(null===h||"object"!=typeof h||Array.isArray(h))throw Error("MCP Skill resource content is malformed");if(void 0!==h.uri&&(0,l.sm)(h.uri)!==f.uri)throw Error("MCP Skill resource read returned a different URI");let i=function(a){let b="string"==typeof a.text;if(b===("string"==typeof a.blob))throw Error("MCP Skill resource must contain exactly one of text or blob");return b?{bytes:Buffer.from(a.text,"utf8"),text:a.text}:{bytes:function(a){if(a.length%4!=0||!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(a))throw Error("MCP Skill resource contains invalid base64");return Buffer.from(a,"base64")}(a.blob),blob:a.blob}}(h);if(i.bytes.byteLength!==f.size)throw Error("MCP Skill resource size verification failed");if(`sha256:${(0,br.createHash)("sha256").update(i.bytes).digest("hex")}`!==f.digest)throw Error("MCP Skill resource digest verification failed");return{uri:f.uri,digest:f.digest,size:f.size,..."string"==typeof h.mimeType?{mimeType:h.mimeType}:{},...i,verified:!0}}async function bC(a,b,c,d){if("dynamic"===d.resources)throw Error("Dynamic MCP Skills cannot be integrity-verified");let e=d.resources,f=Array(e.length),g=0,h=async()=>{for(;;){let c=g;if(g+=1,c>=e.length)return;f[c]=await bB(a,b,d,e[c].uri)}};await Promise.all(Array.from({length:Math.min(4,e.length)},()=>h()));let i=f.find(a=>a.uri===d.uri);if(!i||void 0===i.text)throw Error("MCP Skill SKILL.md must be textual content");return!function(a,b){let c,d=a.replace(/\r\n/g,"\n");if(!d.startsWith("---\n"))throw Error("MCP Skill SKILL.md must start with YAML frontmatter");let e=d.indexOf("\n---",4);if(e<0)throw Error("MCP Skill SKILL.md frontmatter is not terminated");let f=d.slice(4,e);try{c=(0,bt.parse)(f)}catch{throw Error("MCP Skill SKILL.md frontmatter is invalid YAML")}if(null===c||"object"!=typeof c||Array.isArray(c)||!(0,bs.isDeepStrictEqual)(c,b.frontmatter))throw Error("MCP Skill SKILL.md frontmatter does not match its advertised entry")}(i.text,d),{identity:{serverName:c,skillUri:d.uri},protocolRevision:l.v$,entry:d,manifest:i,resources:f,verification:"sha256",trust:"untrusted-external-content"}}var bD=c(77145);let bE=(0,i.h)("backend/services/mcp/runtimeHomeIsolation");async function bF(a,b=process.env){if("stdio"!==a.transport)return!1;let c=function(a){let b=a?.trim().toLowerCase();if(b){if(["1","true","yes","on","isolated"].includes(b))return!0;if(["0","false","no","off","host"].includes(b))return!1}}(b.FLUJO_MCP_RUNTIME_HOME_ISOLATION);if(void 0!==c)return c;if("isolated"===a.runtimeHomeMode)return!0;if("host"===a.runtimeHomeMode)return!1;try{let a=await (0,I.loadItem)(J.Zg.SPEECH_SETTINGS,void 0);return a?.experimental?.mcpRuntimeHomeIsolation===!0}catch(a){return bE.warn("Could not read the workspace MCP runtime-home preference; defaulting to host home",{error:a}),!1}}var bG=c(38004),bH=c(17492),bI=c(72628);function bJ(a){return"stdio"===a.transport&&Z(a.command,a.args??[])}var bK=c(83449);let bL=(0,i.h)("backend/services/mcp/resourceNotifications"),bM=/^[A-Za-z0-9_-]{1,64}$/;function bN(a,b,c,d){let e=d?.conversationId?.trim();if("model"===c&&"create_ticket_for_human"===b&&e&&bM.test(e)&&a?.transport==="stdio"&&(0,_.AW)(a)?.packageId==="@mario.andreschak/mcp-flujo")return e}function bO(a,b){let c=(0,j.getCurrentWorkspace)();if(c===j.DEFAULT_WORKSPACE)return b;let d=global.__mcp_workspace_registries??=new Map,e=d.get(c);e||(e=new Map,d.set(c,e));let f=e.get(a);return f||(f=b instanceof Set?new Set:new Map,e.set(a,f)),f}function bP(a){return{success:!1,error:a.error,statusCode:a.statusCode,errorType:a.errorType}}void 0===global.__mcp_clients&&(global.__mcp_clients=new Map),void 0===global.__mcp_connecting&&(global.__mcp_connecting=new Set),void 0===global.__mcp_starting_up&&(global.__mcp_starting_up=!0),void 0===global.__mcp_active_transports&&(global.__mcp_active_transports=new Map),void 0===global.__mcp_client_generation&&(global.__mcp_client_generation=new Map),void 0===global.__mcp_tool_schema_hash&&(global.__mcp_tool_schema_hash=new Map);let bQ=(0,i.h)("backend/services/mcp/index");function bR(a){let b=a,c=new Set;for(;b&&"object"==typeof b&&!c.has(b);){c.add(b);let a=b.__flujoInnerTransport;if(!a)break;b=a}return b}function bS(a){if("streamable"!==a.transport&&"sse"!==a.transport)return!1;let b=a.headers;return!!b&&Object.entries(b).some(([a,b])=>"authorization"===a.toLowerCase()&&(0,aM.at)(b,a).value.trim().length>0)}class bT{get stderrLogs(){return bO("stderrLogs",this.stderrLogsBase)}get lastConnectionError(){return bO("lastConnectionError",this.lastConnectionErrorBase)}get inFlightConnects(){return bO("inFlightConnects",this.inFlightConnectsBase)}get connectionRetryTimers(){return bO("connectionRetryTimers",this.connectionRetryTimersBase)}get connectionRetryAttempts(){return bO("connectionRetryAttempts",this.connectionRetryAttemptsBase)}get resourceListVersion(){return bO("resourceListVersion",this.resourceListVersionBase)}get pendingResourceUpdates(){return bO("pendingResourceUpdates",this.pendingResourceUpdatesBase)}async clearLegacyInferredOAuthScopesForHeaderAuth(a){try{let b=await this.loadServerConfigs();if(!Array.isArray(b))return;let c=b.findIndex(b=>b.name===a);if(-1===c||"streamable"!==b[c].transport)return;let d=b[c];if(!bS(d)||d.oauthScopes?.length!==1||"read"!==d.oauthScopes[0]||d.oauthClientId||d.oauthClientSecret||d.oauthClientMetadata||d.oauthClientInformation||d.oauthTokens||d.oauthCodeVerifier||d.oauthState||d.authorizationUrl)return;b[c]={...d,oauthScopes:void 0};let e=await (0,m.saveConfig)(new Map(b.map(a=>[a.name,a])));e.success?bQ.info(`Removed stale inferred OAuth scopes from header-authenticated server ${a}`):bQ.warn(`Failed to remove stale inferred OAuth scopes from ${a}: ${e.error}`)}catch(b){bQ.warn(`Failed to clean inferred OAuth scopes for ${a}: ${b instanceof Error?b.message:String(b)}`)}}get clients(){return bO("clients",global.__mcp_clients)}get connectingServers(){return bO("connectingServers",global.__mcp_connecting)}get activeTransports(){return bO("activeTransports",global.__mcp_active_transports)}get clientGenerations(){return bO("clientGenerations",global.__mcp_client_generation)}get toolSchemaHashes(){return bO("toolSchemaHashes",global.__mcp_tool_schema_hash)}static{this.MAX_STDERR_LOG_ENTRIES=200}appendStderrLog(a,b){let c=this.stderrLogs.get(a)||[];c.push(b),c.length>bT.MAX_STDERR_LOG_ENTRIES&&c.splice(0,c.length-bT.MAX_STDERR_LOG_ENTRIES),this.stderrLogs.set(a,c)}deregisterClient(a){this.clients.delete(a),this.activeTransports.delete(a);ay(a);let b=(0,j.getCurrentWorkspace)();for(let c of Array.from(ap.values()))c.workspace===b&&c.serverName===a&&(c.resolveElicitation?.({action:"cancel"}),c.abortController.abort(),c.rejectPrompt(Error("Authorization was cancelled because the MCP connection closed.")),aA(c));(0,aO.HW)(a)}onResourceListChanged(a){let b=this.resourceListVersion.get(a)??0;this.resourceListVersion.set(a,b+1),bQ.debug(`onResourceListChanged: server=${a} version=${b+1}`)}onResourceUpdated(a,b){let c=this.pendingResourceUpdates.get(a)??new Set;c.add(b),this.pendingResourceUpdates.set(a,c),bQ.debug(`onResourceUpdated: server=${a} uri=${b}`)}getResourceListVersion(a){return this.resourceListVersion.get(a)??0}async subscribeToResource(a,b){try{let c=this.getClient(a);if(!c)return;let d=c.getServerCapabilities?.();if(!d?.resources?.subscribe)return;await c.subscribeResource({uri:b}),bQ.debug(`subscribeToResource: server=${a} uri=${b}`)}catch(c){bQ.debug(`subscribeToResource: ignored error for ${a}/${b}:`,c)}}clearRetryTimer(a){let b=this.connectionRetryTimers.get(a);b&&(clearTimeout(b),this.connectionRetryTimers.delete(a),bQ.debug(`Cleared retry timer for server ${a}`))}scheduleConnectionRetry(a,b){this.clearRetryTimer(a);let c=this.connectionRetryAttempts.get(a)||0;if(c>=5){bQ.warn(`Maximum retry attempts (5) reached for server ${a}, stopping retries`),this.connectionRetryAttempts.delete(a);return}let d=Math.min(5e3*Math.pow(2,c),3e5);bQ.info(`Scheduling connection retry for server ${a} in ${d}ms (attempt ${c+1}/5)`);let e=setTimeout((0,j.bindToCurrentWorkspace)(async()=>{bQ.info(`Attempting to reconnect server ${a} (attempt ${c+1}/5)`);let b=await this.getServerConfig(a);if(!b){bQ.info(`Server ${a} configuration not found, stopping retry attempts`),this.connectionRetryAttempts.delete(a);return}if(b.disabled){bQ.info(`Server ${a} is now disabled, stopping retry attempts`),this.connectionRetryAttempts.delete(a);return}let d=this.getClient(a);if(d)try{await d.ping({timeout:5e3}),bQ.info(`Server ${a} is already connected and responsive, cancelling retry`),this.connectionRetryAttempts.delete(a);return}catch(b){bQ.warn(`Server ${a} has a registered client but ping failed (${b instanceof Error?b.message:String(b)}); reconnecting from scratch`)}this.connectionRetryAttempts.set(a,c+1);try{let e=d?await this.forceReconnect(a):await this.connectServer(b);if(e.success)bQ.info(`Successfully reconnected server ${a} after ${c+1} attempts`),this.connectionRetryAttempts.delete(a);else{if(bQ.warn(`Failed to reconnect server ${a}: ${e.error}`),e.requiresAuthentication){bQ.info(`Server ${a} requires authentication, stopping retry attempts`),this.connectionRetryAttempts.delete(a);return}this.scheduleConnectionRetry(a,b)}}catch(c){bQ.error(`Error during retry connection for server ${a}:`,c),this.scheduleConnectionRetry(a,b)}}),d);this.connectionRetryTimers.set(a,e)}isStartingUp(){let a=(0,j.getCurrentWorkspace)();return a===j.DEFAULT_WORKSPACE?!0===global.__mcp_starting_up:global.__mcp_starting_up_by_workspace?.get(a)===!0}setStartingUp(a){let b=(0,j.getCurrentWorkspace)();b===j.DEFAULT_WORKSPACE?global.__mcp_starting_up=a:(global.__mcp_starting_up_by_workspace??=new Map).set(b,a),bQ.info(`Backend startup state set to: ${a?"starting":"complete"}`)}getClientGeneration(a){return this.clientGenerations.get(a)??0}setToolSchemaHash(a,b,c){this.toolSchemaHashes.set(`${a}\0${b}`,c)}getToolSchemaHash(a,b){return this.toolSchemaHashes.get(`${a}\0${b}`)}getClient(a){let b=this.clients.get(a);if(b&&(0,T.wk)(b)){bQ.warn(`getClient: client for ${a} has a closed/aborted connection — evicting it`),this.clients.delete(a);return}return bQ.debug(`getClient: Looking for client: ${a}`,b?"Found":"Not found"),b}async loadServerConfigs(){bQ.debug("loadServerConfigs: Entering method");try{let a=await (0,m.loadServerConfigs)();if(!Array.isArray(a))return bQ.warn("loadServerConfigs: Received non-array response",a),a;return bQ.debug(`loadServerConfigs: Loaded ${a.length} server configs`),a}catch(a){return bQ.warn("loadServerConfigs: Failed to load server configs:",a),{success:!1,error:`Failed to load server configs: ${a instanceof Error?a.message:"Unknown error"}`}}}async getServerConfig(a){bQ.debug(`getServerConfig: Looking up config for server ${a}`);let b=await this.loadServerConfigs();if(!Array.isArray(b))return bQ.warn(`getServerConfig: Failed to load configs for ${a}:`,b.error),null;let c=b.find(b=>b.name===a);return c||(bQ.warn(`getServerConfig: Server ${a} not found in configs`),null)}async isServerDisabled(a){let b=await this.getServerConfig(a);return b?.disabled===!0}async connectServer(a){let b="string"==typeof a?a:a.name;return t(b,async()=>{let c=this.connectServerInternal(a).finally(()=>{this.inFlightConnects.delete(b)});this.inFlightConnects.set(b,c);let d=await c;if(d.success){var e;let c;e=this.configFingerprint(a),c=q(b),c.generation+=1,c.state="warm",c.configFingerprint=e,c.retryAttempts=0,c.lastError=void 0,c.warmSince=Date.now(),c.lastUsedAt=Date.now(),c.generation}else{let a=this.activeTransports.has(b)&&!this.clients.has(b);!function(a,b,c=!1){let d=q(a);d.state="error",d.lastError=b,d.connectFailures=Math.min(d.connectFailures+1,Number.MAX_SAFE_INTEGER),c&&(d.handshakeFailures+=1),d.retryAttempts+=1}(b,d.error??"unknown connection failure",a)}return d})}configFingerprint(a){if("string"!=typeof a)return[a.transport,a.command??"",(a.args??[]).join(" "),a.url??"",a.websocketUrl??"",a.rootPath??"",a.disabled?"disabled":"enabled"].join("\0")}async connectServerInternal(a){let b;if("string"==typeof a){bQ.info(`connectServer: Looking up config for server ${a}`);let c=await this.getServerConfig(a);if(!c)return bQ.warn(`connectServer: Server ${a} not found in configs`),{success:!1,error:`Server configuration for "${a}" not found. The server may have been deleted or not properly configured.`};b=c}else b=a;let c="string"==typeof a?b:await this.getServerConfig(b.name),e=c??b;if((c??b).disabled)return bQ.info(`connectServer: Server ${b.name} is disabled — refusing to create a client/transport`),this.clearRetryTimer(b.name),this.connectionRetryAttempts.delete(b.name),{success:!1,error:`Server '${b.name}' is disabled. Enable it on the MCP page to use it.`};let f=(0,d.A)();bQ.info(`connectServer: Starting connection for server ${b.name} [RequestID: ${f}]`),this.connectingServers.add(b.name);try{this.stderrLogs.set(b.name,[]),b=await aR(b);let a=await a2()&&"websocket"!==b.transport,c=await bF(b),d={enableRuntimeBroker:!0,isolateRuntimeHome:c},e=this.clients.get(b.name);if(e){let{needsNewClient:c,reason:f}=function(a,b,c=!1,d){if(aQ.debug("Entering shouldRecreateClient method"),(0,T.wk)(a))return{needsNewClient:!0,reason:"Existing connection is closed"};if((a.__flujoCapKey??"")!==aP(b))return{needsNewClient:!0,reason:"Client capabilities (sampling/elicitation/MCP Apps/Skills) changed"};let e=!0===a.__flujoBeta,f=c&&"websocket"!==b.transport;if(e!==f)return{needsNewClient:!0,reason:f?"Beta MCP protocol enabled":"Beta MCP protocol disabled"};if(e){let c=a.transport;if(!c||c.__flujoKind!==b.transport)return{needsNewClient:!0,reason:`Transport type changed to ${b.transport}`};if("stdio"===b.transport){if(c.__flujoStdioKey!==aW(b,d?.isolateRuntimeHome===!0))return{needsNewClient:!0,reason:"Connection parameters changed"}}else if(c.__flujoHttpKey!==aX(b))return{needsNewClient:!0,reason:`${b.transport} auth/connection parameters changed`};return{needsNewClient:!1}}if("websocket"===b.transport){if(!(a.transport instanceof M.I))return{needsNewClient:!0,reason:"Transport type changed to websocket"}}else if("streamable"===b.transport){if(!(a.transport instanceof N.j))return{needsNewClient:!0,reason:"Transport type changed to streamable"};let c=a.transport,d=c._url?.toString();if(void 0!==d&&d!==new URL(b.serverUrl).toString())return{needsNewClient:!0,reason:"Streamable server URL changed"};let e=c.__flujoHttpKey;if(!e)return{needsNewClient:!0,reason:"Existing streamable transport has no config key"};if(e!==aX(b))return{needsNewClient:!0,reason:"Streamable auth/connection parameters changed"}}else if("sse"===b.transport){if(!(a.transport instanceof O.A))return{needsNewClient:!0,reason:"Transport type changed to sse"};let c=a.transport,d=c._url?.toString();if(void 0!==d&&d!==new URL(b.serverUrl).toString())return{needsNewClient:!0,reason:"SSE server URL changed"};let e=c.__flujoHttpKey;if(!e)return{needsNewClient:!0,reason:"Existing sse transport has no config key"};if(e!==aX(b))return{needsNewClient:!0,reason:"SSE auth/connection parameters changed"}}else{if(!(a.transport instanceof L.oQ))return{needsNewClient:!0,reason:"Transport type changed to stdio"};if("stdio"!==b.transport)return{needsNewClient:!0,reason:"Transport type changed from stdio"};let c=a.transport.__flujoStdioKey;if(!c)return{needsNewClient:!0,reason:"Existing stdio transport has no config key"};if(c!==aW(b,d?.isolateRuntimeHome===!0))return{needsNewClient:!0,reason:"Connection parameters changed"}}return{needsNewClient:!1}}(e,b,a,d);if(!c)return bQ.info(`connectServer: Server ${b.name} is already connected`),this.lastConnectionError.delete(b.name),this.clearRetryTimer(b.name),this.connectionRetryAttempts.delete(b.name),await this.clearLegacyInferredOAuthScopesForHeaderAuth(b.name),{success:!0};bQ.info(`connectServer: Existing client for ${b.name} is stale (${f}), recreating`),this.deregisterClient(b.name);try{await a_(e,b.name,b)}catch(a){bQ.debug(`connectServer: error closing stale client for ${b.name}: ${a instanceof Error?a.message:String(a)}`)}e=void 0}e=a?a4(b):aY(b);let f=a?a6(b,d):aZ(b,d);if("stdio"===b.transport&&au(e,b.name,a?a7.get(f):void 0),a){let a=e.setNotificationHandler?.bind(e);a&&(a("notifications/resources/list_changed",(0,j.bindToCurrentWorkspace)(()=>{this.onResourceListChanged(b.name)})),a("notifications/resources/updated",(0,j.bindToCurrentWorkspace)(a=>{let c=a?.params?.uri;c&&this.onResourceUpdated(b.name,c)})))}else!function(a,b,c,d){try{a.setNotificationHandler(D.hh,a=>{bL.debug(`resourceListChanged notification received for ${b}`),c(b)})}catch(a){bL.warn(`registerResourceNotificationHandlers: failed to register list_changed for ${b}`,a)}if(d)try{a.setNotificationHandler(D.cL,a=>{let c=a.params?.uri;c&&(bL.debug(`resourceUpdated notification received for ${b} uri=${c}`),d(b,c))})}catch(a){bL.warn(`registerResourceNotificationHandlers: failed to register resource_updated for ${b}`,a)}}(e,b.name,(0,j.bindToCurrentWorkspace)(a=>this.onResourceListChanged(a)),(0,j.bindToCurrentWorkspace)((a,b)=>this.onResourceUpdated(a,b)));let g=bR(f).stderr;if(g&&"function"==typeof g.on){let a=b.name;g.on("data",(0,j.bindToCurrentWorkspace)(b=>{let c=b.toString();bQ.warn(`stderr: [${a}]: ${c}`),this.appendStderrLog(a,c)}))}if(f.onclose=(0,j.bindToCurrentWorkspace)(()=>{this.activeTransports.get(b.name)!==f?bQ.debug(`connectServer: ignoring close event from a stale/deregistered transport for ${b.name}`):(bQ.warn(`connectServer: Connection closed for server ${b.name}`),this.deregisterClient(b.name),this.getServerConfig(b.name).then(a=>{!a||a.disabled?bQ.info(`Server ${b.name} is now disabled, skipping reconnection logic`):(bQ.info(`Connection closed for enabled server ${b.name}, scheduling reconnection`),this.scheduleConnectionRetry(b.name,a))}).catch(a=>{bQ.warn(`Error checking server config for ${b.name} during onclose:`,a)}))}),f.onerror=(0,j.bindToCurrentWorkspace)(a=>{if((0,T.lO)(a))return void bQ.debug(`connectServer: transient SSE stream disconnect for ${b.name} (self-healing, ignored): ${a instanceof Error?a.message:String(a)}`);if(this.activeTransports.get(b.name)!==f)return void bQ.debug(`connectServer: ignoring error event from a stale/deregistered transport for ${b.name}`);if(bQ.error(`connectServer: Transport error for server ${b.name}:`),a instanceof Error){bQ.error(`Error name: ${a.name}`),bQ.error(`Error message: ${a.message}`),bQ.error(`Error stack: ${a.stack}`);let b=a.code;void 0!==b&&bQ.error(`Error code: ${b}`),bQ.error(`Error chain: ${(0,T.jf)(a)}`)}else if(a&&"object"==typeof a){let b=Object.getPrototypeOf(a),c="string"==typeof b?.constructor?.name?b.constructor.name:"Unknown";bQ.error(`Error type: ${typeof a}`),bQ.error(`Error constructor: ${c}`);let d=Object.getOwnPropertyNames(a);d.length>0?(bQ.error(`Error properties: ${d.join(", ")}`),d.forEach(b=>{try{let c=a[b];bQ.error(` ${b}: ${"function"==typeof c?"[Function]":JSON.stringify(c)}`)}catch(a){bQ.error(` ${b}: [Unable to serialize: ${a}]`)}})):bQ.error("Error object has no enumerable properties");try{let b=JSON.stringify(a);bQ.error(`JSON stringified error: ${b}`)}catch(a){bQ.error(`Cannot JSON stringify error: ${a}`)}}else bQ.error(`Error value: ${String(a)} (type: ${typeof a})`);this.appendStderrLog(b.name,`Transport error: ${(0,T.jf)(a)}`),this.deregisterClient(b.name),this.getServerConfig(b.name).then(a=>{!a||a.disabled?bQ.info(`Server ${b.name} is now disabled, skipping reconnection after transport error`):(bQ.info(`Transport error for enabled server ${b.name}, scheduling reconnection`),this.scheduleConnectionRetry(b.name,a))}).catch(a=>{bQ.warn(`Error checking server config for ${b.name} during onerror:`,a)})}),await e.connect(f),"stdio"===b.transport&&a&&a8(f),this.clients.set(b.name,e),this.activeTransports.set(b.name,f),this.clientGenerations.set(b.name,this.getClientGeneration(b.name)+1),aw(e))try{await ax(e,b.name,{force:!0})}catch(a){bQ.warn(`mcp-stdio-oauth readiness probe failed for ${b.name}:`,a)}this.lastConnectionError.delete(b.name),this.clearRetryTimer(b.name),this.connectionRetryAttempts.delete(b.name),await this.clearLegacyInferredOAuthScopesForHeaderAuth(b.name);let h=function(a){if(a3(a))try{return a.getNegotiatedProtocolVersion()}catch{return}}(e);return bQ.info(`connectServer: Successfully connected to ${b.name}`+(h?` (beta SDK, negotiated MCP protocol ${h})`:"")),{success:!0}}catch(j){let a;"stdio"===b.transport&&(0,aO.HW)(b.name),bQ.error(`connectServer: Failed to connect to server ${b.name}:`,j);let c=j instanceof Error?j.message:String(j),d=(0,T.uP)(j),f=(0,T.Ah)(j),g=bS(e);if(f&&!g&&("streamable"===b.transport||"sse"===b.transport)){let c=b.serverUrl;c&&(a=(await (0,bK.n)(c)).oauthCapable)}if(d||a){if(bQ.info(`OAuth authentication error detected for server ${b.name}: ${c}`),"streamable"===b.transport&&a){let a=b;if(!a.oauthScopes||0===a.oauthScopes.length){bQ.info(`Dynamically enabling OAuth for server ${b.name} after capability confirmation`);try{let c={...a,oauthScopes:["read"]},d=await this.loadServerConfigs();if(Array.isArray(d)){let a=d.findIndex(a=>a.name===b.name);-1!==a&&(d[a]=c,await (0,m.saveConfig)(new Map(d.map(a=>[a.name,a]))),bQ.info(`Updated config for ${b.name} to enable OAuth`))}}catch(a){bQ.warn(`Failed to update config for ${b.name} to enable OAuth:`,a)}}}return{success:!1,error:"OAuth authentication failed or tokens have expired. Please re-authenticate.",requiresAuthentication:!0,oauthCapable:!0}}if(f)return{success:!1,error:c,requiresAuthentication:!0,oauthCapable:a};let h=this.stderrLogs.get(b.name)||[],i=(0,T.ox)(j,b,h);return this.lastConnectionError.set(b.name,i),{success:!1,error:i}}finally{this.connectingServers.delete(b.name)}}async testConnection(a,b,c){bQ.info(`testConnection: Testing connection to ${a.name||"(unnamed)"} via ${a.transport} transport`);let d=a=>{try{b?.(a)}catch{}},e=[],f=null,g=null;try{var h;let b,i=a,j=c?.storedName||a.name;if(("streamable"===a.transport||"sse"===a.transport)&&j){let b=await this.loadServerConfigs(),c=Array.isArray(b)?b.find(a=>a.name===j):void 0,d=c?.headers,e=a.headers;i={...a,headers:(0,aM.x0)(e,d)}}let k=await aR(i),l=await a2()&&"websocket"!==k.transport,m={isolateRuntimeHome:await bF(k)};f=l?a4(k):aY(k),g=l?a6(k,m):aZ(k,m),"stdio"===k.transport&&au(f,k.name,l?(h=g,a7.get(h)):void 0);let n=bR(g).stderr;n&&"function"==typeof n.on&&n.on("data",a=>{let b=a.toString();e.push(b),d({type:"stderr",data:b})}),g.onerror=a=>{let b=`Transport error: ${(0,T.jf)(a)}`;e.push(b),d({type:"stderr",data:b+"\n"})},d({type:"status",phase:"spawning",message:"Starting server / opening transport..."});let o=bJ(a)?9e4:15e3,p=bJ(a),q=new Promise((a,c)=>{b=setTimeout(()=>c(Error(`Connection timeout after ${o/1e3}s`+(p?" — the package may still be downloading via npx/uvx. Try running the Test again (the package is cached after the first download), or verify the command and network access.":""))),o)});d({type:"status",phase:"handshaking",message:"Performing MCP handshake..."});try{await Promise.race([f.connect(g),q])}finally{b&&clearTimeout(b)}"stdio"===k.transport&&l&&a8(g),d({type:"status",phase:"listing-tools",message:"Handshake OK — listing tools..."});let r=0;try{let a=await f.listTools();r=Array.isArray(a?.tools)?a.tools.length:0}catch(b){bQ.debug(`testConnection: connected to ${a.name} but listTools failed: ${b instanceof Error?b.message:String(b)}`)}return bQ.info(`testConnection: Successfully connected to ${a.name} (${r} tools)`),d({type:"result",success:!0,data:{toolCount:r}}),{success:!0,data:{toolCount:r}}}catch(g){let b;bQ.warn(`testConnection: Failed to connect to ${a.name}:`,g);let c=(0,T.Ah)(g);if(c&&("streamable"===a.transport||"sse"===a.transport)){let c=a.serverUrl;c&&(b=(await (0,bK.n)(c)).oauthCapable)}let f=(0,T.ox)(g,a,e);return d({type:"result",success:!1,error:f,requiresAuthentication:c,oauthCapable:b}),{success:!1,error:f,requiresAuthentication:c,oauthCapable:b}}finally{if(f)try{await a_(f,a.name,a,{gracePeriodMs:3e3,killEscalationMs:2e3})}catch(b){bQ.debug(`testConnection: error closing test client for ${a.name}: ${b instanceof Error?b.message:String(b)}`)}}}setNodeRoots(a,b,c){for(let d of(0,aa.eS)(a,b,c))this.notifyRootsChanged(d)}notifyRootsChanged(a){let b=this.getClient(a);if(!b)return void bQ.debug(`notifyRootsChanged: ${a} not connected, skipping notification`);try{b.sendRootsListChanged().catch(b=>{bQ.warn(`notifyRootsChanged: failed to notify ${a}:`,b)}),bQ.debug(`notifyRootsChanged: sent roots/list_changed to ${a}`)}catch(b){bQ.warn(`notifyRootsChanged: failed to notify ${a}:`,b)}}notifyAllRootsChanged(){for(let a of this.clients.keys())this.notifyRootsChanged(a)}async disconnectServer(a){bQ.debug(`disconnectServer: Entering method for server ${a}`),this.clearRetryTimer(a),this.connectionRetryAttempts.delete(a);let b=this.getClient(a);if(!b)return bQ.warn(`disconnectServer: Server ${a} not found in clients map`),this.deregisterClient(a),{success:!1,error:`Server ${a} not found`};this.deregisterClient(a);try{let c=await this.getServerConfig(a);return await function(a,b,c){let d=q(a);if(d.teardownPromise)return n.debug(`beginTeardown: folding onto in-flight teardown for ${a} (${b})`),d.teardownPromise;let e=Date.now();d.state="stopping",d.teardownReason=b;let f=(async()=>{d.connectPromise&&await d.connectPromise.catch(()=>void 0);try{let a=await c(d);a&&a.forced&&(d.forcedKills+=1)}catch(c){n.warn(`beginTeardown: close failed for ${a} (${b}): ${c instanceof Error?c.message:String(c)}`)}finally{d.lastTeardownMs=Date.now()-e,d.state="cold",d.warmSince=void 0,d.configFingerprint=void 0,d.teardownPromise=void 0}})();return d.teardownPromise=f,f}(a,"disconnect",async()=>({forced:(await a_(b,a,c||void 0)).forced})),bQ.info(`disconnectServer: Disconnected server ${a}`),{success:!0}}catch(b){return bQ.warn(`disconnectServer: Failed to disconnect server ${a}:`,b),{success:!1,error:`Failed to disconnect server: ${b instanceof Error?b.message:"Unknown error"}`}}}async disconnectAll(a){let b=[],c=[],d=Array.from(new Set(Array.from(this.clients.keys())));for(let e of(bQ.info(`disconnectAll: tearing down ${d.length} MCP server(s) (${a})`),d)){this.clearRetryTimer(e),this.connectionRetryAttempts.delete(e);try{(await this.disconnectServer(e)).success?b.push(e):c.push(e)}catch(a){bQ.warn(`disconnectAll: teardown of ${e} threw: ${a instanceof Error?a.message:String(a)}`),c.push(e)}}for(let[a]of Array.from(this.connectionRetryTimers))this.clearRetryTimer(a),this.connectionRetryAttempts.delete(a);return bQ.info(`disconnectAll: closed=${b.length} failed=${c.length} (${a})`),{closed:b,failed:c}}getLifecycleReport(){let a;return{runtimes:function(a=!1){let b=Date.now();return(a?Array.from(o().values()):s()).map(a=>({server:a.serverName,workspace:a.workspace,state:a.state,generation:a.generation,leases:a.leases,pins:Array.from(a.pins),idleMs:Math.max(0,b-a.lastUsedAt),connectFailures:a.connectFailures,handshakeFailures:a.handshakeFailures,forcedKills:a.forcedKills,lastTeardownMs:a.lastTeardownMs,lastError:a.lastError}))}(),pool:(a=Date.now(),{...x(),idleTtlMs:v(),maxWarmServers:w(),servers:s().map(b=>({server:b.serverName,state:b.state,leases:b.leases,pins:Array.from(b.pins),idleMs:Math.max(0,a-b.lastUsedAt)}))}),liveClients:this.clients.size}}async sweepIdleMcpServers(){return[...await B(this),...await C(this)]}acquireServerLease(a){return z(this,a)}pinServer(a,b){A(a,b)}unpinServer(a,b){r(a)?.pins.delete(b)}async forceReconnect(a){bQ.info(`forceReconnect: Forcing fresh connection for server ${a}`);let b=this.clients.get(a);if(b){this.deregisterClient(a);let c=await this.getServerConfig(a);try{await a_(b,a,c||void 0)}catch(b){bQ.debug(`forceReconnect: error closing stale client for ${a}: ${b instanceof Error?b.message:String(b)}`)}}return this.connectServer(a)}async listServerTools(a,b="model"){if(bQ.debug(`listServerTools: Entering method for server ${a}, audience ${b}`),await this.isServerDisabled(a)){let b=`Server '${a}' is disabled. Enable it on the MCP page to use it.`;return bQ.warn(`listServerTools: ${b}`),{tools:[],error:b}}let c=this.getClient(a);c||bQ.warn(`listServerTools: Client not found for ${a}`);let d=await bi(c,a,b);if(d.error){bQ.warn(`listServerTools: Listing tools for ${a} failed (${d.error}); forcing reconnect and retrying once`);let e=await this.forceReconnect(a);if(!e.success)return bQ.warn(`listServerTools: Reconnect for ${a} failed: ${e.error}`),{tools:[],error:e.error||d.error};c=this.clients.get(a),(d=await bi(c,a,b)).error?bQ.warn(`listServerTools: Retry after reconnect still failed for ${a}:`,d.error):bQ.info(`listServerTools: Recovered after reconnect for ${a}; listed ${d.tools.length} tools`)}else bQ.info(`listServerTools: Listed ${d.tools.length} tools for ${a}`);return d}async getExternalAuthorizationStatus(a,b=!1){return ax(this.getClient(a),a,{force:b})}async prepareExternalAuthorization(a,b,c={}){let d=this.getClient(a);if(!d){let b=await this.forceReconnect(a);if(!b.success)throw Error(b.error||`Could not connect to ${a}.`);d=this.getClient(a)}if(!d)throw Error(`MCP server '${a}' is not connected.`);return aD(d,a,b,c)}confirmExternalAuthorization(a,b){let c=ap.get(at(b));if(!c||c.serverName!==a||!c.prompt)throw Error("The authorization request is no longer active. Start it again.");if(!c.resolveElicitation||c.elicitationResponded)throw Error("The authorization request is no longer awaiting consent. Start it again.");let d=c.resolveElicitation;return c.resolveElicitation=void 0,c.elicitationResponded=!0,d({action:"accept"}),ay(a),c.prompt}declineExternalAuthorization(a,b){let c=ap.get(at(b));if(!c||c.serverName!==a||!c.prompt||!c.resolveElicitation)return!1;let d=c.resolveElicitation;return c.resolveElicitation=void 0,c.elicitationResponded=!0,d({action:"decline"}),ay(a),!0}cancelExternalAuthorization(a,b){return aB(a,b)}async callTool(a,b,d,e,f,g,h,i="host",j,k){if(bQ.debug(`callTool: Entering method for server ${a}, tool ${b}, source ${i}`),await this.isServerDisabled(a)){let b=`Server '${a}' is disabled. Enable it on the MCP page to use it.`;return bQ.warn(`callTool: ${b}`),{success:!1,error:b}}let l=this.getClient(a),m=await this.acquireServerLease(a),n=m.lease;n?l=n.client:l||bQ.warn(`callTool: Lease acquisition for ${a} failed: ${m.error}`);try{let m;if(l&&aw(l))try{let c=await ax(l,a,{force:!0});if(c.blockingAuthorization){let d=c.blockingAuthorization,e=d.message||`${d.label} authorization is required. Open the MCP page to authenticate before running this flow.`;return bQ.warn(`callTool: blocked ${a}/${b}: ${e}`),{success:!1,error:e,errorType:"stdio-oauth-required",statusCode:428,requiresAuthentication:!0}}}catch(c){let b=c instanceof Error?c.message:String(c);return bQ.warn(`callTool: mcp-stdio-oauth readiness check failed for ${a}: ${b}`),{success:!1,error:`Could not verify account readiness for '${a}': ${b}`,errorType:"stdio-oauth-status",statusCode:503}}let n="model"===i&&"create_ticket_for_human"===b&&k?.conversationId?await this.getServerConfig(a):null,o=bN(n,b,i,k),p=o?(m=bN(n,b,i,k))?{...d,conversation_id:m}:d:d,q=await bj(l,a,b,p,e,f,h,i,g,j);if(q.success&&o){let a=function(a){if(!a||"object"!=typeof a)return;let b=a.content;if(Array.isArray(b))for(let a of b){if(!a||"object"!=typeof a||"text"!==a.type)continue;let b=a.text;if("string"==typeof b)try{let a=JSON.parse(b);if(!0===a.created&&"string"==typeof a.id&&bM.test(a.id))return a.id}catch{}}}(q.data);if(a)try{let{ticketService:b}=await c.e(7780).then(c.bind(c,77780));await b.stampPersonaAttributionFromTrustedConversation(a,o)}catch(b){bQ.error(`callTool: Failed to stamp trusted ticket attribution for ${a}`,b)}}return bQ.info(`callTool: Called tool ${b} on ${a}`),q}finally{n?.release()}}async callToolFromApp(a,b,c,d,e,f){let g=await this.checkMcpAppAccess(a);if(g)return g;let h=await this.callTool(a,b,c,d,void 0,void 0,e,"app",f);if("tool-authorization-list"!==h.errorType)return h;bQ.warn(`callToolFromApp: visibility lookup failed for ${a}/${b}; reconnecting and retrying once before dispatch`);let i=await this.forceReconnect(a);return i.success?h=await this.callTool(a,b,c,d,void 0,void 0,e,"app",f):{success:!1,error:i.error||h.error,statusCode:h.statusCode}}async isMcpAppAccessEnabled(a){let b=await this.getServerConfig(a);return b?.disabled!==!0&&b?.enableMcpApps===!0}async checkMcpAppAccess(a){if(await this.isMcpAppAccessEnabled(a))return null;let b=`MCP Apps are not enabled for server '${a}'. Enable them on the MCP page before opening or using this app.`;return bQ.warn(`MCP App access denied: ${b}`),{success:!1,error:b,statusCode:403}}async readResourceFromApp(a,b){let c=await this.checkMcpAppAccess(a);return c||this.readResource(a,b)}async listWithReconnect(a,b,c){if(await this.isServerDisabled(a)){let b=`Server '${a}' is disabled. Enable it on the MCP page to use it.`;return bQ.warn(`listWithReconnect: ${b}`),{...c,error:b}}let d=this.getClient(a);d||bQ.warn(`listWithReconnect: Client not found for ${a}`);let e=await b(d,a);if(!e.error)return e;bQ.warn(`listWithReconnect: Listing for ${a} failed (${e.error}); forcing reconnect and retrying once`);let f=await this.forceReconnect(a);return f.success?(d=this.clients.get(a),(e=await b(d,a)).error?bQ.warn(`listWithReconnect: Retry after reconnect still failed for ${a}:`,e.error):bQ.info(`listWithReconnect: Recovered after reconnect for ${a}`),e):(bQ.warn(`listWithReconnect: Reconnect for ${a} failed: ${f.error}`),{...c,error:f.error||e.error})}async listServerResources(a){return bQ.debug(`listServerResources: Entering method for server ${a}`),this.listWithReconnect(a,bl,{resources:[]})}async listServerResourceTemplates(a){return bQ.debug(`listServerResourceTemplates: Entering method for server ${a}`),this.listWithReconnect(a,bm,{resourceTemplates:[]})}async readResource(a,b){bQ.debug(`readResource: Entering method for server ${a}, uri ${b}`);let c=this.getClient(a);c||bQ.warn(`readResource: Client not found for ${a}`);let d=await bn(c,a,b);return bQ.info(`readResource: Read resource ${b} on ${a}`),d}async prepareMcpSkillsClient(a){let b=await this.getServerConfig(a);if(!b)return{success:!1,error:`MCP server '${a}' was not found.`,statusCode:404};if(b.disabled)return{success:!1,error:`Server '${a}' is disabled. Enable it on the MCP page to use it.`,statusCode:409,errorType:"disabled"};if(!0!==b.enableMcpSkills)return{success:!1,error:`MCP Skills are disabled for server '${a}'.`,statusCode:409,errorType:"skills_disabled"};let c=await this.connectServer(a);if(!c.success)return{success:!1,error:c.error||`Failed to connect to MCP server '${a}'.`,statusCode:c.statusCode||502};let d=this.getClient(a),e=bv(d,!0);return d&&e?{success:!0,data:{client:d,capability:e}}:{success:!1,error:`Server '${a}' does not advertise ${l.ET}.`,statusCode:404,errorType:"skills_unsupported"}}async getServerSkillsCapability(a){let b=await this.prepareMcpSkillsClient(a);return b.success?b.data?.capability:void 0}async listServerSkills(a,b){let c=await this.getServerConfig(a);if(!c||c.disabled||!0!==c.enableMcpSkills)return{resultType:"complete",skills:[],serverName:a,availability:"disabled",...!c?{error:`MCP server '${a}' was not found.`}:{}};let d=await this.prepareMcpSkillsClient(a);if(!d.success||!d.data)return{resultType:"complete",skills:[],serverName:a,availability:"skills_unsupported"===d.errorType?"unsupported":"available",..."skills_unsupported"===d.errorType?{}:{error:d.error}};let e=async a=>by(a,!0,b);try{return{...await e(d.data.client),serverName:a,availability:"available",capability:d.data.capability}}catch(b){if(b instanceof bu)return{resultType:"complete",skills:[],serverName:a,availability:"unsupported"};if((await this.forceReconnect(a)).success){let c=this.getClient(a);try{let b=await e(c),d=bv(c,!0);return{...b,serverName:a,availability:"available",...d?{capability:d}:{}}}catch(a){b=a}}return{resultType:"complete",skills:[],serverName:a,availability:"available",error:b instanceof Error?b.message:"Failed to list MCP Skills."}}}async getServerSkill(a,b){let c=await this.prepareMcpSkillsClient(a);if(!c.success||!c.data)return bP(c);try{return{success:!0,data:await bz(c.data.client,!0,b)}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to get MCP Skill.",statusCode:a instanceof bu?404:502}}}async readServerSkillDirectory(a,b,c){let d=await this.prepareMcpSkillsClient(a);if(!d.success||!d.data)return bP(d);try{return{success:!0,data:await bA(d.data.client,!0,b,c)}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to read MCP Skill directory.",statusCode:a instanceof bu?404:502}}}async readVerifiedSkillResource(a,b,c){let d=await this.prepareMcpSkillsClient(a);if(!d.success||!d.data)return bP(d);let e=await this.getServerSkill(a,b);if(!e.success||!e.data)return bP(e);try{return{success:!0,data:await bB(d.data.client,!0,e.data.skill,c)}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to verify MCP Skill resource.",statusCode:422}}}async loadVerifiedSkill(a,b,c){let d=await this.prepareMcpSkillsClient(a);if(!d.success||!d.data)return bP(d);let e=await this.getServerSkill(a,b);if(!e.success||!e.data)return bP(e);if("dynamic"===e.data.skill.resources)return{success:!1,error:"Dynamic MCP Skills cannot be integrity-verified.",statusCode:422};let f=(0,l.Bw)(e.data.skill.uri).normalizedUri,g=e.data.skill.resources.find(a=>a.uri===f);if(!g)return{success:!1,error:"MCP Skill manifest metadata is missing.",statusCode:422};if(!(0,bD.f9)({conversationId:c,serverName:a,skillUri:f,manifestDigest:g.digest}))return{success:!1,error:"This MCP Skill is not approved for the current conversation and manifest digest.",statusCode:403,errorType:"skills_approval_required"};try{return{success:!0,data:await bC(d.data.client,!0,a,e.data.skill)}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to load MCP Skill.",statusCode:422}}}async listServerPrompts(a){return bQ.debug(`listServerPrompts: Entering method for server ${a}`),this.listWithReconnect(a,bp,{prompts:[]})}async getPrompt(a,b,c){bQ.debug(`getPrompt: Entering method for server ${a}, prompt ${b}`);let d=this.getClient(a);d||bQ.warn(`getPrompt: Client not found for ${a}`);let e=await bq(d,a,b,c);return bQ.info(`getPrompt: Got prompt ${b} on ${a}`),e}async resolveOAuthSecretForSave(a,b){return((0,aM.uh)(a)&&(a=b??""),a)?a.startsWith("${global:")?a:this.encryptSecretForSave(a):""}async encryptSecretForSave(a){if(a.startsWith("encrypted_failed:"))throw Error("MCP credential encryption failed");if(a.startsWith("encrypted:")&&a.length>10)return a;let b=await (0,bG.Rs)(a);if(!b.startsWith("encrypted:")||b.length<=10)throw Error("MCP credential encryption failed");return b}async resolveEnvForSave(a,b){let c={};for(let[d,e]of Object.entries((0,bI.ds)(a))){let a="string"==typeof e?e:e.value,f=b?.[d],g="object"==typeof f&&f.metadata.isSecret;if(!("string"==typeof e?g||(0,bH.xc)(d):e.metadata.isSecret)){c[d]=e;continue}if(!((0,aM.uh)(a)&&(void 0===f||(a="string"==typeof f?f:f.value,(0,aM.uh)(a)))))c[d]={value:!a||(0,aM.T6)(a)?a:await this.encryptSecretForSave(a),metadata:{isSecret:!0}}}return c}async resolveHeadersForSave(a,b){let c={};for(let[d,e]of Object.entries(a||{})){if(!d)continue;let{value:a}=(0,aM.at)(e,d),{isSecret:f}=(0,aM.at)(e,d);if(!f){""!==a&&(c[d]={value:a,metadata:{isSecret:!1}});continue}if((0,aM.uh)(a)){let c=b?.[d];if(void 0===c||(a=(0,aM.at)(c,d).value,(0,aM.uh)(a)))continue}if(a){if((0,aM.T6)(a)){c[d]={value:a,metadata:{isSecret:!0}};continue}c[d]={value:await this.encryptSecretForSave(a),metadata:{isSecret:!0}}}}return c}async ensureManagedServerRootDir(a){try{let b=(a.rootPath||"").trim();if(!b)return;let c=["streamable","sse","websocket"].includes(a.transport),d="stdio"===a.transport&&(a.source?.type==="registry"||a.source?.type==="marketplace");if(!c&&!d)return;let e=h().resolve((0,j.getWorkspaceDataDir)(),b);if(h().dirname(e)===e)return;if(d){let a=h().join((0,j.getWorkspaceDataDir)(),"mcp-servers"),b=h().relative(a,e);if(!b||b.startsWith("..")||h().isAbsolute(b))return}await f().mkdir(e,{recursive:!0}),bQ.debug(`ensureManagedServerRootDir: ensured ${e} for ${a.name}`)}catch(b){bQ.warn(`ensureManagedServerRootDir: could not create root dir for ${a.name}:`,b)}}async updateServerConfig(a,b){bQ.debug(`updateServerConfig: Entering method for server ${a}`);let d=await this.loadServerConfigs();if(!Array.isArray(d))return bQ.warn("updateServerConfig: Failed to load configs:",d.error),d;let e=d.find(b=>b.name===a),f=!!e&&"string"==typeof b.name&&b.name!==a;if(f&&d.some(a=>a.name===b.name))return bQ.warn(`updateServerConfig: Refusing to rename ${a} -> ${b.name}: name already in use`),{success:!1,error:`A server named "${b.name}" already exists`};if(!e&&b.name)bQ.info(`updateServerConfig: Creating new server config for ${b.name}`),e={name:b.name,transport:"stdio",command:"",args:[],env:{},disabled:!1,_buildCommand:"",_installCommand:"",rootPath:""},d.push(e);else if(!e)return bQ.warn(`updateServerConfig: Server ${a} not found`),{success:!1,error:`Server ${a} not found`};b={...b};try{void 0!==b.env&&(b.env=await this.resolveEnvForSave(b.env,e.env));let a=b.oauthClientSecret;if(void 0!==a){let c=e.oauthClientSecret;b.oauthClientSecret=await this.resolveOAuthSecretForSave(a,c)}let c=b.headers;if(void 0!==c){let a=e.headers;b.headers=await this.resolveHeadersForSave(c,a)}}catch{return{success:!1,error:"Failed to encrypt MCP credentials; configuration was not saved"}}let g={...e};g={...e,...b};let h=JSON.stringify(e.roots??[])!==JSON.stringify(g.roots??[])||(e.rootPath??"")!==(g.rootPath??""),i=d.findIndex(b=>b.name===a);-1!==i?d[i]=g:g.name&&d.push(g);let j=await (0,m.saveConfig)(new Map(d.map(a=>[a.name,a])));if(!j.success)return bQ.warn(`updateServerConfig: Failed to save config for ${a}:`,j.error),j;if(await this.ensureManagedServerRootDir(g),f)try{let{flowService:b}=await Promise.resolve().then(c.bind(c,5385)),d=await b.migrateMcpServerReferences(a,g.name);d.success?d.migratedReferences>0&&bQ.info(`updateServerConfig: Migrated ${d.migratedReferences} MCP reference(s) across ${d.migratedFlows} flow(s)`):bQ.warn("updateServerConfig: Server rename succeeded, but some flow references could not be migrated",d)}catch(a){bQ.warn("updateServerConfig: Server rename succeeded, but flow-reference migration failed",a)}return f?(this.clients.has(a)?await this.disconnectServer(a):(this.clearRetryTimer(a),this.connectionRetryAttempts.delete(a)),this.stderrLogs.delete(a),this.lastConnectionError.delete(a),await this.handleConnectionStateChange(g.name,g)):await this.handleConnectionStateChange(a,g),h&&this.notifyRootsChanged(g.name),bQ.info(`updateServerConfig: Successfully updated config for ${a}${f?` (renamed to ${g.name})`:""}`),g}async handleConnectionStateChange(a,b){bQ.debug(`handleConnectionStateChange: Entering method for server ${a}`);let c=!!this.getClient(a),d=!b.disabled;if(c&&!d){bQ.info(`handleConnectionStateChange: Disconnecting disabled server ${a}`);try{await this.disconnectServer(a)}catch(b){bQ.warn(`handleConnectionStateChange: Failed to disconnect server ${a} during update:`,b)}}else!c&&d?(bQ.info(`handleConnectionStateChange: Connecting previously disabled server ${a}`),await this.connectServer(b)):c&&d?(bQ.info(`handleConnectionStateChange: Re-applying config to connected server ${a}`),await this.connectServer(b)):d||(bQ.info(`handleConnectionStateChange: Clearing retry timers for disabled server ${a}`),this.clearRetryTimer(a),this.connectionRetryAttempts.delete(a))}async clearRetryTimersForDisabledServers(){bQ.debug("clearRetryTimersForDisabledServers: Checking for disabled servers with active retry timers");try{let a=await this.loadServerConfigs();if(!Array.isArray(a))return void bQ.warn("clearRetryTimersForDisabledServers: Failed to load server configs");for(let b of a.filter(a=>a.disabled))this.connectionRetryTimers.has(b.name)&&(bQ.info(`clearRetryTimersForDisabledServers: Clearing retry timer for disabled server ${b.name}`),this.clearRetryTimer(b.name),this.connectionRetryAttempts.delete(b.name))}catch(a){bQ.error("clearRetryTimersForDisabledServers: Error clearing retry timers:",a)}}async deleteServerConfig(a){bQ.debug(`deleteServerConfig: Entering method for server ${a}`),this.clients.has(a)&&(bQ.info(`deleteServerConfig: Disconnecting server ${a} before deletion`),await this.disconnectServer(a));let b=await this.loadServerConfigs();if(!Array.isArray(b))return bQ.warn("deleteServerConfig: Failed to load configs:",b.error),b;let c=b.findIndex(b=>b.name===a);if(-1===c)return bQ.warn(`deleteServerConfig: Server ${a} not found in configs`),{success:!1,error:`Server ${a} not found`};b.splice(c,1),bQ.debug(`deleteServerConfig: Saving updated configs after deleting ${a}`);let d=await (0,m.saveConfig)(new Map(b.map(a=>[a.name,a])));return d.success?bQ.info(`deleteServerConfig: Successfully deleted server ${a}`):bQ.warn(`deleteServerConfig: Error saving configs after deleting ${a}:`,d.error),d}async getServerStatus(a){let b,c=await this.getServerConfig(a);if(!c)return bQ.warn(`getServerStatus: Server ${a} not found`),{status:"error",message:`Server ${a} configuration not found. The server may have been deleted or not properly configured.`};if(c.disabled)return bQ.debug(`getServerStatus: Server ${a} is disabled`),{status:"disconnected"};let d=!!this.getClient(a);if("streamable"===c.transport&&!d&&c.oauthScopes&&c.oauthScopes.length>0){if(!c.oauthTokens||!c.oauthTokens.access_token)return bQ.info(`getServerStatus: Server ${a} requires OAuth authentication but has no valid tokens`),{status:"requires_authentication",message:"OAuth authentication required. Click the authenticate button to complete the OAuth flow."};let b=c.oauthTokens.issued_at;if(!c.oauthTokens.refresh_token&&c.oauthTokens.expires_in&&b){let d=c.oauthTokens.expires_in;if(Math.floor(Date.now()/1e3)>=b+d)return bQ.info(`getServerStatus: OAuth tokens for ${a} have expired and no refresh token is available`),{status:"requires_authentication",message:"OAuth tokens have expired. Please re-authenticate."}}}let e=(this.stderrLogs.get(a)||[]).join("\n").trim(),f=this.lastConnectionError.get(a);if(d){let c=this.getClient(a);if(aw(c))try{if((b=await ax(c,a)).blockingAuthorization){let a=b.blockingAuthorization;return{status:"requires_authentication",message:a.message||`${a.label} authorization is required before this server can be used by unattended flows.`,stderrOutput:e||void 0,stdioOAuth:b}}}catch(b){let a=b instanceof Error?b.message:String(b);return{status:"error",message:`Connected, but the mcp-stdio-oauth readiness check failed: ${a}`,stderrOutput:e||void 0}}}if(d||this.getClient(a))return bQ.info(`getServerStatus: Server ${a} is connected`),{status:"connected",stderrOutput:e||void 0,...b?{stdioOAuth:b}:{}};{let b=this.isStartingUp()&&!this.lastConnectionError.has(a);if(this.connectingServers.has(a)||b)return bQ.info(`getServerStatus: Server ${a} is still connecting`),{status:"connecting",message:"Server is starting up. This may take a few moments."};if(e&&(e.includes("OAuth authentication required")||e.includes("invalid_token")))return bQ.info(`getServerStatus: OAuth authentication error detected for ${a}`),{status:"requires_authentication",message:"OAuth authentication required. Please complete the OAuth flow.",stderrOutput:e};let c=e||f;return c?(bQ.info(`getServerStatus: Using ${e?"stderr output":"persisted connection error"} as error message for ${a}`),{status:"error",message:c,stderrOutput:e||void 0}):(bQ.info(`getServerStatus: No specific error details available for ${a}`),{status:"error",message:`Server ${a} is configured but not connected. The server process may have crashed or been terminated.`,stderrOutput:void 0})}}async startEnabledServers(){bQ.info("Starting all enabled servers"),this.setStartingUp(!0);try{await this.clearRetryTimersForDisabledServers();let a=await this.loadServerConfigs();if(!Array.isArray(a))return void bQ.warn("Failed to load server configs, cannot start servers");let b=a.filter(a=>!a.disabled),c=/^(1|true|yes)$/i.test(process.env.FLUJO_MCP_LAZY_START??""),d=b.filter(a=>!0===a.alwaysOn);for(let a of d)A(a.name,"always-on");let e=c?d:b;c?bQ.info(`Lazy MCP start: ${b.length} enabled server(s) discovered, warming only ${d.length} always-on server(s)`):(bQ.info(`Found ${e.length} enabled servers to start`),bQ.debug(`${e}`)),e.forEach(a=>this.connectingServers.add(a.name));let f=Math.max(1,Number(process.env.FLUJO_MCP_BOOT_CONCURRENCY)||2);bQ.info(`Connecting ${e.length} enabled servers with boot concurrency ${f}`),await (0,k.P)(e,f,async a=>{bQ.info(`Starting server: ${a.name}`),await this.connectServer(a).catch(b=>{bQ.error(`Failed to start server ${a.name}:`,b)})})}finally{this.setStartingUp(!1)}}async getAvailableClients(){try{let a=await this.loadServerConfigs();if(!a||"error"in a)return bQ.warn("getAvailableClients: Failed to load server configs:",a?.error),[];return(await Promise.all(a.map(async a=>{try{let b=await this.getServerStatus(a.name);return{name:a.name,status:"string"==typeof b?b:b.status,connected:"string"==typeof b?"connected"===b:"connected"===b.status}}catch(b){return bQ.warn(`getAvailableClients: Error getting status for ${a.name}:`,b),{name:a.name,status:"error",connected:!1}}}))).map(a=>`${a.name} (${a.status})`)}catch(a){return bQ.error("getAvailableClients: Error getting available clients:",a),[]}}constructor(){this.stderrLogsBase=new Map,this.lastConnectionErrorBase=new Map,this.inFlightConnectsBase=new Map,this.connectionRetryTimersBase=new Map,this.connectionRetryAttemptsBase=new Map,this.resourceListVersionBase=new Map,this.pendingResourceUpdatesBase=new Map}}let bU=new bT},21995:(a,b,c)=>{"use strict";c.d(b,{Fv:()=>l,IT:()=>i,NK:()=>m,hF:()=>g,jg:()=>f,ks:()=>d,lM:()=>h,nj:()=>e,pV:()=>k});let d=.75,e={importanceWeight:.25,confidenceWeight:.15,exactContentMatchBonus:4,termHitBonus:1,termCoverageBonus:1.5,lengthNormalisationChars:280,lengthNormalisationFloor:.6,recencyHalfLifeDays:90,recencyFloor:.15,trustWeights:{explicit_user:1.3,verified_tool:1.15,model_inference:1,external_untrusted:.8},coreBonus:2,coreExemptFromDecay:!0,lexicalWeight:.6,semanticWeight:.4},f={enabled:!0,shingleSize:3,nearDuplicateThreshold:.82,comparisonWindow:200,confidenceReinforcementStep:.05,importanceReinforcementStep:.02,maxSourceRefsPerItem:64};function g(a){return a.toLocaleLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}\s_]/gu," ").replace(/\s+/g," ").trim()}function h(a,b=f.shingleSize){let c=new Set;if(a.length<b)return a.length>0&&c.add(a),c;for(let d=0;d<=a.length-b;d++)c.add(a.substring(d,d+b));return c}function i(a,b){if(0===a.size&&0===b.size)return 1;if(0===a.size||0===b.size)return 0;let c=new Set([...a].filter(a=>b.has(a))),d=new Set([...a,...b]);return c.size/d.size}function j(a){return void 0!==a&&Number.isFinite(a)?Math.min(1,Math.max(0,a)):null}function k(a,b,c=d){if(a)return!0;if(!b?.available)return!1;let e=j(b.score),f=Number.isFinite(c)?Math.min(1,Math.max(0,c)):d;return null!==e&&e>=f}function l(a){let{item:b,terms:c,core:d,asOf:f,weights:g=e}=a,h=a.semantic??(void 0===a.semanticScore?void 0:{available:!0,score:a.semanticScore}),i=b.content.toLocaleLowerCase(),k=b.importance*g.importanceWeight+b.confidence*g.confidenceWeight,l=0;for(let a of c)i===a?(k+=g.exactContentMatchBonus,l++):i.includes(a)&&(k+=g.termHitBonus,l++);c.length>0&&(k+=g.termCoverageBonus*(l/c.length));let m=function(a,b,c=e){let d="number"==typeof b?{available:!0,score:b}:b,f=j(d?.score);return d?.available&&null!==f?c.lexicalWeight*a+c.semanticWeight*f:a}(Math.min(1,k/10),h,g)*function(a,b=e){if(a<=b.lengthNormalisationChars)return 1;let c=1/(1+a/b.lengthNormalisationChars);return Math.max(b.lengthNormalisationFloor,c)}(b.content.length,g)*function(a,b=e){return b.trustWeights[a]??b.trustWeights.model_inference}(b.trust,g)*function(a,b,c={}){let d=c.weights??e,f=c.core??!1,g=c.halfLifeDays??d.recencyHalfLifeDays,h=c.floor??d.recencyFloor;return f&&d.coreExemptFromDecay?1:Math.max(h,Math.pow(2,-Math.max(0,(b-a)/864e5)/g))}(b.updatedAt,f,{core:d,weights:g});return d&&(m+=g.coreBonus),m}function m(a,b,c=f){if(!c.enabled)return null;let d=a.filter(a=>"active"===a.status&&a.kind===b.kind&&a.scope===b.scope).sort((a,b)=>b.updatedAt-a.updatedAt||a.id.localeCompare(b.id)).slice(0,c.comparisonWindow),e=h(g(b.content),c.shingleSize),j=null;for(let a of d){let b=i(e,h(g(a.content),c.shingleSize));b>=c.nearDuplicateThreshold&&(null===j||b>j.similarity)&&(j={candidate:a,similarity:b})}return j}Object.freeze({id:"current",ranking:e,dedup:f})},23759:(a,b,c)=>{"use strict";c.d(b,{L9:()=>j,OM:()=>h,SP:()=>g,gg:()=>k});var d=c(66844),e=c(20228);let f=(0,d.h)("backend/flow/execution/handlers/runQuestionTool"),g="question";function h(a){return a===g}let i="Type your own answer";function j(){return{name:g,description:'Ask the user one or more multiple-choice questions and wait for their answer, then CONTINUE working with that answer — use this instead of guessing or ending your turn when you genuinely need the user to decide between options. Provide a list of questions; each has a prompt and a list of options. Set `multiple: true` on a question to let the user pick more than one option (answers come back as a list). `custom` defaults to true and automatically appends a "'+i+'" free-text option — so do NOT add your own "Other"/"Something else" catch-all option. If you want to recommend an option, put it FIRST and suffix its label with " (Recommended)". Only ask when it materially changes what you do next; keep the number of questions and options small.',inputSchema:{type:"object",properties:{questions:{type:"array",description:"The questions to ask the user.",items:{type:"object",properties:{prompt:{type:"string",description:"The question to ask."},options:{type:"array",items:{type:"string"},description:'The options the user can choose from. Do not include an "Other" option.'},multiple:{type:"boolean",description:"Allow selecting more than one option. Defaults to false."},custom:{type:"boolean",description:'Auto-append a free-text "'+i+'" option. Defaults to true.'}},required:["prompt","options"]}}},required:["questions"]}}}async function k(a,b){if(!b.conversationId)return{success:!1,error:"The question tool is not available in this run."};let c=function(a){let b=a?.questions??[];if(!Array.isArray(b)||0===b.length)return{error:'question requires a non-empty "questions" array.'};let c=[];for(let a of b){let b="string"==typeof a.prompt?a.prompt.trim():"";if(!b)return{error:'each question requires a non-empty "prompt".'};let d=Array.isArray(a.options)?a.options.filter(a=>"string"==typeof a&&a.trim().length>0).map(a=>a.trim()):[],e=!0===a.multiple,f=!1!==a.custom,g=[...d];if(f&&!g.includes(i)&&g.push(i),0===g.length)return{error:`question "${b}" needs at least one option.`};c.push({prompt:b,options:g,multiple:e,custom:f})}return{questions:c}}(a);if("error"in c)return{success:!1,error:c.error};let{questions:d}=c;if(b.unattended)return f.info("question tool called in unattended run; returning a tool-error",{conversationId:b.conversationId}),{success:!1,error:"This is an unattended run with no user available to answer questions. Proceed using your best judgement without asking."};let g=crypto.randomUUID();f.info("Suspending for question",{conversationId:b.conversationId,questionId:g,count:d.length}),b.emit?.({type:"run:awaiting_question",node:b.node,questionId:g,questions:d});let h=await (0,e.RZ)(b.conversationId,g,d,b.timeoutMs);if("answer"===h.action){var j;let a,c=(j=h.answers,a=d.map((a,b)=>{let c=j[b]??[];return`"${a.prompt}" = "${c.join(", ")}"`}),`User has answered your questions: ${a.join("; ")}. You can now continue with the user's answers in mind.`);return f.info("question answered",{conversationId:b.conversationId,questionId:g}),{success:!0,data:c}}return"decline"===h.action?(f.info("question declined",{conversationId:b.conversationId,questionId:g}),{success:!0,declined:!0,data:"The user declined to answer your question. Do not ask again; stop and end your turn."}):(f.warn("question timed out",{conversationId:b.conversationId,questionId:g}),{success:!1,error:"No answer was received in time. Proceed without the user's answer."})}},25021:(a,b,c)=>{"use strict";c.d(b,{Y$:()=>k,oI:()=>m,oc:()=>j});var d=c(18963),e=c(92870),f=c(52649);let g=e.DW,h=d.k5(g),i={...f.PS,work_item_list:{name:"work_item_list",description:"Read this Persona's durable goals and tasks, including progress, next actions, dependencies and blocked work. Use this to continue an existing plan instead of creating duplicate tasks.",inputSchema:{type:"object",properties:{statuses:{type:"array",items:{type:"string",enum:["open","in_progress","blocked","completed","cancelled"]}},parent_goal_id:{type:"string",description:"Optionally show only the tasks belonging to this ongoing goal."},limit:{type:"integer",minimum:1,maximum:100,default:50},offset:{type:"integer",minimum:0,default:0,description:"Continue from next_offset when a previous list was truncated."}}}},work_item_create:{name:"work_item_create",description:"Create a durable task. During ongoing-goal work it automatically belongs to that goal and runs when ready; outside an ongoing goal it is saved for assignment. List existing tasks first to avoid duplicates. Run todos remain scratch-scoped unless promoted separately.",inputSchema:{type:"object",properties:{title:{type:"string"},description:{type:"string"},priority:{type:"string",enum:["low","normal","high","urgent"]},dependency_ids:{type:"array",items:{type:"string"}},next_action:{type:"string"},deadline:{type:"number"},parent_goal_id:{type:"string",description:"The owning ongoing goal. Inherited from the current goal Activity when omitted."}},required:["title"]}},work_item_update:{name:"work_item_update",description:"Update a durable Persona WorkItem, including status, priority, dependencies, deadline, and next action.",inputSchema:{type:"object",properties:{work_item_id:{type:"string"},title:{type:"string"},description:{type:["string","null"]},status:{type:"string",enum:["open","in_progress","blocked","completed","cancelled"]},priority:{type:"string",enum:["low","normal","high","urgent"]},dependency_ids:{type:"array",items:{type:"string"}},next_action:{type:["string","null"]},deadline:{type:["number","null"]},expected_updated_at:{type:"number"}},required:["work_item_id"]}},work_item_complete:{name:"work_item_complete",description:"Complete one durable Persona WorkItem after all dependencies are completed.",inputSchema:{type:"object",properties:{work_item_id:{type:"string"},expected_updated_at:{type:"number"}},required:["work_item_id"]}},work_item_promote_todo:{name:"work_item_promote_todo",description:"Explicitly promote one pending/in-progress run todo into a durable Persona WorkItem. The scratch todo is not changed.",inputSchema:{type:"object",properties:{todo_id:{type:"string"},title:{type:"string"},priority:{type:"string",enum:["low","normal","high","urgent"]},next_action:{type:"string"},deadline:{type:"number"}},required:["todo_id"]}},report_activity_outcome:{name:"report_activity_outcome",description:"Before ending this Activity, persist what was actually achieved and verified, remaining work and the next action. Succeeded means this Activity succeeded; set goal_achieved only when the entire ongoing goal's success criteria are met. A plan or draft alone is not evidence of a published result. Reporting does not end the current run.",inputSchema:{type:"object",properties:{resolution:{type:"string",enum:["succeeded","partial","blocked","failed","unknown"]},summary:{type:"string",maxLength:2e3,description:"Verified results with concrete evidence such as artifact paths, source URLs or observed tool results; distinguish completed actions from plans."},next_action:{type:"string",maxLength:2e3,description:"Required when work is unfinished. State the next executable step or the exact human input needed."},blocker_kind:{type:"string",enum:["information","approval","permission","capability","dependency","external","transient","policy","unknown"]},goal_achieved:{type:"boolean",description:"True only when the entire ongoing goal is achieved, all necessary tasks are complete and its success criteria have been verified."},retry_after_ms:{type:"integer",minimum:0,maximum:6048e5,description:"Optional wait before the next attempt, for example when a service is temporarily unavailable or an external result needs time."}},required:["resolution","summary"]}},suggest_improvement:{name:"suggest_improvement",description:"After completing work, propose one reusable instruction-only Behavior improvement when concrete Activity evidence shows it would help future work. The change is validated, shown in Improvements, and follows the user-selected review rule.",inputSchema:{type:"object",properties:{behavior_slot:{type:"string",description:"Behavior slot to improve. Use primary for the main Persona Flow."},rationale:{type:"string",description:"Plain-language explanation of the repeated problem and expected benefit."},instruction:{type:"string",description:"One concise reusable instruction for future work. Do not include credentials, external content, or task-specific facts."}},required:["rationale","instruction"]}}};function j(a){return h.safeParse(a).success}function k(a,b={}){if(!Array.isArray(a))return[];let c=[...new Set(a.filter(a=>"string"==typeof a&&j(a)))];return g.filter(a=>c.includes(a)).map(a=>{let c=structuredClone(i[a]);if("remember"===a&&b.maintenanceMemoryProposal){let a=Array.isArray(c.inputSchema.required)?c.inputSchema.required.filter(a=>"string"==typeof a):[];c.inputSchema.required=[...new Set([...a,"evidence_ids"])],c.description="Submit one evidence-backed candidate memory during post-Activity maintenance. Invalid proposals are rejected without writing and may be corrected and retried."}return c})}function l(a,b){return"string"==typeof a[b]&&a[b].trim()||void 0}async function m(a,b,e){if((0,f.NS)(a))return(0,f.pY)(a,b,e);try{let g=(0,f.Rq)(e),h={executionAuthority:g.executionAuthority},i=[{kind:"activity",id:g.activityId,...e.conversationId?{uri:`flujo://conversation/${e.conversationId}`}:{}}];switch(a){case"work_item_list":{let{queryPersonaWorkItems:a,withPersonaDomainMutation:e}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106)),f=d.ai().int().min(1).max(100).parse(b.limit??50),i=d.ai().int().min(0).max(1e6).parse(b.offset??0),j=await e(g.personaId,h,async({activity:c})=>{if(c?.id!==g.activityId)throw Error("Task access crossed Activity ownership.");return a(g.personaId,{...void 0!==b.statuses?{statuses:b.statuses}:{}})}),k=l(b,"parent_goal_id"),m=k?j.filter(a=>a.parentGoalId===k):j,n=m.length>i+f;return{success:!0,data:{items:m.slice(i,i+f),total:m.length,truncated:n,...n?{next_offset:i+f}:{}}}}case"report_activity_outcome":{let{reportPersonaActivityOutcome:a}=await c.e(9434).then(c.bind(c,19434)),d=await a(g.personaId,g.activityId,{resolution:b.resolution,summary:b.summary,...void 0!==b.next_action?{nextAction:b.next_action}:{},...void 0!==b.blocker_kind?{blockerKind:b.blocker_kind}:{},...void 0!==b.goal_achieved?{goalAchieved:b.goal_achieved}:{},...void 0!==b.retry_after_ms?{retryAfterMs:b.retry_after_ms}:{}},h);return{success:!0,data:{reported:!0,outcome:d}}}case"work_item_create":{let{createPersonaWorkItem:a}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106)),d=await a({personaId:g.personaId,title:l(b,"title")??"",...l(b,"description")?{description:l(b,"description")}:{},...l(b,"priority")?{priority:b.priority}:{},...Array.isArray(b.dependency_ids)?{dependencyIds:b.dependency_ids}:{},...l(b,"next_action")?{nextAction:l(b,"next_action")}:{},..."number"==typeof b.deadline?{deadline:b.deadline}:{},...l(b,"parent_goal_id")?{parentGoalId:l(b,"parent_goal_id")}:{},sourceRefs:i},h);return{success:!0,data:{created:!0,item:d}}}case"work_item_update":{let{updatePersonaWorkItem:a}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106)),d=await a(g.personaId,l(b,"work_item_id")??"",{...l(b,"title")?{title:l(b,"title")}:{},...null===b.description||"string"==typeof b.description?{description:b.description}:{},...l(b,"status")?{status:b.status}:{},...l(b,"priority")?{priority:b.priority}:{},...Array.isArray(b.dependency_ids)?{dependencyIds:b.dependency_ids}:{},...null===b.next_action||"string"==typeof b.next_action?{nextAction:b.next_action}:{},...null===b.deadline||"number"==typeof b.deadline?{deadline:b.deadline}:{},..."number"==typeof b.expected_updated_at?{expectedUpdatedAt:b.expected_updated_at}:{}},h);return{success:!0,data:{updated:!0,item:d}}}case"work_item_complete":{let{updatePersonaWorkItem:a}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106)),d=await a(g.personaId,l(b,"work_item_id")??"",{status:"completed",..."number"==typeof b.expected_updated_at?{expectedUpdatedAt:b.expected_updated_at}:{}},h);return{success:!0,data:{completed:!0,item:d}}}case"work_item_promote_todo":{let{promoteRunTodoToWorkItem:a}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106)),d=await a(g.personaId,{todoId:l(b,"todo_id")??"",...l(b,"title")?{title:l(b,"title")}:{},...l(b,"priority")?{priority:b.priority}:{},...l(b,"next_action")?{nextAction:l(b,"next_action")}:{},..."number"==typeof b.deadline?{deadline:b.deadline}:{}},h);return{success:!0,data:{promoted:!0,item:d}}}case"suggest_improvement":{let{suggestBehaviorInstructionImprovement:a}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106));await g.executionAuthority.assertCurrent();let d=await a({personaId:g.personaId,slotKey:l(b,"behavior_slot")??"primary",rationale:l(b,"rationale")??"",instruction:l(b,"instruction")??"",evidenceRefs:i});return await g.executionAuthority.assertCurrent(),{success:!0,data:{proposed:!0,applied:"activated"===d.status,proposal:d}}}}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Persona tool failed."}}}},26100:(a,b,c)=>{"use strict";c.d(b,{Yp:()=>h,nl:()=>i});var d=c(47304),e=c.n(d);let f=(0,c(66844).h)("backend/execution/flow/pocketflow"),g="default";class h{constructor(){f.debug("BaseNode constructor called"),this.flow_params={},this.successors=new Map}setParams(a,b){f.debug("setParams called with params",{params:a}),f.verbose("setParams input",{params:a,node_params:b}),this.flow_params=a,this.node_params=b,f.debug("setParams finished. parameter counts",{flowParams:Object.keys(this.flow_params).length,nodeParams:Object.keys(this.node_params).length}),f.verbose("setParams result",{flow_params:this.flow_params,node_params:this.node_params})}clone(){f.debug("clone called");let a=this._clone();return f.verbose("_clone result",{newNode:a}),a.flow_params=e()(this.flow_params),f.verbose("Cloned flow_params",{flow_params:a.flow_params}),a.node_params=e()(this.node_params),f.verbose("Cloned node_params",{node_params:a.node_params}),a.successors=new Map(this.successors),f.verbose("Cloned successors",{successors:a.successors}),f.verbose("clone finished"),a}addSuccessor(a,b=g){if(f.verbose(`addSuccessor called with action: ${b}`),this.successors.has(b))throw f.error(`Action ${b} already exists`),Error(`Action ${b} already exists`);this.successors.set(b,a),f.debug("addSuccessor finished. Successors",{successors:this.successors})}getSuccessor(a){if(f.debug(`getSuccessor called with name: ${a}`),!this.successors.has(a))return void f.error(`Successor ${a} not found`);let b=this.successors.get(a).clone();return f.debug("getSuccessor finished. Returning successor",{successor:b}),b}async execWrapper(a,b){f.debug("execWrapper called with prepResult",{prepResult:a}),f.verbose("execWrapper input",{prepResult:a,node_params:b});let c=await this.execCore(a,b);return f.debug("execWrapper finished. Result",{result:c}),f.verbose("execWrapper result",c),c}async run(a){f.debug("run called with sharedState",{sharedState:a}),f.debug("Current flow_params at start of run",{flow_params:this.flow_params}),f.verbose("run input",{sharedState:a,flow_params:this.flow_params,node_params:this.node_params});let b=await this.prep(a,this.node_params);f.verbose("run prepResult",b);let c=await this.execWrapper(b,this.node_params);f.verbose("run execResult",c);let d=await this.post(b,c,a,this.node_params);return f.debug("action",{action:d}),f.debug(`run finished. Returning action: ${d}`),f.verbose("run action result",{action:d,prepResult:b,execResult:c}),{action:d,prepResult:b,execResult:c}}}class i extends h{constructor(a){f.debug("Flow constructor called with start",{start:a}),super(),this.start=a}_clone(){f.debug("Flow _clone called");let a=new i(this.start);return f.debug("Flow _clone finished. Returning",{newFlow:a}),a}async getStartNode(){f.debug("getStartNode called");let a=this.start.clone();return f.debug("getStartNode finished. Returning",{clonedStart:a}),a}async execCore(a){throw f.error("Flow node does not support direct execution"),f.verbose("Flow execCore error",{error:"Flow node does not support direct execution"}),Error("Flow node does not support direct execution")}async prep(a,b){return f.debug("Flow prep called with sharedState",{sharedState:a}),f.verbose("Flow prep input",{sharedState:a,node_params:b}),f.debug("Flow prep finished. Returning empty object"),f.verbose("Flow prep result",{}),{}}async post(a,b,c,d){return f.debug("Flow post called with prepResult, execResult, and sharedState",{prepResult:a,execResult:b,sharedState:c}),f.verbose("Flow post input",{prepResult:a,execResult:b,node_params:d}),f.debug("Flow post finished. Returning DEFAULT_ACTION"),f.verbose("Flow post result",{action:g}),g}}},28051:(a,b,c)=>{"use strict";c.d(b,{R:()=>f,S:()=>e});let d=(0,c(66844).h)("backend/services/mcp/ownerScope");function e(a){let b=a.runId?.trim();if(b)return`run:${b}`;let c=a.conversationId?.trim();if(c)return`conversation:${c}`}async function f(a,b="bash"){if(a)try{let{mcpService:e}=await Promise.resolve().then(c.bind(c,21627));if(!e.getClient(b))return;let f=await e.callTool(b,"release_owner",{},30,void 0,void 0,void 0,"host",a);f.success||d.debug(`releaseRunOwnedBashSessions: release_owner reported ${f.error}`)}catch(b){d.debug(`releaseRunOwnedBashSessions: release for ${a} failed: ${b instanceof Error?b.message:String(b)}`)}}},29567:(a,b,c)=>{"use strict";c.d(b,{EQ:()=>l,EY:()=>g,bP:()=>j,mE:()=>k});var d=c(66844),e=c(77823);let f=(0,d.h)("backend/execution/flow/handlers/summarizingCompaction"),g="[FLUJO conversation summary]",h=["## Objective","## Important Details","## Work State","## Next Move","## Relevant Files"];function i(a){let b=0;try{b=JSON.stringify(a).length}catch{b="string"==typeof a.content?a.content.length:0}return Math.ceil(b/4)}function j(a){let b=0;for(let c of a)b+=i(c);return b}function k(a){return"assistant"===a.role&&"string"==typeof a.content&&a.content.startsWith(g)}async function l(a,b,c){var d;let j,l,m,n=c.now??Date.now,o=c.uuid??(()=>crypto.randomUUID()),p=function(a,b){let c,d={toSummarize:[],leadingSystem:[],preservedSubflow:[],toKeep:a};if(0===a.length)return d;let e=0,f=a.length;for(let c=a.length-1;c>=0&&(e+=i(a[c]),f=c,!(e>=b));c--);if(f<=0&&e<b)return d;for(;f>0;){let b=a[f],c=a[f-1],d="assistant"===c.role&&Array.isArray(c.tool_calls)&&(c.tool_calls?.length??0)>0;if("tool"===b.role||d)f--;else break}let h=a.slice(0,f),j=a.slice(f),l=[],m=[],n=[];for(let a of h){if("system"===a.role){l.push(a);continue}if((a.depth??0)>0){m.push(a);continue}k(a)&&"string"==typeof a.content&&(c=a.content.slice(g.length).trim()),n.push(a)}return{toSummarize:n,leadingSystem:l,preservedSubflow:m,toKeep:j,previousSummary:c}}(a,b.keepTokens);if(0===p.toSummarize.length)return f.debug("compactHistory: nothing old enough to summarize; no-op"),null;let q=b.reusableArtifact;if(q&&1===q.schemaVersion&&q.conversationId===b.conversationId&&q.nodeId===b.nodeId&&q.sourceDigest===b.sourceDigest&&q.projectionDigest===b.projectionDigest&&q.policyVersion===b.policyVersion&&q.modelId===b.modelId&&q.sourceStartId===p.toSummarize[0]?.id&&q.sourceEndId===p.toSummarize.at(-1)?.id&&q.sourceMessageCount===p.toSummarize.length){let a={id:q.artifactId,role:"assistant",content:q.summaryText,timestamp:q.createdAt,...void 0!==b.nodeId?{processNodeId:b.nodeId}:{}};return{wireMessages:[...p.leadingSystem,a,...p.preservedSubflow,...p.toKeep],artifact:q,summarizedMessageIds:p.toSummarize.map(a=>a.id).filter(a=>!!a)}}let r=(d={previousSummary:p.previousSummary},m=h.join("\n"),{system:`You are compacting a long agentic conversation into a compact, loss-minimising anchor the assistant will continue from. Produce ONLY the summary in the exact section structure below — no preamble, no closing remarks, and NEVER mention that the conversation was summarized or compacted.
|
|
13
|
+
`,"utf8"),await v(d,c)})})(a).catch(()=>{m.warn("Statistics event append failed",{type:a.type})})}async function B(){for(;p.size>0;)await Promise.allSettled([...p.values()])}async function C(a){let b=o();try{let c=await f.promises.stat(t(b,a));return{day:a,exists:!0,mtimeMs:c.mtimeMs,size:c.size}}catch(b){if("ENOENT"===b.code)return{day:a,exists:!1};throw b}}async function D(a){let b,c=o();try{b=await f.promises.readFile(t(c,a),"utf8")}catch(a){if("ENOENT"===a.code)return[];throw a}let d=[],e=0;for(let a of b.split("\n"))if(a.trim())try{let b=(0,i.N5)(JSON.parse(a));b?d.push(b):e+=1}catch{e+=1}return e>0&&m.warn("Ignored invalid statistics records",{day:a,count:e}),d}async function E(a){let b=h().join(a,".installation-key");await f.promises.mkdir(a,{recursive:!0});try{return await f.promises.readFile(b)}catch(a){if("ENOENT"!==a.code)throw a}let c=(0,e.randomBytes)(32);try{return await f.promises.writeFile(b,c,{flag:"wx",mode:384}),c}catch(a){if("EEXIST"===a.code)return f.promises.readFile(b);throw a}}async function F(a){if(!a)return;let b=o(),c=u(b,"statistics-installation-key"),d=q.get(c);d||(d=E(b),q.set(c,d));let f=await d;return`cred_${(0,e.createHmac)("sha256",f).update(a).digest("base64url").slice(0,22)}`}function G(a){let b="object"==typeof a&&null!==a?String(a.code??a.type??""):"",c=a instanceof Error?a.name:"",d=`${b} ${c}`.toLowerCase();return/cancel|abort/.test(d)?"cancelled":/401|authenticat|api_key/.test(d)?"authentication":/403|permission|authoriz/.test(d)?"authorization":/429|rate.?limit/.test(d)?"rate_limit":/context|token.?limit/.test(d)?"context_limit":/timeout/.test(d)?"timeout":/network|fetch|socket|econn/.test(d)?"network":/config|model_not_found/.test(d)?"configuration":/valid|parse|schema/.test(d)?"validation":/provider|api_error/.test(d)?"provider":"unknown"}function H(a){let b=a.toLowerCase();return b.includes("disabled")?"disabled":b.includes("deleted")?"deleted":b.includes("encryption locked")?"encryption_locked":b.includes("queue full")||b.includes("queue cap")?"queue_full":b.includes("exclusive")?"exclusive_lock":b.includes("overlap")||b.includes("previous run")?"overlap":b.includes("pause")?"paused":b.includes("duplicate")?"duplicate":b.includes("ineligible")||b.includes("no longer")?"ineligible":"unknown"}},8677:(a,b,c)=>{"use strict";c.d(b,{AP:()=>m,JG:()=>l});var d=c(21627),e=c(75505),f=c(66844),g=c(62511);let h=(0,f.h)("backend/mcpApps/toolUi");function i(a){return!!a&&"object"==typeof a&&!Array.isArray(a)}async function j(a){try{let b=await d.mcpService.loadServerConfigs();if(!Array.isArray(b))return!1;let c=b.find(b=>b.name===a);return c?.source?.type==="marketplace"&&"@mario.andreschak/mcp-flujo"===c.source.id}catch(b){return h.warn(`Failed to verify FLUJO control server provenance for ${a}`,b),!1}}async function k(a,b,c,f){if(!(0,e.DG)(c))return;let i=(0,e.Gt)(f?._meta);i&&i!==c&&h.warn(`Ignoring MCP App result URI redirect for ${a}/${b}: ${i}`);let j=(0,g.AQ)(f),k={uri:c,serverName:a,toolName:b,...j?{toolOwnerScope:j}:{}};try{return await d.mcpService.isMcpAppAccessEnabled(a)?k:void 0}catch(b){h.warn(`resolveAdvertisedToolUiLink: failed to check MCP Apps opt-in for ${a}`,b);return}}async function l(a,b,c,f,g){if((0,e.DG)(c))return k(a,b,c,f);let l="call_mcp_tool"===b?function(a){if(!i(a))return;let b="string"==typeof a.server?a.server.trim():"",c="string"==typeof a.tool?a.tool.trim():"";if(b&&c)return{serverName:b,toolName:c,toolArgs:i(a.args)?a.args:{}}}(g):void 0;if(l&&await j(a))try{let{tools:a}=await d.mcpService.listServerTools(l.serverName,"model"),b=Array.isArray(a)?a.find(a=>a.name===l.toolName):void 0,c=(0,e.Gt)(b?._meta),g=await k(l.serverName,l.toolName,c,f);return g?{...g,toolArgs:JSON.stringify(l.toolArgs)}:void 0}catch(a){h.warn(`Failed to resolve forwarded MCP App for ${l.serverName}/${l.toolName}`,a);return}}function m(a){if(!a.success&&("cancelled"===a.errorType||"timeout"===a.errorType))return a.error??("timeout"===a.errorType?"Tool execution timed out.":"Tool call was cancelled.")}},10031:(a,b,c)=>{"use strict";c.d(b,{GG:()=>m,MM:()=>t,aC:()=>s,gw:()=>l,hk:()=>p,oV:()=>q,wL:()=>r});var d=c(55511),e=c(68751),f=c(74294),g=c(47570);let h=(0,d.randomUUID)(),i="A tool may have produced an external side effect before execution stopped. Automatic replay is disabled; restart the turn or confirm the effect before retrying.";function j(a){return"number"==typeof a&&Number.isFinite(a)?a:void 0}function k(a){return"string"==typeof a&&a.length>0?a:void 0}function l(a){let b=a&&"object"==typeof a?a:{},c=b.details&&"object"==typeof b.details?b.details:b.errorDetails&&"object"==typeof b.errorDetails?b.errorDetails:b,d=j(c.status)??j(c.statusCode),e=k(c.code)??k(c.type)??k(b.code),f=a instanceof Error?a.message:"string"==typeof a?a:"string"==typeof a?.message?a.message:"string"==typeof a?.error?a.error:"Execution failed.",h=`${e??""} ${f}`.toLowerCase(),i="unknown",l=!1;429===d||/rate.?limit|too many requests/.test(h)?(i="rate_limit",l=!0):/context.{0,12}(limit|length|window)|maximum context/.test(h)?i="context_limit":/input.{0,12}(limit|length|too large)|request.{0,12}too large/.test(h)?i="input_limit":/session.{0,12}(lost|expired|invalid)|thread.{0,12}(lost|expired|not found)/.test(h)?i="session_loss":/empty response|no response content|response was empty/.test(h)?(i="model_empty_response",l=!0):/truncated response|unexpected end|premature end/.test(h)?(i="model_truncated_response",l=!0):/tool/.test(h)?i="tool_failure":408===d||502===d||503===d||504===d||/timeout|timed out|econnreset|econnrefused|socket|network|fetch failed|connection closed/.test(h)?(i="transport_failure",l=!0):(void 0!==d||/provider|model|api/.test(h))&&(i="provider_failure",l=void 0===d||d>=500);let m=j(c.retryAfterMs)??(0,g.oR)(c.retryAfter);return{classification:l?"retryable_failure":"permanent_failure",failure:{category:i,message:f,code:e,status:d,retryable:l},retryAfterAt:void 0!==m?Date.now()+Math.max(0,m):void 0}}function m(a,b){let c=Date.now(),e=a.recovery;if(e?.runId===b)return e.classification="running",e.ownerId=h,e.ownerHeartbeatAt=c,e.updatedAt=c,e.terminalAt=void 0,e.failure=void 0,e.retryAfterAt=void 0,e.manualActionRequired=!1,e.sideEffectWarning=void 0,a.recovery=e,e;let f={version:1,runId:b,attemptId:(0,d.randomUUID)(),attempt:1,classification:"running",parentRunId:a.parentRunId,ownerId:h,ownerHeartbeatAt:c,startedAt:c,updatedAt:c};return a.recovery=f,f}function n(a,b){let c=(a.messages??[]).slice(-8).map(a=>({id:a.id,role:a.role,content:a.content,toolCalls:a.tool_calls,toolCallId:a.tool_call_id}));return(0,d.createHash)("sha256").update(JSON.stringify({flowId:a.flowId,nodeId:b,messages:c})).digest("hex")}async function o(a,b,c,d){d?(d(c),b.conversationId&&!b.ephemeral&&await (0,e.flushConversationLog)(b.conversationId)):await (0,e.appendRawForState)(b,[c]),await (0,f.persistConversationState)(a,b)}async function p(a,b,c,e){if(b.ephemeral)return;let f=b.recovery??m(b,b.logicalRunId??(0,d.randomUUID)()),g=Date.now(),j={id:(0,d.randomUUID)(),phase:c.phase,nodeId:c.nodeId,turnEntryNodeId:c.turnEntryNodeId??f.lastSafeCheckpoint?.turnEntryNodeId??c.nodeId,attempt:f.attempt,inputFingerprint:n(b,c.nodeId),safe:c.safe,effectStatus:c.effectStatus??"none",parentRunId:b.parentRunId,lane:f.lane,tools:c.tools,createdAt:g};return f.currentCheckpoint=j,j.safe&&(f.lastSafeCheckpoint=j),f.ownerId=h,f.ownerHeartbeatAt=g,f.updatedAt=g,j.safe||"unknown"!==j.effectStatus||(f.manualActionRequired=!0,f.sideEffectWarning=i),b.recovery=f,await o(a,b,{type:"recovery:checkpoint",checkpoint:j},e),j}async function q(a,b,c,d,e){let f=c.map(a=>{let c=b.toolNameMap?.[a.function.name],d=c?.annotations,e=d?.readOnlyHint===!0;return{toolCallId:a.id,name:a.function.name,readOnly:e,idempotent:e||d?.idempotentHint===!0,destructive:d?.destructiveHint}});f.some(a=>!a.readOnly)&&await p(a,b,{phase:"before"===d?"tool:before":"completed"===d?"tool:after":"tool:unknown",nodeId:b.currentNodeId,safe:"completed"===d,effectStatus:"before"===d?"pending":"completed"===d?"completed":"unknown",tools:f},e)}async function r(a,b,c,e={},f){let g=function(a,b,c={}){let e=a.recovery??m(a,a.logicalRunId??(0,d.randomUUID)()),f=Date.now();return e.classification=b,e.failure=c.failure,e.retryAfterAt=c.retryAfterAt,e.cancellationRequestedAt=c.cancellationRequestedAt??e.cancellationRequestedAt,e.manualActionRequired=c.manualActionRequired??e.manualActionRequired,e.sideEffectWarning=c.sideEffectWarning??e.sideEffectWarning,e.updatedAt=f,e.ownerHeartbeatAt=f,"running"!==b&&"paused"!==b&&(e.terminalAt=f),a.recovery=e,e}(b,c,e);return await o(a,b,{type:"recovery:transition",recovery:{...g}},f),g}async function s(a,b){let c=b.recovery;return"running"===b.status&&!!c?.ownerId&&c.ownerId!==h&&(b.status="error",b.isCancelled=!1,b.lastResponse={success:!1,error:"Execution was interrupted before it reached a terminal boundary."},await r(a,b,"interrupted",{failure:{category:"unclean_process_interruption",message:"The process that owned this run is no longer active.",retryable:!1},manualActionRequired:!0}),!0)}function t(a,b="interrupted"){let c=a.recovery??m(a,a.logicalRunId??(0,d.randomUUID)()),e=Date.now(),f={id:(0,d.randomUUID)(),phase:"tool:unknown",nodeId:a.currentNodeId,turnEntryNodeId:c.lastSafeCheckpoint?.turnEntryNodeId,attempt:c.attempt,inputFingerprint:n(a,a.currentNodeId),safe:!1,effectStatus:"unknown",parentRunId:a.parentRunId,lane:c.lane,createdAt:e};c.currentCheckpoint=f,c.classification=b,c.failure={category:"tool_failure",message:"A dangling tool call was repaired after interruption; its external effect is unknown.",retryable:!1},c.manualActionRequired=!0,c.sideEffectWarning=i,c.updatedAt=e,c.terminalAt="interrupted"===b?e:void 0,a.recovery=c}},10408:(a,b,c)=>{"use strict";c.d(b,{$X:()=>u,CW:()=>t,KO:()=>q,Mw:()=>x,lp:()=>v});var d=c(33873),e=c.n(d),f=c(29021),g=c(66844),h=c(7986),i=c(65445),j=c(20149),k=c(53506),l=c(1230);let m=(0,g.h)("backend/execution/flow/conversationSummaryStore");function n(){return e().join((0,h.getWorkspaceDataDir)(),"db","conversations")}function o(){return e().join((0,h.getWorkspaceDataDir)(),"db","conversation-summaries")}function p(a){return e().join(o(),`${a}.json`)}function q(a,b="Untitled Conversation"){if(!("schedule"===a.source||!a.source&&a.plannedExecutionId&&!a.parentConversationId))return a.title||b;if("completed"===a.status||"capped"===a.status){let b="string"==typeof a.lastResponse&&a.lastResponse.trim()?a.lastResponse:function(a){for(let b=a.messages.length-1;b>=0;b-=1){let c=a.messages[b];if("assistant"===c.role&&"string"==typeof c.content&&c.content.trim())return c.content}}(a);if(b)return(0,l.oO)(b)}let c=a.statisticsPlannedExecutionName?.trim();return c?(0,l.oO)(c):"Automation run"}function r(a,b){let c;return{id:a.conversationId||b,title:q(a),flowId:a.flowId||null,...a.status?{status:a.status}:{},createdAt:a.createdAt||0,updatedAt:a.updatedAt||0,...void 0!==a.lastUserMessageAt?{lastUserMessageAt:a.lastUserMessageAt}:{},...void 0!==a.plannedExecutionId?{plannedExecutionId:a.plannedExecutionId}:{},...void 0!==a.parentConversationId?{parentConversationId:a.parentConversationId}:{},...void 0!==a.rootConversationId?{rootConversationId:a.rootConversationId}:{},...a.subflowLane?.sessionKey?{sessionKey:a.subflowLane.sessionKey}:{},...a.subflowLane?.sessionIdentity?{sessionIdentity:a.subflowLane.sessionIdentity}:{},...a.recovery?{recovery:a.recovery}:{},...void 0!==a.source?{source:a.source}:{},...(0,k.g)(a)?{personaOwned:!0}:{},...a.personaArchived?{personaArchived:!0}:{},...a.personaAttribution?.personaId??a.personaTargetId?{personaId:a.personaAttribution?.personaId??a.personaTargetId}:{},...(a.personaAttribution?.personaId??a.personaTargetId)&&a.personaBehaviorSlotKey?{personaBehaviorSlotKey:a.personaBehaviorSlotKey}:{},...a.personaAttribution?.activityId?{activityId:a.personaAttribution.activityId}:{},...a.personaAttribution?.behaviorRevisionId?{behaviorRevisionId:a.personaAttribution.behaviorRevisionId}:{},..."error"===a.status&&(c=a.lastError??(0,j.Jj)(a.lastResponse))?{lastError:{message:c.message,...c.code?{code:c.code}:{},...c.errorClass?{errorClass:c.errorClass}:{}}}:{}}}async function s(a,b,c){if((0,i.ln)(a),b.personaAttribution&&!b.executionAuthority)throw Error("Persona-attributed conversation summaries require current execution authority.");let d=async()=>{let d=c??await f.promises.stat(e().join(n(),`${a}.json`)),g={version:9,...r(b,a),snapshotMtimeMs:d.mtimeMs,snapshotSize:d.size};await (0,i.l_)(`conversation-summaries/${a}`,()=>(0,i.Zf)(p(a),JSON.stringify(g,null,2)))};b.executionAuthority?.commitWhileCurrent?await b.executionAuthority.commitWhileCurrent(d):(await b.executionAuthority?.assertCurrent(),await d())}async function t(a,b){try{await s(a,b)}catch(b){m.warn(`Could not refresh conversation summary ${a}; it will be rebuilt on list.`,b)}}async function u(a,b){await s(a,b)}async function v(a){try{(0,i.ln)(a),await (0,i.l_)(`conversation-summaries/${a}`,async()=>{try{await f.promises.unlink(p(a))}catch(a){if("ENOENT"!==a.code)throw a}})}catch(b){m.warn(`Could not delete conversation summary ${a}.`,b)}}async function w(){let a;try{a=await f.promises.readdir(o())}catch(a){if("ENOENT"===a.code)return new Map;throw a}let b=new Map,c=0,d=async()=>{for(;;){let d=a[c++];if(!d)return;if(!(!d.endsWith(".json")||d.includes(".tmp.")||d.includes(".corrupted.")))try{let a=JSON.parse(await f.promises.readFile(e().join(o(),d),"utf8")),c=d.replace(/\.json$/,"");(0,i.ln)(c),9===a.version&&"string"==typeof a.id&&b.set(c,a)}catch(a){m.warn(`Skipping unreadable conversation summary ${d}; it will be rebuilt if needed.`,a)}}};return await Promise.all(Array.from({length:Math.min(32,Math.max(1,a.length))},()=>d())),b}async function x(){let a;try{a=(await f.promises.readdir(n())).filter(a=>a.endsWith(".json"))}catch(a){if("ENOENT"===a.code)return[];throw a}let b=await w(),c=Array(a.length).fill(null),d=0,g=async()=>{for(;;){let g=d++;if(g>=a.length)return;let h=a[g],j=h.replace(/\.json$/,"");try{(0,i.ln)(j);let a=e().join(n(),h),d=await f.promises.stat(a),k=b.get(j);if(k&&k.snapshotMtimeMs===d.mtimeMs&&k.snapshotSize===d.size){c[g]=function(a){let{version:b,snapshotMtimeMs:c,snapshotSize:d,...e}=a;return e}(k);continue}let l=JSON.parse(await f.promises.readFile(a,"utf8"));c[g]=r(l,j),await s(j,l,d)}catch(a){m.warn(`Skipping unreadable conversation snapshot ${h}.`,a)}}};return await Promise.all(Array.from({length:Math.min(32,Math.max(1,a.length))},()=>g())),c.filter(a=>null!==a)}},10837:(a,b,c)=>{"use strict";c.d(b,{E5:()=>j,Jp:()=>g,M6:()=>e,Ne:()=>d,O:()=>i,V8:()=>k,g4:()=>h,xg:()=>f});let d=["chat","api","schedule","trigger","subflow","mcp","internal","meeting"];function e(a){return"string"==typeof a&&d.includes(a)}function f(a){return"chat"!==a&&"api"!==a}let g="TOOL_CALL",h="FINAL_RESPONSE",i="ERROR",j="STAY_ON_NODE",k="IMPLICIT_SUBFLOW_RETURN"},12969:(a,b,c)=>{"use strict";c.d(b,{A:()=>d});let d=8},14671:(a,b,c)=>{"use strict";c.d(b,{Av:()=>g,By:()=>d,E9:()=>f,gP:()=>h});let d="call_subflow_";function e(a,b){let c=new Set,d=new Map;for(let e of a){if(d.has(e.id))continue;let a=function(a,b){let c=(a&&a.trim()||b&&b.trim()||"node").toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/_+/g,"_").replace(/^_+|_+$/g,"");return c.length>48&&(c=c.slice(0,48).replace(/_+$/g,"")),c||(c=b&&b.trim().toLowerCase().replace(/[^a-z0-9]+/g,"_")||"node"),c||"node"}(e.label,e.type),f=`${b}${a}`;if(c.has(f)){let d=2;for(;c.has(`${b}${a}_${d}`);)d++;f=`${b}${a}_${d}`}c.add(f),d.set(e.id,f)}return d}function f(a){return e(a,"handoff_to_")}function g(a){return e(a,d)}function h(a){return a.startsWith(d)}},17350:(a,b,c)=>{"use strict";c.d(b,{B1:()=>n,J2:()=>m,JM:()=>k,W5:()=>j,ll:()=>o,pb:()=>l});var d=c(66844),e=c(58253),f=c(47798),g=c(77823),h=c(49233);let i=(0,d.h)("backend/flow/execution/handlers/runResourceTools"),j="write_resource",k="read_resource";function l(a){return a===j||a===k}function m(){return{name:k,description:"Read resource content by URI or file path. Supports stored flujo://run/... resources, native MCP URIs, and paths readable by a bound filesystem MCP. Use list_mcp_resources to find native URIs. Large or binary resources may return a flujo://run/... URI.",inputSchema:{type:"object",properties:{uri:{type:"string",description:"A flujo://run/... URI, native MCP URI, file:// URI, or filesystem path."},max_chars:{type:"integer",minimum:1,maximum:2e5,description:"Optional bounded text limit. Visual archives default to 50,000 characters."},expected_sha256:{type:"string",pattern:"^[a-fA-F0-9]{64}$",description:"Optional SHA-256 to verify against the immutable stored payload."}},required:["uri"]}}}function n(a){let b=(a??[]).filter(a=>"produce"===a.role&&a.properties?.scope==="run"&&!!a.properties?.runName?.trim());if(0===b.length)return[];let c=Array.from(new Set(b.map(a=>a.properties.runName.trim()))),d=c.map(a=>`"${a}"`).join(", ");return[{name:j,description:`Produce/update a run artifact — a named data output of this flow run that later steps can read via \${res:NAME} and that appears in the run-data panel. Write the artifact's FULL content here rather than only describing it in your reply. This step is wired to produce: ${d}. Writing the same name again replaces the previous content (last write wins).`,inputSchema:{type:"object",properties:{name:{type:"string",description:`The artifact name to write. Use one of: ${c.join(", ")}.`},content:{type:"string",description:"The full content of the artifact (text/markdown)."}},required:["name","content"]}}]}async function o(a,b,c){if(a===k)return p(b,c);if(a!==j)return{success:!1,error:`Unknown run-resource tool: ${a}`};if(!c.conversationId||c.ephemeral)return{success:!1,error:"Run artifacts are not available in this run."};let d="string"==typeof b?.name?b.name.trim():"";if(!d)return{success:!1,error:'write_resource requires a non-empty "name".'};let g="string"==typeof b?.content?b.content:"";try{return await (0,e.Gi)(c,async()=>{let a=await (0,f.tm)({conversationId:c.conversationId,name:d,mimeType:"text/markdown",kind:"text",data:{text:g},producedBy:{source:"capture",nodeId:c.node?.nodeId,nodeName:c.node?.nodeName}});return"skipped"in a?(i.warn("write_resource skipped by store cap",{name:d,reason:a.skipped}),{success:!1,error:`Artifact not stored (${a.skipped}).`}):(c.emit?.({type:"resource:write",node:c.node,server:"flujo",uri:a.uri,name:d,mimeType:a.mimeType,size:a.size,source:"capture"}),i.info("write_resource stored run artifact",{name:d,uri:a.uri,size:a.size}),{success:!0,data:{written:!0,name:d,uri:a.uri,size:a.size}})})}catch(a){return(0,e.Vj)(a),i.error("write_resource failed",a),{success:!1,error:a instanceof Error?a.message:String(a)}}}async function p(a,b){let c="string"==typeof a?.uri?a.uri.trim():"";if(!c)return{success:!1,error:'read_resource requires a non-empty "uri".'};let d=(0,f.Ns)(c);if(!d)return c.startsWith(g.j0)?{success:!1,error:`Invalid run-resource URI: ${c}`}:b.mcpNodes&&b.mcpNodes.length>0?(0,h.Nl)(c,{conversationId:b.conversationId,nodeId:b.node?.nodeId,ephemeral:b.ephemeral,mcpNodes:b.mcpNodes,emit:b.emit,node:b.node,executionAuthority:b.executionAuthority,personaAttribution:b.personaAttribution}):{success:!1,error:`Not a run-resource URI: ${c}`};if(b.conversationId&&d.conversationId!==b.conversationId)return{success:!1,error:`Run resource ${c} is not part of this run.`};try{return await (0,e.Gi)(b,async()=>{let d="number"==typeof a?.max_chars&&Number.isFinite(a.max_chars)?Math.floor(a.max_chars):void 0,e="string"==typeof a?.expected_sha256?a.expected_sha256.trim():void 0,g={at:Date.now(),source:"tool-read",nodeId:b.node?.nodeId},h=void 0!==d||e?await (0,f.fg)(c,{maxChars:d,expectedSha256:e,access:g}):null,j=h?null:await (0,f.gy)(c,g);if(!h&&!j)return{success:!1,error:`Run resource not found: ${c}`};let k=h?.entry??j.entry,l=j?.contents;b.emit?.({type:"resource:read",node:b.node,server:"flujo",uri:k.uri,name:k.name,mimeType:k.mimeType,size:k.size,source:"tool-read"});let m=(l?.contents??[]).map(a=>"string"==typeof a.text?a.text:"").filter(a=>a.length>0),n=h?.content??(m.length>0?m.join("\n"):`[binary run resource ${k.mimeType??k.kind} (${k.size} bytes) at ${k.uri}]`),o="text"!==k.kind&&"link"!==k.kind?await (0,f.QT)(k.uri):null;return i.info("read_resource served run resource",{uri:k.uri,size:k.size}),{success:!0,data:{uri:k.uri,name:k.name,mimeType:k.mimeType,content:n,truncated:h?.truncated??!1,sha256:k.sha256,verification:h?.verification,...o?{localPath:o}:{}}}})}catch(a){return(0,e.Vj)(a),i.error("read_resource failed",a),{success:!1,error:a instanceof Error?a.message:String(a)}}}},17943:(a,b,c)=>{"use strict";c.d(b,{ND:()=>m,PL:()=>i,bS:()=>j,dd:()=>f,p:()=>g,p$:()=>d,xB:()=>l});let d=128,e=/\{\{[^{}]+\}\}|\$\{[^{}]+\}|@\{[^{}]+\}/;function f(a){if(null==a)return;let b=String(a).trim();if(!(!b||b.length>d||e.test(b)))return b}function g(a){if(null==a||""===a)return;let b="number"==typeof a?a:Number(a);return Number.isSafeInteger(b)&&b>0?b:void 0}let h=new Map;async function i(a){let b,c=h.get(a);c||(c={tail:Promise.resolve(),claims:0},h.set(a,c));let d=c.tail;c.tail=new Promise(a=>{b=a}),c.claims+=1,await d;let e=!1;return()=>{e||(e=!0,c.claims-=1,b(),0===c.claims&&h.get(a)===c&&h.delete(a))}}function j(a,b,c,d){if(!a||!b||!c||"per-visit"===c)return;if("per-run"===c)return`${a}::${b}::`;let e=f(d);if("per-key"===c&&e)return`${a}::${b}::${encodeURIComponent(e)}`}function k(a){return(Number.isFinite(a.visits)?Math.max(0,Math.floor(a.visits)):0)+1}function l(a,b,c,d){if(!b||!a)return{conversationId:crypto.randomUUID?crypto.randomUUID():n(),resumedVisit:!1};let e=a.subflowSessions?.[b];if(e&&e.conversationId)return e.lastUsedAt=Date.now(),e.status="running",{conversationId:e.conversationId,resumedVisit:!0,sessionVisit:k(e)};let g=crypto.randomUUID?crypto.randomUUID():n();return a.subflowSessions||(a.subflowSessions={}),a.subflowSessions[b]={version:1,conversationId:g,nodeId:c,sessionKey:f(d),visits:0,lastUsedAt:Date.now(),status:"running"},{conversationId:g,resumedVisit:!1,sessionVisit:k(a.subflowSessions[b])}}function m(a,b,c){if(!b||!a)return;let d=a.subflowSessions?.[b];d&&(d.visits+=1,d.lastUsedAt=Date.now(),d.status="completed"===c?"idle":"error"===c?"failed":"idle")}function n(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){let b=16*Math.random()|0;return("x"===a?b:3&b|8).toString(16)})}},18126:(a,b,c)=>{"use strict";function d(...a){let b=a.filter(a=>!!a);if(0===b.length)return;if(1===b.length)return b[0];let c=AbortSignal.any;if("function"==typeof c)return c(b);let e=new AbortController,f=b.find(a=>a.aborted);if(f)return e.abort(f.reason),e.signal;for(let a of b)a.addEventListener("abort",()=>e.abort(a.reason),{once:!0});return e.signal}c.d(b,{N:()=>d})},19031:(a,b,c)=>{"use strict";c.d(b,{E0:()=>t,J1:()=>m,Sy:()=>l,eK:()=>s,m7:()=>r});var d=c(77598),e=c(73024),f=c(48161),g=c.n(f),h=c(76760),i=c.n(h),j=c(18477),k=c(7986);let l="flujo-auth-source.json",m={version:1,source:"workspace"};function n(){return process.env.CODEX_HOME?.trim()||i().join(g().homedir(),".codex")}async function o(a){let b,c=i().join(a,"config.toml"),d=!1;try{let a=await e.promises.lstat(c);d=!0;let f=a.isSymbolicLink()?await e.promises.stat(c):a;if(!f.isFile()||f.size>1048576)throw Error();let g=await e.promises.readFile(c),h=await e.promises.stat(c);if(g.length>1048576||g.length!==f.size||f.ino!==h.ino||f.size!==h.size||f.mtimeMs!==h.mtimeMs)throw Error();b=(0,j.qg)(new TextDecoder("utf-8",{fatal:!0}).decode(g))}catch(a){if(!d&&"ENOENT"===a.code)return;throw Error("Could not verify the host Codex credential store. Repair or make its config.toml readable before using its login in FLUJO.")}let f=b.cli_auth_credentials_store;if(void 0!==f&&"file"!==f)throw Error('FLUJO requires file-backed Codex authentication. Configure cli_auth_credentials_store = "file" and sign in again; keyring and auto storage cannot identify the active login from auth.json.')}async function p(a){try{let b=JSON.parse(await e.promises.readFile(i().join(a,l),"utf8"));if(b?.version!==1||!["host","workspace"].includes(b.source))throw Error("Invalid FLUJO Codex authentication source.");return b}catch(a){if("ENOENT"===a.code)return;throw Error("Could not read FLUJO Codex authentication source.")}}async function q(a,b){let c=`${a}.${(0,d.randomUUID)()}.tmp`;try{await e.promises.writeFile(c,b,{mode:384,flag:"wx"}),await e.promises.rename(c,a),await e.promises.chmod(a,384)}finally{await e.promises.rm(c,{force:!0})}}async function r(a){let b,c=await p(a),f=i().join(a,"auth.json");if(c?.source==="workspace")return void await e.promises.access(f).catch(()=>{throw Error("The worker Codex login is missing. Sign in using its CODEX_HOME.")});let g=n();await o(g);let h=i().join(g,"auth.json");if(i().resolve(h)===i().resolve(f))return;try{b=await e.promises.readFile(h)}catch(b){if("ENOENT"!==b.code)throw Error("Could not read the host Codex login.");await e.promises.rm(f,{force:!0}),await e.promises.rm(i().join(a,l),{force:!0});return}let j=(0,d.createHash)("sha256").update(b).digest("hex"),k=await e.promises.access(f).then(()=>!0,()=>!1);c?.sourceHash===j&&k||(await q(f,b),await q(i().join(a,l),JSON.stringify({version:1,source:"host",sourceHash:j})))}function s(a){try{let b=JSON.parse(a.toString("utf8"));return(!b.auth_mode||"chatgpt"===b.auth_mode)&&!b.OPENAI_API_KEY&&"string"==typeof b.tokens?.access_token&&b.tokens.access_token.length>0&&"string"==typeof b.tokens?.refresh_token&&b.tokens.refresh_token.length>0}catch{return!1}}async function t(a){let b,c=i().join((0,k.getWorkspaceDataDir)(a),"db","codex-runtime"),f=await p(c),g=f?.source==="workspace"?c:n();f?.source!=="workspace"&&await o(g);let h=i().join(g,"auth.json");if(f?.source==="host"&&f.sourceHash){let a=await e.promises.readFile(h).catch(()=>void 0);if(a&&(0,d.createHash)("sha256").update(a).digest("hex")===f.sourceHash){let a=i().join(c,"auth.json");await e.promises.access(a).then(()=>!0,()=>!1)&&(h=a)}}try{let a=await e.promises.lstat(h);if(!a.isFile()||a.isSymbolicLink()||a.size>1048576)throw Error();b=await e.promises.readFile(h);let c=await e.promises.lstat(h);if(a.ino!==c.ino||a.size!==c.size||a.mtimeMs!==c.mtimeMs)throw Error()}catch{throw Error("A file-backed Codex ChatGPT login is required. Sign in with Codex using file credential storage before cloning.")}if(!s(b))throw Error("The Codex authentication cache is not a transferable ChatGPT login.");return b}},20149:(a,b,c)=>{"use strict";c.d(b,{G1:()=>m,Jj:()=>k,NS:()=>l,g9:()=>j});var d=c(8619);let e=/^(authorization|api[-_]?key|x-api-key|cookie|set-cookie|proxy-authorization|www-authenticate)$/i,f=/sk-[A-Za-z0-9_-]{8,}/g,g=/bearer\s+[A-Za-z0-9._.~+/=-]{8,}/gi;function h(a){return"string"==typeof a&&a.length>0?a:void 0}function i(a){return"number"==typeof a&&Number.isFinite(a)?a:void 0}function j(a,b){let c,j=a&&"object"==typeof a&&a.details&&"object"==typeof a.details?a.details:void 0;c=a instanceof Error?a.message||"An unknown error occurred.":"string"==typeof a&&a.length>0?a:a&&"object"==typeof a&&h(a.message)?a.message:null==a?"An unknown error occurred.":String(a);let k=h(j?.code)??(a&&"object"==typeof a?h(a.code):void 0),l=i(j?.status)??(a&&"object"==typeof a?i(a.status):void 0),m=h(j?.type)??(a instanceof Error?h(a.name):void 0),n=h(j?.retryAfter),o=j?.providerError!==void 0?function(a){let b;if(null==a)return;let c=function a(b,c){if(c>6)return"[REDACTED: max depth exceeded]";if("string"==typeof b)return b.replace(g,"Bearer [REDACTED]").replace(f,"[REDACTED]");if(Array.isArray(b))return b.map(b=>a(b,c+1));if(b&&"object"==typeof b){let d={};for(let[f,g]of Object.entries(b))d[f]=e.test(f)?"[REDACTED]":a(g,c+1);return d}return b}(a,0);try{b=JSON.stringify(c)??""}catch{return{note:"[REDACTED: unserializable provider error body]"}}if(b)return b.length>8192?{note:"[REDACTED: provider error body truncated]",truncated:b.slice(0,8192)}:c&&"object"==typeof c&&!Array.isArray(c)?c:{value:c}}(j.providerError):void 0;return{message:c,...k?{code:k}:{},...void 0!==l?{httpStatus:l}:{},...m?{providerType:m}:{},errorClass:(0,d.Ys)(a instanceof Error?Object.assign(Error(a.message),{name:a.name,code:k,type:m}):{code:k,type:m}),...b?.nodeId?{nodeId:b.nodeId}:{},...b?.nodeName?{nodeName:b.nodeName}:{},...n?{retryAfter:n}:{},occurredAt:Date.now(),...o?{details:o}:{}}}function k(a){if(null!=a){if("string"==typeof a)return a.length>0?j(Error(a)):void 0;if("object"==typeof a&&!1===a.success){let b=h(a.error)??"An unknown error occurred.",c=a.errorDetails&&"object"==typeof a.errorDetails?a.errorDetails:void 0;return j(Object.assign(Error(b),c?{details:c}:{}))}}}function l(a,b,c,d){return a.errorEventEmitted?a.lastError:m(a,b,j(c,d),d)}function m(a,b,c,d){return a.errorEventEmitted?a.lastError??c:(a.errorEventEmitted=!0,a.lastError=c,b?.({type:"error",node:d?.nodeId?{nodeId:d.nodeId}:void 0,message:c.message,error:c}),c)}},20228:(a,b,c)=>{"use strict";c.d(b,{Mv:()=>m,RZ:()=>j,Wg:()=>l,wC:()=>k});var d=c(66844),e=c(7986);let f=(0,d.h)("backend/services/questionRegistry"),g=globalThis,h=g.__flujoQuestionRegistry??(g.__flujoQuestionRegistry=new Map);function i(a,b){return(0,e.workspaceCacheKey)(a,b)}function j(a,b,c,d=3e5){let g=i(a,b);return new Promise(i=>{let j=setTimeout(()=>{h.has(g)&&(f.warn(`Question ${b} (conv ${a}) timed out after ${d}ms`),h.delete(g),i({action:"timeout"}))},d);h.set(g,{workspace:(0,e.getCurrentWorkspace)(),conversationId:a,questionId:b,questions:c,createdAt:Date.now(),resolve:i,timer:j})})}function k(a,b,c){let d=i(a,b),e=h.get(d);return!!e&&(clearTimeout(e.timer),h.delete(d),e.resolve({action:"answer",answers:c}),!0)}function l(a,b){let c=i(a,b),d=h.get(c);return!!d&&(clearTimeout(d.timer),h.delete(c),d.resolve({action:"decline"}),!0)}function m(){let a=(0,e.getCurrentWorkspace)();return Array.from(h.values()).filter(b=>b.workspace===a).map(a=>({conversationId:a.conversationId,questionId:a.questionId,questions:a.questions,createdAt:a.createdAt}))}},20593:(a,b,c)=>{"use strict";c.d(b,{ToolHandler:()=>l});var d=c(66844),e=c(63342),f=c(21627),g=c(65385),h=c(49233),i=c(75505),j=c(88022);let k=(0,d.h)("backend/flow/execution/handlers/ToolHandler");class l{static sanitizeSchema(a){if(!a||"object"!=typeof a||Array.isArray(a))return{};let b=JSON.parse(JSON.stringify(a));if("string"===b.type&&b.format&&"enum"!==b.format&&"date-time"!==b.format&&(b.description||(b.description=""),b.description+=` (format: ${b.format})`,delete b.format),b.properties){let a=b.properties;Object.keys(a).forEach(b=>{a[b]=l.sanitizeSchema(a[b])})}if(Array.isArray(b.required))if(b.properties){let a=new Set(Object.keys(b.properties));b.required=b.required.filter(b=>"string"==typeof b&&a.has(b)),0===b.required.length&&delete b.required}else delete b.required;return b.items&&(b.items=l.sanitizeSchema(b.items)),Array.isArray(b.oneOf)&&(b.oneOf=b.oneOf.map(a=>l.sanitizeSchema(a))),Array.isArray(b.anyOf)&&(b.anyOf=b.anyOf.map(a=>l.sanitizeSchema(a))),Array.isArray(b.allOf)&&(b.allOf=b.allOf.map(a=>l.sanitizeSchema(a))),b}static prepareTools(a){let{availableTools:b}=a;if(k.verbose("prepareTools input",JSON.stringify(a)),!b||0===b.length){let a={success:!0,value:{tools:[]}};return k.verbose("prepareTools empty result",JSON.stringify(a)),a}try{for(let a of b){if(!a.name)return{success:!1,error:(0,e.Po)("invalid_tool","Tool missing required 'name' property","unknown")};if(!a.inputSchema)return{success:!1,error:(0,e.Po)("invalid_tool",`Tool '${a.name}' missing required 'inputSchema' property`,a.name)}}let a=[...b].sort((a,b)=>a.name<b.name?-1:+(a.name>b.name)).map(a=>({type:"function",function:{name:a.name,description:a.description||`Tool: ${a.name}`,parameters:l.sanitizeSchema(a.inputSchema)}})),c={success:!0,value:{tools:a}};return k.verbose("prepareTools success result",JSON.stringify(c)),c}catch(b){let a={success:!1,error:(0,e.Po)("tool_preparation_failed",b instanceof Error?b.message:String(b),"unknown")};return k.verbose("prepareTools error result",JSON.stringify(a)),a}}static async processMCPNodes(a){let{mcpNodes:b}=a;if(k.verbose("processMCPNodes input",JSON.stringify(a)),!b||0===b.length){let a={success:!0,value:{availableTools:[]}};return k.verbose("processMCPNodes empty result",JSON.stringify(a)),a}try{let a=[],c=[];try{let a=await f.mcpService.loadServerConfigs?.();c=Array.isArray(a)?a:[]}catch(a){k.warn("Could not load server-wide tool parameter presets",a)}for(let d of b){let b=d.properties;if(b&&b.boundServer){let h=b.boundServer,k=b.enabledTools||[],l=b.toolTimeout,m=c.find(a=>a.name===h);f.mcpService.setNodeRoots(h,d.id,b.roots);let n=await f.mcpService.connectServer(h);if(!n.success)return{success:!1,error:(0,e.Fp)("server_connection_failed",`Failed to connect to MCP server '${h}': ${n.error}`,h,"connect")};let o=await f.mcpService.listServerTools(h);if(o.error)return{success:!1,error:(0,e.Fp)("list_tools_failed",`Failed to list tools for MCP server '${h}': ${o.error}`,h,"listTools")};for(let c of(o.tools||[]).filter(a=>k.includes(a.name)).map(a=>{let c=(0,j.Ge)(m?.toolParameterPresets,b.toolParameterPresets,a.name),e=(0,g.az)(a.inputSchema);return f.mcpService.setToolSchemaHash(h,a.name,e),{originalName:a.name,server:h,nodeId:d.id,name:(0,g.Y6)(h,a.name),timeout:l,description:a.description,inputSchema:(0,j.Qm)(a.inputSchema,c),...Object.keys(c).length>0?{presetArgs:c}:{},annotations:a.annotations,clientGeneration:f.mcpService.getClientGeneration(h),schemaHash:e,uiResourceUri:(0,i.Gt)(a._meta)}}))a.some(a=>a.name===c.name)||a.push(c)}}try{for(let c of(await (0,h.QH)(b)))a.some(a=>a.name===c.name)||a.push(c)}catch(a){k.warn("processMCPNodes: buildMCPResourceTools failed, skipping resource tool",{resourceErr:a})}let d={success:!0,value:{availableTools:a}};return k.verbose("processMCPNodes success result",JSON.stringify(d)),d}catch(b){let a={success:!1,error:(0,e.Fp)("mcp_processing_failed",b instanceof Error?b.message:String(b),"unknown","processMCPNodes")};return k.verbose("processMCPNodes error result",JSON.stringify(a)),a}}}},20616:(a,b,c)=>{"use strict";c.d(b,{l:()=>d});let d=18e6},21627:(a,b,c)=>{"use strict";c.r(b),c.d(b,{MCPService:()=>bT,mcpService:()=>bU});var d=c(78796),e=c(79748),f=c.n(e),g=c(33873),h=c.n(g),i=c(66844),j=c(7986),k=c(74164),l=c(94247),m=c(80244);let n=(0,i.h)("backend/services/mcp/lifecycleCoordinator");function o(){return global.__flujo_mcp_lifecycle||(global.__flujo_mcp_lifecycle=new Map),global.__flujo_mcp_lifecycle}function p(a,b=(0,j.getCurrentWorkspace)()){return`${b}\0${a}`}function q(a){let b=(0,j.getCurrentWorkspace)(),c=p(a,b),d=o().get(c);return d||(d={key:c,workspace:b,serverName:a,state:"cold",generation:0,retryAttempts:0,connectFailures:0,handshakeFailures:0,forcedKills:0,leases:0,pins:new Set,lastUsedAt:Date.now()},o().set(c,d)),d}function r(a){return o().get(p(a))}function s(){let a=(0,j.getCurrentWorkspace)();return Array.from(o().values()).filter(b=>b.workspace===a)}async function t(a,b){let c=q(a);c.teardownPromise&&await c.teardownPromise.catch(()=>void 0);let d=c.connectPromise;if(d)return n.debug(`beginConnect: reusing in-flight attempt for ${a}`),d;c.state="warm"===c.state?"warm":"starting";let e=(async()=>b(c))().finally(()=>{c.connectPromise===e&&(c.connectPromise=void 0)});return c.connectPromise=e,e}let u=(0,i.h)("backend/services/mcp/mcpLeasePool");function v(){let a=Number(process.env.FLUJO_MCP_IDLE_TTL_MS);return Number.isFinite(a)&&a>0?a:6e5}function w(){let a=Number(process.env.FLUJO_MCP_MAX_WARM_SERVERS);return Number.isFinite(a)&&a>0?Math.floor(a):8}function x(){let a=()=>({acquires:0,coalesced:0,connects:0,failures:0,idleClosures:0,lruEvictions:0}),b=(0,j.getCurrentWorkspace)();if(b===j.DEFAULT_WORKSPACE)return global.__flujo_mcp_pool_counters||(global.__flujo_mcp_pool_counters=a()),global.__flujo_mcp_pool_counters;let c=global.__flujo_mcp_pool_counters_by_workspace??=new Map,d=c.get(b);return d||(d=a(),c.set(b,d)),d}function y(a,b,c){let d,e=!1;return d=q(a),d.leases+=1,d.lastUsedAt=Date.now(),{serverName:a,generation:c,client:b,isStale(){let b=r(a);return!b||b.generation!==c},release(){if(!e){let b;e=!0,(b=q(a)).leases=Math.max(0,b.leases-1),b.lastUsedAt=Date.now()}}}}async function z(a,b){if(x().acquires+=1,await a.isServerDisabled(b))return{success:!1,error:`Server '${b}' is disabled. Enable it on the MCP page to use it.`};let c=a.getClient(b);if(c){x().coalesced+=1;let a=q(b);return{success:!0,lease:y(b,c,a.generation)}}x().connects+=1;let d=await a.connectServer(b),e=a.getClient(b);if(!d.success||!e)return x().failures+=1,{success:!1,error:d.error??`Could not establish an MCP connection to '${b}'.`};let f=q(b);return{success:!0,lease:y(b,e,f.generation)}}function A(a,b){q(a).pins.add(b)}async function B(a){let b=v(),c=Date.now(),d=[];for(let e of s())"warm"!==e.state||e.leases>0||e.pins.size>0||c-e.lastUsedAt<b||!function(a){let b=r(a);return!!b&&(b.leases>0||b.pins.size>0)}(e.serverName)&&(u.info(`sweepIdleServers: closing ${e.serverName} after ${Math.round((c-e.lastUsedAt)/1e3)}s idle`),await a.disconnectServer(e.serverName).catch(()=>void 0),x().idleClosures+=1,d.push(e.serverName));return d}async function C(a){let b=w(),c=[];for(;;){let d=s().filter(a=>"warm"===a.state);if(d.length<=b)break;let e=d.filter(a=>0===a.leases&&0===a.pins.size).sort((a,b)=>a.lastUsedAt-b.lastUsedAt)[0];if(!e)break;u.info(`enforceWarmCapacity: evicting idle LRU server ${e.serverName} (warm=${d.length}, limit=${b})`),await a.disconnectServer(e.serverName).catch(()=>void 0),x().lruEvictions+=1,c.push(e.serverName)}return c}var D=c(9901),E=c(18705),F=c(88152),G=c(1262),H=c(35617),I=c(65445),J=c(74755),K=c(91019),L=c(90945),M=c(1477),N=c(8476),O=c(41231),P=c(29021),Q=c(21820),R=c(55511),S=c(80531),T=c(78705),U=c(61240),V=c(34887);let W=new Set(["npx","bunx","uvx","pipx","dlx"]),X=new Set(["pnpm","yarn","bun","npm"]),Y=new Set(["dlx","exec","x"]);function Z(a,b=[]){let c=((a||"").split(/[\\/]/).filter(Boolean).pop()||"").toLowerCase().replace(/\.(cmd|exe|bat|ps1)$/i,"");if(W.has(c))return!0;if(X.has(c)){let a=(b[0]||"").toLowerCase();return Y.has(a)}return!1}let $=new Set(["node","npm","npx"]);var _=c(51539),aa=c(51969),ab=c(42740),ac=c(39536),ad=c(70087);let ae=(0,i.h)("backend/services/mcp/sampling");function af(a){return a.sampling}function ag(a){let b=af(a);return!!(b?.enabled&&b.modelId)}function ah(a){let b=[];return async c=>{let d=af(a);if(!d?.enabled||!d.modelId)throw new D.Nh(D.O4.InvalidRequest,"Sampling is not enabled for this server");let e=d.maxCallsPerMinute??10,f=Date.now(),g=f-6e4;for(;b.length>0&&b[0]<g;)b.shift();if(b.length>=e)throw ae.warn(`Sampling rate limit (${e}/min) hit for ${a.name}`),new D.Nh(D.O4.InvalidRequest,`Sampling rate limit of ${e}/min exceeded`);b.push(f);let h=await ab.modelService.getModel(d.modelId);if(!h)throw new D.Nh(D.O4.InternalError,`Sampling model not found: ${d.modelId}`);let i=await ab.modelService.resolveAndDecryptApiKey(h.ApiKey);if(!i)throw new D.Nh(D.O4.InternalError,"Could not resolve the sampling model API key");let j=c.params,k=function(a){let b=[];for(let c of(a.systemPrompt&&b.push({role:"system",content:a.systemPrompt}),a.messages||[])){let a=c.content,d=a?.type==="text"&&"string"==typeof a.text?a.text:`[unsupported ${a?.type||"non-text"} content omitted]`;b.push({role:c.role,content:d})}return b}(j),l="number"==typeof j.temperature?j.temperature:.7;ae.info(`Sampling for ${a.name} via model ${h.name} (${k.length} messages)`);let m=(0,ac.getCompletionAdapter)(h),n=d.maxTokens??(0,ad.normalizeMaxTokens)(h.maxTokens),{completion:o}=await m.createCompletion({model:h,apiKey:i,messages:k,temperature:l,maxTokens:n}),p=o.choices?.[0]?.message?.content;return{role:"assistant",content:{type:"text",text:"string"==typeof p?p:""},model:h.name,stopReason:"endTurn"}}}var ai=c(51459),aj=c(67274),ak=c(1934),al=c(45649),am=c(78893);let an=(0,i.h)("backend/services/mcp/externalAuthorization");({...am.XC});let ao=global.__mcp_external_authorization_status??(global.__mcp_external_authorization_status=new Map),ap=global.__mcp_external_authorization_sessions??(global.__mcp_external_authorization_sessions=new Map),aq=global.__mcp_stdio_oauth_clients??(global.__mcp_stdio_oauth_clients=new WeakMap);function ar(a){return(0,j.workspaceCacheKey)(a)}function as(a,b){return`${a}\0${b}`}function at(a){return as((0,j.getCurrentWorkspace)(),a)}function au(a,b,c){if(aq.has(a))return;let d=(0,al._V)({mcpClient:a,installElicitationHandler:!1,...c?{mrtrController:c}:{},onUrlElicitation:(0,j.bindToCurrentWorkspace)(async a=>await aC(b,{mode:a.mode,url:a.target.href,message:a.message})??{action:"cancel"})});aq.set(a,d),a.__flujoStdioOAuth=!0}function av(a){let b=aq.get(a);if(!b)throw Error("This MCP client did not negotiate mcp-stdio-oauth.");return b}function aw(a){if(!a)return!1;let b=!0===a.__flujoStdioOAuth,c=aq.get(a);return b&&!!c?.isSupported()}async function ax(a,b,c={}){if(!aw(a))return{supported:!1,authorizations:[]};let d=ar(b),e=ao.get(d);if(!c.force&&e&&Date.now()-e.timestamp<2e3)return e.value;let f=(await av(a).getStatus({timeout:8e3})).authorizations.map(a=>({id:a.id,...a.provider?{provider:a.provider}:{},label:a.label,state:a.state,blocksUnattendedUse:a.blocksUnattendedUse,...a.message?{message:a.message}:{}})),g={supported:!0,authorizations:f,blockingAuthorization:f.find(a=>a.blocksUnattendedUse&&"ready"!==a.state)};return ao.set(d,{value:g,timestamp:Date.now()}),g}function ay(a){ao.delete(ar(a))}function az(a){let b=(0,j.getCurrentWorkspace)();return Array.from(ap.values()).filter(c=>c.workspace===b&&c.serverName===a).sort((a,b)=>b.createdAt-a.createdAt)[0]}function aA(a){a.timer&&clearTimeout(a.timer),ap.delete(as(a.workspace,a.sessionId))}function aB(a,b){let c=b?ap.get(at(b)):az(a);if(!c||c.serverName!==a)return!1;if(c.resolveElicitation){let a=c.resolveElicitation;c.resolveElicitation=void 0,c.elicitationResponded=!0,a({action:"cancel"})}else c.elicitationResponded,c.abortController.abort();return c.rejectPrompt(Error("Authorization was cancelled.")),!0}async function aC(a,b){if("url"!==b.mode)return;let c=az(a);if("string"!=typeof b.url||0===b.url.length)return c&&(c.rejectPrompt(Error("The MCP server supplied a malformed authorization URL.")),c.abortController.abort()),{action:"cancel"};if(!c)return an.warn(`Rejected unsolicited URL elicitation from ${a}`),{action:"cancel"};if(c.abortController.signal.aborted)return an.warn(`Rejected URL elicitation from cancelled start on ${a}`),{action:"cancel"};if(c.resolveElicitation||c.elicitationResponded)return an.warn(`Rejected duplicate URL elicitation from ${a}`),{action:"cancel"};try{!function(a,b,c){if(a.prompt)return a.prompt;let d=(0,al.Z)(b),e={sessionId:a.sessionId,authorizationId:a.authorizationId,url:d.href,origin:d.origin,hasPunycode:d.hasPunycode,...c?{message:c}:{}};a.prompt=e,a.resolvePrompt(e)}(c,b.url,b.message)}catch(a){return c.rejectPrompt(a instanceof Error?a:Error(String(a))),c.abortController.abort(),{action:"cancel"}}return new Promise(a=>{c.resolveElicitation=a})}async function aD(a,b,c,d={}){let e,f,g;if(d.signal?.throwIfAborted(),!aw(a))throw Error("This MCP server did not negotiate external authorization support.");let h=(await ax(a,b,{force:!0})).authorizations.find(a=>a.id===c);if(!h)throw Error("The OAuth authorization is no longer available. Refresh and try again.");if("ready"===h.state)return{sessionId:crypto.randomUUID(),authorizationId:c,url:"",origin:"",hasPunycode:!1,alreadyReady:!0};let i=az(b);if(i&&(aB(b,i.sessionId),ap.has(as(i.workspace,i.sessionId))))throw Error("The previous authorization request is still closing. Try again in a moment.");d.signal?.throwIfAborted();let k=new Promise((a,b)=>{e=a,f=b}),l={workspace:(0,j.getCurrentWorkspace)(),sessionId:crypto.randomUUID(),serverName:b,authorizationId:c,createdAt:Date.now(),resolvePrompt:e,rejectPrompt:f,promptPromise:k,abortController:new AbortController};l.timer=setTimeout((0,j.bindToCurrentWorkspace)(()=>{let a=l.resolveElicitation;l.resolveElicitation=void 0,l.elicitationResponded=!0,a?.({action:"cancel"}),l.abortController.abort(),l.rejectPrompt(Error("Authorization request timed out."))}),3e5),ap.set(as(l.workspace,l.sessionId),l);let m=(0,j.bindToCurrentWorkspace)(()=>{aB(b,l.sessionId)});d.signal?.addEventListener("abort",m,{once:!0});let n=(0,j.bindToCurrentWorkspace)(async d=>{if(ay(b),"ready"===d.state){l.resolvePrompt({sessionId:l.sessionId,authorizationId:c,url:"",origin:"",hasPunycode:!1,alreadyReady:!0}),aA(l);return}let e=(await ax(a,b,{force:!0})).authorizations.find(a=>a.id===c);if(e?.state==="ready"){l.resolvePrompt({sessionId:l.sessionId,authorizationId:c,url:"",origin:"",hasPunycode:!1,alreadyReady:!0}),aA(l);return}l.rejectPrompt(Error("The MCP server completed OAuth start without URL elicitation or ready status.")),aA(l)}),o=(0,j.bindToCurrentWorkspace)(a=>{l.rejectPrompt(a instanceof Error?a:Error(String(a)))}),p=(0,j.bindToCurrentWorkspace)(()=>aA(l));av(a).start(c,{timeout:3e5,signal:l.abortController.signal}).then(n).catch(o).finally(p);try{return await Promise.race([k,new Promise((a,b)=>{g=setTimeout(()=>b(Error("The MCP server did not present an authorization URL in time.")),3e4)})])}catch(a){throw aB(b,l.sessionId),a}finally{g&&clearTimeout(g),d.signal?.removeEventListener("abort",m)}}let aE=(0,i.h)("backend/services/mcp/taskInputRegistry"),aF=globalThis,aG=aF.__flujoMcpTaskInputRegistry??(aF.__flujoMcpTaskInputRegistry=new Map);function aH(a,b){return(0,j.workspaceCacheKey)(a,b)}let aI=(0,i.h)("backend/services/mcp/elicitation");function aJ(a){return a.elicitation}function aK(a){let b=aJ(a);return!!b?.enabled}function aL(a){return(0,j.bindToCurrentWorkspace)(async b=>{var c,d,e;let f,g,h,i,j,k=b.params,l=(0,F.PJ)(k?._meta),m=await aC(a.name,k??{});if(m)return m;if(!aK(a))throw new D.Nh(D.O4.MethodNotFound,"Elicitation is not enabled for this server");let n=(0,aj.lx)(a.name);if(!n&&l&&aI.warn(`Task ${l} on ${a.name} requested input outside an attended run; auto-cancelling`),!n)return aI.warn(`Elicitation request from ${a.name} outside an active run; auto-cancelling`),{action:"cancel"};if(n.getUnattended())return aI.warn(`Elicitation request from ${a.name} in unattended run ${n.conversationId}; auto-cancelling`),{action:"cancel"};let o=k?.message??"Additional information required",p=k?.requestedSchema??{type:"object",properties:{}},q=crypto.randomUUID();aI.info(`Suspending for elicitation ${q} from ${a.name} in conv ${n.conversationId}`),l&&(c=a.name,f=aH(c,l),g=Date.now(),(h=aG.get(f)??{outstanding:new Set,answered:new Set,firstRequestedAt:g,lastRequestedAt:g}).answered.has(q)||(h.outstanding.add(q),h.lastRequestedAt=g,aG.set(f,h),aE.info(`Task ${l} on ${c} requested input (elicitation ${q}); outstanding=${h.outstanding.size}`))),ai.$.emitterFor(n.conversationId)({type:"run:awaiting_elicitation",elicitationId:q,message:o,requestedSchema:p});let r=await (0,ak.gV)(q);return aI.info(`Elicitation ${q} resolved with action=${r.action}`),l&&(d=a.name,e=r.action,i=aH(d,l),!(j=aG.get(i))||!j.outstanding.delete(q)&&j.answered.has(q)||(j.answered.add(q),aG.set(i,j),aE.info(`Task ${l} on ${d} input ${q} resolved with action=${e}; outstanding=${j.outstanding.size}`))),r})}var aM=c(71202),aN=c(85482),aO=c(62156);function aP(a){let b,c;return[(b=af(a),!b?.enabled?"":JSON.stringify({m:b.modelId,t:b.maxTokens,r:b.maxCallsPerMinute})),(c=aJ(a),c?.enabled?"e:1":""),!0===a.enableMcpApps?"mcp-apps:on":"mcp-apps:off",!0===a.enableMcpSkills?"mcp-skills:on":"mcp-skills:off"].join("|")}let aQ=(0,i.h)("backend/services/mcp/connection");async function aR(a){let b=a;if(a.env&&"object"==typeof a.env){let c={};for(let[b,d]of Object.entries(a.env)){if(!b)continue;let a=d&&"object"==typeof d&&"value"in d?d.value??"":d??"";if(!a||(0,aM.uh)(a))continue;let e=await (0,E.G)(a);e&&(c[b]=e)}b={...b,env:c}}if("streamable"!==a.transport&&"sse"!==a.transport||!a.headers||"object"!=typeof a.headers)return b;let c={};for(let[b,d]of Object.entries(a.headers)){if(!b)continue;let{value:a}=(0,aM.at)(d,b);if(!a||(0,aM.uh)(a))continue;let e=await (0,E.G)(a);e&&(c[b]=e)}return{...b,headers:c}}function aS(a){let b={};for(let[c,d]of Object.entries(a)){if(!c)continue;let{value:a}=(0,aM.at)(d,c);"string"==typeof a&&a.length>0&&(b[c]=a)}return b}function aT(a){let b={};if(a)for(let[c,d]of Object.entries(a))d&&"object"==typeof d&&"value"in d?b[c]=d.value:b[c]=d;return b}let aU=new Set(["path","pathext","home","userprofile","homedrive","homepath","appdata","localappdata","programdata","xdg_config_home","xdg_cache_home","xdg_data_home","xdg_state_home","xdg_runtime_dir","tmp","temp","tmpdir","shell","comspec","systemroot","windir","systemdrive","programfiles","programfiles(x86)","gh_config_dir"]);function aV(a,b,c){for(let c of Object.keys(a))c.toLowerCase()===b.toLowerCase()&&delete a[c];void 0!==c&&(a[b]=c)}function aW(a,b=!1){return JSON.stringify({command:a.command,args:a.args??[],env:aT(a.env),cwd:String(a.cwd??""),rootPath:a.rootPath??"",isolateRuntimeHome:b})}function aX(a){return JSON.stringify({transport:a.transport,url:a.serverUrl??"",headers:a.headers??{},requestInit:a.requestInit??{},eventSourceInit:a.eventSourceInit??{},reconnectionOptions:a.reconnectionOptions??{},sessionId:a.sessionId??"",oauthClientId:a.oauthClientId??"",oauthClientInformation:a.oauthClientInformation??{},oauthClientSecret:a.oauthClientSecret??"",oauthTokens:a.oauthTokens??{}})}function aY(a){aQ.debug("Entering createNewClient method");let b=ag(a),c=aK(a),d=!0===a.enableMcpApps,e="stdio"===a.transport,f=new K.K({name:`flujo-${a.name}-client`,version:"3.45.2"},{capabilities:{experimental:{},roots:{listChanged:!0},...b?{sampling:{}}:{},...e||c?{elicitation:{...e?{url:{}}:{},...c?{form:{}}:{}}}:{},extensions:{...e?{[am.OM]:am.XC}:{},...d?{[aN.OF]:{mimeTypes:[aN.cM]}}:{}}}});return(0,aa.FP)(f,a),b&&f.setRequestHandler(D.u9,ah(a)),(e||c)&&f.setRequestHandler(D.$9,aL(a)),f.__flujoCapKey=aP(a),f}function aZ(a,b){if(aQ.debug("Entering createTransport method"),"streamable"===a.transport){aQ.info(`Creating streamable http transport for server ${a.name} with URL ${a.serverUrl}`);let b={};if(a.requestInit&&"object"==typeof a.requestInit&&(b.requestInit=a.requestInit),a.reconnectionOptions&&"object"==typeof a.reconnectionOptions&&(b.reconnectionOptions=a.reconnectionOptions),"string"==typeof a.sessionId&&a.sessionId.length>0&&(b.sessionId=a.sessionId),a.headers&&"object"==typeof a.headers){let c=aS(a.headers);Object.keys(c).length>0&&(b.requestInit={...b.requestInit||{},headers:{...b.requestInit?.headers||{},...c}},aQ.info(`Applied ${Object.keys(c).length} custom header(s) for ${a.name}: ${Object.keys(c).join(", ")}`))}a.oauthClientId||a.oauthClientInformation?(aQ.info(`Setting up OAuth authentication for ${a.name}`),b.authProvider=(0,S.Cl)(a),a.oauthTokens?.access_token?(aQ.debug(`OAuth provider configured for ${a.name} with existing tokens`),aQ.debug(`Token expires in: ${a.oauthTokens.expires_in} seconds`)):aQ.debug(`OAuth provider configured for ${a.name} - will initiate OAuth flow if needed`)):aQ.debug(`No OAuth configuration found for ${a.name}`);let c=new N.j(new URL(a.serverUrl),b);return c.__flujoHttpKey=aX(a),c}if("sse"===a.transport){aQ.info(`Creating legacy sse transport for server ${a.name} with URL ${a.serverUrl}`);let b={};if(a.requestInit&&"object"==typeof a.requestInit&&(b.requestInit=a.requestInit),a.eventSourceInit&&"object"==typeof a.eventSourceInit&&(b.eventSourceInit=a.eventSourceInit),a.headers&&"object"==typeof a.headers){let c=aS(a.headers);Object.keys(c).length>0&&(b.requestInit={...b.requestInit||{},headers:{...b.requestInit?.headers||{},...c}},aQ.info(`Applied ${Object.keys(c).length} custom header(s) for ${a.name}: ${Object.keys(c).join(", ")}`))}let c=new O.A(new URL(a.serverUrl),b);return c.__flujoHttpKey=aX(a),c}return"websocket"===a.transport?(aQ.info(`Creating WebSocket transport for server ${a.name} with URL ${a.websocketUrl}`),new M.I(new URL(a.websocketUrl))):function(a,b){let c;if(aQ.debug("Entering createStdioTransport method"),"stdio"!==a.transport)throw Error("Cannot create stdio transport for non-stdio config");let{command:d,args:e,env:f,cwd:g}=a$(a,b),h=b?.enableRuntimeBroker&&!0===a.enableMcpApps?(0,aO.D9)(a.name):void 0;aQ.info(`Creating StdioClientTransport for ${a.name} with stderr: 'pipe'`);let i={command:d,args:e,env:h?{...f,...h.env}:f,cwd:g,stderr:"pipe"};try{c=new L.oQ(i)}catch(a){throw(0,aO.tS)(h?.leaseId),a}return h&&(c.__flujoRuntimeBrokerLeaseId=h.leaseId),c.__flujoStdioKey=aW(a,b?.isolateRuntimeHome===!0),c.stderr?aQ.info(`Stderr stream is available for ${a.name}`):aQ.warn(`Stderr stream is NOT available for ${a.name}`),c}(a,b)}function a$(a,b){let c=(0,_.AW)(a),d=!!c,e=c?.defaultName==="bash",f=a=>d?a:(0,j.remapLegacyDefaultWorkspaceReference)(a,"mcp-servers"),h=f(a.command),i=a.args?a.args.map(f):[],k=`${l.VL}/${a.name}`;aQ.info(`Creating stdio transport for server ${a.name}`),aQ.debug(`Original command: ${h}`),aQ.debug(`Original args: ${JSON.stringify(i)}`),aQ.debug(`Server directory: ${k}`);let m=!g.isAbsolute(h)&&(h.includes("/")||h.includes("\\")),n=!h.includes("/")&&!h.includes("\\");if(aQ.debug(`Is relative path: ${m}`),aQ.debug(`Is just filename: ${n}`),"win32"===Q.platform()&&h.toLowerCase().endsWith(".bat"))if(aQ.debug(`Detected .bat file on Windows: ${h}`),n){let a=g.join((0,j.getWorkspaceDataDir)(),k,h);aQ.debug(`Checking if file exists at: ${a}`);let b=P.existsSync(a);aQ.debug(`File exists: ${b}`),b?(aQ.debug(`Using full path to .bat file: ${a}`),i=["/c",a,...i]):(aQ.warn(`WARNING: .bat file not found at ${a}`),i=["/c",h,...i]),h="cmd.exe"}else aQ.debug(`Using cmd.exe with path as provided: ${h}`),i=["/c",h,...i],h="cmd.exe";let o=function(a,b){if(!a||!(!a.includes("/")&&!a.includes("\\")))return a;let c=a.toLowerCase();if(!$.has(c))return a;if("node"===c)return b.execPath||a;if(!b.execPath)return a;let d=b.dirname(b.execPath);for(let a of"win32"===b.platform?[`${c}.cmd`,`${c}.exe`,c]:[c]){let c=b.joinPath(d,a);if(b.fileExists(c))return c}return a}(h,{execPath:process.execPath,platform:Q.platform(),dirname:g.dirname,joinPath:g.join,fileExists:P.existsSync});o!==h&&(aQ.debug(`Resolved Node toolchain command "${h}" to absolute path: ${o}`),h=o),aQ.debug(`Final command: ${h}`),aQ.debug(`Final args: ${JSON.stringify(i)}`);let p=e||b?.isolateRuntimeHome!==!0?void 0:function(a){let b=(0,j.getWorkspaceDataDir)(),c=(0,R.createHash)("sha256").update(a,"utf8").digest("hex").slice(0,24),d=(a,b)=>{try{let c=P.lstatSync(a);if(!c.isDirectory()||c.isSymbolicLink())throw Error(`${b} must be a real directory: ${a}`)}catch(d){if("ENOENT"!==d.code)throw d;P.mkdirSync(a,{mode:448});let c=P.lstatSync(a);if(!c.isDirectory()||c.isSymbolicLink())throw Error(`${b} must be a real directory: ${a}`)}},e=P.lstatSync(b);if(!e.isDirectory()||e.isSymbolicLink())throw Error(`Workspace root must be a real directory: ${b}`);let f=b;for(let a of["userdata","mcp-runtime",c])d(f=g.join(f,a),"MCP runtime directory");let h=f,i=g.join(h,"home"),k=g.join(h,"cwd");d(i,"MCP runtime home"),d(k,"MCP runtime cwd");let l={appData:g.join(i,"AppData","Roaming"),localAppData:g.join(i,"AppData","Local"),config:g.join(i,".config"),cache:g.join(i,".cache"),data:g.join(i,".local","share"),state:g.join(i,".local","state"),runtime:g.join(i,".runtime"),temp:g.join(i,"tmp"),npm:g.join(i,".npm"),pip:g.join(i,".cache","pip"),uv:g.join(i,".cache","uv")};for(let a of Object.values(l)){let b=g.relative(i,a),c=i;for(let a of b.split(g.sep).filter(Boolean))d(c=g.join(c,a),"MCP runtime directory")}let m={HOME:i,USERPROFILE:i,APPDATA:l.appData,LOCALAPPDATA:l.localAppData,XDG_CONFIG_HOME:l.config,XDG_CACHE_HOME:l.cache,XDG_DATA_HOME:l.data,XDG_STATE_HOME:l.state,XDG_RUNTIME_DIR:l.runtime,TMPDIR:l.temp,TMP:l.temp,TEMP:l.temp,NPM_CONFIG_CACHE:l.npm,PIP_CACHE_DIR:l.pip,UV_CACHE_DIR:l.uv};if("win32"===process.platform){let a=g.parse(i);m.HOMEDRIVE=a.root.replace(/[\\/]$/,""),m.HOMEPATH=i.slice(a.root.length-1)}return{cwd:k,env:m}}(a.name),q=f(function({command:a,args:b=[],rootPath:c,cwd:d,serverName:e,defaultCwd:f,packageRunnerCwd:g}){let h=c||d||f;if(Z(a,b)&&g)return g;if(e&&Z(a,b)&&(h.split(/[\\/]/).filter(Boolean).pop()||"")===e){let a;return((a=h.match(/^(.*[\\/])[^\\/]+[\\/]*$/))?a[1].replace(/[\\/]+$/,""):"")||h}return h}({command:a.command,args:a.args,rootPath:a.rootPath,cwd:a.cwd,serverName:a.name,defaultCwd:`${l.VL}/${a.name}`,packageRunnerCwd:p?.cwd})),r=g.isAbsolute(q)?q:g.join((0,j.getWorkspaceDataDir)(),q);aQ.debug(`cwd: ${r}`),aQ.debug(`Environment variable names: ${JSON.stringify(Object.keys(a.env??{}))}`);let s=aT(a.env),t=e?function(a){let b={...a},c=Object.entries(process.env).filter(a=>"string"==typeof a[1]);for(let[a,d]of c)aV(b,a,d);for(let a of aU)c.find(([b])=>b.toLowerCase()===a)||aV(b,a,void 0);return b}(s):s;if(!d)for(let[a,b]of Object.entries(t))t[a]=f(b);p&&Object.assign(t,p.env),function(a){if("win32"!==process.platform)return;let b=(a,b)=>Object.entries(a).find(([a,c])=>a.toLowerCase()===b.toLowerCase()&&""!==(c??"").trim())?.[1],c=b(process.env,"SystemRoot")??b(process.env,"windir")??"C:\\Windows";for(let[d,e]of Object.entries({SystemRoot:c,windir:c,ComSpec:b(process.env,"ComSpec")??g.join(c,"System32","cmd.exe"),PATHEXT:b(process.env,"PATHEXT")??".COM;.EXE;.BAT;.CMD"}))if(void 0===b(a,d)){for(let b of Object.keys(a))b.toLowerCase()===d.toLowerCase()&&delete a[b];a[d]=e}}(t);let u=(0,V.ok)(),v=(0,j.getWorkspaceDataDir)();if(t.FLUJO_PARENT_DATA_DIR=u,t.FLUJO_DATA_DIR=v,t.FLUJO_WORKSPACE=(0,j.getCurrentWorkspace)(),c?.defaultName==="browser"){if(!t.PLAYWRIGHT_BROWSERS_PATH?.trim()){let a=(0,_.AI)(process.env);a&&(t.PLAYWRIGHT_BROWSERS_PATH=a)}t.FLUJO_BROWSER_PROFILE_DIR=g.join(v,"browser-profile","trusted"),t.FLUJO_BROWSER_SCREENSHOT_DIR=g.join(v,"screenshots","browser"),t.FLUJO_BROWSER_RECORD_DIR=g.join(v,"recordings","browser")}return aQ.verbose("Transformed environment variable names",JSON.stringify(Object.keys(t))),"1"===process.env.FLUJO_WORKER_MODE&&c?.defaultName==="flujo"&&(t.FLUJO_WORKER_MODE="1",process.env.FLUJO_SNAPSHOT_CONTROL_TOKEN&&(t.FLUJO_SNAPSHOT_CONTROL_TOKEN=process.env.FLUJO_SNAPSHOT_CONTROL_TOKEN)),{command:h,args:i,env:t,cwd:r}}async function a_(a,b,c,d){aQ.debug("Entering safelyCloseClient method");let e=Date.now(),f=d?.gracePeriodMs??15e3,g=d?.killEscalationMs??5e3,h=!0,i=!1,j=function(a){let b=a,c=new Set;for(;b&&"object"==typeof b&&!c.has(b);){c.add(b);let a=b.__flujoInnerTransport;if(!a)break;b=a}return b}(a.transport);try{let c=j?._process;if(c&&"function"==typeof c.kill&&null===c.exitCode&&null===c.signalCode){try{c.stdin&&!c.stdin.destroyed&&(c.stdin.end(),aQ.debug(`Closed stdin for graceful shutdown for ${b}`))}catch(a){aQ.warn(`Error closing stdin for ${b}:`,a)}if(h=await (null!==c.exitCode||null!==c.signalCode?Promise.resolve(!0):new Promise(a=>{let b=()=>{clearTimeout(d),a(!0)},d=setTimeout(()=>{c.removeListener("exit",b),a(!1)},f);d.unref?.(),c.once("exit",b)})))aQ.info(`Process exited gracefully for ${b}`);else{aQ.warn(`Process did not exit within ${f}ms after stdin close; escalating to a tree kill for ${b}`);let a=await (0,U.U)(c,{graceMs:g,finalWaitMs:g});h=a.exited,i=a.forced,h?aQ.warn(`Process tree for ${b} force-terminated after ${a.durationMs}ms`):aQ.error(`Process tree for ${b} (pid ${a.pid??"unknown"}) did not exit after forced escalation`)}}await a.close(),aQ.info(`Client closed successfully for ${b}`)}catch(a){aQ.warn(`Error closing client for ${b}:`,a)}finally{(0,aO.tS)(j?.__flujoRuntimeBrokerLeaseId)}return{exited:h,forced:i,durationMs:Date.now()-e}}var a0=c(4618);let a1=(0,i.h)("backend/services/mcp/betaClient");async function a2(){try{let a=await (0,I.loadItem)(J.Zg.SPEECH_SETTINGS,void 0);return!!a?.experimental?.mcpBetaProtocol}catch(a){return a1.warn("Failed to read mcpBetaProtocol setting; defaulting to disabled",{err:a}),!1}}function a3(a){return!0===a.__flujoBeta}function a4(a){let b=ag(a),c=aK(a),d=!0===a.enableMcpApps,e="stdio"===a.transport,f=new G.Kj({name:`flujo-${a.name}-client`,version:"3.45.2"},{capabilities:{roots:{listChanged:!0},...b?{sampling:{}}:{},...e||c?{elicitation:{...e?{url:{}}:{},...c?{form:{}}:{}}}:{},extensions:{...e?{[am.OM]:am.XC}:{},...d?{[aN.OF]:{mimeTypes:[aN.cM]}}:{}}},versionNegotiation:{mode:"auto"}});if(f.setRequestHandler("roots/list",(0,aa.sG)(a)),b){let b=ah(a);f.setRequestHandler("sampling/createMessage",async a=>b(a))}if(e||c){let b=aL(a);f.setRequestHandler("elicitation/create",async a=>b(a))}return f.__flujoBeta=!0,f.__flujoCapKey=aP(a),a1.info(`Created v2-beta MCP client for ${a.name} (version negotiation: auto)`),f}function a5(a){let b=a.requestInit&&"object"==typeof a.requestInit?a.requestInit:void 0;if(a.headers&&"object"==typeof a.headers){let c=aS(a.headers);Object.keys(c).length>0&&(b={...b||{},headers:{...b?.headers||{},...c}})}return b}function a6(a,b){let c;if("websocket"===a.transport)throw Error("The v2-beta MCP SDK has no websocket transport; use the v1 path");if("streamable"===a.transport){let b={},c=a5(a);c&&(b.requestInit=c),a.reconnectionOptions&&"object"==typeof a.reconnectionOptions&&(b.reconnectionOptions=a.reconnectionOptions),"string"==typeof a.sessionId&&a.sessionId.length>0&&(b.sessionId=a.sessionId),(a.oauthClientId||a.oauthClientInformation)&&(b.authProvider=(0,S.Cl)(a));let d=new G.jS(new URL(a.serverUrl),b);return d.__flujoHttpKey=aX(a),d.__flujoKind="streamable",a1.info(`Created v2-beta streamable transport for ${a.name}`),d}if("sse"===a.transport){let b={},c=a5(a);c&&(b.requestInit=c),a.eventSourceInit&&"object"==typeof a.eventSourceInit&&(b.eventSourceInit=a.eventSourceInit);let d=new G.Am(new URL(a.serverUrl),b);return d.__flujoHttpKey=aX(a),d.__flujoKind="sse",a1.info(`Created v2-beta SSE transport for ${a.name}`),d}let{command:d,args:e,env:f,cwd:g}=a$(a,b),h=b?.enableRuntimeBroker&&!0===a.enableMcpApps?(0,aO.D9)(a.name):void 0;try{c=new H.oQ({command:d,args:e,env:h?{...f,...h.env}:f,cwd:g,stderr:"pipe"})}catch(a){throw(0,aO.tS)(h?.leaseId),a}let i=c;return i.__flujoRuntimeBrokerLeaseId=h?.leaseId,i.__flujoStdioKey=aW(a,b?.isolateRuntimeHome===!0),i.__flujoKind="stdio",a7.set(c,new a0.$6),a1.info(`Created v2-beta stdio transport for ${a.name}`),c}let a7=new WeakMap;function a8(a){a7.get(a)?.attach(a)}var a9=c(2398),ba=c(44907),bb=c(86364);let bc=(0,i.h)("backend/services/mcp/clientTasks");function bd(a,b,c){return"completed"===a.status?{success:!0,data:c,progressToken:a.taskId}:"failed"===a.status?{success:!1,error:a.statusMessage??`Task ${a.taskId} failed`,errorType:"task-failed",progressToken:a.taskId,toolName:b}:{success:!1,error:a.statusMessage??`Tool '${b}' task ${a.taskId} was cancelled by the server.`,errorType:"cancelled",progressToken:a.taskId,toolName:b}}async function be(a){var b,c;let d,{client:e,serverName:f,serverIdentity:g,toolName:h,task:i,timeoutMs:j,signal:k,onProgress:l,ownership:m,persist:n}=a,o=await (0,bb.VX)(),p=Date.now(),q=(0,F.uY)(i.pollInterval,{minMs:o.minPollIntervalMs,maxMs:o.maxPollIntervalMs,defaultMs:o.defaultPollIntervalMs}),r=(0,F.on)(i,p,o.fallbackTtlMs);bc.info(`Tool ${h} on ${f} returned task ${i.taskId} (status=${i.status}, poll=${q}ms, expiresAt=${r??"none"})`),l?.({progress:0,message:`Task ${i.taskId} created (${i.status})`});let s=await (0,bb.Au)(f);if(!s)return bc.warn(`Refusing to poll task ${i.taskId}: poll concurrency limit reached for ${f}`),a.supportsCancel&&await (0,a9.O0)(e,i.taskId),{success:!1,error:`Too many concurrent MCP tasks are being polled; task ${i.taskId} was not started.`,errorType:"task-poll-limit",progressToken:i.taskId,toolName:h};let t=null;n&&(t=await (0,bb.ZN)({remoteTaskId:i.taskId,serverName:f,serverIdentity:g,toolName:h,args:a.args,ownership:m,status:i.status,statusMessage:i.statusMessage,pollIntervalMs:q,...void 0!==r?{expiresAt:r,ttlMs:r-p}:{}}));let u=async a=>{if(!t)return;let b=await (0,bb.Pi)(t.recordId,a);b&&(t=b)},v=b=>(d||(d=(async()=>(await u({cancelRequestedAt:Date.now(),...b?{diagnostic:b}:{}}),a.supportsCancel)?(0,a9.O0)(e,i.taskId):void bc.warn(`Server ${f} does not advertise tasks.cancel; skipping cancellation of ${i.taskId}`))()),d),w=()=>{v()};k?.addEventListener("abort",w,{once:!0});try{let a;if((0,F.gJ)(i.status))return await x(i);let c=i,d=0,g=q,m=0;for(;;){let i;if(k?.aborted)return await v(),await u({status:"cancelled"}),{success:!1,error:`Tool '${h}' task ${c.taskId} was cancelled.`,errorType:"cancelled",progressToken:c.taskId,toolName:h};let n=Date.now();if(void 0!==r&&n>=r)return await v("expired"),await u({status:"failed",diagnostic:"expired",errorMessage:"Remote MCP task expired before completing."}),{success:!1,error:`Task ${c.taskId} expired before completing.`,errorType:"task-expired",progressToken:c.taskId,toolName:h};if(n-p>=j){await v(),await u({status:"failed",errorMessage:"Caller timeout elapsed while polling the remote MCP task."});let a=Math.round(j/1e3);return{success:!1,error:`Tool execution timed out after ${a} seconds`,errorType:"timeout",timeout:a,statusCode:408,progressToken:c.taskId,toolName:h}}if(await (0,ba.y)(g),k?.aborted)continue;try{i=await (0,a9.k$)(e,c.taskId,{timeout:Math.min(4*g+1e4,j)}),d=0,g=q}catch(a){if(d++,await u({diagnostic:"transport-error",lastPolledAt:Date.now()}),d>=o.maxTransientPollFailures)return await v("transport-error"),await u({status:"failed",diagnostic:"transport-error",errorMessage:`tasks/get failed ${d} times: ${String(a)}`}),{success:!1,error:`Lost contact with '${f}' while polling task ${c.taskId}.`,errorType:"task-transport-error",progressToken:c.taskId,toolName:h};g=(0,F.uY)(2*g,{minMs:o.minPollIntervalMs,maxMs:o.maxPollIntervalMs,defaultMs:o.defaultPollIntervalMs}),bc.warn(`Transient tasks/get failure ${d}/${o.maxTransientPollFailures} for ${c.taskId}; backing off to ${g}ms`);continue}if(!i.ok)return await v("protocol-invalid"),await u({status:"failed",diagnostic:"protocol-invalid",errorMessage:`Invalid tasks/get result: ${i.reason}`}),{success:!1,error:`Server '${f}' returned an invalid task status: ${i.reason}`,errorType:"task-protocol-invalid",progressToken:c.taskId,toolName:h};c=i.task,m++;let s=Date.now()-p;if(await u({status:c.status,statusMessage:c.statusMessage,lastPolledAt:Date.now(),nextPollAt:Date.now()+g,pollCount:m,outstandingInputKeys:(b=c.taskId,[...aG.get(aH(f,b))?.outstanding??[]])}),l?.({progress:"completed"===c.status?100:Math.min(99,Math.round(s/1e3)),message:`Task ${c.taskId}: ${c.status}${c.statusMessage?` — ${c.statusMessage}`:""}`}),(0,F.gJ)(c.status))return await x(c);if("input_required"===c.status){a??=Date.now();let b=function(a,b,c,d,e=Date.now()){let f=(0,aj.lx)(a),g=aG.get(aH(a,b));return f?f.getUnattended()?{action:"abandon",error:`Task ${b} on '${a}' requires input, but the run is unattended.`,errorType:"task-input-required-unattended",diagnostic:"input-required-unattended"}:e-c>=d?{action:"abandon",error:`Task ${b} on '${a}' was waiting for input for longer than the configured window (${Math.round(d/1e3)}s)${g?`; ${g.outstanding.size} request(s) unanswered`:""}.`,errorType:"task-input-timeout",diagnostic:"input-required-unattended"}:{action:"wait"}:{action:"abandon",error:`Task ${b} on '${a}' requires input, but no attended run is available to answer it.`,errorType:"task-input-required-unattended",diagnostic:"input-required-unattended"}}(f,c.taskId,a,o.inputRequiredTimeoutMs);if("abandon"===b.action)return await v(b.diagnostic),await u({status:"failed",diagnostic:b.diagnostic,errorMessage:b.error}),{success:!1,error:b.error,errorType:b.errorType,progressToken:c.taskId,toolName:h}}else a=void 0}}finally{k?.removeEventListener("abort",w),s.release(),c=i.taskId,aG.delete(aH(f,c))}async function x(a){if("completed"!==a.status)return await u({status:a.status,statusMessage:a.statusMessage,..."failed"===a.status?{errorMessage:a.statusMessage??"Remote MCP task failed."}:{}}),bd(a,h);try{let b=await (0,a9.Yr)(e,a.taskId,{timeout:Math.min(6e4,j)});return await u({status:"completed",resultRetrieved:!0}),l?.({progress:100,message:`Task ${a.taskId}: completed`}),bd(a,h,b)}catch(b){return await u({status:"completed",resultRetrieved:!1,errorMessage:`tasks/result failed: ${String(b)}`}),{success:!1,error:`Task ${a.taskId} completed but its result could not be retrieved from '${f}'.`,errorType:"task-result-unavailable",progressToken:a.taskId,toolName:h}}}}var bf=c(62511);let bg=(0,i.h)("backend/services/mcp/tools"),bh=0x80000000-1;async function bi(a,b,c="model"){if(bg.debug("Entering listServerTools method"),!a)return bg.warn(`Server ${b} not connected`),{tools:[],error:"Server not connected"};try{bg.info(`Listing tools for server ${b}`);let d=await a.listTools();bg.verbose("Raw response from MCP server:",d);let e=(d.tools||[]).map(a=>({...a,description:a.description||"",inputSchema:a.inputSchema||{type:"object"}})),f=(0,aN.zm)(e,c);return bg.verbose(`Processed tools for ${c} audience:`,f),{tools:f}}catch(c){bg.warn(`Failed to list tools for server ${b}:`,c);let a=c instanceof Error?c.message:"Unknown error";return{tools:[],error:a.includes("Connection timeout")?a:`Failed to list tools: ${a}`}}}async function bj(a,b,c,d,e,f,g,h="host",i,j){if(bg.debug("Entering callTool method"),!a)return bg.warn(`Server ${b} not found`),{success:!1,error:`Server ${b} not found`,statusCode:404};let k=void 0!==e&&e>0?Math.min(1e3*e,bh):bh;try{if("app"===h||"model"===h){let d=await bi(a,b,"all");if(d.error)return{success:!1,error:`Could not verify MCP App access to tool '${c}' on '${b}': ${d.error}`,errorType:"tool-authorization-list",statusCode:502};let e=(0,aN.F)(d.tools,b,c,h);if(!e.allowed)return bg.warn(`Rejected ${h} tool call: ${e.error}`),{success:!1,error:e.error,statusCode:e.statusCode}}bg.debug(`Original args for tool ${c}:`,d);let e=await (0,E.resolveGlobalVars)(d),l=function(a,b){if(!a)return{};let c={};for(let d in a){let e=a[d];null==e?(bg.debug(`Normalizing undefined/null value for parameter '${d}' in tool '${b}'`),d.includes("number")||d.endsWith("Count")||d.endsWith("Id")||d.endsWith("Limit")?(c[d]=0,bg.debug(`Using default value 0 for likely number parameter: ${d}`)):d.includes("bool")||d.startsWith("is")||d.startsWith("has")||d.startsWith("should")?(c[d]=!1,bg.debug(`Using default value false for likely boolean parameter: ${d}`)):d.includes("array")||d.endsWith("s")||d.endsWith("List")||d.endsWith("Items")?(c[d]=[],bg.debug(`Using empty array for likely array parameter: ${d}`)):d.includes("object")||d.endsWith("Options")||d.endsWith("Config")||d.endsWith("Settings")?(c[d]={},bg.debug(`Using empty object for likely object parameter: ${d}`)):(c[d]="",bg.debug(`Using empty string for parameter with unknown type: ${d}`))):c[d]=e}return c}("object"==typeof e&&null!==e?e:{},c);bg.debug(`Normalized args for tool ${c}:`,l),bg.debug(`Calling tool ${c} with SDK timeout ${k}ms`);let m={timeout:k,resetTimeoutOnProgress:!0,...g?{signal:g}:{},onprogress:a=>{bg.debug(`Progress for tool ${c}: ${a.progress}${void 0!==a.total?`/${a.total}`:""}${a.message?` — ${a.message}`:""}`),f?.(a)}},n=await (0,a9.u2)(a,c);n.request&&bg.info(`Requesting task-augmented execution of ${c} on ${b} (${n.reason})`);let o={name:c,arguments:l,...n.request?(0,a9.E4)(n.ttlMs):{},...i||j?{_meta:{flujo:{...i?{callerNodeId:i}:{},...j?{ownerScope:j}:{}}}}:{}},p=a3(a)?await a.callTool.call(a,o,m):await a.callTool(o,void 0,m),q=(0,F.Qh)(p,{taskRequested:n.request});if("protocol-invalid"===q.kind)return bg.warn(`Server ${b} returned an invalid task result for ${c}: ${q.reason}`),{success:!1,error:`Server '${b}' returned an invalid MCP task result: ${q.reason}`,errorType:"task-protocol-invalid",statusCode:502,toolName:c};if("task"===q.kind){let d=(0,a9.rf)(),e=d?await (0,bb.kI)(b):"unnegotiated",m=await be({client:a,serverName:b,serverIdentity:e,toolName:c,args:l,task:q.task,timeoutMs:k,...g?{signal:g}:{},...f?{onProgress:f}:{},ownership:{...i?{nodeId:i}:{},...j?{ownerScope:j}:{},source:h},persist:d,supportsCancel:n.negotiation.supportsCancel||!n.negotiation.supported});return void 0===m.data?m:{...m,data:(0,bf.iL)(m.data,j)}}return{success:!0,data:(0,bf.iL)(p,j)}}catch(h){bg.warn(`Failed to call tool ${c} on server ${b}:`,h);let d=h instanceof Error?h.message:"Unknown error",e=500;if(g?.aborted)return{success:!1,error:`Tool '${c}' call was cancelled.`,errorType:"cancelled",toolName:c};if(h instanceof D.Nh&&h.code===D.O4.RequestTimeout){let a=Math.round(k/1e3);return bg.warn(`Tool ${c} execution timed out after ${a} seconds`),{success:!1,error:`Tool execution timed out after ${a} seconds`,errorType:"timeout",toolName:c,timeout:a,statusCode:408}}let f=aw(a)?(0,am.W2)(h):void 0;if(f){ay(b);try{await ax(a,b,{force:!0})}catch(a){bg.warn(`Failed to refresh mcp-stdio-oauth status after revocation on ${b}:`,a)}return{success:!1,error:f.message?f.message:"External account authorization is required. Open the MCP page to authenticate.",errorType:"stdio-oauth-required",statusCode:428,requiresAuthentication:!0}}if(d.includes("401")||d.includes("Unauthorized")||d.includes("invalid_token")||d.includes("token_expired"))return bg.info(`OAuth authentication error detected for tool ${c} on server ${b}`),{success:!1,error:"OAuth authentication failed or tokens have expired. Please re-authenticate the server.",statusCode:401,requiresAuthentication:!0};return(d.includes("404")||d.includes("Not Found"))&&(bg.info(`404 error detected for tool ${c} on server ${b} - may indicate OAuth issues`),e=404,d="Tool endpoint not found (404). This may indicate OAuth authentication issues or the server may not be properly configured."),h instanceof D.Nh?(d=`Failed to call tool: ${d} (Code: ${h.code})`,-32601===h.code?e=404:-32602===h.code?e=400:-32603===h.code&&(e=500)):d=`Failed to call tool: ${d}`,{success:!1,error:d,statusCode:e}}}let bk=(0,i.h)("backend/services/mcp/resources");async function bl(a,b){if(bk.debug("Entering listServerResources method"),!a)return bk.warn(`Server ${b} not connected`),{resources:[],error:"Server not connected"};try{bk.info(`Listing resources for server ${b}`);let c=(await a.listResources()).resources||[];return bk.verbose("Processed resources:",c),{resources:c}}catch(c){if(c instanceof D.Nh&&-32601===c.code)return bk.debug(`Server ${b} does not support resources/list`),{resources:[]};bk.warn(`Failed to list resources for server ${b}:`,c);let a=c instanceof Error?c.message:"Unknown error";return{resources:[],error:a.includes("Connection timeout")?a:`Failed to list resources: ${a}`}}}async function bm(a,b){if(bk.debug("Entering listServerResourceTemplates method"),!a)return bk.warn(`Server ${b} not connected`),{resourceTemplates:[],error:"Server not connected"};try{return bk.info(`Listing resource templates for server ${b}`),{resourceTemplates:(await a.listResourceTemplates()).resourceTemplates||[]}}catch(c){if(c instanceof D.Nh&&-32601===c.code)return bk.debug(`Server ${b} does not support resources/templates/list`),{resourceTemplates:[]};bk.warn(`Failed to list resource templates for server ${b}:`,c);let a=c instanceof Error?c.message:"Unknown error";return{resourceTemplates:[],error:a.includes("Connection timeout")?a:`Failed to list resource templates: ${a}`}}}async function bn(a,b,c){if(bk.debug("Entering readResource method"),!a)return bk.warn(`Server ${b} not found`),{success:!1,error:`Server ${b} not found`,statusCode:404};try{let d=await (0,E.resolveGlobalVars)(c);bk.info(`Reading resource ${d} from server ${b}`);let e=await a.readResource({uri:d});return{success:!0,data:e}}catch(e){bk.warn(`Failed to read resource ${c} on server ${b}:`,e);let a=e instanceof Error?e.message:"Unknown error",d=500;return e instanceof D.Nh?(a=`Failed to read resource: ${a} (Code: ${e.code})`,-32601===e.code?d=404:-32602===e.code&&(d=400)):a=`Failed to read resource: ${a}`,{success:!1,error:a,statusCode:d}}}let bo=(0,i.h)("backend/services/mcp/prompts");async function bp(a,b){if(bo.debug("Entering listServerPrompts method"),!a)return bo.warn(`Server ${b} not connected`),{prompts:[],error:"Server not connected"};try{return bo.info(`Listing prompts for server ${b}`),{prompts:(await a.listPrompts()).prompts||[]}}catch(c){if(c instanceof D.Nh&&-32601===c.code)return bo.debug(`Server ${b} does not support prompts/list`),{prompts:[]};bo.warn(`Failed to list prompts for server ${b}:`,c);let a=c instanceof Error?c.message:"Unknown error";return{prompts:[],error:a.includes("Connection timeout")?a:`Failed to list prompts: ${a}`}}}async function bq(a,b,c,d){if(bo.debug("Entering getPrompt method"),!a)return bo.warn(`Server ${b} not found`),{success:!1,error:`Server ${b} not found`,statusCode:404};try{let e;if(d&&Object.keys(d).length>0){let a=await (0,E.resolveGlobalVars)(d);e="object"==typeof a&&null!==a?a:void 0}bo.info(`Getting prompt ${c} from server ${b}`);let f=await a.getPrompt({name:c,arguments:e});return{success:!0,data:f}}catch(e){bo.warn(`Failed to get prompt ${c} on server ${b}:`,e);let a=e instanceof Error?e.message:"Unknown error",d=500;return e instanceof D.Nh?(a=`Failed to get prompt: ${a} (Code: ${e.code})`,-32601===e.code?d=404:-32602===e.code&&(d=400)):a=`Failed to get prompt: ${a}`,{success:!1,error:a,statusCode:d}}}var br=c(77598),bs=c(57975),bt=c(33225);class bu extends Error{constructor(a){super(`MCP Skills are unavailable: ${a}`),this.name="McpSkillsUnsupportedError",this.reason=a}}function bv(a,b){if(!b||!a)return;let c=a.getServerCapabilities();return(0,l.zT)(c?.extensions?.[l.ET])}function bw(a,b){if(!b)throw new bu("disabled");if(!a)throw new bu("extension-not-negotiated");let c=bv(a,b);if(!c)throw new bu("extension-not-negotiated");return{client:a,capability:c}}async function bx(a){try{return await a()}catch(a){if(a instanceof D.Nh&&-32601===a.code)throw new bu("method-not-found");throw a}}async function by(a,b,c){let d=bw(a,b);return bx(async()=>await d.client.request({method:"skills/list",params:void 0===c?{}:{cursor:c}},l.lX))}async function bz(a,b,c){let d=bw(a,b),e=(0,l.Bw)(c).normalizedUri;return bx(async()=>{let a=await d.client.request({method:"skills/get",params:{uri:e}},l.Kg);if(a.skill.uri!==e)throw Error("skills/get returned a different skill URI");return a})}async function bA(a,b,c,d){let e=bw(a,b);if(!0!==e.capability.directoryRead)throw new bu("directory-read-not-negotiated");let f=(0,l.sm)(c);return bx(async()=>await e.client.request({method:"resources/directory/read",params:{uri:f,...void 0===d?{}:{cursor:d}}},l.Pd))}async function bB(a,b,c,d){let e=bw(a,b),f=function(a,b){if("dynamic"===a.resources)throw Error("Dynamic MCP Skills cannot be integrity-verified");let c=(0,l.sm)(b),d=a.resources.find(a=>a.uri===c);if(!d)throw Error("Resource is not declared by the held MCP Skill entry");return d}(c,d),g=(await e.client.readResource({uri:f.uri})).contents;if(!Array.isArray(g)||1!==g.length)throw Error("MCP Skill resource read must return exactly one content item");let h=g[0];if(null===h||"object"!=typeof h||Array.isArray(h))throw Error("MCP Skill resource content is malformed");if(void 0!==h.uri&&(0,l.sm)(h.uri)!==f.uri)throw Error("MCP Skill resource read returned a different URI");let i=function(a){let b="string"==typeof a.text;if(b===("string"==typeof a.blob))throw Error("MCP Skill resource must contain exactly one of text or blob");return b?{bytes:Buffer.from(a.text,"utf8"),text:a.text}:{bytes:function(a){if(a.length%4!=0||!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(a))throw Error("MCP Skill resource contains invalid base64");return Buffer.from(a,"base64")}(a.blob),blob:a.blob}}(h);if(i.bytes.byteLength!==f.size)throw Error("MCP Skill resource size verification failed");if(`sha256:${(0,br.createHash)("sha256").update(i.bytes).digest("hex")}`!==f.digest)throw Error("MCP Skill resource digest verification failed");return{uri:f.uri,digest:f.digest,size:f.size,..."string"==typeof h.mimeType?{mimeType:h.mimeType}:{},...i,verified:!0}}async function bC(a,b,c,d){if("dynamic"===d.resources)throw Error("Dynamic MCP Skills cannot be integrity-verified");let e=d.resources,f=Array(e.length),g=0,h=async()=>{for(;;){let c=g;if(g+=1,c>=e.length)return;f[c]=await bB(a,b,d,e[c].uri)}};await Promise.all(Array.from({length:Math.min(4,e.length)},()=>h()));let i=f.find(a=>a.uri===d.uri);if(!i||void 0===i.text)throw Error("MCP Skill SKILL.md must be textual content");return!function(a,b){let c,d=a.replace(/\r\n/g,"\n");if(!d.startsWith("---\n"))throw Error("MCP Skill SKILL.md must start with YAML frontmatter");let e=d.indexOf("\n---",4);if(e<0)throw Error("MCP Skill SKILL.md frontmatter is not terminated");let f=d.slice(4,e);try{c=(0,bt.parse)(f)}catch{throw Error("MCP Skill SKILL.md frontmatter is invalid YAML")}if(null===c||"object"!=typeof c||Array.isArray(c)||!(0,bs.isDeepStrictEqual)(c,b.frontmatter))throw Error("MCP Skill SKILL.md frontmatter does not match its advertised entry")}(i.text,d),{identity:{serverName:c,skillUri:d.uri},protocolRevision:l.v$,entry:d,manifest:i,resources:f,verification:"sha256",trust:"untrusted-external-content"}}var bD=c(77145);let bE=(0,i.h)("backend/services/mcp/runtimeHomeIsolation");async function bF(a,b=process.env){if("stdio"!==a.transport)return!1;let c=function(a){let b=a?.trim().toLowerCase();if(b){if(["1","true","yes","on","isolated"].includes(b))return!0;if(["0","false","no","off","host"].includes(b))return!1}}(b.FLUJO_MCP_RUNTIME_HOME_ISOLATION);if(void 0!==c)return c;if("isolated"===a.runtimeHomeMode)return!0;if("host"===a.runtimeHomeMode)return!1;try{let a=await (0,I.loadItem)(J.Zg.SPEECH_SETTINGS,void 0);return a?.experimental?.mcpRuntimeHomeIsolation===!0}catch(a){return bE.warn("Could not read the workspace MCP runtime-home preference; defaulting to host home",{error:a}),!1}}var bG=c(38004),bH=c(17492),bI=c(72628);function bJ(a){return"stdio"===a.transport&&Z(a.command,a.args??[])}var bK=c(83449);let bL=(0,i.h)("backend/services/mcp/resourceNotifications"),bM=/^[A-Za-z0-9_-]{1,64}$/;function bN(a,b,c,d){let e=d?.conversationId?.trim();if("model"===c&&"create_ticket_for_human"===b&&e&&bM.test(e)&&a?.transport==="stdio"&&(0,_.AW)(a)?.packageId==="@mario.andreschak/mcp-flujo")return e}function bO(a,b){let c=(0,j.getCurrentWorkspace)();if(c===j.DEFAULT_WORKSPACE)return b;let d=global.__mcp_workspace_registries??=new Map,e=d.get(c);e||(e=new Map,d.set(c,e));let f=e.get(a);return f||(f=b instanceof Set?new Set:new Map,e.set(a,f)),f}function bP(a){return{success:!1,error:a.error,statusCode:a.statusCode,errorType:a.errorType}}void 0===global.__mcp_clients&&(global.__mcp_clients=new Map),void 0===global.__mcp_connecting&&(global.__mcp_connecting=new Set),void 0===global.__mcp_starting_up&&(global.__mcp_starting_up=!0),void 0===global.__mcp_active_transports&&(global.__mcp_active_transports=new Map),void 0===global.__mcp_client_generation&&(global.__mcp_client_generation=new Map),void 0===global.__mcp_tool_schema_hash&&(global.__mcp_tool_schema_hash=new Map);let bQ=(0,i.h)("backend/services/mcp/index");function bR(a){let b=a,c=new Set;for(;b&&"object"==typeof b&&!c.has(b);){c.add(b);let a=b.__flujoInnerTransport;if(!a)break;b=a}return b}function bS(a){if("streamable"!==a.transport&&"sse"!==a.transport)return!1;let b=a.headers;return!!b&&Object.entries(b).some(([a,b])=>"authorization"===a.toLowerCase()&&(0,aM.at)(b,a).value.trim().length>0)}class bT{get stderrLogs(){return bO("stderrLogs",this.stderrLogsBase)}get lastConnectionError(){return bO("lastConnectionError",this.lastConnectionErrorBase)}get inFlightConnects(){return bO("inFlightConnects",this.inFlightConnectsBase)}get connectionRetryTimers(){return bO("connectionRetryTimers",this.connectionRetryTimersBase)}get connectionRetryAttempts(){return bO("connectionRetryAttempts",this.connectionRetryAttemptsBase)}get resourceListVersion(){return bO("resourceListVersion",this.resourceListVersionBase)}get pendingResourceUpdates(){return bO("pendingResourceUpdates",this.pendingResourceUpdatesBase)}async clearLegacyInferredOAuthScopesForHeaderAuth(a){try{let b=await this.loadServerConfigs();if(!Array.isArray(b))return;let c=b.findIndex(b=>b.name===a);if(-1===c||"streamable"!==b[c].transport)return;let d=b[c];if(!bS(d)||d.oauthScopes?.length!==1||"read"!==d.oauthScopes[0]||d.oauthClientId||d.oauthClientSecret||d.oauthClientMetadata||d.oauthClientInformation||d.oauthTokens||d.oauthCodeVerifier||d.oauthState||d.authorizationUrl)return;b[c]={...d,oauthScopes:void 0};let e=await (0,m.saveConfig)(new Map(b.map(a=>[a.name,a])));e.success?bQ.info(`Removed stale inferred OAuth scopes from header-authenticated server ${a}`):bQ.warn(`Failed to remove stale inferred OAuth scopes from ${a}: ${e.error}`)}catch(b){bQ.warn(`Failed to clean inferred OAuth scopes for ${a}: ${b instanceof Error?b.message:String(b)}`)}}get clients(){return bO("clients",global.__mcp_clients)}get connectingServers(){return bO("connectingServers",global.__mcp_connecting)}get activeTransports(){return bO("activeTransports",global.__mcp_active_transports)}get clientGenerations(){return bO("clientGenerations",global.__mcp_client_generation)}get toolSchemaHashes(){return bO("toolSchemaHashes",global.__mcp_tool_schema_hash)}static{this.MAX_STDERR_LOG_ENTRIES=200}appendStderrLog(a,b){let c=this.stderrLogs.get(a)||[];c.push(b),c.length>bT.MAX_STDERR_LOG_ENTRIES&&c.splice(0,c.length-bT.MAX_STDERR_LOG_ENTRIES),this.stderrLogs.set(a,c)}deregisterClient(a){this.clients.delete(a),this.activeTransports.delete(a);ay(a);let b=(0,j.getCurrentWorkspace)();for(let c of Array.from(ap.values()))c.workspace===b&&c.serverName===a&&(c.resolveElicitation?.({action:"cancel"}),c.abortController.abort(),c.rejectPrompt(Error("Authorization was cancelled because the MCP connection closed.")),aA(c));(0,aO.HW)(a)}onResourceListChanged(a){let b=this.resourceListVersion.get(a)??0;this.resourceListVersion.set(a,b+1),bQ.debug(`onResourceListChanged: server=${a} version=${b+1}`)}onResourceUpdated(a,b){let c=this.pendingResourceUpdates.get(a)??new Set;c.add(b),this.pendingResourceUpdates.set(a,c),bQ.debug(`onResourceUpdated: server=${a} uri=${b}`)}getResourceListVersion(a){return this.resourceListVersion.get(a)??0}async subscribeToResource(a,b){try{let c=this.getClient(a);if(!c)return;let d=c.getServerCapabilities?.();if(!d?.resources?.subscribe)return;await c.subscribeResource({uri:b}),bQ.debug(`subscribeToResource: server=${a} uri=${b}`)}catch(c){bQ.debug(`subscribeToResource: ignored error for ${a}/${b}:`,c)}}clearRetryTimer(a){let b=this.connectionRetryTimers.get(a);b&&(clearTimeout(b),this.connectionRetryTimers.delete(a),bQ.debug(`Cleared retry timer for server ${a}`))}scheduleConnectionRetry(a,b){this.clearRetryTimer(a);let c=this.connectionRetryAttempts.get(a)||0;if(c>=5){bQ.warn(`Maximum retry attempts (5) reached for server ${a}, stopping retries`),this.connectionRetryAttempts.delete(a);return}let d=Math.min(5e3*Math.pow(2,c),3e5);bQ.info(`Scheduling connection retry for server ${a} in ${d}ms (attempt ${c+1}/5)`);let e=setTimeout((0,j.bindToCurrentWorkspace)(async()=>{bQ.info(`Attempting to reconnect server ${a} (attempt ${c+1}/5)`);let b=await this.getServerConfig(a);if(!b){bQ.info(`Server ${a} configuration not found, stopping retry attempts`),this.connectionRetryAttempts.delete(a);return}if(b.disabled){bQ.info(`Server ${a} is now disabled, stopping retry attempts`),this.connectionRetryAttempts.delete(a);return}let d=this.getClient(a);if(d)try{await d.ping({timeout:5e3}),bQ.info(`Server ${a} is already connected and responsive, cancelling retry`),this.connectionRetryAttempts.delete(a);return}catch(b){bQ.warn(`Server ${a} has a registered client but ping failed (${b instanceof Error?b.message:String(b)}); reconnecting from scratch`)}this.connectionRetryAttempts.set(a,c+1);try{let e=d?await this.forceReconnect(a):await this.connectServer(b);if(e.success)bQ.info(`Successfully reconnected server ${a} after ${c+1} attempts`),this.connectionRetryAttempts.delete(a);else{if(bQ.warn(`Failed to reconnect server ${a}: ${e.error}`),e.requiresAuthentication){bQ.info(`Server ${a} requires authentication, stopping retry attempts`),this.connectionRetryAttempts.delete(a);return}this.scheduleConnectionRetry(a,b)}}catch(c){bQ.error(`Error during retry connection for server ${a}:`,c),this.scheduleConnectionRetry(a,b)}}),d);this.connectionRetryTimers.set(a,e)}isStartingUp(){let a=(0,j.getCurrentWorkspace)();return a===j.DEFAULT_WORKSPACE?!0===global.__mcp_starting_up:global.__mcp_starting_up_by_workspace?.get(a)===!0}setStartingUp(a){let b=(0,j.getCurrentWorkspace)();b===j.DEFAULT_WORKSPACE?global.__mcp_starting_up=a:(global.__mcp_starting_up_by_workspace??=new Map).set(b,a),bQ.info(`Backend startup state set to: ${a?"starting":"complete"}`)}getClientGeneration(a){return this.clientGenerations.get(a)??0}setToolSchemaHash(a,b,c){this.toolSchemaHashes.set(`${a}\0${b}`,c)}getToolSchemaHash(a,b){return this.toolSchemaHashes.get(`${a}\0${b}`)}getClient(a){let b=this.clients.get(a);if(b&&(0,T.wk)(b)){bQ.warn(`getClient: client for ${a} has a closed/aborted connection — evicting it`),this.clients.delete(a);return}return bQ.debug(`getClient: Looking for client: ${a}`,b?"Found":"Not found"),b}async loadServerConfigs(){bQ.debug("loadServerConfigs: Entering method");try{let a=await (0,m.loadServerConfigs)();if(!Array.isArray(a))return bQ.warn("loadServerConfigs: Received non-array response",a),a;return bQ.debug(`loadServerConfigs: Loaded ${a.length} server configs`),a}catch(a){return bQ.warn("loadServerConfigs: Failed to load server configs:",a),{success:!1,error:`Failed to load server configs: ${a instanceof Error?a.message:"Unknown error"}`}}}async getServerConfig(a){bQ.debug(`getServerConfig: Looking up config for server ${a}`);let b=await this.loadServerConfigs();if(!Array.isArray(b))return bQ.warn(`getServerConfig: Failed to load configs for ${a}:`,b.error),null;let c=b.find(b=>b.name===a);return c||(bQ.warn(`getServerConfig: Server ${a} not found in configs`),null)}async isServerDisabled(a){let b=await this.getServerConfig(a);return b?.disabled===!0}async connectServer(a){let b="string"==typeof a?a:a.name;return t(b,async()=>{let c=this.connectServerInternal(a).finally(()=>{this.inFlightConnects.delete(b)});this.inFlightConnects.set(b,c);let d=await c;if(d.success){var e;let c;e=this.configFingerprint(a),c=q(b),c.generation+=1,c.state="warm",c.configFingerprint=e,c.retryAttempts=0,c.lastError=void 0,c.warmSince=Date.now(),c.lastUsedAt=Date.now(),c.generation}else{let a=this.activeTransports.has(b)&&!this.clients.has(b);!function(a,b,c=!1){let d=q(a);d.state="error",d.lastError=b,d.connectFailures=Math.min(d.connectFailures+1,Number.MAX_SAFE_INTEGER),c&&(d.handshakeFailures+=1),d.retryAttempts+=1}(b,d.error??"unknown connection failure",a)}return d})}configFingerprint(a){if("string"!=typeof a)return[a.transport,a.command??"",(a.args??[]).join(" "),a.url??"",a.websocketUrl??"",a.rootPath??"",a.disabled?"disabled":"enabled"].join("\0")}async connectServerInternal(a){let b;if("string"==typeof a){bQ.info(`connectServer: Looking up config for server ${a}`);let c=await this.getServerConfig(a);if(!c)return bQ.warn(`connectServer: Server ${a} not found in configs`),{success:!1,error:`Server configuration for "${a}" not found. The server may have been deleted or not properly configured.`};b=c}else b=a;let c="string"==typeof a?b:await this.getServerConfig(b.name),e=c??b;if((c??b).disabled)return bQ.info(`connectServer: Server ${b.name} is disabled — refusing to create a client/transport`),this.clearRetryTimer(b.name),this.connectionRetryAttempts.delete(b.name),{success:!1,error:`Server '${b.name}' is disabled. Enable it on the MCP page to use it.`};let f=(0,d.A)();bQ.info(`connectServer: Starting connection for server ${b.name} [RequestID: ${f}]`),this.connectingServers.add(b.name);try{this.stderrLogs.set(b.name,[]),b=await aR(b);let a=await a2()&&"websocket"!==b.transport,c=await bF(b),d={enableRuntimeBroker:!0,isolateRuntimeHome:c},e=this.clients.get(b.name);if(e){let{needsNewClient:c,reason:f}=function(a,b,c=!1,d){if(aQ.debug("Entering shouldRecreateClient method"),(0,T.wk)(a))return{needsNewClient:!0,reason:"Existing connection is closed"};if((a.__flujoCapKey??"")!==aP(b))return{needsNewClient:!0,reason:"Client capabilities (sampling/elicitation/MCP Apps/Skills) changed"};let e=!0===a.__flujoBeta,f=c&&"websocket"!==b.transport;if(e!==f)return{needsNewClient:!0,reason:f?"Beta MCP protocol enabled":"Beta MCP protocol disabled"};if(e){let c=a.transport;if(!c||c.__flujoKind!==b.transport)return{needsNewClient:!0,reason:`Transport type changed to ${b.transport}`};if("stdio"===b.transport){if(c.__flujoStdioKey!==aW(b,d?.isolateRuntimeHome===!0))return{needsNewClient:!0,reason:"Connection parameters changed"}}else if(c.__flujoHttpKey!==aX(b))return{needsNewClient:!0,reason:`${b.transport} auth/connection parameters changed`};return{needsNewClient:!1}}if("websocket"===b.transport){if(!(a.transport instanceof M.I))return{needsNewClient:!0,reason:"Transport type changed to websocket"}}else if("streamable"===b.transport){if(!(a.transport instanceof N.j))return{needsNewClient:!0,reason:"Transport type changed to streamable"};let c=a.transport,d=c._url?.toString();if(void 0!==d&&d!==new URL(b.serverUrl).toString())return{needsNewClient:!0,reason:"Streamable server URL changed"};let e=c.__flujoHttpKey;if(!e)return{needsNewClient:!0,reason:"Existing streamable transport has no config key"};if(e!==aX(b))return{needsNewClient:!0,reason:"Streamable auth/connection parameters changed"}}else if("sse"===b.transport){if(!(a.transport instanceof O.A))return{needsNewClient:!0,reason:"Transport type changed to sse"};let c=a.transport,d=c._url?.toString();if(void 0!==d&&d!==new URL(b.serverUrl).toString())return{needsNewClient:!0,reason:"SSE server URL changed"};let e=c.__flujoHttpKey;if(!e)return{needsNewClient:!0,reason:"Existing sse transport has no config key"};if(e!==aX(b))return{needsNewClient:!0,reason:"SSE auth/connection parameters changed"}}else{if(!(a.transport instanceof L.oQ))return{needsNewClient:!0,reason:"Transport type changed to stdio"};if("stdio"!==b.transport)return{needsNewClient:!0,reason:"Transport type changed from stdio"};let c=a.transport.__flujoStdioKey;if(!c)return{needsNewClient:!0,reason:"Existing stdio transport has no config key"};if(c!==aW(b,d?.isolateRuntimeHome===!0))return{needsNewClient:!0,reason:"Connection parameters changed"}}return{needsNewClient:!1}}(e,b,a,d);if(!c)return bQ.info(`connectServer: Server ${b.name} is already connected`),this.lastConnectionError.delete(b.name),this.clearRetryTimer(b.name),this.connectionRetryAttempts.delete(b.name),await this.clearLegacyInferredOAuthScopesForHeaderAuth(b.name),{success:!0};bQ.info(`connectServer: Existing client for ${b.name} is stale (${f}), recreating`),this.deregisterClient(b.name);try{await a_(e,b.name,b)}catch(a){bQ.debug(`connectServer: error closing stale client for ${b.name}: ${a instanceof Error?a.message:String(a)}`)}e=void 0}e=a?a4(b):aY(b);let f=a?a6(b,d):aZ(b,d);if("stdio"===b.transport&&au(e,b.name,a?a7.get(f):void 0),a){let a=e.setNotificationHandler?.bind(e);a&&(a("notifications/resources/list_changed",(0,j.bindToCurrentWorkspace)(()=>{this.onResourceListChanged(b.name)})),a("notifications/resources/updated",(0,j.bindToCurrentWorkspace)(a=>{let c=a?.params?.uri;c&&this.onResourceUpdated(b.name,c)})))}else!function(a,b,c,d){try{a.setNotificationHandler(D.hh,a=>{bL.debug(`resourceListChanged notification received for ${b}`),c(b)})}catch(a){bL.warn(`registerResourceNotificationHandlers: failed to register list_changed for ${b}`,a)}if(d)try{a.setNotificationHandler(D.cL,a=>{let c=a.params?.uri;c&&(bL.debug(`resourceUpdated notification received for ${b} uri=${c}`),d(b,c))})}catch(a){bL.warn(`registerResourceNotificationHandlers: failed to register resource_updated for ${b}`,a)}}(e,b.name,(0,j.bindToCurrentWorkspace)(a=>this.onResourceListChanged(a)),(0,j.bindToCurrentWorkspace)((a,b)=>this.onResourceUpdated(a,b)));let g=bR(f).stderr;if(g&&"function"==typeof g.on){let a=b.name;g.on("data",(0,j.bindToCurrentWorkspace)(b=>{let c=b.toString();bQ.warn(`stderr: [${a}]: ${c}`),this.appendStderrLog(a,c)}))}if(f.onclose=(0,j.bindToCurrentWorkspace)(()=>{this.activeTransports.get(b.name)!==f?bQ.debug(`connectServer: ignoring close event from a stale/deregistered transport for ${b.name}`):(bQ.warn(`connectServer: Connection closed for server ${b.name}`),this.deregisterClient(b.name),this.getServerConfig(b.name).then(a=>{!a||a.disabled?bQ.info(`Server ${b.name} is now disabled, skipping reconnection logic`):(bQ.info(`Connection closed for enabled server ${b.name}, scheduling reconnection`),this.scheduleConnectionRetry(b.name,a))}).catch(a=>{bQ.warn(`Error checking server config for ${b.name} during onclose:`,a)}))}),f.onerror=(0,j.bindToCurrentWorkspace)(a=>{if((0,T.lO)(a))return void bQ.debug(`connectServer: transient SSE stream disconnect for ${b.name} (self-healing, ignored): ${a instanceof Error?a.message:String(a)}`);if(this.activeTransports.get(b.name)!==f)return void bQ.debug(`connectServer: ignoring error event from a stale/deregistered transport for ${b.name}`);if(bQ.error(`connectServer: Transport error for server ${b.name}:`),a instanceof Error){bQ.error(`Error name: ${a.name}`),bQ.error(`Error message: ${a.message}`),bQ.error(`Error stack: ${a.stack}`);let b=a.code;void 0!==b&&bQ.error(`Error code: ${b}`),bQ.error(`Error chain: ${(0,T.jf)(a)}`)}else if(a&&"object"==typeof a){let b=Object.getPrototypeOf(a),c="string"==typeof b?.constructor?.name?b.constructor.name:"Unknown";bQ.error(`Error type: ${typeof a}`),bQ.error(`Error constructor: ${c}`);let d=Object.getOwnPropertyNames(a);d.length>0?(bQ.error(`Error properties: ${d.join(", ")}`),d.forEach(b=>{try{let c=a[b];bQ.error(` ${b}: ${"function"==typeof c?"[Function]":JSON.stringify(c)}`)}catch(a){bQ.error(` ${b}: [Unable to serialize: ${a}]`)}})):bQ.error("Error object has no enumerable properties");try{let b=JSON.stringify(a);bQ.error(`JSON stringified error: ${b}`)}catch(a){bQ.error(`Cannot JSON stringify error: ${a}`)}}else bQ.error(`Error value: ${String(a)} (type: ${typeof a})`);this.appendStderrLog(b.name,`Transport error: ${(0,T.jf)(a)}`),this.deregisterClient(b.name),this.getServerConfig(b.name).then(a=>{!a||a.disabled?bQ.info(`Server ${b.name} is now disabled, skipping reconnection after transport error`):(bQ.info(`Transport error for enabled server ${b.name}, scheduling reconnection`),this.scheduleConnectionRetry(b.name,a))}).catch(a=>{bQ.warn(`Error checking server config for ${b.name} during onerror:`,a)})}),await e.connect(f),"stdio"===b.transport&&a&&a8(f),this.clients.set(b.name,e),this.activeTransports.set(b.name,f),this.clientGenerations.set(b.name,this.getClientGeneration(b.name)+1),aw(e))try{await ax(e,b.name,{force:!0})}catch(a){bQ.warn(`mcp-stdio-oauth readiness probe failed for ${b.name}:`,a)}this.lastConnectionError.delete(b.name),this.clearRetryTimer(b.name),this.connectionRetryAttempts.delete(b.name),await this.clearLegacyInferredOAuthScopesForHeaderAuth(b.name);let h=function(a){if(a3(a))try{return a.getNegotiatedProtocolVersion()}catch{return}}(e);return bQ.info(`connectServer: Successfully connected to ${b.name}`+(h?` (beta SDK, negotiated MCP protocol ${h})`:"")),{success:!0}}catch(j){let a;"stdio"===b.transport&&(0,aO.HW)(b.name),bQ.error(`connectServer: Failed to connect to server ${b.name}:`,j);let c=j instanceof Error?j.message:String(j),d=(0,T.uP)(j),f=(0,T.Ah)(j),g=bS(e);if(f&&!g&&("streamable"===b.transport||"sse"===b.transport)){let c=b.serverUrl;c&&(a=(await (0,bK.n)(c)).oauthCapable)}if(d||a){if(bQ.info(`OAuth authentication error detected for server ${b.name}: ${c}`),"streamable"===b.transport&&a){let a=b;if(!a.oauthScopes||0===a.oauthScopes.length){bQ.info(`Dynamically enabling OAuth for server ${b.name} after capability confirmation`);try{let c={...a,oauthScopes:["read"]},d=await this.loadServerConfigs();if(Array.isArray(d)){let a=d.findIndex(a=>a.name===b.name);-1!==a&&(d[a]=c,await (0,m.saveConfig)(new Map(d.map(a=>[a.name,a]))),bQ.info(`Updated config for ${b.name} to enable OAuth`))}}catch(a){bQ.warn(`Failed to update config for ${b.name} to enable OAuth:`,a)}}}return{success:!1,error:"OAuth authentication failed or tokens have expired. Please re-authenticate.",requiresAuthentication:!0,oauthCapable:!0}}if(f)return{success:!1,error:c,requiresAuthentication:!0,oauthCapable:a};let h=this.stderrLogs.get(b.name)||[],i=(0,T.ox)(j,b,h);return this.lastConnectionError.set(b.name,i),{success:!1,error:i}}finally{this.connectingServers.delete(b.name)}}async testConnection(a,b,c){bQ.info(`testConnection: Testing connection to ${a.name||"(unnamed)"} via ${a.transport} transport`);let d=a=>{try{b?.(a)}catch{}},e=[],f=null,g=null;try{var h;let b,i=a,j=c?.storedName||a.name;if(("streamable"===a.transport||"sse"===a.transport)&&j){let b=await this.loadServerConfigs(),c=Array.isArray(b)?b.find(a=>a.name===j):void 0,d=c?.headers,e=a.headers;i={...a,headers:(0,aM.x0)(e,d)}}let k=await aR(i),l=await a2()&&"websocket"!==k.transport,m={isolateRuntimeHome:await bF(k)};f=l?a4(k):aY(k),g=l?a6(k,m):aZ(k,m),"stdio"===k.transport&&au(f,k.name,l?(h=g,a7.get(h)):void 0);let n=bR(g).stderr;n&&"function"==typeof n.on&&n.on("data",a=>{let b=a.toString();e.push(b),d({type:"stderr",data:b})}),g.onerror=a=>{let b=`Transport error: ${(0,T.jf)(a)}`;e.push(b),d({type:"stderr",data:b+"\n"})},d({type:"status",phase:"spawning",message:"Starting server / opening transport..."});let o=bJ(a)?9e4:15e3,p=bJ(a),q=new Promise((a,c)=>{b=setTimeout(()=>c(Error(`Connection timeout after ${o/1e3}s`+(p?" — the package may still be downloading via npx/uvx. Try running the Test again (the package is cached after the first download), or verify the command and network access.":""))),o)});d({type:"status",phase:"handshaking",message:"Performing MCP handshake..."});try{await Promise.race([f.connect(g),q])}finally{b&&clearTimeout(b)}"stdio"===k.transport&&l&&a8(g),d({type:"status",phase:"listing-tools",message:"Handshake OK — listing tools..."});let r=0;try{let a=await f.listTools();r=Array.isArray(a?.tools)?a.tools.length:0}catch(b){bQ.debug(`testConnection: connected to ${a.name} but listTools failed: ${b instanceof Error?b.message:String(b)}`)}return bQ.info(`testConnection: Successfully connected to ${a.name} (${r} tools)`),d({type:"result",success:!0,data:{toolCount:r}}),{success:!0,data:{toolCount:r}}}catch(g){let b;bQ.warn(`testConnection: Failed to connect to ${a.name}:`,g);let c=(0,T.Ah)(g);if(c&&("streamable"===a.transport||"sse"===a.transport)){let c=a.serverUrl;c&&(b=(await (0,bK.n)(c)).oauthCapable)}let f=(0,T.ox)(g,a,e);return d({type:"result",success:!1,error:f,requiresAuthentication:c,oauthCapable:b}),{success:!1,error:f,requiresAuthentication:c,oauthCapable:b}}finally{if(f)try{await a_(f,a.name,a,{gracePeriodMs:3e3,killEscalationMs:2e3})}catch(b){bQ.debug(`testConnection: error closing test client for ${a.name}: ${b instanceof Error?b.message:String(b)}`)}}}setNodeRoots(a,b,c){for(let d of(0,aa.eS)(a,b,c))this.notifyRootsChanged(d)}notifyRootsChanged(a){let b=this.getClient(a);if(!b)return void bQ.debug(`notifyRootsChanged: ${a} not connected, skipping notification`);try{b.sendRootsListChanged().catch(b=>{bQ.warn(`notifyRootsChanged: failed to notify ${a}:`,b)}),bQ.debug(`notifyRootsChanged: sent roots/list_changed to ${a}`)}catch(b){bQ.warn(`notifyRootsChanged: failed to notify ${a}:`,b)}}notifyAllRootsChanged(){for(let a of this.clients.keys())this.notifyRootsChanged(a)}async disconnectServer(a){bQ.debug(`disconnectServer: Entering method for server ${a}`),this.clearRetryTimer(a),this.connectionRetryAttempts.delete(a);let b=this.getClient(a);if(!b)return bQ.warn(`disconnectServer: Server ${a} not found in clients map`),this.deregisterClient(a),{success:!1,error:`Server ${a} not found`};this.deregisterClient(a);try{let c=await this.getServerConfig(a);return await function(a,b,c){let d=q(a);if(d.teardownPromise)return n.debug(`beginTeardown: folding onto in-flight teardown for ${a} (${b})`),d.teardownPromise;let e=Date.now();d.state="stopping",d.teardownReason=b;let f=(async()=>{d.connectPromise&&await d.connectPromise.catch(()=>void 0);try{let a=await c(d);a&&a.forced&&(d.forcedKills+=1)}catch(c){n.warn(`beginTeardown: close failed for ${a} (${b}): ${c instanceof Error?c.message:String(c)}`)}finally{d.lastTeardownMs=Date.now()-e,d.state="cold",d.warmSince=void 0,d.configFingerprint=void 0,d.teardownPromise=void 0}})();return d.teardownPromise=f,f}(a,"disconnect",async()=>({forced:(await a_(b,a,c||void 0)).forced})),bQ.info(`disconnectServer: Disconnected server ${a}`),{success:!0}}catch(b){return bQ.warn(`disconnectServer: Failed to disconnect server ${a}:`,b),{success:!1,error:`Failed to disconnect server: ${b instanceof Error?b.message:"Unknown error"}`}}}async disconnectAll(a){let b=[],c=[],d=Array.from(new Set(Array.from(this.clients.keys())));for(let e of(bQ.info(`disconnectAll: tearing down ${d.length} MCP server(s) (${a})`),d)){this.clearRetryTimer(e),this.connectionRetryAttempts.delete(e);try{(await this.disconnectServer(e)).success?b.push(e):c.push(e)}catch(a){bQ.warn(`disconnectAll: teardown of ${e} threw: ${a instanceof Error?a.message:String(a)}`),c.push(e)}}for(let[a]of Array.from(this.connectionRetryTimers))this.clearRetryTimer(a),this.connectionRetryAttempts.delete(a);return bQ.info(`disconnectAll: closed=${b.length} failed=${c.length} (${a})`),{closed:b,failed:c}}getLifecycleReport(){let a;return{runtimes:function(a=!1){let b=Date.now();return(a?Array.from(o().values()):s()).map(a=>({server:a.serverName,workspace:a.workspace,state:a.state,generation:a.generation,leases:a.leases,pins:Array.from(a.pins),idleMs:Math.max(0,b-a.lastUsedAt),connectFailures:a.connectFailures,handshakeFailures:a.handshakeFailures,forcedKills:a.forcedKills,lastTeardownMs:a.lastTeardownMs,lastError:a.lastError}))}(),pool:(a=Date.now(),{...x(),idleTtlMs:v(),maxWarmServers:w(),servers:s().map(b=>({server:b.serverName,state:b.state,leases:b.leases,pins:Array.from(b.pins),idleMs:Math.max(0,a-b.lastUsedAt)}))}),liveClients:this.clients.size}}async sweepIdleMcpServers(){return[...await B(this),...await C(this)]}acquireServerLease(a){return z(this,a)}pinServer(a,b){A(a,b)}unpinServer(a,b){r(a)?.pins.delete(b)}async forceReconnect(a){bQ.info(`forceReconnect: Forcing fresh connection for server ${a}`);let b=this.clients.get(a);if(b){this.deregisterClient(a);let c=await this.getServerConfig(a);try{await a_(b,a,c||void 0)}catch(b){bQ.debug(`forceReconnect: error closing stale client for ${a}: ${b instanceof Error?b.message:String(b)}`)}}return this.connectServer(a)}async listServerTools(a,b="model"){if(bQ.debug(`listServerTools: Entering method for server ${a}, audience ${b}`),await this.isServerDisabled(a)){let b=`Server '${a}' is disabled. Enable it on the MCP page to use it.`;return bQ.warn(`listServerTools: ${b}`),{tools:[],error:b}}let c=this.getClient(a);c||bQ.warn(`listServerTools: Client not found for ${a}`);let d=await bi(c,a,b);if(d.error){bQ.warn(`listServerTools: Listing tools for ${a} failed (${d.error}); forcing reconnect and retrying once`);let e=await this.forceReconnect(a);if(!e.success)return bQ.warn(`listServerTools: Reconnect for ${a} failed: ${e.error}`),{tools:[],error:e.error||d.error};c=this.clients.get(a),(d=await bi(c,a,b)).error?bQ.warn(`listServerTools: Retry after reconnect still failed for ${a}:`,d.error):bQ.info(`listServerTools: Recovered after reconnect for ${a}; listed ${d.tools.length} tools`)}else bQ.info(`listServerTools: Listed ${d.tools.length} tools for ${a}`);return d}async getExternalAuthorizationStatus(a,b=!1){return ax(this.getClient(a),a,{force:b})}async prepareExternalAuthorization(a,b,c={}){let d=this.getClient(a);if(!d){let b=await this.forceReconnect(a);if(!b.success)throw Error(b.error||`Could not connect to ${a}.`);d=this.getClient(a)}if(!d)throw Error(`MCP server '${a}' is not connected.`);return aD(d,a,b,c)}confirmExternalAuthorization(a,b){let c=ap.get(at(b));if(!c||c.serverName!==a||!c.prompt)throw Error("The authorization request is no longer active. Start it again.");if(!c.resolveElicitation||c.elicitationResponded)throw Error("The authorization request is no longer awaiting consent. Start it again.");let d=c.resolveElicitation;return c.resolveElicitation=void 0,c.elicitationResponded=!0,d({action:"accept"}),ay(a),c.prompt}declineExternalAuthorization(a,b){let c=ap.get(at(b));if(!c||c.serverName!==a||!c.prompt||!c.resolveElicitation)return!1;let d=c.resolveElicitation;return c.resolveElicitation=void 0,c.elicitationResponded=!0,d({action:"decline"}),ay(a),!0}cancelExternalAuthorization(a,b){return aB(a,b)}async callTool(a,b,d,e,f,g,h,i="host",j,k){if(bQ.debug(`callTool: Entering method for server ${a}, tool ${b}, source ${i}`),await this.isServerDisabled(a)){let b=`Server '${a}' is disabled. Enable it on the MCP page to use it.`;return bQ.warn(`callTool: ${b}`),{success:!1,error:b}}let l=this.getClient(a),m=await this.acquireServerLease(a),n=m.lease;n?l=n.client:l||bQ.warn(`callTool: Lease acquisition for ${a} failed: ${m.error}`);try{let m;if(l&&aw(l))try{let c=await ax(l,a,{force:!0});if(c.blockingAuthorization){let d=c.blockingAuthorization,e=d.message||`${d.label} authorization is required. Open the MCP page to authenticate before running this flow.`;return bQ.warn(`callTool: blocked ${a}/${b}: ${e}`),{success:!1,error:e,errorType:"stdio-oauth-required",statusCode:428,requiresAuthentication:!0}}}catch(c){let b=c instanceof Error?c.message:String(c);return bQ.warn(`callTool: mcp-stdio-oauth readiness check failed for ${a}: ${b}`),{success:!1,error:`Could not verify account readiness for '${a}': ${b}`,errorType:"stdio-oauth-status",statusCode:503}}let n="model"===i&&"create_ticket_for_human"===b&&k?.conversationId?await this.getServerConfig(a):null,o=bN(n,b,i,k),p=o?(m=bN(n,b,i,k))?{...d,conversation_id:m}:d:d,q=await bj(l,a,b,p,e,f,h,i,g,j);if(q.success&&o){let a=function(a){if(!a||"object"!=typeof a)return;let b=a.content;if(Array.isArray(b))for(let a of b){if(!a||"object"!=typeof a||"text"!==a.type)continue;let b=a.text;if("string"==typeof b)try{let a=JSON.parse(b);if(!0===a.created&&"string"==typeof a.id&&bM.test(a.id))return a.id}catch{}}}(q.data);if(a)try{let{ticketService:b}=await c.e(7780).then(c.bind(c,77780));await b.stampPersonaAttributionFromTrustedConversation(a,o)}catch(b){bQ.error(`callTool: Failed to stamp trusted ticket attribution for ${a}`,b)}}return bQ.info(`callTool: Called tool ${b} on ${a}`),q}finally{n?.release()}}async callToolFromApp(a,b,c,d,e,f){let g=await this.checkMcpAppAccess(a);if(g)return g;let h=await this.callTool(a,b,c,d,void 0,void 0,e,"app",f);if("tool-authorization-list"!==h.errorType)return h;bQ.warn(`callToolFromApp: visibility lookup failed for ${a}/${b}; reconnecting and retrying once before dispatch`);let i=await this.forceReconnect(a);return i.success?h=await this.callTool(a,b,c,d,void 0,void 0,e,"app",f):{success:!1,error:i.error||h.error,statusCode:h.statusCode}}async isMcpAppAccessEnabled(a){let b=await this.getServerConfig(a);return b?.disabled!==!0&&b?.enableMcpApps===!0}async checkMcpAppAccess(a){if(await this.isMcpAppAccessEnabled(a))return null;let b=`MCP Apps are not enabled for server '${a}'. Enable them on the MCP page before opening or using this app.`;return bQ.warn(`MCP App access denied: ${b}`),{success:!1,error:b,statusCode:403}}async readResourceFromApp(a,b){let c=await this.checkMcpAppAccess(a);return c||this.readResource(a,b)}async listWithReconnect(a,b,c){if(await this.isServerDisabled(a)){let b=`Server '${a}' is disabled. Enable it on the MCP page to use it.`;return bQ.warn(`listWithReconnect: ${b}`),{...c,error:b}}let d=this.getClient(a);d||bQ.warn(`listWithReconnect: Client not found for ${a}`);let e=await b(d,a);if(!e.error)return e;bQ.warn(`listWithReconnect: Listing for ${a} failed (${e.error}); forcing reconnect and retrying once`);let f=await this.forceReconnect(a);return f.success?(d=this.clients.get(a),(e=await b(d,a)).error?bQ.warn(`listWithReconnect: Retry after reconnect still failed for ${a}:`,e.error):bQ.info(`listWithReconnect: Recovered after reconnect for ${a}`),e):(bQ.warn(`listWithReconnect: Reconnect for ${a} failed: ${f.error}`),{...c,error:f.error||e.error})}async listServerResources(a){return bQ.debug(`listServerResources: Entering method for server ${a}`),this.listWithReconnect(a,bl,{resources:[]})}async listServerResourceTemplates(a){return bQ.debug(`listServerResourceTemplates: Entering method for server ${a}`),this.listWithReconnect(a,bm,{resourceTemplates:[]})}async readResource(a,b){bQ.debug(`readResource: Entering method for server ${a}, uri ${b}`);let c=this.getClient(a);c||bQ.warn(`readResource: Client not found for ${a}`);let d=await bn(c,a,b);return bQ.info(`readResource: Read resource ${b} on ${a}`),d}async prepareMcpSkillsClient(a){let b=await this.getServerConfig(a);if(!b)return{success:!1,error:`MCP server '${a}' was not found.`,statusCode:404};if(b.disabled)return{success:!1,error:`Server '${a}' is disabled. Enable it on the MCP page to use it.`,statusCode:409,errorType:"disabled"};if(!0!==b.enableMcpSkills)return{success:!1,error:`MCP Skills are disabled for server '${a}'.`,statusCode:409,errorType:"skills_disabled"};let c=await this.connectServer(a);if(!c.success)return{success:!1,error:c.error||`Failed to connect to MCP server '${a}'.`,statusCode:c.statusCode||502};let d=this.getClient(a),e=bv(d,!0);return d&&e?{success:!0,data:{client:d,capability:e}}:{success:!1,error:`Server '${a}' does not advertise ${l.ET}.`,statusCode:404,errorType:"skills_unsupported"}}async getServerSkillsCapability(a){let b=await this.prepareMcpSkillsClient(a);return b.success?b.data?.capability:void 0}async listServerSkills(a,b){let c=await this.getServerConfig(a);if(!c||c.disabled||!0!==c.enableMcpSkills)return{resultType:"complete",skills:[],serverName:a,availability:"disabled",...!c?{error:`MCP server '${a}' was not found.`}:{}};let d=await this.prepareMcpSkillsClient(a);if(!d.success||!d.data)return{resultType:"complete",skills:[],serverName:a,availability:"skills_unsupported"===d.errorType?"unsupported":"available",..."skills_unsupported"===d.errorType?{}:{error:d.error}};let e=async a=>by(a,!0,b);try{return{...await e(d.data.client),serverName:a,availability:"available",capability:d.data.capability}}catch(b){if(b instanceof bu)return{resultType:"complete",skills:[],serverName:a,availability:"unsupported"};if((await this.forceReconnect(a)).success){let c=this.getClient(a);try{let b=await e(c),d=bv(c,!0);return{...b,serverName:a,availability:"available",...d?{capability:d}:{}}}catch(a){b=a}}return{resultType:"complete",skills:[],serverName:a,availability:"available",error:b instanceof Error?b.message:"Failed to list MCP Skills."}}}async getServerSkill(a,b){let c=await this.prepareMcpSkillsClient(a);if(!c.success||!c.data)return bP(c);try{return{success:!0,data:await bz(c.data.client,!0,b)}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to get MCP Skill.",statusCode:a instanceof bu?404:502}}}async readServerSkillDirectory(a,b,c){let d=await this.prepareMcpSkillsClient(a);if(!d.success||!d.data)return bP(d);try{return{success:!0,data:await bA(d.data.client,!0,b,c)}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to read MCP Skill directory.",statusCode:a instanceof bu?404:502}}}async readVerifiedSkillResource(a,b,c){let d=await this.prepareMcpSkillsClient(a);if(!d.success||!d.data)return bP(d);let e=await this.getServerSkill(a,b);if(!e.success||!e.data)return bP(e);try{return{success:!0,data:await bB(d.data.client,!0,e.data.skill,c)}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to verify MCP Skill resource.",statusCode:422}}}async loadVerifiedSkill(a,b,c){let d=await this.prepareMcpSkillsClient(a);if(!d.success||!d.data)return bP(d);let e=await this.getServerSkill(a,b);if(!e.success||!e.data)return bP(e);if("dynamic"===e.data.skill.resources)return{success:!1,error:"Dynamic MCP Skills cannot be integrity-verified.",statusCode:422};let f=(0,l.Bw)(e.data.skill.uri).normalizedUri,g=e.data.skill.resources.find(a=>a.uri===f);if(!g)return{success:!1,error:"MCP Skill manifest metadata is missing.",statusCode:422};if(!(0,bD.f9)({conversationId:c,serverName:a,skillUri:f,manifestDigest:g.digest}))return{success:!1,error:"This MCP Skill is not approved for the current conversation and manifest digest.",statusCode:403,errorType:"skills_approval_required"};try{return{success:!0,data:await bC(d.data.client,!0,a,e.data.skill)}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to load MCP Skill.",statusCode:422}}}async listServerPrompts(a){return bQ.debug(`listServerPrompts: Entering method for server ${a}`),this.listWithReconnect(a,bp,{prompts:[]})}async getPrompt(a,b,c){bQ.debug(`getPrompt: Entering method for server ${a}, prompt ${b}`);let d=this.getClient(a);d||bQ.warn(`getPrompt: Client not found for ${a}`);let e=await bq(d,a,b,c);return bQ.info(`getPrompt: Got prompt ${b} on ${a}`),e}async resolveOAuthSecretForSave(a,b){return((0,aM.uh)(a)&&(a=b??""),a)?a.startsWith("${global:")?a:this.encryptSecretForSave(a):""}async encryptSecretForSave(a){if(a.startsWith("encrypted_failed:"))throw Error("MCP credential encryption failed");if(a.startsWith("encrypted:")&&a.length>10)return a;let b=await (0,bG.Rs)(a);if(!b.startsWith("encrypted:")||b.length<=10)throw Error("MCP credential encryption failed");return b}async resolveEnvForSave(a,b){let c={};for(let[d,e]of Object.entries((0,bI.ds)(a))){let a="string"==typeof e?e:e.value,f=b?.[d],g="object"==typeof f&&f.metadata.isSecret;if(!("string"==typeof e?g||(0,bH.xc)(d):e.metadata.isSecret)){c[d]=e;continue}if(!((0,aM.uh)(a)&&(void 0===f||(a="string"==typeof f?f:f.value,(0,aM.uh)(a)))))c[d]={value:!a||(0,aM.T6)(a)?a:await this.encryptSecretForSave(a),metadata:{isSecret:!0}}}return c}async resolveHeadersForSave(a,b){let c={};for(let[d,e]of Object.entries(a||{})){if(!d)continue;let{value:a}=(0,aM.at)(e,d),{isSecret:f}=(0,aM.at)(e,d);if(!f){""!==a&&(c[d]={value:a,metadata:{isSecret:!1}});continue}if((0,aM.uh)(a)){let c=b?.[d];if(void 0===c||(a=(0,aM.at)(c,d).value,(0,aM.uh)(a)))continue}if(a){if((0,aM.T6)(a)){c[d]={value:a,metadata:{isSecret:!0}};continue}c[d]={value:await this.encryptSecretForSave(a),metadata:{isSecret:!0}}}}return c}async ensureManagedServerRootDir(a){try{let b=(a.rootPath||"").trim();if(!b)return;let c=["streamable","sse","websocket"].includes(a.transport),d="stdio"===a.transport&&(a.source?.type==="registry"||a.source?.type==="marketplace");if(!c&&!d)return;let e=h().resolve((0,j.getWorkspaceDataDir)(),b);if(h().dirname(e)===e)return;if(d){let a=h().join((0,j.getWorkspaceDataDir)(),"mcp-servers"),b=h().relative(a,e);if(!b||b.startsWith("..")||h().isAbsolute(b))return}await f().mkdir(e,{recursive:!0}),bQ.debug(`ensureManagedServerRootDir: ensured ${e} for ${a.name}`)}catch(b){bQ.warn(`ensureManagedServerRootDir: could not create root dir for ${a.name}:`,b)}}async updateServerConfig(a,b){bQ.debug(`updateServerConfig: Entering method for server ${a}`);let d=await this.loadServerConfigs();if(!Array.isArray(d))return bQ.warn("updateServerConfig: Failed to load configs:",d.error),d;let e=d.find(b=>b.name===a),f=!!e&&"string"==typeof b.name&&b.name!==a;if(f&&d.some(a=>a.name===b.name))return bQ.warn(`updateServerConfig: Refusing to rename ${a} -> ${b.name}: name already in use`),{success:!1,error:`A server named "${b.name}" already exists`};if(!e&&b.name)bQ.info(`updateServerConfig: Creating new server config for ${b.name}`),e={name:b.name,transport:"stdio",command:"",args:[],env:{},disabled:!1,_buildCommand:"",_installCommand:"",rootPath:""},d.push(e);else if(!e)return bQ.warn(`updateServerConfig: Server ${a} not found`),{success:!1,error:`Server ${a} not found`};b={...b};try{void 0!==b.env&&(b.env=await this.resolveEnvForSave(b.env,e.env));let a=b.oauthClientSecret;if(void 0!==a){let c=e.oauthClientSecret;b.oauthClientSecret=await this.resolveOAuthSecretForSave(a,c)}let c=b.headers;if(void 0!==c){let a=e.headers;b.headers=await this.resolveHeadersForSave(c,a)}}catch{return{success:!1,error:"Failed to encrypt MCP credentials; configuration was not saved"}}let g={...e};g={...e,...b};let h=JSON.stringify(e.roots??[])!==JSON.stringify(g.roots??[])||(e.rootPath??"")!==(g.rootPath??""),i=d.findIndex(b=>b.name===a);-1!==i?d[i]=g:g.name&&d.push(g);let j=await (0,m.saveConfig)(new Map(d.map(a=>[a.name,a])));if(!j.success)return bQ.warn(`updateServerConfig: Failed to save config for ${a}:`,j.error),j;if(await this.ensureManagedServerRootDir(g),f)try{let{flowService:b}=await Promise.resolve().then(c.bind(c,5385)),d=await b.migrateMcpServerReferences(a,g.name);d.success?d.migratedReferences>0&&bQ.info(`updateServerConfig: Migrated ${d.migratedReferences} MCP reference(s) across ${d.migratedFlows} flow(s)`):bQ.warn("updateServerConfig: Server rename succeeded, but some flow references could not be migrated",d)}catch(a){bQ.warn("updateServerConfig: Server rename succeeded, but flow-reference migration failed",a)}return f?(this.clients.has(a)?await this.disconnectServer(a):(this.clearRetryTimer(a),this.connectionRetryAttempts.delete(a)),this.stderrLogs.delete(a),this.lastConnectionError.delete(a),await this.handleConnectionStateChange(g.name,g)):await this.handleConnectionStateChange(a,g),h&&this.notifyRootsChanged(g.name),bQ.info(`updateServerConfig: Successfully updated config for ${a}${f?` (renamed to ${g.name})`:""}`),g}async handleConnectionStateChange(a,b){bQ.debug(`handleConnectionStateChange: Entering method for server ${a}`);let c=!!this.getClient(a),d=!b.disabled;if(c&&!d){bQ.info(`handleConnectionStateChange: Disconnecting disabled server ${a}`);try{await this.disconnectServer(a)}catch(b){bQ.warn(`handleConnectionStateChange: Failed to disconnect server ${a} during update:`,b)}}else!c&&d?(bQ.info(`handleConnectionStateChange: Connecting previously disabled server ${a}`),await this.connectServer(b)):c&&d?(bQ.info(`handleConnectionStateChange: Re-applying config to connected server ${a}`),await this.connectServer(b)):d||(bQ.info(`handleConnectionStateChange: Clearing retry timers for disabled server ${a}`),this.clearRetryTimer(a),this.connectionRetryAttempts.delete(a))}async clearRetryTimersForDisabledServers(){bQ.debug("clearRetryTimersForDisabledServers: Checking for disabled servers with active retry timers");try{let a=await this.loadServerConfigs();if(!Array.isArray(a))return void bQ.warn("clearRetryTimersForDisabledServers: Failed to load server configs");for(let b of a.filter(a=>a.disabled))this.connectionRetryTimers.has(b.name)&&(bQ.info(`clearRetryTimersForDisabledServers: Clearing retry timer for disabled server ${b.name}`),this.clearRetryTimer(b.name),this.connectionRetryAttempts.delete(b.name))}catch(a){bQ.error("clearRetryTimersForDisabledServers: Error clearing retry timers:",a)}}async deleteServerConfig(a){bQ.debug(`deleteServerConfig: Entering method for server ${a}`),this.clients.has(a)&&(bQ.info(`deleteServerConfig: Disconnecting server ${a} before deletion`),await this.disconnectServer(a));let b=await this.loadServerConfigs();if(!Array.isArray(b))return bQ.warn("deleteServerConfig: Failed to load configs:",b.error),b;let c=b.findIndex(b=>b.name===a);if(-1===c)return bQ.warn(`deleteServerConfig: Server ${a} not found in configs`),{success:!1,error:`Server ${a} not found`};b.splice(c,1),bQ.debug(`deleteServerConfig: Saving updated configs after deleting ${a}`);let d=await (0,m.saveConfig)(new Map(b.map(a=>[a.name,a])));return d.success?bQ.info(`deleteServerConfig: Successfully deleted server ${a}`):bQ.warn(`deleteServerConfig: Error saving configs after deleting ${a}:`,d.error),d}async getServerStatus(a){let b,c=await this.getServerConfig(a);if(!c)return bQ.warn(`getServerStatus: Server ${a} not found`),{status:"error",message:`Server ${a} configuration not found. The server may have been deleted or not properly configured.`};if(c.disabled)return bQ.debug(`getServerStatus: Server ${a} is disabled`),{status:"disconnected"};let d=!!this.getClient(a);if("streamable"===c.transport&&!d&&c.oauthScopes&&c.oauthScopes.length>0){if(!c.oauthTokens||!c.oauthTokens.access_token)return bQ.info(`getServerStatus: Server ${a} requires OAuth authentication but has no valid tokens`),{status:"requires_authentication",message:"OAuth authentication required. Click the authenticate button to complete the OAuth flow."};let b=c.oauthTokens.issued_at;if(!c.oauthTokens.refresh_token&&c.oauthTokens.expires_in&&b){let d=c.oauthTokens.expires_in;if(Math.floor(Date.now()/1e3)>=b+d)return bQ.info(`getServerStatus: OAuth tokens for ${a} have expired and no refresh token is available`),{status:"requires_authentication",message:"OAuth tokens have expired. Please re-authenticate."}}}let e=(this.stderrLogs.get(a)||[]).join("\n").trim(),f=this.lastConnectionError.get(a);if(d){let c=this.getClient(a);if(aw(c))try{if((b=await ax(c,a)).blockingAuthorization){let a=b.blockingAuthorization;return{status:"requires_authentication",message:a.message||`${a.label} authorization is required before this server can be used by unattended flows.`,stderrOutput:e||void 0,stdioOAuth:b}}}catch(b){let a=b instanceof Error?b.message:String(b);return{status:"error",message:`Connected, but the mcp-stdio-oauth readiness check failed: ${a}`,stderrOutput:e||void 0}}}if(d||this.getClient(a))return bQ.info(`getServerStatus: Server ${a} is connected`),{status:"connected",stderrOutput:e||void 0,...b?{stdioOAuth:b}:{}};{let b=this.isStartingUp()&&!this.lastConnectionError.has(a);if(this.connectingServers.has(a)||b)return bQ.info(`getServerStatus: Server ${a} is still connecting`),{status:"connecting",message:"Server is starting up. This may take a few moments."};if(e&&(e.includes("OAuth authentication required")||e.includes("invalid_token")))return bQ.info(`getServerStatus: OAuth authentication error detected for ${a}`),{status:"requires_authentication",message:"OAuth authentication required. Please complete the OAuth flow.",stderrOutput:e};let c=e||f;return c?(bQ.info(`getServerStatus: Using ${e?"stderr output":"persisted connection error"} as error message for ${a}`),{status:"error",message:c,stderrOutput:e||void 0}):(bQ.info(`getServerStatus: No specific error details available for ${a}`),{status:"error",message:`Server ${a} is configured but not connected. The server process may have crashed or been terminated.`,stderrOutput:void 0})}}async startEnabledServers(){bQ.info("Starting all enabled servers"),this.setStartingUp(!0);try{await this.clearRetryTimersForDisabledServers();let a=await this.loadServerConfigs();if(!Array.isArray(a))return void bQ.warn("Failed to load server configs, cannot start servers");let b=a.filter(a=>!a.disabled),c=/^(1|true|yes)$/i.test(process.env.FLUJO_MCP_LAZY_START??""),d=b.filter(a=>!0===a.alwaysOn);for(let a of d)A(a.name,"always-on");let e=c?d:b;c?bQ.info(`Lazy MCP start: ${b.length} enabled server(s) discovered, warming only ${d.length} always-on server(s)`):(bQ.info(`Found ${e.length} enabled servers to start`),bQ.debug(`${e}`)),e.forEach(a=>this.connectingServers.add(a.name));let f=Math.max(1,Number(process.env.FLUJO_MCP_BOOT_CONCURRENCY)||2);bQ.info(`Connecting ${e.length} enabled servers with boot concurrency ${f}`),await (0,k.P)(e,f,async a=>{bQ.info(`Starting server: ${a.name}`),await this.connectServer(a).catch(b=>{bQ.error(`Failed to start server ${a.name}:`,b)})})}finally{this.setStartingUp(!1)}}async getAvailableClients(){try{let a=await this.loadServerConfigs();if(!a||"error"in a)return bQ.warn("getAvailableClients: Failed to load server configs:",a?.error),[];return(await Promise.all(a.map(async a=>{try{let b=await this.getServerStatus(a.name);return{name:a.name,status:"string"==typeof b?b:b.status,connected:"string"==typeof b?"connected"===b:"connected"===b.status}}catch(b){return bQ.warn(`getAvailableClients: Error getting status for ${a.name}:`,b),{name:a.name,status:"error",connected:!1}}}))).map(a=>`${a.name} (${a.status})`)}catch(a){return bQ.error("getAvailableClients: Error getting available clients:",a),[]}}constructor(){this.stderrLogsBase=new Map,this.lastConnectionErrorBase=new Map,this.inFlightConnectsBase=new Map,this.connectionRetryTimersBase=new Map,this.connectionRetryAttemptsBase=new Map,this.resourceListVersionBase=new Map,this.pendingResourceUpdatesBase=new Map}}let bU=new bT},21995:(a,b,c)=>{"use strict";c.d(b,{Fv:()=>l,IT:()=>i,NK:()=>m,hF:()=>g,jg:()=>f,ks:()=>d,lM:()=>h,nj:()=>e,pV:()=>k});let d=.75,e={importanceWeight:.25,confidenceWeight:.15,exactContentMatchBonus:4,termHitBonus:1,termCoverageBonus:1.5,lengthNormalisationChars:280,lengthNormalisationFloor:.6,recencyHalfLifeDays:90,recencyFloor:.15,trustWeights:{explicit_user:1.3,verified_tool:1.15,model_inference:1,external_untrusted:.8},coreBonus:2,coreExemptFromDecay:!0,lexicalWeight:.6,semanticWeight:.4},f={enabled:!0,shingleSize:3,nearDuplicateThreshold:.82,comparisonWindow:200,confidenceReinforcementStep:.05,importanceReinforcementStep:.02,maxSourceRefsPerItem:64};function g(a){return a.toLocaleLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}\s_]/gu," ").replace(/\s+/g," ").trim()}function h(a,b=f.shingleSize){let c=new Set;if(a.length<b)return a.length>0&&c.add(a),c;for(let d=0;d<=a.length-b;d++)c.add(a.substring(d,d+b));return c}function i(a,b){if(0===a.size&&0===b.size)return 1;if(0===a.size||0===b.size)return 0;let c=new Set([...a].filter(a=>b.has(a))),d=new Set([...a,...b]);return c.size/d.size}function j(a){return void 0!==a&&Number.isFinite(a)?Math.min(1,Math.max(0,a)):null}function k(a,b,c=d){if(a)return!0;if(!b?.available)return!1;let e=j(b.score),f=Number.isFinite(c)?Math.min(1,Math.max(0,c)):d;return null!==e&&e>=f}function l(a){let{item:b,terms:c,core:d,asOf:f,weights:g=e}=a,h=a.semantic??(void 0===a.semanticScore?void 0:{available:!0,score:a.semanticScore}),i=b.content.toLocaleLowerCase(),k=b.importance*g.importanceWeight+b.confidence*g.confidenceWeight,l=0;for(let a of c)i===a?(k+=g.exactContentMatchBonus,l++):i.includes(a)&&(k+=g.termHitBonus,l++);c.length>0&&(k+=g.termCoverageBonus*(l/c.length));let m=function(a,b,c=e){let d="number"==typeof b?{available:!0,score:b}:b,f=j(d?.score);return d?.available&&null!==f?c.lexicalWeight*a+c.semanticWeight*f:a}(Math.min(1,k/10),h,g)*function(a,b=e){if(a<=b.lengthNormalisationChars)return 1;let c=1/(1+a/b.lengthNormalisationChars);return Math.max(b.lengthNormalisationFloor,c)}(b.content.length,g)*function(a,b=e){return b.trustWeights[a]??b.trustWeights.model_inference}(b.trust,g)*function(a,b,c={}){let d=c.weights??e,f=c.core??!1,g=c.halfLifeDays??d.recencyHalfLifeDays,h=c.floor??d.recencyFloor;return f&&d.coreExemptFromDecay?1:Math.max(h,Math.pow(2,-Math.max(0,(b-a)/864e5)/g))}(b.updatedAt,f,{core:d,weights:g});return d&&(m+=g.coreBonus),m}function m(a,b,c=f){if(!c.enabled)return null;let d=a.filter(a=>"active"===a.status&&a.kind===b.kind&&a.scope===b.scope).sort((a,b)=>b.updatedAt-a.updatedAt||a.id.localeCompare(b.id)).slice(0,c.comparisonWindow),e=h(g(b.content),c.shingleSize),j=null;for(let a of d){let b=i(e,h(g(a.content),c.shingleSize));b>=c.nearDuplicateThreshold&&(null===j||b>j.similarity)&&(j={candidate:a,similarity:b})}return j}Object.freeze({id:"current",ranking:e,dedup:f})},23759:(a,b,c)=>{"use strict";c.d(b,{L9:()=>j,OM:()=>h,SP:()=>g,gg:()=>k});var d=c(66844),e=c(20228);let f=(0,d.h)("backend/flow/execution/handlers/runQuestionTool"),g="question";function h(a){return a===g}let i="Type your own answer";function j(){return{name:g,description:'Ask the user one or more multiple-choice questions and wait for their answer, then CONTINUE working with that answer — use this instead of guessing or ending your turn when you genuinely need the user to decide between options. Provide a list of questions; each has a prompt and a list of options. Set `multiple: true` on a question to let the user pick more than one option (answers come back as a list). `custom` defaults to true and automatically appends a "'+i+'" free-text option — so do NOT add your own "Other"/"Something else" catch-all option. If you want to recommend an option, put it FIRST and suffix its label with " (Recommended)". Only ask when it materially changes what you do next; keep the number of questions and options small.',inputSchema:{type:"object",properties:{questions:{type:"array",description:"The questions to ask the user.",items:{type:"object",properties:{prompt:{type:"string",description:"The question to ask."},options:{type:"array",items:{type:"string"},description:'The options the user can choose from. Do not include an "Other" option.'},multiple:{type:"boolean",description:"Allow selecting more than one option. Defaults to false."},custom:{type:"boolean",description:'Auto-append a free-text "'+i+'" option. Defaults to true.'}},required:["prompt","options"]}}},required:["questions"]}}}async function k(a,b){if(!b.conversationId)return{success:!1,error:"The question tool is not available in this run."};let c=function(a){let b=a?.questions??[];if(!Array.isArray(b)||0===b.length)return{error:'question requires a non-empty "questions" array.'};let c=[];for(let a of b){let b="string"==typeof a.prompt?a.prompt.trim():"";if(!b)return{error:'each question requires a non-empty "prompt".'};let d=Array.isArray(a.options)?a.options.filter(a=>"string"==typeof a&&a.trim().length>0).map(a=>a.trim()):[],e=!0===a.multiple,f=!1!==a.custom,g=[...d];if(f&&!g.includes(i)&&g.push(i),0===g.length)return{error:`question "${b}" needs at least one option.`};c.push({prompt:b,options:g,multiple:e,custom:f})}return{questions:c}}(a);if("error"in c)return{success:!1,error:c.error};let{questions:d}=c;if(b.unattended)return f.info("question tool called in unattended run; returning a tool-error",{conversationId:b.conversationId}),{success:!1,error:"This is an unattended run with no user available to answer questions. Proceed using your best judgement without asking."};let g=crypto.randomUUID();f.info("Suspending for question",{conversationId:b.conversationId,questionId:g,count:d.length}),b.emit?.({type:"run:awaiting_question",node:b.node,questionId:g,questions:d});let h=await (0,e.RZ)(b.conversationId,g,d,b.timeoutMs);if("answer"===h.action){var j;let a,c=(j=h.answers,a=d.map((a,b)=>{let c=j[b]??[];return`"${a.prompt}" = "${c.join(", ")}"`}),`User has answered your questions: ${a.join("; ")}. You can now continue with the user's answers in mind.`);return f.info("question answered",{conversationId:b.conversationId,questionId:g}),{success:!0,data:c}}return"decline"===h.action?(f.info("question declined",{conversationId:b.conversationId,questionId:g}),{success:!0,declined:!0,data:"The user declined to answer your question. Do not ask again; stop and end your turn."}):(f.warn("question timed out",{conversationId:b.conversationId,questionId:g}),{success:!1,error:"No answer was received in time. Proceed without the user's answer."})}},25021:(a,b,c)=>{"use strict";c.d(b,{Y$:()=>k,oI:()=>m,oc:()=>j});var d=c(18963),e=c(92870),f=c(52649);let g=e.DW,h=d.k5(g),i={...f.PS,work_item_list:{name:"work_item_list",description:"Read this Persona's durable goals and tasks, including progress, next actions, dependencies and blocked work. Use this to continue an existing plan instead of creating duplicate tasks.",inputSchema:{type:"object",properties:{statuses:{type:"array",items:{type:"string",enum:["open","in_progress","blocked","completed","cancelled"]}},parent_goal_id:{type:"string",description:"Optionally show only the tasks belonging to this ongoing goal."},limit:{type:"integer",minimum:1,maximum:100,default:50},offset:{type:"integer",minimum:0,default:0,description:"Continue from next_offset when a previous list was truncated."}}}},work_item_create:{name:"work_item_create",description:"Create a durable task. During ongoing-goal work it automatically belongs to that goal and runs when ready; outside an ongoing goal it is saved for assignment. List existing tasks first to avoid duplicates. Run todos remain scratch-scoped unless promoted separately.",inputSchema:{type:"object",properties:{title:{type:"string"},description:{type:"string"},priority:{type:"string",enum:["low","normal","high","urgent"]},dependency_ids:{type:"array",items:{type:"string"}},next_action:{type:"string"},deadline:{type:"number"},parent_goal_id:{type:"string",description:"The owning ongoing goal. Inherited from the current goal Activity when omitted."}},required:["title"]}},work_item_update:{name:"work_item_update",description:"Update a durable Persona WorkItem, including status, priority, dependencies, deadline, and next action.",inputSchema:{type:"object",properties:{work_item_id:{type:"string"},title:{type:"string"},description:{type:["string","null"]},status:{type:"string",enum:["open","in_progress","blocked","completed","cancelled"]},priority:{type:"string",enum:["low","normal","high","urgent"]},dependency_ids:{type:"array",items:{type:"string"}},next_action:{type:["string","null"]},deadline:{type:["number","null"]},expected_updated_at:{type:"number"}},required:["work_item_id"]}},work_item_complete:{name:"work_item_complete",description:"Complete one durable Persona WorkItem after all dependencies are completed.",inputSchema:{type:"object",properties:{work_item_id:{type:"string"},expected_updated_at:{type:"number"}},required:["work_item_id"]}},work_item_promote_todo:{name:"work_item_promote_todo",description:"Explicitly promote one pending/in-progress run todo into a durable Persona WorkItem. The scratch todo is not changed.",inputSchema:{type:"object",properties:{todo_id:{type:"string"},title:{type:"string"},priority:{type:"string",enum:["low","normal","high","urgent"]},next_action:{type:"string"},deadline:{type:"number"}},required:["todo_id"]}},report_activity_outcome:{name:"report_activity_outcome",description:"Before ending this Activity, persist what was actually achieved and verified, remaining work and the next action. Succeeded means this Activity succeeded; set goal_achieved only when the entire ongoing goal's success criteria are met. A plan or draft alone is not evidence of a published result. Reporting does not end the current run.",inputSchema:{type:"object",properties:{resolution:{type:"string",enum:["succeeded","partial","blocked","failed","unknown"]},summary:{type:"string",maxLength:2e3,description:"Verified results with concrete evidence such as artifact paths, source URLs or observed tool results; distinguish completed actions from plans."},next_action:{type:"string",maxLength:2e3,description:"Required when work is unfinished. State the next executable step or the exact human input needed."},blocker_kind:{type:"string",enum:["information","approval","permission","capability","dependency","external","transient","policy","unknown"]},goal_achieved:{type:"boolean",description:"True only when the entire ongoing goal is achieved, all necessary tasks are complete and its success criteria have been verified."},retry_after_ms:{type:"integer",minimum:0,maximum:6048e5,description:"Optional wait before the next attempt, for example when a service is temporarily unavailable or an external result needs time."}},required:["resolution","summary"]}},suggest_improvement:{name:"suggest_improvement",description:"After completing work, propose one reusable instruction-only Behavior improvement when concrete Activity evidence shows it would help future work. The change is validated, shown in Improvements, and follows the user-selected review rule.",inputSchema:{type:"object",properties:{behavior_slot:{type:"string",description:"Behavior slot to improve. Use primary for the main Persona Flow."},rationale:{type:"string",description:"Plain-language explanation of the repeated problem and expected benefit."},instruction:{type:"string",description:"One concise reusable instruction for future work. Do not include credentials, external content, or task-specific facts."}},required:["rationale","instruction"]}}};function j(a){return h.safeParse(a).success}function k(a,b={}){if(!Array.isArray(a))return[];let c=[...new Set(a.filter(a=>"string"==typeof a&&j(a)))];return g.filter(a=>c.includes(a)).map(a=>{let c=structuredClone(i[a]);if("remember"===a&&b.maintenanceMemoryProposal){let a=Array.isArray(c.inputSchema.required)?c.inputSchema.required.filter(a=>"string"==typeof a):[];c.inputSchema.required=[...new Set([...a,"evidence_ids"])],c.description="Submit one evidence-backed candidate memory during post-Activity maintenance. Invalid proposals are rejected without writing and may be corrected and retried."}return c})}function l(a,b){return"string"==typeof a[b]&&a[b].trim()||void 0}async function m(a,b,e){if((0,f.NS)(a))return(0,f.pY)(a,b,e);try{let g=(0,f.Rq)(e),h={executionAuthority:g.executionAuthority},i=[{kind:"activity",id:g.activityId,...e.conversationId?{uri:`flujo://conversation/${e.conversationId}`}:{}}];switch(a){case"work_item_list":{let{queryPersonaWorkItems:a,withPersonaDomainMutation:e}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106)),f=d.ai().int().min(1).max(100).parse(b.limit??50),i=d.ai().int().min(0).max(1e6).parse(b.offset??0),j=await e(g.personaId,h,async({activity:c})=>{if(c?.id!==g.activityId)throw Error("Task access crossed Activity ownership.");return a(g.personaId,{...void 0!==b.statuses?{statuses:b.statuses}:{}})}),k=l(b,"parent_goal_id"),m=k?j.filter(a=>a.parentGoalId===k):j,n=m.length>i+f;return{success:!0,data:{items:m.slice(i,i+f),total:m.length,truncated:n,...n?{next_offset:i+f}:{}}}}case"report_activity_outcome":{let{reportPersonaActivityOutcome:a}=await c.e(9434).then(c.bind(c,19434)),d=await a(g.personaId,g.activityId,{resolution:b.resolution,summary:b.summary,...void 0!==b.next_action?{nextAction:b.next_action}:{},...void 0!==b.blocker_kind?{blockerKind:b.blocker_kind}:{},...void 0!==b.goal_achieved?{goalAchieved:b.goal_achieved}:{},...void 0!==b.retry_after_ms?{retryAfterMs:b.retry_after_ms}:{}},h);return{success:!0,data:{reported:!0,outcome:d}}}case"work_item_create":{let{createPersonaWorkItem:a}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106)),d=await a({personaId:g.personaId,title:l(b,"title")??"",...l(b,"description")?{description:l(b,"description")}:{},...l(b,"priority")?{priority:b.priority}:{},...Array.isArray(b.dependency_ids)?{dependencyIds:b.dependency_ids}:{},...l(b,"next_action")?{nextAction:l(b,"next_action")}:{},..."number"==typeof b.deadline?{deadline:b.deadline}:{},...l(b,"parent_goal_id")?{parentGoalId:l(b,"parent_goal_id")}:{},sourceRefs:i},h);return{success:!0,data:{created:!0,item:d}}}case"work_item_update":{let{updatePersonaWorkItem:a}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106)),d=await a(g.personaId,l(b,"work_item_id")??"",{...l(b,"title")?{title:l(b,"title")}:{},...null===b.description||"string"==typeof b.description?{description:b.description}:{},...l(b,"status")?{status:b.status}:{},...l(b,"priority")?{priority:b.priority}:{},...Array.isArray(b.dependency_ids)?{dependencyIds:b.dependency_ids}:{},...null===b.next_action||"string"==typeof b.next_action?{nextAction:b.next_action}:{},...null===b.deadline||"number"==typeof b.deadline?{deadline:b.deadline}:{},..."number"==typeof b.expected_updated_at?{expectedUpdatedAt:b.expected_updated_at}:{}},h);return{success:!0,data:{updated:!0,item:d}}}case"work_item_complete":{let{updatePersonaWorkItem:a}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106)),d=await a(g.personaId,l(b,"work_item_id")??"",{status:"completed",..."number"==typeof b.expected_updated_at?{expectedUpdatedAt:b.expected_updated_at}:{}},h);return{success:!0,data:{completed:!0,item:d}}}case"work_item_promote_todo":{let{promoteRunTodoToWorkItem:a}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106)),d=await a(g.personaId,{todoId:l(b,"todo_id")??"",...l(b,"title")?{title:l(b,"title")}:{},...l(b,"priority")?{priority:b.priority}:{},...l(b,"next_action")?{nextAction:l(b,"next_action")}:{},..."number"==typeof b.deadline?{deadline:b.deadline}:{}},h);return{success:!0,data:{promoted:!0,item:d}}}case"suggest_improvement":{let{suggestBehaviorInstructionImprovement:a}=await Promise.all([c.e(5481),c.e(4314),c.e(1346),c.e(2611),c.e(9592),c.e(4753),c.e(8927),c.e(6009),c.e(1587),c.e(6239),c.e(1969)]).then(c.bind(c,57106));await g.executionAuthority.assertCurrent();let d=await a({personaId:g.personaId,slotKey:l(b,"behavior_slot")??"primary",rationale:l(b,"rationale")??"",instruction:l(b,"instruction")??"",evidenceRefs:i});return await g.executionAuthority.assertCurrent(),{success:!0,data:{proposed:!0,applied:"activated"===d.status,proposal:d}}}}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Persona tool failed."}}}},26100:(a,b,c)=>{"use strict";c.d(b,{Yp:()=>h,nl:()=>i});var d=c(47304),e=c.n(d);let f=(0,c(66844).h)("backend/execution/flow/pocketflow"),g="default";class h{constructor(){f.debug("BaseNode constructor called"),this.flow_params={},this.successors=new Map}setParams(a,b){f.debug("setParams called with params",{params:a}),f.verbose("setParams input",{params:a,node_params:b}),this.flow_params=a,this.node_params=b,f.debug("setParams finished. parameter counts",{flowParams:Object.keys(this.flow_params).length,nodeParams:Object.keys(this.node_params).length}),f.verbose("setParams result",{flow_params:this.flow_params,node_params:this.node_params})}clone(){f.debug("clone called");let a=this._clone();return f.verbose("_clone result",{newNode:a}),a.flow_params=e()(this.flow_params),f.verbose("Cloned flow_params",{flow_params:a.flow_params}),a.node_params=e()(this.node_params),f.verbose("Cloned node_params",{node_params:a.node_params}),a.successors=new Map(this.successors),f.verbose("Cloned successors",{successors:a.successors}),f.verbose("clone finished"),a}addSuccessor(a,b=g){if(f.verbose(`addSuccessor called with action: ${b}`),this.successors.has(b))throw f.error(`Action ${b} already exists`),Error(`Action ${b} already exists`);this.successors.set(b,a),f.debug("addSuccessor finished. Successors",{successors:this.successors})}getSuccessor(a){if(f.debug(`getSuccessor called with name: ${a}`),!this.successors.has(a))return void f.error(`Successor ${a} not found`);let b=this.successors.get(a).clone();return f.debug("getSuccessor finished. Returning successor",{successor:b}),b}async execWrapper(a,b){f.debug("execWrapper called with prepResult",{prepResult:a}),f.verbose("execWrapper input",{prepResult:a,node_params:b});let c=await this.execCore(a,b);return f.debug("execWrapper finished. Result",{result:c}),f.verbose("execWrapper result",c),c}async run(a){f.debug("run called with sharedState",{sharedState:a}),f.debug("Current flow_params at start of run",{flow_params:this.flow_params}),f.verbose("run input",{sharedState:a,flow_params:this.flow_params,node_params:this.node_params});let b=await this.prep(a,this.node_params);f.verbose("run prepResult",b);let c=await this.execWrapper(b,this.node_params);f.verbose("run execResult",c);let d=await this.post(b,c,a,this.node_params);return f.debug("action",{action:d}),f.debug(`run finished. Returning action: ${d}`),f.verbose("run action result",{action:d,prepResult:b,execResult:c}),{action:d,prepResult:b,execResult:c}}}class i extends h{constructor(a){f.debug("Flow constructor called with start",{start:a}),super(),this.start=a}_clone(){f.debug("Flow _clone called");let a=new i(this.start);return f.debug("Flow _clone finished. Returning",{newFlow:a}),a}async getStartNode(){f.debug("getStartNode called");let a=this.start.clone();return f.debug("getStartNode finished. Returning",{clonedStart:a}),a}async execCore(a){throw f.error("Flow node does not support direct execution"),f.verbose("Flow execCore error",{error:"Flow node does not support direct execution"}),Error("Flow node does not support direct execution")}async prep(a,b){return f.debug("Flow prep called with sharedState",{sharedState:a}),f.verbose("Flow prep input",{sharedState:a,node_params:b}),f.debug("Flow prep finished. Returning empty object"),f.verbose("Flow prep result",{}),{}}async post(a,b,c,d){return f.debug("Flow post called with prepResult, execResult, and sharedState",{prepResult:a,execResult:b,sharedState:c}),f.verbose("Flow post input",{prepResult:a,execResult:b,node_params:d}),f.debug("Flow post finished. Returning DEFAULT_ACTION"),f.verbose("Flow post result",{action:g}),g}}},28051:(a,b,c)=>{"use strict";c.d(b,{R:()=>f,S:()=>e});let d=(0,c(66844).h)("backend/services/mcp/ownerScope");function e(a){let b=a.runId?.trim();if(b)return`run:${b}`;let c=a.conversationId?.trim();if(c)return`conversation:${c}`}async function f(a,b="bash"){if(a)try{let{mcpService:e}=await Promise.resolve().then(c.bind(c,21627));if(!e.getClient(b))return;let f=await e.callTool(b,"release_owner",{},30,void 0,void 0,void 0,"host",a);f.success||d.debug(`releaseRunOwnedBashSessions: release_owner reported ${f.error}`)}catch(b){d.debug(`releaseRunOwnedBashSessions: release for ${a} failed: ${b instanceof Error?b.message:String(b)}`)}}},29567:(a,b,c)=>{"use strict";c.d(b,{EQ:()=>l,EY:()=>g,bP:()=>j,mE:()=>k});var d=c(66844),e=c(77823);let f=(0,d.h)("backend/execution/flow/handlers/summarizingCompaction"),g="[FLUJO conversation summary]",h=["## Objective","## Important Details","## Work State","## Next Move","## Relevant Files"];function i(a){let b=0;try{b=JSON.stringify(a).length}catch{b="string"==typeof a.content?a.content.length:0}return Math.ceil(b/4)}function j(a){let b=0;for(let c of a)b+=i(c);return b}function k(a){return"assistant"===a.role&&"string"==typeof a.content&&a.content.startsWith(g)}async function l(a,b,c){var d;let j,l,m,n=c.now??Date.now,o=c.uuid??(()=>crypto.randomUUID()),p=function(a,b){let c,d={toSummarize:[],leadingSystem:[],preservedSubflow:[],toKeep:a};if(0===a.length)return d;let e=0,f=a.length;for(let c=a.length-1;c>=0&&(e+=i(a[c]),f=c,!(e>=b));c--);if(f<=0&&e<b)return d;for(;f>0;){let b=a[f],c=a[f-1],d="assistant"===c.role&&Array.isArray(c.tool_calls)&&(c.tool_calls?.length??0)>0;if("tool"===b.role||d)f--;else break}let h=a.slice(0,f),j=a.slice(f),l=[],m=[],n=[];for(let a of h){if("system"===a.role){l.push(a);continue}if((a.depth??0)>0){m.push(a);continue}k(a)&&"string"==typeof a.content&&(c=a.content.slice(g.length).trim()),n.push(a)}return{toSummarize:n,leadingSystem:l,preservedSubflow:m,toKeep:j,previousSummary:c}}(a,b.keepTokens);if(0===p.toSummarize.length)return f.debug("compactHistory: nothing old enough to summarize; no-op"),null;let q=b.reusableArtifact;if(q&&1===q.schemaVersion&&q.conversationId===b.conversationId&&q.nodeId===b.nodeId&&q.sourceDigest===b.sourceDigest&&q.projectionDigest===b.projectionDigest&&q.policyVersion===b.policyVersion&&q.modelId===b.modelId&&q.sourceStartId===p.toSummarize[0]?.id&&q.sourceEndId===p.toSummarize.at(-1)?.id&&q.sourceMessageCount===p.toSummarize.length){let a={id:q.artifactId,role:"assistant",content:q.summaryText,timestamp:q.createdAt,...void 0!==b.nodeId?{processNodeId:b.nodeId}:{}};return{wireMessages:[...p.leadingSystem,a,...p.preservedSubflow,...p.toKeep],artifact:q,summarizedMessageIds:p.toSummarize.map(a=>a.id).filter(a=>!!a)}}let r=(d={previousSummary:p.previousSummary},m=h.join("\n"),{system:`You are compacting a long agentic conversation into a compact, loss-minimising anchor the assistant will continue from. Produce ONLY the summary in the exact section structure below — no preamble, no closing remarks, and NEVER mention that the conversation was summarized or compacted.
|
|
14
14
|
|
|
15
15
|
Sections (always output all of them, even if a section is empty):
|
|
16
16
|
${m}
|