aws-runtime-bridge 1.9.117 → 1.9.118
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/routes/instance.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Router as X}from"express";import _ from"axios";import{spawn as x}from"node:child_process";import{createHash as H,timingSafeEqual as V}from"node:crypto";import{fileURLToPath as W}from"node:url";import I from"node:path";import{getBridgeVersion as R,resolveSchedulerBaseUrlFrom as G}from"../config.js";import{validateToken as S,validateTokenOrPanelSession as v}from"../middleware/auth.js";import{getConfiguredConnectionKeys as A,getRegistrationState as J,requestRuntimeAccessTokenRefreshForServer as Y,resolveSchedulerBaseUrlFromToken as Q}from"../services/auto-register.js";import{discoverCcSwitchConfiguredItems as Z,loadCcSwitchSdk as ee}from"../services/cc-switch-sdk.js";import{initInstance as te,syncLegacyStateFromSdk as re}from"../services/instance-init-service.js";import{setAgentFeatures as se,getAgentFeatures as C}from"../services/instance-features.js";import{createBridgeLifecycleOperation as L,deliverPendingBridgeLifecycleNotifications as U,upsertBridgeLifecycleOperation as b}from"../services/lifecycle-state.js";import{appendUpdateLog as p,readUpdateLog as oe}from"../services/update-log.js";import{checkBridgeUpdate as q}from"../utils/npm-version.js";import{loadInstanceState as P,saveInstanceState as O}from"../services/instance-state.js";import{getRuntimeAccessToken as ne}from"../services/runtime-binding.js";import{detectToolStatuses as j,ensureToolsInstalled as ae,SUPPORTED_INSTALLABLE_TOOLS as E,SUPPORTED_UNINSTALLABLE_TOOLS as $,uninstallTools as ie}from"../services/tool-installer.js";import{createLogger as le}from"../utils/logger.js";const n=le("instance"),ce=["acode","claude","opencode","codex"];let T=null;function De(r){T=r}const d=X();function K(r){return String(r||"").trim()||void 0}function D(r){const t=r.get("host");if(t)return`${r.protocol}://${t}`}function F(){const r=I.resolve(I.dirname(W(import.meta.url)),"..","..");return I.join(r,"dist","index.js")}function de(){return new Promise((r,t)=>{const e=x(process.execPath,[F(),"update","--no-kill"],{shell:!1,windowsHide:!0});let s="",o="";e.stdout.on("data",a=>{s+=a.toString("utf8")}),e.stderr.on("data",a=>{o+=a.toString("utf8")}),e.on("error",t),e.on("close",a=>{r({exitCode:a,stdout:s,stderr:o})})})}function M(){const r=x(process.execPath,[F(),"service","restart"],{shell:!1,windowsHide:!0,stdio:["ignore","pipe","pipe"]});r.stdout.on("data",t=>{p(String(t)).catch(()=>{})}),r.stderr.on("data",t=>{p(String(t)).catch(()=>{})})}const N=3e3;async function ue(r){const t={...r,status:"running",message:"Bridge \u66F4\u65B0\u6B63\u5728\u540E\u53F0\u6267\u884C\u3002"};await b(t);try{n.info("[update-bridge] \u6B63\u5728\u540E\u53F0\u6267\u884C awsb update --yes"),await p(`===== Bridge \u66F4\u65B0\u5F00\u59CB\uFF1Av${R()} -> latest\uFF08\u64CD\u4F5C ${r.operationId}\uFF09 =====`);const e=await de();if(e.stdout&&await p(e.stdout),e.stderr&&await p(e.stderr),e.exitCode===0){await p("===== Bridge \u66F4\u65B0\u6210\u529F\uFF0C\u51C6\u5907\u81EA\u52A8\u91CD\u542F ===== ");const s={...t,status:"restarting",message:"Bridge \u66F4\u65B0\u5B8C\u6210\uFF0C\u6B63\u5728\u91CD\u542F..."};await b(s),await U(),n.info("[update-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),M(),setTimeout(()=>{if(process.exitCode=42,T){T("BRIDGE_UPDATE_RESTART",!0).catch(o=>{const a=o;n.error("[update-bridge] graceful shutdown failed:",a),process.exit(42)});return}process.exit(42)},N)}else await p(`===== Bridge \u66F4\u65B0\u5931\u8D25\uFF1A\u9000\u51FA\u7801 ${e.exitCode??"unknown"} =====`),await b({...t,status:"failed",message:`Bridge \u66F4\u65B0\u5931\u8D25\uFF0Cnpm \u9000\u51FA\u7801: ${e.exitCode??"unknown"}`,error:e.stderr||e.stdout}),await U()}catch(e){const s=e;n.error("[update-bridge] background update failed:",s),await p(`===== Bridge \u66F4\u65B0\u5F02\u5E38\uFF1A${s.message} =====`).catch(()=>{}),await b({...t,status:"failed",message:"Bridge \u66F4\u65B0\u5931\u8D25\u3002",error:s.message||"update bridge failed"}),await U()}}async function z(r){const t=await import("node:fs/promises"),e=await import("node:path"),s=await import("node:os"),o=e.join(s.tmpdir(),"agentswork-runtime-bridge",".preserve-sessions");if(r){await t.mkdir(e.dirname(o),{recursive:!0}),await t.writeFile(o,JSON.stringify({preserveSessions:!0,timestamp:new Date().toISOString()}),"utf-8"),n.info(`[prepare-restart] \u5DF2\u521B\u5EFA\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6: ${o}`);return}try{await t.unlink(o),n.info("[prepare-restart] \u5DF2\u5220\u9664\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6")}catch{}}function ge(r){return H("md5").update(r,"utf8").digest("hex")}function fe(r){const t=r.trim().toLowerCase();if(!/^[a-f0-9]{32}$/.test(t))return!1;const e=Buffer.from(t,"hex");return A().map(s=>s.trim()).filter(Boolean).some(s=>{const o=Buffer.from(ge(s),"hex");return o.length===e.length&&V(o,e)})}function pe(r){const e=A().length>0,s=R();return e?fe(r)?{status:200,body:{ok:!0,runtimeBridge:"healthy",version:s,connectionKeyMatched:!0,connectionKeyRequired:!0}}:{status:401,body:{ok:!1,error:"connection_key_mismatch",version:s,connectionKeyMatched:!1,connectionKeyRequired:!0}}:{status:200,body:{ok:!0,runtimeBridge:"healthy",version:s,connectionKeyMatched:!0,connectionKeyRequired:!1}}}function me(r,t){const s=t.trim()||"http://localhost:8080",o=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?(?:\/|$)/i.test(s);return{ok:!1,error:r.message||"scheduler ping failed",failureStage:"scheduler_ping",runtimeBridge:"healthy",schedulerBaseUrl:s,hint:o?"aws-runtime-bridge \u5DF2\u8FDE\u901A\uFF0C\u4F46\u5B83\u56DE\u8FDE\u8C03\u5EA6\u4E2D\u5FC3\u5931\u8D25\u3002\u8BF7\u5728 bridge \u542F\u52A8\u73AF\u5883\u4E2D\u5C06 AWS_RUNTIME_SCHEDULER_BASE_URL \u914D\u7F6E\u4E3A\u8BE5\u5B9E\u4F8B\u53EF\u8BBF\u95EE\u7684\u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740\uFF0C\u4F8B\u5982 http://<server-host>:7380\u3002":"aws-runtime-bridge \u5DF2\u8FDE\u901A\uFF0C\u4F46\u5B83\u56DE\u8FDE\u8C03\u5EA6\u4E2D\u5FC3\u5931\u8D25\u3002\u8BF7\u786E\u8BA4 AWS_RUNTIME_SCHEDULER_BASE_URL \u6307\u5411\u7684\u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740\u53EF\u4ECE bridge \u673A\u5668\u8BBF\u95EE\uFF0C\u5E76\u4E14\u8FD0\u884C\u65F6\u8BBF\u95EE\u4EE4\u724C\u4ECD\u6709\u6548\u3002"}}function he(r){if(typeof r!="object"||r===null)return;const t=Reflect.get(r,"response");if(typeof t!="object"||t===null)return;const e=Reflect.get(t,"status");return typeof e=="number"?e:void 0}async function Se(r,t){try{const e=await _.get(`${r}/api/runtime/ping`,{headers:{"X-Runtime-Token":t}});return{schedulerReachable:e.status>=200&&e.status<300,tokenRefreshed:!1}}catch(e){if(he(e)!==401)throw e;const s=await Y(r);if(!s.success||!s.runtimeAccessToken)throw e;const o=await _.get(`${r}/api/runtime/ping`,{headers:{"X-Runtime-Token":s.runtimeAccessToken}});return{schedulerReachable:o.status>=200&&o.status<300,tokenRefreshed:!0}}}function we(r){return{ok:!1,error:"ambiguous_scheduler_base_url",failureStage:"scheduler_ping",runtimeBridge:"healthy",schedulerBaseUrl:"",autoRegisterTargetUrls:r,hint:"Multiple autoRegisterTargets.serverUrl values were found, so bridge cannot safely infer which scheduler /runtime/ping should call back. Set AWS_RUNTIME_SCHEDULER_BASE_URL explicitly, or use future schedulerId/token-bound multi-scheduler routing."}}function be(r){return Array.from(new Set([...r,...ce].map(t=>String(t||"").trim().toLowerCase()).filter(Boolean)))}function ye(r,t){const e=r.filter(s=>t[s]?.installed);return e.length===0?"":e.map(s=>{const o=t[s],a=o?.error||o?.executable||"command is still available";return`${s}: ${a}`}).join("; ")}function k(r){return Object.fromEntries(Object.entries(r||{}).map(([t,e])=>[t,{installed:!!e?.installed,version:e?.version||null,executable:e?.executable||null,error:e?.error||null}]))}d.get("/check-update",async(r,t)=>{t.json(await q())}),d.get("/update-log",v,async(r,t)=>{try{const e=await oe();t.json({ok:!0,...e})}catch(e){const s=e;n.error("[update-log] Error:",s),t.status(500).json({ok:!1,error:s.message||"read update log failed"})}}),d.get("/healthz",(r,t)=>{t.json({ok:!0,runtimeBridge:"healthy"})}),d.get("/connection-check",(r,t)=>{const e=String(r.header("X-Bridge-Connection-Key-MD5")||""),s=pe(e);t.status(s.status).json(s.body)}),d.get("/ping",S,async(r,t)=>{let e=G(r.header("X-Scheduler-Base-Url"),r.header("X-Bridge-Instance-Id"),r.header("X-Bridge-Instance-Name"));if(e.source==="ambiguous-auto-register-targets"){const o=Q(r.header("X-Runtime-Token"));if(o)e={url:o,source:"token-match",ambiguousTargetUrls:[]};else{const a=r.header("X-Bridge-Instance-Id");if(a){const l=J(),i=Object.entries(l.registrations).find(([,c])=>c===a)?.[0];i&&(e={url:i,source:"instance-id-match",ambiguousTargetUrls:[]})}if(!e.url||e.source==="ambiguous-auto-register-targets"){t.status(400).json(we(e.ambiguousTargetUrls));return}}}const s=e.url;try{const o=ne(s);if(!o){t.status(401).json({ok:!1,error:"runtime_access_token_required"});return}const a=await Se(s,o);t.json({ok:!0,runtimeBridge:"healthy",version:R(),schedulerReachable:a.schedulerReachable,tokenRefreshed:a.tokenRefreshed,schedulerBaseUrl:s,instanceId:e.instanceId,instanceName:e.instanceName})}catch(o){const a=o;t.status(502).json(me(a,s))}}),d.post("/init-instance",S,async(r,t)=>{const{agentId:e,workspacePath:s,skillEnabled:o,mcpEnabled:a,ccSwitchEnabledTools:l,skillPackage:i,skillPackages:c,mcpServers:m}=r.body||{};if(!e||!s){t.status(400).json({error:"agentId and workspacePath are required"});return}try{n.info("[init-instance] Request received",{agentId:String(e),workspacePath:String(s),skillEnabled:o,mcpEnabled:a,ccSwitchEnabledTools:l});const u=await te(e,s,{skillEnabled:o,mcpEnabled:a,ccSwitchEnabledTools:l,skillPackage:i,skillPackages:c,mcpServers:m});n.info("[init-instance] Initialization completed",{agentId:String(e),ok:u.ok,logCount:u.logs?.length||0,enabledTools:u.enabledTools}),t.json(u)}catch(u){const g=u;n.error("[init-instance] Initialization failed",{agentId:String(e),workspacePath:String(s),error:g?.message||String(u),stack:g?.stack||null}),t.status(400).json({error:g?.message||"initialize instance failed"})}}),d.post("/features",S,async(r,t)=>{const{agentId:e,features:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}se(String(e),s),n.info("[instance/features] \u80FD\u529B\u5F00\u5173\u5DF2\u66F4\u65B0",{agentId:String(e),features:C(String(e))}),t.json({ok:!0,agentId:String(e),features:C(String(e))})}),d.post("/cc-switch/state",S,async(r,t)=>{const{agentId:e}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}try{n.info("[cc-switch/state] Request received",{agentId:String(e)});const s=await ee(e),o=await Z(s),l=(await re(e,s)).state,i=be(l.enabledTools||[]);n.info("[cc-switch/state] Detecting SDK statuses",{agentId:String(e),detectionTargets:i});const c=await j(i);n.info("[cc-switch/state] SDK status detection completed",{agentId:String(e),toolStatus:k(c),importedMcpCount:o.mcpServers,importedSkillCount:o.skills}),t.json({ok:!0,agentId:String(e),imported:{mcpServers:o.mcpServers,skills:o.skills},state:{...l,toolStatus:c}})}catch(s){const o=s;n.error("[cc-switch/state] Failed to load state",{agentId:String(e),error:o?.message||String(s),stack:o?.stack||null}),t.status(400).json({error:o?.message||"load state failed"})}}),d.post("/cc-switch/install-tools",S,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const o=Array.isArray(s)?s.map(i=>String(i||"").trim().toLowerCase()).filter(Boolean):[];n.info("[cc-switch/install-tools] Request received",{agentId:String(e),requestedTools:o});const a=new Set(E),l=o.filter(i=>a.has(i));if(n.info("[cc-switch/install-tools] Request normalized",{agentId:String(e),requestedTools:o,installableTools:l,supportedInstallableTools:E}),l.length===0){n.warn("[cc-switch/install-tools] No supported installable tools requested",{agentId:String(e),requestedTools:o}),t.status(400).json({error:`tools must include ${E.join(", ")}`});return}try{const i=await P(e),c=Array.from(new Set([...i.enabledTools||[],...l]));n.info("[cc-switch/install-tools] Starting installer",{agentId:String(e),installableTools:l,previousEnabledTools:i.enabledTools||[],nextEnabledTools:c});const m=await ae(l);n.info("[cc-switch/install-tools] Installer completed",{agentId:String(e),toolStatus:k(m)});const u=await j(c);n.info("[cc-switch/install-tools] Refreshed enabled SDK statuses",{agentId:String(e),refreshedToolStatus:k(u)});const g={...u,...m},h=await O(e,{...i,enabledTools:c,toolStatus:g}),y=new Set(l),w=Object.entries(g).filter(([f])=>y.has(f)).filter(([,f])=>!f.installed).map(([f,B])=>({tool:f,error:B.error||null}));w.length>0&&n.warn("[cc-switch/install-tools] Some SDKs remain unavailable",{agentId:String(e),failedTools:w}),n.info("[cc-switch/install-tools] State saved",{agentId:String(e),enabledTools:h.enabledTools,toolStatus:k(g)}),t.json({ok:w.length===0,agentId:String(e),toolStatus:g,failedTools:w,state:h})}catch(i){const c=i;n.error("[cc-switch/install-tools] Install route failed",{agentId:String(e),requestedTools:o,installableTools:l,error:c?.message||String(i),stack:c?.stack||null}),t.status(400).json({error:c?.message||"install tools failed"})}}),d.post("/cc-switch/uninstall-tools",S,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const o=Array.isArray(s)?s.map(i=>String(i||"").trim().toLowerCase()).filter(Boolean):[],a=new Set($),l=o.filter(i=>a.has(i));if(l.length===0){t.status(400).json({error:`tools must include ${$.join(", ")}`});return}try{const i=await P(e),c=new Set(l),m=(i.enabledTools||[]).filter(B=>!c.has(String(B||"").trim().toLowerCase())),u=await ie(l),h={...await j([...m,...l]),...u},y=ye(l,h),w=y?i.enabledTools||[]:m,f=await O(e,{...i,enabledTools:w,toolStatus:h});if(y){t.status(400).json({ok:!1,agentId:String(e),error:`uninstall incomplete: ${y}`,toolStatus:h,state:f});return}t.json({ok:!0,agentId:String(e),toolStatus:h,state:f})}catch(i){const c=i;t.status(400).json({error:c?.message||"uninstall tools failed"})}}),d.post("/prepare-restart",S,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{};try{n.info(`[prepare-restart] \u6536\u5230\u51C6\u5907\u91CD\u542F\u901A\u77E5\uFF0CpreserveSessions=${e}`),await z(!!e),t.json({ok:!0,preserveSessions:e,message:e?"Bridge will preserve sessions for aws-mcp-server restart":"Bridge will clean up sessions on shutdown"})}catch(s){const o=s;n.error("[prepare-restart] Error:",o),t.status(500).json({error:o.message})}}),d.post("/update-bridge",v,async(r,t)=>{const e=K(r.body?.requestedByUserId);try{if(!e){t.status(400).json({error:"requestedByUserId is required"});return}const s=await q(),o=L({operationType:"update",requestedByUserId:e,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:D(r),status:"accepted",message:"Bridge \u66F4\u65B0\u8BF7\u6C42\u5DF2\u6536\u5230\uFF0C\u5C06\u5728\u540E\u53F0\u6267\u884C\u5E76\u81EA\u52A8\u91CD\u542F\u3002",latestVersion:s.ok&&s.latestVersion||void 0});await b(o),ue(o),t.json({ok:!0,operationId:o.operationId,message:"Bridge \u66F4\u65B0\u5DF2\u5728\u540E\u53F0\u5F00\u59CB\uFF0C\u66F4\u65B0\u5B8C\u6210\u540E\u5C06\u81EA\u52A8\u91CD\u542F\u5B9E\u4F8B Bridge\u3002"})}catch(s){const o=s;n.error("[update-bridge] Error:",o),t.status(500).json({error:o.message||"update bridge failed"})}}),d.post("/restart-bridge",v,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{},s=K(r.body?.requestedByUserId);try{if(!s){t.status(400).json({error:"requestedByUserId is required"});return}n.info(`[restart-bridge] \u6536\u5230\u5B9E\u4F8B Bridge \u91CD\u542F\u8BF7\u6C42\uFF0CpreserveSessions=${e}`);const o=L({operationType:"restart",requestedByUserId:s,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:D(r),status:"accepted",message:"Bridge \u5DF2\u6536\u5230\u91CD\u542F\u8BF7\u6C42\uFF1B\u4E0B\u6B21\u542F\u52A8\u540E\u4F1A\u53D1\u9001\u786E\u8BA4\u901A\u77E5\u3002"});await b(o),await z(!!e),t.json({ok:!0,operationId:o.operationId,preserveSessions:!!e,message:"Bridge \u6B63\u5728\u91CD\u542F\uFF0C\u670D\u52A1\u7BA1\u7406\u5668\u4F1A\u81EA\u52A8\u62C9\u8D77\u5B9E\u4F8B\uFF1B\u4E0B\u6B21\u542F\u52A8\u540E\u4F1A\u901A\u8FC7\u6D88\u606F\u4E2D\u5FC3\u901A\u77E5\u7ED3\u679C\u3002"}),n.info("[restart-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),M(),setTimeout(()=>{if(process.exitCode=42,T){T("PANEL_RESTART",!!e).catch(a=>{const l=a;n.error("[restart-bridge] graceful shutdown failed:",l),process.exit(42)});return}process.exit(42)},N)}catch(o){const a=o;n.error("[restart-bridge] Error:",a),t.status(500).json({error:a.message||"restart bridge failed"})}});export{we as buildAmbiguousSchedulerBaseUrlResponse,pe as buildConnectionCheckResponse,me as buildSchedulerPingFailureResponse,be as buildToolStatusDetectionTargets,ye as buildUninstallFailureMessage,d as instanceRouter,De as setGracefulShutdownFn,k as summarizeToolStatus};
|
|
1
|
+
import{Router as H}from"express";import E from"axios";import{spawn as _}from"node:child_process";import{createHash as W,timingSafeEqual as G}from"node:crypto";import{fileURLToPath as V}from"node:url";import k from"node:path";import{getBridgeVersion as R,resolveSchedulerBaseUrlFrom as J}from"../config.js";import{validateToken as S,validateTokenOrPanelSession as v}from"../middleware/auth.js";import{getConfiguredConnectionKeys as A,getRegistrationState as Y,requestRuntimeAccessTokenRefreshForServer as Q,resolveSchedulerBaseUrlFromToken as Z}from"../services/auto-register.js";import{discoverCcSwitchConfiguredItems as ee,loadCcSwitchSdk as te}from"../services/cc-switch-sdk.js";import{initInstance as re,syncLegacyStateFromSdk as se}from"../services/instance-init-service.js";import{setAgentFeatures as oe,getAgentFeatures as x}from"../services/instance-features.js";import{createBridgeLifecycleOperation as L,deliverPendingBridgeLifecycleNotifications as C,loadLifecycleState as ne,removeBridgeLifecycleOperation as ae,upsertBridgeLifecycleOperation as b}from"../services/lifecycle-state.js";import{appendUpdateLog as p,readUpdateLog as ie}from"../services/update-log.js";import{checkBridgeUpdate as O}from"../utils/npm-version.js";import{loadInstanceState as $,saveInstanceState as P}from"../services/instance-state.js";import{getRuntimeAccessToken as ce}from"../services/runtime-binding.js";import{detectToolStatuses as U,ensureToolsInstalled as le,SUPPORTED_INSTALLABLE_TOOLS as j,SUPPORTED_UNINSTALLABLE_TOOLS as q,uninstallTools as de}from"../services/tool-installer.js";import{createLogger as ue}from"../utils/logger.js";const a=ue("instance"),ge=["acode","claude","opencode","codex"];let I=null;function Xe(r){I=r}const d=H();function D(r){return String(r||"").trim()||void 0}function F(r){const t=r.get("host");if(t)return`${r.protocol}://${t}`}function N(){const r=k.resolve(k.dirname(V(import.meta.url)),"..","..");return k.join(r,"dist","index.js")}function fe(){return new Promise((r,t)=>{const e=_(process.execPath,[N(),"update","--no-kill"],{shell:!1,windowsHide:!0});let s="",o="";e.stdout.on("data",n=>{s+=n.toString("utf8")}),e.stderr.on("data",n=>{o+=n.toString("utf8")}),e.on("error",t),e.on("close",n=>{r({exitCode:n,stdout:s,stderr:o})})})}function K(){const r=_(process.execPath,[N(),"service","restart"],{shell:!1,windowsHide:!0,stdio:["ignore","pipe","pipe"]});r.stdout.on("data",t=>{p(String(t)).catch(()=>{})}),r.stderr.on("data",t=>{p(String(t)).catch(()=>{})})}const M=3e3;async function pe(r){const t={...r,status:"running",message:"Bridge \u66F4\u65B0\u6B63\u5728\u540E\u53F0\u6267\u884C\u3002"};await b(t);try{a.info("[update-bridge] \u6B63\u5728\u540E\u53F0\u6267\u884C awsb update --yes"),await p(`===== Bridge \u66F4\u65B0\u5F00\u59CB\uFF1Av${R()} -> latest\uFF08\u64CD\u4F5C ${r.operationId}\uFF09 =====`);const e=await fe();if(e.stdout&&await p(e.stdout),e.stderr&&await p(e.stderr),e.exitCode===0){await p("===== Bridge \u66F4\u65B0\u6210\u529F\uFF0C\u51C6\u5907\u81EA\u52A8\u91CD\u542F ===== ");const s={...t,status:"restarting",message:"Bridge \u66F4\u65B0\u5B8C\u6210\uFF0C\u6B63\u5728\u91CD\u542F..."};await b(s),a.info("[update-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),K(),setTimeout(()=>{if(process.exitCode=42,I){I("BRIDGE_UPDATE_RESTART",!0).catch(o=>{const n=o;a.error("[update-bridge] graceful shutdown failed:",n),process.exit(42)});return}process.exit(42)},M)}else await p(`===== Bridge \u66F4\u65B0\u5931\u8D25\uFF1A\u9000\u51FA\u7801 ${e.exitCode??"unknown"} =====`),await b({...t,status:"failed",message:`Bridge \u66F4\u65B0\u5931\u8D25\uFF0Cnpm \u9000\u51FA\u7801: ${e.exitCode??"unknown"}`,error:e.stderr||e.stdout}),await C()}catch(e){const s=e;a.error("[update-bridge] background update failed:",s),await p(`===== Bridge \u66F4\u65B0\u5F02\u5E38\uFF1A${s.message} =====`).catch(()=>{}),await b({...t,status:"failed",message:"Bridge \u66F4\u65B0\u5931\u8D25\u3002",error:s.message||"update bridge failed"}),await C()}}async function z(r){const t=await import("node:fs/promises"),e=await import("node:path"),s=await import("node:os"),o=e.join(s.tmpdir(),"agentswork-runtime-bridge",".preserve-sessions");if(r){await t.mkdir(e.dirname(o),{recursive:!0}),await t.writeFile(o,JSON.stringify({preserveSessions:!0,timestamp:new Date().toISOString()}),"utf-8"),a.info(`[prepare-restart] \u5DF2\u521B\u5EFA\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6: ${o}`);return}try{await t.unlink(o),a.info("[prepare-restart] \u5DF2\u5220\u9664\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6")}catch{}}function me(r){return W("md5").update(r,"utf8").digest("hex")}function he(r){const t=r.trim().toLowerCase();if(!/^[a-f0-9]{32}$/.test(t))return!1;const e=Buffer.from(t,"hex");return A().map(s=>s.trim()).filter(Boolean).some(s=>{const o=Buffer.from(me(s),"hex");return o.length===e.length&&G(o,e)})}function Se(r){const e=A().length>0,s=R();return e?he(r)?{status:200,body:{ok:!0,runtimeBridge:"healthy",version:s,connectionKeyMatched:!0,connectionKeyRequired:!0}}:{status:401,body:{ok:!1,error:"connection_key_mismatch",version:s,connectionKeyMatched:!1,connectionKeyRequired:!0}}:{status:200,body:{ok:!0,runtimeBridge:"healthy",version:s,connectionKeyMatched:!0,connectionKeyRequired:!1}}}function we(r,t){const s=t.trim()||"http://localhost:8080",o=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?(?:\/|$)/i.test(s);return{ok:!1,error:r.message||"scheduler ping failed",failureStage:"scheduler_ping",runtimeBridge:"healthy",schedulerBaseUrl:s,hint:o?"aws-runtime-bridge \u5DF2\u8FDE\u901A\uFF0C\u4F46\u5B83\u56DE\u8FDE\u8C03\u5EA6\u4E2D\u5FC3\u5931\u8D25\u3002\u8BF7\u5728 bridge \u542F\u52A8\u73AF\u5883\u4E2D\u5C06 AWS_RUNTIME_SCHEDULER_BASE_URL \u914D\u7F6E\u4E3A\u8BE5\u5B9E\u4F8B\u53EF\u8BBF\u95EE\u7684\u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740\uFF0C\u4F8B\u5982 http://<server-host>:7380\u3002":"aws-runtime-bridge \u5DF2\u8FDE\u901A\uFF0C\u4F46\u5B83\u56DE\u8FDE\u8C03\u5EA6\u4E2D\u5FC3\u5931\u8D25\u3002\u8BF7\u786E\u8BA4 AWS_RUNTIME_SCHEDULER_BASE_URL \u6307\u5411\u7684\u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740\u53EF\u4ECE bridge \u673A\u5668\u8BBF\u95EE\uFF0C\u5E76\u4E14\u8FD0\u884C\u65F6\u8BBF\u95EE\u4EE4\u724C\u4ECD\u6709\u6548\u3002"}}function be(r){if(typeof r!="object"||r===null)return;const t=Reflect.get(r,"response");if(typeof t!="object"||t===null)return;const e=Reflect.get(t,"status");return typeof e=="number"?e:void 0}async function ye(r,t){try{const e=await E.get(`${r}/api/runtime/ping`,{headers:{"X-Runtime-Token":t}});return{schedulerReachable:e.status>=200&&e.status<300,tokenRefreshed:!1}}catch(e){if(be(e)!==401)throw e;const s=await Q(r);if(!s.success||!s.runtimeAccessToken)throw e;const o=await E.get(`${r}/api/runtime/ping`,{headers:{"X-Runtime-Token":s.runtimeAccessToken}});return{schedulerReachable:o.status>=200&&o.status<300,tokenRefreshed:!0}}}function Ie(r){return{ok:!1,error:"ambiguous_scheduler_base_url",failureStage:"scheduler_ping",runtimeBridge:"healthy",schedulerBaseUrl:"",autoRegisterTargetUrls:r,hint:"Multiple autoRegisterTargets.serverUrl values were found, so bridge cannot safely infer which scheduler /runtime/ping should call back. Set AWS_RUNTIME_SCHEDULER_BASE_URL explicitly, or use future schedulerId/token-bound multi-scheduler routing."}}function Be(r){return Array.from(new Set([...r,...ge].map(t=>String(t||"").trim().toLowerCase()).filter(Boolean)))}function Te(r,t){const e=r.filter(s=>t[s]?.installed);return e.length===0?"":e.map(s=>{const o=t[s],n=o?.error||o?.executable||"command is still available";return`${s}: ${n}`}).join("; ")}function B(r){return Object.fromEntries(Object.entries(r||{}).map(([t,e])=>[t,{installed:!!e?.installed,version:e?.version||null,executable:e?.executable||null,error:e?.error||null}]))}d.get("/check-update",async(r,t)=>{t.json(await O())}),d.get("/update-log",v,async(r,t)=>{try{const e=await ie();t.json({ok:!0,...e})}catch(e){const s=e;a.error("[update-log] Error:",s),t.status(500).json({ok:!1,error:s.message||"read update log failed"})}}),d.get("/healthz",(r,t)=>{t.json({ok:!0,runtimeBridge:"healthy"})}),d.get("/connection-check",(r,t)=>{const e=String(r.header("X-Bridge-Connection-Key-MD5")||""),s=Se(e);t.status(s.status).json(s.body)}),d.get("/ping",S,async(r,t)=>{let e=J(r.header("X-Scheduler-Base-Url"),r.header("X-Bridge-Instance-Id"),r.header("X-Bridge-Instance-Name"));if(e.source==="ambiguous-auto-register-targets"){const o=Z(r.header("X-Runtime-Token"));if(o)e={url:o,source:"token-match",ambiguousTargetUrls:[]};else{const n=r.header("X-Bridge-Instance-Id");if(n){const c=Y(),i=Object.entries(c.registrations).find(([,l])=>l===n)?.[0];i&&(e={url:i,source:"instance-id-match",ambiguousTargetUrls:[]})}if(!e.url||e.source==="ambiguous-auto-register-targets"){t.status(400).json(Ie(e.ambiguousTargetUrls));return}}}const s=e.url;try{const o=ce(s);if(!o){t.status(401).json({ok:!1,error:"runtime_access_token_required"});return}const n=await ye(s,o);t.json({ok:!0,runtimeBridge:"healthy",version:R(),schedulerReachable:n.schedulerReachable,tokenRefreshed:n.tokenRefreshed,schedulerBaseUrl:s,instanceId:e.instanceId,instanceName:e.instanceName})}catch(o){const n=o;t.status(502).json(we(n,s))}}),d.post("/init-instance",S,async(r,t)=>{const{agentId:e,workspacePath:s,skillEnabled:o,mcpEnabled:n,ccSwitchEnabledTools:c,skillPackage:i,skillPackages:l,mcpServers:m}=r.body||{};if(!e||!s){t.status(400).json({error:"agentId and workspacePath are required"});return}try{a.info("[init-instance] Request received",{agentId:String(e),workspacePath:String(s),skillEnabled:o,mcpEnabled:n,ccSwitchEnabledTools:c});const u=await re(e,s,{skillEnabled:o,mcpEnabled:n,ccSwitchEnabledTools:c,skillPackage:i,skillPackages:l,mcpServers:m});a.info("[init-instance] Initialization completed",{agentId:String(e),ok:u.ok,logCount:u.logs?.length||0,enabledTools:u.enabledTools}),t.json(u)}catch(u){const g=u;a.error("[init-instance] Initialization failed",{agentId:String(e),workspacePath:String(s),error:g?.message||String(u),stack:g?.stack||null}),t.status(400).json({error:g?.message||"initialize instance failed"})}}),d.post("/features",S,async(r,t)=>{const{agentId:e,features:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}oe(String(e),s),a.info("[instance/features] \u80FD\u529B\u5F00\u5173\u5DF2\u66F4\u65B0",{agentId:String(e),features:x(String(e))}),t.json({ok:!0,agentId:String(e),features:x(String(e))})}),d.post("/cc-switch/state",S,async(r,t)=>{const{agentId:e}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}try{a.info("[cc-switch/state] Request received",{agentId:String(e)});const s=await te(e),o=await ee(s),c=(await se(e,s)).state,i=Be(c.enabledTools||[]);a.info("[cc-switch/state] Detecting SDK statuses",{agentId:String(e),detectionTargets:i});const l=await U(i);a.info("[cc-switch/state] SDK status detection completed",{agentId:String(e),toolStatus:B(l),importedMcpCount:o.mcpServers,importedSkillCount:o.skills}),t.json({ok:!0,agentId:String(e),imported:{mcpServers:o.mcpServers,skills:o.skills},state:{...c,toolStatus:l}})}catch(s){const o=s;a.error("[cc-switch/state] Failed to load state",{agentId:String(e),error:o?.message||String(s),stack:o?.stack||null}),t.status(400).json({error:o?.message||"load state failed"})}}),d.post("/cc-switch/install-tools",S,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const o=Array.isArray(s)?s.map(i=>String(i||"").trim().toLowerCase()).filter(Boolean):[];a.info("[cc-switch/install-tools] Request received",{agentId:String(e),requestedTools:o});const n=new Set(j),c=o.filter(i=>n.has(i));if(a.info("[cc-switch/install-tools] Request normalized",{agentId:String(e),requestedTools:o,installableTools:c,supportedInstallableTools:j}),c.length===0){a.warn("[cc-switch/install-tools] No supported installable tools requested",{agentId:String(e),requestedTools:o}),t.status(400).json({error:`tools must include ${j.join(", ")}`});return}try{const i=await $(e),l=Array.from(new Set([...i.enabledTools||[],...c]));a.info("[cc-switch/install-tools] Starting installer",{agentId:String(e),installableTools:c,previousEnabledTools:i.enabledTools||[],nextEnabledTools:l});const m=await le(c);a.info("[cc-switch/install-tools] Installer completed",{agentId:String(e),toolStatus:B(m)});const u=await U(l);a.info("[cc-switch/install-tools] Refreshed enabled SDK statuses",{agentId:String(e),refreshedToolStatus:B(u)});const g={...u,...m},h=await P(e,{...i,enabledTools:l,toolStatus:g}),y=new Set(c),w=Object.entries(g).filter(([f])=>y.has(f)).filter(([,f])=>!f.installed).map(([f,T])=>({tool:f,error:T.error||null}));w.length>0&&a.warn("[cc-switch/install-tools] Some SDKs remain unavailable",{agentId:String(e),failedTools:w}),a.info("[cc-switch/install-tools] State saved",{agentId:String(e),enabledTools:h.enabledTools,toolStatus:B(g)}),t.json({ok:w.length===0,agentId:String(e),toolStatus:g,failedTools:w,state:h})}catch(i){const l=i;a.error("[cc-switch/install-tools] Install route failed",{agentId:String(e),requestedTools:o,installableTools:c,error:l?.message||String(i),stack:l?.stack||null}),t.status(400).json({error:l?.message||"install tools failed"})}}),d.post("/cc-switch/uninstall-tools",S,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const o=Array.isArray(s)?s.map(i=>String(i||"").trim().toLowerCase()).filter(Boolean):[],n=new Set(q),c=o.filter(i=>n.has(i));if(c.length===0){t.status(400).json({error:`tools must include ${q.join(", ")}`});return}try{const i=await $(e),l=new Set(c),m=(i.enabledTools||[]).filter(T=>!l.has(String(T||"").trim().toLowerCase())),u=await de(c),h={...await U([...m,...c]),...u},y=Te(c,h),w=y?i.enabledTools||[]:m,f=await P(e,{...i,enabledTools:w,toolStatus:h});if(y){t.status(400).json({ok:!1,agentId:String(e),error:`uninstall incomplete: ${y}`,toolStatus:h,state:f});return}t.json({ok:!0,agentId:String(e),toolStatus:h,state:f})}catch(i){const l=i;t.status(400).json({error:l?.message||"uninstall tools failed"})}}),d.post("/prepare-restart",S,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{};try{a.info(`[prepare-restart] \u6536\u5230\u51C6\u5907\u91CD\u542F\u901A\u77E5\uFF0CpreserveSessions=${e}`),await z(!!e),t.json({ok:!0,preserveSessions:e,message:e?"Bridge will preserve sessions for aws-mcp-server restart":"Bridge will clean up sessions on shutdown"})}catch(s){const o=s;a.error("[prepare-restart] Error:",o),t.status(500).json({error:o.message})}});const ke={update:15*60*1e3,restart:5*60*1e3};async function Re(r){try{const t=await ne(),e=Date.now(),s=ke[r],o=[];for(const n of t.operations){if(n.operationType!==r||!["accepted","running","restarting"].includes(n.status))continue;const c=new Date(n.updatedAt).getTime();if(!Number.isNaN(c)&&e-c<=s)return{operationId:n.operationId};o.push(n.operationId)}for(const n of o)try{await ae(n),a.info(`[${r}-bridge] \u5DF2\u6E05\u7406\u8D85\u65F6\u672A\u4EA4\u4ED8\u7684\u9648\u65E7\u64CD\u4F5C: ${n}`)}catch(c){const i=c;a.warn(`[${r}-bridge] \u6E05\u7406\u9648\u65E7\u64CD\u4F5C\u5931\u8D25\uFF0C\u7EE7\u7EED\u653E\u884C: ${n}, ${i.message}`)}return null}catch(t){const e=t;return a.warn(`[${r}-bridge] \u5728\u9014\u64CD\u4F5C\u68C0\u67E5\u5931\u8D25\uFF0C\u653E\u884C\u8BF7\u6C42: ${e.message}`),null}}async function X(r,t,e){const s=await Re(r);return s?(e.status(409).json({error:t,operationId:s.operationId}),!0):!1}d.post("/update-bridge",v,async(r,t)=>{const e=D(r.body?.requestedByUserId);try{if(!e){t.status(400).json({error:"requestedByUserId is required"});return}if(await X("update","\u5B9E\u4F8B Bridge \u66F4\u65B0\u6B63\u5728\u6267\u884C\u4E2D\uFF0C\u8BF7\u52FF\u91CD\u590D\u89E6\u53D1",t))return;const s=await O(),o=L({operationType:"update",requestedByUserId:e,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:F(r),status:"accepted",message:"Bridge \u66F4\u65B0\u8BF7\u6C42\u5DF2\u6536\u5230\uFF0C\u5C06\u5728\u540E\u53F0\u6267\u884C\u5E76\u81EA\u52A8\u91CD\u542F\u3002",latestVersion:s.ok&&s.latestVersion||void 0});await b(o),pe(o),t.json({ok:!0,operationId:o.operationId,message:"Bridge \u66F4\u65B0\u5DF2\u5728\u540E\u53F0\u5F00\u59CB\uFF0C\u66F4\u65B0\u5B8C\u6210\u540E\u5C06\u81EA\u52A8\u91CD\u542F\u5B9E\u4F8B Bridge\u3002"})}catch(s){const o=s;a.error("[update-bridge] Error:",o),t.status(500).json({error:o.message||"update bridge failed"})}}),d.post("/restart-bridge",v,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{},s=D(r.body?.requestedByUserId);try{if(!s){t.status(400).json({error:"requestedByUserId is required"});return}if(await X("restart","\u5B9E\u4F8B Bridge \u6B63\u5728\u91CD\u542F\u4E2D\uFF0C\u8BF7\u7A0D\u5019\u518D\u8BD5",t))return;a.info(`[restart-bridge] \u6536\u5230\u5B9E\u4F8B Bridge \u91CD\u542F\u8BF7\u6C42\uFF0CpreserveSessions=${e}`);const o=L({operationType:"restart",requestedByUserId:s,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:F(r),status:"accepted",message:"Bridge \u5DF2\u6536\u5230\u91CD\u542F\u8BF7\u6C42\uFF1B\u4E0B\u6B21\u542F\u52A8\u540E\u4F1A\u53D1\u9001\u786E\u8BA4\u901A\u77E5\u3002"});await b(o),await z(!!e),t.json({ok:!0,operationId:o.operationId,preserveSessions:!!e,message:"Bridge \u6B63\u5728\u91CD\u542F\uFF0C\u670D\u52A1\u7BA1\u7406\u5668\u4F1A\u81EA\u52A8\u62C9\u8D77\u5B9E\u4F8B\uFF1B\u4E0B\u6B21\u542F\u52A8\u540E\u4F1A\u901A\u8FC7\u6D88\u606F\u4E2D\u5FC3\u901A\u77E5\u7ED3\u679C\u3002"}),a.info("[restart-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),K(),setTimeout(()=>{if(process.exitCode=42,I){I("PANEL_RESTART",!!e).catch(n=>{const c=n;a.error("[restart-bridge] graceful shutdown failed:",c),process.exit(42)});return}process.exit(42)},M)}catch(o){const n=o;a.error("[restart-bridge] Error:",n),t.status(500).json({error:n.message||"restart bridge failed"})}});export{Ie as buildAmbiguousSchedulerBaseUrlResponse,Se as buildConnectionCheckResponse,we as buildSchedulerPingFailureResponse,Be as buildToolStatusDetectionTargets,Te as buildUninstallFailureMessage,d as instanceRouter,Xe as setGracefulShutdownFn,B as summarizeToolStatus};
|
|
2
2
|
|
|
@@ -14,6 +14,10 @@ export interface BridgeLifecycleOperation {
|
|
|
14
14
|
|
|
15
15
|
latestVersion?: string;
|
|
16
16
|
}
|
|
17
|
+
interface BridgeLifecycleState {
|
|
18
|
+
operations: BridgeLifecycleOperation[];
|
|
19
|
+
}
|
|
20
|
+
export declare function loadLifecycleState(): Promise<BridgeLifecycleState>;
|
|
17
21
|
export declare function createBridgeLifecycleOperation(input: {
|
|
18
22
|
operationType: BridgeLifecycleOperationType;
|
|
19
23
|
requestedByUserId: string;
|
|
@@ -27,3 +31,4 @@ export declare function upsertBridgeLifecycleOperation(operation: BridgeLifecycl
|
|
|
27
31
|
export declare function removeBridgeLifecycleOperation(operationId: string): Promise<void>;
|
|
28
32
|
|
|
29
33
|
export declare function deliverPendingBridgeLifecycleNotifications(): Promise<void>;
|
|
34
|
+
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import s from"node:fs/promises";import
|
|
2
|
-
`,{encoding:"utf8",mode:384})}function
|
|
1
|
+
import s from"node:fs/promises";import o from"node:path";import{randomUUID as p}from"node:crypto";import g from"axios";import{getRuntimeHomeDir as y,resolveSchedulerBaseUrlFrom as c}from"../config.js";import{getRuntimeAccessToken as B,loadRuntimeBinding as w,normalizeSchedulerBaseUrl as n}from"./runtime-binding.js";import{createLogger as U}from"../utils/logger.js";const d=U("bridge-lifecycle");function l(){return o.join(y(),".aws-bridge","lifecycle-state.json")}function u(e){return String(e||"").trim()||void 0}async function a(){try{const e=await s.readFile(l(),"utf8"),t=JSON.parse(e);return{operations:Array.isArray(t.operations)?t.operations:[]}}catch{return{operations:[]}}}async function f(e){const t=l();await s.mkdir(o.dirname(t),{recursive:!0}),await s.writeFile(t,`${JSON.stringify(e,null,2)}
|
|
2
|
+
`,{encoding:"utf8",mode:384})}function D(e){const t=new Date().toISOString(),r=n(e.schedulerBaseUrl)||c(void 0).url;return{operationId:p(),operationType:e.operationType,status:e.status||"accepted",requestedByUserId:e.requestedByUserId,requestedAt:t,updatedAt:t,schedulerBaseUrl:r,runtimeBridgeBaseUrl:u(e.runtimeBridgeBaseUrl),message:e.message,latestVersion:u(e.latestVersion)}}async function V(e){const r=(await a()).operations.filter(i=>i.operationId!==e.operationId);r.push({...e,updatedAt:new Date().toISOString()}),await f({operations:r})}async function I(e){const t=await a();await f({operations:t.operations.filter(r=>r.operationId!==e)})}function h(e){return["succeeded","failed","startup-confirmed"].includes(e.status)}async function S(e){const t=n(e.schedulerBaseUrl)||n(w().schedulerBaseUrl)||c(void 0).url,r=B(t);if(!r)throw new Error("runtime access token is missing");await g.post(`${t}/api/runtime/callback/bridge-lifecycle`,{operationId:e.operationId,operationType:e.operationType,status:e.status,requestedByUserId:e.requestedByUserId,message:e.message,error:e.error,runtimeBridgeBaseUrl:e.runtimeBridgeBaseUrl,latestVersion:e.latestVersion},{headers:{"X-Runtime-Token":r}})}function v(e){return e.operationType==="update"&&(e.status==="accepted"||e.status==="running")?{...e,status:"failed",message:"Bridge \u66F4\u65B0\u4E2D\u65AD\uFF0C\u8FDB\u7A0B\u5DF2\u91CD\u542F\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u66F4\u65B0\u3002",error:e.error||"update interrupted by process restart"}:{...e,status:"startup-confirmed",message:e.operationType==="update"?e.latestVersion?`\u66F4\u65B0\u5E76\u91CD\u542F\u5B8C\u6210\uFF0C\u5F53\u524D\u7248\u672C v${e.latestVersion}\u3002`:"\u66F4\u65B0\u5E76\u91CD\u542F\u5B8C\u6210\u3002":"Bridge \u91CD\u542F\u5B8C\u6210\uFF0C\u5B9E\u4F8B\u5DF2\u6062\u590D\u8FD0\u884C\u3002"}}async function $(){const e=await a();for(const t of e.operations){const r=v(t);if(h(r))try{await S(r),await I(t.operationId),d.info(`[bridge-lifecycle] notification delivered: ${t.operationId}`)}catch(i){const m=i;d.warn(`[bridge-lifecycle] notification delivery failed: ${t.operationId}, ${m.message}`)}}}export{D as createBridgeLifecycleOperation,$ as deliverPendingBridgeLifecycleNotifications,a as loadLifecycleState,I as removeBridgeLifecycleOperation,V as upsertBridgeLifecycleOperation};
|
|
3
3
|
|