aws-runtime-bridge 1.9.147 → 1.9.149
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
本文件记录 aws-runtime-bridge 各版本的发布说明,随 npm 包一并分发(package.json
|
|
4
|
+
files 白名单),供调度中心「查看本次更新内容」弹窗按 `## v<version>` 精确切片
|
|
5
|
+
展示。发布新版本时须在仓库中先写好 `## v<version>` 段(prepack-guard 校验缺段
|
|
6
|
+
即阻断发布);Bridge 自更新成功后的运行时追加仅作为包内缺段时的兜底。
|
|
7
|
+
|
|
8
|
+
## v1.9.149
|
|
9
|
+
|
|
10
|
+
_发布日期:2026-09-06_
|
|
11
|
+
|
|
12
|
+
- 项目头像支持裁剪:PNG / JPG / WebP / GIF 位图在选文件或点击现有图标后进入方形裁剪
|
|
13
|
+
(拖动调整位置、滚轮或滑块缩放),以 512×512 输出确认保存;SVG / ICO 等无法用
|
|
14
|
+
canvas 裁剪的格式仍直接按原文上传;favicon 预览复用已下载文件,点击直接进入裁剪,
|
|
15
|
+
避免二次网络下载。
|
|
16
|
+
- Pencil 嵌入式画布跟随 Dashboard 明暗主题:iframe URL 携带 theme 参数,主题切换时
|
|
17
|
+
经 pencil:theme 消息同步画布配色,不再固定白底。
|
|
18
|
+
- 修复浅色主题下消息中心 agent 上下文用量 / 待办 / 子代理按钮的选中态样式:选中项
|
|
19
|
+
不再被浅色覆盖规则盖成深色文字(`:not(--active)` 限定浅色覆盖范围,避开高特异性
|
|
20
|
+
覆盖选中态)。
|
|
21
|
+
- 「限制操作」入口从输入框左侧常驻盾牌图标移回「+」菜单(撤销 v1.9.148 的常驻盾牌,
|
|
22
|
+
并移除权限档位拉取与盾牌着色逻辑,简化输入框布局)。
|
|
23
|
+
- 版本升级 1.9.148 → 1.9.149:Bridge 本包无运行时代码改动,随前端 Pencil / 消息中心
|
|
24
|
+
更新一并发布。
|
|
25
|
+
|
|
26
|
+
## v1.9.148
|
|
27
|
+
|
|
28
|
+
_发布日期:2026-09-06_
|
|
29
|
+
|
|
30
|
+
- Pencil 导出 savePath 不再限制在工作区内:绝对路径(如 D:\exports\hero.svg 或
|
|
31
|
+
用户 Downloads)直接使用,相对路径仍基于工作区根解析——导出交付物可落盘到
|
|
32
|
+
任意位置。
|
|
33
|
+
- Pencil 渲染缓存升级为原始分辨率(最长边 ≤8192 内不缩放,此前 1280),agent
|
|
34
|
+
pencil_export_image 与人工导出拿到原图;导出等待超时 8s→15s;升级规格后对旧
|
|
35
|
+
低分辨率缓存自动补渲一次。
|
|
36
|
+
- Pencil 画板编辑锁:有写权限时默认锁定只读,点击解锁才可编辑;编辑中画布被
|
|
37
|
+
agent 工具/协作端推进版本时自动回锁并加载最新快照,防止基于旧版编辑整份覆盖
|
|
38
|
+
他人写入(脏写);写权限被收回时强制回锁。
|
|
39
|
+
- 输入框新增终端式 ↑/↓ 发送历史回溯(按会话隔离,Esc 退出并恢复进入前的草稿);
|
|
40
|
+
「限制操作」入口从「+」菜单移到输入框左侧盾牌常驻图标,存在授权/禁止档位时
|
|
41
|
+
显示绿色。
|
|
42
|
+
- 修复:侧板拖拽经过 iframe(画布/终端)宽度冻结且无法结束的问题(拖拽期间禁用
|
|
43
|
+
容器内 iframe 鼠标事件,窗口失焦自动结束拖拽);全局设置菜单横向滚动两端留白
|
|
44
|
+
被吞掉的问题;项目头像弹窗标题显示项目名而非 projectId。
|
|
45
|
+
- 更新健壮性:包内 CHANGELOG 缺目标版本段时继续尝试 ~/.aws-bridge 下运行时追加
|
|
46
|
+
的候选文件;更新成功后的发布说明追加改为 await 在重启前完成,版本号优先取 npm
|
|
47
|
+
刚落盘的 package.json。
|
|
48
|
+
- 发布护栏:prepack-guard 校验 CHANGELOG.md 必须含当前版本段(缺段阻断发布),
|
|
49
|
+
verify-pack-contents 将 CHANGELOG.md 列为必需 payload。
|
|
50
|
+
|
|
51
|
+
## v1.9.147
|
|
52
|
+
|
|
53
|
+
_发布日期:2026-09-06_
|
|
54
|
+
|
|
55
|
+
- Pencil 设计画布全栈接入:t_pencil_doc 权威存储(迁移 v1.26.0~v1.26.3)与协作者
|
|
56
|
+
权限、MCP pencil_* 工具(AWS_PENCIL_TOOLS 兜底可见性过滤)。
|
|
57
|
+
- 桌面自动化增强:nuphus-mcp 0.1.12 的 desktop_window_activate 先还原再激活,修复
|
|
58
|
+
托盘/最小化窗口无法激活的问题;新增 som.rs 与 UIA 安全增强。
|
|
59
|
+
- acode 新增 runtime-environment;后台命令/文件/图片工具优化,AcodeSdkAdapter 与
|
|
60
|
+
浏览器池稳定性改进。
|
|
61
|
+
- 修复:CHANGELOG.md 自本版本起随包分发。此前发布说明依赖"执行更新的旧进程"运行
|
|
62
|
+
时追加,旧版 Bridge(≤1.9.145 无此代码)执行更新会导致新版本弹窗无发布说明可
|
|
63
|
+
展示,只能回退安装过程日志。
|
|
64
|
+
|
|
65
|
+
## v1.9.146
|
|
66
|
+
|
|
67
|
+
- 新增「本次更新内容」展示:将更新弹窗从安装过程日志(updates.log)切换为版本
|
|
68
|
+
发布说明(CHANGELOG.md),让用户看到本次版本相对变更的要点,而非 npm 安装
|
|
69
|
+
过程噪声。
|
|
70
|
+
- 更新成功重启后,由 Bridge 自动在 CHANGELOG.md 顶部追加当前版本段。
|
|
71
|
+
- 当目标版本未找到发布说明时,弹窗自动回退展示 updates.log(安装过程日志)并
|
|
72
|
+
给出提示。
|
|
73
|
+
|
|
74
|
+
<!-- append-new-version-above -->
|
package/dist/routes/instance.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{spawn as A}from"node:child_process";import{createHash as V,timingSafeEqual as W}from"node:crypto";import T from"node:path";import{fileURLToPath as G}from"node:url";import _ from"axios";import{Router as J}from"express";import{adapterRegistry as Q}from"../adapter/index.js";import{getBridgeVersion as I,resolveSchedulerBaseUrlFrom as Y}from"../config.js";import{validateToken as h,validateTokenOrPanelSession as R}from"../middleware/auth.js";import{getConfiguredConnectionKeys as O,getRegistrationState as Z,requestRuntimeAccessTokenRefreshForServer as ee,resolveSchedulerBaseUrlFromToken as te}from"../services/auto-register.js";import{getEffective as v,getOverrides as j}from"../services/capability-config.js";import{appendChangelogSection as re,readChangelog as se}from"../services/changelog.js";import{setAgentFeatures as ne,setAgentCapabilities as oe,getAgentFeatures as x}from"../services/instance-features.js";import{initInstance as ae}from"../services/instance-init-service.js";import{loadInstanceState as U,saveInstanceState as C}from"../services/instance-state.js";import{createBridgeLifecycleOperation as L,deliverPendingBridgeLifecycleNotifications as P,loadLifecycleState as ie,removeBridgeLifecycleOperation as ce,upsertBridgeLifecycleOperation as b}from"../services/lifecycle-state.js";import{mcpDeployManager as de}from"../services/mcp-deploy.js";import{pluginManager as le}from"../services/plugin-manager.js";import{getRuntimeAccessToken as ue}from"../services/runtime-binding.js";import{skillManager as ge}from"../services/skill-manager.js";import{detectToolStatuses as E,ensureToolsInstalled as pe,SUPPORTED_INSTALLABLE_TOOLS as $,SUPPORTED_UNINSTALLABLE_TOOLS as D,uninstallTools as fe}from"../services/tool-installer.js";import{appendUpdateLog as m,readUpdateLog as me}from"../services/update-log.js";import{createLogger as he}from"../utils/logger.js";import{checkBridgeUpdate as N}from"../utils/npm-version.js";const i=he("instance");import{buildToolStatusDetectionTargets as Se}from"./instance-tool-status.js";let B=null;function tt(r){B=r}const g=J();function M(r){return String(r||"").trim()||void 0}function q(r){const t=r.get("host");if(t)return`${r.protocol}://${t}`}function F(){const r=T.resolve(T.dirname(G(import.meta.url)),"..","..");return T.join(r,"dist","index.js")}function ye(){return new Promise((r,t)=>{const e=A(process.execPath,[F(),"update","--no-kill"],{shell:!1,windowsHide:!0});let s="",n="";e.stdout.on("data",o=>{s+=o.toString("utf8")}),e.stderr.on("data",o=>{n+=o.toString("utf8")}),e.on("error",t),e.on("close",o=>{r({exitCode:o,stdout:s,stderr:n})})})}function K(){const r=A(process.execPath,[F(),"service","restart"],{shell:!1,windowsHide:!0,stdio:["ignore","pipe","pipe"]});r.stdout.on("data",t=>{m(String(t)).catch(()=>{})}),r.stderr.on("data",t=>{m(String(t)).catch(()=>{})})}const z=3e3;async function we(r){const t={...r,status:"running",message:"Bridge \u66F4\u65B0\u6B63\u5728\u540E\u53F0\u6267\u884C\u3002"};await b(t);try{i.info("[update-bridge] \u6B63\u5728\u540E\u53F0\u6267\u884C awsb update --yes"),await m(`===== Bridge \u66F4\u65B0\u5F00\u59CB\uFF1Av${I()} -> latest\uFF08\u64CD\u4F5C ${r.operationId}\uFF09 =====`);const e=await ye();if(e.stdout&&await m(e.stdout),e.stderr&&await m(e.stderr),e.exitCode===0){const s=r.latestVersion||I();re(s,`Bridge \u5DF2\u66F4\u65B0\u81F3 ${s}\u3002`).catch(o=>{const a=o;i.warn(`[update-bridge] \u8FFD\u52A0 changelog \u6BB5\u5931\u8D25\uFF08\u5DF2\u5FFD\u7565\uFF09: ${a.message}`)}),await m("===== Bridge \u66F4\u65B0\u6210\u529F\uFF0C\u51C6\u5907\u81EA\u52A8\u91CD\u542F ===== ");const n={...t,status:"restarting",message:"Bridge \u66F4\u65B0\u5B8C\u6210\uFF0C\u6B63\u5728\u91CD\u542F..."};await b(n),i.info("[update-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),K(),setTimeout(()=>{if(process.exitCode=42,B){B("BRIDGE_UPDATE_RESTART",!0).catch(o=>{const a=o;i.error("[update-bridge] graceful shutdown failed:",a),process.exit(42)});return}process.exit(42)},z)}else await m(`===== 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 P()}catch(e){const s=e;i.error("[update-bridge] background update failed:",s),await m(`===== 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 P()}}async function X(r){const t=await import("node:fs/promises"),e=await import("node:path"),s=await import("node:os"),n=e.join(s.tmpdir(),"agentswork-runtime-bridge",".preserve-sessions");if(r){await t.mkdir(e.dirname(n),{recursive:!0}),await t.writeFile(n,JSON.stringify({preserveSessions:!0,timestamp:new Date().toISOString()}),"utf-8"),i.info(`[prepare-restart] \u5DF2\u521B\u5EFA\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6: ${n}`);return}try{await t.unlink(n),i.info("[prepare-restart] \u5DF2\u5220\u9664\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6")}catch{}}function be(r){return V("md5").update(r,"utf8").digest("hex")}function ke(r){const t=r.trim().toLowerCase();if(!/^[a-f0-9]{32}$/.test(t))return!1;const e=Buffer.from(t,"hex");return O().map(s=>s.trim()).filter(Boolean).some(s=>{const n=Buffer.from(be(s),"hex");return n.length===e.length&&W(n,e)})}function Be(r){const e=O().length>0,s=I();return e?ke(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 Ie(r,t){const s=t.trim()||"http://localhost:8080",n=/^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:n?"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 Re(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 Te(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(Re(e)!==401)throw e;const s=await ee(r);if(!s.success||!s.runtimeAccessToken)throw e;const n=await _.get(`${r}/api/runtime/ping`,{headers:{"X-Runtime-Token":s.runtimeAccessToken}});return{schedulerReachable:n.status>=200&&n.status<300,tokenRefreshed:!0}}}function ve(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 je(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}]))}g.get("/check-update",async(r,t)=>{t.json(await N())}),g.get("/update-log",R,async(r,t)=>{try{const e=await me();t.json({ok:!0,...e})}catch(e){const s=e;i.error("[update-log] Error:",s),t.status(500).json({ok:!1,error:s.message||"read update log failed"})}}),g.get("/changelog",R,async(r,t)=>{const e=String(r.query?.version||"").trim();if(!e){t.status(400).json({ok:!1,error:"version is required"});return}try{const s=await se(e);t.json({ok:!0,version:e,...s})}catch(s){const n=s;i.error("[changelog] Error:",n),t.status(500).json({ok:!1,error:n.message||"read changelog failed"})}}),g.get("/healthz",(r,t)=>{t.json({ok:!0,runtimeBridge:"healthy"})}),g.get("/connection-check",(r,t)=>{const e=String(r.header("X-Bridge-Connection-Key-MD5")||""),s=Be(e);t.status(s.status).json(s.body)}),g.get("/ping",h,async(r,t)=>{let e=Y(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 n=te(r.header("X-Runtime-Token"));if(n)e={url:n,source:"token-match",ambiguousTargetUrls:[]};else{const o=r.header("X-Bridge-Instance-Id");if(o){const a=Z(),c=Object.entries(a.registrations).find(([,l])=>l===o)?.[0];c&&(e={url:c,source:"instance-id-match",ambiguousTargetUrls:[]})}if(!e.url||e.source==="ambiguous-auto-register-targets"){t.status(400).json(ve(e.ambiguousTargetUrls));return}}}const s=e.url;try{const n=ue(s);if(!n){t.status(401).json({ok:!1,error:"runtime_access_token_required"});return}const o=await Te(s,n);t.json({ok:!0,runtimeBridge:"healthy",version:I(),schedulerReachable:o.schedulerReachable,tokenRefreshed:o.tokenRefreshed,schedulerBaseUrl:s,instanceId:e.instanceId,instanceName:e.instanceName})}catch(n){const o=n;t.status(502).json(Ie(o,s))}}),g.post("/init-instance",h,async(r,t)=>{const{agentId:e,workspacePath:s,skillEnabled:n,mcpEnabled:o,ccSwitchEnabledTools:a,skillPackage:c,skillPackages:l,pluginPackages:f,mcpServers:S}=r.body||{};if(!e||!s){t.status(400).json({error:"agentId and workspacePath are required"});return}try{i.info("[init-instance] Request received",{agentId:String(e),workspacePath:String(s),skillEnabled:n,mcpEnabled:o,ccSwitchEnabledTools:a});const u=await ae(e,s,{skillEnabled:n,mcpEnabled:o,ccSwitchEnabledTools:a,skillPackage:c,skillPackages:l,pluginPackages:f,mcpServers:S});i.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 p=u;i.error("[init-instance] Initialization failed",{agentId:String(e),workspacePath:String(s),error:p?.message||String(u),stack:p?.stack||null}),t.status(400).json({error:p?.message||"initialize instance failed"})}}),g.post("/features",h,async(r,t)=>{const{agentId:e,features:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}ne(String(e),s),r.body.capabilities!==void 0&&oe(String(e),r.body.capabilities),i.info("[instance/features] \u80FD\u529B\u5F00\u5173\u5DF2\u66F4\u65B0",{agentId:String(e),features:x(String(e))});let n=0;for(const o of Q.getAll())if(typeof o.applyAgentFeatures=="function")try{await o.applyAgentFeatures(String(e)),n+=1}catch(a){i.error("[instance/features] adapter \u70ED\u540C\u6B65\u5931\u8D25",{agentId:String(e),providerId:o.providerId,error:a?.message||String(a)})}t.json({ok:!0,agentId:String(e),features:x(String(e)),hotSyncedAdapters:n})}),g.post("/cc-switch/state",h,async(r,t)=>{const{agentId:e}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}try{i.info("[cc-switch/state] Request received",{agentId:String(e)});const s=await U(e),n=Se(s.enabledTools||[]);i.info("[cc-switch/state] Detecting SDK statuses",{agentId:String(e),detectionTargets:n});const o=await E(n),a=await le.listDeployed(),c=ge.listDeployed(),l=de.listDeployed(),f=j(e,"skills"),S=j(e,"mcp"),u=j(e,"plugins"),p=c.map(d=>({...d,enabled:v(e,"skills",d.skillName),source:f[d.skillName]!==void 0?"agent":"bridge"})),y=l.map(d=>({...d,enabled:v(e,"mcp",d.name),source:S[d.name]!==void 0?"agent":"bridge"})),w=a.map(d=>({...d,enabled:v(e,"plugins",d.pluginName),source:u[d.pluginName]!==void 0?"agent":"bridge"}));i.info("[cc-switch/state] SDK status detection completed",{agentId:String(e),toolStatus:je(o)}),t.json({ok:!0,agentId:String(e),imported:{mcpServers:0,skills:0},deployedPlugins:w,deployedSkills:p,deployedMcp:y,state:{...s,toolStatus:o}})}catch(s){const n=s;i.error("[cc-switch/state] Failed to load state",{agentId:String(e),error:n?.message||String(s),stack:n?.stack||null}),t.status(400).json({error:n?.message||"load state failed"})}}),g.post("/tools/install",h,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const n=Array.isArray(s)?s.map(c=>String(c||"").trim().toLowerCase()).filter(Boolean):[],o=new Set($),a=n.filter(c=>o.has(c));if(a.length===0){t.status(400).json({error:`tools must include ${$.join(", ")}`});return}try{const c=await U(e),l=Array.from(new Set([...c.enabledTools||[],...a])),f=await pe(a),u={...await E(l),...f},p=await C(e,{...c,enabledTools:l,toolStatus:u}),y=new Set(a),w=Object.entries(u).filter(([d])=>y.has(d)).filter(([,d])=>!d.installed).map(([d,k])=>({tool:d,error:k.error||null}));t.json({ok:w.length===0,agentId:String(e),toolStatus:u,failedTools:w,state:p})}catch(c){const l=c;t.status(400).json({error:l?.message||"install tools failed"})}}),g.post("/tools/uninstall",h,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const n=Array.isArray(s)?s.map(c=>String(c||"").trim().toLowerCase()).filter(Boolean):[],o=new Set(D),a=n.filter(c=>o.has(c));if(a.length===0){t.status(400).json({error:`tools must include ${D.join(", ")}`});return}try{const c=await U(e),l=new Set(a),f=(c.enabledTools||[]).filter(k=>!l.has(String(k||"").trim().toLowerCase())),S=await fe(a),p={...await E([...f,...a]),...S},y=a.filter(k=>p[k]?.installed),w=y.length>0?c.enabledTools||[]:f,d=await C(e,{...c,enabledTools:w,toolStatus:p});if(y.length>0){t.status(400).json({ok:!1,agentId:String(e),error:"uninstall incomplete",toolStatus:p,state:d});return}t.json({ok:!0,agentId:String(e),toolStatus:p,state:d})}catch(c){const l=c;t.status(400).json({error:l?.message||"uninstall tools failed"})}}),g.post("/prepare-restart",h,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{};try{i.info(`[prepare-restart] \u6536\u5230\u51C6\u5907\u91CD\u542F\u901A\u77E5\uFF0CpreserveSessions=${e}`),await X(!!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 n=s;i.error("[prepare-restart] Error:",n),t.status(500).json({error:n.message})}});const Ue={update:15*60*1e3,restart:5*60*1e3};async function Ee(r){try{const t=await ie(),e=Date.now(),s=Ue[r],n=[];for(const o of t.operations){if(o.operationType!==r||!["accepted","running","restarting"].includes(o.status))continue;const a=new Date(o.updatedAt).getTime();if(!Number.isNaN(a)&&e-a<=s)return{operationId:o.operationId};n.push(o.operationId)}for(const o of n)try{await ce(o),i.info(`[${r}-bridge] \u5DF2\u6E05\u7406\u8D85\u65F6\u672A\u4EA4\u4ED8\u7684\u9648\u65E7\u64CD\u4F5C: ${o}`)}catch(a){const c=a;i.warn(`[${r}-bridge] \u6E05\u7406\u9648\u65E7\u64CD\u4F5C\u5931\u8D25\uFF0C\u7EE7\u7EED\u653E\u884C: ${o}, ${c.message}`)}return null}catch(t){const e=t;return i.warn(`[${r}-bridge] \u5728\u9014\u64CD\u4F5C\u68C0\u67E5\u5931\u8D25\uFF0C\u653E\u884C\u8BF7\u6C42: ${e.message}`),null}}async function H(r,t,e){const s=await Ee(r);return s?(e.status(409).json({error:t,operationId:s.operationId}),!0):!1}g.post("/update-bridge",R,async(r,t)=>{const e=M(r.body?.requestedByUserId);try{if(!e){t.status(400).json({error:"requestedByUserId is required"});return}if(await H("update","\u5B9E\u4F8B Bridge \u66F4\u65B0\u6B63\u5728\u6267\u884C\u4E2D\uFF0C\u8BF7\u52FF\u91CD\u590D\u89E6\u53D1",t))return;const s=await N(),n=L({operationType:"update",requestedByUserId:e,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:q(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(n),we(n),t.json({ok:!0,operationId:n.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 n=s;i.error("[update-bridge] Error:",n),t.status(500).json({error:n.message||"update bridge failed"})}}),g.post("/restart-bridge",R,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{},s=M(r.body?.requestedByUserId);try{if(!s){t.status(400).json({error:"requestedByUserId is required"});return}if(await H("restart","\u5B9E\u4F8B Bridge \u6B63\u5728\u91CD\u542F\u4E2D\uFF0C\u8BF7\u7A0D\u5019\u518D\u8BD5",t))return;i.info(`[restart-bridge] \u6536\u5230\u5B9E\u4F8B Bridge \u91CD\u542F\u8BF7\u6C42\uFF0CpreserveSessions=${e}`);const n=L({operationType:"restart",requestedByUserId:s,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:q(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(n),await X(!!e),t.json({ok:!0,operationId:n.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"}),i.info("[restart-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),K(),setTimeout(()=>{if(process.exitCode=42,B){B("PANEL_RESTART",!!e).catch(o=>{const a=o;i.error("[restart-bridge] graceful shutdown failed:",a),process.exit(42)});return}process.exit(42)},z)}catch(n){const o=n;i.error("[restart-bridge] Error:",o),t.status(500).json({error:o.message||"restart bridge failed"})}});export{ve as buildAmbiguousSchedulerBaseUrlResponse,Be as buildConnectionCheckResponse,Ie as buildSchedulerPingFailureResponse,g as instanceRouter,tt as setGracefulShutdownFn,je as summarizeToolStatus};
|
|
1
|
+
import{spawn as A}from"node:child_process";import{createHash as W,timingSafeEqual as G}from"node:crypto";import J from"node:fs/promises";import b from"node:path";import{fileURLToPath as _}from"node:url";import O from"axios";import{Router as Q}from"express";import{adapterRegistry as Y}from"../adapter/index.js";import{getBridgeVersion as R,resolveSchedulerBaseUrlFrom as Z}from"../config.js";import{validateToken as h,validateTokenOrPanelSession as T}from"../middleware/auth.js";import{getConfiguredConnectionKeys as x,getRegistrationState as ee,requestRuntimeAccessTokenRefreshForServer as te,resolveSchedulerBaseUrlFromToken as re}from"../services/auto-register.js";import{getEffective as v,getOverrides as j}from"../services/capability-config.js";import{appendChangelogSection as se,readChangelog as ne}from"../services/changelog.js";import{setAgentFeatures as oe,setAgentCapabilities as ae,getAgentFeatures as C}from"../services/instance-features.js";import{initInstance as ie}from"../services/instance-init-service.js";import{loadInstanceState as U,saveInstanceState as L}from"../services/instance-state.js";import{createBridgeLifecycleOperation as P,deliverPendingBridgeLifecycleNotifications as $,loadLifecycleState as ce,removeBridgeLifecycleOperation as de,upsertBridgeLifecycleOperation as k}from"../services/lifecycle-state.js";import{mcpDeployManager as le}from"../services/mcp-deploy.js";import{pluginManager as ue}from"../services/plugin-manager.js";import{getRuntimeAccessToken as ge}from"../services/runtime-binding.js";import{skillManager as pe}from"../services/skill-manager.js";import{detectToolStatuses as E,ensureToolsInstalled as fe,SUPPORTED_INSTALLABLE_TOOLS as D,SUPPORTED_UNINSTALLABLE_TOOLS as N,uninstallTools as me}from"../services/tool-installer.js";import{appendUpdateLog as m,readUpdateLog as he}from"../services/update-log.js";import{createLogger as Se}from"../utils/logger.js";import{checkBridgeUpdate as F}from"../utils/npm-version.js";const c=Se("instance");import{buildToolStatusDetectionTargets as ye}from"./instance-tool-status.js";let I=null;function nt(r){I=r}const g=Q();function M(r){return String(r||"").trim()||void 0}function q(r){const t=r.get("host");if(t)return`${r.protocol}://${t}`}function K(){const r=b.resolve(b.dirname(_(import.meta.url)),"..","..");return b.join(r,"dist","index.js")}function we(){return new Promise((r,t)=>{const e=A(process.execPath,[K(),"update","--no-kill"],{shell:!1,windowsHide:!0});let s="",n="";e.stdout.on("data",o=>{s+=o.toString("utf8")}),e.stderr.on("data",o=>{n+=o.toString("utf8")}),e.on("error",t),e.on("close",o=>{r({exitCode:o,stdout:s,stderr:n})})})}function z(){const r=A(process.execPath,[K(),"service","restart"],{shell:!1,windowsHide:!0,stdio:["ignore","pipe","pipe"]});r.stdout.on("data",t=>{m(String(t)).catch(()=>{})}),r.stderr.on("data",t=>{m(String(t)).catch(()=>{})})}async function be(){try{const r=b.join(b.dirname(b.dirname(_(import.meta.url))),"package.json"),t=JSON.parse(await J.readFile(r,{encoding:"utf8"}));return(typeof t.version=="string"?t.version.trim():"")||null}catch{return null}}const V=3e3;async function ke(r){const t={...r,status:"running",message:"Bridge \u66F4\u65B0\u6B63\u5728\u540E\u53F0\u6267\u884C\u3002"};await k(t);try{c.info("[update-bridge] \u6B63\u5728\u540E\u53F0\u6267\u884C awsb update --yes"),await m(`===== Bridge \u66F4\u65B0\u5F00\u59CB\uFF1Av${R()} -> latest\uFF08\u64CD\u4F5C ${r.operationId}\uFF09 =====`);const e=await we();if(e.stdout&&await m(e.stdout),e.stderr&&await m(e.stderr),e.exitCode===0){const s=await be(),n=r.latestVersion||s||R();await se(n,`Bridge \u5DF2\u66F4\u65B0\u81F3 ${n}\u3002`).catch(a=>{const i=a;c.warn(`[update-bridge] \u8FFD\u52A0 changelog \u6BB5\u5931\u8D25\uFF08\u5DF2\u5FFD\u7565\uFF09: ${i.message}`)}),await m("===== Bridge \u66F4\u65B0\u6210\u529F\uFF0C\u51C6\u5907\u81EA\u52A8\u91CD\u542F ===== ");const o={...t,status:"restarting",message:"Bridge \u66F4\u65B0\u5B8C\u6210\uFF0C\u6B63\u5728\u91CD\u542F..."};await k(o),c.info("[update-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),z(),setTimeout(()=>{if(process.exitCode=42,I){I("BRIDGE_UPDATE_RESTART",!0).catch(a=>{const i=a;c.error("[update-bridge] graceful shutdown failed:",i),process.exit(42)});return}process.exit(42)},V)}else await m(`===== Bridge \u66F4\u65B0\u5931\u8D25\uFF1A\u9000\u51FA\u7801 ${e.exitCode??"unknown"} =====`),await k({...t,status:"failed",message:`Bridge \u66F4\u65B0\u5931\u8D25\uFF0Cnpm \u9000\u51FA\u7801: ${e.exitCode??"unknown"}`,error:e.stderr||e.stdout}),await $()}catch(e){const s=e;c.error("[update-bridge] background update failed:",s),await m(`===== Bridge \u66F4\u65B0\u5F02\u5E38\uFF1A${s.message} =====`).catch(()=>{}),await k({...t,status:"failed",message:"Bridge \u66F4\u65B0\u5931\u8D25\u3002",error:s.message||"update bridge failed"}),await $()}}async function X(r){const t=await import("node:fs/promises"),e=await import("node:path"),s=await import("node:os"),n=e.join(s.tmpdir(),"agentswork-runtime-bridge",".preserve-sessions");if(r){await t.mkdir(e.dirname(n),{recursive:!0}),await t.writeFile(n,JSON.stringify({preserveSessions:!0,timestamp:new Date().toISOString()}),"utf-8"),c.info(`[prepare-restart] \u5DF2\u521B\u5EFA\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6: ${n}`);return}try{await t.unlink(n),c.info("[prepare-restart] \u5DF2\u5220\u9664\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6")}catch{}}function Be(r){return W("md5").update(r,"utf8").digest("hex")}function Ie(r){const t=r.trim().toLowerCase();if(!/^[a-f0-9]{32}$/.test(t))return!1;const e=Buffer.from(t,"hex");return x().map(s=>s.trim()).filter(Boolean).some(s=>{const n=Buffer.from(Be(s),"hex");return n.length===e.length&&G(n,e)})}function Re(r){const e=x().length>0,s=R();return e?Ie(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 Te(r,t){const s=t.trim()||"http://localhost:8080",n=/^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:n?"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 ve(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 je(r,t){try{const e=await O.get(`${r}/api/runtime/ping`,{headers:{"X-Runtime-Token":t}});return{schedulerReachable:e.status>=200&&e.status<300,tokenRefreshed:!1}}catch(e){if(ve(e)!==401)throw e;const s=await te(r);if(!s.success||!s.runtimeAccessToken)throw e;const n=await O.get(`${r}/api/runtime/ping`,{headers:{"X-Runtime-Token":s.runtimeAccessToken}});return{schedulerReachable:n.status>=200&&n.status<300,tokenRefreshed:!0}}}function Ue(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 Ee(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}]))}g.get("/check-update",async(r,t)=>{t.json(await F())}),g.get("/update-log",T,async(r,t)=>{try{const e=await he();t.json({ok:!0,...e})}catch(e){const s=e;c.error("[update-log] Error:",s),t.status(500).json({ok:!1,error:s.message||"read update log failed"})}}),g.get("/changelog",T,async(r,t)=>{const e=String(r.query?.version||"").trim();if(!e){t.status(400).json({ok:!1,error:"version is required"});return}try{const s=await ne(e);t.json({ok:!0,version:e,...s})}catch(s){const n=s;c.error("[changelog] Error:",n),t.status(500).json({ok:!1,error:n.message||"read changelog failed"})}}),g.get("/healthz",(r,t)=>{t.json({ok:!0,runtimeBridge:"healthy"})}),g.get("/connection-check",(r,t)=>{const e=String(r.header("X-Bridge-Connection-Key-MD5")||""),s=Re(e);t.status(s.status).json(s.body)}),g.get("/ping",h,async(r,t)=>{let e=Z(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 n=re(r.header("X-Runtime-Token"));if(n)e={url:n,source:"token-match",ambiguousTargetUrls:[]};else{const o=r.header("X-Bridge-Instance-Id");if(o){const a=ee(),i=Object.entries(a.registrations).find(([,l])=>l===o)?.[0];i&&(e={url:i,source:"instance-id-match",ambiguousTargetUrls:[]})}if(!e.url||e.source==="ambiguous-auto-register-targets"){t.status(400).json(Ue(e.ambiguousTargetUrls));return}}}const s=e.url;try{const n=ge(s);if(!n){t.status(401).json({ok:!1,error:"runtime_access_token_required"});return}const o=await je(s,n);t.json({ok:!0,runtimeBridge:"healthy",version:R(),schedulerReachable:o.schedulerReachable,tokenRefreshed:o.tokenRefreshed,schedulerBaseUrl:s,instanceId:e.instanceId,instanceName:e.instanceName})}catch(n){const o=n;t.status(502).json(Te(o,s))}}),g.post("/init-instance",h,async(r,t)=>{const{agentId:e,workspacePath:s,skillEnabled:n,mcpEnabled:o,ccSwitchEnabledTools:a,skillPackage:i,skillPackages:l,pluginPackages:f,mcpServers:S}=r.body||{};if(!e||!s){t.status(400).json({error:"agentId and workspacePath are required"});return}try{c.info("[init-instance] Request received",{agentId:String(e),workspacePath:String(s),skillEnabled:n,mcpEnabled:o,ccSwitchEnabledTools:a});const u=await ie(e,s,{skillEnabled:n,mcpEnabled:o,ccSwitchEnabledTools:a,skillPackage:i,skillPackages:l,pluginPackages:f,mcpServers:S});c.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 p=u;c.error("[init-instance] Initialization failed",{agentId:String(e),workspacePath:String(s),error:p?.message||String(u),stack:p?.stack||null}),t.status(400).json({error:p?.message||"initialize instance failed"})}}),g.post("/features",h,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),r.body.capabilities!==void 0&&ae(String(e),r.body.capabilities),c.info("[instance/features] \u80FD\u529B\u5F00\u5173\u5DF2\u66F4\u65B0",{agentId:String(e),features:C(String(e))});let n=0;for(const o of Y.getAll())if(typeof o.applyAgentFeatures=="function")try{await o.applyAgentFeatures(String(e)),n+=1}catch(a){c.error("[instance/features] adapter \u70ED\u540C\u6B65\u5931\u8D25",{agentId:String(e),providerId:o.providerId,error:a?.message||String(a)})}t.json({ok:!0,agentId:String(e),features:C(String(e)),hotSyncedAdapters:n})}),g.post("/cc-switch/state",h,async(r,t)=>{const{agentId:e}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}try{c.info("[cc-switch/state] Request received",{agentId:String(e)});const s=await U(e),n=ye(s.enabledTools||[]);c.info("[cc-switch/state] Detecting SDK statuses",{agentId:String(e),detectionTargets:n});const o=await E(n),a=await ue.listDeployed(),i=pe.listDeployed(),l=le.listDeployed(),f=j(e,"skills"),S=j(e,"mcp"),u=j(e,"plugins"),p=i.map(d=>({...d,enabled:v(e,"skills",d.skillName),source:f[d.skillName]!==void 0?"agent":"bridge"})),y=l.map(d=>({...d,enabled:v(e,"mcp",d.name),source:S[d.name]!==void 0?"agent":"bridge"})),w=a.map(d=>({...d,enabled:v(e,"plugins",d.pluginName),source:u[d.pluginName]!==void 0?"agent":"bridge"}));c.info("[cc-switch/state] SDK status detection completed",{agentId:String(e),toolStatus:Ee(o)}),t.json({ok:!0,agentId:String(e),imported:{mcpServers:0,skills:0},deployedPlugins:w,deployedSkills:p,deployedMcp:y,state:{...s,toolStatus:o}})}catch(s){const n=s;c.error("[cc-switch/state] Failed to load state",{agentId:String(e),error:n?.message||String(s),stack:n?.stack||null}),t.status(400).json({error:n?.message||"load state failed"})}}),g.post("/tools/install",h,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const n=Array.isArray(s)?s.map(i=>String(i||"").trim().toLowerCase()).filter(Boolean):[],o=new Set(D),a=n.filter(i=>o.has(i));if(a.length===0){t.status(400).json({error:`tools must include ${D.join(", ")}`});return}try{const i=await U(e),l=Array.from(new Set([...i.enabledTools||[],...a])),f=await fe(a),u={...await E(l),...f},p=await L(e,{...i,enabledTools:l,toolStatus:u}),y=new Set(a),w=Object.entries(u).filter(([d])=>y.has(d)).filter(([,d])=>!d.installed).map(([d,B])=>({tool:d,error:B.error||null}));t.json({ok:w.length===0,agentId:String(e),toolStatus:u,failedTools:w,state:p})}catch(i){const l=i;t.status(400).json({error:l?.message||"install tools failed"})}}),g.post("/tools/uninstall",h,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const n=Array.isArray(s)?s.map(i=>String(i||"").trim().toLowerCase()).filter(Boolean):[],o=new Set(N),a=n.filter(i=>o.has(i));if(a.length===0){t.status(400).json({error:`tools must include ${N.join(", ")}`});return}try{const i=await U(e),l=new Set(a),f=(i.enabledTools||[]).filter(B=>!l.has(String(B||"").trim().toLowerCase())),S=await me(a),p={...await E([...f,...a]),...S},y=a.filter(B=>p[B]?.installed),w=y.length>0?i.enabledTools||[]:f,d=await L(e,{...i,enabledTools:w,toolStatus:p});if(y.length>0){t.status(400).json({ok:!1,agentId:String(e),error:"uninstall incomplete",toolStatus:p,state:d});return}t.json({ok:!0,agentId:String(e),toolStatus:p,state:d})}catch(i){const l=i;t.status(400).json({error:l?.message||"uninstall tools failed"})}}),g.post("/prepare-restart",h,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{};try{c.info(`[prepare-restart] \u6536\u5230\u51C6\u5907\u91CD\u542F\u901A\u77E5\uFF0CpreserveSessions=${e}`),await X(!!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 n=s;c.error("[prepare-restart] Error:",n),t.status(500).json({error:n.message})}});const Ae={update:15*60*1e3,restart:5*60*1e3};async function _e(r){try{const t=await ce(),e=Date.now(),s=Ae[r],n=[];for(const o of t.operations){if(o.operationType!==r||!["accepted","running","restarting"].includes(o.status))continue;const a=new Date(o.updatedAt).getTime();if(!Number.isNaN(a)&&e-a<=s)return{operationId:o.operationId};n.push(o.operationId)}for(const o of n)try{await de(o),c.info(`[${r}-bridge] \u5DF2\u6E05\u7406\u8D85\u65F6\u672A\u4EA4\u4ED8\u7684\u9648\u65E7\u64CD\u4F5C: ${o}`)}catch(a){const i=a;c.warn(`[${r}-bridge] \u6E05\u7406\u9648\u65E7\u64CD\u4F5C\u5931\u8D25\uFF0C\u7EE7\u7EED\u653E\u884C: ${o}, ${i.message}`)}return null}catch(t){const e=t;return c.warn(`[${r}-bridge] \u5728\u9014\u64CD\u4F5C\u68C0\u67E5\u5931\u8D25\uFF0C\u653E\u884C\u8BF7\u6C42: ${e.message}`),null}}async function H(r,t,e){const s=await _e(r);return s?(e.status(409).json({error:t,operationId:s.operationId}),!0):!1}g.post("/update-bridge",T,async(r,t)=>{const e=M(r.body?.requestedByUserId);try{if(!e){t.status(400).json({error:"requestedByUserId is required"});return}if(await H("update","\u5B9E\u4F8B Bridge \u66F4\u65B0\u6B63\u5728\u6267\u884C\u4E2D\uFF0C\u8BF7\u52FF\u91CD\u590D\u89E6\u53D1",t))return;const s=await F(),n=P({operationType:"update",requestedByUserId:e,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:q(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 k(n),ke(n),t.json({ok:!0,operationId:n.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 n=s;c.error("[update-bridge] Error:",n),t.status(500).json({error:n.message||"update bridge failed"})}}),g.post("/restart-bridge",T,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{},s=M(r.body?.requestedByUserId);try{if(!s){t.status(400).json({error:"requestedByUserId is required"});return}if(await H("restart","\u5B9E\u4F8B Bridge \u6B63\u5728\u91CD\u542F\u4E2D\uFF0C\u8BF7\u7A0D\u5019\u518D\u8BD5",t))return;c.info(`[restart-bridge] \u6536\u5230\u5B9E\u4F8B Bridge \u91CD\u542F\u8BF7\u6C42\uFF0CpreserveSessions=${e}`);const n=P({operationType:"restart",requestedByUserId:s,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:q(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 k(n),await X(!!e),t.json({ok:!0,operationId:n.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"}),c.info("[restart-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),z(),setTimeout(()=>{if(process.exitCode=42,I){I("PANEL_RESTART",!!e).catch(o=>{const a=o;c.error("[restart-bridge] graceful shutdown failed:",a),process.exit(42)});return}process.exit(42)},V)}catch(n){const o=n;c.error("[restart-bridge] Error:",o),t.status(500).json({error:o.message||"restart bridge failed"})}});export{Ue as buildAmbiguousSchedulerBaseUrlResponse,Re as buildConnectionCheckResponse,Te as buildSchedulerPingFailureResponse,g as instanceRouter,nt as setGracefulShutdownFn,Ee as summarizeToolStatus};
|
|
2
2
|
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import g from"node:fs/promises";import s from"node:path";import{fileURLToPath as E}from"node:url";import{getRuntimeHomeDir as v}from"../config.js";import{createLogger as S}from"../utils/logger.js";const l=S("changelog");function
|
|
2
|
-
`)}async function R(
|
|
1
|
+
import g from"node:fs/promises";import s from"node:path";import{fileURLToPath as E}from"node:url";import{getRuntimeHomeDir as v}from"../config.js";import{createLogger as S}from"../utils/logger.js";const l=S("changelog");function p(){const t=String(process.env.AWS_BRIDGE_CHANGELOG_PATH||"").trim();if(t)return[t];const r=s.resolve(s.dirname(E(import.meta.url)),"..","..");return[s.join(r,"CHANGELOG.md"),s.join(v(),".aws-bridge","CHANGELOG.md")]}const $=256*1024,d="<!-- append-new-version-above -->";function A(t){return/^v?\d+\.\d+\.\d+/.test(t.trim())}function w(t){const r=t.trim();return r.startsWith("v")?r:`v${r}`}async function I(t){const r=w(t),i=p();let o=null;for(const c of i)try{const e=await g.readFile(c,{encoding:"utf8"}),n=String(e),a=x(n,r);if(a!==null)return{found:!0,content:a.trimEnd(),path:c};o===null&&(o={content:n.length>$?n.slice(-$):n,path:c})}catch(e){const n=e;if(n.code==="ENOENT")continue;l.warn(`[changelog] read failed for ${c}: ${n.message}`)}return{found:!1,content:o?.content??"",path:o?.path??i[0]}}function x(t,r){const i=t.split(/\r?\n/);let o=-1;for(let e=0;e<i.length;e++){const n=i[e];if(/^##\s+/.test(n.trim())){const a=n.trim().replace(/^##\s+/,"");if(a===r||a===r.replace(/^v/,"")){o=e;break}}}if(o===-1)return null;let c=i.length;for(let e=o+1;e<i.length;e++)if(/^##\s+/.test(i[e].trim())||i[e].includes(d)){c=e;break}return i.slice(o,c).join(`
|
|
2
|
+
`)}async function R(t,r){const i=w(t);if(!A(t)){l.warn(`[changelog] skip append: invalid version "${t}"`);return}const o=p(),c=[];for(const e of o)try{let n="";try{n=await g.readFile(e,{encoding:"utf8"})}catch(h){if(h.code!=="ENOENT")throw h;n=`# Changelog
|
|
3
3
|
|
|
4
4
|
\u672C\u6587\u4EF6\u8BB0\u5F55 aws-runtime-bridge \u5404\u7248\u672C\u7684\u53D1\u5E03\u8BF4\u660E\u3002
|
|
5
5
|
|
|
6
6
|
${d}
|
|
7
|
-
`}if(N(
|
|
8
|
-
## ${
|
|
7
|
+
`}if(N(n,i)){l.info(`[changelog] ${i} \u6BB5\u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\u8FFD\u52A0`);return}const a=new Date().toISOString().slice(0,10),u=`
|
|
8
|
+
## ${i}
|
|
9
9
|
|
|
10
10
|
_\u53D1\u5E03\u65E5\u671F\uFF1A${a}_
|
|
11
11
|
|
|
12
12
|
${r.trim()}
|
|
13
|
-
`,m=C(
|
|
14
|
-
${u}${
|
|
15
|
-
${d}`):f=`${
|
|
16
|
-
${u}`,await g.mkdir(s.dirname(
|
|
13
|
+
`,m=C(n);let f;m>=0?f=`${n.slice(0,m).replace(/\s*$/,"")}
|
|
14
|
+
${u}${n.slice(m)}`:n.includes(d)?f=n.replace(d,`${u}
|
|
15
|
+
${d}`):f=`${n.replace(/\s*$/,"")}
|
|
16
|
+
${u}`,await g.mkdir(s.dirname(e),{recursive:!0}),await g.writeFile(e,f,{encoding:"utf8"}),l.info(`[changelog] \u5DF2\u8FFD\u52A0 ${i} \u6BB5\u5230 ${e}`);return}catch(n){const a=n;c.push(`${e}: ${a.message}`)}l.warn(`[changelog] \u8FFD\u52A0\u5931\u8D25\uFF08\u5DF2\u5FFD\u7565\uFF09\uFF1A${c.join("; ")}`)}function N(t,r){return x(t,r)!==null}function C(t){return t.match(/^[ \t]*##\s+v?\d+\.\d+\.\d+.*$/m)?.index??-1}export{R as appendChangelogSection,I as readChangelog};
|
|
17
17
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import P from"node:fs";import x from"node:os";import _ from"node:path";import{execFile as X}from"node:child_process";import{fileURLToPath as Z}from"node:url";import{Server as Q}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as ee}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as te,ListToolsRequestSchema as re}from"@modelcontextprotocol/sdk/types.js";import{AgentClient as se,PollLongPollTimeoutError as ie}from"./agent-client.js";import{normalizeServerHttpBase as ne}from"./http-client.js";import{MCP_SERVER_NAME as oe,MCP_SERVER_VERSION as ae,REGISTER_MAX_RETRIES as D,REGISTER_RETRY_INTERVAL_MS as le,DEGRADED_MODE_ENABLED as H,DEGRADED_MODE_RETRY_INTERVAL_MS as ce,DEGRADED_MODE_MAX_RETRIES as me}from"./constants.js";import{resolveAcodeDataHome as U}from"./config.js";import{logger as l}from"./logger.js";import{meetingDebugFingerprints as O,meetingDebugLog as I}from"./meeting-debug-log.js";import{MCP_TOOLS as F,MEMORY_TOOL_NAMES as W,LAUNCH_CONFIG_TOOL_NAMES as q,HIRE_TOOL_NAMES as z,PENCIL_TOOL_NAMES as G}from"./mcp-tools.js";import{MessageBuffer as ue}from"./message-buffer.js";import{ContextManager as de}from"./context-manager.js";import{MemoryCapacityError as he,MemoryStore as L}from"./memory-store.js";import{ServerMemoryStore as pe}from"./server-memory-store.js";const ge=3e3,j=10,Y=(()=>{const C=Number.parseInt(process.env.AWS_MCP_FILE_CHANGE_RENOTIFY_COOLDOWN_MS||"",10);return Number.isFinite(C)&&C>0?C:30*6e4})(),K=500,fe=30,ye=new Set(["<",">",":",'"',"/","\\","|","?","*"]),J=20*1024*1024,_e={".pdf":"application/pdf",".txt":"text/plain",".md":"text/markdown",".csv":"text/csv",".json":"application/json",".html":"text/html",".xml":"application/xml",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".zip":"application/zip",".gz":"application/gzip",".tar":"application/x-tar",".7z":"application/x-7z-compressed",".rar":"application/vnd.rar",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".mp3":"audio/mpeg",".mp4":"video/mp4"};function Me(C){return _e[_.extname(C).toLowerCase()]||"application/octet-stream"}function Se(C){return(C||"").replace(/[|[\]\r\n]/g,"_").trim()||"\u6587\u4EF6"}function we(C){if(!Number.isFinite(C)||C<=0)return"0 B";const e=["B","KB","MB","GB"],t=Math.min(e.length-1,Math.floor(Math.log(C)/Math.log(1024)));return`${Number.parseFloat((C/1024**t).toFixed(2))} ${e[t]}`}function ve(C){return`[\u6587\u4EF6: ${Se(C.name)} | ${C.url} | ${C.mediaType||"application/octet-stream"} | ${we(C.size)}]`}class T{server;agentClient;messageBuffer;memoryStore;roleMemoryStore;sessionContextMemoryStore;initialRoleName="";hasRoleName=!1;contextManager;isSubAgent;fileChangeNotifyHistory=new Map;featuresCache=null;static FEATURES_CACHE_TTL_MS=5e3;static LAUNCH_ITEM_FEATURE_KEY="agentSys.launchItem";static LAUNCH_TOOLS_ENV_KEY="AWS_LAUNCH_CONFIG_TOOLS";static HIRE_FEATURE_KEY="agentSys.hire";static HIRE_TOOLS_ENV_KEY="AWS_HIRE_TOOLS";static PENCIL_FEATURE_KEY="pencil";static PENCIL_TOOLS_ENV_KEY="AWS_PENCIL_TOOLS";leaseRenewalTimer=null;activeLeaseUris=new Set;static LEASE_DURATION_MINUTES=10;static LEASE_RENEW_INTERVAL_MS=6e4;profileSynced=!1;urgentMeetingHydrateRequested=!1;cachedPluginCatalog=null;deliveredPluginNames=new Set;pluginCatalogDrainCompactionSeq=0;pluginCatalogLastSeenCompactionSeq=0;static MEETING_HYDRATE_RETRY_COUNT=3;static MEETING_HYDRATE_RETRY_DELAY_MS=150;static MEETING_HYDRATE_TIMEOUT_REARM_DELAY_MS=1e4;meetingHydrateTimeoutRearmDelayMs=T.MEETING_HYDRATE_TIMEOUT_REARM_DELAY_MS;static MEETING_HYDRATE_POLL_TIMEOUT_MS=65e3;static MEETING_PREEMPTIVE_JOIN_WAIT_MS=45e3;pendingPollMessage=null;syncRoleMemoryStore(e){if(l.info(`[McpServer] syncRoleMemoryStore \u88AB\u8C03\u7528: displayName=${e.displayName}, roleName="${e.roleName??"(\u7A7A)"}", id=${e.id}`),!e.roleName){l.warn(`[McpServer] syncRoleMemoryStore: profile.roleName \u4E3A\u7A7A\uFF0ChasRoleName \u4FDD\u6301 false\u3002profile=${JSON.stringify({id:e.id,displayName:e.displayName,roleName:e.roleName,instanceName:e.instanceName})}`);return}const t=T.sanitizeRoleDirectoryName(e.roleName);this.hasRoleName=!0,t!==this.initialRoleName&&(l.info(`[McpServer] \u89D2\u8272\u76EE\u5F55\u4E0E\u521D\u59CB\u503C\u4E0D\u4E00\u81F4\uFF0C\u91CD\u5EFA roleMemoryStore: "${this.initialRoleName}" -> "${t}"`),this.roleMemoryStore=new L(T.buildRoleMemoryStorePath(t)),this.initialRoleName=t)}maybeSyncPermanentMemoryToServer(){this.doMaybeSyncPermanentMemoryToServer().catch(e=>{l.warn("[McpServer] maybeSyncPermanentMemoryToServer \u5F02\u5E38: %s, stack=%s",e instanceof Error?e.message:String(e),e instanceof Error?e.stack:"(no stack)")})}async doMaybeSyncPermanentMemoryToServer(){l.info("[McpServer] maybeSyncPermanentMemoryToServer \u5F00\u59CB\uFF0CinitialRoleName="+this.initialRoleName);let e;try{e=await this.memoryStore.getStats()}catch(n){l.warn("[McpServer] \u83B7\u53D6 server \u8BB0\u5FC6\u7EDF\u8BA1\u5931\u8D25\uFF0C\u8DF3\u8FC7\u540C\u6B65:",n instanceof Error?n.message:n);return}const t=e.by_type.project_memory?.count??0;l.info(`[McpServer] server memory \u8BA1\u6570=${t}`);let r=[];try{r=await this.roleMemoryStore.listByType("project_memory"),l.info(`[McpServer] \u89D2\u8272\u5B50\u76EE\u5F55\u8BFB\u53D6\u5230 ${r.length} \u6761\u6C38\u4E45\u8BB0\u5FC6`)}catch(n){l.warn("[McpServer] \u8BFB\u53D6\u89D2\u8272\u5B50\u76EE\u5F55\u6C38\u4E45\u8BB0\u5FC6\u5931\u8D25:",n instanceof Error?n.message:n)}if(r.length===0){const n=_.dirname(T.buildRoleMemoryStorePath(this.initialRoleName));l.info(`[McpServer] \u5C1D\u8BD5\u4ECE\u9057\u7559\u76EE\u5F55\u8BFB\u53D6: ${n}`);try{const a=await new L(n).listByType("project_memory");a.length>0&&(l.info(`[McpServer] \u4ECE\u9057\u7559\u76EE\u5F55\u8BFB\u53D6\u5230 ${a.length} \u6761\u6C38\u4E45\u8BB0\u5FC6`),r=a)}catch(o){l.warn("[McpServer] \u8BFB\u53D6\u9057\u7559\u76EE\u5F55\u6C38\u4E45\u8BB0\u5FC6\u5931\u8D25:",o instanceof Error?o.message:o)}}if(r.length===0){l.info("[McpServer] \u672C\u5730\u4E5F\u65E0\u6C38\u4E45\u8BB0\u5FC6\uFF0C\u8DF3\u8FC7\u540C\u6B65");return}if(t>=r.length){l.info(`[McpServer] \u670D\u52A1\u7AEF\u5DF2\u6709 ${t} \u6761 >= \u672C\u5730 ${r.length} \u6761\uFF0C\u65E0\u9700\u56DE\u586B`);return}l.info(`[McpServer] \u68C0\u6D4B\u5230\u7F3A\u91CF\uFF1A\u672C\u5730 ${r.length} \u6761 > \u670D\u52A1\u7AEF ${t} \u6761\uFF0C\u5F00\u59CB\u589E\u91CF\u56DE\u586B`);let i=0,s=0;for(const n of r)try{await this.memoryStore.createMemory({memory_type:"project_memory",uri:n.uri,title:n.title,content:n.content,keywords:n.keywords,bound_files:n.bound_files,file_md5_map:n.file_md5_map,last_check_time:n.last_check_time}),i++,l.info(`[McpServer] \u540C\u6B65\u6C38\u4E45\u8BB0\u5FC6\u6210\u529F: ${n.uri}`)}catch(o){const a=o instanceof Error?o.message:String(o);a.includes("already exists")||a.includes("Memory already exists")||l.warn(`[McpServer] \u540C\u6B65\u6C38\u4E45\u8BB0\u5FC6\u5931\u8D25 (${n.uri}): ${a}`),s++}l.info(`[McpServer] \u6C38\u4E45\u8BB0\u5FC6\u540C\u6B65\u5B8C\u6210: \u6210\u529F ${i}, \u8DF3\u8FC7 ${s}, \u5171 ${r.length}`),await this.reportMemoryStatsToServer()}normalizeBoundFilePath(e){const t=String(e||"").trim().replace(/\\/g,"/");if(!t)return t;const r=t.startsWith("@/")?t.substring(1):t;return r.startsWith("./")?r:`./${r.replace(/^\/+/,"")}`}normalizeBoundFiles(e){return!e||!Array.isArray(e)?e:e.map(t=>this.normalizeBoundFilePath(String(t)))}async validateBoundFilesExist(e){if(!e||e.length===0)return;const t=process.env.AWS_WORKSPACE_PATH||process.cwd(),{access:r}=await import("node:fs/promises"),i=[];for(const s of e)try{const n=_.resolve(t,s);await r(n)}catch{i.push(s)}if(i.length>0)throw new Error(`\u7ED1\u5B9A\u7684\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u786E\u8BA4\u6587\u4EF6\u8DEF\u5F84\u6B63\u786E\u540E\u518D\u91CD\u65B0\u63D0\u4EA4:
|
|
2
2
|
${i.map(s=>` - ${s}`).join(`
|
|
3
|
-
`)}`)}toMemoryWriteResult(e){return{id:e.id,uri:e.uri,domain:e.domain,path:e.path,title:e.title,memory_type:e.memory_type,createdAt:e.createdAt,updatedAt:e.updatedAt,version:e.version,keywords:e.keywords,bound_files:e.bound_files}}toMemoryRecordWithMetadata(e){return{id:e.id,uri:e.uri,domain:e.domain,path:e.path,title:e.title,content:e.content,memory_type:e.memory_type,createdAt:e.createdAt,updatedAt:e.updatedAt,version:e.version,keywords:e.keywords,bound_files:e.bound_files,file_md5_map:e.file_md5_map,memory_status:e.memory_status,updating_agent_id:e.updating_agent_id,last_check_time:e.last_check_time,path_prefix:e.path_prefix,readonly:e.readonly,source_agent_id:e.source_agent_id,source_display_name:e.source_display_name,source_role_name:e.source_role_name,source_workspace_path:e.source_workspace_path}}constructor(){this.agentClient=new se,this.messageBuffer=new ue,this.initialRoleName=T.resolveRoleMemoryDirectoryName(),this.hasRoleName=!!process.env.AWS_ROLE_NAME;const e=T.resolveMemoryStorePaths();this.memoryStore=new pe(this.agentClient),this.roleMemoryStore=new L(e.rolePath),this.sessionContextMemoryStore=new L(g.join(g.dirname(e.rolePath),"..","session_context")),this.isSubAgent=process.env.AWS_SUB_AGENT==="true",this.contextManager=new de(this.sessionContextMemoryStore),this.server=new Q({name:oe,version:ae},{capabilities:{tools:{}}}),this.setupHandlers()}setupHandlers(){this.server.setRequestHandler(re,async()=>{let e=this.isSubAgent?F.filter(t=>W.has(t.name)):F;return!this.isSubAgent&&!await this.isLaunchConfigToolsEnabled()&&(e=e.filter(t=>!q.has(t.name))),!this.isSubAgent&&!await this.isHireToolsEnabled()&&(e=e.filter(t=>!z.has(t.name))),!this.isSubAgent&&!await this.isPencilToolsEnabled()&&(e=e.filter(t=>!G.has(t.name))),{tools:e}}),this.server.setRequestHandler(te,async(e,t)=>{const{name:r,arguments:i}=e.params;try{const s=await this.handleToolCall(r,i,t?.signal);return{content:this.buildToolResultContent(s)}}catch(s){const n=s instanceof Error?s.message:String(s),o=s instanceof he?{error:n,...s.details}:{error:n};return l.error("[McpServer] \u5DE5\u5177\u8C03\u7528\u5F02\u5E38: tool=%s, error=%s, stack=%s",r,n,s instanceof Error?s.stack:"(no stack)"),{content:[{type:"text",text:JSON.stringify(o,null,2)}],isError:!0}}})}async handlePencilExportImage(e){const t=typeof e.savePath=="string"?e.savePath.trim():"";if(t){const o=g.resolve(process.env.AWS_WORKSPACE_PATH||process.cwd()),a=g.resolve(o,t);if(a!==o&&!a.startsWith(o+g.sep))throw new Error("savePath \u5FC5\u987B\u4F4D\u4E8E\u5DE5\u4F5C\u533A\u5185\uFF08\u76F8\u5BF9\u5DE5\u4F5C\u533A\u6839\u7684\u8DEF\u5F84\uFF09\uFF0C\u5982 design/hero.png")}const r=await this.agentClient.callAgentScopedTool("pencil_export_image",e),i=typeof r?.image=="string"?r.image:"";if(!i)return r;const s=i.startsWith("data:")?i.slice(i.indexOf(",")+1):i,n={...r};delete n.image,delete n.mimeType,n.sizeKb=Math.ceil(s.length*3/4/1024);try{const{mkdir:o,writeFile:a}=await import("node:fs/promises");let m;if(t){const d=g.resolve(process.env.AWS_WORKSPACE_PATH||process.cwd());m=g.resolve(d,t)}else{const p=(typeof r?.docId=="string"?r.docId:"").replace(/[^a-zA-Z0-9_-]/g,"").slice(0,40)||"doc",u=g.join(x.tmpdir(),"pencil-export");await o(u,{recursive:!0}),m=g.join(u,`${p}-${Date.now()}-${Math.random().toString(36).slice(2,8)}.png`)}return await o(g.dirname(m),{recursive:!0}),await a(m,Buffer.from(s,"base64")),{...n,savedTo:m,temp:!t}}catch(o){return{...n,savedTo:null,saveError:o instanceof Error?o.message:String(o)}}}static PENCIL_EXPORT_FORMATS=new Set(["svg","html","png","jpg","webp","pptx","fig","jsx"]);async handlePencilExportDocument(e){const t=typeof e.format=="string"&&e.format.trim()?e.format.trim().toLowerCase():"svg";if(!T.PENCIL_EXPORT_FORMATS.has(t))throw new Error(`\u4E0D\u652F\u6301\u7684\u5BFC\u51FA\u683C\u5F0F: ${t}\uFF08\u652F\u6301 svg/html/png/jpg/webp/pptx/fig/jsx\uFF1Bpdf \u6682\u4E0D\u652F\u6301\uFF09`);const r=typeof e.nodeId=="string"&&e.nodeId.trim()?e.nodeId.trim():"";if(t==="jsx"&&!r)throw new Error("jsx \u5BFC\u51FA\u9700\u8981\u4F20 nodeId\uFF08\u6765\u81EA pencil_get_tree\uFF09\uFF0C\u5B83\u6309\u5355\u8282\u70B9\u751F\u6210 React \u7EC4\u4EF6");const i=typeof e.savePath=="string"?e.savePath.trim():"",s=g.resolve(process.env.AWS_WORKSPACE_PATH||process.cwd());if(i){const v=g.resolve(s,i);if(v!==s&&!v.startsWith(s+g.sep))throw new Error("savePath \u5FC5\u987B\u4F4D\u4E8E\u5DE5\u4F5C\u533A\u5185\uFF08\u76F8\u5BF9\u5DE5\u4F5C\u533A\u6839\u7684\u8DEF\u5F84\uFF09\uFF0C\u5982 design/hero.svg")}const n=await this.agentClient.callAgentScopedTool("pencil_export_document",e),o=typeof n?.snapshotJson=="string"?n.snapshotJson:"";if(!o)return n;const{mkdir:a,writeFile:m,stat:d}=await import("node:fs/promises"),u=(typeof n?.docId=="string"?n.docId:"").replace(/[^a-zA-Z0-9_-]/g,"").slice(0,40)||"doc",M=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,R=g.join(x.tmpdir(),"pencil-export");await a(R,{recursive:!0});const h=g.join(R,`${u}-${M}.snapshot.json`);await m(h,o,"utf8");const w=t,c=i?g.resolve(s,i):g.join(R,`${u}-${M}.${w}`),_=g.resolve(process.env.AWS_OPEN_PENCIL_HOME||Z(new URL("../../../../open-pencil",import.meta.url))),f=[{cmd:process.execPath,entry:g.join(_,"packages","cli","dist","index.mjs")},{cmd:"bun",entry:g.join(_,"packages","cli","src","index.ts")}].filter(v=>k.existsSync(v.entry));if(f.length===0)throw new Error(`\u672A\u627E\u5230 open-pencil CLI\uFF08\u67E5\u627E\u76EE\u5F55 ${_}\uFF09\uFF0C\u8BF7\u786E\u8BA4\u5B89\u88C5\u5E03\u5C40\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_OPEN_PENCIL_HOME \u6307\u5411 open-pencil \u4ED3\u5E93\u6839\u76EE\u5F55`);const S=["export",h,"--snapshot","-f",t,"-o",c];r&&S.push("--node",r),t==="html"&&S.push("--html","standalone"),(t==="png"||t==="jpg"||t==="webp")&&(typeof e.scale=="number"&&e.scale>0&&S.push("--scale",String(e.scale)),typeof e.quality=="number"&&e.quality>0&&S.push("--quality",String(e.quality)));const E=[];let P=!1;for(const v of f)try{await this.runPencilCli(v.cmd,[v.entry,...S],_),P=!0;break}catch(A){E.push(`${g.basename(v.cmd)}: ${A instanceof Error?A.message:String(A)}`)}if(!P)throw new Error(`\u753B\u5E03\u5BFC\u51FA\u5931\u8D25\uFF08format=${t}\uFF09\uFF1A${E.join("\uFF1B")||"\u672A\u77E5\u9519\u8BEF"}`);let y=null;try{y=Math.ceil((await d(c)).size/1024)}catch{y=null}const b={...n};return delete b.snapshotJson,{...b,format:t,savedTo:c,temp:!i,sizeKb:y}}runPencilCli(e,t,r){return new Promise((i,s)=>{X(e,t,{cwd:r,timeout:18e4,maxBuffer:16*1024*1024},(n,o,a)=>{if(n){const m=String(a||o||"").trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" | ");s(new Error(m||n.message));return}i(String(o||""))})})}stripRenderImageForReporting(e){if(e&&typeof e=="object"&&!Array.isArray(e)){const t=e;let r=null;if(typeof t.image=="string"){const s=t.image.length,n=Math.ceil(s*3/4/1024);r={...t,image:`<PNG base64 \u5DF2\u7701\u7565\uFF0C\u7EA6 ${n}KB\uFF0C\u6B63\u6587\u89C1 t_pencil_doc.render_image>`}}const i=r??t;if(typeof i.snapshotJson=="string"){const s=Math.ceil(i.snapshotJson.length/1024);r={...i,snapshotJson:`<GraphSnapshot JSON \u5DF2\u7701\u7565\uFF0C\u7EA6 ${s}KB\uFF0C\u6743\u5A01\u6570\u636E\u89C1 t_pencil_doc.snapshot>`}}if(r)return r}return e}buildToolResultContent(e){if(e&&typeof e=="object"&&!Array.isArray(e)){const t=e;if(typeof t.image=="string"&&typeof t.mimeType=="string"){const r={...t};delete r.image;const i=[{type:"image",data:t.image,mimeType:t.mimeType}];return Object.keys(r).length>0&&i.push({type:"text",text:JSON.stringify(r,null,2)}),i}}return[{type:"text",text:JSON.stringify(e,null,2)}]}async handleToolCall(e,t,r){const i=t?._aws_sub_agent===!0,s=t?._aws_silent_poll===!0,n=t?._aws_force_inject===!0,o={...t};delete o._aws_sub_agent,delete o._aws_silent_poll,delete o._aws_force_inject;const a=i?null:this.agentClient.getStatusReporter();a&&!s&&this.safeReportStatus(()=>a.reportToolUse(e,this.sanitizeToolUseArgs(e,o)));try{const m=await this.executeToolCall(e,o,{forceInject:n,signal:r});if(a&&!s){const d=this.stripAutoDelegateForReporting(m);d!==null&&(this.safeReportStatus(()=>a.reportToolResult(this.stripRenderImageForReporting(d))),this.safeReportStatus(()=>a.reportThinking()))}return m}catch(m){throw a&&!s&&this.safeReportStatus(()=>a.reportToolError(m)),m}}safeReportStatus(e){try{e()}catch(t){l.warn("[McpServer] \u72B6\u6001\u4E0A\u62A5\u5931\u8D25\uFF08\u5DF2\u5FFD\u7565\uFF0C\u4E0D\u5F71\u54CD\u5DE5\u5177\u8C03\u7528\uFF09: %s",t instanceof Error?t.message:String(t))}}async executeToolCall(e,t,r={}){if(this.isSubAgent&&!W.has(e))throw new Error(`Sub-agent is not allowed to call tool: ${e}`);if(q.has(e)&&!await this.isLaunchConfigToolsEnabled())throw new Error("\u542F\u52A8\u9879\u7BA1\u7406\u80FD\u529B\u672A\u5F00\u542F\uFF08\u8BF7\u5148\u5728\u80FD\u529B\u914D\u7F6E\u4E2D\u5F00\u542F\u300CAgent \u7CFB\u7EDF\u7BA1\u7406 \u2192 \u542F\u52A8\u9879\u7BA1\u7406\u300D\u540E\u518D\u8C03\u7528 launch_config_* \u5DE5\u5177\uFF09");if(z.has(e)&&!await this.isHireToolsEnabled())throw new Error("\u62DB\u8058\u5DE5\u5177\u80FD\u529B\u672A\u5F00\u542F\uFF08\u8BF7\u5148\u5728\u80FD\u529B\u914D\u7F6E\u4E2D\u5F00\u542F\u300CAgent \u7CFB\u7EDF\u7BA1\u7406 \u2192 \u62DB\u8058\u5DE5\u5177\u300D\u540E\u518D\u8C03\u7528 hire_colleague\uFF09");if(G.has(e)&&!await this.isPencilToolsEnabled())throw new Error("\u8BBE\u8BA1\u753B\u5E03\u80FD\u529B\u672A\u5F00\u542F\uFF08\u8BF7\u5148\u5728\u80FD\u529B\u914D\u7F6E\u4E2D\u5F00\u542F\u300C\u8BBE\u8BA1\u753B\u5E03 (Pencil)\u300D\u540E\u518D\u8C03\u7528 pencil_* \u5DE5\u5177\uFF09");switch(e){case"get_colleague":return await this.agentClient.discoverColleagues();case"get_group_rooms":return await this.agentClient.discoverGroupRooms();case"get_profile":return await this.agentClient.getProfile();case"hire_colleague":return await this.handleHireColleague(t);case"send_group":return await this.handleSendGroup(t);case"send_private":return await this.handleSendPrivate(t);case"poll_message":return await this.handlePollMessage(r.signal);case"get_message":return this.handleGetMessage(r.forceInject===!0);case"get_dm_history":return await this.handleGetDmHistory(t);case"get_group_history":return await this.handleGetGroupHistory(t);case"create_meeting":case"leave_meeting":case"end_meeting":case"meeting_speak":case"get_meeting_info":case"my_meetings":return await this.agentClient.callAgentScopedTool(e,t);case"pencil_create_document":case"pencil_list_documents":case"pencil_open_document":case"pencil_close_document":case"pencil_get_tree":case"pencil_get_changes":case"pencil_create_nodes":case"pencil_update_nodes":case"pencil_delete_nodes":case"pencil_share_document":case"pencil_revoke_share":case"pencil_delete_document":case"pencil_rename_document":return await this.agentClient.callAgentScopedTool(e,t);case"pencil_export_image":return await this.handlePencilExportImage(t);case"pencil_export_document":return await this.handlePencilExportDocument(t);case"my_task":return await this.agentClient.getMyTasks();case"create_task_instance_comment":return await this.handleCreateTaskInstanceComment(t);case"submit_task_result":return await this.handleSubmitTaskResult(t);case"start_task_rollback":return await this.handleStartTaskRollback(t);case"finish_task_rollback":return await this.handleFinishTaskRollback(t);case"reject_task":return await this.handleRejectTask(t);case"terminate_task":return await this.handleTerminateTask(t);case"create_memory":return await this.handleCreateMemory(t);case"read_memory":return await this.handleReadMemory(t);case"update_memory":return await this.handleUpdateMemory(t);case"delete_memory":return await this.handleDeleteMemory(t);case"search_memory":return await this.handleSearchMemory(t);case"list_memories":return await this.handleListMemories(t);case"get_memory_stats":return await this.handleGetMemoryStats(t);case"list_memories_by_file":return await this.handleListMemoriesByFile(t);case"abandon_memory_update":return await this.handleAbandonMemoryUpdate(t);case"memory_recurrence":return await this.handleMemoryRecurrence(t);case"memory_recurrence_complete":return await this.handleMemoryRecurrenceComplete(t);case"get_debug_log_config":return await this.agentClient.getDebugLogConfig();case"query_debug_logs":return await this.agentClient.queryDebugLogs(t);case"query_file_changes_history":return await this.agentClient.queryFileChangesHistory(t);case"launch_config_list":return await this.agentClient.listLaunchConfigs();case"launch_config_create":return await this.agentClient.createLaunchConfig(t);case"launch_config_update":return await this.agentClient.updateLaunchConfig(t);case"launch_config_delete":return await this.agentClient.deleteLaunchConfig(String(t?.configId??""));case"launch_config_start":return await this.agentClient.startLaunchConfig(t);case"launch_config_restart":return await this.agentClient.restartLaunchConfig(t);case"launch_config_stop":return await this.agentClient.stopLaunchConfig(String(t?.configId??""));case"launch_config_logs":return await this.agentClient.getLaunchLogs(t);case"launch_config_status":return await this.agentClient.listLaunchRuns();default:throw new Error(`Unknown tool: ${e}`)}}async isLaunchConfigToolsEnabled(){const{features:e,ok:t}=await this.fetchRuntimeFeaturesWithStatus();return t&&Object.keys(e).length>0?e[T.LAUNCH_ITEM_FEATURE_KEY]===!0:process.env[T.LAUNCH_TOOLS_ENV_KEY]==="1"}async isHireToolsEnabled(){const{features:e,ok:t}=await this.fetchRuntimeFeaturesWithStatus();return t&&Object.keys(e).length>0?e[T.HIRE_FEATURE_KEY]===!0:process.env[T.HIRE_TOOLS_ENV_KEY]==="1"}async isPencilToolsEnabled(){const{features:e,ok:t}=await this.fetchRuntimeFeaturesWithStatus();return t&&Object.keys(e).length>0?e[T.PENCIL_FEATURE_KEY]===!0:process.env[T.PENCIL_TOOLS_ENV_KEY]==="1"}async fetchRuntimeFeaturesWithStatus(){const e=Date.now();if(this.featuresCache&&e-this.featuresCache.fetchedAt<T.FEATURES_CACHE_TTL_MS)return{features:this.featuresCache.features,ok:this.featuresCache.ok};let t={},r=!1;try{t=await this.agentClient.getRuntimeFeatures(),r=!0}catch(i){l.warn("[McpServer] \u83B7\u53D6\u80FD\u529B\u5F00\u5173\u5931\u8D25\uFF0C\u6309\u542F\u52A8\u671F env \u515C\u5E95: %s",i instanceof Error?i.message:String(i))}return this.featuresCache={features:t,ok:r,fetchedAt:e},{features:t,ok:r}}static MEMORY_TYPES=["recently_memory","agent_memory","project_memory","session_context"];static MEMORY_TOOL_NAMES=new Set(["create_memory","read_memory","update_memory","delete_memory","search_memory","list_memories","get_memory_stats","list_memories_by_file","abandon_memory_update","memory_recurrence","memory_recurrence_complete"]);static findAgentsworkDirSync(e){let t=g.resolve(e);for(;;){if(k.existsSync(g.join(t,".agentswork")))return g.join(t,".agentswork");const r=g.dirname(t);if(r===t)break;t=r}return g.join(g.resolve(e),".agentswork")}static sanitizeRoleDirectoryName(e){return String(e||"").trim().split("").map(r=>ye.has(r)||r.charCodeAt(0)<32?"_":r).join("").replace(/^\.+|\.+$/g,"").trim()||"default-role"}static resolveRoleMemoryDirectoryName(){return T.sanitizeRoleDirectoryName(process.env.AWS_ROLE_NAME||"")}static buildRoleMemoryStorePath(e){const t=process.env.AWS_WORKSPACE_PATH||process.cwd(),r=T.findAgentsworkDirSync(t);return g.join(r,"memory","memory",T.sanitizeRoleDirectoryName(e))}static resolveMemoryStorePaths(){const e=String(process.env.AWS_MEMORY_STORE_PATH||"").trim();if(e)return{instancePath:e,rolePath:e};const t=process.env.AWS_WORKSPACE_PATH||process.cwd(),r=T.findAgentsworkDirSync(t),i=String(process.env.AWS_INSTANCE_MEMORY_STORE_PATH||"").trim()||g.join(r,"memory","server-managed"),s=String(process.env.AWS_ROLE_MEMORY_STORE_PATH||"").trim()||g.join(r,"memory","memory",T.resolveRoleMemoryDirectoryName());return{instancePath:i,rolePath:s}}getRequiredString(e,t){const r=e[t];if(typeof r!="string"||r.trim().length===0)throw new Error(`${t} is required`);return r}getOptionalString(e,t){const r=e[t];return typeof r=="string"?r:void 0}getOptionalNumber(e,t){const r=e[t];return typeof r=="number"?r:void 0}getOptionalStringArray(e,t){const r=e[t];return Array.isArray(r)?r.map(i=>String(i)):void 0}getOptionalMemoryType(e){const t=e.memory_type;if(t!==void 0)return this.parseMemoryType(t)}parseMemoryType(e){if(typeof e!="string")throw new Error(`Invalid memory_type: ${String(e)}`);const t=e.trim();if(!this.isMemoryType(t))throw new Error(`Invalid memory_type: ${e}`);return t}isMemoryType(e){return T.MEMORY_TYPES.some(t=>t===e)}getMemoryStoreForType(e){return this.memoryStore}async readMemoryFromScopedStores(e){if(e.memory_type)return await this.memoryStore.readMemory(e);const t=await this.memoryStore.readMemory({...e,memory_type:"project_memory"}).catch(()=>null);return t||await this.memoryStore.readMemory(e)}async backupProjectMemoryToLocal(e){try{const t=await this.memoryStore.readMemory({uri:e.uri,memory_type:"project_memory"});t&&(await this.roleMemoryStore.deleteMemory({uri:e.uri,memory_type:"project_memory"}).catch(()=>{}),await this.roleMemoryStore.createMemory(t))}catch(t){l.warn("[McpServer] backupProjectMemoryToLocal \u5931\u8D25: uri=%s",e.uri,t)}}async removeProjectMemoryLocalBackup(e){try{await this.roleMemoryStore.deleteMemory({uri:e,memory_type:"project_memory"})}catch(t){l.warn("[McpServer] removeProjectMemoryLocalBackup \u5931\u8D25: uri=%s",e,t)}}async findMemoryStoreForMutation(e){return e.memory_type?{store:this.memoryStore,memory_type:e.memory_type}:await this.memoryStore.readMemory({uri:e.uri,memory_type:"project_memory"}).catch(()=>null)?{store:this.memoryStore,memory_type:"project_memory"}:{store:this.memoryStore}}async reportMemoryStatsToServer(){const e=await this.memoryStore.getStats();try{await this.agentClient.reportMemoryStats(e)}catch(t){l.warn("[McpServer] \u4E0A\u62A5 memory \u7EDF\u8BA1\u5931\u8D25:",t)}}sanitizeToolUseArgs(e,t){if(!T.MEMORY_TOOL_NAMES.has(e))return t;const r={},i=this.getOptionalString(t,"uri"),s=this.getOptionalString(t,"memory_type"),n=this.getOptionalNumber(t,"limit");return i&&(r.uri=i),s&&(r.memory_type=s),typeof n=="number"&&(r.limit=n),e==="search_memory"&&(r.queryProvided=typeof t.query=="string"&&t.query.length>0,t.keyword_mode!==void 0&&(r.keyword_mode=t.keyword_mode)),r}stripAutoDelegateForReporting(e){if(!e||typeof e!="object")return e;const t=e,r=Array.isArray(t.directMessages)?t.directMessages:[],i=Array.isArray(t.groupMessages)?t.groupMessages:[],s=a=>!!a&&typeof a=="object"&&"_acodeAutoDelegate"in a;if(!r.some(s))return e;const o=r.filter(a=>!s(a));return o.length===0&&i.length===0?null:{...t,directMessages:o}}async handleCreateMemory(e){const t=this.normalizeBoundFiles(this.getOptionalStringArray(e,"bound_files"));await this.validateBoundFilesExist(t);let r,i;if(t&&t.length>0){r={};for(const o of t){const a=await this.calculateFileMd5(o);a&&(r[o]=a)}i=new Date().toISOString()}const s={memory_type:this.parseMemoryType(this.getRequiredString(e,"memory_type")),uri:this.getRequiredString(e,"uri"),title:this.getOptionalString(e,"title"),content:this.getRequiredString(e,"content"),keywords:this.getOptionalStringArray(e,"keywords"),bound_files:t,file_md5_map:r,last_check_time:i},n=await this.memoryStore.createMemory(s);return s.memory_type==="project_memory"&&this.backupProjectMemoryToLocal(s).catch(o=>{l.warn("[McpServer] \u5907\u4EFD project_memory \u5230\u672C\u5730\u5931\u8D25:",o)}),await this.reportMemoryStatsToServer(),this.toMemoryWriteResult(n)}async handleReadMemory(e){const t={uri:this.getRequiredString(e,"uri"),memory_type:this.getOptionalMemoryType(e)};return await this.readMemoryFromScopedStores(t)}async handleUpdateMemory(e){const t=typeof e.old_string=="string"||typeof e.new_string=="string",r=typeof e.old_string=="string"&&typeof e.new_string=="string",i=this.getOptionalString(e,"append");if(t&&!r)throw new Error("old_string and new_string must be provided together");const s={uri:this.getRequiredString(e,"uri"),memory_type:this.getOptionalMemoryType(e),title:this.getOptionalString(e,"title"),old_string:this.getOptionalString(e,"old_string"),new_string:this.getOptionalString(e,"new_string"),append:i,keywords:this.getOptionalStringArray(e,"keywords"),bound_files:this.normalizeBoundFiles(this.getOptionalStringArray(e,"bound_files"))},n=await this.findMemoryStoreForMutation(s),o=await n.store.readMemory({uri:s.uri,memory_type:n.memory_type??s.memory_type});s.bound_files!==void 0?await this.validateBoundFilesExist(s.bound_files):o?.bound_files&&o.bound_files.length>0&&await this.validateBoundFilesExist(o.bound_files);const a=s.bound_files??o?.bound_files;let m,d;if(a&&a.length>0){m={};for(const u of a){const M=await this.calculateFileMd5(u);M&&(m[u]=M)}d=new Date().toISOString()}const p=await n.store.updateMemory({...s,memory_type:n.memory_type??s.memory_type,file_md5_map:m,last_check_time:d});if(n.memory_type==="project_memory"&&this.backupProjectMemoryToLocal({...s,memory_type:"project_memory",file_md5_map:m,last_check_time:d}).catch(u=>{l.warn("[McpServer] \u5907\u4EFD project_memory \u66F4\u65B0\u5230\u672C\u5730\u5931\u8D25:",u)}),await this.reportMemoryStatsToServer(),n.memory_type==="project_memory"&&o?.memory_status==="updating")try{await this.memoryStore.releaseMemoryClaim(s.uri),this.activeLeaseUris.delete(s.uri),this.activeLeaseUris.size===0&&this.stopLeaseRenewal()}catch(u){l.warn("[McpServer] \u91CA\u653E memory claim \u5931\u8D25: uri=%s, error=%s",s.uri,u instanceof Error?u.message:String(u))}return this.toMemoryWriteResult(p)}async handleDeleteMemory(e){const t=typeof e.uri=="string"?e.uri:void 0,r=Array.isArray(e.memories)?e.memories:void 0;if(t&&r&&r.length>0)throw new Error("delete_memory \u4E0D\u652F\u6301\u540C\u65F6\u4F20\u5165 uri \u548C memories\uFF0C\u8BF7\u4E8C\u9009\u4E00");if(!t&&(!r||r.length===0))throw new Error("delete_memory \u9700\u8981 uri \u6216 memories \u53C2\u6570");if(t){const o=this.getOptionalMemoryType(e);return{deleted:await this.deleteMemorySingle(t,o)}}let i=0;const s=[],n=[];for(let o=0;o<r.length;o++){const a=r[o];if(typeof a!="object"||a===null){n.push({uri:String(a),reason:`memories[${o}] \u4E0D\u662F\u5BF9\u8C61`});continue}const m=a,d=typeof m.uri=="string"?m.uri:"";if(!d){n.push({uri:"",reason:`memories[${o}].uri \u7F3A\u5931`});continue}const p=typeof m.memory_type=="string"?this.parseMemoryType(m.memory_type):void 0;try{await this.deleteMemorySingle(d,p,!0)?i++:s.push(d)}catch(u){n.push({uri:d,reason:u instanceof Error?u.message:String(u)})}}return i>0&&await this.reportMemoryStatsToServer(),{deleted:i,not_found:s,failed:n}}async deleteMemorySingle(e,t,r=!1){const i={uri:e,memory_type:t},s=await this.findMemoryStoreForMutation(i),n=s.memory_type??i.memory_type,o=await s.store.deleteMemory({...i,memory_type:n});return o&&(n==="project_memory"&&this.removeProjectMemoryLocalBackup(e).catch(a=>{l.warn("[McpServer] \u5220\u9664 project_memory \u672C\u5730\u5907\u4EFD\u5931\u8D25:",a)}),r||await this.reportMemoryStatsToServer()),o}async handleSearchMemory(e){const t=this.getOptionalString(e,"scope"),r=t==="children"||t==="all"?t:"own",i=this.getOptionalString(e,"keyword_mode"),s=i==="all"?"all":i==="any"?"any":void 0,n={query:this.getRequiredString(e,"query"),limit:this.getOptionalNumber(e,"limit"),memory_type:this.getOptionalMemoryType(e),keywords:this.getOptionalStringArray(e,"keywords"),keyword_mode:s,scope:r};if(r==="children")return await this.memoryStore.searchMemory(n);const o=await this.searchOwnMemories(n);if(r==="own")return o;const a=await this.memoryStore.searchMemory({...n,scope:"children"});return this.mergeSearchResults(o,a,n.limit)}async searchOwnMemories(e){return await this.memoryStore.searchMemory(e)}mergeSearchResults(e,t,r){const i=new Set,s=typeof r=="number"&&r>0?r:10,n=[...e.results,...t.results].filter(o=>{const a=o.uri;return i.has(a)?!1:(i.add(a),!0)}).sort((o,a)=>a.updatedAt.localeCompare(o.updatedAt)).slice(0,s);return{query:e.query||t.query,results:n}}async handleListMemories(e){const t=this.getRequiredString(e,"memory_type"),r=this.getOptionalNumber(e,"offset"),i=this.getOptionalNumber(e,"limit"),s=Math.max(0,Math.floor(r??0)),n=i!==void 0&&i>=1?Math.floor(i):fe,o=await this.memoryStore.listByType(t),a=o.length,m=o.slice(s,s+n);return{memory_type:t,total:a,offset:s,limit:n,has_more:s+n<a,memories:m}}async handleGetMemoryStats(e){const t=await this.memoryStore.getStats(),r=this.getOptionalMemoryType(e);return r?{memory_type:r,total:t.by_type[r].count,by_type:{[r]:t.by_type[r]}}:t}async handleListMemoriesByFile(e){const t=this.getRequiredString(e,"file_path"),r=this.normalizeBoundFilePath(t),i=this.getOptionalMemoryType(e),s=this.getOptionalString(e,"scope"),n=s==="own"||s==="children"?s:"all",o=async()=>await this.memoryStore.listByFile(r,{memory_type:i,scope:"children"}).catch(()=>[]);if(n==="children"){const u=await o();return{file_path:r,count:u.length,memories:u.map(M=>this.toMemoryRecordWithMetadata(M))}}if(n==="own"){const u=await this.collectOwnMemoriesByFile(r,i);return{file_path:r,count:u.length,memories:u.map(M=>this.toMemoryRecordWithMetadata(M))}}const[a,m,d]=await Promise.all([this.memoryStore.listByFile(r,{memory_type:i,scope:"all"}).catch(()=>[]),this.searchChildMemoriesByFileLocal(r,i).catch(()=>[]),this.searchPeerMemoriesByFileLocal(r,i).catch(()=>[])]),p=this.mergeIdDedupe(this.mergeIdDedupe(a,m),d);return{file_path:r,count:p.length,memories:p.map(u=>this.toMemoryRecordWithMetadata(u))}}mergeIdDedupe(e,t){const r=new Set;for(const s of e)s.id&&r.add(s.id);const i=[...e];for(const s of t)s.id&&!r.has(s.id)&&(i.push(s),r.add(s.id));return i.sort((s,n)=>n.updatedAt.localeCompare(s.updatedAt)),i}async searchChildMemoriesByFileLocal(e,t){const r=process.env.AWS_WORKSPACE_PATH||process.cwd(),i=this.normalizeBoundFilePath(e),n=(i.startsWith("./")?i.substring(2):i).split("/"),o=[],a=new Set,{access:m,readdir:d,readFile:p}=await import("node:fs/promises");for(let u=n.length-1;u>=1;u--){const M=n.slice(0,u),h="./"+n.slice(u).join("/"),w=g.join(r,...M);if(w===r)continue;const c=g.join(w,".agentswork");try{await m(c)}catch{continue}const _=g.join(c,"memory","memory");let f;try{f=(await d(_,{withFileTypes:!0})).filter(E=>E.isDirectory()).map(E=>E.name)}catch{continue}for(const S of f){const E=g.join(_,S);let P;try{P=await d(E)}catch{continue}for(const y of P){if(!y.endsWith(".json"))continue;const b=g.join(E,y);let v;try{v=await p(b,"utf-8")}catch{continue}let A;try{A=JSON.parse(v)}catch{continue}if(A.by_uri)for(const[N,$]of Object.entries(A.by_uri)){if(!$)continue;const B=$.id||N;a.has(B)||t&&$.memory_type!==t||$.bound_files&&$.bound_files.length>0&&$.bound_files.some(V=>this.normalizeBoundFilePath(V)===h)&&(a.add(B),o.push({...$,uri:$.uri||N}))}}}}return o.sort((u,M)=>String(M.updatedAt??"").localeCompare(String(u.updatedAt??""))),o}async searchPeerMemoriesByFileLocal(e,t){if(!this.hasRoleName||!this.initialRoleName)return[];const r=process.env.AWS_WORKSPACE_PATH||process.cwd(),i=this.normalizeBoundFilePath(e),s=g.join(r,".agentswork","memory","memory"),{access:n,readdir:o,readFile:a}=await import("node:fs/promises");try{await n(s)}catch{return[]}let m;try{m=(await o(s,{withFileTypes:!0})).filter(M=>M.isDirectory()).map(M=>M.name)}catch{return[]}const d=[],p=new Set;for(const u of m){if(u===this.initialRoleName)continue;const M=g.join(s,u);let R;try{R=await o(M)}catch{continue}for(const h of R){if(!h.endsWith(".json"))continue;let w;try{w=JSON.parse(await a(g.join(M,h),"utf-8"))}catch{continue}if(w.by_uri)for(const[c,_]of Object.entries(w.by_uri)){if(!_)continue;const f=_.id||c;p.has(f)||_.memory_type==="project_memory"&&(t&&_.memory_type!==t||_.bound_files&&_.bound_files.length>0&&_.bound_files.some(E=>this.normalizeBoundFilePath(E)===i)&&(p.add(f),d.push({..._,uri:_.uri||c,readonly:!0,source_role_name:u})))}}}return d.sort((u,M)=>String(M.updatedAt??"").localeCompare(String(u.updatedAt??""))),d}async collectOwnMemoriesByFile(e,t){return await this.memoryStore.listByFile(e,{memory_type:t})}async handleAbandonMemoryUpdate(e){const t=this.getRequiredString(e,"uri"),r=this.getOptionalMemoryType(e),i=await this.memoryStore.readMemory({uri:t,memory_type:r});return i?.bound_files&&i.bound_files.length>0&&await this.validateBoundFilesExist(i.bound_files),await this.memoryStore.releaseMemoryClaim(t),i?.memory_type==="project_memory"&&this.backupProjectMemoryToLocal({uri:t,memory_type:"project_memory"}).catch(s=>{l.info(`[McpServer] abandon_memory_update: \u540C\u6B65\u672C\u5730\u5907\u4EFD\u5931\u8D25: ${t}`,s)}),this.activeLeaseUris.delete(t),this.activeLeaseUris.size===0&&this.stopLeaseRenewal(),{success:!0,uri:t,message:"Memory \u66F4\u65B0\u72B6\u6001\u5DF2\u6E05\u9664"}}async handleMemoryRecurrence(e){const t=Math.max(1,e?.limit??10);try{((await this.memoryStore.markExpiredMemoriesRecalling()).uris?.length??0)>0&&this.startLeaseRenewal()}catch(a){l.warn("[McpServer] \u539F\u5B50\u8BA4\u9886\u8FC7\u671F\u8BB0\u5FC6\u5931\u8D25: %s",a instanceof Error?a.message:String(a))}const r=await this.memoryStore.listExpiredRecentlyMemories();if(r.length===0)return{memories:[],count:0,limit:t,remaining:0,totalExpired:0,message:"\u6CA1\u6709\u5F85\u56DE\u5FC6\u7684\u5373\u5C06\u9057\u5FD8\u8BB0\u5FC6\u3002"};const s=[...r].sort((a,m)=>{const d=new Date(a.expiresAt||a.createdAt||0).getTime(),p=new Date(m.expiresAt||m.createdAt||0).getTime();return d-p}).slice(0,t),n=Math.max(0,r.length-s.length);return{memories:s.map(a=>({uri:a.uri,title:a.title,domain:a.domain,path:a.path,memory_status:"recalling",contentPreview:typeof a.content=="string"&&a.content.length>200?a.content.substring(0,200)+"...":a.content,createdAt:a.createdAt,updatedAt:a.updatedAt})),count:s.length,limit:t,remaining:n,totalExpired:r.length,message:n>0?`\u672C\u6B21\u5904\u7406 ${s.length} \u6761\u5373\u5C06\u9057\u5FD8\u7684\u8BB0\u5FC6\uFF08\u6700\u65E9\u8FC7\u671F\u4F18\u5148\uFF09\uFF0C\u5269\u4F59 ${n} \u6761\u5F85\u5904\u7406\u3002
|
|
3
|
+
`)}`)}toMemoryWriteResult(e){return{id:e.id,uri:e.uri,domain:e.domain,path:e.path,title:e.title,memory_type:e.memory_type,createdAt:e.createdAt,updatedAt:e.updatedAt,version:e.version,keywords:e.keywords,bound_files:e.bound_files}}toMemoryRecordWithMetadata(e){return{id:e.id,uri:e.uri,domain:e.domain,path:e.path,title:e.title,content:e.content,memory_type:e.memory_type,createdAt:e.createdAt,updatedAt:e.updatedAt,version:e.version,keywords:e.keywords,bound_files:e.bound_files,file_md5_map:e.file_md5_map,memory_status:e.memory_status,updating_agent_id:e.updating_agent_id,last_check_time:e.last_check_time,path_prefix:e.path_prefix,readonly:e.readonly,source_agent_id:e.source_agent_id,source_display_name:e.source_display_name,source_role_name:e.source_role_name,source_workspace_path:e.source_workspace_path}}constructor(){this.agentClient=new se,this.messageBuffer=new ue,this.initialRoleName=T.resolveRoleMemoryDirectoryName(),this.hasRoleName=!!process.env.AWS_ROLE_NAME;const e=T.resolveMemoryStorePaths();this.memoryStore=new pe(this.agentClient),this.roleMemoryStore=new L(e.rolePath),this.sessionContextMemoryStore=new L(_.join(_.dirname(e.rolePath),"..","session_context")),this.isSubAgent=process.env.AWS_SUB_AGENT==="true",this.contextManager=new de(this.sessionContextMemoryStore),this.server=new Q({name:oe,version:ae},{capabilities:{tools:{}}}),this.setupHandlers()}setupHandlers(){this.server.setRequestHandler(re,async()=>{let e=this.isSubAgent?F.filter(t=>W.has(t.name)):F;return!this.isSubAgent&&!await this.isLaunchConfigToolsEnabled()&&(e=e.filter(t=>!q.has(t.name))),!this.isSubAgent&&!await this.isHireToolsEnabled()&&(e=e.filter(t=>!z.has(t.name))),!this.isSubAgent&&!await this.isPencilToolsEnabled()&&(e=e.filter(t=>!G.has(t.name))),{tools:e}}),this.server.setRequestHandler(te,async(e,t)=>{const{name:r,arguments:i}=e.params;try{const s=await this.handleToolCall(r,i,t?.signal);return{content:this.buildToolResultContent(s)}}catch(s){const n=s instanceof Error?s.message:String(s),o=s instanceof he?{error:n,...s.details}:{error:n};return l.error("[McpServer] \u5DE5\u5177\u8C03\u7528\u5F02\u5E38: tool=%s, error=%s, stack=%s",r,n,s instanceof Error?s.stack:"(no stack)"),{content:[{type:"text",text:JSON.stringify(o,null,2)}],isError:!0}}})}async handlePencilExportImage(e){const t=typeof e.savePath=="string"?e.savePath.trim():"",r=await this.agentClient.callAgentScopedTool("pencil_export_image",e),i=typeof r?.image=="string"?r.image:"";if(!i)return r;const s=i.startsWith("data:")?i.slice(i.indexOf(",")+1):i,n={...r};delete n.image,delete n.mimeType,n.sizeKb=Math.ceil(s.length*3/4/1024);try{const{mkdir:o,writeFile:a}=await import("node:fs/promises");let m;if(t){const d=_.resolve(process.env.AWS_WORKSPACE_PATH||process.cwd());m=_.resolve(d,t)}else{const p=(typeof r?.docId=="string"?r.docId:"").replace(/[^a-zA-Z0-9_-]/g,"").slice(0,40)||"doc",u=_.join(x.tmpdir(),"pencil-export");await o(u,{recursive:!0}),m=_.join(u,`${p}-${Date.now()}-${Math.random().toString(36).slice(2,8)}.png`)}return await o(_.dirname(m),{recursive:!0}),await a(m,Buffer.from(s,"base64")),{...n,savedTo:m,temp:!t}}catch(o){return{...n,savedTo:null,saveError:o instanceof Error?o.message:String(o)}}}static PENCIL_EXPORT_FORMATS=new Set(["svg","html","png","jpg","webp","pptx","fig","jsx"]);async handlePencilExportDocument(e){const t=typeof e.format=="string"&&e.format.trim()?e.format.trim().toLowerCase():"svg";if(!T.PENCIL_EXPORT_FORMATS.has(t))throw new Error(`\u4E0D\u652F\u6301\u7684\u5BFC\u51FA\u683C\u5F0F: ${t}\uFF08\u652F\u6301 svg/html/png/jpg/webp/pptx/fig/jsx\uFF1Bpdf \u6682\u4E0D\u652F\u6301\uFF09`);const r=typeof e.nodeId=="string"&&e.nodeId.trim()?e.nodeId.trim():"";if(t==="jsx"&&!r)throw new Error("jsx \u5BFC\u51FA\u9700\u8981\u4F20 nodeId\uFF08\u6765\u81EA pencil_get_tree\uFF09\uFF0C\u5B83\u6309\u5355\u8282\u70B9\u751F\u6210 React \u7EC4\u4EF6");const i=typeof e.savePath=="string"?e.savePath.trim():"",s=_.resolve(process.env.AWS_WORKSPACE_PATH||process.cwd()),n=await this.agentClient.callAgentScopedTool("pencil_export_document",e),o=typeof n?.snapshotJson=="string"?n.snapshotJson:"";if(!o)return n;const{mkdir:a,writeFile:m,stat:d}=await import("node:fs/promises"),u=(typeof n?.docId=="string"?n.docId:"").replace(/[^a-zA-Z0-9_-]/g,"").slice(0,40)||"doc",M=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,R=_.join(x.tmpdir(),"pencil-export");await a(R,{recursive:!0});const h=_.join(R,`${u}-${M}.snapshot.json`);await m(h,o,"utf8");const w=t,c=i?_.resolve(s,i):_.join(R,`${u}-${M}.${w}`),y=_.resolve(process.env.AWS_OPEN_PENCIL_HOME||Z(new URL("../../../../open-pencil",import.meta.url))),g=[{cmd:process.execPath,entry:_.join(y,"packages","cli","dist","index.mjs")},{cmd:"bun",entry:_.join(y,"packages","cli","src","index.ts")}].filter(E=>P.existsSync(E.entry));if(g.length===0)throw new Error(`\u672A\u627E\u5230 open-pencil CLI\uFF08\u67E5\u627E\u76EE\u5F55 ${y}\uFF09\uFF0C\u8BF7\u786E\u8BA4\u5B89\u88C5\u5E03\u5C40\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_OPEN_PENCIL_HOME \u6307\u5411 open-pencil \u4ED3\u5E93\u6839\u76EE\u5F55`);const S=["export",h,"--snapshot","-f",t,"-o",c];r&&S.push("--node",r),t==="html"&&S.push("--html","standalone"),(t==="png"||t==="jpg"||t==="webp")&&(typeof e.scale=="number"&&e.scale>0&&S.push("--scale",String(e.scale)),typeof e.quality=="number"&&e.quality>0&&S.push("--quality",String(e.quality)));const v=[];let k=!1;for(const E of g)try{await this.runPencilCli(E.cmd,[E.entry,...S],y),k=!0;break}catch(A){v.push(`${_.basename(E.cmd)}: ${A instanceof Error?A.message:String(A)}`)}if(!k)throw new Error(`\u753B\u5E03\u5BFC\u51FA\u5931\u8D25\uFF08format=${t}\uFF09\uFF1A${v.join("\uFF1B")||"\u672A\u77E5\u9519\u8BEF"}`);let f=null;try{f=Math.ceil((await d(c)).size/1024)}catch{f=null}const b={...n};return delete b.snapshotJson,{...b,format:t,savedTo:c,temp:!i,sizeKb:f}}runPencilCli(e,t,r){return new Promise((i,s)=>{X(e,t,{cwd:r,timeout:18e4,maxBuffer:16*1024*1024},(n,o,a)=>{if(n){const m=String(a||o||"").trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" | ");s(new Error(m||n.message));return}i(String(o||""))})})}stripRenderImageForReporting(e){if(e&&typeof e=="object"&&!Array.isArray(e)){const t=e;let r=null;if(typeof t.image=="string"){const s=t.image.length,n=Math.ceil(s*3/4/1024);r={...t,image:`<PNG base64 \u5DF2\u7701\u7565\uFF0C\u7EA6 ${n}KB\uFF0C\u6B63\u6587\u89C1 t_pencil_doc.render_image>`}}const i=r??t;if(typeof i.snapshotJson=="string"){const s=Math.ceil(i.snapshotJson.length/1024);r={...i,snapshotJson:`<GraphSnapshot JSON \u5DF2\u7701\u7565\uFF0C\u7EA6 ${s}KB\uFF0C\u6743\u5A01\u6570\u636E\u89C1 t_pencil_doc.snapshot>`}}if(r)return r}return e}buildToolResultContent(e){if(e&&typeof e=="object"&&!Array.isArray(e)){const t=e;if(typeof t.image=="string"&&typeof t.mimeType=="string"){const r={...t};delete r.image;const i=[{type:"image",data:t.image,mimeType:t.mimeType}];return Object.keys(r).length>0&&i.push({type:"text",text:JSON.stringify(r,null,2)}),i}}return[{type:"text",text:JSON.stringify(e,null,2)}]}async handleToolCall(e,t,r){const i=t?._aws_sub_agent===!0,s=t?._aws_silent_poll===!0,n=t?._aws_force_inject===!0,o={...t};delete o._aws_sub_agent,delete o._aws_silent_poll,delete o._aws_force_inject;const a=i?null:this.agentClient.getStatusReporter();a&&!s&&this.safeReportStatus(()=>a.reportToolUse(e,this.sanitizeToolUseArgs(e,o)));try{const m=await this.executeToolCall(e,o,{forceInject:n,signal:r});if(a&&!s){const d=this.stripAutoDelegateForReporting(m);d!==null&&(this.safeReportStatus(()=>a.reportToolResult(this.stripRenderImageForReporting(d))),this.safeReportStatus(()=>a.reportThinking()))}return m}catch(m){throw a&&!s&&this.safeReportStatus(()=>a.reportToolError(m)),m}}safeReportStatus(e){try{e()}catch(t){l.warn("[McpServer] \u72B6\u6001\u4E0A\u62A5\u5931\u8D25\uFF08\u5DF2\u5FFD\u7565\uFF0C\u4E0D\u5F71\u54CD\u5DE5\u5177\u8C03\u7528\uFF09: %s",t instanceof Error?t.message:String(t))}}async executeToolCall(e,t,r={}){if(this.isSubAgent&&!W.has(e))throw new Error(`Sub-agent is not allowed to call tool: ${e}`);if(q.has(e)&&!await this.isLaunchConfigToolsEnabled())throw new Error("\u542F\u52A8\u9879\u7BA1\u7406\u80FD\u529B\u672A\u5F00\u542F\uFF08\u8BF7\u5148\u5728\u80FD\u529B\u914D\u7F6E\u4E2D\u5F00\u542F\u300CAgent \u7CFB\u7EDF\u7BA1\u7406 \u2192 \u542F\u52A8\u9879\u7BA1\u7406\u300D\u540E\u518D\u8C03\u7528 launch_config_* \u5DE5\u5177\uFF09");if(z.has(e)&&!await this.isHireToolsEnabled())throw new Error("\u62DB\u8058\u5DE5\u5177\u80FD\u529B\u672A\u5F00\u542F\uFF08\u8BF7\u5148\u5728\u80FD\u529B\u914D\u7F6E\u4E2D\u5F00\u542F\u300CAgent \u7CFB\u7EDF\u7BA1\u7406 \u2192 \u62DB\u8058\u5DE5\u5177\u300D\u540E\u518D\u8C03\u7528 hire_colleague\uFF09");if(G.has(e)&&!await this.isPencilToolsEnabled())throw new Error("\u8BBE\u8BA1\u753B\u5E03\u80FD\u529B\u672A\u5F00\u542F\uFF08\u8BF7\u5148\u5728\u80FD\u529B\u914D\u7F6E\u4E2D\u5F00\u542F\u300C\u8BBE\u8BA1\u753B\u5E03 (Pencil)\u300D\u540E\u518D\u8C03\u7528 pencil_* \u5DE5\u5177\uFF09");switch(e){case"get_colleague":return await this.agentClient.discoverColleagues();case"get_group_rooms":return await this.agentClient.discoverGroupRooms();case"get_profile":return await this.agentClient.getProfile();case"hire_colleague":return await this.handleHireColleague(t);case"send_group":return await this.handleSendGroup(t);case"send_private":return await this.handleSendPrivate(t);case"poll_message":return await this.handlePollMessage(r.signal);case"get_message":return this.handleGetMessage(r.forceInject===!0);case"get_dm_history":return await this.handleGetDmHistory(t);case"get_group_history":return await this.handleGetGroupHistory(t);case"create_meeting":case"leave_meeting":case"end_meeting":case"meeting_speak":case"get_meeting_info":case"my_meetings":return await this.agentClient.callAgentScopedTool(e,t);case"pencil_create_document":case"pencil_list_documents":case"pencil_open_document":case"pencil_close_document":case"pencil_get_tree":case"pencil_get_changes":case"pencil_create_nodes":case"pencil_update_nodes":case"pencil_delete_nodes":case"pencil_share_document":case"pencil_revoke_share":case"pencil_delete_document":case"pencil_rename_document":return await this.agentClient.callAgentScopedTool(e,t);case"pencil_export_image":return await this.handlePencilExportImage(t);case"pencil_export_document":return await this.handlePencilExportDocument(t);case"my_task":return await this.agentClient.getMyTasks();case"create_task_instance_comment":return await this.handleCreateTaskInstanceComment(t);case"submit_task_result":return await this.handleSubmitTaskResult(t);case"start_task_rollback":return await this.handleStartTaskRollback(t);case"finish_task_rollback":return await this.handleFinishTaskRollback(t);case"reject_task":return await this.handleRejectTask(t);case"terminate_task":return await this.handleTerminateTask(t);case"create_memory":return await this.handleCreateMemory(t);case"read_memory":return await this.handleReadMemory(t);case"update_memory":return await this.handleUpdateMemory(t);case"delete_memory":return await this.handleDeleteMemory(t);case"search_memory":return await this.handleSearchMemory(t);case"list_memories":return await this.handleListMemories(t);case"get_memory_stats":return await this.handleGetMemoryStats(t);case"list_memories_by_file":return await this.handleListMemoriesByFile(t);case"abandon_memory_update":return await this.handleAbandonMemoryUpdate(t);case"memory_recurrence":return await this.handleMemoryRecurrence(t);case"memory_recurrence_complete":return await this.handleMemoryRecurrenceComplete(t);case"get_debug_log_config":return await this.agentClient.getDebugLogConfig();case"query_debug_logs":return await this.agentClient.queryDebugLogs(t);case"query_file_changes_history":return await this.agentClient.queryFileChangesHistory(t);case"launch_config_list":return await this.agentClient.listLaunchConfigs();case"launch_config_create":return await this.agentClient.createLaunchConfig(t);case"launch_config_update":return await this.agentClient.updateLaunchConfig(t);case"launch_config_delete":return await this.agentClient.deleteLaunchConfig(String(t?.configId??""));case"launch_config_start":return await this.agentClient.startLaunchConfig(t);case"launch_config_restart":return await this.agentClient.restartLaunchConfig(t);case"launch_config_stop":return await this.agentClient.stopLaunchConfig(String(t?.configId??""));case"launch_config_logs":return await this.agentClient.getLaunchLogs(t);case"launch_config_status":return await this.agentClient.listLaunchRuns();default:throw new Error(`Unknown tool: ${e}`)}}async isLaunchConfigToolsEnabled(){const{features:e,ok:t}=await this.fetchRuntimeFeaturesWithStatus();return t&&Object.keys(e).length>0?e[T.LAUNCH_ITEM_FEATURE_KEY]===!0:process.env[T.LAUNCH_TOOLS_ENV_KEY]==="1"}async isHireToolsEnabled(){const{features:e,ok:t}=await this.fetchRuntimeFeaturesWithStatus();return t&&Object.keys(e).length>0?e[T.HIRE_FEATURE_KEY]===!0:process.env[T.HIRE_TOOLS_ENV_KEY]==="1"}async isPencilToolsEnabled(){const{features:e,ok:t}=await this.fetchRuntimeFeaturesWithStatus();return t&&Object.keys(e).length>0?e[T.PENCIL_FEATURE_KEY]===!0:process.env[T.PENCIL_TOOLS_ENV_KEY]==="1"}async fetchRuntimeFeaturesWithStatus(){const e=Date.now();if(this.featuresCache&&e-this.featuresCache.fetchedAt<T.FEATURES_CACHE_TTL_MS)return{features:this.featuresCache.features,ok:this.featuresCache.ok};let t={},r=!1;try{t=await this.agentClient.getRuntimeFeatures(),r=!0}catch(i){l.warn("[McpServer] \u83B7\u53D6\u80FD\u529B\u5F00\u5173\u5931\u8D25\uFF0C\u6309\u542F\u52A8\u671F env \u515C\u5E95: %s",i instanceof Error?i.message:String(i))}return this.featuresCache={features:t,ok:r,fetchedAt:e},{features:t,ok:r}}static MEMORY_TYPES=["recently_memory","agent_memory","project_memory","session_context"];static MEMORY_TOOL_NAMES=new Set(["create_memory","read_memory","update_memory","delete_memory","search_memory","list_memories","get_memory_stats","list_memories_by_file","abandon_memory_update","memory_recurrence","memory_recurrence_complete"]);static findAgentsworkDirSync(e){let t=_.resolve(e);for(;;){if(P.existsSync(_.join(t,".agentswork")))return _.join(t,".agentswork");const r=_.dirname(t);if(r===t)break;t=r}return _.join(_.resolve(e),".agentswork")}static sanitizeRoleDirectoryName(e){return String(e||"").trim().split("").map(r=>ye.has(r)||r.charCodeAt(0)<32?"_":r).join("").replace(/^\.+|\.+$/g,"").trim()||"default-role"}static resolveRoleMemoryDirectoryName(){return T.sanitizeRoleDirectoryName(process.env.AWS_ROLE_NAME||"")}static buildRoleMemoryStorePath(e){const t=process.env.AWS_WORKSPACE_PATH||process.cwd(),r=T.findAgentsworkDirSync(t);return _.join(r,"memory","memory",T.sanitizeRoleDirectoryName(e))}static resolveMemoryStorePaths(){const e=String(process.env.AWS_MEMORY_STORE_PATH||"").trim();if(e)return{instancePath:e,rolePath:e};const t=process.env.AWS_WORKSPACE_PATH||process.cwd(),r=T.findAgentsworkDirSync(t),i=String(process.env.AWS_INSTANCE_MEMORY_STORE_PATH||"").trim()||_.join(r,"memory","server-managed"),s=String(process.env.AWS_ROLE_MEMORY_STORE_PATH||"").trim()||_.join(r,"memory","memory",T.resolveRoleMemoryDirectoryName());return{instancePath:i,rolePath:s}}getRequiredString(e,t){const r=e[t];if(typeof r!="string"||r.trim().length===0)throw new Error(`${t} is required`);return r}getOptionalString(e,t){const r=e[t];return typeof r=="string"?r:void 0}getOptionalNumber(e,t){const r=e[t];return typeof r=="number"?r:void 0}getOptionalStringArray(e,t){const r=e[t];return Array.isArray(r)?r.map(i=>String(i)):void 0}getOptionalMemoryType(e){const t=e.memory_type;if(t!==void 0)return this.parseMemoryType(t)}parseMemoryType(e){if(typeof e!="string")throw new Error(`Invalid memory_type: ${String(e)}`);const t=e.trim();if(!this.isMemoryType(t))throw new Error(`Invalid memory_type: ${e}`);return t}isMemoryType(e){return T.MEMORY_TYPES.some(t=>t===e)}getMemoryStoreForType(e){return this.memoryStore}async readMemoryFromScopedStores(e){if(e.memory_type)return await this.memoryStore.readMemory(e);const t=await this.memoryStore.readMemory({...e,memory_type:"project_memory"}).catch(()=>null);return t||await this.memoryStore.readMemory(e)}async backupProjectMemoryToLocal(e){try{const t=await this.memoryStore.readMemory({uri:e.uri,memory_type:"project_memory"});t&&(await this.roleMemoryStore.deleteMemory({uri:e.uri,memory_type:"project_memory"}).catch(()=>{}),await this.roleMemoryStore.createMemory(t))}catch(t){l.warn("[McpServer] backupProjectMemoryToLocal \u5931\u8D25: uri=%s",e.uri,t)}}async removeProjectMemoryLocalBackup(e){try{await this.roleMemoryStore.deleteMemory({uri:e,memory_type:"project_memory"})}catch(t){l.warn("[McpServer] removeProjectMemoryLocalBackup \u5931\u8D25: uri=%s",e,t)}}async findMemoryStoreForMutation(e){return e.memory_type?{store:this.memoryStore,memory_type:e.memory_type}:await this.memoryStore.readMemory({uri:e.uri,memory_type:"project_memory"}).catch(()=>null)?{store:this.memoryStore,memory_type:"project_memory"}:{store:this.memoryStore}}async reportMemoryStatsToServer(){const e=await this.memoryStore.getStats();try{await this.agentClient.reportMemoryStats(e)}catch(t){l.warn("[McpServer] \u4E0A\u62A5 memory \u7EDF\u8BA1\u5931\u8D25:",t)}}sanitizeToolUseArgs(e,t){if(!T.MEMORY_TOOL_NAMES.has(e))return t;const r={},i=this.getOptionalString(t,"uri"),s=this.getOptionalString(t,"memory_type"),n=this.getOptionalNumber(t,"limit");return i&&(r.uri=i),s&&(r.memory_type=s),typeof n=="number"&&(r.limit=n),e==="search_memory"&&(r.queryProvided=typeof t.query=="string"&&t.query.length>0,t.keyword_mode!==void 0&&(r.keyword_mode=t.keyword_mode)),r}stripAutoDelegateForReporting(e){if(!e||typeof e!="object")return e;const t=e,r=Array.isArray(t.directMessages)?t.directMessages:[],i=Array.isArray(t.groupMessages)?t.groupMessages:[],s=a=>!!a&&typeof a=="object"&&"_acodeAutoDelegate"in a;if(!r.some(s))return e;const o=r.filter(a=>!s(a));return o.length===0&&i.length===0?null:{...t,directMessages:o}}async handleCreateMemory(e){const t=this.normalizeBoundFiles(this.getOptionalStringArray(e,"bound_files"));await this.validateBoundFilesExist(t);let r,i;if(t&&t.length>0){r={};for(const o of t){const a=await this.calculateFileMd5(o);a&&(r[o]=a)}i=new Date().toISOString()}const s={memory_type:this.parseMemoryType(this.getRequiredString(e,"memory_type")),uri:this.getRequiredString(e,"uri"),title:this.getOptionalString(e,"title"),content:this.getRequiredString(e,"content"),keywords:this.getOptionalStringArray(e,"keywords"),bound_files:t,file_md5_map:r,last_check_time:i},n=await this.memoryStore.createMemory(s);return s.memory_type==="project_memory"&&this.backupProjectMemoryToLocal(s).catch(o=>{l.warn("[McpServer] \u5907\u4EFD project_memory \u5230\u672C\u5730\u5931\u8D25:",o)}),await this.reportMemoryStatsToServer(),this.toMemoryWriteResult(n)}async handleReadMemory(e){const t={uri:this.getRequiredString(e,"uri"),memory_type:this.getOptionalMemoryType(e)};return await this.readMemoryFromScopedStores(t)}async handleUpdateMemory(e){const t=typeof e.old_string=="string"||typeof e.new_string=="string",r=typeof e.old_string=="string"&&typeof e.new_string=="string",i=this.getOptionalString(e,"append");if(t&&!r)throw new Error("old_string and new_string must be provided together");const s={uri:this.getRequiredString(e,"uri"),memory_type:this.getOptionalMemoryType(e),title:this.getOptionalString(e,"title"),old_string:this.getOptionalString(e,"old_string"),new_string:this.getOptionalString(e,"new_string"),append:i,keywords:this.getOptionalStringArray(e,"keywords"),bound_files:this.normalizeBoundFiles(this.getOptionalStringArray(e,"bound_files"))},n=await this.findMemoryStoreForMutation(s),o=await n.store.readMemory({uri:s.uri,memory_type:n.memory_type??s.memory_type});s.bound_files!==void 0?await this.validateBoundFilesExist(s.bound_files):o?.bound_files&&o.bound_files.length>0&&await this.validateBoundFilesExist(o.bound_files);const a=s.bound_files??o?.bound_files;let m,d;if(a&&a.length>0){m={};for(const u of a){const M=await this.calculateFileMd5(u);M&&(m[u]=M)}d=new Date().toISOString()}const p=await n.store.updateMemory({...s,memory_type:n.memory_type??s.memory_type,file_md5_map:m,last_check_time:d});if(n.memory_type==="project_memory"&&this.backupProjectMemoryToLocal({...s,memory_type:"project_memory",file_md5_map:m,last_check_time:d}).catch(u=>{l.warn("[McpServer] \u5907\u4EFD project_memory \u66F4\u65B0\u5230\u672C\u5730\u5931\u8D25:",u)}),await this.reportMemoryStatsToServer(),n.memory_type==="project_memory"&&o?.memory_status==="updating")try{await this.memoryStore.releaseMemoryClaim(s.uri),this.activeLeaseUris.delete(s.uri),this.activeLeaseUris.size===0&&this.stopLeaseRenewal()}catch(u){l.warn("[McpServer] \u91CA\u653E memory claim \u5931\u8D25: uri=%s, error=%s",s.uri,u instanceof Error?u.message:String(u))}return this.toMemoryWriteResult(p)}async handleDeleteMemory(e){const t=typeof e.uri=="string"?e.uri:void 0,r=Array.isArray(e.memories)?e.memories:void 0;if(t&&r&&r.length>0)throw new Error("delete_memory \u4E0D\u652F\u6301\u540C\u65F6\u4F20\u5165 uri \u548C memories\uFF0C\u8BF7\u4E8C\u9009\u4E00");if(!t&&(!r||r.length===0))throw new Error("delete_memory \u9700\u8981 uri \u6216 memories \u53C2\u6570");if(t){const o=this.getOptionalMemoryType(e);return{deleted:await this.deleteMemorySingle(t,o)}}let i=0;const s=[],n=[];for(let o=0;o<r.length;o++){const a=r[o];if(typeof a!="object"||a===null){n.push({uri:String(a),reason:`memories[${o}] \u4E0D\u662F\u5BF9\u8C61`});continue}const m=a,d=typeof m.uri=="string"?m.uri:"";if(!d){n.push({uri:"",reason:`memories[${o}].uri \u7F3A\u5931`});continue}const p=typeof m.memory_type=="string"?this.parseMemoryType(m.memory_type):void 0;try{await this.deleteMemorySingle(d,p,!0)?i++:s.push(d)}catch(u){n.push({uri:d,reason:u instanceof Error?u.message:String(u)})}}return i>0&&await this.reportMemoryStatsToServer(),{deleted:i,not_found:s,failed:n}}async deleteMemorySingle(e,t,r=!1){const i={uri:e,memory_type:t},s=await this.findMemoryStoreForMutation(i),n=s.memory_type??i.memory_type,o=await s.store.deleteMemory({...i,memory_type:n});return o&&(n==="project_memory"&&this.removeProjectMemoryLocalBackup(e).catch(a=>{l.warn("[McpServer] \u5220\u9664 project_memory \u672C\u5730\u5907\u4EFD\u5931\u8D25:",a)}),r||await this.reportMemoryStatsToServer()),o}async handleSearchMemory(e){const t=this.getOptionalString(e,"scope"),r=t==="children"||t==="all"?t:"own",i=this.getOptionalString(e,"keyword_mode"),s=i==="all"?"all":i==="any"?"any":void 0,n={query:this.getRequiredString(e,"query"),limit:this.getOptionalNumber(e,"limit"),memory_type:this.getOptionalMemoryType(e),keywords:this.getOptionalStringArray(e,"keywords"),keyword_mode:s,scope:r};if(r==="children")return await this.memoryStore.searchMemory(n);const o=await this.searchOwnMemories(n);if(r==="own")return o;const a=await this.memoryStore.searchMemory({...n,scope:"children"});return this.mergeSearchResults(o,a,n.limit)}async searchOwnMemories(e){return await this.memoryStore.searchMemory(e)}mergeSearchResults(e,t,r){const i=new Set,s=typeof r=="number"&&r>0?r:10,n=[...e.results,...t.results].filter(o=>{const a=o.uri;return i.has(a)?!1:(i.add(a),!0)}).sort((o,a)=>a.updatedAt.localeCompare(o.updatedAt)).slice(0,s);return{query:e.query||t.query,results:n}}async handleListMemories(e){const t=this.getRequiredString(e,"memory_type"),r=this.getOptionalNumber(e,"offset"),i=this.getOptionalNumber(e,"limit"),s=Math.max(0,Math.floor(r??0)),n=i!==void 0&&i>=1?Math.floor(i):fe,o=await this.memoryStore.listByType(t),a=o.length,m=o.slice(s,s+n);return{memory_type:t,total:a,offset:s,limit:n,has_more:s+n<a,memories:m}}async handleGetMemoryStats(e){const t=await this.memoryStore.getStats(),r=this.getOptionalMemoryType(e);return r?{memory_type:r,total:t.by_type[r].count,by_type:{[r]:t.by_type[r]}}:t}async handleListMemoriesByFile(e){const t=this.getRequiredString(e,"file_path"),r=this.normalizeBoundFilePath(t),i=this.getOptionalMemoryType(e),s=this.getOptionalString(e,"scope"),n=s==="own"||s==="children"?s:"all",o=async()=>await this.memoryStore.listByFile(r,{memory_type:i,scope:"children"}).catch(()=>[]);if(n==="children"){const u=await o();return{file_path:r,count:u.length,memories:u.map(M=>this.toMemoryRecordWithMetadata(M))}}if(n==="own"){const u=await this.collectOwnMemoriesByFile(r,i);return{file_path:r,count:u.length,memories:u.map(M=>this.toMemoryRecordWithMetadata(M))}}const[a,m,d]=await Promise.all([this.memoryStore.listByFile(r,{memory_type:i,scope:"all"}).catch(()=>[]),this.searchChildMemoriesByFileLocal(r,i).catch(()=>[]),this.searchPeerMemoriesByFileLocal(r,i).catch(()=>[])]),p=this.mergeIdDedupe(this.mergeIdDedupe(a,m),d);return{file_path:r,count:p.length,memories:p.map(u=>this.toMemoryRecordWithMetadata(u))}}mergeIdDedupe(e,t){const r=new Set;for(const s of e)s.id&&r.add(s.id);const i=[...e];for(const s of t)s.id&&!r.has(s.id)&&(i.push(s),r.add(s.id));return i.sort((s,n)=>n.updatedAt.localeCompare(s.updatedAt)),i}async searchChildMemoriesByFileLocal(e,t){const r=process.env.AWS_WORKSPACE_PATH||process.cwd(),i=this.normalizeBoundFilePath(e),n=(i.startsWith("./")?i.substring(2):i).split("/"),o=[],a=new Set,{access:m,readdir:d,readFile:p}=await import("node:fs/promises");for(let u=n.length-1;u>=1;u--){const M=n.slice(0,u),h="./"+n.slice(u).join("/"),w=_.join(r,...M);if(w===r)continue;const c=_.join(w,".agentswork");try{await m(c)}catch{continue}const y=_.join(c,"memory","memory");let g;try{g=(await d(y,{withFileTypes:!0})).filter(v=>v.isDirectory()).map(v=>v.name)}catch{continue}for(const S of g){const v=_.join(y,S);let k;try{k=await d(v)}catch{continue}for(const f of k){if(!f.endsWith(".json"))continue;const b=_.join(v,f);let E;try{E=await p(b,"utf-8")}catch{continue}let A;try{A=JSON.parse(E)}catch{continue}if(A.by_uri)for(const[N,$]of Object.entries(A.by_uri)){if(!$)continue;const B=$.id||N;a.has(B)||t&&$.memory_type!==t||$.bound_files&&$.bound_files.length>0&&$.bound_files.some(V=>this.normalizeBoundFilePath(V)===h)&&(a.add(B),o.push({...$,uri:$.uri||N}))}}}}return o.sort((u,M)=>String(M.updatedAt??"").localeCompare(String(u.updatedAt??""))),o}async searchPeerMemoriesByFileLocal(e,t){if(!this.hasRoleName||!this.initialRoleName)return[];const r=process.env.AWS_WORKSPACE_PATH||process.cwd(),i=this.normalizeBoundFilePath(e),s=_.join(r,".agentswork","memory","memory"),{access:n,readdir:o,readFile:a}=await import("node:fs/promises");try{await n(s)}catch{return[]}let m;try{m=(await o(s,{withFileTypes:!0})).filter(M=>M.isDirectory()).map(M=>M.name)}catch{return[]}const d=[],p=new Set;for(const u of m){if(u===this.initialRoleName)continue;const M=_.join(s,u);let R;try{R=await o(M)}catch{continue}for(const h of R){if(!h.endsWith(".json"))continue;let w;try{w=JSON.parse(await a(_.join(M,h),"utf-8"))}catch{continue}if(w.by_uri)for(const[c,y]of Object.entries(w.by_uri)){if(!y)continue;const g=y.id||c;p.has(g)||y.memory_type==="project_memory"&&(t&&y.memory_type!==t||y.bound_files&&y.bound_files.length>0&&y.bound_files.some(v=>this.normalizeBoundFilePath(v)===i)&&(p.add(g),d.push({...y,uri:y.uri||c,readonly:!0,source_role_name:u})))}}}return d.sort((u,M)=>String(M.updatedAt??"").localeCompare(String(u.updatedAt??""))),d}async collectOwnMemoriesByFile(e,t){return await this.memoryStore.listByFile(e,{memory_type:t})}async handleAbandonMemoryUpdate(e){const t=this.getRequiredString(e,"uri"),r=this.getOptionalMemoryType(e),i=await this.memoryStore.readMemory({uri:t,memory_type:r});return i?.bound_files&&i.bound_files.length>0&&await this.validateBoundFilesExist(i.bound_files),await this.memoryStore.releaseMemoryClaim(t),i?.memory_type==="project_memory"&&this.backupProjectMemoryToLocal({uri:t,memory_type:"project_memory"}).catch(s=>{l.info(`[McpServer] abandon_memory_update: \u540C\u6B65\u672C\u5730\u5907\u4EFD\u5931\u8D25: ${t}`,s)}),this.activeLeaseUris.delete(t),this.activeLeaseUris.size===0&&this.stopLeaseRenewal(),{success:!0,uri:t,message:"Memory \u66F4\u65B0\u72B6\u6001\u5DF2\u6E05\u9664"}}async handleMemoryRecurrence(e){const t=Math.max(1,e?.limit??10);try{((await this.memoryStore.markExpiredMemoriesRecalling()).uris?.length??0)>0&&this.startLeaseRenewal()}catch(a){l.warn("[McpServer] \u539F\u5B50\u8BA4\u9886\u8FC7\u671F\u8BB0\u5FC6\u5931\u8D25: %s",a instanceof Error?a.message:String(a))}const r=await this.memoryStore.listExpiredRecentlyMemories();if(r.length===0)return{memories:[],count:0,limit:t,remaining:0,totalExpired:0,message:"\u6CA1\u6709\u5F85\u56DE\u5FC6\u7684\u5373\u5C06\u9057\u5FD8\u8BB0\u5FC6\u3002"};const s=[...r].sort((a,m)=>{const d=new Date(a.expiresAt||a.createdAt||0).getTime(),p=new Date(m.expiresAt||m.createdAt||0).getTime();return d-p}).slice(0,t),n=Math.max(0,r.length-s.length);return{memories:s.map(a=>({uri:a.uri,title:a.title,domain:a.domain,path:a.path,memory_status:"recalling",contentPreview:typeof a.content=="string"&&a.content.length>200?a.content.substring(0,200)+"...":a.content,createdAt:a.createdAt,updatedAt:a.updatedAt})),count:s.length,limit:t,remaining:n,totalExpired:r.length,message:n>0?`\u672C\u6B21\u5904\u7406 ${s.length} \u6761\u5373\u5C06\u9057\u5FD8\u7684\u8BB0\u5FC6\uFF08\u6700\u65E9\u8FC7\u671F\u4F18\u5148\uFF09\uFF0C\u5269\u4F59 ${n} \u6761\u5F85\u5904\u7406\u3002
|
|
4
4
|
\u8BF7\u5BA1\u67E5\u540E\u51B3\u5B9A\uFF08update_memory \u7EED\u671F\uFF0CTTL \xD72 / \u4E0D\u5904\u7406\uFF09\uFF0C
|
|
5
5
|
\u672C\u6279\u5BA1\u67E5\u5B8C\u6BD5\u540E\u8C03\u7528 memory_recurrence_complete(uris=[\u672C\u6279\u786E\u5B9A\u5220\u9664\u7684URI]) \u6E05\u7406\uFF0C\u518D\u8C03 memory_recurrence \u5904\u7406\u4E0B\u4E00\u6279\u3002`:`\u5DF2\u5904\u7406\u5168\u90E8 ${s.length} \u6761\u5373\u5C06\u9057\u5FD8\u7684\u8BB0\u5FC6\u3002
|
|
6
6
|
\u8BF7\u5BA1\u67E5\u540E\u51B3\u5B9A\uFF08update_memory \u7EED\u671F\uFF0CTTL \xD72 / \u4E0D\u5904\u7406\uFF09\uFF0C
|
|
7
|
-
\u672C\u6279\u5BA1\u67E5\u5B8C\u6BD5\u540E\u8C03\u7528 memory_recurrence_complete(uris=[\u672C\u6279\u786E\u5B9A\u5220\u9664\u7684URI]) \u6E05\u7406\u3002`}}async handleMemoryRecurrenceComplete(e){let t={deleted:0,uris:[]};try{t=await this.memoryStore.clearRecallingExpiredMemories(e?.uris)}catch(i){l.warn("[McpServer] \u6E05\u7406\u56DE\u5FC6\u4E2D\u8BB0\u5FC6\u5931\u8D25: %s",i instanceof Error?i.message:String(i))}await this.reportMemoryStatsToServer();const r=t.deleted??0;return{deleted:r,uris:t.uris??[],message:r===0?"\u6CA1\u6709\u5F85\u758F\u7406\u7684\u56DE\u5FC6\u4E2D\u8BB0\u5FC6\u3002":`\u5DF2\u6E05\u7406 ${r} \u6761\u5DF2\u8FC7\u671F\u8FD1\u671F\u8BB0\u5FC6\u3002`}}async fetchRecentMessages(){const[e,t]=await Promise.all([this.agentClient.getDmHistory(void 0,200).catch(()=>({messages:[],count:0})),this.agentClient.getGroupHistory(200).catch(()=>({messages:[],count:0}))]),r=[...e.messages,...t.messages];return r.sort((i,s)=>new Date(i.timestamp).getTime()-new Date(s.timestamp).getTime()),r}async handleSendGroup(e){const t=typeof e.content=="string"?e.content:"",r=Array.isArray(e.attachments)?e.attachments:[];if(!t.trim()&&r.length===0)throw new Error("content \u4E0E attachments \u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u975E\u7A7A\u503C");const i=r.length>0?this.mergeContentWithAttachmentMarkers(t,await this.uploadAttachmentFiles(r)):t;return this.recordMessageTokenUsage(i).catch(s=>l.warn("[McpServer] Failed to record token usage",s)),await this.agentClient.sendGroupMessage(i,e.projectId,e.roomId)}async uploadAttachmentFiles(e){if(e.length===0)return[];const t=process.env.AWS_WORKSPACE_PATH||process.cwd(),r=
|
|
7
|
+
\u672C\u6279\u5BA1\u67E5\u5B8C\u6BD5\u540E\u8C03\u7528 memory_recurrence_complete(uris=[\u672C\u6279\u786E\u5B9A\u5220\u9664\u7684URI]) \u6E05\u7406\u3002`}}async handleMemoryRecurrenceComplete(e){let t={deleted:0,uris:[]};try{t=await this.memoryStore.clearRecallingExpiredMemories(e?.uris)}catch(i){l.warn("[McpServer] \u6E05\u7406\u56DE\u5FC6\u4E2D\u8BB0\u5FC6\u5931\u8D25: %s",i instanceof Error?i.message:String(i))}await this.reportMemoryStatsToServer();const r=t.deleted??0;return{deleted:r,uris:t.uris??[],message:r===0?"\u6CA1\u6709\u5F85\u758F\u7406\u7684\u56DE\u5FC6\u4E2D\u8BB0\u5FC6\u3002":`\u5DF2\u6E05\u7406 ${r} \u6761\u5DF2\u8FC7\u671F\u8FD1\u671F\u8BB0\u5FC6\u3002`}}async fetchRecentMessages(){const[e,t]=await Promise.all([this.agentClient.getDmHistory(void 0,200).catch(()=>({messages:[],count:0})),this.agentClient.getGroupHistory(200).catch(()=>({messages:[],count:0}))]),r=[...e.messages,...t.messages];return r.sort((i,s)=>new Date(i.timestamp).getTime()-new Date(s.timestamp).getTime()),r}async handleSendGroup(e){const t=typeof e.content=="string"?e.content:"",r=Array.isArray(e.attachments)?e.attachments:[];if(!t.trim()&&r.length===0)throw new Error("content \u4E0E attachments \u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u975E\u7A7A\u503C");const i=r.length>0?this.mergeContentWithAttachmentMarkers(t,await this.uploadAttachmentFiles(r)):t;return this.recordMessageTokenUsage(i).catch(s=>l.warn("[McpServer] Failed to record token usage",s)),await this.agentClient.sendGroupMessage(i,e.projectId,e.roomId)}async uploadAttachmentFiles(e){if(e.length===0)return[];const t=process.env.AWS_WORKSPACE_PATH||process.cwd(),r=_.resolve(t),i=this.agentClient.getServerConfig(),s=ne(i.serverUrl,{fromAgentWebSocketUrl:!0})||"",n=i.runtimeAccessToken||"",o=[];for(const a of e){if(typeof a!="string"||!a.trim())throw new Error("attachments \u4E2D\u5B58\u5728\u7A7A\u8DEF\u5F84");const m=_.resolve(r,a);let d;try{d=await P.promises.stat(m)}catch{throw new Error(`\u9644\u4EF6\u6587\u4EF6\u4E0D\u5B58\u5728: ${a}\uFF08\u89E3\u6790\u4E3A ${m}\uFF09`)}if(!d.isFile())throw new Error(`\u9644\u4EF6\u4E0D\u662F\u666E\u901A\u6587\u4EF6: ${a}`);if(d.size>J)throw new Error(`\u9644\u4EF6\u6587\u4EF6\u8FC7\u5927\uFF08\u4E0A\u9650 ${Math.floor(J/1024/1024)}MB\uFF09: ${a}`);const p=_.basename(m),u=Me(m),M=new FormData;M.append("file",new Blob([await P.promises.readFile(m)],{type:u}),p);const R=await this.uploadFileRequest(`${s}/api/files/upload`,M,n,p);if(!R.ok){const w=await R.text().catch(()=>"");throw new Error(`\u9644\u4EF6\u4E0A\u4F20\u5931\u8D25 (HTTP ${R.status}): ${p}${w?` - ${w.slice(0,200)}`:""}`)}const h=await R.json();if(!h?.url)throw new Error(`\u9644\u4EF6\u4E0A\u4F20\u54CD\u5E94\u7F3A\u5C11 url: ${p}`);o.push({name:h.name||p,url:h.url.startsWith("http")?h.url:`${s}${h.url}`,mediaType:h.mediaType||u,size:typeof h.size=="number"?h.size:d.size})}return o}async uploadFileRequest(e,t,r,i){try{return await fetch(e,{method:"POST",headers:r?{"X-Runtime-Token":r}:void 0,body:t})}catch(s){const n=s?.cause,o=n?.code||n?.message||(s instanceof Error?s.message:String(s));throw new Error(`\u9644\u4EF6\u4E0A\u4F20\u8BF7\u6C42\u5931\u8D25\uFF08\u670D\u52A1\u7AEF\u4E0D\u53EF\u8FBE ${e}\uFF09: ${i} - ${o}`)}}mergeContentWithAttachmentMarkers(e,t){if(t.length===0)return e;const r=t.map(ve).join(`
|
|
8
8
|
`);return e.trim()?`${e}
|
|
9
9
|
|
|
10
|
-
${r}`:r}async recordMessageTokenUsage(e){try{const t=await this.agentClient.getProfile().catch(()=>null);if(!t?.runtimeSessionId)return;const r=this.contextManager.estimateTokens(e);await this.contextManager.recordUsage(t.runtimeSessionId,{input:0,output:r})}catch{}}async handleHireColleague(e){if(Array.isArray(e.items)){if(e.items.length===0)throw new Error("items must contain at least one hire item");return e.items.forEach((t,r)=>{if(!t.workspacePath||typeof t.workspacePath!="string")throw new Error(`items[${r}].workspacePath is required`)}),await this.agentClient.hireColleague(e)}if(!e.workspacePath||typeof e.workspacePath!="string")throw new Error("workspacePath is required");return await this.agentClient.hireColleague(e)}async handleSendPrivate(e){if(!e.targetId||typeof e.targetId!="string")throw new Error("targetId is required");const t=typeof e.content=="string"?e.content:"",r=Array.isArray(e.attachments)?e.attachments:[];if(!t.trim()&&r.length===0)throw new Error("content \u4E0E attachments \u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u975E\u7A7A\u503C");const i=r.length>0?this.mergeContentWithAttachmentMarkers(t,await this.uploadAttachmentFiles(r)):t;return this.recordMessageTokenUsage(i).catch(s=>l.warn("[McpServer] Failed to record token usage",s)),await this.agentClient.sendDirectMessage(e.targetId,i,e.waitReply,e.replyToCallId,e.timeoutMs)}async handleCreateTaskInstanceComment(e){const t=this.getRequiredString(e,"taskInstanceId"),r=this.getRequiredString(e,"content");return await this.agentClient.createTaskInstanceComment({taskInstanceId:t,content:r})}async prependMemoryNotification(e,t){const r=await t();return r?(e.directMessages.unshift(r),!0):!1}async handlePollMessage(e){if(l.info("[McpServer] handlePollMessage \u88AB\u8C03\u7528"),this.pendingPollMessage)return l.info("[McpServer] poll_message \u5DF2\u6709\u8FDB\u884C\u4E2D\u7684\u8C03\u7528\uFF0C\u7B49\u5F85\u5176\u5B8C\u6210"),I("poll.singleton-join","\u7B2C\u4E8C\u4E2A poll_message \u8C03\u7528\u5230\u8FBE\uFF0C\u5408\u5E76\u5230\u8FDB\u884C\u4E2D\u7684 poll Promise\uFF08\u82E5\u9996\u4E2A\u5FAA\u73AF\u5361\u6B7B\u5219\u4E24\u8005\u4E00\u8D77\u6302\u8D77\uFF09"),await this.pendingPollMessage;const t=Date.now();this.pendingPollMessage=(async()=>await this.doPollMessage(e))();try{const r=await this.pendingPollMessage;return l.info("[McpServer] poll_message Promise resolved\uFF0C\u8017\u65F6 %dms, directMessages=%d, groupMessages=%d",Date.now()-t,Array.isArray(r?.directMessages)?r.directMessages.length:-1,Array.isArray(r?.groupMessages)?r.groupMessages.length:-1),I("poll.resolved",`elapsedMs=${Date.now()-t} dm=${O(r?.directMessages)} gm=${O(r?.groupMessages)}`),r}catch(r){throw l.warn("[McpServer] poll_message Promise rejected\uFF0C\u8017\u65F6 %dms: %s",Date.now()-t,r instanceof Error?r.message:String(r)),I("poll.rejected",`elapsedMs=${Date.now()-t} error=${r instanceof Error?r.message:String(r)}`),r}finally{this.pendingPollMessage=null}}async doPollMessage(e){if(l.info("[McpServer] doPollMessage \u88AB\u8C03\u7528"),I("poll.enter","doPollMessage \u5165\u53E3"),e?.aborted)return l.info("[McpServer] poll_message \u8C03\u7528\u5DF2\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u8DF3\u8FC7\u963B\u585E\u7B49\u5F85"),this.buildPollResult({directMessages:[],groupMessages:[]});const t=await this.buildTodoBlockNotification();if(t)return this.buildPollResult({directMessages:[t],groupMessages:[]});await this.hydrateUnreadMessagesFromServer({blockIfEmpty:!1,includePipelineTasks:!0,pollMessageTimeoutMs:5e3,preemptiveJoinWaitMs:0}),await this.hydrateBrowserListenerEvents(),await this.hydratePluginEvents();const r=await this.buildBackgroundTaskNotification(),i=await this.confirmServerMessages(this.messageBuffer.get());if(i.directMessages.length>0||i.groupMessages.length>0)return e?.aborted?(this.messageBuffer.requeue(i),l.info("[McpServer] poll_message \u5165\u53E3\u68C0\u67E5\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u56DE\u6EDA\u672A\u4EA4\u4ED8\u6D88\u606F"),this.buildPollResult({directMessages:[],groupMessages:[]})):(r&&i.directMessages.unshift(r),this.buildPollResult(i));if(r)return this.buildPollResult({directMessages:[r],groupMessages:[]});const s=await this.checkAllLocalNonUrgentNotifications();if(s.length>0)return this.buildPollResult({directMessages:s,groupMessages:[]});let n=!1,o=0,a=0;for(;;){if(e?.aborted)return l.info("[McpServer] poll_message \u7B49\u5F85\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u9000\u51FA\u963B\u585E\u5FAA\u73AF"),I("poll.loop-abort","\u7B49\u5F85\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u9000\u51FA\u963B\u585E\u5FAA\u73AF"),this.buildPollResult({directMessages:[],groupMessages:[]});if(!n){const f=this.agentClient.getStatusReporter();if(f){const S=f.getCurrentStatus();S.status==="tool_using"&&S.actionDetail!=null&&S.actionDetail.includes("poll_message")||f.reportToolUse("poll_message",{}),n=!0}}const m=await this.confirmServerMessages(await this.messageBuffer.poll(ge));if(a++,I("poll.loop-tick",`\u7B2C ${a} \u62CD: polled dm=${m.directMessages.length} gm=${m.groupMessages.length}`),e?.aborted)return this.messageBuffer.requeue(m),l.info("[McpServer] poll_message \u7B49\u5F85\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u56DE\u6EDA %d \u6761\u672A\u4EA4\u4ED8\u6D88\u606F\u540E\u9000\u51FA\u963B\u585E\u5FAA\u73AF",m.directMessages.length+m.groupMessages.length),this.buildPollResult({directMessages:[],groupMessages:[]});if(m.directMessages.length>0||m.groupMessages.length>0)return this.buildPollResult(m);if(l.debug("[McpServer] poll \u8D85\u65F6\uFF0C\u68C0\u67E5\u6D4F\u89C8\u5668\u76D1\u542C\u5668\u4E8B\u4EF6"),await this.hydrateBrowserListenerEvents()){if(e?.aborted)return l.info("[McpServer] poll_message \u76D1\u542C\u5668\u4E8B\u4EF6\u68C0\u67E5\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u9000\u51FA\u963B\u585E\u5FAA\u73AF"),this.buildPollResult({directMessages:[],groupMessages:[]});const f=await this.confirmServerMessages(this.messageBuffer.get());if(f.directMessages.length>0||f.groupMessages.length>0)return e?.aborted?(this.messageBuffer.requeue(f),l.info("[McpServer] poll_message \u76D1\u542C\u5668\u4E8B\u4EF6\u786E\u8BA4\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u56DE\u6EDA %d \u6761\u672A\u4EA4\u4ED8\u6D88\u606F",f.directMessages.length+f.groupMessages.length),this.buildPollResult({directMessages:[],groupMessages:[]})):(l.info("[McpServer] \u76D1\u542C\u5668\u4E8B\u4EF6\u5DF2\u6CE8\u5165\uFF0Cpoll_message \u8FD4\u56DE %d \u6761\u79C1\u4FE1",f.directMessages.length),this.buildPollResult(f))}if(l.debug("[McpServer] poll \u8D85\u65F6\uFF0C\u68C0\u67E5\u63D2\u4EF6\u4E8B\u4EF6"),await this.hydratePluginEvents()){if(e?.aborted)return l.info("[McpServer] poll_message \u63D2\u4EF6\u4E8B\u4EF6\u68C0\u67E5\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u9000\u51FA\u963B\u585E\u5FAA\u73AF"),this.buildPollResult({directMessages:[],groupMessages:[]});const f=await this.confirmServerMessages(this.messageBuffer.get());if(f.directMessages.length>0||f.groupMessages.length>0)return e?.aborted?(this.messageBuffer.requeue(f),l.info("[McpServer] poll_message \u63D2\u4EF6\u4E8B\u4EF6\u786E\u8BA4\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u56DE\u6EDA %d \u6761\u672A\u4EA4\u4ED8\u6D88\u606F",f.directMessages.length+f.groupMessages.length),this.buildPollResult({directMessages:[],groupMessages:[]})):(l.info("[McpServer] \u63D2\u4EF6\u4E8B\u4EF6\u5DF2\u6CE8\u5165\uFF0Cpoll_message \u8FD4\u56DE %d \u6761\u79C1\u4FE1",f.directMessages.length),this.buildPollResult(f))}o++;let u=!1;if(this.urgentMeetingHydrateRequested&&(this.urgentMeetingHydrateRequested=!1,o=j,u=!0),o<j)continue;o=0;const M=await this.buildTodoBlockNotification();if(M)return this.buildPollResult({directMessages:[M],groupMessages:[]});let R=!1;const h=u?T.MEETING_HYDRATE_RETRY_COUNT:1;for(let f=1;f<=h;f++){l.info("[McpServer] %s hydrate poll_message\uFF0C\u7B2C %d/%d \u6B21",u?"\u4F1A\u8BAE\u9080\u8BF7\u5F3A\u5236":"\u666E\u901A",f,h);const S=this.messageBuffer.size();if(u&&S>0){l.info("[McpServer] \u4F1A\u8BAE\u9080\u8BF7\u5F3A\u5236 hydrate \u524D\u53D1\u73B0\u672C\u5730\u7F13\u51B2\u5DF2\u6709 %d \u6761\u6D88\u606F\uFF0C\u8DF3\u8FC7 hydrate \u76F4\u63A5\u4EA4\u4ED8",S);break}const E={blockIfEmpty:!1,includePipelineTasks:!0,pollMessageTimeoutMs:u?T.MEETING_HYDRATE_POLL_TIMEOUT_MS:void 0,skipGroupMessages:u,preemptiveJoinWaitMs:u?T.MEETING_PREEMPTIVE_JOIN_WAIT_MS:0,propagatePollTimeout:u},P=Date.now(),y=await this.hydrateUnreadMessagesFromServer(E);if(u&&I("poll.forced-hydrate-outcome",`\u7B2C ${f}/${h} \u6B21\u5F3A\u5236 hydrate \u5B8C\u6210\uFF08\u8017\u65F6 ${Date.now()-P}ms\uFF09: timedOut=${y.timedOut} failed=${y.failed} \u7F13\u51B2\u533A=${this.messageBuffer.size()} \u6761`),y.timedOut){l.warn("[McpServer] \u4F1A\u8BAE\u9080\u8BF7\u5F3A\u5236 hydrate \u7B2C %d/%d \u6B21\u5BA2\u6237\u7AEF\u8D85\u65F6\uFF08\u670D\u52A1\u7AEF\u53EF\u80FD\u4ECD\u5728\u6267\u884C\u4E0A\u4E00\u8BF7\u6C42\uFF09\uFF0C\u505C\u6B62\u7ACB\u5373\u91CD\u8BD5",f,h),R=!0;break}const b=this.messageBuffer.size();if(l.info("[McpServer] hydrate poll_message \u5B8C\u6210\uFF0C\u7B2C %d/%d \u6B21\uFF0C\u7F13\u51B2\u533A\u6D88\u606F\u6570=%d",f,h,b),b>0||!u)break;f<h&&await new Promise(v=>setTimeout(v,T.MEETING_HYDRATE_RETRY_DELAY_MS))}R&&(I("poll.forced-hydrate-rearm",`\u5F3A\u5236 hydrate \u8D85\u65F6\uFF0C${this.meetingHydrateTimeoutRearmDelayMs}ms \u540E\u91CD\u65B0\u7F6E\u4F4D\u5524\u9192\u6807\u8BB0`),setTimeout(()=>{l.info("[McpServer] \u4F1A\u8BAE\u5F3A\u5236 hydrate \u8D85\u65F6\u81EA\u6108\uFF1A\u91CD\u65B0\u7F6E\u4F4D\u5524\u9192\u6807\u8BB0\u89E6\u53D1\u4E0B\u4E00\u8F6E\u5F3A\u5236 hydrate"),this.urgentMeetingHydrateRequested=!0,this.messageBuffer.wakeUpWaiters()},this.meetingHydrateTimeoutRearmDelayMs).unref());const w=await this.buildBackgroundTaskNotification();if(e?.aborted)return l.info("[McpServer] poll_message hydrate \u540E\u68C0\u67E5\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u9000\u51FA\u963B\u585E\u5FAA\u73AF"),this.buildPollResult({directMessages:[],groupMessages:[]});const c=await this.confirmServerMessages(this.messageBuffer.get());if(c.directMessages.length>0||c.groupMessages.length>0)return e?.aborted?(this.messageBuffer.requeue(c),l.info("[McpServer] poll_message hydrate \u786E\u8BA4\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u56DE\u6EDA %d \u6761\u672A\u4EA4\u4ED8\u6D88\u606F",c.directMessages.length+c.groupMessages.length),this.buildPollResult({directMessages:[],groupMessages:[]})):(w&&c.directMessages.unshift(w),this.buildPollResult(c));if(u&&!w&&!R&&(l.info("[McpServer] \u4F1A\u8BAE\u9080\u8BF7\u5524\u9192\u540E\u7684\u5F3A\u5236 hydrate \u672A\u53D6\u5230\u53EF\u6295\u9012\u6D88\u606F\uFF08\u670D\u52A1\u7AEF\u672A\u62A2\u5360\u6216\u65E0\u65B0\u4F1A\u8BAE\u5185\u5BB9\uFF09\uFF0C\u7EE7\u7EED\u7B49\u5F85"),I("poll.forced-hydrate-empty","\u4F1A\u8BAE\u9080\u8BF7\u5524\u9192\u540E\u7684\u5F3A\u5236 hydrate \u672A\u53D6\u5230\u4EFB\u4F55\u53EF\u6295\u9012\u6D88\u606F\uFF08\u670D\u52A1\u7AEF\u672A\u62A2\u5360/\u65E0\u65B0\u5185\u5BB9/\u6D88\u606F\u88AB\u53BB\u91CD\u62E6\u622A\uFF09\uFF0C\u7EE7\u7EED\u7B49\u5F85"),o=j-1),w)return this.buildPollResult({directMessages:[w],groupMessages:[]});const _=await this.checkAllLocalNonUrgentNotifications(!1);if(_.length>0)return this.buildPollResult({directMessages:_,groupMessages:[]})}}async checkAllLocalNonUrgentNotifications(e=!0){const t=[],r=await this.buildMemoryRecurrenceNotification();if(r&&t.push(r),e){const s=await this.buildMemoryFileChangeNotification();s&&t.push(s)}const i=await this.buildMemoryCleanupNotification();return i&&t.push(i),t}buildPollResult(e,t=!0){l.info("[McpServer][DEBUG-poll] \u8FD4\u56DE poll \u7ED3\u679C: directMessages=%d, groupMessages=%d, \u660E\u7EC6=%s",e.directMessages.length,e.groupMessages.length,JSON.stringify(e.directMessages.map(i=>({id:i.msgId,channel:i.channel,sender:i.senderId}))));const r=this.shouldDeliverPluginCatalog();return{directMessages:e.directMessages,groupMessages:e.groupMessages,fromBuffer:t,systemMessages:[],...r?{pluginCatalog:r}:{}}}shouldDeliverPluginCatalog(){if(!this.cachedPluginCatalog||this.cachedPluginCatalog.plugins.length===0)return null;const e=this.pluginCatalogDrainCompactionSeq;e!==this.pluginCatalogLastSeenCompactionSeq&&(this.deliveredPluginNames.clear(),this.pluginCatalogLastSeenCompactionSeq=e);const t=[];for(const r of this.cachedPluginCatalog.plugins)this.deliveredPluginNames.has(r.plugin)||(this.deliveredPluginNames.add(r.plugin),t.push(r));return t.length===0?null:(l.debug("[McpServer] \u4EA4\u4ED8 pluginCatalog: plugins=[%s], compactionSeq=%d",t.map(r=>r.plugin).join(", "),e),{revision:this.cachedPluginCatalog.revision,plugins:t})}parsePositiveIntegerEnv(e,t){const r=process.env[e];if(!r||!r.trim())return t;const i=Number.parseInt(r,10);return!Number.isFinite(i)||i<=0?(l.warn(`[McpServer] ${e} \u65E0\u6548\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u503C ${t}ms`),t):i}sleep(e){return e<=0?Promise.resolve():new Promise(t=>setTimeout(t,e))}async buildMemoryCleanupNotification(){try{const e=await this.memoryStore.getStats(),t=Object.entries(e.by_type).filter(([,o])=>o.listable&&o.exceeded),r=Object.entries(e.by_type).flatMap(([o,a])=>a.listable?Object.entries(a.by_domain).filter(([,m])=>m.exceeded).map(([m,d])=>({memoryType:o,domain:m,domainStats:d})):[]);if(t.length===0&&r.length===0)return null;const i=t.map(([o,a])=>`${o} \u5F53\u524D ${a.domainCount} \u4E2A URI domain \u7C7B\u578B\uFF0C\u5EFA\u8BAE\u4E0A\u9650 ${a.limit} \u4E2A\uFF0C\u786C\u4E0A\u9650 ${a.hardLimit} \u4E2A`),s=r.map(({memoryType:o,domain:a,domainStats:m})=>`${o}/${a} \u7C7B\u578B\u4E0B\u5F53\u524D ${m.count} \u6761 memory\uFF0C\u5EFA\u8BAE\u4E0A\u9650 ${m.limit} \u6761\uFF0C\u786C\u4E0A\u9650 ${m.hardLimit} \u6761`),n=["\u8BF7\u8C03\u7528 get_memory_stats \u67E5\u770B\u5BB9\u91CF\u8BE6\u60C5","\u8C03\u7528 list_memories \u6309\u7C7B\u578B\u67E5\u770B\u8D85\u9650\u8BB0\u5FC6","\u5220\u9664\u4E0D\u518D\u9700\u8981\u7684 recently_memory","\u66F4\u65B0 agent_memory \u7EED\u671F\uFF08TTL \xD72\uFF09\u6216\u5220\u9664\u8FC7\u671F\u9879"].join("\uFF1B");return{msgId:`memory-cleanup-${Date.now()}`,senderId:"MCP-System",senderName:"\u7CFB\u7EDF",receiverId:this.getCurrentAgentId()||void 0,content:`\u672C\u5730 memory \u5DF2\u8D85\u8FC7\u5EFA\u8BAE\u5BB9\u91CF\uFF0C\u9700\u8981\u6574\u7406\u3002${[...i,...s].join("\uFF1B")}\u3002${n}\u3002`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_cleanup",uris:r.map(o=>`${o.memoryType}/${o.domain}`)}}}catch(e){return l.warn("[McpServer] \u6784\u5EFA\u672C\u5730 memory \u6574\u7406\u63D0\u9192\u5931\u8D25: %s",e instanceof Error?e.message:String(e)),null}}async buildMemoryRecurrenceNotification(){try{const e=await this.memoryStore.listExpiredRecentlyMemories();if(e.length===0)return null;const t=this.getCurrentAgentId();if(!t)return null;const r=e.filter(s=>s.memory_status==="recalling"),i=e.filter(s=>!r.includes(s));if(r.length>0){const s=r.slice(0,5).map(n=>n.uri).join(`
|
|
10
|
+
${r}`:r}async recordMessageTokenUsage(e){try{const t=await this.agentClient.getProfile().catch(()=>null);if(!t?.runtimeSessionId)return;const r=this.contextManager.estimateTokens(e);await this.contextManager.recordUsage(t.runtimeSessionId,{input:0,output:r})}catch{}}async handleHireColleague(e){if(Array.isArray(e.items)){if(e.items.length===0)throw new Error("items must contain at least one hire item");return e.items.forEach((t,r)=>{if(!t.workspacePath||typeof t.workspacePath!="string")throw new Error(`items[${r}].workspacePath is required`)}),await this.agentClient.hireColleague(e)}if(!e.workspacePath||typeof e.workspacePath!="string")throw new Error("workspacePath is required");return await this.agentClient.hireColleague(e)}async handleSendPrivate(e){if(!e.targetId||typeof e.targetId!="string")throw new Error("targetId is required");const t=typeof e.content=="string"?e.content:"",r=Array.isArray(e.attachments)?e.attachments:[];if(!t.trim()&&r.length===0)throw new Error("content \u4E0E attachments \u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u975E\u7A7A\u503C");const i=r.length>0?this.mergeContentWithAttachmentMarkers(t,await this.uploadAttachmentFiles(r)):t;return this.recordMessageTokenUsage(i).catch(s=>l.warn("[McpServer] Failed to record token usage",s)),await this.agentClient.sendDirectMessage(e.targetId,i,e.waitReply,e.replyToCallId,e.timeoutMs)}async handleCreateTaskInstanceComment(e){const t=this.getRequiredString(e,"taskInstanceId"),r=this.getRequiredString(e,"content");return await this.agentClient.createTaskInstanceComment({taskInstanceId:t,content:r})}async prependMemoryNotification(e,t){const r=await t();return r?(e.directMessages.unshift(r),!0):!1}async handlePollMessage(e){if(l.info("[McpServer] handlePollMessage \u88AB\u8C03\u7528"),this.pendingPollMessage)return l.info("[McpServer] poll_message \u5DF2\u6709\u8FDB\u884C\u4E2D\u7684\u8C03\u7528\uFF0C\u7B49\u5F85\u5176\u5B8C\u6210"),I("poll.singleton-join","\u7B2C\u4E8C\u4E2A poll_message \u8C03\u7528\u5230\u8FBE\uFF0C\u5408\u5E76\u5230\u8FDB\u884C\u4E2D\u7684 poll Promise\uFF08\u82E5\u9996\u4E2A\u5FAA\u73AF\u5361\u6B7B\u5219\u4E24\u8005\u4E00\u8D77\u6302\u8D77\uFF09"),await this.pendingPollMessage;const t=Date.now();this.pendingPollMessage=(async()=>await this.doPollMessage(e))();try{const r=await this.pendingPollMessage;return l.info("[McpServer] poll_message Promise resolved\uFF0C\u8017\u65F6 %dms, directMessages=%d, groupMessages=%d",Date.now()-t,Array.isArray(r?.directMessages)?r.directMessages.length:-1,Array.isArray(r?.groupMessages)?r.groupMessages.length:-1),I("poll.resolved",`elapsedMs=${Date.now()-t} dm=${O(r?.directMessages)} gm=${O(r?.groupMessages)}`),r}catch(r){throw l.warn("[McpServer] poll_message Promise rejected\uFF0C\u8017\u65F6 %dms: %s",Date.now()-t,r instanceof Error?r.message:String(r)),I("poll.rejected",`elapsedMs=${Date.now()-t} error=${r instanceof Error?r.message:String(r)}`),r}finally{this.pendingPollMessage=null}}async doPollMessage(e){if(l.info("[McpServer] doPollMessage \u88AB\u8C03\u7528"),I("poll.enter","doPollMessage \u5165\u53E3"),e?.aborted)return l.info("[McpServer] poll_message \u8C03\u7528\u5DF2\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u8DF3\u8FC7\u963B\u585E\u7B49\u5F85"),this.buildPollResult({directMessages:[],groupMessages:[]});const t=await this.buildTodoBlockNotification();if(t)return this.buildPollResult({directMessages:[t],groupMessages:[]});await this.hydrateUnreadMessagesFromServer({blockIfEmpty:!1,includePipelineTasks:!0,pollMessageTimeoutMs:5e3,preemptiveJoinWaitMs:0}),await this.hydrateBrowserListenerEvents(),await this.hydratePluginEvents();const r=await this.buildBackgroundTaskNotification(),i=await this.confirmServerMessages(this.messageBuffer.get());if(i.directMessages.length>0||i.groupMessages.length>0)return e?.aborted?(this.messageBuffer.requeue(i),l.info("[McpServer] poll_message \u5165\u53E3\u68C0\u67E5\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u56DE\u6EDA\u672A\u4EA4\u4ED8\u6D88\u606F"),this.buildPollResult({directMessages:[],groupMessages:[]})):(r&&i.directMessages.unshift(r),this.buildPollResult(i));if(r)return this.buildPollResult({directMessages:[r],groupMessages:[]});const s=await this.checkAllLocalNonUrgentNotifications();if(s.length>0)return this.buildPollResult({directMessages:s,groupMessages:[]});let n=!1,o=0,a=0;for(;;){if(e?.aborted)return l.info("[McpServer] poll_message \u7B49\u5F85\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u9000\u51FA\u963B\u585E\u5FAA\u73AF"),I("poll.loop-abort","\u7B49\u5F85\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u9000\u51FA\u963B\u585E\u5FAA\u73AF"),this.buildPollResult({directMessages:[],groupMessages:[]});if(!n){const g=this.agentClient.getStatusReporter();if(g){const S=g.getCurrentStatus();S.status==="tool_using"&&S.actionDetail!=null&&S.actionDetail.includes("poll_message")||g.reportToolUse("poll_message",{}),n=!0}}const m=await this.confirmServerMessages(await this.messageBuffer.poll(ge));if(a++,I("poll.loop-tick",`\u7B2C ${a} \u62CD: polled dm=${m.directMessages.length} gm=${m.groupMessages.length}`),e?.aborted)return this.messageBuffer.requeue(m),l.info("[McpServer] poll_message \u7B49\u5F85\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u56DE\u6EDA %d \u6761\u672A\u4EA4\u4ED8\u6D88\u606F\u540E\u9000\u51FA\u963B\u585E\u5FAA\u73AF",m.directMessages.length+m.groupMessages.length),this.buildPollResult({directMessages:[],groupMessages:[]});if(m.directMessages.length>0||m.groupMessages.length>0)return this.buildPollResult(m);if(l.debug("[McpServer] poll \u8D85\u65F6\uFF0C\u68C0\u67E5\u6D4F\u89C8\u5668\u76D1\u542C\u5668\u4E8B\u4EF6"),await this.hydrateBrowserListenerEvents()){if(e?.aborted)return l.info("[McpServer] poll_message \u76D1\u542C\u5668\u4E8B\u4EF6\u68C0\u67E5\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u9000\u51FA\u963B\u585E\u5FAA\u73AF"),this.buildPollResult({directMessages:[],groupMessages:[]});const g=await this.confirmServerMessages(this.messageBuffer.get());if(g.directMessages.length>0||g.groupMessages.length>0)return e?.aborted?(this.messageBuffer.requeue(g),l.info("[McpServer] poll_message \u76D1\u542C\u5668\u4E8B\u4EF6\u786E\u8BA4\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u56DE\u6EDA %d \u6761\u672A\u4EA4\u4ED8\u6D88\u606F",g.directMessages.length+g.groupMessages.length),this.buildPollResult({directMessages:[],groupMessages:[]})):(l.info("[McpServer] \u76D1\u542C\u5668\u4E8B\u4EF6\u5DF2\u6CE8\u5165\uFF0Cpoll_message \u8FD4\u56DE %d \u6761\u79C1\u4FE1",g.directMessages.length),this.buildPollResult(g))}if(l.debug("[McpServer] poll \u8D85\u65F6\uFF0C\u68C0\u67E5\u63D2\u4EF6\u4E8B\u4EF6"),await this.hydratePluginEvents()){if(e?.aborted)return l.info("[McpServer] poll_message \u63D2\u4EF6\u4E8B\u4EF6\u68C0\u67E5\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u9000\u51FA\u963B\u585E\u5FAA\u73AF"),this.buildPollResult({directMessages:[],groupMessages:[]});const g=await this.confirmServerMessages(this.messageBuffer.get());if(g.directMessages.length>0||g.groupMessages.length>0)return e?.aborted?(this.messageBuffer.requeue(g),l.info("[McpServer] poll_message \u63D2\u4EF6\u4E8B\u4EF6\u786E\u8BA4\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u56DE\u6EDA %d \u6761\u672A\u4EA4\u4ED8\u6D88\u606F",g.directMessages.length+g.groupMessages.length),this.buildPollResult({directMessages:[],groupMessages:[]})):(l.info("[McpServer] \u63D2\u4EF6\u4E8B\u4EF6\u5DF2\u6CE8\u5165\uFF0Cpoll_message \u8FD4\u56DE %d \u6761\u79C1\u4FE1",g.directMessages.length),this.buildPollResult(g))}o++;let u=!1;if(this.urgentMeetingHydrateRequested&&(this.urgentMeetingHydrateRequested=!1,o=j,u=!0),o<j)continue;o=0;const M=await this.buildTodoBlockNotification();if(M)return this.buildPollResult({directMessages:[M],groupMessages:[]});let R=!1;const h=u?T.MEETING_HYDRATE_RETRY_COUNT:1;for(let g=1;g<=h;g++){l.info("[McpServer] %s hydrate poll_message\uFF0C\u7B2C %d/%d \u6B21",u?"\u4F1A\u8BAE\u9080\u8BF7\u5F3A\u5236":"\u666E\u901A",g,h);const S=this.messageBuffer.size();if(u&&S>0){l.info("[McpServer] \u4F1A\u8BAE\u9080\u8BF7\u5F3A\u5236 hydrate \u524D\u53D1\u73B0\u672C\u5730\u7F13\u51B2\u5DF2\u6709 %d \u6761\u6D88\u606F\uFF0C\u8DF3\u8FC7 hydrate \u76F4\u63A5\u4EA4\u4ED8",S);break}const v={blockIfEmpty:!1,includePipelineTasks:!0,pollMessageTimeoutMs:u?T.MEETING_HYDRATE_POLL_TIMEOUT_MS:void 0,skipGroupMessages:u,preemptiveJoinWaitMs:u?T.MEETING_PREEMPTIVE_JOIN_WAIT_MS:0,propagatePollTimeout:u},k=Date.now(),f=await this.hydrateUnreadMessagesFromServer(v);if(u&&I("poll.forced-hydrate-outcome",`\u7B2C ${g}/${h} \u6B21\u5F3A\u5236 hydrate \u5B8C\u6210\uFF08\u8017\u65F6 ${Date.now()-k}ms\uFF09: timedOut=${f.timedOut} failed=${f.failed} \u7F13\u51B2\u533A=${this.messageBuffer.size()} \u6761`),f.timedOut){l.warn("[McpServer] \u4F1A\u8BAE\u9080\u8BF7\u5F3A\u5236 hydrate \u7B2C %d/%d \u6B21\u5BA2\u6237\u7AEF\u8D85\u65F6\uFF08\u670D\u52A1\u7AEF\u53EF\u80FD\u4ECD\u5728\u6267\u884C\u4E0A\u4E00\u8BF7\u6C42\uFF09\uFF0C\u505C\u6B62\u7ACB\u5373\u91CD\u8BD5",g,h),R=!0;break}const b=this.messageBuffer.size();if(l.info("[McpServer] hydrate poll_message \u5B8C\u6210\uFF0C\u7B2C %d/%d \u6B21\uFF0C\u7F13\u51B2\u533A\u6D88\u606F\u6570=%d",g,h,b),b>0||!u)break;g<h&&await new Promise(E=>setTimeout(E,T.MEETING_HYDRATE_RETRY_DELAY_MS))}R&&(I("poll.forced-hydrate-rearm",`\u5F3A\u5236 hydrate \u8D85\u65F6\uFF0C${this.meetingHydrateTimeoutRearmDelayMs}ms \u540E\u91CD\u65B0\u7F6E\u4F4D\u5524\u9192\u6807\u8BB0`),setTimeout(()=>{l.info("[McpServer] \u4F1A\u8BAE\u5F3A\u5236 hydrate \u8D85\u65F6\u81EA\u6108\uFF1A\u91CD\u65B0\u7F6E\u4F4D\u5524\u9192\u6807\u8BB0\u89E6\u53D1\u4E0B\u4E00\u8F6E\u5F3A\u5236 hydrate"),this.urgentMeetingHydrateRequested=!0,this.messageBuffer.wakeUpWaiters()},this.meetingHydrateTimeoutRearmDelayMs).unref());const w=await this.buildBackgroundTaskNotification();if(e?.aborted)return l.info("[McpServer] poll_message hydrate \u540E\u68C0\u67E5\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u9000\u51FA\u963B\u585E\u5FAA\u73AF"),this.buildPollResult({directMessages:[],groupMessages:[]});const c=await this.confirmServerMessages(this.messageBuffer.get());if(c.directMessages.length>0||c.groupMessages.length>0)return e?.aborted?(this.messageBuffer.requeue(c),l.info("[McpServer] poll_message hydrate \u786E\u8BA4\u671F\u95F4\u88AB\u5BA2\u6237\u7AEF\u53D6\u6D88\uFF0C\u56DE\u6EDA %d \u6761\u672A\u4EA4\u4ED8\u6D88\u606F",c.directMessages.length+c.groupMessages.length),this.buildPollResult({directMessages:[],groupMessages:[]})):(w&&c.directMessages.unshift(w),this.buildPollResult(c));if(u&&!w&&!R&&(l.info("[McpServer] \u4F1A\u8BAE\u9080\u8BF7\u5524\u9192\u540E\u7684\u5F3A\u5236 hydrate \u672A\u53D6\u5230\u53EF\u6295\u9012\u6D88\u606F\uFF08\u670D\u52A1\u7AEF\u672A\u62A2\u5360\u6216\u65E0\u65B0\u4F1A\u8BAE\u5185\u5BB9\uFF09\uFF0C\u7EE7\u7EED\u7B49\u5F85"),I("poll.forced-hydrate-empty","\u4F1A\u8BAE\u9080\u8BF7\u5524\u9192\u540E\u7684\u5F3A\u5236 hydrate \u672A\u53D6\u5230\u4EFB\u4F55\u53EF\u6295\u9012\u6D88\u606F\uFF08\u670D\u52A1\u7AEF\u672A\u62A2\u5360/\u65E0\u65B0\u5185\u5BB9/\u6D88\u606F\u88AB\u53BB\u91CD\u62E6\u622A\uFF09\uFF0C\u7EE7\u7EED\u7B49\u5F85"),o=j-1),w)return this.buildPollResult({directMessages:[w],groupMessages:[]});const y=await this.checkAllLocalNonUrgentNotifications(!1);if(y.length>0)return this.buildPollResult({directMessages:y,groupMessages:[]})}}async checkAllLocalNonUrgentNotifications(e=!0){const t=[],r=await this.buildMemoryRecurrenceNotification();if(r&&t.push(r),e){const s=await this.buildMemoryFileChangeNotification();s&&t.push(s)}const i=await this.buildMemoryCleanupNotification();return i&&t.push(i),t}buildPollResult(e,t=!0){l.info("[McpServer][DEBUG-poll] \u8FD4\u56DE poll \u7ED3\u679C: directMessages=%d, groupMessages=%d, \u660E\u7EC6=%s",e.directMessages.length,e.groupMessages.length,JSON.stringify(e.directMessages.map(i=>({id:i.msgId,channel:i.channel,sender:i.senderId}))));const r=this.shouldDeliverPluginCatalog();return{directMessages:e.directMessages,groupMessages:e.groupMessages,fromBuffer:t,systemMessages:[],...r?{pluginCatalog:r}:{}}}shouldDeliverPluginCatalog(){if(!this.cachedPluginCatalog||this.cachedPluginCatalog.plugins.length===0)return null;const e=this.pluginCatalogDrainCompactionSeq;e!==this.pluginCatalogLastSeenCompactionSeq&&(this.deliveredPluginNames.clear(),this.pluginCatalogLastSeenCompactionSeq=e);const t=[];for(const r of this.cachedPluginCatalog.plugins)this.deliveredPluginNames.has(r.plugin)||(this.deliveredPluginNames.add(r.plugin),t.push(r));return t.length===0?null:(l.debug("[McpServer] \u4EA4\u4ED8 pluginCatalog: plugins=[%s], compactionSeq=%d",t.map(r=>r.plugin).join(", "),e),{revision:this.cachedPluginCatalog.revision,plugins:t})}parsePositiveIntegerEnv(e,t){const r=process.env[e];if(!r||!r.trim())return t;const i=Number.parseInt(r,10);return!Number.isFinite(i)||i<=0?(l.warn(`[McpServer] ${e} \u65E0\u6548\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u503C ${t}ms`),t):i}sleep(e){return e<=0?Promise.resolve():new Promise(t=>setTimeout(t,e))}async buildMemoryCleanupNotification(){try{const e=await this.memoryStore.getStats(),t=Object.entries(e.by_type).filter(([,o])=>o.listable&&o.exceeded),r=Object.entries(e.by_type).flatMap(([o,a])=>a.listable?Object.entries(a.by_domain).filter(([,m])=>m.exceeded).map(([m,d])=>({memoryType:o,domain:m,domainStats:d})):[]);if(t.length===0&&r.length===0)return null;const i=t.map(([o,a])=>`${o} \u5F53\u524D ${a.domainCount} \u4E2A URI domain \u7C7B\u578B\uFF0C\u5EFA\u8BAE\u4E0A\u9650 ${a.limit} \u4E2A\uFF0C\u786C\u4E0A\u9650 ${a.hardLimit} \u4E2A`),s=r.map(({memoryType:o,domain:a,domainStats:m})=>`${o}/${a} \u7C7B\u578B\u4E0B\u5F53\u524D ${m.count} \u6761 memory\uFF0C\u5EFA\u8BAE\u4E0A\u9650 ${m.limit} \u6761\uFF0C\u786C\u4E0A\u9650 ${m.hardLimit} \u6761`),n=["\u8BF7\u8C03\u7528 get_memory_stats \u67E5\u770B\u5BB9\u91CF\u8BE6\u60C5","\u8C03\u7528 list_memories \u6309\u7C7B\u578B\u67E5\u770B\u8D85\u9650\u8BB0\u5FC6","\u5220\u9664\u4E0D\u518D\u9700\u8981\u7684 recently_memory","\u66F4\u65B0 agent_memory \u7EED\u671F\uFF08TTL \xD72\uFF09\u6216\u5220\u9664\u8FC7\u671F\u9879"].join("\uFF1B");return{msgId:`memory-cleanup-${Date.now()}`,senderId:"MCP-System",senderName:"\u7CFB\u7EDF",receiverId:this.getCurrentAgentId()||void 0,content:`\u672C\u5730 memory \u5DF2\u8D85\u8FC7\u5EFA\u8BAE\u5BB9\u91CF\uFF0C\u9700\u8981\u6574\u7406\u3002${[...i,...s].join("\uFF1B")}\u3002${n}\u3002`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_cleanup",uris:r.map(o=>`${o.memoryType}/${o.domain}`)}}}catch(e){return l.warn("[McpServer] \u6784\u5EFA\u672C\u5730 memory \u6574\u7406\u63D0\u9192\u5931\u8D25: %s",e instanceof Error?e.message:String(e)),null}}async buildMemoryRecurrenceNotification(){try{const e=await this.memoryStore.listExpiredRecentlyMemories();if(e.length===0)return null;const t=this.getCurrentAgentId();if(!t)return null;const r=e.filter(s=>s.memory_status==="recalling"),i=e.filter(s=>!r.includes(s));if(r.length>0){const s=r.slice(0,5).map(n=>n.uri).join(`
|
|
11
11
|
`);return{msgId:`memory-recurrence-pending-${Date.now()}`,senderId:"MCP-System",senderName:"\u7CFB\u7EDF",receiverId:t,content:`\u5B58\u5728\u5F85\u758F\u7406\u7684\u5373\u5C06\u9057\u5FD8\u8BB0\u5FC6\uFF08\u5171 ${r.length} \u6761\uFF09\uFF0C\u8BF7\u901A\u8FC7 memory_recurrence \u83B7\u53D6\u8FDB\u884C\u6574\u7406\u3002
|
|
12
12
|
|
|
13
13
|
\u5F85\u758F\u7406\u8BB0\u5FC6\uFF1A
|
|
@@ -17,36 +17,36 @@ ${s}${r.length>5?`
|
|
|
17
17
|
|
|
18
18
|
\u5373\u5C06\u9057\u5FD8\u7684\u8BB0\u5FC6\uFF1A
|
|
19
19
|
${s}${i.length>5?`
|
|
20
|
-
...\u53CA\u5176\u4ED6 ${i.length-5} \u6761`:""}`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_expiration",uris:i.map(n=>n.uri)}}}return null}catch(e){return l.warn("[McpServer] \u6784\u5EFA\u8FD1\u671F\u8BB0\u5FC6\u8FC7\u671F\u56DE\u5FC6\u901A\u77E5\u5931\u8D25: %s",e instanceof Error?e.message:String(e)),null}}async buildMemoryFileChangeNotification(){if(l.info(`[McpServer] buildMemoryFileChangeNotification \u88AB\u8C03\u7528: hasRoleName=${this.hasRoleName}, agentId=${this.getCurrentAgentId()??"(\u7A7A)"}`),!this.hasRoleName)return l.info("[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B\u8DF3\u8FC7: hasRoleName=false"),null;try{const e=this.getCurrentAgentId();if(!e)return l.info("[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B\u8DF3\u8FC7: agentId \u4E3A\u7A7A"),null;const t=await this.memoryStore.listByType("project_memory"),r=t.filter(c=>c.memory_status==="updating"&&c.updating_agent_id===e);if(r.length>0){this.startLeaseRenewal();const c=this.filterFileChangesByRenotifyCooldown(await this.checkMemoriesFileChanges(r));if(c.length>0){for(const
|
|
21
|
-
`);return{msgId:`memory-file-change-${Date.now()}`,senderId:"MCP-System",senderName:"\u7CFB\u7EDF",receiverId:e,content:`\u68C0\u6D4B\u5230\u4EE5\u4E0B ${
|
|
20
|
+
...\u53CA\u5176\u4ED6 ${i.length-5} \u6761`:""}`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_expiration",uris:i.map(n=>n.uri)}}}return null}catch(e){return l.warn("[McpServer] \u6784\u5EFA\u8FD1\u671F\u8BB0\u5FC6\u8FC7\u671F\u56DE\u5FC6\u901A\u77E5\u5931\u8D25: %s",e instanceof Error?e.message:String(e)),null}}async buildMemoryFileChangeNotification(){if(l.info(`[McpServer] buildMemoryFileChangeNotification \u88AB\u8C03\u7528: hasRoleName=${this.hasRoleName}, agentId=${this.getCurrentAgentId()??"(\u7A7A)"}`),!this.hasRoleName)return l.info("[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B\u8DF3\u8FC7: hasRoleName=false"),null;try{const e=this.getCurrentAgentId();if(!e)return l.info("[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B\u8DF3\u8FC7: agentId \u4E3A\u7A7A"),null;const t=await this.memoryStore.listByType("project_memory"),r=t.filter(c=>c.memory_status==="updating"&&c.updating_agent_id===e);if(r.length>0){this.startLeaseRenewal();const c=this.filterFileChangesByRenotifyCooldown(await this.checkMemoriesFileChanges(r));if(c.length>0){for(const E of c){const A=r.find(N=>N.id===E.memoryId);A&&await this.memoryStore.updateMemory({uri:A.uri,memory_type:"project_memory",memory_status:"updating",updating_agent_id:e,file_md5_map:A.file_md5_map,last_check_time:A.last_check_time,bound_files:A.bound_files})}const f=Math.min(c.length,5),b=c.slice(0,5).map(E=>`- ${E.memoryUri} (\u6587\u4EF6: ${E.changedFiles.join(", ")})`).join(`
|
|
21
|
+
`);return{msgId:`memory-file-change-${Date.now()}`,senderId:"MCP-System",senderName:"\u7CFB\u7EDF",receiverId:e,content:`\u68C0\u6D4B\u5230\u4EE5\u4E0B ${f} \u4E2A\u5904\u4E8E\u66F4\u65B0\u4E2D\u7684 Memory \u7ED1\u5B9A\u7684\u6587\u4EF6\u518D\u6B21\u53D8\u66F4\uFF0C\u5DF2\u66F4\u65B0 MD5 \u8BB0\u5F55\uFF1A
|
|
22
22
|
|
|
23
23
|
${b}
|
|
24
24
|
|
|
25
|
-
\u8BF7\u8C03\u7528 read_memory \u67E5\u770B\u6700\u65B0\u5185\u5BB9\u5E76\u8C03\u7528 update_memory \u66F4\u65B0\u3002`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_file_change",uris:c.slice(0,5).map(
|
|
25
|
+
\u8BF7\u8C03\u7528 read_memory \u67E5\u770B\u6700\u65B0\u5185\u5BB9\u5E76\u8C03\u7528 update_memory \u66F4\u65B0\u3002`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_file_change",uris:c.slice(0,5).map(E=>E.memoryUri),fileChanges:c.slice(0,5).map(E=>{const A=r.find(N=>N.id===E.memoryId);return{uri:E.memoryUri,boundFiles:A?.bound_files??[],fileStatuses:E.fileStatuses,changedFiles:E.changedFiles}})}}}const y=r,g=new Map;for(const f of y.slice(0,5))g.set(f.uri,await this.computeBoundFileStatuses(f));const S=y.filter(f=>{const b=g.get(f.uri);return!b||b.length===0?!1:b.some(E=>E.status==="content_changed"||E.status==="not_found")}),v=y.filter(f=>!S.includes(f));if(v.length>0){l.info(`[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B Step1: ${v.length} \u4E2A updating memory \u7ED1\u5B9A\u6587\u4EF6\u65E0\u771F\u5B9E\u53D8\u66F4\uFF0C\u81EA\u52A8\u91CA\u653E: ${v.map(f=>f.uri).join(", ")}`);for(const f of v)try{await this.memoryStore.releaseMemoryClaim(f.uri),this.activeLeaseUris.delete(f.uri),await this.memoryStore.updateMemory({uri:f.uri,memory_type:"project_memory"})}catch(b){l.info(`[McpServer] \u81EA\u52A8\u91CA\u653E stale updating memory \u5931\u8D25: ${f.uri}`,b)}this.activeLeaseUris.size===0&&this.stopLeaseRenewal()}if(S.length===0)return l.info("[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B Step1: \u6240\u6709 updating memory \u7ED1\u5B9A\u6587\u4EF6\u5747\u65E0\u771F\u5B9E\u53D8\u66F4\uFF0C\u5DF2\u81EA\u52A8\u91CA\u653E\uFF0C\u8DF3\u8FC7\u59D4\u6258"),null;const k=S.slice(0,5).map(f=>`- ${f.uri} (\u6587\u4EF6: ${f.bound_files?.join(", ")||"\u672A\u77E5"})`).join(`
|
|
26
26
|
`);return l.info(`[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B Step1: ${S.length}/${r.length} \u4E2A updating memory \u6709\u771F\u5B9E\u6587\u4EF6\u53D8\u66F4\uFF0C\u89E6\u53D1\u59D4\u6258`),{msgId:`memory-update-pending-${Date.now()}`,senderId:"MCP-System",senderName:"\u7CFB\u7EDF",receiverId:e,content:`\u60A8\u6709\u4EE5\u4E0B Memory \u6B63\u5904\u4E8E\u66F4\u65B0\u4E2D\u72B6\u6001\u4F46\u5C1A\u672A\u5B8C\u6210\u66F4\u65B0\uFF1A
|
|
27
27
|
|
|
28
|
-
${
|
|
28
|
+
${k}
|
|
29
29
|
|
|
30
|
-
\u8BF7\u7EE7\u7EED\u5B8C\u6210\u66F4\u65B0\u5DE5\u4F5C\u3002`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_file_change",uris:S.slice(0,5).map(
|
|
30
|
+
\u8BF7\u7EE7\u7EED\u5B8C\u6210\u66F4\u65B0\u5DE5\u4F5C\u3002`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_file_change",uris:S.slice(0,5).map(f=>f.uri),fileChanges:S.slice(0,5).map(f=>({uri:f.uri,boundFiles:f.bound_files??[],fileStatuses:g.get(f.uri)??[]}))}}}const i=await this.memoryStore.listByType("recently_memory"),s=await this.memoryStore.listByType("agent_memory"),n=[...i,...s],o=n.filter(c=>c.bound_files&&c.bound_files.length>0);l.info(`[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B Step2: recently=${i.length}, agent=${s.length}, \u6709\u7ED1\u5B9A\u6587\u4EF6=${o.length}/${n.length}\u3002\u8BE6\u60C5: ${n.map(c=>`${c.uri}(bound=${c.bound_files?.length??0},md5=${Object.keys(c.file_md5_map??{}).length})`).join("; ")||"\u65E0 memory"}`);const a=new Map;for(const c of n)c.bound_files&&c.bound_files.length>0&&a.set(c.id,JSON.stringify(c.file_md5_map??{}));const m=this.filterFileChangesByRenotifyCooldown(await this.checkMemoriesFileChanges(n)),d=m;l.info(`[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B Step2: \u68C0\u6D4B\u5230\u53D8\u66F4=${m.length}`+(m.length>0?` \u53D8\u66F4\u9879: ${m.map(c=>`${c.memoryUri}(${c.changedFiles.join(",")})`).join("; ")}`:""));const p=n.filter(c=>{if(!c.bound_files||c.bound_files.length===0||m.some(S=>S.memoryId===c.id))return!1;const y=a.get(c.id),g=JSON.stringify(c.file_md5_map??{});return y!==g});if(p.length>0){l.info(`[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B Step2: \u56DE\u5199 ${p.length} \u4E2A listable memory \u7684\u4FEE\u6B63 MD5 map`);for(const c of p)try{await this.memoryStore.updateMemory({uri:c.uri,memory_type:c.memory_type,file_md5_map:c.file_md5_map,last_check_time:c.last_check_time})}catch(y){l.info(`[McpServer] \u56DE\u5199 listable MD5 map \u5931\u8D25: ${c.uri}`,y)}}if(d.length>0){const c=d.map(y=>`- ${y.memoryUri} (\u6587\u4EF6: ${y.changedFiles.join(", ")})`).join(`
|
|
31
31
|
`);return{msgId:`memory-file-change-${Date.now()}`,senderId:"MCP-System",senderName:"\u7CFB\u7EDF",receiverId:e,content:`\u68C0\u6D4B\u5230\u4EE5\u4E0B Memory \u7ED1\u5B9A\u7684\u6587\u4EF6\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u53CA\u65F6\u66F4\u65B0\uFF1A
|
|
32
32
|
|
|
33
33
|
${c}
|
|
34
34
|
|
|
35
|
-
\u8BF7\u8C03\u7528 read_memory \u67E5\u770B\u5185\u5BB9\u5E76\u8C03\u7528 update_memory \u66F4\u65B0\u3002`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_file_change",uris:d.map(
|
|
36
|
-
`);return{msgId:`memory-file-change-${Date.now()}`,senderId:"MCP-System",senderName:"\u7CFB\u7EDF",receiverId:e,content:`\u68C0\u6D4B\u5230\u4EE5\u4E0B ${
|
|
35
|
+
\u8BF7\u8C03\u7528 read_memory \u67E5\u770B\u5185\u5BB9\u5E76\u8C03\u7528 update_memory \u66F4\u65B0\u3002`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_file_change",uris:d.map(y=>y.memoryUri),fileChanges:d.map(y=>{const g=n.find(S=>S.id===y.memoryId);return{uri:y.memoryUri,boundFiles:g?.bound_files??[],fileStatuses:y.fileStatuses,changedFiles:y.changedFiles}})}}}const u=t.filter(c=>c.bound_files&&c.bound_files.length>0&&(c.memory_status==="normal"||!c.memory_status)&&!this.isClaimCached(c.uri)),M=t.filter(c=>c.bound_files&&c.bound_files.length>0);l.info(`[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B Step3: project_memory \u603B\u6570=${t.length}, \u6709\u7ED1\u5B9A\u6587\u4EF6=${M.length}, \u5F85\u68C0\u6D4B(\u8FC7\u6EE4updating/claimed\u540E)=${u.length}\u3002\u88AB\u8FC7\u6EE4\u539F\u56E0: ${M.length-u.length} \u9879(memory_status=updating \u6216 isClaimCached)`);const R=new Map;for(const c of u)R.set(c.id,JSON.stringify(c.file_md5_map??{}));const h=this.filterFileChangesByRenotifyCooldown(await this.checkMemoriesFileChanges(u)),w=u.filter(c=>{if(h.some(S=>S.memoryId===c.id))return!1;const y=R.get(c.id),g=JSON.stringify(c.file_md5_map??{});return y!==g&&c.file_md5_map&&Object.keys(c.file_md5_map).length>0});if(w.length>0){l.info(`[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B Step3: \u56DE\u5199 ${w.length} \u4E2A memory \u7684\u4FEE\u6B63 MD5 map \u5230\u670D\u52A1\u7AEF\uFF08\u65E0\u57FA\u7EBF/\u952E\u7F3A\u5931\u4FEE\u590D\uFF09`);for(const c of w)try{await this.memoryStore.updateMemory({uri:c.uri,memory_type:"project_memory",file_md5_map:c.file_md5_map,last_check_time:c.last_check_time})}catch(y){l.info(`[McpServer] \u56DE\u5199\u57FA\u7EBF MD5 \u5931\u8D25: ${c.uri}`,y)}}if(l.info(`[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B Step3: \u68C0\u6D4B\u5230\u53D8\u66F4=${h.length}`+(h.length>0?` \u53D8\u66F4\u9879: ${h.map(c=>`${c.memoryUri}(${c.changedFiles.join(",")})`).join("; ")}`:"")),h.length>0){const c=h.slice(0,5),y=c.map(v=>v.memoryUri);let g=!1,S=new Set;try{const v=await this.memoryStore.claimMemoryUpdate(y,T.LEASE_DURATION_MINUTES,"project_memory");S=new Set(v.claimed_uris??[]),g=!0}catch(v){l.info("[McpServer] Server claim API \u4E0D\u53EF\u7528\uFF0C\u964D\u7EA7\u5230\u672C\u5730\u76F4\u63A5\u6807\u8BB0:",v),S=new Set(y)}if(S.size>0){const v=c.filter(f=>S.has(f.memoryUri));for(const f of v){const b=t.find(E=>E.id===f.memoryId);b&&(await this.memoryStore.updateMemory({uri:b.uri,memory_type:"project_memory",memory_status:"updating",updating_agent_id:e,file_md5_map:b.file_md5_map,last_check_time:b.last_check_time,bound_files:b.bound_files}),this.activeLeaseUris.add(b.uri))}g&&S.size>0&&this.startLeaseRenewal();const k=v.map(f=>`- ${f.memoryUri} (\u6587\u4EF6: ${f.changedFiles.join(", ")})`).join(`
|
|
36
|
+
`);return{msgId:`memory-file-change-${Date.now()}`,senderId:"MCP-System",senderName:"\u7CFB\u7EDF",receiverId:e,content:`\u68C0\u6D4B\u5230\u4EE5\u4E0B ${v.length} \u4E2A\u6C38\u4E45\u8BB0\u5FC6\u7ED1\u5B9A\u7684\u6587\u4EF6\u5DF2\u53D8\u66F4\uFF0C\u5DF2\u4E3A\u60A8\u6807\u8BB0\u4E3A\u66F4\u65B0\u4E2D\uFF1A
|
|
37
37
|
|
|
38
|
-
${
|
|
38
|
+
${k}
|
|
39
39
|
|
|
40
|
-
\u8BF7\u8C03\u7528 read_memory \u67E5\u770B\u5185\u5BB9\u5E76\u8C03\u7528 update_memory \u66F4\u65B0\u3002\u66F4\u65B0\u5B8C\u6210\u540E\u72B6\u6001\u5C06\u81EA\u52A8\u6062\u590D\u4E3A\u6B63\u5E38\u3002`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_file_change",uris:E.map(y=>y.memoryUri),fileChanges:E.map(y=>{const b=t.find(v=>v.id===y.memoryId);return{uri:y.memoryUri,boundFiles:b?.bound_files??[],fileStatuses:y.fileStatuses,changedFiles:y.changedFiles}})}}}}return l.info("[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B\u5B8C\u6210: \u65E0\u53D8\u66F4\u901A\u77E5\u4EA7\u751F"),null}catch(e){return l.warn("[McpServer] \u6784\u5EFA Memory \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B\u901A\u77E5\u5931\u8D25: %s",e instanceof Error?e.message:String(e)),null}}isClaimCached(e){return this.activeLeaseUris.has(e)}async computeBoundFileStatuses(e){const t=[];if(!e.bound_files||e.bound_files.length===0)return t;const r=e.file_md5_map||{},i=process.env.AWS_WORKSPACE_PATH||process.cwd();for(const s of e.bound_files)try{const n=await this.calculateFileMd5(s);if(n===null){const a=g.resolve(i,s);await this.verifyFileNotExist(a)&&r[s]?t.push({path:s,status:"not_found",serverMd5:r[s]}):t.push({path:s,status:"no_change"});continue}const o=r[s];o?o!==n?t.push({path:s,status:"content_changed",localMd5:n,serverMd5:o}):t.push({path:s,status:"no_change"}):t.push({path:s,status:"no_change"})}catch{t.push({path:s,status:"no_change"})}return t}fileChangeFingerprint(e){const t=e.fileStatuses.filter(r=>r.status!=="no_change").map(r=>`${r.path}:${r.status}:${r.localMd5??""}`).sort();return`${e.memoryId}|${t.join("|")}`}filterFileChangesByRenotifyCooldown(e){if(e.length===0)return e;const t=Date.now(),r=[];let i=0;for(const s of e){const n=this.fileChangeFingerprint(s),o=this.fileChangeNotifyHistory.get(n);if(o!==void 0&&t-o<Y){i++;continue}this.fileChangeNotifyHistory.set(n,t),r.push(s)}if(i>0&&l.info("[McpServer] \u6587\u4EF6\u53D8\u66F4\u63D0\u9192\u51B7\u5374\u4E2D\uFF0C\u672C\u8F6E\u6291\u5236 %d \u6761\u91CD\u590D\u901A\u77E5\uFF08cooldown=%dms\uFF09",i,Y),this.fileChangeNotifyHistory.size>K){const s=this.fileChangeNotifyHistory.size-K;let n=0;for(const o of this.fileChangeNotifyHistory.keys()){if(n>=s)break;this.fileChangeNotifyHistory.delete(o),n++}}return r}async checkMemoriesFileChanges(e){const t=[];for(const r of e)if(!(!r.bound_files||r.bound_files.length===0))try{const i=[],s=[],n={},o=r.file_md5_map||{},a=process.env.AWS_WORKSPACE_PATH||process.cwd(),m=Object.keys(o).length===0;let d=!1;for(const p of r.bound_files)try{const u=await this.calculateFileMd5(p);if(u===null){const R=g.resolve(a,p);l.info(`[McpServer] MD5 \u8BA1\u7B97\u8FD4\u56DE null: ${p} -> ${R} (workspace=${a})`);const h=o[p];h?await this.verifyFileNotExist(R)?(s.push({path:p,status:"not_found",serverMd5:h}),i.push(`${p}\uFF08\u6587\u4EF6\u627E\u4E0D\u5230 Server: ${h}\uFF09`),r.bound_files&&(r.bound_files=r.bound_files.filter(c=>c!==p))):(l.info(`[McpServer] \u6587\u4EF6\u5B58\u5728\u4F46 MD5 \u8BA1\u7B97\u5931\u8D25\uFF08\u77AC\u6001\u9519\u8BEF\uFF09\uFF0C\u8DF3\u8FC7: ${p}`),s.push({path:p,status:"no_change"})):s.push({path:p,status:"no_change"});continue}n[p]=u;const M=o[p];M?M!==u?(l.info(`[McpServer] \u6587\u4EF6\u53D8\u66F4: ${p} old=${M} new=${u} (workspace=${a})`),s.push({path:p,status:"content_changed",localMd5:u,serverMd5:M}),i.push(`${p}\uFF08\u5185\u5BB9\u53D8\u66F4 \u672C\u5730: ${u} Server: ${M}\uFF09`)):s.push({path:p,status:"no_change"}):(s.push({path:p,status:"no_change"}),d=!0,l.info(`[McpServer] \u5EFA\u7ACB\u5355\u6587\u4EF6\u57FA\u7EBF: ${p} new=${u} (workspace=${a}, memory=${r.uri})`))}catch(u){l.info(`[McpServer] \u8BA1\u7B97\u6587\u4EF6 MD5 \u5931\u8D25: ${p}`,u),s.push({path:p,status:"no_change"})}if(m&&Object.keys(n).length>0){r.file_md5_map=n,r.last_check_time=new Date().toISOString();continue}d&&Object.keys(n).length>0&&(r.file_md5_map=n,r.last_check_time=new Date().toISOString()),i.length>0&&(t.push({memoryId:r.id,memoryUri:r.uri,fileStatuses:s,changedFiles:i}),r.last_check_time=new Date().toISOString())}catch(i){l.warn(`[McpServer] \u68C0\u67E5 Memory ${r.id} \u6587\u4EF6\u53D8\u66F4\u5931\u8D25:`,i)}return t}async calculateFileMd5(e){try{const{createReadStream:t}=await import("node:fs"),{createHash:r}=await import("node:crypto"),i=process.env.AWS_WORKSPACE_PATH||process.cwd(),s=g.resolve(i,e),n=g.resolve(i),o=g.resolve(s);return!o.startsWith(n+g.sep)&&o!==n?(l.warn(`[McpServer] calculateFileMd5: \u8DEF\u5F84\u9003\u9038\u88AB\u62D2\u7EDD: ${e}`),null):new Promise(a=>{const m=r("md5"),d=t(s);d.on("data",p=>m.update(p)),d.on("end",()=>a(m.digest("hex"))),d.on("error",()=>a(null))})}catch(t){return l.info(`[McpServer] \u8BA1\u7B97\u6587\u4EF6 MD5 \u5931\u8D25: ${e}`,t),null}}async verifyFileNotExist(e){try{return await k.promises.access(e,k.constants.F_OK),!1}catch{return!0}}async handleGetMessage(e=!1){if(e){const n=await this.confirmServerMessages(this.messageBuffer.takeForceDirectMessages());return this.buildPollResult(n)}const t=this.messageBuffer.size()>0;await this.hydrateUnreadMessagesFromServer();const r=await this.confirmServerMessages(this.messageBuffer.get()),i=r.directMessages.length>0||r.groupMessages.length>0,s=t||!i;return await this.prependMemoryNotification(r,()=>this.buildMemoryRecurrenceNotification())?this.buildPollResult(r,s):await this.prependMemoryNotification(r,()=>this.buildMemoryCleanupNotification())?this.buildPollResult(r,s):this.buildPollResult(r,s)}async confirmServerMessages(e){const t=a=>!!a.msgId&&(a.channel==="meeting_invite"||a.channel==="notification")&&!a._awsServerMessage,r=a=>!!a._awsServerMessage&&!!a.msgId&&a.channel==="meeting",i=e.directMessages.filter(a=>a._awsServerMessage&&a.msgId&&!r(a)),s=e.directMessages.filter(r),n=e.groupMessages.filter(a=>a._awsServerMessage&&a.msgId!==void 0),o=e.directMessages.filter(t);if(i.length===0&&s.length===0&&n.length===0&&o.length===0)return e;try{const a=Date.now();let m=null;if(i.length>0&&(I("confirm.dm-read.start",`mark_dm_read ${i.length} \u6761\uFF08\u6807\u51C6 callTool\uFF0C\u5E26\u91CD\u8BD5\u6700\u957F\u53EF\u8FBE 30s\uFF09`),m=await this.agentClient.markDmRead(i.map(h=>h.msgId)),I("confirm.dm-read.done",`\u8017\u65F6 ${Date.now()-a}ms\uFF0C\u53EF\u4EA4\u4ED8=${m.size}/${i.length}`)),s.length>0){l.info("[McpServer][DEBUG-poll] \u786E\u8BA4\u4EA4\u4ED8\u4F1A\u8BAE\u6D88\u606F %d \u6761: %s",s.length,JSON.stringify(s.map(w=>({id:w.msgId,channel:w.channel})))),I("confirm.meeting-messages",`count=${s.length} msgs=${O(s)}\uFF08\u5F00\u59CB mark_meeting_read\uFF09`);const h=Date.now();await this.agentClient.markMeetingRead(s.map(w=>w.msgId)),I("confirm.meeting-messages.done",`mark_meeting_read \u5B8C\u6210\uFF0C\u8017\u65F6 ${Date.now()-h}ms`)}const d=new Set,p=new Map;for(const h of n){if(!h.roomId){d.add(h.msgId);continue}const w=p.get(h.roomId)||[];w.push(h.msgId),p.set(h.roomId,w)}for(const[h,w]of p){const c=await this.agentClient.markGroupRead(h,w);for(const _ of c)d.add(_)}o.length>0&&(l.info("[McpServer][DEBUG-poll] \u786E\u8BA4\u4EA4\u4ED8\u901A\u77E5 %d \u6761: %s",o.length,JSON.stringify(o.map(h=>({id:h.msgId,channel:h.channel})))),I("confirm.notifications",`count=${o.length} msgs=${O(o)}\uFF08\u5F00\u59CB mark_notification_read\uFF09`),await this.agentClient.markNotificationRead(o.map(h=>h.msgId)),I("confirm.notifications.done",`mark_notification_read \u5B8C\u6210\uFF0C\u7D2F\u8BA1\u8017\u65F6 ${Date.now()-a}ms`));const u=e.directMessages.filter(h=>t(h)||r(h)||!h._awsServerMessage||!h.msgId?!0:m?m.has(h.msgId):!0),M=e.groupMessages.filter(h=>!h._awsServerMessage||h.msgId===void 0?!0:d.has(h.msgId)),R=e.directMessages.length-u.length+e.groupMessages.length-M.length;R>0&&l.info("[McpServer] \u4EA4\u4ED8\u786E\u8BA4\uFF1A\u4E22\u5F03\u5DF2\u64A4\u56DE\u6D88\u606F %d \u6761\uFF08\u79C1\u4FE1 %d / \u7FA4\u804A %d\uFF09",R,e.directMessages.length-u.length,e.groupMessages.length-M.length);for(const h of u)delete h._awsServerMessage;for(const h of M)delete h._awsServerMessage;return{directMessages:u,groupMessages:M}}catch(a){l.warn("[McpServer] \u6D88\u606F\u4EA4\u4ED8\u786E\u8BA4\u5931\u8D25\uFF0C\u964D\u7EA7\u4E3A\u76F4\u63A5\u4EA4\u4ED8: %s",a instanceof Error?a.message:String(a)),I("confirm.failed-degrade",`\u786E\u8BA4\u5931\u8D25\u964D\u7EA7\u4E3A\u76F4\u63A5\u4EA4\u4ED8: ${a instanceof Error?a.message:String(a)}\uFF08\u82E5\u6B64\u5904\u957F\u65F6\u95F4\u65E0\u4E0B\u6587\uFF0C\u8BF4\u660E\u5361\u5728\u6807\u51C6 callTool \u7684\u91CD\u8BD5\u5FAA\u73AF\u5185\uFF09`);for(const m of e.directMessages)delete m._awsServerMessage;for(const m of e.groupMessages)delete m._awsServerMessage;return e}}async hydrateUnreadMessagesFromServer(e={}){try{let t;try{t=await this.agentClient.fetchUnreadMessages({blockIfEmpty:e.blockIfEmpty??!1,blockTimeoutMs:e.blockTimeoutMs,includePipelineTasks:e.includePipelineTasks,pollMessageTimeoutMs:e.pollMessageTimeoutMs,skipGroupMessages:e.skipGroupMessages,preemptiveJoinWaitMs:e.preemptiveJoinWaitMs,propagatePollTimeout:e.propagatePollTimeout===!0})}catch(n){if(n instanceof ie)return I("hydrate.poll-timeout",`pollMessageTimeoutMs=${String(e.pollMessageTimeoutMs??"-")} \u5BA2\u6237\u7AEF\u8D85\u65F6\uFF0C\u670D\u52A1\u7AEF\u5927\u6982\u7387\u4ECD\u5728\u6267\u884C\u540C\u4E00\u8BF7\u6C42`),{failed:!0,timedOut:!0};throw n}if(t.directMessages.length===0&&t.groupMessages.length===0)return I("hydrate.empty",`blockIfEmpty=${String(e.blockIfEmpty??!1)} preemptiveJoinWaitMs=${String(e.preemptiveJoinWaitMs??"-")} \u670D\u52A1\u7AEF\u672C\u6B21\u8FD4\u56DE 0 \u6761`),{failed:!1,timedOut:!1};const r=t.directMessages.filter(n=>!this.shouldBufferIncomingMessage(n)),i=t.directMessages.filter(n=>this.shouldBufferIncomingMessage(n));r.length>0&&I("hydrate.dropped-by-filter",`dropped=${O(r)}`);const s=t.groupMessages.filter(n=>this.shouldBufferIncomingMessage(n));return i.forEach(n=>{const o=n.channel;o!=="meeting_invite"&&o!=="notification"&&(n._awsServerMessage=!0),this.messageBuffer.push(n)}),s.forEach(n=>{n._awsServerMessage=!0,this.messageBuffer.push(n)}),l.info(`[McpServer] \u5DF2\u8865\u62C9\u672A\u8BFB\u6D88\u606F\uFF0C\u79C1\u804A: ${i.length}\uFF0C\u7FA4\u804A: ${s.length}`),I("hydrate.buffered",`dm=${O(i)} gm=${s.length}`),{failed:!1,timedOut:!1}}catch(t){return l.error("[McpServer] \u8865\u62C9\u672A\u8BFB\u6D88\u606F\u5931\u8D25: %s, stack=%s",t instanceof Error?t.message:String(t),t instanceof Error?t.stack:"(no stack)"),I("hydrate.failed",`${t instanceof Error?t.message:String(t)}`),{failed:!0,timedOut:!1}}}async hydrateBrowserListenerEvents(){try{const e=await this.agentClient.fetchBrowserListenerEvents();if(e.length===0)return!1;l.info(`[McpServer] \u62C9\u53D6\u5230 ${e.length} \u6761\u6D4F\u89C8\u5668\u76D1\u542C\u5668\u4E8B\u4EF6\uFF0C\u6CE8\u5165\u6D88\u606F\u7F13\u51B2`);for(const t of e){const r=this.buildListenerEventNotification(t);r&&this.messageBuffer.push(r)}return!0}catch(e){return l.warn("[McpServer] \u62C9\u53D6\u6D4F\u89C8\u5668\u76D1\u542C\u5668\u4E8B\u4EF6\u5931\u8D25: %s",e instanceof Error?e.message:String(e)),!1}}async hydratePluginEvents(){try{const e=await this.agentClient.fetchPluginEvents();if(e.catalog&&(this.cachedPluginCatalog=e.catalog,this.pluginCatalogDrainCompactionSeq=e.compactionSeq),e.events.length===0)return!1;l.info(`[McpServer] \u62C9\u53D6\u5230 ${e.events.length} \u6761\u63D2\u4EF6\u4E8B\u4EF6\uFF0C\u6CE8\u5165\u6D88\u606F\u7F13\u51B2`);for(const t of e.events)this.messageBuffer.push(t);return!0}catch(e){return l.warn("[McpServer] \u62C9\u53D6\u63D2\u4EF6\u4E8B\u4EF6\u5931\u8D25: %s",e instanceof Error?e.message:String(e)),!1}}buildListenerEventNotification(e){try{const t=this.getCurrentAgentId(),r=e.browserId&&e.browserId!=="default"?`\u6D4F\u89C8\u5668[${e.browserId}]`:"\u6D4F\u89C8\u5668",i=e.selector?`\u5143\u7D20\u9009\u62E9\u5668: ${e.selector}
|
|
40
|
+
\u8BF7\u8C03\u7528 read_memory \u67E5\u770B\u5185\u5BB9\u5E76\u8C03\u7528 update_memory \u66F4\u65B0\u3002\u66F4\u65B0\u5B8C\u6210\u540E\u72B6\u6001\u5C06\u81EA\u52A8\u6062\u590D\u4E3A\u6B63\u5E38\u3002`,requireReply:!1,timestamp:new Date().toISOString(),_acodeAutoDelegate:{type:"memory_file_change",uris:v.map(f=>f.memoryUri),fileChanges:v.map(f=>{const b=t.find(E=>E.id===f.memoryId);return{uri:f.memoryUri,boundFiles:b?.bound_files??[],fileStatuses:f.fileStatuses,changedFiles:f.changedFiles}})}}}}return l.info("[McpServer] \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B\u5B8C\u6210: \u65E0\u53D8\u66F4\u901A\u77E5\u4EA7\u751F"),null}catch(e){return l.warn("[McpServer] \u6784\u5EFA Memory \u6587\u4EF6\u53D8\u66F4\u68C0\u6D4B\u901A\u77E5\u5931\u8D25: %s",e instanceof Error?e.message:String(e)),null}}isClaimCached(e){return this.activeLeaseUris.has(e)}async computeBoundFileStatuses(e){const t=[];if(!e.bound_files||e.bound_files.length===0)return t;const r=e.file_md5_map||{},i=process.env.AWS_WORKSPACE_PATH||process.cwd();for(const s of e.bound_files)try{const n=await this.calculateFileMd5(s);if(n===null){const a=_.resolve(i,s);await this.verifyFileNotExist(a)&&r[s]?t.push({path:s,status:"not_found",serverMd5:r[s]}):t.push({path:s,status:"no_change"});continue}const o=r[s];o?o!==n?t.push({path:s,status:"content_changed",localMd5:n,serverMd5:o}):t.push({path:s,status:"no_change"}):t.push({path:s,status:"no_change"})}catch{t.push({path:s,status:"no_change"})}return t}fileChangeFingerprint(e){const t=e.fileStatuses.filter(r=>r.status!=="no_change").map(r=>`${r.path}:${r.status}:${r.localMd5??""}`).sort();return`${e.memoryId}|${t.join("|")}`}filterFileChangesByRenotifyCooldown(e){if(e.length===0)return e;const t=Date.now(),r=[];let i=0;for(const s of e){const n=this.fileChangeFingerprint(s),o=this.fileChangeNotifyHistory.get(n);if(o!==void 0&&t-o<Y){i++;continue}this.fileChangeNotifyHistory.set(n,t),r.push(s)}if(i>0&&l.info("[McpServer] \u6587\u4EF6\u53D8\u66F4\u63D0\u9192\u51B7\u5374\u4E2D\uFF0C\u672C\u8F6E\u6291\u5236 %d \u6761\u91CD\u590D\u901A\u77E5\uFF08cooldown=%dms\uFF09",i,Y),this.fileChangeNotifyHistory.size>K){const s=this.fileChangeNotifyHistory.size-K;let n=0;for(const o of this.fileChangeNotifyHistory.keys()){if(n>=s)break;this.fileChangeNotifyHistory.delete(o),n++}}return r}async checkMemoriesFileChanges(e){const t=[];for(const r of e)if(!(!r.bound_files||r.bound_files.length===0))try{const i=[],s=[],n={},o=r.file_md5_map||{},a=process.env.AWS_WORKSPACE_PATH||process.cwd(),m=Object.keys(o).length===0;let d=!1;for(const p of r.bound_files)try{const u=await this.calculateFileMd5(p);if(u===null){const R=_.resolve(a,p);l.info(`[McpServer] MD5 \u8BA1\u7B97\u8FD4\u56DE null: ${p} -> ${R} (workspace=${a})`);const h=o[p];h?await this.verifyFileNotExist(R)?(s.push({path:p,status:"not_found",serverMd5:h}),i.push(`${p}\uFF08\u6587\u4EF6\u627E\u4E0D\u5230 Server: ${h}\uFF09`),r.bound_files&&(r.bound_files=r.bound_files.filter(c=>c!==p))):(l.info(`[McpServer] \u6587\u4EF6\u5B58\u5728\u4F46 MD5 \u8BA1\u7B97\u5931\u8D25\uFF08\u77AC\u6001\u9519\u8BEF\uFF09\uFF0C\u8DF3\u8FC7: ${p}`),s.push({path:p,status:"no_change"})):s.push({path:p,status:"no_change"});continue}n[p]=u;const M=o[p];M?M!==u?(l.info(`[McpServer] \u6587\u4EF6\u53D8\u66F4: ${p} old=${M} new=${u} (workspace=${a})`),s.push({path:p,status:"content_changed",localMd5:u,serverMd5:M}),i.push(`${p}\uFF08\u5185\u5BB9\u53D8\u66F4 \u672C\u5730: ${u} Server: ${M}\uFF09`)):s.push({path:p,status:"no_change"}):(s.push({path:p,status:"no_change"}),d=!0,l.info(`[McpServer] \u5EFA\u7ACB\u5355\u6587\u4EF6\u57FA\u7EBF: ${p} new=${u} (workspace=${a}, memory=${r.uri})`))}catch(u){l.info(`[McpServer] \u8BA1\u7B97\u6587\u4EF6 MD5 \u5931\u8D25: ${p}`,u),s.push({path:p,status:"no_change"})}if(m&&Object.keys(n).length>0){r.file_md5_map=n,r.last_check_time=new Date().toISOString();continue}d&&Object.keys(n).length>0&&(r.file_md5_map=n,r.last_check_time=new Date().toISOString()),i.length>0&&(t.push({memoryId:r.id,memoryUri:r.uri,fileStatuses:s,changedFiles:i}),r.last_check_time=new Date().toISOString())}catch(i){l.warn(`[McpServer] \u68C0\u67E5 Memory ${r.id} \u6587\u4EF6\u53D8\u66F4\u5931\u8D25:`,i)}return t}async calculateFileMd5(e){try{const{createReadStream:t}=await import("node:fs"),{createHash:r}=await import("node:crypto"),i=process.env.AWS_WORKSPACE_PATH||process.cwd(),s=_.resolve(i,e),n=_.resolve(i),o=_.resolve(s);return!o.startsWith(n+_.sep)&&o!==n?(l.warn(`[McpServer] calculateFileMd5: \u8DEF\u5F84\u9003\u9038\u88AB\u62D2\u7EDD: ${e}`),null):new Promise(a=>{const m=r("md5"),d=t(s);d.on("data",p=>m.update(p)),d.on("end",()=>a(m.digest("hex"))),d.on("error",()=>a(null))})}catch(t){return l.info(`[McpServer] \u8BA1\u7B97\u6587\u4EF6 MD5 \u5931\u8D25: ${e}`,t),null}}async verifyFileNotExist(e){try{return await P.promises.access(e,P.constants.F_OK),!1}catch{return!0}}async handleGetMessage(e=!1){if(e){const n=await this.confirmServerMessages(this.messageBuffer.takeForceDirectMessages());return this.buildPollResult(n)}const t=this.messageBuffer.size()>0;await this.hydrateUnreadMessagesFromServer();const r=await this.confirmServerMessages(this.messageBuffer.get()),i=r.directMessages.length>0||r.groupMessages.length>0,s=t||!i;return await this.prependMemoryNotification(r,()=>this.buildMemoryRecurrenceNotification())?this.buildPollResult(r,s):await this.prependMemoryNotification(r,()=>this.buildMemoryCleanupNotification())?this.buildPollResult(r,s):this.buildPollResult(r,s)}async confirmServerMessages(e){const t=a=>!!a.msgId&&(a.channel==="meeting_invite"||a.channel==="notification")&&!a._awsServerMessage,r=a=>!!a._awsServerMessage&&!!a.msgId&&a.channel==="meeting",i=e.directMessages.filter(a=>a._awsServerMessage&&a.msgId&&!r(a)),s=e.directMessages.filter(r),n=e.groupMessages.filter(a=>a._awsServerMessage&&a.msgId!==void 0),o=e.directMessages.filter(t);if(i.length===0&&s.length===0&&n.length===0&&o.length===0)return e;try{const a=Date.now();let m=null;if(i.length>0&&(I("confirm.dm-read.start",`mark_dm_read ${i.length} \u6761\uFF08\u6807\u51C6 callTool\uFF0C\u5E26\u91CD\u8BD5\u6700\u957F\u53EF\u8FBE 30s\uFF09`),m=await this.agentClient.markDmRead(i.map(h=>h.msgId)),I("confirm.dm-read.done",`\u8017\u65F6 ${Date.now()-a}ms\uFF0C\u53EF\u4EA4\u4ED8=${m.size}/${i.length}`)),s.length>0){l.info("[McpServer][DEBUG-poll] \u786E\u8BA4\u4EA4\u4ED8\u4F1A\u8BAE\u6D88\u606F %d \u6761: %s",s.length,JSON.stringify(s.map(w=>({id:w.msgId,channel:w.channel})))),I("confirm.meeting-messages",`count=${s.length} msgs=${O(s)}\uFF08\u5F00\u59CB mark_meeting_read\uFF09`);const h=Date.now();await this.agentClient.markMeetingRead(s.map(w=>w.msgId)),I("confirm.meeting-messages.done",`mark_meeting_read \u5B8C\u6210\uFF0C\u8017\u65F6 ${Date.now()-h}ms`)}const d=new Set,p=new Map;for(const h of n){if(!h.roomId){d.add(h.msgId);continue}const w=p.get(h.roomId)||[];w.push(h.msgId),p.set(h.roomId,w)}for(const[h,w]of p){const c=await this.agentClient.markGroupRead(h,w);for(const y of c)d.add(y)}o.length>0&&(l.info("[McpServer][DEBUG-poll] \u786E\u8BA4\u4EA4\u4ED8\u901A\u77E5 %d \u6761: %s",o.length,JSON.stringify(o.map(h=>({id:h.msgId,channel:h.channel})))),I("confirm.notifications",`count=${o.length} msgs=${O(o)}\uFF08\u5F00\u59CB mark_notification_read\uFF09`),await this.agentClient.markNotificationRead(o.map(h=>h.msgId)),I("confirm.notifications.done",`mark_notification_read \u5B8C\u6210\uFF0C\u7D2F\u8BA1\u8017\u65F6 ${Date.now()-a}ms`));const u=e.directMessages.filter(h=>t(h)||r(h)||!h._awsServerMessage||!h.msgId?!0:m?m.has(h.msgId):!0),M=e.groupMessages.filter(h=>!h._awsServerMessage||h.msgId===void 0?!0:d.has(h.msgId)),R=e.directMessages.length-u.length+e.groupMessages.length-M.length;R>0&&l.info("[McpServer] \u4EA4\u4ED8\u786E\u8BA4\uFF1A\u4E22\u5F03\u5DF2\u64A4\u56DE\u6D88\u606F %d \u6761\uFF08\u79C1\u4FE1 %d / \u7FA4\u804A %d\uFF09",R,e.directMessages.length-u.length,e.groupMessages.length-M.length);for(const h of u)delete h._awsServerMessage;for(const h of M)delete h._awsServerMessage;return{directMessages:u,groupMessages:M}}catch(a){l.warn("[McpServer] \u6D88\u606F\u4EA4\u4ED8\u786E\u8BA4\u5931\u8D25\uFF0C\u964D\u7EA7\u4E3A\u76F4\u63A5\u4EA4\u4ED8: %s",a instanceof Error?a.message:String(a)),I("confirm.failed-degrade",`\u786E\u8BA4\u5931\u8D25\u964D\u7EA7\u4E3A\u76F4\u63A5\u4EA4\u4ED8: ${a instanceof Error?a.message:String(a)}\uFF08\u82E5\u6B64\u5904\u957F\u65F6\u95F4\u65E0\u4E0B\u6587\uFF0C\u8BF4\u660E\u5361\u5728\u6807\u51C6 callTool \u7684\u91CD\u8BD5\u5FAA\u73AF\u5185\uFF09`);for(const m of e.directMessages)delete m._awsServerMessage;for(const m of e.groupMessages)delete m._awsServerMessage;return e}}async hydrateUnreadMessagesFromServer(e={}){try{let t;try{t=await this.agentClient.fetchUnreadMessages({blockIfEmpty:e.blockIfEmpty??!1,blockTimeoutMs:e.blockTimeoutMs,includePipelineTasks:e.includePipelineTasks,pollMessageTimeoutMs:e.pollMessageTimeoutMs,skipGroupMessages:e.skipGroupMessages,preemptiveJoinWaitMs:e.preemptiveJoinWaitMs,propagatePollTimeout:e.propagatePollTimeout===!0})}catch(n){if(n instanceof ie)return I("hydrate.poll-timeout",`pollMessageTimeoutMs=${String(e.pollMessageTimeoutMs??"-")} \u5BA2\u6237\u7AEF\u8D85\u65F6\uFF0C\u670D\u52A1\u7AEF\u5927\u6982\u7387\u4ECD\u5728\u6267\u884C\u540C\u4E00\u8BF7\u6C42`),{failed:!0,timedOut:!0};throw n}if(t.directMessages.length===0&&t.groupMessages.length===0)return I("hydrate.empty",`blockIfEmpty=${String(e.blockIfEmpty??!1)} preemptiveJoinWaitMs=${String(e.preemptiveJoinWaitMs??"-")} \u670D\u52A1\u7AEF\u672C\u6B21\u8FD4\u56DE 0 \u6761`),{failed:!1,timedOut:!1};const r=t.directMessages.filter(n=>!this.shouldBufferIncomingMessage(n)),i=t.directMessages.filter(n=>this.shouldBufferIncomingMessage(n));r.length>0&&I("hydrate.dropped-by-filter",`dropped=${O(r)}`);const s=t.groupMessages.filter(n=>this.shouldBufferIncomingMessage(n));return i.forEach(n=>{const o=n.channel;o!=="meeting_invite"&&o!=="notification"&&(n._awsServerMessage=!0),this.messageBuffer.push(n)}),s.forEach(n=>{n._awsServerMessage=!0,this.messageBuffer.push(n)}),l.info(`[McpServer] \u5DF2\u8865\u62C9\u672A\u8BFB\u6D88\u606F\uFF0C\u79C1\u804A: ${i.length}\uFF0C\u7FA4\u804A: ${s.length}`),I("hydrate.buffered",`dm=${O(i)} gm=${s.length}`),{failed:!1,timedOut:!1}}catch(t){return l.error("[McpServer] \u8865\u62C9\u672A\u8BFB\u6D88\u606F\u5931\u8D25: %s, stack=%s",t instanceof Error?t.message:String(t),t instanceof Error?t.stack:"(no stack)"),I("hydrate.failed",`${t instanceof Error?t.message:String(t)}`),{failed:!0,timedOut:!1}}}async hydrateBrowserListenerEvents(){try{const e=await this.agentClient.fetchBrowserListenerEvents();if(e.length===0)return!1;l.info(`[McpServer] \u62C9\u53D6\u5230 ${e.length} \u6761\u6D4F\u89C8\u5668\u76D1\u542C\u5668\u4E8B\u4EF6\uFF0C\u6CE8\u5165\u6D88\u606F\u7F13\u51B2`);for(const t of e){const r=this.buildListenerEventNotification(t);r&&this.messageBuffer.push(r)}return!0}catch(e){return l.warn("[McpServer] \u62C9\u53D6\u6D4F\u89C8\u5668\u76D1\u542C\u5668\u4E8B\u4EF6\u5931\u8D25: %s",e instanceof Error?e.message:String(e)),!1}}async hydratePluginEvents(){try{const e=await this.agentClient.fetchPluginEvents();if(e.catalog&&(this.cachedPluginCatalog=e.catalog,this.pluginCatalogDrainCompactionSeq=e.compactionSeq),e.events.length===0)return!1;l.info(`[McpServer] \u62C9\u53D6\u5230 ${e.events.length} \u6761\u63D2\u4EF6\u4E8B\u4EF6\uFF0C\u6CE8\u5165\u6D88\u606F\u7F13\u51B2`);for(const t of e.events)this.messageBuffer.push(t);return!0}catch(e){return l.warn("[McpServer] \u62C9\u53D6\u63D2\u4EF6\u4E8B\u4EF6\u5931\u8D25: %s",e instanceof Error?e.message:String(e)),!1}}buildListenerEventNotification(e){try{const t=this.getCurrentAgentId(),r=e.browserId&&e.browserId!=="default"?`\u6D4F\u89C8\u5668[${e.browserId}]`:"\u6D4F\u89C8\u5668",i=e.selector?`\u5143\u7D20\u9009\u62E9\u5668: ${e.selector}
|
|
41
41
|
`:"",s=this.formatChangeType(e.changeType),n=new Date(e.triggeredAt).toISOString(),o=`\u3010\u6D4F\u89C8\u5668\u76D1\u542C\u5668\u89E6\u53D1 | ${r} | URL: ${e.url}\u3011
|
|
42
42
|
${i}\u53D8\u5316\u7C7B\u578B: ${s}
|
|
43
43
|
\u89E6\u53D1\u65F6\u95F4: ${n}
|
|
44
|
-
\u63D0\u793A\u8BCD: ${e.prompt}`;return{msgId:`browser-listener-${e.listenerId}-${e.triggeredAt}`,senderId:"MCP-BrowserListener",senderName:"\u6D4F\u89C8\u5668\u76D1\u542C\u5668",receiverId:t||void 0,content:o,requireReply:!1,role:"system",timestamp:n}}catch{return null}}formatChangeType(e){switch(e){case"added":return"\u65B0\u589E";case"removed":return"\u5220\u9664";case"changed":return"\u6539\u53D8";case"exists":return"\u5B58\u5728";default:return"\u6539\u53D8"}}async handleGetDmHistory(e){return await this.agentClient.getDmHistory(e.targetUserId,e.limit,e.since)}async handleGetGroupHistory(e){return await this.agentClient.getGroupHistory(e.limit,e.roomId,e.since)}async handleSubmitTaskResult(e){if(!e.nodeId||typeof e.nodeId!="string")throw new Error("nodeId is required");if(!e.outputPayload||typeof e.outputPayload!="string")throw new Error("outputPayload is required");const t=Array.isArray(e.changeLog)?e.changeLog:void 0;return await this.agentClient.submitTaskResult(e.nodeId,e.outputPayload,t)}async handleStartTaskRollback(e){const t={rollbackTaskId:this.getRequiredString(e,"rollbackTaskId")};return await this.agentClient.startTaskRollback(t)}async handleFinishTaskRollback(e){const t={rollbackTaskId:this.getRequiredString(e,"rollbackTaskId"),resultMessage:this.getOptionalString(e,"resultMessage")};return await this.agentClient.finishTaskRollback(t)}async handleRejectTask(e){if(!e.nodeId||typeof e.nodeId!="string")throw new Error("nodeId is required");if(!e.reason||typeof e.reason!="string")throw new Error("reason is required");return await this.agentClient.rejectTask(e.nodeId,e.reason)}async handleTerminateTask(e){if(!e.taskInstanceId||typeof e.taskInstanceId!="string")throw new Error("taskInstanceId is required");if(!e.reason||typeof e.reason!="string")throw new Error("reason is required");return await this.agentClient.terminateTask(e.taskInstanceId,e.reason)}async handleIncomingMessage(e){if(!this.shouldBufferIncomingMessage(e)){!this.isGroupMessage(e)&&this.isPipelineTaskAssignedNotification(e)&&(l.info("[McpServer] \u6536\u5230 pipeline_task_assigned \u5524\u9192\u4FE1\u53F7\uFF0C\u7ACB\u5373\u5524\u9192 poll \u8D70 hydrate \u91CD\u67E5"),this.messageBuffer.wakeUpWaiters());return}l.info(`[McpServer] \u6536\u5230\u6D88\u606F: ${e.content?.substring(0,50)||"(\u65E0\u5185\u5BB9)"}`);const t=e.channel;t!=="meeting_invite"&&t!=="notification"&&(e._awsServerMessage=!0),this.messageBuffer.push(e),!this.isGroupMessage(e)&&e.force===!0&&this.agentClient.notifyBridgeForceMessage().catch(()=>{})}handleSystemNotify(e){const t=e?.type;if(typeof t!="string"||t!=="meeting_invite"&&t!=="meeting_creator_prompt")return;const r=this.parseNotificationPayload(e.payload);l.info("[McpServer] \u6536\u5230\u4F1A\u8BAE\u57DF\u7CFB\u7EDF\u901A\u77E5(type=%s, competitive=%s, meetingId=%s)\uFF0C\u5524\u9192 poll \u89E6\u53D1\u5F3A\u5236 hydrate",t,r?.competitive===!0?"true(\u89D2\u8272\u5E2D\u4F4D)":"false(\u76F4\u63A5\u6307\u540D)",typeof r?.meetingId=="string"?r.meetingId:typeof e.meetingId=="string"?e.meetingId:"unknown"),this.urgentMeetingHydrateRequested=!0,this.messageBuffer.wakeUpWaiters(),I("systemNotify.meeting-domain",`type=${t} \u5DF2\u7F6E\u4F4D\u5F3A\u5236 hydrate \u5E76\u5524\u9192 poll`)}parseNotificationPayload(e){if(e&&typeof e=="object")return e;if(!(typeof e!="string"||e.length===0))try{const t=JSON.parse(e);return t&&typeof t=="object"?t:void 0}catch{return}}shouldBufferIncomingMessage(e){return!e||typeof e!="object"?(l.warn("[McpServer] \u5FFD\u7565\u7ED3\u6784\u5F02\u5E38\u7684\u6D88\u606F\uFF0C\u907F\u514D\u7F13\u51B2\u533A\u6C61\u67D3"),!1):this.isSelfSentMessage(e)?(l.info("[McpServer] \u5FFD\u7565\u5F53\u524D Agent \u81EA\u5DF1\u53D1\u9001\u7684\u6D88\u606F\uFF0C\u907F\u514D poll_message/get_message \u56DE\u73AF"),!1):this.isGroupMessage(e)?!0:this.isPipelineTaskAssignedNotification(e)?(l.info("[McpServer] \u5FFD\u7565\u6301\u4E45\u5316 pipeline_task_assigned \u79C1\u4FE1\uFF0C\u4EC5\u4F5C\u4E3A poll_message \u5524\u9192\u4FE1\u53F7\u5904\u7406"),!1):!0}isGroupMessage(e){return!!e&&typeof e=="object"&&typeof e.msgId=="number"}isPipelineTaskAssignedNotification(e){const t=typeof e.content=="string"?e.content:"",r=typeof e.prompt=="string"?e.prompt:"";return t.includes("pipeline_task_assigned")||r.includes("pipeline_task_assigned")}isSelfSentMessage(e){if(!e||typeof e!="object")return!1;const t=this.getCurrentAgentId();return!!t&&typeof e.senderId=="string"&&e.senderId===t}getCurrentAgentId(){const e=this.agentClient;return typeof e.getState!="function"?null:e.getState().agentId??null}sanitizeAgentIdForTodoFile(e){return String(e).replace(/[^a-zA-Z0-9_-]/g,"_")}async buildTodoBlockNotification(){const e=this.getCurrentAgentId();if(!e)return null;const t=
|
|
44
|
+
\u63D0\u793A\u8BCD: ${e.prompt}`;return{msgId:`browser-listener-${e.listenerId}-${e.triggeredAt}`,senderId:"MCP-BrowserListener",senderName:"\u6D4F\u89C8\u5668\u76D1\u542C\u5668",receiverId:t||void 0,content:o,requireReply:!1,role:"system",timestamp:n}}catch{return null}}formatChangeType(e){switch(e){case"added":return"\u65B0\u589E";case"removed":return"\u5220\u9664";case"changed":return"\u6539\u53D8";case"exists":return"\u5B58\u5728";default:return"\u6539\u53D8"}}async handleGetDmHistory(e){return await this.agentClient.getDmHistory(e.targetUserId,e.limit,e.since)}async handleGetGroupHistory(e){return await this.agentClient.getGroupHistory(e.limit,e.roomId,e.since)}async handleSubmitTaskResult(e){if(!e.nodeId||typeof e.nodeId!="string")throw new Error("nodeId is required");if(!e.outputPayload||typeof e.outputPayload!="string")throw new Error("outputPayload is required");const t=Array.isArray(e.changeLog)?e.changeLog:void 0;return await this.agentClient.submitTaskResult(e.nodeId,e.outputPayload,t)}async handleStartTaskRollback(e){const t={rollbackTaskId:this.getRequiredString(e,"rollbackTaskId")};return await this.agentClient.startTaskRollback(t)}async handleFinishTaskRollback(e){const t={rollbackTaskId:this.getRequiredString(e,"rollbackTaskId"),resultMessage:this.getOptionalString(e,"resultMessage")};return await this.agentClient.finishTaskRollback(t)}async handleRejectTask(e){if(!e.nodeId||typeof e.nodeId!="string")throw new Error("nodeId is required");if(!e.reason||typeof e.reason!="string")throw new Error("reason is required");return await this.agentClient.rejectTask(e.nodeId,e.reason)}async handleTerminateTask(e){if(!e.taskInstanceId||typeof e.taskInstanceId!="string")throw new Error("taskInstanceId is required");if(!e.reason||typeof e.reason!="string")throw new Error("reason is required");return await this.agentClient.terminateTask(e.taskInstanceId,e.reason)}async handleIncomingMessage(e){if(!this.shouldBufferIncomingMessage(e)){!this.isGroupMessage(e)&&this.isPipelineTaskAssignedNotification(e)&&(l.info("[McpServer] \u6536\u5230 pipeline_task_assigned \u5524\u9192\u4FE1\u53F7\uFF0C\u7ACB\u5373\u5524\u9192 poll \u8D70 hydrate \u91CD\u67E5"),this.messageBuffer.wakeUpWaiters());return}l.info(`[McpServer] \u6536\u5230\u6D88\u606F: ${e.content?.substring(0,50)||"(\u65E0\u5185\u5BB9)"}`);const t=e.channel;t!=="meeting_invite"&&t!=="notification"&&(e._awsServerMessage=!0),this.messageBuffer.push(e),!this.isGroupMessage(e)&&e.force===!0&&this.agentClient.notifyBridgeForceMessage().catch(()=>{})}handleSystemNotify(e){const t=e?.type;if(typeof t!="string"||t!=="meeting_invite"&&t!=="meeting_creator_prompt")return;const r=this.parseNotificationPayload(e.payload);l.info("[McpServer] \u6536\u5230\u4F1A\u8BAE\u57DF\u7CFB\u7EDF\u901A\u77E5(type=%s, competitive=%s, meetingId=%s)\uFF0C\u5524\u9192 poll \u89E6\u53D1\u5F3A\u5236 hydrate",t,r?.competitive===!0?"true(\u89D2\u8272\u5E2D\u4F4D)":"false(\u76F4\u63A5\u6307\u540D)",typeof r?.meetingId=="string"?r.meetingId:typeof e.meetingId=="string"?e.meetingId:"unknown"),this.urgentMeetingHydrateRequested=!0,this.messageBuffer.wakeUpWaiters(),I("systemNotify.meeting-domain",`type=${t} \u5DF2\u7F6E\u4F4D\u5F3A\u5236 hydrate \u5E76\u5524\u9192 poll`)}parseNotificationPayload(e){if(e&&typeof e=="object")return e;if(!(typeof e!="string"||e.length===0))try{const t=JSON.parse(e);return t&&typeof t=="object"?t:void 0}catch{return}}shouldBufferIncomingMessage(e){return!e||typeof e!="object"?(l.warn("[McpServer] \u5FFD\u7565\u7ED3\u6784\u5F02\u5E38\u7684\u6D88\u606F\uFF0C\u907F\u514D\u7F13\u51B2\u533A\u6C61\u67D3"),!1):this.isSelfSentMessage(e)?(l.info("[McpServer] \u5FFD\u7565\u5F53\u524D Agent \u81EA\u5DF1\u53D1\u9001\u7684\u6D88\u606F\uFF0C\u907F\u514D poll_message/get_message \u56DE\u73AF"),!1):this.isGroupMessage(e)?!0:this.isPipelineTaskAssignedNotification(e)?(l.info("[McpServer] \u5FFD\u7565\u6301\u4E45\u5316 pipeline_task_assigned \u79C1\u4FE1\uFF0C\u4EC5\u4F5C\u4E3A poll_message \u5524\u9192\u4FE1\u53F7\u5904\u7406"),!1):!0}isGroupMessage(e){return!!e&&typeof e=="object"&&typeof e.msgId=="number"}isPipelineTaskAssignedNotification(e){const t=typeof e.content=="string"?e.content:"",r=typeof e.prompt=="string"?e.prompt:"";return t.includes("pipeline_task_assigned")||r.includes("pipeline_task_assigned")}isSelfSentMessage(e){if(!e||typeof e!="object")return!1;const t=this.getCurrentAgentId();return!!t&&typeof e.senderId=="string"&&e.senderId===t}getCurrentAgentId(){const e=this.agentClient;return typeof e.getState!="function"?null:e.getState().agentId??null}sanitizeAgentIdForTodoFile(e){return String(e).replace(/[^a-zA-Z0-9_-]/g,"_")}async buildTodoBlockNotification(){const e=this.getCurrentAgentId();if(!e)return null;const t=_.join(U(),"todos",`${this.sanitizeAgentIdForTodoFile(e)}.json`);let r;try{r=await P.promises.readFile(t,"utf-8")}catch(o){return o?.code==="ENOENT"||l.warn("[McpServer] \u8BFB\u53D6 Todo \u6587\u4EF6\u5931\u8D25\uFF0C\u653E\u884C poll_message: %s",o instanceof Error?o.message:String(o)),null}let i;try{i=JSON.parse(r)}catch(o){return l.warn("[McpServer] \u89E3\u6790 Todo \u6587\u4EF6\u5931\u8D25\uFF0C\u653E\u884C poll_message: %s",o instanceof Error?o.message:String(o)),null}return(Array.isArray(i.todos)?i.todos:[]).filter(o=>o&&typeof o=="object"&&typeof o.content=="string"&&(o.status==="pending"||o.status==="in_progress"||o.status==="cancelled")).length===0?null:{msgId:`todo-block-${Date.now()}`,senderId:"MCP-System",senderName:"\u7CFB\u7EDF",receiverId:e,content:"\u5F53\u524D\u6709\u672A\u5904\u7406\u7684todo list\u4E0D\u80FD\u4F7F\u7528poll_message\u963B\u585E\u83B7\u53D6\u6D88\u606F",requireReply:!1,timestamp:new Date().toISOString()}}async buildBackgroundTaskNotification(){try{const e=this.getCurrentAgentId();if(!e)return null;const t=_.join(U(),"bg-tasks",this.sanitizeAgentIdForTodoFile(e),"state.json");let r;try{r=await P.promises.readFile(t,"utf-8")}catch(d){if(d?.code==="ENOENT")return null;throw d}const i=JSON.parse(r),s=Array.isArray(i.tasks)?i.tasks:[],n=s.filter(d=>d&&typeof d=="object"&&typeof d.taskId=="string"&&d.status!=="running"&&!d.notified);if(n.length===0)return null;const o=n.slice(0,5),a=o.map(d=>`[bg:${d.taskId}] ${d.status} (exitCode=${d.exitCode??"?"}) ${d.commandPreview??""}
|
|
45
45
|
lines=${d.outputLineCount??0} bytes=${d.outputBytes??0}
|
|
46
46
|
Use read_background_output(task_id="${d.taskId}", mode="tail", lines=50) for full output.`).join(`
|
|
47
47
|
|
|
48
48
|
`),m=n.length>o.length?`
|
|
49
49
|
|
|
50
|
-
\uFF08\u53E6\u6709 ${n.length-o.length} \u6761\u5DF2\u5B8C\u6210\uFF0C\u8BF7\u7528 list_background_commands \u67E5\u770B\uFF09`:"";return await
|
|
50
|
+
\uFF08\u53E6\u6709 ${n.length-o.length} \u6761\u5DF2\u5B8C\u6210\uFF0C\u8BF7\u7528 list_background_commands \u67E5\u770B\uFF09`:"";return await P.promises.writeFile(t,JSON.stringify({...i,updatedAt:Date.now(),tasks:s.map(d=>n.some(p=>p.taskId===d.taskId)?{...d,notified:!0}:d)},null,2),"utf-8").catch(d=>{l.warn("[McpServer] \u6807\u8BB0\u540E\u53F0\u4EFB\u52A1\u5DF2\u901A\u77E5\u5931\u8D25: %s",d?.message??d)}),{msgId:`bg-notif-${Date.now()}`,senderId:"MCP-System",senderName:"ACode Background",receiverId:e,content:`[Background commands completed]
|
|
51
51
|
${a}${m}`,requireReply:!1,timestamp:new Date().toISOString()}}catch(e){return l.warn("[McpServer] \u6784\u5EFA\u540E\u53F0\u547D\u4EE4\u5B8C\u6210\u901A\u77E5\u5931\u8D25: %s",e instanceof Error?e.message:String(e)),null}}async start(){const e=new ee;await this.server.connect(e),await this.agentClient.initialize(),l.info("[McpServer] MCP Server \u5DF2\u542F\u52A8\uFF0C\u7B49\u5F85\u8FDE\u63A5..."),l.info(`[McpServer] \u53EF\u7528\u5DE5\u5177: ${F.map(t=>t.name).join(", ")}`),l.info(`[McpServer] \u5DE5\u4F5C\u76EE\u5F55: ${process.env.AWS_WORKSPACE_PATH||process.cwd()}`),H&&l.info("[McpServer] \u964D\u7EA7\u6A21\u5F0F\u5DF2\u542F\u7528\uFF0C\u6CE8\u518C\u5931\u8D25\u65F6\u5C06\u4EE5\u79BB\u7EBF\u6A21\u5F0F\u7EE7\u7EED\u8FD0\u884C"),this.autoRegisterInBackground(),l.info("[McpServer] MCP Server \u5DF2\u5C31\u7EEA\uFF0C\u5DE5\u5177\u5DF2\u53EF\u7528")}startLeaseRenewal(){this.leaseRenewalTimer||(this.leaseRenewalTimer=setInterval(async()=>{try{if(!this.getCurrentAgentId())return;(await this.memoryStore.renewMemoryLease(T.LEASE_DURATION_MINUTES)).renewed===0&&(l.warn("[McpServer] \u79DF\u7EA6\u5DF2\u4E22\u5931\uFF08renewed=0\uFF09\uFF0C\u505C\u6B62\u7EED\u671F\u5B9A\u65F6\u5668"),this.stopLeaseRenewal())}catch(e){const t=e instanceof Error?e.message:String(e);t.includes("not supported")?(l.info("[McpServer] \u5F53\u524D\u5B58\u50A8\u4E0D\u652F\u6301\u79DF\u7EA6\u7EED\u671F\uFF0C\u505C\u6B62\u7EED\u671F\u5B9A\u65F6\u5668"),this.stopLeaseRenewal()):l.warn("[McpServer] \u7EED\u671F\u79DF\u7EA6\u5931\u8D25: %s",t)}},T.LEASE_RENEW_INTERVAL_MS),l.info("[McpServer] \u79DF\u7EA6\u7EED\u671F\u5B9A\u65F6\u5668\u5DF2\u542F\u52A8\uFF0C\u95F4\u9694: 60s"))}stopLeaseRenewal(){this.leaseRenewalTimer&&(clearInterval(this.leaseRenewalTimer),this.leaseRenewalTimer=null,l.info("[McpServer] \u79DF\u7EA6\u7EED\u671F\u5B9A\u65F6\u5668\u5DF2\u505C\u6B62"))}stop(){this.stopLeaseRenewal(),this.getCurrentAgentId()&&this.memoryStore.releaseAllMemoryClaims().catch(t=>l.warn("[McpServer] \u91CA\u653E claim \u5931\u8D25: %s",t instanceof Error?t.message:String(t))),this.agentClient.stop(),l.info("[McpServer] MCP Server \u5DF2\u505C\u6B62")}async autoRegister(){const e=this.agentClient.getAgentConfig();l.info(`[McpServer] \u89D2\u8272: "${e.roleName}"`),l.info(`[McpServer] AgentID: "${e.agentId||"(\u81EA\u52A8\u5206\u914D)"}"`),l.info("[McpServer] \u6B63\u5728\u8BF7\u6C42\u8C03\u5EA6\u4E2D\u5FC3\u6CE8\u518C...");let t=0;for(;;)try{const r=await this.agentClient.register();l.info(`[McpServer] \u6CE8\u518C\u6210\u529F: ${r.displayName} (${r.agentId})`),l.info(`[McpServer] \u72B6\u6001: ${r.status}`),this.startListeningInternal(),l.info("[McpServer] \u6D88\u606F\u76D1\u542C\u5DF2\u81EA\u52A8\u542F\u52A8");const i=this.agentClient.getStatusReporter();i&&i.reportWaitingInput(),await this.reportMemoryStatsToServer(),this.maybeSyncPermanentMemoryToServer();return}catch(r){const i=r instanceof Error?r.message:String(r);if(t++,D>0&&t>=D){if(H){l.warn(`[McpServer] \u6CE8\u518C\u8D85\u8FC7\u6700\u5927\u91CD\u8BD5\u6B21\u6570 (${D}\u6B21)\uFF0C\u8FDB\u5165\u964D\u7EA7\u6A21\u5F0F`),this.agentClient.enterDegradedMode(),this.startListeningInternal(),l.info("[McpServer] \u964D\u7EA7\u6A21\u5F0F\uFF1A\u6D88\u606F\u76D1\u542C\u5DF2\u542F\u52A8"),this.agentClient.retryRegistrationInBackground(ce,me);const s=this.agentClient.getStatusReporter();s&&s.reportWaitingInput(),await this.reportMemoryStatsToServer();return}throw new Error(`\u6CE8\u518C\u8D85\u8FC7\u6700\u5927\u91CD\u8BD5\u6B21\u6570 (${D}\u6B21)\uFF0C\u653E\u5F03\u542F\u52A8: ${i}`)}l.warn(`[McpServer] \u6CE8\u518C\u5931\u8D25\uFF0C\u7B49\u5F85\u91CD\u8BD5... (${t}/${D}): ${i}`),await this.delay(le)}}autoRegisterInBackground(){this.autoRegister().catch(e=>{l.error("[McpServer] \u540E\u53F0\u6CE8\u518C\u5F02\u5E38: %s, stack=%s",e instanceof Error?e.message:String(e),e instanceof Error?e.stack:"(no stack)")})}startListeningInternal(){l.info("[McpServer] startListeningInternal \u88AB\u8C03\u7528");const e=t=>{l.info(`[McpServer] profileHandler \u88AB\u8C03\u7528\uFF0CdisplayName: ${t.displayName}`),this.messageBuffer.setProfileMessage(t),this.profileSynced=!0,this.syncRoleMemoryStore(t),this.maybeSyncPermanentMemoryToServer()};if(this.agentClient.isInDegradedMode()){l.info("[McpServer] \u964D\u7EA7\u6A21\u5F0F\uFF1A\u8DF3\u8FC7 WebSocket \u8FDE\u63A5\uFF0C\u4EC5\u542F\u52A8\u672C\u5730\u6D88\u606F\u76D1\u542C"),this.agentClient.start(this.handleIncomingMessage.bind(this),{pollMode:!1,profileHandler:e,systemNotifyHandler:this.handleSystemNotify.bind(this)}),this.activelySyncProfile();return}this.agentClient.start(this.handleIncomingMessage.bind(this),{pollMode:!1,profileHandler:e,systemNotifyHandler:this.handleSystemNotify.bind(this)}),this.activelySyncProfile()}activelySyncProfile(){this.profileSynced||this.agentClient.getProfile().then(e=>{this.profileSynced||(this.profileSynced=!0,l.info(`[McpServer] \u4E3B\u52A8\u83B7\u53D6 profile \u6210\u529F: displayName=${e.displayName}, roleName="${e.roleName??"(\u7A7A)"}"`),this.messageBuffer.setProfileMessage(e),this.syncRoleMemoryStore(e),this.maybeSyncPermanentMemoryToServer())}).catch(e=>{l.warn("[McpServer] \u4E3B\u52A8\u83B7\u53D6 profile \u5931\u8D25: %s",e instanceof Error?e.message:String(e))})}delay(e){return new Promise(t=>setTimeout(t,e))}}export{T as McpServer};
|
|
52
52
|
|
|
@@ -38,5 +38,5 @@ MCP \u5DE5\u5177\uFF08poll_message/get_message\uFF09\u4E0D\u518D\u8FD4\u56DE sys
|
|
|
38
38
|
|
|
39
39
|
\u8FD4\u56DE\u5B57\u6BB5\uFF1Aid\u3001projectId\u3001businessLine\u3001module\u3001level\u3001detail\u3001createdAt\u3002`,inputSchema:{type:"object",properties:{projectId:{type:"string",description:"\u9879\u76EE ID\uFF08\u5FC5\u586B\uFF09"},businessLine:{type:"string",description:"\u4E1A\u52A1\u7EBF\u540D\u79F0\uFF08\u5FC5\u586B\uFF09"},module:{type:"string",description:"\u6A21\u5757\u540D\uFF08\u53EF\u9009\uFF09"},level:{type:"string",description:"\u65E5\u5FD7\u7EA7\u522B\uFF1ADEBUG / INFO / WARN / ERROR\uFF08\u53EF\u9009\uFF09",enum:["DEBUG","INFO","WARN","ERROR"]},startTime:{type:"string",description:"\u8D77\u59CB\u65F6\u95F4\uFF0CISO \u683C\u5F0F\u5982 2026-08-01T00:00:00\uFF08\u53EF\u9009\uFF09"},endTime:{type:"string",description:"\u7ED3\u675F\u65F6\u95F4\uFF0CISO \u683C\u5F0F\u5982 2026-08-02T00:00:00\uFF08\u53EF\u9009\uFF09"},offset:{type:"number",description:"\u504F\u79FB\u91CF\uFF0C\u9ED8\u8BA4 0"},limit:{type:"number",description:"\u6BCF\u9875\u6761\u6570\uFF0C\u9ED8\u8BA4 20\uFF0C\u6700\u5927 200"}},required:["projectId","businessLine"]}},C={name:"query_file_changes_history",description:`\u5206\u9875\u67E5\u8BE2\u6587\u4EF6\u53D8\u66F4\u5386\u53F2\uFF08\u6309\u65F6\u95F4\u5012\u5E8F\uFF09\u3002\u7528\u4E8E\u4E86\u89E3\u5176\u5B83 Agent \u5BF9\u6587\u4EF6\u505A\u8FC7\u54EA\u4E9B\u4FEE\u6539\u3001\u4FEE\u6539\u539F\u56E0\u4E0E\u5F53\u524D\u72B6\u6001\uFF0C\u652F\u6301\u6309 \u89D2\u8272/\u5B9E\u4F8B/\u6587\u4EF6\u540D/\u76F8\u5BF9\u8DEF\u5F84/\u64CD\u4F5C/\u72B6\u6001/\u4EFB\u52A1\u5B9E\u4F8B/\u65F6\u95F4\u8303\u56F4 \u8FC7\u6EE4\u3002\u67E5\u8BE2\u8303\u56F4\u81EA\u52A8\u9650\u5B9A\u4E3A\u5F53\u524D Agent \u6240\u5C5E\u9879\u76EE\u3002
|
|
40
40
|
|
|
41
|
-
\u8FD4\u56DE\u5B57\u6BB5\uFF1Aid\u3001projectId\u3001roleName\u3001instanceName\u3001agentId\u3001operation\uFF08CREATE/UPDATE/DELETE\uFF09\u3001targetPath\u3001fullPath\u3001reason\u3001status\uFF08APPLIED/REVERTED/REVERT_FAILED\uFF09\u3001createdAt\u3001revertedAt\u3001revertedBy\u3002`,inputSchema:{type:"object",properties:{roleId:{type:"string",description:"\u89D2\u8272\u5B9A\u4E49 ID\uFF08\u53EF\u9009\uFF09"},agentId:{type:"string",description:"Agent \u5B9E\u4F8B ID\uFF08\u53EF\u9009\uFF1B\u4E0D\u4F20=\u67E5\u8BE2\u5F53\u524D\u9879\u76EE\u4E0B\u6240\u6709 Agent\uFF1B\u4F20\u5176\u5B83 Agent \u65F6\u670D\u52A1\u7AEF\u6821\u9A8C\u5176\u4E0E\u8C03\u7528\u8005\u540C\u9879\u76EE\uFF09"},fileName:{type:"string",description:"\u6587\u4EF6\u540D\uFF08\u53EF\u9009\uFF0C\u6309 basename \u6A21\u7CCA\u5339\u914D\uFF09"},filePath:{type:"string",description:"\u5DE5\u4F5C\u533A\u76F8\u5BF9\u8DEF\u5F84\uFF08\u53EF\u9009\uFF0C\u6309\u8D26\u672C\u8BB0\u5F55\u7684\u76F8\u5BF9\u8DEF\u5F84 targetPath \u5339\u914D\uFF0C\u542B\u76EE\u5F55\u524D\u7F00\u5339\u914D\uFF09\u3002\u652F\u6301 ./xx\u3001xx\u3001@/xx\u3001/xx \u7B49\u4EF7\u5199\u6CD5\uFF08@ \u89C6\u4E3A\u5DE5\u4F5C\u533A\u6839\u8DEF\u5F84\u522B\u540D\uFF09\u3002\u793A\u4F8B\uFF1A@/src/main.ts \u7CBE\u786E\u5339\u914D src/main.ts\uFF1B@/src \u5339\u914D src/ \u76EE\u5F55\u53CA\u5176\u4E0B\u6240\u6709\u6587\u4EF6\u7684\u53D8\u66F4\u3002\u4E0E fileName \u6B63\u4EA4\uFF1AfileName \u6309\u6587\u4EF6\u540D\u6A21\u7CCA\uFF0CfilePath \u6309\u76F8\u5BF9\u8DEF\u5F84\u5339\u914D\u3002"},operation:{type:"string",description:"\u64CD\u4F5C\u7C7B\u578B\uFF1ACREATE / UPDATE / DELETE\uFF08\u53EF\u9009\uFF09",enum:["CREATE","UPDATE","DELETE"]},status:{type:"string",description:"\u8BB0\u5F55\u72B6\u6001\uFF1AAPPLIED\uFF08\u5DF2\u751F\u6548\uFF09/ REVERTED\uFF08\u5DF2\u64A4\u9500\uFF09/ REVERT_FAILED\uFF08\u64A4\u9500\u5931\u8D25\uFF09\uFF08\u53EF\u9009\uFF09",enum:["APPLIED","REVERTED","REVERT_FAILED"]},taskInstanceId:{type:"string",description:"\u4EFB\u52A1\u5B9E\u4F8B ID\uFF08\u53EF\u9009\uFF09"},startTime:{type:"string",description:"\u8D77\u59CB\u65F6\u95F4\uFF0CISO \u683C\u5F0F\u5982 2026-08-01T00:00:00\uFF08\u53EF\u9009\uFF09"},endTime:{type:"string",description:"\u7ED3\u675F\u65F6\u95F4\uFF0CISO \u683C\u5F0F\u5982 2026-08-02T00:00:00\uFF08\u53EF\u9009\uFF09"},page:{type:"number",description:"\u9875\u7801\uFF0C\u9ED8\u8BA4 1"},pageSize:{type:"number",description:"\u6BCF\u9875\u6761\u6570\uFF0C\u9ED8\u8BA4 20"}},required:[]}},ce=new Set(["create_memory","read_memory","update_memory","delete_memory","search_memory","list_memories","get_memory_stats","list_memories_by_file","memory_recurrence","memory_recurrence_complete"]),M={name:"launch_config_list",description:"\u67E5\u8BE2\u5F53\u524D Agent \u6240\u5C5E\u9879\u76EE\u4E0B\u7684\u542F\u52A8\u9879\uFF08\u7C7B IDEA Run Configuration\uFF09\u5217\u8868\u3002\u6BCF\u4E2A\u542F\u52A8\u9879\u542B id\u3001name\u3001type\uFF08generic/java/python/node/go/php\uFF09\u3001command\u3001cwd\u3001env\u3001jdkId\u3001groupId\u3001sortOrder\u3002\u67E5\u8BE2\u8303\u56F4\u81EA\u52A8\u9650\u5B9A\u4E3A\u5F53\u524D\u9879\u76EE\uFF0C\u65E0\u9700\u4F20 projectId\u3002",inputSchema:{type:"object",properties:{},required:[]}},P={name:"launch_config_create",description:"\u5728\u5F53\u524D Agent \u6240\u5C5E\u9879\u76EE\u4E0B\u65B0\u5EFA\u542F\u52A8\u9879\uFF08\u7C7B IDEA Run Configuration\uFF09\u3002\u521B\u5EFA\u524D\u5EFA\u8BAE\u5148 launch_config_list \u67E5\u770B\u73B0\u6709\u914D\u7F6E\u4E0E\u547D\u540D\u4E60\u60EF\u3002\u9879\u76EE\u8303\u56F4\u81EA\u52A8\u63A8\u5BFC\uFF0C\u65E0\u9700\u4F20 projectId\u3002\u521B\u5EFA\u6210\u529F\u540E\u8FD4\u56DE\u65B0\u542F\u52A8\u9879\u5B8C\u6574\u4FE1\u606F\uFF08\u542B id\uFF09\u3002",inputSchema:{type:"object",properties:{name:{type:"string",description:"\u542F\u52A8\u9879\u540D\u79F0\uFF08\u5FC5\u586B\uFF0C\u9879\u76EE\u5185\u552F\u4E00\uFF0C\u2264128 \u5B57\u7B26\uFF09"},type:{type:"string",description:"\u542F\u52A8\u9879\u7C7B\u578B\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4 generic\uFF09\uFF1Ageneric / java / python / node / go / php",enum:["generic","java","python","node","go","php"]},command:{type:"string",description:"\u542F\u52A8\u547D\u4EE4\uFF08\u5FC5\u586B\uFF0C\u22648192 \u5B57\u7B26\uFF09\u3002\u652F\u6301\u5360\u4F4D\u7B26 ${WORKSPACE}\uFF08\u9879\u76EE\u5DE5\u4F5C\u533A\uFF09\u3001${JAVA_HOME}\uFF08\u6240\u9009 JDK\uFF09\u3001${VAR}\uFF08env \u4E2D\u5B9A\u4E49\u7684\u53D8\u91CF\uFF09\u3002\u793A\u4F8B\uFF1Anpm run dev\u3001python main.py\u3001mvn spring-boot:run"},cwd:{type:"string",description:"\u5DE5\u4F5C\u76EE\u5F55\uFF08\u5FC5\u586B\uFF0C\u2264512 \u5B57\u7B26\uFF09\u2014\u2014\u9879\u76EE\u5B9E\u9645\u4EE3\u7801/\u6784\u5EFA\u76EE\u5F55\u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u5982 D:/code/xxx/backend"},env:{type:"object",description:"\u989D\u5916\u73AF\u5883\u53D8\u91CF\uFF08\u53EF\u9009\uFF0C\u226464 \u9879\uFF09\uFF0C\u989D\u5916\u5C5E\u6027\uFF1A\u5B57\u7B26\u4E32\u503C",additionalProperties:{type:"string"}},jdkId:{type:"string",description:"\u9009\u4E2D\u7684 JDK ID\uFF08type=java \u65F6\u6709\u6548\uFF0C\u53EF\u9009\uFF09"},groupId:{type:"string",description:"\u6240\u5C5E\u542F\u52A8\u9879\u5206\u7EC4 ID\uFF08\u53EF\u9009\uFF0Cnull/\u7A7A=\u672A\u5206\u7EC4\uFF09"},sortOrder:{type:"number",description:"\u6392\u5E8F\u6743\u91CD\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u8FFD\u52A0\u5230\u6240\u5728\u5BB9\u5668\u672B\u5C3E\uFF09"},readinessPattern:{type:"string",description:'\u5C31\u7EEA\u65E5\u5FD7\u6B63\u5219\uFF08\u53EF\u9009\uFF0C\u2264512 \u5B57\u7B26\uFF0CJS RegExp \u8BED\u6CD5\uFF09\u3002\u8BBE\u7F6E\u540E wait_timeout_ms \u7B49\u5F85\u7684 ready \u4FE1\u53F7\u6539\u4E3A"\u8F93\u51FA\u884C\u547D\u4E2D\u8BE5\u6B63\u5219"\uFF08\u9002\u914D\u4E0D\u76D1\u542C\u7AEF\u53E3\u7684\u5E38\u9A7B\u8FDB\u7A0B\uFF0C\u5982 worker/\u6D88\u8D39\u8005\uFF09\u3002\u793A\u4F8B\uFF1A^Server ready|^Build (SUCCESS|successful)\u3002\u7559\u7A7A=\u7AEF\u53E3\u76D1\u542C\u63A2\u6D4B'}},required:["name","command","cwd"]}},f={name:"launch_config_update",description:"\u66F4\u65B0\u542F\u52A8\u9879\uFF08\u540D\u79F0/\u7C7B\u578B/\u547D\u4EE4/\u5DE5\u4F5C\u76EE\u5F55/\u73AF\u5883\u53D8\u91CF/JDK/\u5206\u7EC4/\u6392\u5E8F\uFF09\u3002\u672A\u4F20\u5B57\u6BB5\u4FDD\u6301\u539F\u503C\uFF1B\u4FEE\u6539\u540D\u79F0\u65F6\u9879\u76EE\u5185\u4E0D\u80FD\u91CD\u540D\u3002\u76EE\u6807\u542F\u52A8\u9879\u5FC5\u987B\u5C5E\u4E8E\u5F53\u524D\u9879\u76EE\uFF08\u670D\u52A1\u7AEF\u6821\u9A8C\uFF09\u3002\u8FD0\u884C\u4E2D\u7684\u542F\u52A8\u9879\uFF1A\u4FEE\u6539\u914D\u7F6E\u4E0D\u4F1A\u5F71\u54CD\u5DF2\u8FD0\u884C\u8FDB\u7A0B\uFF0C\u9700\u91CD\u542F\u540E\u751F\u6548\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5FC5\u586B\uFF09"},name:{type:"string",description:"\u542F\u52A8\u9879\u540D\u79F0\uFF08\u53EF\u9009\uFF0C\u2264128 \u5B57\u7B26\uFF09"},type:{type:"string",description:"\u542F\u52A8\u9879\u7C7B\u578B\uFF08\u53EF\u9009\uFF09\uFF1Ageneric / java / python / node / go / php",enum:["generic","java","python","node","go","php"]},command:{type:"string",description:"\u542F\u52A8\u547D\u4EE4\uFF08\u53EF\u9009\uFF0C\u22648192 \u5B57\u7B26\uFF09"},cwd:{type:"string",description:"\u5DE5\u4F5C\u76EE\u5F55\uFF08\u53EF\u9009\uFF09"},env:{type:"object",description:"\u989D\u5916\u73AF\u5883\u53D8\u91CF\uFF08\u53EF\u9009\uFF0C\u6574\u4F53\u8986\u76D6\u539F env\uFF09",additionalProperties:{type:"string"}},jdkId:{type:"string",description:"\u9009\u4E2D\u7684 JDK ID\uFF08type=java \u65F6\u6709\u6548\uFF0C\u53EF\u9009\uFF09"},groupId:{type:"string",description:"\u6240\u5C5E\u542F\u52A8\u9879\u5206\u7EC4 ID\uFF08\u53EF\u9009\uFF09"},clearGroupId:{type:"boolean",description:"\u663E\u5F0F\u6E05\u9664\u5206\u7EC4\uFF08\u79FB\u56DE\u9ED8\u8BA4\u5206\u7EC4\uFF0C\u53EF\u9009\uFF1B\u4E0D\u80FD\u4E0E groupId \u540C\u65F6\u4F20\uFF09"},sortOrder:{type:"number",description:"\u6392\u5E8F\u6743\u91CD\uFF08\u53EF\u9009\uFF09"},readinessPattern:{type:"string",description:"\u5C31\u7EEA\u65E5\u5FD7\u6B63\u5219\uFF08\u53EF\u9009\uFF0CJS RegExp \u8BED\u6CD5\uFF09\uFF1A\u8BBE\u7F6E\u540E\u542F\u52A8\u7B49\u5F85\u7684 ready \u4FE1\u53F7\u4E3A\u8F93\u51FA\u884C\u547D\u4E2D\u6B63\u5219\uFF08\u9002\u914D\u4E0D\u76D1\u542C\u7AEF\u53E3\u7684\u8FDB\u7A0B\uFF09\u3002\u7559\u7A7A=\u7AEF\u53E3\u76D1\u542C\u63A2\u6D4B"},clearReadinessPattern:{type:"boolean",description:"\u663E\u5F0F\u6E05\u9664\u5C31\u7EEA\u6B63\u5219\uFF0C\u6062\u590D\u7AEF\u53E3\u63A2\u6D4B\uFF08\u53EF\u9009\uFF1B\u4E0D\u80FD\u4E0E readinessPattern \u540C\u65F6\u4F20\uFF09"}},required:["configId"]}},j={name:"launch_config_delete",description:"\u5220\u9664\u542F\u52A8\u9879\u914D\u7F6E\u3002\u76EE\u6807\u542F\u52A8\u9879\u5FC5\u987B\u5C5E\u4E8E\u5F53\u524D\u9879\u76EE\uFF08\u670D\u52A1\u7AEF\u6821\u9A8C\uFF09\u3002\u6CE8\u610F\uFF1A\u82E5\u8BE5\u542F\u52A8\u9879\u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148 launch_config_stop \u505C\u6B62\u8FDB\u7A0B\u518D\u5220\u9664\uFF08\u5220\u9664\u914D\u7F6E\u4E0D\u4F1A\u81EA\u52A8\u505C\u6B62\u5DF2\u8FD0\u884C\u8FDB\u7A0B\uFF09\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5FC5\u586B\uFF09"}},required:["configId"]}},q={name:"launch_config_start",description:"\u542F\u52A8\u542F\u52A8\u9879\uFF0C\u5728\u8C03\u7528\u8005\u6240\u5728 runtime-bridge \u673A\u5668\u4E0A\u62C9\u8D77\u8FDB\u7A0B\u3002\u652F\u6301\u5355\u9879\uFF08configId\uFF09\u4E0E\u6279\u91CF\uFF08configIds \u6570\u7EC4\uFF0C\u4E00\u6B21\u5E76\u884C\u62C9\u8D77\u591A\u4E2A\uFF09\uFF1A\u6279\u91CF\u65F6\u9010\u9879\u4EE5\u914D\u7F6E\u4E3A\u51C6\u5E76\u884C\u542F\u52A8\uFF0C\u5355\u9879\u5931\u8D25\u4E0D\u5F71\u54CD\u5176\u4F59\u9879\uFF0C\u8FD4\u56DE\u9010\u9879\u7ED3\u679C\u4E0E\u6C47\u603B\uFF08ready/exited/timeout/failed/skipped \u8BA1\u6570\uFF09\u3002\u82E5\u542F\u52A8\u9879\u5DF2\u5904\u4E8E\u8FD0\u884C/\u6B63\u5728\u542F\u52A8\u72B6\u6001\uFF08\u672A\u9000\u51FA/\u505C\u6B62\uFF09\uFF0C\u8C03\u7528\u4F1A\u8FD4\u56DE skipped=true\uFF08\u9644 message\u300C\u5F53\u524D\u5DF2\u5904\u4E8E\u542F\u52A8/\u6B63\u5728\u542F\u52A8\u72B6\u6001\uFF0C\u8DF3\u8FC7\u300D\u4E0E\u5F53\u524D run\uFF09\u800C\u975E\u62A5\u9519\uFF0C\u4E0D\u4F1A\u91CD\u590D\u62C9\u8D77\uFF0C\u4E5F\u65E0\u9700\u5148 launch_config_status \u786E\u8BA4\u3002\u9ED8\u8BA4\u4E0D\u7B49\u5F85\u7ACB\u5373\u8FD4\u56DE\uFF1B\u4F20 wait_timeout_ms > 0 \u65F6\u963B\u585E\u7B49\u5F85\u542F\u52A8\u7ED3\u679C\uFF08\u5355\u9879\u8FD4\u56DE wait \u5B57\u6BB5\uFF0C\u6279\u91CF\u5BF9\u6210\u529F\u62C9\u8D77\u9879\u5E76\u884C\u7B49\u5F85\u3001\u6574\u4F53\u8FD4\u56DE\u65F6\u95F4\u2248\u6700\u6162\u4E00\u9879\uFF1B\u88AB\u8DF3\u8FC7\u7684\u9879\u4E0D\u53C2\u4E0E\u7B49\u5F85\uFF09\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5355\u9879\u542F\u52A8\u65F6\u5FC5\u586B\uFF1B\u4E0E configIds \u4E8C\u9009\u4E00\uFF09"},configIds:{type:"array",items:{type:"string"},description:"\u6279\u91CF\u542F\u52A8\uFF1A\u542F\u52A8\u9879 ID \u6570\u7EC4\uFF081-20 \u4E2A\uFF0C\u81EA\u52A8\u53BB\u91CD\uFF1B\u4E0E configId \u4E8C\u9009\u4E00\uFF0C\u4F20\u4E86\u4F18\u5148\u8D70\u6279\u91CF\uFF09\u3002\u6279\u91CF\u6A21\u5F0F\u4EE5\u5404\u9879\u914D\u7F6E\u4E3A\u51C6\u542F\u52A8\uFF0C\u5FFD\u7565 command/cwd/env/readinessPattern \u8986\u76D6\u53C2\u6570\uFF1BworkspacePath/jdkPath \u4E0E wait_timeout_ms \u5BF9\u5168\u90E8\u9879\u751F\u6548"},command:{type:"string",description:"\u542F\u52A8\u547D\u4EE4\u8986\u76D6\uFF08\u53EF\u9009\uFF0C\u4EC5\u5355\u9879\u6A21\u5F0F\uFF09"},cwd:{type:"string",description:"\u5DE5\u4F5C\u76EE\u5F55\u8986\u76D6\uFF08\u53EF\u9009\uFF0C\u4EC5\u5355\u9879\u6A21\u5F0F\uFF09"},env:{type:"object",description:"\u73AF\u5883\u53D8\u91CF\u8986\u76D6\uFF08\u53EF\u9009\uFF0C\u6574\u4F53\u8986\u76D6\u914D\u7F6E env\uFF1B\u4EC5\u5355\u9879\u6A21\u5F0F\uFF09",additionalProperties:{type:"string"}},jdkPath:{type:"string",description:"JDK \u8DEF\u5F84\uFF08type=java \u65F6\u6709\u6548\uFF0C\u53EF\u9009\uFF1B\u5355\u9879=\u8BE5\u9879\u8986\u76D6\uFF0C\u6279\u91CF=\u5168\u90E8\u9879\u751F\u6548\uFF09"},workspacePath:{type:"string",description:"\u9879\u76EE\u5DE5\u4F5C\u533A\u8DEF\u5F84\uFF08\u53EF\u9009\uFF1B\u5355\u9879=\u8BE5\u9879\u8986\u76D6\uFF0C\u6279\u91CF=\u5168\u90E8\u9879\u751F\u6548\uFF09"},readinessPattern:{type:"string",description:"\u5C31\u7EEA\u65E5\u5FD7\u6B63\u5219\u8986\u76D6\uFF08\u53EF\u9009\uFF0C\u4EC5\u5355\u9879\u6A21\u5F0F\uFF0CJS RegExp \u8BED\u6CD5\uFF09\uFF1A\u8BBE\u7F6E\u540E\u542F\u52A8\u7B49\u5F85\u7684 ready \u4FE1\u53F7\u4E3A\u8F93\u51FA\u884C\u547D\u4E2D\u6B63\u5219\uFF08\u9002\u914D\u4E0D\u76D1\u542C\u7AEF\u53E3\u7684\u8FDB\u7A0B\uFF09\u3002\u7559\u7A7A=\u4EE5\u542F\u52A8\u9879\u914D\u7F6E\u4E3A\u51C6\uFF08\u9ED8\u8BA4\u7AEF\u53E3\u76D1\u542C\u63A2\u6D4B\uFF09"},wait_timeout_ms:{type:"number",description:"\u963B\u585E\u7B49\u5F85\u542F\u52A8\u7ED3\u679C\u7684\u8D85\u65F6\u6BEB\u79D2\u6570\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4 0=\u4E0D\u7B49\u5F85\uFF0Cspawn \u540E\u7ACB\u5373\u8FD4\u56DE\uFF09\u3002>0 \u65F6\u672C\u6B21\u8C03\u7528\u963B\u585E\uFF0C\u76F4\u5230\u4EE5\u4E0B\u4FE1\u53F7\u6700\u5148\u5230\u8FBE\u5E76\u5728 wait \u5B57\u6BB5\u8FD4\u56DE\uFF1Aready=\u8FDB\u7A0B\u6811\u63A2\u6D4B\u5230\u76D1\u542C\u7AEF\u53E3\uFF08\u5E38\u9A7B\u670D\u52A1\u542F\u52A8\u6210\u529F\uFF0C\u9644 ports\uFF09\uFF0C\u6216\u8F93\u51FA\u884C\u547D\u4E2D\u5C31\u7EEA\u6B63\u5219\uFF08readinessPattern\uFF0C\u89C1\u4E0A\uFF09\uFF1Bexited=\u8FDB\u7A0B\u9000\u51FA\uFF08\u4E00\u6B21\u6027\u547D\u4EE4\u5B8C\u6210\u6216\u542F\u52A8\u5FEB\u901F\u5931\u8D25\uFF0CexitCode=0 \u4E3A\u6210\u529F\uFF0C\u975E 0 \u68C0\u67E5 logTail \u5B9A\u4F4D\u539F\u56E0\uFF09\uFF1Bstopped=\u7B49\u5F85\u671F\u95F4\u88AB\u505C\u6B62\uFF1Btimeout=\u8D85\u65F6\uFF0C\u8FDB\u7A0B\u4ECD\u5728\u8FD0\u884C\uFF08\u4E0D\u7B97\u9519\u8BEF\uFF0C\u6309 logTail \u81EA\u884C\u5224\u65AD\u6216\u7A0D\u540E launch_config_logs \u8F6E\u8BE2\uFF09\u3002\u4E0A\u9650 300000\uFF085 \u5206\u949F\uFF09\uFF0C\u6162\u542F\u52A8\u670D\u52A1\uFF08\u5982 Spring Boot\uFF09\u5EFA\u8BAE 60000-120000\u3002\u6279\u91CF\u6A21\u5F0F\u5BF9\u5168\u90E8\u6210\u529F\u9879\u5E76\u884C\u7B49\u5F85\uFF08\u6BCF\u9879\u72EC\u7ACB\u8BA1\u65F6\uFF09\u3002"}},required:[]}},k={name:"launch_config_restart",description:"\u91CD\u542F\u542F\u52A8\u9879\uFF08bridge \u5185\u539F\u5B50\u6267\u884C\u300C\u505C\u6B62\u65E7\u8FDB\u7A0B + \u91CD\u65B0\u62C9\u8D77\u300D\uFF0C\u4EE3\u7406\u5230\u8C03\u7528\u8005\u6240\u5728 runtime-bridge\uFF09\u3002\u76F8\u6BD4\u5148 launch_config_stop \u518D launch_config_start\uFF0C\u4E0D\u5B58\u5728 stop \u8BF7\u6C42\u4E22\u5931\u5BFC\u81F4 start \u649E\u4E0A\u4ECD\u5728\u8FD0\u884C\u65E7\u8FDB\u7A0B\u7684\u7ADE\u6001\u3002\u672A\u8FD0\u884C\u65F6\u7B49\u4EF7\u4E8E\u76F4\u63A5 start\u3002\u8986\u76D6\u53C2\u6570\uFF08command/cwd/env \u7B49\uFF09\u4E0E\u542F\u52A8\u7B49\u5F85\u8BED\u4E49\u540C launch_config_start\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5FC5\u586B\uFF09"},command:{type:"string",description:"\u542F\u52A8\u547D\u4EE4\u8986\u76D6\uFF08\u53EF\u9009\uFF09"},cwd:{type:"string",description:"\u5DE5\u4F5C\u76EE\u5F55\u8986\u76D6\uFF08\u53EF\u9009\uFF09"},env:{type:"object",description:"\u73AF\u5883\u53D8\u91CF\u8986\u76D6\uFF08\u53EF\u9009\uFF0C\u6574\u4F53\u8986\u76D6\u914D\u7F6E env\uFF09",additionalProperties:{type:"string"}},jdkPath:{type:"string",description:"JDK \u8DEF\u5F84\uFF08type=java \u65F6\u6709\u6548\uFF0C\u53EF\u9009\uFF09"},workspacePath:{type:"string",description:"\u9879\u76EE\u5DE5\u4F5C\u533A\u8DEF\u5F84\uFF08\u53EF\u9009\uFF09"},readinessPattern:{type:"string",description:"\u5C31\u7EEA\u65E5\u5FD7\u6B63\u5219\u8986\u76D6\uFF08\u53EF\u9009\uFF0CJS RegExp \u8BED\u6CD5\uFF09\uFF1A\u8BBE\u7F6E\u540E\u65B0\u8FDB\u7A0B\u542F\u52A8\u7B49\u5F85\u7684 ready \u4FE1\u53F7\u4E3A\u8F93\u51FA\u884C\u547D\u4E2D\u6B63\u5219\u3002\u7559\u7A7A=\u4EE5\u542F\u52A8\u9879\u914D\u7F6E\u4E3A\u51C6\uFF08\u9ED8\u8BA4\u7AEF\u53E3\u76D1\u542C\u63A2\u6D4B\uFF09"},wait_timeout_ms:{type:"number",description:"\u963B\u585E\u7B49\u5F85\u65B0\u8FDB\u7A0B\u542F\u52A8\u7ED3\u679C\u7684\u8D85\u65F6\u6BEB\u79D2\u6570\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4 0=\u4E0D\u7B49\u5F85\uFF09\u3002\u8BED\u4E49\u540C launch_config_start\uFF1Aready=\u7AEF\u53E3\u5C31\u7EEA\u6216\u65E5\u5FD7\u547D\u4E2D\u5C31\u7EEA\u6B63\u5219 / exited=\u8FDB\u7A0B\u9000\u51FA / timeout=\u8D85\u65F6\uFF08\u8FDB\u7A0B\u4ECD\u5728\u8FD0\u884C\uFF0C\u975E\u9519\u8BEF\uFF09\u3002"}},required:["configId"]}},U={name:"launch_config_stop",description:"\u505C\u6B62\u542F\u52A8\u9879\u8FDB\u7A0B\uFF08\u542B\u8FDB\u7A0B\u6811\uFF0C\u4EE3\u7406\u5230\u8C03\u7528\u8005\u6240\u5728 runtime-bridge\uFF09\u3002\u76EE\u6807\u542F\u52A8\u9879\u5FC5\u987B\u5C5E\u4E8E\u5F53\u524D\u9879\u76EE\uFF08\u670D\u52A1\u7AEF\u6821\u9A8C\uFF09\u3002\u82E5\u8FDB\u7A0B\u5DF2\u9000\u51FA\uFF0C\u8FD4\u56DE\u5DF2\u505C\u6B62/\u65E0\u8FD0\u884C\u8FDB\u7A0B\u7684\u72B6\u6001\uFF0C\u4E0D\u62A5\u9519\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5FC5\u586B\uFF09"}},required:["configId"]}},G={name:"launch_config_logs",description:"\u589E\u91CF\u62C9\u53D6\u542F\u52A8\u9879\u8FD0\u884C\u65E5\u5FD7\uFF08\u6700\u8FD1 200 \u6761\u73AF\u5F62\u7F13\u51B2\uFF0C\u4EE3\u7406\u5230\u8C03\u7528\u8005\u6240\u5728 runtime-bridge\uFF09\u3002\u9996\u6B21\u8C03\u7528\u4E0D\u4F20 since \u83B7\u53D6\u5168\u90E8\u7F13\u51B2\u65E5\u5FD7\uFF1B\u540E\u7EED\u6BCF\u6B21\u628A\u8FD4\u56DE\u7684 nextSince \u4F5C\u4E3A since \u7EED\u62C9\u589E\u91CF\u3002\u8FD4\u56DE\u5B57\u6BB5\uFF1Alines\uFF08\u65E5\u5FD7\u884C\uFF09\u3001nextSince\uFF08\u4E0B\u6B21\u6E38\u6807\uFF09\u3001running\uFF08\u8FDB\u7A0B\u662F\u5426\u8FD0\u884C\u4E2D\uFF09\u3002\u76EE\u6807\u542F\u52A8\u9879\u5FC5\u987B\u5C5E\u4E8E\u5F53\u524D\u9879\u76EE\uFF08\u670D\u52A1\u7AEF\u6821\u9A8C\uFF09\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5FC5\u586B\uFF09"},since:{type:"number",description:"\u65E5\u5FD7\u6E38\u6807\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4 0 = \u4ECE\u5934\u62C9\u53D6\uFF09"}},required:["configId"]}},w={name:"launch_config_status",description:"\u67E5\u8BE2\u8C03\u7528\u8005\u6240\u5728 bridge \u673A\u5668\u4E0A\u5F53\u524D\u9879\u76EE\u7684\u5168\u90E8\u542F\u52A8\u9879\u8FD0\u884C\u72B6\u6001\u3002\u8FD4\u56DE runs \u6570\u7EC4\uFF1A\u6BCF\u9879\u542B configId\u3001status\uFF08running/exited/stopped\uFF09\u3001pid\u3001startTime\u3001command \u7B49\u3002\u4EC5\u8FD4\u56DE\u5F53\u524D\u9879\u76EE\u914D\u7F6E\u7684\u542F\u52A8\u9879\uFF08\u670D\u52A1\u7AEF\u6309\u9879\u76EE\u8FC7\u6EE4\uFF09\u3002",inputSchema:{type:"object",properties:{},required:[]}},de=new Set(["launch_config_list","launch_config_create","launch_config_update","launch_config_delete","launch_config_start","launch_config_restart","launch_config_stop","launch_config_logs","launch_config_status"]),ae=new Set(["hire_colleague"]),v={name:"create_meeting",description:"\u521B\u5EFA\u65B0\u4F1A\u8BAE\u5E76\u9080\u8BF7\u6307\u5B9A\u89D2\u8272\uFF08\u542B Agent \u5B9E\u4F8B\uFF09\u3002\u6210\u5458\u5168\u90E8\u5230\u4F4D\u540E\u4F1A\u8BAE\u5F00\u59CB\uFF0C\u968F\u540E\u4F7F\u7528 meeting_speak \u53D1\u8A00 / poll_message \u7B49\u5F85\u5176\u5B83\u7528\u6237\u53D1\u8A00 / end_meeting \u7ED3\u675F\u4F1A\u8BAE\u3002\u963B\u585E\u578B\u5DE5\u5177\uFF1A\u5168\u5458\u5230\u4F4D\u6216\u7B49\u5F85\u8D85\u65F6\u540E\u624D\u8FD4\u56DE\u3002\u6301\u6709\u8FDB\u884C\u4E2D\u6D41\u7A0B\u4EFB\u52A1\u65F6\u540C\u6837\u53EF\u4EE5\u521B\u5EFA\u4F1A\u8BAE\uFF08\u4F8B\u5982\u4EFB\u52A1\u672C\u8EAB\u8981\u6C42\u5F00\u4F1A\u8BA8\u8BBA/\u534F\u8C03\u7684\u573A\u666F\uFF09\uFF0C\u4E0D\u4F1A\u88AB\u4EFB\u52A1\u62E6\u622A\uFF1B\u8FDB\u5165\u4F1A\u8BAE\u540E\u4EFB\u52A1\u63D0\u9192\u6682\u505C\uFF0C\u4F1A\u8BAE\u7ED3\u675F\u540E\u81EA\u52A8\u6062\u590D\u3002",inputSchema:{type:"object",properties:{topic:{type:"string",description:"\u4F1A\u8BAE\u4E3B\u9898\uFF08\u5FC5\u586B\uFF09"},description:{type:"string",description:"\u4F1A\u8BAE\u63CF\u8FF0\uFF08\u53EF\u9009\uFF09"},members:{type:"array",description:"\u53D7\u9080\u6210\u5458\uFF1A[{roleId, agentId?}, ...]\uFF0CagentId \u672A\u6307\u5B9A\u65F6\u670D\u52A1\u7AEF\u6309\u89D2\u8272\u81EA\u52A8\u9009\u53D6\u5B9E\u4F8B",items:{type:"object",properties:{roleId:{type:"string",description:"\u89D2\u8272 id\uFF08\u5FC5\u586B\uFF09"},agentId:{type:"string",description:"Agent \u5B9E\u4F8B id\uFF08\u53EF\u9009\uFF09"}},required:["roleId"]}},waitTimeoutMs:{type:"number",description:"\u7B49\u5F85\u5168\u5458\u5230\u4F4D\u7684\u8D85\u65F6\u65F6\u957F\uFF08\u6BEB\u79D2\uFF0C\u53EF\u9009\uFF0C\u9ED8\u8BA4/\u4E0A\u9650 270000\uFF09\u3002\u8D85\u65F6\u8FD4\u56DE WAITING \u72B6\u6001\u800C\u975E\u9519\u8BEF\uFF0C\u53EF\u7EE7\u7EED poll_message \u7B49\u5F85\u5168\u5458\u5230\u4F4D"}},required:["topic","members"]}},H={name:"leave_meeting",description:"\u9000\u51FA\u5F53\u524D\u52A0\u5165\u7684\u4F1A\u8BAE\u3002\u5DF2\u52A0\u5165\u6210\u5458\u6B63\u5F0F\u9000\u51FA\uFF1B\u672A\u52A0\u5165\u6210\u5458\u8C03\u7528\u89C6\u4E3A\u5A49\u62D2\u9080\u8BF7\u3002",inputSchema:{type:"object",properties:{meetingId:{type:"string",description:"\u4F1A\u8BAE ID\uFF08\u5FC5\u586B\uFF09"}},required:["meetingId"]}},Y={name:"end_meeting",description:"\u7ED3\u675F\u6307\u5B9A\u4F1A\u8BAE\uFF08\u4EC5\u4F1A\u8BAE\u521B\u5EFA\u8005\u53EF\u8C03\u7528\uFF09\u3002\u7ED3\u675F\u540E\u6210\u5458\u53EF\u4F7F\u7528 get_meeting_info \u67E5\u770B\u5386\u53F2\u53D1\u8A00\u3002",inputSchema:{type:"object",properties:{meetingId:{type:"string",description:"\u4F1A\u8BAE ID\uFF08\u5FC5\u586B\uFF09"}},required:["meetingId"]}},F={name:"meeting_speak",description:"\u5411\u6D3B\u8DC3\u4F1A\u8BAE\u53D1\u8A00\uFF08\u4EC5\u5DF2\u52A0\u5165\u4E14\u4F1A\u8BAE\u5DF2 STARTED \u7684\u6210\u5458\u53EF\u7528\uFF09\u3002\u53D1\u8A00\u5B9E\u65F6\u5E7F\u64AD\u7ED9\u6240\u6709\u53C2\u4F1A\u6210\u5458\u3002",inputSchema:{type:"object",properties:{meetingId:{type:"string",description:"\u4F1A\u8BAE ID\uFF08\u5FC5\u586B\uFF09"},content:{type:"string",description:"\u53D1\u8A00\u5185\u5BB9\uFF08\u5FC5\u586B\uFF09"}},required:["meetingId","content"]}},K={name:"get_meeting_info",description:"\u83B7\u53D6\u4F1A\u8BAE\u4FE1\u606F JSON\uFF1A\u4E3B\u9898/\u63CF\u8FF0/\u72B6\u6001/\u6210\u5458\u5217\u8868\uFF08\u521B\u5EFA\u4EBA\u6807\u6CE8 isCreator\uFF09/\u6700\u8FD1\u53D1\u8A00\u8BB0\u5F55\u3002\u53EF\u7528\u4E8E\u67E5\u770B\u81EA\u5DF1\u521B\u5EFA\u7684\u4F1A\u8BAE\u8FDB\u5EA6\u6216\u5DF2\u52A0\u5165\u4F1A\u8BAE\u7684\u8BE6\u60C5\u3002",inputSchema:{type:"object",properties:{meetingId:{type:"string",description:"\u4F1A\u8BAE ID\uFF08\u5FC5\u586B\uFF09"}},required:["meetingId"]}},B={name:"my_meetings",description:"\u67E5\u770B\u4E0E\u6211\u76F8\u5173\u7684\u4F1A\u8BAE\u5217\u8868\uFF08\u65E0\u9700 meetingId\uFF09\uFF1Aactive=\u5DF2\u52A0\u5165\u7684\u8FDB\u884C\u4E2D\u4F1A\u8BAE\uFF1Binvited=\u53D7\u9080\u5C1A\u672A\u52A0\u5165\u7684\u4F1A\u8BAE\u3002\u6BCF\u4E2A\u4F1A\u8BAE\u542B meetingId/\u4E3B\u9898/\u72B6\u6001/\u6210\u5458\u5230\u4F4D\u60C5\u51B5\uFF0C\u53EF\u5148\u7528\u672C\u5DE5\u5177\u83B7\u53D6 meetingId \u518D\u8C03\u7528 get_meeting_info\u3002\u52A0\u5165\u4F1A\u8BAE\u4E0D\u9700\u8981\u624B\u52A8\u5DE5\u5177\uFF1A\u53D7\u9080\u540E\u5C06\u5728 poll_message \u65F6\u81EA\u52A8\u52A0\u5165\u3002",inputSchema:{type:"object",properties:{},required:[]}},_e=new Set(["create_meeting","leave_meeting","end_meeting","meeting_speak","get_meeting_info","my_meetings"]),V={name:"pencil_create_document",description:"\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684\u8BBE\u8BA1\u753B\u5E03\u6587\u6863\uFF08\u7A7A\u767D\u5355\u9875\uFF09\u3002\u521B\u5EFA\u540E\u7528 pencil_open_document \u6253\u5F00\u5E76\u5728 dashboard \u9762\u677F\u6E32\u67D3\uFF0C\u518D\u7528 pencil_create_nodes \u6DFB\u52A0\u56FE\u5F62\u3002",inputSchema:{type:"object",properties:{name:{type:"string",description:"\u753B\u5E03\u540D\u79F0\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u300C\u672A\u547D\u540D\u753B\u5E03\u300D\uFF09"}},required:[]}},J={name:"pencil_list_documents",description:"\u5217\u51FA\u5F53\u524D Agent \u7684\u6240\u6709\u8BBE\u8BA1\u753B\u5E03\u6587\u6863\uFF08\u672C\u5730 + \u88AB\u9080\u8BF7\u534F\u4F5C\u7684\u6258\u7BA1\u753B\u5E03\uFF0C\u9644 permission \u4E0E shared \u6807\u8BB0\uFF09\u3002",inputSchema:{type:"object",properties:{},required:[]}},W={name:"pencil_open_document",description:"\u6253\u5F00\u4E00\u4E2A\u8BBE\u8BA1\u753B\u5E03\u6587\u6863\uFF08dashboard \u5C06\u5728\u753B\u5E03\u9762\u677F\u6E32\u67D3\u5B83\uFF0Cagent \u884C\u4E0A\u65B9\u51FA\u73B0\u753B\u5E03\u6807\u8BB0\uFF09\u3002docId \u6765\u81EA pencil_create_document \u6216 pencil_list_documents\uFF1B\u88AB\u9080\u8BF7\u534F\u4F5C\u7684\u753B\u5E03\u4E5F\u5728\u5217\u8868\u4E2D\uFF08shared=true\uFF0C\u9644\u672C\u4EBA permission\uFF09\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"}},required:["docId"]}},z={name:"pencil_close_document",description:"\u5173\u95ED\u8BBE\u8BA1\u753B\u5E03\u9762\u677F\uFF08\u4EC5\u6536\u8D77 dashboard \u9762\u677F\uFF0C\u4E0D\u5F71\u54CD\u5FBD\u6807\u8BA1\u6570\uFF0C\u6587\u6863\u4FDD\u7559\uFF0C\u53EF\u968F\u65F6 pencil_open_document \u91CD\u65B0\u6253\u5F00\uFF09\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"}},required:["docId"]}},X={name:"pencil_get_tree",description:"\u8BFB\u53D6\u753B\u5E03\u7684\u8282\u70B9\u6811\u6458\u8981\uFF08id/\u7C7B\u578B/\u540D\u79F0/\u51E0\u4F55\u4F4D\u7F6E\uFF0C\u542B\u6587\u672C\u5185\u5BB9\u622A\u65AD\uFF0C\u8FD4\u56DE truncated \u6807\u8BB0\u662F\u5426\u88AB\u622A\u65AD\uFF09\u3002\u7528\u4E8E\u5728\u521B\u5EFA/\u4FEE\u6539\u524D\u4E86\u89E3\u753B\u5E03\u73B0\u72B6\uFF1B\u8FD4\u56DE\u7684 version \u53EF\u4F5C\u4E3A expectedVersion \u4E50\u89C2\u9501\u4F20\u5165\u5199\u5DE5\u5177\u3002\u6811\u4E2D\u5B50\u8282\u70B9\u7684 x/y \u4E3A\u76F8\u5BF9\u7236\u8282\u70B9\u7684\u5C40\u90E8\u5750\u6807\uFF08\u4E0E pencil_create_nodes \u4E00\u81F4\uFF09\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"}},required:["docId"]}},$={name:"pencil_get_changes",description:"\u8FFD\u8D76\u534F\u4F5C\u753B\u5E03\u81EA sinceVersion \u4EE5\u6765\u7684\u53D8\u66F4\uFF08\u9010\u7248\u672C\u6458\u8981\uFF1A\u8C01\u6539\u7684\u3001\u65B0\u589E/\u66F4\u65B0/\u5220\u9664\u4E86\u54EA\u4E9B\u8282\u70B9\u53CA\u65B0\u503C\uFF09\u3002\u6536\u5230\u300C\u8BBE\u8BA1\u753B\u5E03\u53D8\u66F4\u300D\u7CFB\u7EDF\u901A\u77E5\u540E\u8C03\u7528\uFF1Btruncated=true \u8868\u793A\u53D8\u66F4\u65E5\u5FD7\u5DF2\u88AB\u4FEE\u526A\uFF0C\u8BF7\u6539\u7528 pencil_open_document \u5168\u91CF\u91CD\u8BFB\u3002\u8BF7\u628A\u8FD4\u56DE\u7684 toVersion \u8BB0\u4E3A\u8BE5\u753B\u5E03\u4F60\u5DF2\u770B\u5230\u7684\u6700\u65B0\u7248\u672C\uFF1A\u540E\u7EED\u5199\u5DE5\u5177\u4F20\u5B83\u4F5C expectedVersion \u4E50\u89C2\u9501\uFF0C\u4E0B\u6B21\u8FFD\u8D76\u4F20\u5B83\u4F5C sinceVersion\u3002\u4F60\u4E0A\u6B21\u770B\u5230\u7684\u7248\u672C\u6765\u81EA\u9080\u8BF7\u901A\u77E5\u7684 version \u6216\u672C\u5DE5\u5177\u4E0A\u6B21\u8FD4\u56DE\u7684 toVersion\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},sinceVersion:{type:"number",description:"\u4F60\u5DF2\u770B\u5230\u7684\u6700\u65B0\u753B\u5E03\u7248\u672C\uFF08\u7F3A\u7701 0 = \u4ECE\u5934\u8FFD\u8D76\uFF1B\u4F20\u5165\u9080\u8BF7\u901A\u77E5/\u4E0A\u4E00\u6B21\u8FFD\u8D76\u8FD4\u56DE\u7684\u7248\u672C\u53EF\u53EA\u62FF\u589E\u91CF\uFF09"}},required:["docId"]}},Q={name:"pencil_create_nodes",description:"\u5728\u8BBE\u8BA1\u753B\u5E03\u4E2D\u521B\u5EFA\u8282\u70B9\uFF08\u4E00\u6B21\u53EF\u521B\u5EFA\u591A\u4E2A\u3001\u4E0A\u9650 500 \u4E2A\uFF0C\u652F\u6301 frame/rect/ellipse/text/line\uFF09\u3002\u989C\u8272\u7528\u5341\u516D\u8FDB\u5236\uFF08#RRGGBB / #RRGGBBAA / none\uFF09\u3002\u5750\u6807\u7CFB\uFF1Ax/y \u4E3A\u76F8\u5BF9 parentId \u7684\u5C40\u90E8\u5750\u6807\u2014\u2014parentId \u7F3A\u7701\uFF08\u6302\u5230\u9875\u9762\uFF09\u65F6\u662F\u9875\u9762\u5750\u6807\uFF08\u5DE6\u4E0A\u89D2\u539F\u70B9\uFF09\uFF0C\u5D4C\u5957\u5230 frame \u5185\u65F6\u4ECE\u8BE5 frame \u7684\u5DE6\u4E0A\u89D2\u8D77\u7B97\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},parentId:{type:"string",description:"\u7236\u8282\u70B9 id\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u753B\u5E03\u7B2C\u4E00\u4E2A\u9875\u9762\uFF1B\u53EF\u4F20 frame \u8282\u70B9 id \u5B9E\u73B0\u5D4C\u5957\uFF0C\u6B64\u65F6 x/y \u76F8\u5BF9\u8BE5 frame\uFF09"},nodes:{type:"array",description:"\u8282\u70B9\u89C4\u683C\u6570\u7EC4",items:{type:"object",properties:{type:{type:"string",description:"frame | rect | ellipse | text | line"},name:{type:"string",description:"\u8282\u70B9\u540D\u79F0\uFF08\u53EF\u9009\uFF09"},x:{type:"number",description:"X \u5750\u6807\uFF08\u76F8\u5BF9 parentId \u5C40\u90E8\u5750\u6807\uFF09"},y:{type:"number",description:"Y \u5750\u6807\uFF08\u76F8\u5BF9 parentId \u5C40\u90E8\u5750\u6807\uFF09"},width:{type:"number",description:"\u5BBD\u5EA6\uFF08line \u9ED8\u8BA4 100\uFF09"},height:{type:"number",description:"\u9AD8\u5EA6\uFF08line \u9ED8\u8BA4 0\uFF09"},fill:{type:"string",description:"\u586B\u5145\u8272\u5341\u516D\u8FDB\u5236\uFF08\u5982 #4F8EF7\uFF0Cnone \u8868\u793A\u65E0\u586B\u5145\uFF09"},stroke:{type:"string",description:"\u63CF\u8FB9\u8272\u5341\u516D\u8FDB\u5236\uFF08\u53EF\u9009\uFF09"},strokeWeight:{type:"number",description:"\u63CF\u8FB9\u7C97\u7EC6\uFF08\u9ED8\u8BA4 1\uFF09"},cornerRadius:{type:"number",description:"\u5706\u89D2\u534A\u5F84"},opacity:{type:"number",description:"\u4E0D\u900F\u660E\u5EA6 0-1"},rotation:{type:"number",description:"\u65CB\u8F6C\u89D2\u5EA6"},visible:{type:"boolean",description:"\u662F\u5426\u53EF\u89C1\uFF08\u9ED8\u8BA4 true\uFF09"},text:{type:"string",description:"text \u8282\u70B9\u7684\u6587\u672C\u5185\u5BB9"},fontSize:{type:"number",description:"\u5B57\u53F7\uFF08\u9ED8\u8BA4 14\uFF09"},fontWeight:{type:"number",description:"\u5B57\u91CD\uFF08\u9ED8\u8BA4 400\uFF09"},fontFamily:{type:"string",description:"\u5B57\u4F53\uFF08\u9ED8\u8BA4 Inter\uFF09"},fontColor:{type:"string",description:"\u6587\u672C\u989C\u8272\uFF08\u9ED8\u8BA4\u9ED1\uFF09"}},required:["type"]}},expectedVersion:{type:"number",description:"\u53EF\u9009\u4E50\u89C2\u9501\uFF1A\u4F20\u5165\u6700\u8FD1\u4E00\u6B21 pencil_get_tree / \u5199\u5DE5\u5177\u8FD4\u56DE\u7684 version\u3002\u753B\u5E03\u5728\u6B64\u671F\u95F4\u88AB\u4EBA\u6216\u5176\u4ED6 Agent \u4FEE\u6539\u65F6\u8FD4\u56DE\u7248\u672C\u51B2\u7A81\uFF08\u800C\u975E\u9759\u9ED8\u8986\u76D6\u5BF9\u65B9\u6539\u52A8\uFF09\uFF1B\u591A\u4EBA/\u591A Agent \u534F\u4F5C\u7F16\u8F91\u65F6\u5EFA\u8BAE\u4F20\u5165"}},required:["docId","nodes"]}},Z={name:"pencil_update_nodes",description:"\u6279\u91CF\u66F4\u65B0\u753B\u5E03\u8282\u70B9\u5C5E\u6027\uFF08\u51E0\u4F55/\u586B\u5145/\u6587\u672C/\u900F\u660E\u5EA6/\u53EF\u89C1\u6027/\u540D\u79F0\u7B49\uFF09\u3002id \u53EF\u901A\u8FC7 pencil_get_tree \u83B7\u5F97\u3002\u4EC5\u652F\u6301\u767D\u540D\u5355\u5B57\u6BB5\uFF0C\u672A\u77E5\u5B57\u6BB5\u4F1A\u88AB\u62D2\u7EDD\uFF1Bid/parentId/childIds \u4E0D\u53EF\u901A\u8FC7\u672C\u5DE5\u5177\u4FEE\u6539\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},updates:{type:"array",description:"\u66F4\u65B0\u5217\u8868",items:{type:"object",properties:{id:{type:"string",description:"\u8282\u70B9 id"},props:{type:"object",description:"\u8981\u66F4\u65B0\u7684\u5C5E\u6027\uFF0C\u4EC5\u652F\u6301\u8FD9\u4E9B\u5B57\u6BB5\uFF08\u5176\u4ED6\u5B57\u6BB5\u4F1A\u88AB\u62D2\u7EDD\uFF09\uFF1Ax / y / width / height / rotation / opacity / visible / name / fill / stroke / strokeWeight / cornerRadius / text / fontSize / fontWeight / fontFamily / fontColor"}},required:["id","props"]}},expectedVersion:{type:"number",description:"\u53EF\u9009\u4E50\u89C2\u9501\uFF1A\u4F20\u5165\u6700\u8FD1\u4E00\u6B21 pencil_get_tree / \u5199\u5DE5\u5177\u8FD4\u56DE\u7684 version\u3002\u753B\u5E03\u5728\u6B64\u671F\u95F4\u88AB\u4EBA\u6216\u5176\u4ED6 Agent \u4FEE\u6539\u65F6\u8FD4\u56DE\u7248\u672C\u51B2\u7A81\uFF08\u800C\u975E\u9759\u9ED8\u8986\u76D6\u5BF9\u65B9\u6539\u52A8\uFF09\uFF1B\u591A\u4EBA/\u591A Agent \u534F\u4F5C\u7F16\u8F91\u65F6\u5EFA\u8BAE\u4F20\u5165"}},required:["docId","updates"]}},ee={name:"pencil_delete_nodes",description:"\u6279\u91CF\u5220\u9664\u753B\u5E03\u8282\u70B9\uFF08\u542B\u5176\u5168\u90E8\u5B50\u8282\u70B9\uFF09\u3002root/\u9875\u9762\u8282\u70B9\u4E0D\u53EF\u5220\u9664\u3002\u5220\u9664\u6574\u4E2A\u753B\u5E03\u7528 pencil_delete_document\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},ids:{type:"array",items:{type:"string"},description:"\u8981\u5220\u9664\u7684\u8282\u70B9 id \u5217\u8868"},expectedVersion:{type:"number",description:"\u53EF\u9009\u4E50\u89C2\u9501\uFF1A\u4F20\u5165\u6700\u8FD1\u4E00\u6B21 pencil_get_tree / \u5199\u5DE5\u5177\u8FD4\u56DE\u7684 version\u3002\u753B\u5E03\u5728\u6B64\u671F\u95F4\u88AB\u4EBA\u6216\u5176\u4ED6 Agent \u4FEE\u6539\u65F6\u8FD4\u56DE\u7248\u672C\u51B2\u7A81\uFF08\u800C\u975E\u9759\u9ED8\u8986\u76D6\u5BF9\u65B9\u6539\u52A8\uFF09\uFF1B\u591A\u4EBA/\u591A Agent \u534F\u4F5C\u7F16\u8F91\u65F6\u5EFA\u8BAE\u4F20\u5165"}},required:["docId","ids"]}},te={name:"pencil_delete_document",description:"\u5220\u9664\u6574\u4E2A\u8BBE\u8BA1\u753B\u5E03\u6587\u6863\uFF08\u4EC5\u753B\u5E03\u62E5\u6709\u8005\u53EF\u8C03\u7528\uFF0C\u4E0D\u53EF\u6062\u590D\uFF1A\u6587\u6863\u3001\u5168\u90E8\u8282\u70B9\u4E0E\u534F\u4F5C\u8005\u4E00\u5E76\u6E05\u9664\uFF09\u3002\u7528\u4E8E\u6E05\u7406\u4E0D\u518D\u9700\u8981\u7684\u753B\u5E03\uFF1B\u53EA\u5220\u9664\u753B\u5E03\u91CC\u7684\u90E8\u5206\u8282\u70B9\u7528 pencil_delete_nodes\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"}},required:["docId"]}},ie={name:"pencil_rename_document",description:"\u91CD\u547D\u540D\u8BBE\u8BA1\u753B\u5E03\uFF08ACL write \u53EF\u8C03\u7528\uFF1A\u62E5\u6709\u8005\u6216 permission=write \u6210\u5458\uFF09\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},name:{type:"string",description:"\u65B0\u7684\u753B\u5E03\u540D\u79F0"},expectedVersion:{type:"number",description:"\u53EF\u9009\u4E50\u89C2\u9501\uFF1A\u4F20\u5165\u6700\u8FD1\u4E00\u6B21 pencil_get_tree / \u5199\u5DE5\u5177\u8FD4\u56DE\u7684 version\u3002\u753B\u5E03\u5728\u6B64\u671F\u95F4\u88AB\u4EBA\u6216\u5176\u4ED6 Agent \u4FEE\u6539\u65F6\u8FD4\u56DE\u7248\u672C\u51B2\u7A81\uFF08\u800C\u975E\u9759\u9ED8\u8986\u76D6\u5BF9\u65B9\u6539\u52A8\uFF09"}},required:["docId","name"]}},ne={name:"pencil_share_document",description:"\u5C06\u8BBE\u8BA1\u753B\u5E03\u5206\u4EAB\u7ED9\u5176\u5B83 Agent \u534F\u4F5C\uFF08\u6BCF\u4F4D\u88AB\u9080\u8BF7\u4EBA\u6307\u5B9A read=\u53EA\u8BFB \u6216 write=\u53EF\u5199\uFF09\u3002\u88AB\u9080\u8BF7\u4EBA\u5FC5\u987B\u5DF2\u5F00\u542F\u300C\u8BBE\u8BA1\u753B\u5E03 (Pencil)\u300D\u80FD\u529B\uFF0C\u5426\u5219\u5206\u4EAB\u4F1A\u88AB\u6574\u4F53\u62D2\u7EDD\u3002\u5206\u4EAB\u540E\u53CC\u65B9\u7EE7\u7EED\u7528 pencil_get_tree / pencil_update_nodes \u7B49\u5DE5\u5177\u534F\u4F5C\uFF1B\u88AB\u9080\u8BF7\u4EBA\u4F1A\u6536\u5230\u9080\u8BF7\u901A\u77E5\u3002\u64A4\u9500\u5206\u4EAB\u914D\u5BF9\u4F7F\u7528 pencil_revoke_share\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u8981\u5206\u4EAB\u7684\u753B\u5E03\u6587\u6863 id\uFF08\u987B\u4E3A\u672C Agent \u521B\u5EFA\u7684\u753B\u5E03\uFF09"},members:{type:"array",description:"\u88AB\u9080\u8BF7\u4EBA\u5217\u8868",items:{type:"object",properties:{agentId:{type:"string",description:"\u88AB\u9080\u8BF7 Agent \u7684\u5B9E\u4F8B id"},permission:{type:"string",enum:["read","write"],description:"\u534F\u4F5C\u6743\u9650\uFF1Aread=\u53EA\u8BFB\u67E5\u770B\uFF0Cwrite=\u53EF\u7F16\u8F91\uFF08\u7F3A\u7701 read\uFF09"}},required:["agentId"]}}},required:["docId","members"]}},re={name:"pencil_revoke_share",description:"\u64A4\u9500\u753B\u5E03\u5206\u4EAB\uFF08\u4EC5\u753B\u5E03\u62E5\u6709\u8005\u53EF\u8C03\u7528\uFF0C\u4E0E pencil_share_document \u914D\u5BF9\u4F7F\u7528\uFF09\u3002agentIds \u7701\u7565\u65F6\u6574\u4F53\u64A4\u9500\uFF0C\u753B\u5E03\u56DE\u5230\u4EC5\u672C Agent \u79C1\u6709\uFF1B\u63D0\u4F9B agentIds \u65F6\u4EC5\u79FB\u9664\u6307\u5B9A\u534F\u4F5C\u8005\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},agentIds:{type:"array",items:{type:"string"},description:"\u8981\u79FB\u9664\u7684\u534F\u4F5C\u8005 agentId \u5217\u8868\uFF08\u7701\u7565 = \u6574\u4F53\u64A4\u9500\u5206\u4EAB\uFF09"}},required:["docId"]}},pe={name:"pencil_export_image",description:"\u5BFC\u51FA\u8BBE\u8BA1\u753B\u5E03\u4E3A PNG \u56FE\u7247\u5230\u6587\u4EF6\u5E76\u8FD4\u56DE\u6587\u4EF6\u8DEF\u5F84\u7B49\u5143\u4FE1\u606F\uFF08\u4E0D\u8FD4\u56DE\u56FE\u7247\u5185\u5BB9\uFF0C\u907F\u514D\u5927\u4F53\u79EF base64 \u5360\u7528\u4E0A\u4E0B\u6587\uFF09\u3002\u9700\u8981\u67E5\u770B\u753B\u5E03\u6548\u679C\u65F6\uFF0C\u7528\u6587\u4EF6\u8BFB\u53D6\u5DE5\u5177\u8BFB\u53D6\u8FD4\u56DE\u8DEF\u5F84\u7684 PNG \u5373\u53EF\u3002savePath \u901A\u5E38\u7701\u7565\uFF1A\u81EA\u52A8\u5BFC\u51FA\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\uFF08\u4E34\u65F6\u6587\u4EF6\u53EF\u80FD\u88AB\u7CFB\u7EDF\u6E05\u7406\uFF0C\u4E0D\u8981\u957F\u671F\u5F15\u7528\uFF09\u3002\u4EC5\u5F53\u9700\u8981\u628A\u56FE\u7247\u4F5C\u4E3A\u4EA4\u4ED8\u7269\u653E\u8FDB\u5DE5\u4F5C\u533A\u65F6\u624D\u4F20 savePath\u3002\u6E32\u67D3\u56FE\u7531 dashboard \u753B\u5E03\u9762\u677F\u81EA\u52A8\u751F\u6210\u5E76\u7F13\u5B58\uFF1B\u753B\u5E03\u521A\u88AB\u5DE5\u5177\u4FEE\u6539\u540E\u82E5\u7F13\u5B58\u843D\u540E\uFF0C\u4F1A\u7B49\u5F85\u9762\u677F\u8865\u6E32\uFF08\u7EA6\u6570\u79D2\uFF09\u3002\u753B\u5E03\u4ECE\u672A\u6E32\u67D3\u8FC7\uFF08dashboard \u9762\u677F\u672A\u6253\u5F00\u8FC7\uFF09\u4F1A\u8FD4\u56DE\u5931\u8D25\u5E76\u63D0\u793A\u5148\u6253\u5F00\u9762\u677F\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id\uFF08\u6765\u81EA pencil_create_document / pencil_list_documents\uFF09"},savePath:{type:"string",description:"\u53EF\u9009\uFF1APNG \u4FDD\u5B58\u5230\u5DE5\u4F5C\u533A\u7684\u8DEF\u5F84\uFF08\u76F8\u5BF9\u5DE5\u4F5C\u533A\u6839\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09\uFF0C\u5982 design/hero.png\u3002\u7701\u7565\u65F6\u5BFC\u51FA\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\u5E76\u8FD4\u56DE\u4E34\u65F6\u8DEF\u5F84"},waitMs:{type:"number",description:"\u53EF\u9009\uFF1A\u7B49\u5F85\u9762\u677F\u8865\u6E32\u7684\u6700\u957F\u6BEB\u79D2\u6570\uFF08\u9ED8\u8BA4 8000\uFF0C\u4E0A\u9650 20000\uFF09"}},required:["docId"]}},oe={name:"pencil_export_document",description:"\u628A\u8BBE\u8BA1\u753B\u5E03\u5BFC\u51FA\u4E3A\u6587\u4EF6\uFF08\u672C\u5730 headless \u5BFC\u51FA\u7BA1\u7EBF\uFF0C\u65E0\u9700\u6253\u5F00\u753B\u5E03\u9762\u677F\uFF09\u3002\u8FD4\u56DE\u5BFC\u51FA\u6587\u4EF6\u8DEF\u5F84\u7B49\u5143\u4FE1\u606F\uFF08\u4E0D\u8FD4\u56DE\u6587\u4EF6\u5185\u5BB9\uFF09\u3002format \u652F\u6301\u591A\u79CD\u6837\u5F0F\uFF1Asvg=\u77E2\u91CF\u56FE\uFF08\u63A8\u8350\uFF0C\u6587\u5B57\u4E3A\u771F\u6587\u672C\uFF09/ html=\u771F\u5B9E DOM+CSS \u7F51\u9875\uFF08standalone \u5355\u6587\u4EF6\uFF0C\u53EF\u76F4\u63A5\u6D4F\u89C8\u5668\u6253\u5F00\uFF09/ png|jpg|webp=\u4F4D\u56FE\uFF08scale \u63A7\u5236\u6E05\u6670\u5EA6\uFF09/ pptx=PowerPoint \u6F14\u793A\u7A3F / fig=Figma \u6587\u6863 / jsx=React \u7EC4\u4EF6\u4EE3\u7801\uFF08\u9700\u4F20 nodeId\uFF09\u3002\u7F3A\u7701\u5BFC\u51FA\u7B2C\u4E00\u9875\u5168\u90E8\u5185\u5BB9\uFF1B\u4F20 nodeId\uFF08\u6765\u81EA pencil_get_tree\uFF09\u53EF\u53EA\u5BFC\u51FA\u5355\u4E2A\u8282\u70B9\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id\uFF08\u6765\u81EA pencil_create_document / pencil_list_documents\uFF09"},format:{type:"string",enum:["svg","html","png","jpg","webp","pptx","fig","jsx"],description:"\u5BFC\u51FA\u683C\u5F0F\uFF08\u9ED8\u8BA4 svg\uFF09"},nodeId:{type:"string",description:"\u53EF\u9009\uFF1A\u53EA\u5BFC\u51FA\u5355\u4E2A\u8282\u70B9\uFF08jsx \u5FC5\u586B\uFF09\uFF1B\u7701\u7565=\u5BFC\u51FA\u7B2C\u4E00\u9875\u5168\u90E8\u5185\u5BB9"},scale:{type:"number",description:"\u53EF\u9009\uFF1Apng/jpg/webp \u7F29\u653E\u500D\u6570\uFF08\u9ED8\u8BA4 1\uFF09"},quality:{type:"number",description:"\u53EF\u9009\uFF1Ajpg/webp \u8D28\u91CF 0-100\uFF08\u9ED8\u8BA4 90\uFF09"},savePath:{type:"string",description:"\u53EF\u9009\uFF1A\u5BFC\u51FA\u6587\u4EF6\u4FDD\u5B58\u5230\u5DE5\u4F5C\u533A\u7684\u8DEF\u5F84\uFF08\u76F8\u5BF9\u5DE5\u4F5C\u533A\u6839\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09\uFF0C\u5982 design/hero.svg\u3002\u7701\u7565\u65F6\u4FDD\u5B58\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\u5E76\u8FD4\u56DE\u4E34\u65F6\u8DEF\u5F84"}},required:["docId"]}},me=new Set(["pencil_create_document","pencil_list_documents","pencil_open_document","pencil_close_document","pencil_get_tree","pencil_get_changes","pencil_create_nodes","pencil_update_nodes","pencil_delete_nodes","pencil_export_image","pencil_share_document","pencil_revoke_share","pencil_delete_document","pencil_rename_document","pencil_export_document"]),ge=[_,m,g,y,u,l,E,I,O,T,h,b,L,S,A,R,N,e,r,o,t,p,n,i,s,c,d,a,D,x,C,M,P,f,j,q,k,U,G,w,v,H,Y,F,K,B,V,J,W,z,X,$,Q,Z,ee,pe,ne,re,te,ie,oe];export{Se as ABANDON_MEMORY_UPDATE_TOOL,v as CREATE_MEETING_TOOL,le as CREATE_MEMORY_TOOL,b as CREATE_TASK_INSTANCE_COMMENT_TOOL,Ee as DELETE_MEMORY_TOOL,Y as END_MEETING_TOOL,A as FINISH_TASK_ROLLBACK_TOOL,_ as GET_COLLEAGUE_TOOL,D as GET_DEBUG_LOG_CONFIG_TOOL,O as GET_DM_HISTORY_TOOL,T as GET_GROUP_HISTORY_TOOL,m as GET_GROUP_ROOMS_TOOL,K as GET_MEETING_INFO_TOOL,Ie as GET_MEMORY_STATS_TOOL,I as GET_MESSAGE_TOOL,g as GET_PROFILE_TOOL,y as HIRE_COLLEAGUE_TOOL,ae as HIRE_TOOL_NAMES,P as LAUNCH_CONFIG_CREATE_TOOL,j as LAUNCH_CONFIG_DELETE_TOOL,M as LAUNCH_CONFIG_LIST_TOOL,G as LAUNCH_CONFIG_LOGS_TOOL,k as LAUNCH_CONFIG_RESTART_TOOL,q as LAUNCH_CONFIG_START_TOOL,w as LAUNCH_CONFIG_STATUS_TOOL,U as LAUNCH_CONFIG_STOP_TOOL,de as LAUNCH_CONFIG_TOOL_NAMES,f as LAUNCH_CONFIG_UPDATE_TOOL,H as LEAVE_MEETING_TOOL,Le as LIST_MEMORIES_BY_FILE_TOOL,Oe as LIST_MEMORIES_TOOL,ge as MCP_TOOLS,F as MEETING_SPEAK_TOOL,_e as MEETING_TOOL_NAMES,Re as MEMORY_RECURRENCE_COMPLETE_TOOL,Ae as MEMORY_RECURRENCE_TOOL,ce as MEMORY_TOOL_NAMES,B as MY_MEETINGS_TOOL,h as MY_TASK_TOOL,z as PENCIL_CLOSE_DOCUMENT_TOOL,V as PENCIL_CREATE_DOCUMENT_TOOL,Q as PENCIL_CREATE_NODES_TOOL,te as PENCIL_DELETE_DOCUMENT_TOOL,ee as PENCIL_DELETE_NODES_TOOL,oe as PENCIL_EXPORT_DOCUMENT_TOOL,pe as PENCIL_EXPORT_IMAGE_TOOL,$ as PENCIL_GET_CHANGES_TOOL,X as PENCIL_GET_TREE_TOOL,J as PENCIL_LIST_DOCUMENTS_TOOL,W as PENCIL_OPEN_DOCUMENT_TOOL,ie as PENCIL_RENAME_DOCUMENT_TOOL,re as PENCIL_REVOKE_SHARE_TOOL,ne as PENCIL_SHARE_DOCUMENT_TOOL,me as PENCIL_TOOL_NAMES,Z as PENCIL_UPDATE_NODES_TOOL,E as POLL_MESSAGE_TOOL,x as QUERY_DEBUG_LOGS_TOOL,C as QUERY_FILE_CHANGES_HISTORY_TOOL,Te as READ_MEMORY_TOOL,R as REJECT_TASK_TOOL,he as SEARCH_MEMORY_TOOL,u as SEND_GROUP_TOOL,l as SEND_PRIVATE_TOOL,S as START_TASK_ROLLBACK_TOOL,L as SUBMIT_TASK_RESULT_TOOL,N as TERMINATE_TASK_TOOL,be as UPDATE_MEMORY_TOOL};
|
|
41
|
+
\u8FD4\u56DE\u5B57\u6BB5\uFF1Aid\u3001projectId\u3001roleName\u3001instanceName\u3001agentId\u3001operation\uFF08CREATE/UPDATE/DELETE\uFF09\u3001targetPath\u3001fullPath\u3001reason\u3001status\uFF08APPLIED/REVERTED/REVERT_FAILED\uFF09\u3001createdAt\u3001revertedAt\u3001revertedBy\u3002`,inputSchema:{type:"object",properties:{roleId:{type:"string",description:"\u89D2\u8272\u5B9A\u4E49 ID\uFF08\u53EF\u9009\uFF09"},agentId:{type:"string",description:"Agent \u5B9E\u4F8B ID\uFF08\u53EF\u9009\uFF1B\u4E0D\u4F20=\u67E5\u8BE2\u5F53\u524D\u9879\u76EE\u4E0B\u6240\u6709 Agent\uFF1B\u4F20\u5176\u5B83 Agent \u65F6\u670D\u52A1\u7AEF\u6821\u9A8C\u5176\u4E0E\u8C03\u7528\u8005\u540C\u9879\u76EE\uFF09"},fileName:{type:"string",description:"\u6587\u4EF6\u540D\uFF08\u53EF\u9009\uFF0C\u6309 basename \u6A21\u7CCA\u5339\u914D\uFF09"},filePath:{type:"string",description:"\u5DE5\u4F5C\u533A\u76F8\u5BF9\u8DEF\u5F84\uFF08\u53EF\u9009\uFF0C\u6309\u8D26\u672C\u8BB0\u5F55\u7684\u76F8\u5BF9\u8DEF\u5F84 targetPath \u5339\u914D\uFF0C\u542B\u76EE\u5F55\u524D\u7F00\u5339\u914D\uFF09\u3002\u652F\u6301 ./xx\u3001xx\u3001@/xx\u3001/xx \u7B49\u4EF7\u5199\u6CD5\uFF08@ \u89C6\u4E3A\u5DE5\u4F5C\u533A\u6839\u8DEF\u5F84\u522B\u540D\uFF09\u3002\u793A\u4F8B\uFF1A@/src/main.ts \u7CBE\u786E\u5339\u914D src/main.ts\uFF1B@/src \u5339\u914D src/ \u76EE\u5F55\u53CA\u5176\u4E0B\u6240\u6709\u6587\u4EF6\u7684\u53D8\u66F4\u3002\u4E0E fileName \u6B63\u4EA4\uFF1AfileName \u6309\u6587\u4EF6\u540D\u6A21\u7CCA\uFF0CfilePath \u6309\u76F8\u5BF9\u8DEF\u5F84\u5339\u914D\u3002"},operation:{type:"string",description:"\u64CD\u4F5C\u7C7B\u578B\uFF1ACREATE / UPDATE / DELETE\uFF08\u53EF\u9009\uFF09",enum:["CREATE","UPDATE","DELETE"]},status:{type:"string",description:"\u8BB0\u5F55\u72B6\u6001\uFF1AAPPLIED\uFF08\u5DF2\u751F\u6548\uFF09/ REVERTED\uFF08\u5DF2\u64A4\u9500\uFF09/ REVERT_FAILED\uFF08\u64A4\u9500\u5931\u8D25\uFF09\uFF08\u53EF\u9009\uFF09",enum:["APPLIED","REVERTED","REVERT_FAILED"]},taskInstanceId:{type:"string",description:"\u4EFB\u52A1\u5B9E\u4F8B ID\uFF08\u53EF\u9009\uFF09"},startTime:{type:"string",description:"\u8D77\u59CB\u65F6\u95F4\uFF0CISO \u683C\u5F0F\u5982 2026-08-01T00:00:00\uFF08\u53EF\u9009\uFF09"},endTime:{type:"string",description:"\u7ED3\u675F\u65F6\u95F4\uFF0CISO \u683C\u5F0F\u5982 2026-08-02T00:00:00\uFF08\u53EF\u9009\uFF09"},page:{type:"number",description:"\u9875\u7801\uFF0C\u9ED8\u8BA4 1"},pageSize:{type:"number",description:"\u6BCF\u9875\u6761\u6570\uFF0C\u9ED8\u8BA4 20"}},required:[]}},ce=new Set(["create_memory","read_memory","update_memory","delete_memory","search_memory","list_memories","get_memory_stats","list_memories_by_file","memory_recurrence","memory_recurrence_complete"]),M={name:"launch_config_list",description:"\u67E5\u8BE2\u5F53\u524D Agent \u6240\u5C5E\u9879\u76EE\u4E0B\u7684\u542F\u52A8\u9879\uFF08\u7C7B IDEA Run Configuration\uFF09\u5217\u8868\u3002\u6BCF\u4E2A\u542F\u52A8\u9879\u542B id\u3001name\u3001type\uFF08generic/java/python/node/go/php\uFF09\u3001command\u3001cwd\u3001env\u3001jdkId\u3001groupId\u3001sortOrder\u3002\u67E5\u8BE2\u8303\u56F4\u81EA\u52A8\u9650\u5B9A\u4E3A\u5F53\u524D\u9879\u76EE\uFF0C\u65E0\u9700\u4F20 projectId\u3002",inputSchema:{type:"object",properties:{},required:[]}},P={name:"launch_config_create",description:"\u5728\u5F53\u524D Agent \u6240\u5C5E\u9879\u76EE\u4E0B\u65B0\u5EFA\u542F\u52A8\u9879\uFF08\u7C7B IDEA Run Configuration\uFF09\u3002\u521B\u5EFA\u524D\u5EFA\u8BAE\u5148 launch_config_list \u67E5\u770B\u73B0\u6709\u914D\u7F6E\u4E0E\u547D\u540D\u4E60\u60EF\u3002\u9879\u76EE\u8303\u56F4\u81EA\u52A8\u63A8\u5BFC\uFF0C\u65E0\u9700\u4F20 projectId\u3002\u521B\u5EFA\u6210\u529F\u540E\u8FD4\u56DE\u65B0\u542F\u52A8\u9879\u5B8C\u6574\u4FE1\u606F\uFF08\u542B id\uFF09\u3002",inputSchema:{type:"object",properties:{name:{type:"string",description:"\u542F\u52A8\u9879\u540D\u79F0\uFF08\u5FC5\u586B\uFF0C\u9879\u76EE\u5185\u552F\u4E00\uFF0C\u2264128 \u5B57\u7B26\uFF09"},type:{type:"string",description:"\u542F\u52A8\u9879\u7C7B\u578B\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4 generic\uFF09\uFF1Ageneric / java / python / node / go / php",enum:["generic","java","python","node","go","php"]},command:{type:"string",description:"\u542F\u52A8\u547D\u4EE4\uFF08\u5FC5\u586B\uFF0C\u22648192 \u5B57\u7B26\uFF09\u3002\u652F\u6301\u5360\u4F4D\u7B26 ${WORKSPACE}\uFF08\u9879\u76EE\u5DE5\u4F5C\u533A\uFF09\u3001${JAVA_HOME}\uFF08\u6240\u9009 JDK\uFF09\u3001${VAR}\uFF08env \u4E2D\u5B9A\u4E49\u7684\u53D8\u91CF\uFF09\u3002\u793A\u4F8B\uFF1Anpm run dev\u3001python main.py\u3001mvn spring-boot:run"},cwd:{type:"string",description:"\u5DE5\u4F5C\u76EE\u5F55\uFF08\u5FC5\u586B\uFF0C\u2264512 \u5B57\u7B26\uFF09\u2014\u2014\u9879\u76EE\u5B9E\u9645\u4EE3\u7801/\u6784\u5EFA\u76EE\u5F55\u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u5982 D:/code/xxx/backend"},env:{type:"object",description:"\u989D\u5916\u73AF\u5883\u53D8\u91CF\uFF08\u53EF\u9009\uFF0C\u226464 \u9879\uFF09\uFF0C\u989D\u5916\u5C5E\u6027\uFF1A\u5B57\u7B26\u4E32\u503C",additionalProperties:{type:"string"}},jdkId:{type:"string",description:"\u9009\u4E2D\u7684 JDK ID\uFF08type=java \u65F6\u6709\u6548\uFF0C\u53EF\u9009\uFF09"},groupId:{type:"string",description:"\u6240\u5C5E\u542F\u52A8\u9879\u5206\u7EC4 ID\uFF08\u53EF\u9009\uFF0Cnull/\u7A7A=\u672A\u5206\u7EC4\uFF09"},sortOrder:{type:"number",description:"\u6392\u5E8F\u6743\u91CD\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u8FFD\u52A0\u5230\u6240\u5728\u5BB9\u5668\u672B\u5C3E\uFF09"},readinessPattern:{type:"string",description:'\u5C31\u7EEA\u65E5\u5FD7\u6B63\u5219\uFF08\u53EF\u9009\uFF0C\u2264512 \u5B57\u7B26\uFF0CJS RegExp \u8BED\u6CD5\uFF09\u3002\u8BBE\u7F6E\u540E wait_timeout_ms \u7B49\u5F85\u7684 ready \u4FE1\u53F7\u6539\u4E3A"\u8F93\u51FA\u884C\u547D\u4E2D\u8BE5\u6B63\u5219"\uFF08\u9002\u914D\u4E0D\u76D1\u542C\u7AEF\u53E3\u7684\u5E38\u9A7B\u8FDB\u7A0B\uFF0C\u5982 worker/\u6D88\u8D39\u8005\uFF09\u3002\u793A\u4F8B\uFF1A^Server ready|^Build (SUCCESS|successful)\u3002\u7559\u7A7A=\u7AEF\u53E3\u76D1\u542C\u63A2\u6D4B'}},required:["name","command","cwd"]}},f={name:"launch_config_update",description:"\u66F4\u65B0\u542F\u52A8\u9879\uFF08\u540D\u79F0/\u7C7B\u578B/\u547D\u4EE4/\u5DE5\u4F5C\u76EE\u5F55/\u73AF\u5883\u53D8\u91CF/JDK/\u5206\u7EC4/\u6392\u5E8F\uFF09\u3002\u672A\u4F20\u5B57\u6BB5\u4FDD\u6301\u539F\u503C\uFF1B\u4FEE\u6539\u540D\u79F0\u65F6\u9879\u76EE\u5185\u4E0D\u80FD\u91CD\u540D\u3002\u76EE\u6807\u542F\u52A8\u9879\u5FC5\u987B\u5C5E\u4E8E\u5F53\u524D\u9879\u76EE\uFF08\u670D\u52A1\u7AEF\u6821\u9A8C\uFF09\u3002\u8FD0\u884C\u4E2D\u7684\u542F\u52A8\u9879\uFF1A\u4FEE\u6539\u914D\u7F6E\u4E0D\u4F1A\u5F71\u54CD\u5DF2\u8FD0\u884C\u8FDB\u7A0B\uFF0C\u9700\u91CD\u542F\u540E\u751F\u6548\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5FC5\u586B\uFF09"},name:{type:"string",description:"\u542F\u52A8\u9879\u540D\u79F0\uFF08\u53EF\u9009\uFF0C\u2264128 \u5B57\u7B26\uFF09"},type:{type:"string",description:"\u542F\u52A8\u9879\u7C7B\u578B\uFF08\u53EF\u9009\uFF09\uFF1Ageneric / java / python / node / go / php",enum:["generic","java","python","node","go","php"]},command:{type:"string",description:"\u542F\u52A8\u547D\u4EE4\uFF08\u53EF\u9009\uFF0C\u22648192 \u5B57\u7B26\uFF09"},cwd:{type:"string",description:"\u5DE5\u4F5C\u76EE\u5F55\uFF08\u53EF\u9009\uFF09"},env:{type:"object",description:"\u989D\u5916\u73AF\u5883\u53D8\u91CF\uFF08\u53EF\u9009\uFF0C\u6574\u4F53\u8986\u76D6\u539F env\uFF09",additionalProperties:{type:"string"}},jdkId:{type:"string",description:"\u9009\u4E2D\u7684 JDK ID\uFF08type=java \u65F6\u6709\u6548\uFF0C\u53EF\u9009\uFF09"},groupId:{type:"string",description:"\u6240\u5C5E\u542F\u52A8\u9879\u5206\u7EC4 ID\uFF08\u53EF\u9009\uFF09"},clearGroupId:{type:"boolean",description:"\u663E\u5F0F\u6E05\u9664\u5206\u7EC4\uFF08\u79FB\u56DE\u9ED8\u8BA4\u5206\u7EC4\uFF0C\u53EF\u9009\uFF1B\u4E0D\u80FD\u4E0E groupId \u540C\u65F6\u4F20\uFF09"},sortOrder:{type:"number",description:"\u6392\u5E8F\u6743\u91CD\uFF08\u53EF\u9009\uFF09"},readinessPattern:{type:"string",description:"\u5C31\u7EEA\u65E5\u5FD7\u6B63\u5219\uFF08\u53EF\u9009\uFF0CJS RegExp \u8BED\u6CD5\uFF09\uFF1A\u8BBE\u7F6E\u540E\u542F\u52A8\u7B49\u5F85\u7684 ready \u4FE1\u53F7\u4E3A\u8F93\u51FA\u884C\u547D\u4E2D\u6B63\u5219\uFF08\u9002\u914D\u4E0D\u76D1\u542C\u7AEF\u53E3\u7684\u8FDB\u7A0B\uFF09\u3002\u7559\u7A7A=\u7AEF\u53E3\u76D1\u542C\u63A2\u6D4B"},clearReadinessPattern:{type:"boolean",description:"\u663E\u5F0F\u6E05\u9664\u5C31\u7EEA\u6B63\u5219\uFF0C\u6062\u590D\u7AEF\u53E3\u63A2\u6D4B\uFF08\u53EF\u9009\uFF1B\u4E0D\u80FD\u4E0E readinessPattern \u540C\u65F6\u4F20\uFF09"}},required:["configId"]}},j={name:"launch_config_delete",description:"\u5220\u9664\u542F\u52A8\u9879\u914D\u7F6E\u3002\u76EE\u6807\u542F\u52A8\u9879\u5FC5\u987B\u5C5E\u4E8E\u5F53\u524D\u9879\u76EE\uFF08\u670D\u52A1\u7AEF\u6821\u9A8C\uFF09\u3002\u6CE8\u610F\uFF1A\u82E5\u8BE5\u542F\u52A8\u9879\u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148 launch_config_stop \u505C\u6B62\u8FDB\u7A0B\u518D\u5220\u9664\uFF08\u5220\u9664\u914D\u7F6E\u4E0D\u4F1A\u81EA\u52A8\u505C\u6B62\u5DF2\u8FD0\u884C\u8FDB\u7A0B\uFF09\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5FC5\u586B\uFF09"}},required:["configId"]}},q={name:"launch_config_start",description:"\u542F\u52A8\u542F\u52A8\u9879\uFF0C\u5728\u8C03\u7528\u8005\u6240\u5728 runtime-bridge \u673A\u5668\u4E0A\u62C9\u8D77\u8FDB\u7A0B\u3002\u652F\u6301\u5355\u9879\uFF08configId\uFF09\u4E0E\u6279\u91CF\uFF08configIds \u6570\u7EC4\uFF0C\u4E00\u6B21\u5E76\u884C\u62C9\u8D77\u591A\u4E2A\uFF09\uFF1A\u6279\u91CF\u65F6\u9010\u9879\u4EE5\u914D\u7F6E\u4E3A\u51C6\u5E76\u884C\u542F\u52A8\uFF0C\u5355\u9879\u5931\u8D25\u4E0D\u5F71\u54CD\u5176\u4F59\u9879\uFF0C\u8FD4\u56DE\u9010\u9879\u7ED3\u679C\u4E0E\u6C47\u603B\uFF08ready/exited/timeout/failed/skipped \u8BA1\u6570\uFF09\u3002\u82E5\u542F\u52A8\u9879\u5DF2\u5904\u4E8E\u8FD0\u884C/\u6B63\u5728\u542F\u52A8\u72B6\u6001\uFF08\u672A\u9000\u51FA/\u505C\u6B62\uFF09\uFF0C\u8C03\u7528\u4F1A\u8FD4\u56DE skipped=true\uFF08\u9644 message\u300C\u5F53\u524D\u5DF2\u5904\u4E8E\u542F\u52A8/\u6B63\u5728\u542F\u52A8\u72B6\u6001\uFF0C\u8DF3\u8FC7\u300D\u4E0E\u5F53\u524D run\uFF09\u800C\u975E\u62A5\u9519\uFF0C\u4E0D\u4F1A\u91CD\u590D\u62C9\u8D77\uFF0C\u4E5F\u65E0\u9700\u5148 launch_config_status \u786E\u8BA4\u3002\u9ED8\u8BA4\u4E0D\u7B49\u5F85\u7ACB\u5373\u8FD4\u56DE\uFF1B\u4F20 wait_timeout_ms > 0 \u65F6\u963B\u585E\u7B49\u5F85\u542F\u52A8\u7ED3\u679C\uFF08\u5355\u9879\u8FD4\u56DE wait \u5B57\u6BB5\uFF0C\u6279\u91CF\u5BF9\u6210\u529F\u62C9\u8D77\u9879\u5E76\u884C\u7B49\u5F85\u3001\u6574\u4F53\u8FD4\u56DE\u65F6\u95F4\u2248\u6700\u6162\u4E00\u9879\uFF1B\u88AB\u8DF3\u8FC7\u7684\u9879\u4E0D\u53C2\u4E0E\u7B49\u5F85\uFF09\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5355\u9879\u542F\u52A8\u65F6\u5FC5\u586B\uFF1B\u4E0E configIds \u4E8C\u9009\u4E00\uFF09"},configIds:{type:"array",items:{type:"string"},description:"\u6279\u91CF\u542F\u52A8\uFF1A\u542F\u52A8\u9879 ID \u6570\u7EC4\uFF081-20 \u4E2A\uFF0C\u81EA\u52A8\u53BB\u91CD\uFF1B\u4E0E configId \u4E8C\u9009\u4E00\uFF0C\u4F20\u4E86\u4F18\u5148\u8D70\u6279\u91CF\uFF09\u3002\u6279\u91CF\u6A21\u5F0F\u4EE5\u5404\u9879\u914D\u7F6E\u4E3A\u51C6\u542F\u52A8\uFF0C\u5FFD\u7565 command/cwd/env/readinessPattern \u8986\u76D6\u53C2\u6570\uFF1BworkspacePath/jdkPath \u4E0E wait_timeout_ms \u5BF9\u5168\u90E8\u9879\u751F\u6548"},command:{type:"string",description:"\u542F\u52A8\u547D\u4EE4\u8986\u76D6\uFF08\u53EF\u9009\uFF0C\u4EC5\u5355\u9879\u6A21\u5F0F\uFF09"},cwd:{type:"string",description:"\u5DE5\u4F5C\u76EE\u5F55\u8986\u76D6\uFF08\u53EF\u9009\uFF0C\u4EC5\u5355\u9879\u6A21\u5F0F\uFF09"},env:{type:"object",description:"\u73AF\u5883\u53D8\u91CF\u8986\u76D6\uFF08\u53EF\u9009\uFF0C\u6574\u4F53\u8986\u76D6\u914D\u7F6E env\uFF1B\u4EC5\u5355\u9879\u6A21\u5F0F\uFF09",additionalProperties:{type:"string"}},jdkPath:{type:"string",description:"JDK \u8DEF\u5F84\uFF08type=java \u65F6\u6709\u6548\uFF0C\u53EF\u9009\uFF1B\u5355\u9879=\u8BE5\u9879\u8986\u76D6\uFF0C\u6279\u91CF=\u5168\u90E8\u9879\u751F\u6548\uFF09"},workspacePath:{type:"string",description:"\u9879\u76EE\u5DE5\u4F5C\u533A\u8DEF\u5F84\uFF08\u53EF\u9009\uFF1B\u5355\u9879=\u8BE5\u9879\u8986\u76D6\uFF0C\u6279\u91CF=\u5168\u90E8\u9879\u751F\u6548\uFF09"},readinessPattern:{type:"string",description:"\u5C31\u7EEA\u65E5\u5FD7\u6B63\u5219\u8986\u76D6\uFF08\u53EF\u9009\uFF0C\u4EC5\u5355\u9879\u6A21\u5F0F\uFF0CJS RegExp \u8BED\u6CD5\uFF09\uFF1A\u8BBE\u7F6E\u540E\u542F\u52A8\u7B49\u5F85\u7684 ready \u4FE1\u53F7\u4E3A\u8F93\u51FA\u884C\u547D\u4E2D\u6B63\u5219\uFF08\u9002\u914D\u4E0D\u76D1\u542C\u7AEF\u53E3\u7684\u8FDB\u7A0B\uFF09\u3002\u7559\u7A7A=\u4EE5\u542F\u52A8\u9879\u914D\u7F6E\u4E3A\u51C6\uFF08\u9ED8\u8BA4\u7AEF\u53E3\u76D1\u542C\u63A2\u6D4B\uFF09"},wait_timeout_ms:{type:"number",description:"\u963B\u585E\u7B49\u5F85\u542F\u52A8\u7ED3\u679C\u7684\u8D85\u65F6\u6BEB\u79D2\u6570\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4 0=\u4E0D\u7B49\u5F85\uFF0Cspawn \u540E\u7ACB\u5373\u8FD4\u56DE\uFF09\u3002>0 \u65F6\u672C\u6B21\u8C03\u7528\u963B\u585E\uFF0C\u76F4\u5230\u4EE5\u4E0B\u4FE1\u53F7\u6700\u5148\u5230\u8FBE\u5E76\u5728 wait \u5B57\u6BB5\u8FD4\u56DE\uFF1Aready=\u8FDB\u7A0B\u6811\u63A2\u6D4B\u5230\u76D1\u542C\u7AEF\u53E3\uFF08\u5E38\u9A7B\u670D\u52A1\u542F\u52A8\u6210\u529F\uFF0C\u9644 ports\uFF09\uFF0C\u6216\u8F93\u51FA\u884C\u547D\u4E2D\u5C31\u7EEA\u6B63\u5219\uFF08readinessPattern\uFF0C\u89C1\u4E0A\uFF09\uFF1Bexited=\u8FDB\u7A0B\u9000\u51FA\uFF08\u4E00\u6B21\u6027\u547D\u4EE4\u5B8C\u6210\u6216\u542F\u52A8\u5FEB\u901F\u5931\u8D25\uFF0CexitCode=0 \u4E3A\u6210\u529F\uFF0C\u975E 0 \u68C0\u67E5 logTail \u5B9A\u4F4D\u539F\u56E0\uFF09\uFF1Bstopped=\u7B49\u5F85\u671F\u95F4\u88AB\u505C\u6B62\uFF1Btimeout=\u8D85\u65F6\uFF0C\u8FDB\u7A0B\u4ECD\u5728\u8FD0\u884C\uFF08\u4E0D\u7B97\u9519\u8BEF\uFF0C\u6309 logTail \u81EA\u884C\u5224\u65AD\u6216\u7A0D\u540E launch_config_logs \u8F6E\u8BE2\uFF09\u3002\u4E0A\u9650 300000\uFF085 \u5206\u949F\uFF09\uFF0C\u6162\u542F\u52A8\u670D\u52A1\uFF08\u5982 Spring Boot\uFF09\u5EFA\u8BAE 60000-120000\u3002\u6279\u91CF\u6A21\u5F0F\u5BF9\u5168\u90E8\u6210\u529F\u9879\u5E76\u884C\u7B49\u5F85\uFF08\u6BCF\u9879\u72EC\u7ACB\u8BA1\u65F6\uFF09\u3002"}},required:[]}},k={name:"launch_config_restart",description:"\u91CD\u542F\u542F\u52A8\u9879\uFF08bridge \u5185\u539F\u5B50\u6267\u884C\u300C\u505C\u6B62\u65E7\u8FDB\u7A0B + \u91CD\u65B0\u62C9\u8D77\u300D\uFF0C\u4EE3\u7406\u5230\u8C03\u7528\u8005\u6240\u5728 runtime-bridge\uFF09\u3002\u76F8\u6BD4\u5148 launch_config_stop \u518D launch_config_start\uFF0C\u4E0D\u5B58\u5728 stop \u8BF7\u6C42\u4E22\u5931\u5BFC\u81F4 start \u649E\u4E0A\u4ECD\u5728\u8FD0\u884C\u65E7\u8FDB\u7A0B\u7684\u7ADE\u6001\u3002\u672A\u8FD0\u884C\u65F6\u7B49\u4EF7\u4E8E\u76F4\u63A5 start\u3002\u8986\u76D6\u53C2\u6570\uFF08command/cwd/env \u7B49\uFF09\u4E0E\u542F\u52A8\u7B49\u5F85\u8BED\u4E49\u540C launch_config_start\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5FC5\u586B\uFF09"},command:{type:"string",description:"\u542F\u52A8\u547D\u4EE4\u8986\u76D6\uFF08\u53EF\u9009\uFF09"},cwd:{type:"string",description:"\u5DE5\u4F5C\u76EE\u5F55\u8986\u76D6\uFF08\u53EF\u9009\uFF09"},env:{type:"object",description:"\u73AF\u5883\u53D8\u91CF\u8986\u76D6\uFF08\u53EF\u9009\uFF0C\u6574\u4F53\u8986\u76D6\u914D\u7F6E env\uFF09",additionalProperties:{type:"string"}},jdkPath:{type:"string",description:"JDK \u8DEF\u5F84\uFF08type=java \u65F6\u6709\u6548\uFF0C\u53EF\u9009\uFF09"},workspacePath:{type:"string",description:"\u9879\u76EE\u5DE5\u4F5C\u533A\u8DEF\u5F84\uFF08\u53EF\u9009\uFF09"},readinessPattern:{type:"string",description:"\u5C31\u7EEA\u65E5\u5FD7\u6B63\u5219\u8986\u76D6\uFF08\u53EF\u9009\uFF0CJS RegExp \u8BED\u6CD5\uFF09\uFF1A\u8BBE\u7F6E\u540E\u65B0\u8FDB\u7A0B\u542F\u52A8\u7B49\u5F85\u7684 ready \u4FE1\u53F7\u4E3A\u8F93\u51FA\u884C\u547D\u4E2D\u6B63\u5219\u3002\u7559\u7A7A=\u4EE5\u542F\u52A8\u9879\u914D\u7F6E\u4E3A\u51C6\uFF08\u9ED8\u8BA4\u7AEF\u53E3\u76D1\u542C\u63A2\u6D4B\uFF09"},wait_timeout_ms:{type:"number",description:"\u963B\u585E\u7B49\u5F85\u65B0\u8FDB\u7A0B\u542F\u52A8\u7ED3\u679C\u7684\u8D85\u65F6\u6BEB\u79D2\u6570\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4 0=\u4E0D\u7B49\u5F85\uFF09\u3002\u8BED\u4E49\u540C launch_config_start\uFF1Aready=\u7AEF\u53E3\u5C31\u7EEA\u6216\u65E5\u5FD7\u547D\u4E2D\u5C31\u7EEA\u6B63\u5219 / exited=\u8FDB\u7A0B\u9000\u51FA / timeout=\u8D85\u65F6\uFF08\u8FDB\u7A0B\u4ECD\u5728\u8FD0\u884C\uFF0C\u975E\u9519\u8BEF\uFF09\u3002"}},required:["configId"]}},U={name:"launch_config_stop",description:"\u505C\u6B62\u542F\u52A8\u9879\u8FDB\u7A0B\uFF08\u542B\u8FDB\u7A0B\u6811\uFF0C\u4EE3\u7406\u5230\u8C03\u7528\u8005\u6240\u5728 runtime-bridge\uFF09\u3002\u76EE\u6807\u542F\u52A8\u9879\u5FC5\u987B\u5C5E\u4E8E\u5F53\u524D\u9879\u76EE\uFF08\u670D\u52A1\u7AEF\u6821\u9A8C\uFF09\u3002\u82E5\u8FDB\u7A0B\u5DF2\u9000\u51FA\uFF0C\u8FD4\u56DE\u5DF2\u505C\u6B62/\u65E0\u8FD0\u884C\u8FDB\u7A0B\u7684\u72B6\u6001\uFF0C\u4E0D\u62A5\u9519\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5FC5\u586B\uFF09"}},required:["configId"]}},G={name:"launch_config_logs",description:"\u589E\u91CF\u62C9\u53D6\u542F\u52A8\u9879\u8FD0\u884C\u65E5\u5FD7\uFF08\u6700\u8FD1 200 \u6761\u73AF\u5F62\u7F13\u51B2\uFF0C\u4EE3\u7406\u5230\u8C03\u7528\u8005\u6240\u5728 runtime-bridge\uFF09\u3002\u9996\u6B21\u8C03\u7528\u4E0D\u4F20 since \u83B7\u53D6\u5168\u90E8\u7F13\u51B2\u65E5\u5FD7\uFF1B\u540E\u7EED\u6BCF\u6B21\u628A\u8FD4\u56DE\u7684 nextSince \u4F5C\u4E3A since \u7EED\u62C9\u589E\u91CF\u3002\u8FD4\u56DE\u5B57\u6BB5\uFF1Alines\uFF08\u65E5\u5FD7\u884C\uFF09\u3001nextSince\uFF08\u4E0B\u6B21\u6E38\u6807\uFF09\u3001running\uFF08\u8FDB\u7A0B\u662F\u5426\u8FD0\u884C\u4E2D\uFF09\u3002\u76EE\u6807\u542F\u52A8\u9879\u5FC5\u987B\u5C5E\u4E8E\u5F53\u524D\u9879\u76EE\uFF08\u670D\u52A1\u7AEF\u6821\u9A8C\uFF09\u3002",inputSchema:{type:"object",properties:{configId:{type:"string",description:"\u542F\u52A8\u9879 ID\uFF08\u5FC5\u586B\uFF09"},since:{type:"number",description:"\u65E5\u5FD7\u6E38\u6807\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4 0 = \u4ECE\u5934\u62C9\u53D6\uFF09"}},required:["configId"]}},v={name:"launch_config_status",description:"\u67E5\u8BE2\u8C03\u7528\u8005\u6240\u5728 bridge \u673A\u5668\u4E0A\u5F53\u524D\u9879\u76EE\u7684\u5168\u90E8\u542F\u52A8\u9879\u8FD0\u884C\u72B6\u6001\u3002\u8FD4\u56DE runs \u6570\u7EC4\uFF1A\u6BCF\u9879\u542B configId\u3001status\uFF08running/exited/stopped\uFF09\u3001pid\u3001startTime\u3001command \u7B49\u3002\u4EC5\u8FD4\u56DE\u5F53\u524D\u9879\u76EE\u914D\u7F6E\u7684\u542F\u52A8\u9879\uFF08\u670D\u52A1\u7AEF\u6309\u9879\u76EE\u8FC7\u6EE4\uFF09\u3002",inputSchema:{type:"object",properties:{},required:[]}},de=new Set(["launch_config_list","launch_config_create","launch_config_update","launch_config_delete","launch_config_start","launch_config_restart","launch_config_stop","launch_config_logs","launch_config_status"]),ae=new Set(["hire_colleague"]),w={name:"create_meeting",description:"\u521B\u5EFA\u65B0\u4F1A\u8BAE\u5E76\u9080\u8BF7\u6307\u5B9A\u89D2\u8272\uFF08\u542B Agent \u5B9E\u4F8B\uFF09\u3002\u6210\u5458\u5168\u90E8\u5230\u4F4D\u540E\u4F1A\u8BAE\u5F00\u59CB\uFF0C\u968F\u540E\u4F7F\u7528 meeting_speak \u53D1\u8A00 / poll_message \u7B49\u5F85\u5176\u5B83\u7528\u6237\u53D1\u8A00 / end_meeting \u7ED3\u675F\u4F1A\u8BAE\u3002\u963B\u585E\u578B\u5DE5\u5177\uFF1A\u5168\u5458\u5230\u4F4D\u6216\u7B49\u5F85\u8D85\u65F6\u540E\u624D\u8FD4\u56DE\u3002\u6301\u6709\u8FDB\u884C\u4E2D\u6D41\u7A0B\u4EFB\u52A1\u65F6\u540C\u6837\u53EF\u4EE5\u521B\u5EFA\u4F1A\u8BAE\uFF08\u4F8B\u5982\u4EFB\u52A1\u672C\u8EAB\u8981\u6C42\u5F00\u4F1A\u8BA8\u8BBA/\u534F\u8C03\u7684\u573A\u666F\uFF09\uFF0C\u4E0D\u4F1A\u88AB\u4EFB\u52A1\u62E6\u622A\uFF1B\u8FDB\u5165\u4F1A\u8BAE\u540E\u4EFB\u52A1\u63D0\u9192\u6682\u505C\uFF0C\u4F1A\u8BAE\u7ED3\u675F\u540E\u81EA\u52A8\u6062\u590D\u3002",inputSchema:{type:"object",properties:{topic:{type:"string",description:"\u4F1A\u8BAE\u4E3B\u9898\uFF08\u5FC5\u586B\uFF09"},description:{type:"string",description:"\u4F1A\u8BAE\u63CF\u8FF0\uFF08\u53EF\u9009\uFF09"},members:{type:"array",description:"\u53D7\u9080\u6210\u5458\uFF1A[{roleId, agentId?}, ...]\uFF0CagentId \u672A\u6307\u5B9A\u65F6\u670D\u52A1\u7AEF\u6309\u89D2\u8272\u81EA\u52A8\u9009\u53D6\u5B9E\u4F8B",items:{type:"object",properties:{roleId:{type:"string",description:"\u89D2\u8272 id\uFF08\u5FC5\u586B\uFF09"},agentId:{type:"string",description:"Agent \u5B9E\u4F8B id\uFF08\u53EF\u9009\uFF09"}},required:["roleId"]}},waitTimeoutMs:{type:"number",description:"\u7B49\u5F85\u5168\u5458\u5230\u4F4D\u7684\u8D85\u65F6\u65F6\u957F\uFF08\u6BEB\u79D2\uFF0C\u53EF\u9009\uFF0C\u9ED8\u8BA4/\u4E0A\u9650 270000\uFF09\u3002\u8D85\u65F6\u8FD4\u56DE WAITING \u72B6\u6001\u800C\u975E\u9519\u8BEF\uFF0C\u53EF\u7EE7\u7EED poll_message \u7B49\u5F85\u5168\u5458\u5230\u4F4D"}},required:["topic","members"]}},H={name:"leave_meeting",description:"\u9000\u51FA\u5F53\u524D\u52A0\u5165\u7684\u4F1A\u8BAE\u3002\u5DF2\u52A0\u5165\u6210\u5458\u6B63\u5F0F\u9000\u51FA\uFF1B\u672A\u52A0\u5165\u6210\u5458\u8C03\u7528\u89C6\u4E3A\u5A49\u62D2\u9080\u8BF7\u3002",inputSchema:{type:"object",properties:{meetingId:{type:"string",description:"\u4F1A\u8BAE ID\uFF08\u5FC5\u586B\uFF09"}},required:["meetingId"]}},Y={name:"end_meeting",description:"\u7ED3\u675F\u6307\u5B9A\u4F1A\u8BAE\uFF08\u4EC5\u4F1A\u8BAE\u521B\u5EFA\u8005\u53EF\u8C03\u7528\uFF09\u3002\u7ED3\u675F\u540E\u6210\u5458\u53EF\u4F7F\u7528 get_meeting_info \u67E5\u770B\u5386\u53F2\u53D1\u8A00\u3002",inputSchema:{type:"object",properties:{meetingId:{type:"string",description:"\u4F1A\u8BAE ID\uFF08\u5FC5\u586B\uFF09"}},required:["meetingId"]}},F={name:"meeting_speak",description:"\u5411\u6D3B\u8DC3\u4F1A\u8BAE\u53D1\u8A00\uFF08\u4EC5\u5DF2\u52A0\u5165\u4E14\u4F1A\u8BAE\u5DF2 STARTED \u7684\u6210\u5458\u53EF\u7528\uFF09\u3002\u53D1\u8A00\u5B9E\u65F6\u5E7F\u64AD\u7ED9\u6240\u6709\u53C2\u4F1A\u6210\u5458\u3002",inputSchema:{type:"object",properties:{meetingId:{type:"string",description:"\u4F1A\u8BAE ID\uFF08\u5FC5\u586B\uFF09"},content:{type:"string",description:"\u53D1\u8A00\u5185\u5BB9\uFF08\u5FC5\u586B\uFF09"}},required:["meetingId","content"]}},K={name:"get_meeting_info",description:"\u83B7\u53D6\u4F1A\u8BAE\u4FE1\u606F JSON\uFF1A\u4E3B\u9898/\u63CF\u8FF0/\u72B6\u6001/\u6210\u5458\u5217\u8868\uFF08\u521B\u5EFA\u4EBA\u6807\u6CE8 isCreator\uFF09/\u6700\u8FD1\u53D1\u8A00\u8BB0\u5F55\u3002\u53EF\u7528\u4E8E\u67E5\u770B\u81EA\u5DF1\u521B\u5EFA\u7684\u4F1A\u8BAE\u8FDB\u5EA6\u6216\u5DF2\u52A0\u5165\u4F1A\u8BAE\u7684\u8BE6\u60C5\u3002",inputSchema:{type:"object",properties:{meetingId:{type:"string",description:"\u4F1A\u8BAE ID\uFF08\u5FC5\u586B\uFF09"}},required:["meetingId"]}},B={name:"my_meetings",description:"\u67E5\u770B\u4E0E\u6211\u76F8\u5173\u7684\u4F1A\u8BAE\u5217\u8868\uFF08\u65E0\u9700 meetingId\uFF09\uFF1Aactive=\u5DF2\u52A0\u5165\u7684\u8FDB\u884C\u4E2D\u4F1A\u8BAE\uFF1Binvited=\u53D7\u9080\u5C1A\u672A\u52A0\u5165\u7684\u4F1A\u8BAE\u3002\u6BCF\u4E2A\u4F1A\u8BAE\u542B meetingId/\u4E3B\u9898/\u72B6\u6001/\u6210\u5458\u5230\u4F4D\u60C5\u51B5\uFF0C\u53EF\u5148\u7528\u672C\u5DE5\u5177\u83B7\u53D6 meetingId \u518D\u8C03\u7528 get_meeting_info\u3002\u52A0\u5165\u4F1A\u8BAE\u4E0D\u9700\u8981\u624B\u52A8\u5DE5\u5177\uFF1A\u53D7\u9080\u540E\u5C06\u5728 poll_message \u65F6\u81EA\u52A8\u52A0\u5165\u3002",inputSchema:{type:"object",properties:{},required:[]}},_e=new Set(["create_meeting","leave_meeting","end_meeting","meeting_speak","get_meeting_info","my_meetings"]),V={name:"pencil_create_document",description:"\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684\u8BBE\u8BA1\u753B\u5E03\u6587\u6863\uFF08\u7A7A\u767D\u5355\u9875\uFF09\u3002\u521B\u5EFA\u540E\u7528 pencil_open_document \u6253\u5F00\u5E76\u5728 dashboard \u9762\u677F\u6E32\u67D3\uFF0C\u518D\u7528 pencil_create_nodes \u6DFB\u52A0\u56FE\u5F62\u3002",inputSchema:{type:"object",properties:{name:{type:"string",description:"\u753B\u5E03\u540D\u79F0\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u300C\u672A\u547D\u540D\u753B\u5E03\u300D\uFF09"}},required:[]}},J={name:"pencil_list_documents",description:"\u5217\u51FA\u5F53\u524D Agent \u7684\u6240\u6709\u8BBE\u8BA1\u753B\u5E03\u6587\u6863\uFF08\u672C\u5730 + \u88AB\u9080\u8BF7\u534F\u4F5C\u7684\u6258\u7BA1\u753B\u5E03\uFF0C\u9644 permission \u4E0E shared \u6807\u8BB0\uFF09\u3002",inputSchema:{type:"object",properties:{},required:[]}},W={name:"pencil_open_document",description:"\u6253\u5F00\u4E00\u4E2A\u8BBE\u8BA1\u753B\u5E03\u6587\u6863\uFF08dashboard \u5C06\u5728\u753B\u5E03\u9762\u677F\u6E32\u67D3\u5B83\uFF0Cagent \u884C\u4E0A\u65B9\u51FA\u73B0\u753B\u5E03\u6807\u8BB0\uFF09\u3002docId \u6765\u81EA pencil_create_document \u6216 pencil_list_documents\uFF1B\u88AB\u9080\u8BF7\u534F\u4F5C\u7684\u753B\u5E03\u4E5F\u5728\u5217\u8868\u4E2D\uFF08shared=true\uFF0C\u9644\u672C\u4EBA permission\uFF09\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"}},required:["docId"]}},z={name:"pencil_close_document",description:"\u5173\u95ED\u8BBE\u8BA1\u753B\u5E03\u9762\u677F\uFF08\u4EC5\u6536\u8D77 dashboard \u9762\u677F\uFF0C\u4E0D\u5F71\u54CD\u5FBD\u6807\u8BA1\u6570\uFF0C\u6587\u6863\u4FDD\u7559\uFF0C\u53EF\u968F\u65F6 pencil_open_document \u91CD\u65B0\u6253\u5F00\uFF09\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"}},required:["docId"]}},X={name:"pencil_get_tree",description:"\u8BFB\u53D6\u753B\u5E03\u7684\u8282\u70B9\u6811\u6458\u8981\uFF08id/\u7C7B\u578B/\u540D\u79F0/\u51E0\u4F55\u4F4D\u7F6E\uFF0C\u542B\u6587\u672C\u5185\u5BB9\u622A\u65AD\uFF0C\u8FD4\u56DE truncated \u6807\u8BB0\u662F\u5426\u88AB\u622A\u65AD\uFF09\u3002\u7528\u4E8E\u5728\u521B\u5EFA/\u4FEE\u6539\u524D\u4E86\u89E3\u753B\u5E03\u73B0\u72B6\uFF1B\u8FD4\u56DE\u7684 version \u53EF\u4F5C\u4E3A expectedVersion \u4E50\u89C2\u9501\u4F20\u5165\u5199\u5DE5\u5177\u3002\u6811\u4E2D\u5B50\u8282\u70B9\u7684 x/y \u4E3A\u76F8\u5BF9\u7236\u8282\u70B9\u7684\u5C40\u90E8\u5750\u6807\uFF08\u4E0E pencil_create_nodes \u4E00\u81F4\uFF09\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"}},required:["docId"]}},$={name:"pencil_get_changes",description:"\u8FFD\u8D76\u534F\u4F5C\u753B\u5E03\u81EA sinceVersion \u4EE5\u6765\u7684\u53D8\u66F4\uFF08\u9010\u7248\u672C\u6458\u8981\uFF1A\u8C01\u6539\u7684\u3001\u65B0\u589E/\u66F4\u65B0/\u5220\u9664\u4E86\u54EA\u4E9B\u8282\u70B9\u53CA\u65B0\u503C\uFF09\u3002\u6536\u5230\u300C\u8BBE\u8BA1\u753B\u5E03\u53D8\u66F4\u300D\u7CFB\u7EDF\u901A\u77E5\u540E\u8C03\u7528\uFF1Btruncated=true \u8868\u793A\u53D8\u66F4\u65E5\u5FD7\u5DF2\u88AB\u4FEE\u526A\uFF0C\u8BF7\u6539\u7528 pencil_open_document \u5168\u91CF\u91CD\u8BFB\u3002\u8BF7\u628A\u8FD4\u56DE\u7684 toVersion \u8BB0\u4E3A\u8BE5\u753B\u5E03\u4F60\u5DF2\u770B\u5230\u7684\u6700\u65B0\u7248\u672C\uFF1A\u540E\u7EED\u5199\u5DE5\u5177\u4F20\u5B83\u4F5C expectedVersion \u4E50\u89C2\u9501\uFF0C\u4E0B\u6B21\u8FFD\u8D76\u4F20\u5B83\u4F5C sinceVersion\u3002\u4F60\u4E0A\u6B21\u770B\u5230\u7684\u7248\u672C\u6765\u81EA\u9080\u8BF7\u901A\u77E5\u7684 version \u6216\u672C\u5DE5\u5177\u4E0A\u6B21\u8FD4\u56DE\u7684 toVersion\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},sinceVersion:{type:"number",description:"\u4F60\u5DF2\u770B\u5230\u7684\u6700\u65B0\u753B\u5E03\u7248\u672C\uFF08\u7F3A\u7701 0 = \u4ECE\u5934\u8FFD\u8D76\uFF1B\u4F20\u5165\u9080\u8BF7\u901A\u77E5/\u4E0A\u4E00\u6B21\u8FFD\u8D76\u8FD4\u56DE\u7684\u7248\u672C\u53EF\u53EA\u62FF\u589E\u91CF\uFF09"}},required:["docId"]}},Q={name:"pencil_create_nodes",description:"\u5728\u8BBE\u8BA1\u753B\u5E03\u4E2D\u521B\u5EFA\u8282\u70B9\uFF08\u4E00\u6B21\u53EF\u521B\u5EFA\u591A\u4E2A\u3001\u4E0A\u9650 500 \u4E2A\uFF0C\u652F\u6301 frame/rect/ellipse/text/line\uFF09\u3002\u989C\u8272\u7528\u5341\u516D\u8FDB\u5236\uFF08#RRGGBB / #RRGGBBAA / none\uFF09\u3002\u5750\u6807\u7CFB\uFF1Ax/y \u4E3A\u76F8\u5BF9 parentId \u7684\u5C40\u90E8\u5750\u6807\u2014\u2014parentId \u7F3A\u7701\uFF08\u6302\u5230\u9875\u9762\uFF09\u65F6\u662F\u9875\u9762\u5750\u6807\uFF08\u5DE6\u4E0A\u89D2\u539F\u70B9\uFF09\uFF0C\u5D4C\u5957\u5230 frame \u5185\u65F6\u4ECE\u8BE5 frame \u7684\u5DE6\u4E0A\u89D2\u8D77\u7B97\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},parentId:{type:"string",description:"\u7236\u8282\u70B9 id\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u753B\u5E03\u7B2C\u4E00\u4E2A\u9875\u9762\uFF1B\u53EF\u4F20 frame \u8282\u70B9 id \u5B9E\u73B0\u5D4C\u5957\uFF0C\u6B64\u65F6 x/y \u76F8\u5BF9\u8BE5 frame\uFF09"},nodes:{type:"array",description:"\u8282\u70B9\u89C4\u683C\u6570\u7EC4",items:{type:"object",properties:{type:{type:"string",description:"frame | rect | ellipse | text | line"},name:{type:"string",description:"\u8282\u70B9\u540D\u79F0\uFF08\u53EF\u9009\uFF09"},x:{type:"number",description:"X \u5750\u6807\uFF08\u76F8\u5BF9 parentId \u5C40\u90E8\u5750\u6807\uFF09"},y:{type:"number",description:"Y \u5750\u6807\uFF08\u76F8\u5BF9 parentId \u5C40\u90E8\u5750\u6807\uFF09"},width:{type:"number",description:"\u5BBD\u5EA6\uFF08line \u9ED8\u8BA4 100\uFF09"},height:{type:"number",description:"\u9AD8\u5EA6\uFF08line \u9ED8\u8BA4 0\uFF09"},fill:{type:"string",description:"\u586B\u5145\u8272\u5341\u516D\u8FDB\u5236\uFF08\u5982 #4F8EF7\uFF0Cnone \u8868\u793A\u65E0\u586B\u5145\uFF09"},stroke:{type:"string",description:"\u63CF\u8FB9\u8272\u5341\u516D\u8FDB\u5236\uFF08\u53EF\u9009\uFF09"},strokeWeight:{type:"number",description:"\u63CF\u8FB9\u7C97\u7EC6\uFF08\u9ED8\u8BA4 1\uFF09"},cornerRadius:{type:"number",description:"\u5706\u89D2\u534A\u5F84"},opacity:{type:"number",description:"\u4E0D\u900F\u660E\u5EA6 0-1"},rotation:{type:"number",description:"\u65CB\u8F6C\u89D2\u5EA6"},visible:{type:"boolean",description:"\u662F\u5426\u53EF\u89C1\uFF08\u9ED8\u8BA4 true\uFF09"},text:{type:"string",description:"text \u8282\u70B9\u7684\u6587\u672C\u5185\u5BB9"},fontSize:{type:"number",description:"\u5B57\u53F7\uFF08\u9ED8\u8BA4 14\uFF09"},fontWeight:{type:"number",description:"\u5B57\u91CD\uFF08\u9ED8\u8BA4 400\uFF09"},fontFamily:{type:"string",description:"\u5B57\u4F53\uFF08\u9ED8\u8BA4 Inter\uFF09"},fontColor:{type:"string",description:"\u6587\u672C\u989C\u8272\uFF08\u9ED8\u8BA4\u9ED1\uFF09"}},required:["type"]}},expectedVersion:{type:"number",description:"\u53EF\u9009\u4E50\u89C2\u9501\uFF1A\u4F20\u5165\u6700\u8FD1\u4E00\u6B21 pencil_get_tree / \u5199\u5DE5\u5177\u8FD4\u56DE\u7684 version\u3002\u753B\u5E03\u5728\u6B64\u671F\u95F4\u88AB\u4EBA\u6216\u5176\u4ED6 Agent \u4FEE\u6539\u65F6\u8FD4\u56DE\u7248\u672C\u51B2\u7A81\uFF08\u800C\u975E\u9759\u9ED8\u8986\u76D6\u5BF9\u65B9\u6539\u52A8\uFF09\uFF1B\u591A\u4EBA/\u591A Agent \u534F\u4F5C\u7F16\u8F91\u65F6\u5EFA\u8BAE\u4F20\u5165"}},required:["docId","nodes"]}},Z={name:"pencil_update_nodes",description:"\u6279\u91CF\u66F4\u65B0\u753B\u5E03\u8282\u70B9\u5C5E\u6027\uFF08\u51E0\u4F55/\u586B\u5145/\u6587\u672C/\u900F\u660E\u5EA6/\u53EF\u89C1\u6027/\u540D\u79F0\u7B49\uFF09\u3002id \u53EF\u901A\u8FC7 pencil_get_tree \u83B7\u5F97\u3002\u4EC5\u652F\u6301\u767D\u540D\u5355\u5B57\u6BB5\uFF0C\u672A\u77E5\u5B57\u6BB5\u4F1A\u88AB\u62D2\u7EDD\uFF1Bid/parentId/childIds \u4E0D\u53EF\u901A\u8FC7\u672C\u5DE5\u5177\u4FEE\u6539\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},updates:{type:"array",description:"\u66F4\u65B0\u5217\u8868",items:{type:"object",properties:{id:{type:"string",description:"\u8282\u70B9 id"},props:{type:"object",description:"\u8981\u66F4\u65B0\u7684\u5C5E\u6027\uFF0C\u4EC5\u652F\u6301\u8FD9\u4E9B\u5B57\u6BB5\uFF08\u5176\u4ED6\u5B57\u6BB5\u4F1A\u88AB\u62D2\u7EDD\uFF09\uFF1Ax / y / width / height / rotation / opacity / visible / name / fill / stroke / strokeWeight / cornerRadius / text / fontSize / fontWeight / fontFamily / fontColor"}},required:["id","props"]}},expectedVersion:{type:"number",description:"\u53EF\u9009\u4E50\u89C2\u9501\uFF1A\u4F20\u5165\u6700\u8FD1\u4E00\u6B21 pencil_get_tree / \u5199\u5DE5\u5177\u8FD4\u56DE\u7684 version\u3002\u753B\u5E03\u5728\u6B64\u671F\u95F4\u88AB\u4EBA\u6216\u5176\u4ED6 Agent \u4FEE\u6539\u65F6\u8FD4\u56DE\u7248\u672C\u51B2\u7A81\uFF08\u800C\u975E\u9759\u9ED8\u8986\u76D6\u5BF9\u65B9\u6539\u52A8\uFF09\uFF1B\u591A\u4EBA/\u591A Agent \u534F\u4F5C\u7F16\u8F91\u65F6\u5EFA\u8BAE\u4F20\u5165"}},required:["docId","updates"]}},ee={name:"pencil_delete_nodes",description:"\u6279\u91CF\u5220\u9664\u753B\u5E03\u8282\u70B9\uFF08\u542B\u5176\u5168\u90E8\u5B50\u8282\u70B9\uFF09\u3002root/\u9875\u9762\u8282\u70B9\u4E0D\u53EF\u5220\u9664\u3002\u5220\u9664\u6574\u4E2A\u753B\u5E03\u7528 pencil_delete_document\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},ids:{type:"array",items:{type:"string"},description:"\u8981\u5220\u9664\u7684\u8282\u70B9 id \u5217\u8868"},expectedVersion:{type:"number",description:"\u53EF\u9009\u4E50\u89C2\u9501\uFF1A\u4F20\u5165\u6700\u8FD1\u4E00\u6B21 pencil_get_tree / \u5199\u5DE5\u5177\u8FD4\u56DE\u7684 version\u3002\u753B\u5E03\u5728\u6B64\u671F\u95F4\u88AB\u4EBA\u6216\u5176\u4ED6 Agent \u4FEE\u6539\u65F6\u8FD4\u56DE\u7248\u672C\u51B2\u7A81\uFF08\u800C\u975E\u9759\u9ED8\u8986\u76D6\u5BF9\u65B9\u6539\u52A8\uFF09\uFF1B\u591A\u4EBA/\u591A Agent \u534F\u4F5C\u7F16\u8F91\u65F6\u5EFA\u8BAE\u4F20\u5165"}},required:["docId","ids"]}},te={name:"pencil_delete_document",description:"\u5220\u9664\u6574\u4E2A\u8BBE\u8BA1\u753B\u5E03\u6587\u6863\uFF08\u4EC5\u753B\u5E03\u62E5\u6709\u8005\u53EF\u8C03\u7528\uFF0C\u4E0D\u53EF\u6062\u590D\uFF1A\u6587\u6863\u3001\u5168\u90E8\u8282\u70B9\u4E0E\u534F\u4F5C\u8005\u4E00\u5E76\u6E05\u9664\uFF09\u3002\u7528\u4E8E\u6E05\u7406\u4E0D\u518D\u9700\u8981\u7684\u753B\u5E03\uFF1B\u53EA\u5220\u9664\u753B\u5E03\u91CC\u7684\u90E8\u5206\u8282\u70B9\u7528 pencil_delete_nodes\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"}},required:["docId"]}},ie={name:"pencil_rename_document",description:"\u91CD\u547D\u540D\u8BBE\u8BA1\u753B\u5E03\uFF08ACL write \u53EF\u8C03\u7528\uFF1A\u62E5\u6709\u8005\u6216 permission=write \u6210\u5458\uFF09\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},name:{type:"string",description:"\u65B0\u7684\u753B\u5E03\u540D\u79F0"},expectedVersion:{type:"number",description:"\u53EF\u9009\u4E50\u89C2\u9501\uFF1A\u4F20\u5165\u6700\u8FD1\u4E00\u6B21 pencil_get_tree / \u5199\u5DE5\u5177\u8FD4\u56DE\u7684 version\u3002\u753B\u5E03\u5728\u6B64\u671F\u95F4\u88AB\u4EBA\u6216\u5176\u4ED6 Agent \u4FEE\u6539\u65F6\u8FD4\u56DE\u7248\u672C\u51B2\u7A81\uFF08\u800C\u975E\u9759\u9ED8\u8986\u76D6\u5BF9\u65B9\u6539\u52A8\uFF09"}},required:["docId","name"]}},ne={name:"pencil_share_document",description:"\u5C06\u8BBE\u8BA1\u753B\u5E03\u5206\u4EAB\u7ED9\u5176\u5B83 Agent \u534F\u4F5C\uFF08\u6BCF\u4F4D\u88AB\u9080\u8BF7\u4EBA\u6307\u5B9A read=\u53EA\u8BFB \u6216 write=\u53EF\u5199\uFF09\u3002\u88AB\u9080\u8BF7\u4EBA\u5FC5\u987B\u5DF2\u5F00\u542F\u300C\u8BBE\u8BA1\u753B\u5E03 (Pencil)\u300D\u80FD\u529B\uFF0C\u5426\u5219\u5206\u4EAB\u4F1A\u88AB\u6574\u4F53\u62D2\u7EDD\u3002\u5206\u4EAB\u540E\u53CC\u65B9\u7EE7\u7EED\u7528 pencil_get_tree / pencil_update_nodes \u7B49\u5DE5\u5177\u534F\u4F5C\uFF1B\u88AB\u9080\u8BF7\u4EBA\u4F1A\u6536\u5230\u9080\u8BF7\u901A\u77E5\u3002\u64A4\u9500\u5206\u4EAB\u914D\u5BF9\u4F7F\u7528 pencil_revoke_share\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u8981\u5206\u4EAB\u7684\u753B\u5E03\u6587\u6863 id\uFF08\u987B\u4E3A\u672C Agent \u521B\u5EFA\u7684\u753B\u5E03\uFF09"},members:{type:"array",description:"\u88AB\u9080\u8BF7\u4EBA\u5217\u8868",items:{type:"object",properties:{agentId:{type:"string",description:"\u88AB\u9080\u8BF7 Agent \u7684\u5B9E\u4F8B id"},permission:{type:"string",enum:["read","write"],description:"\u534F\u4F5C\u6743\u9650\uFF1Aread=\u53EA\u8BFB\u67E5\u770B\uFF0Cwrite=\u53EF\u7F16\u8F91\uFF08\u7F3A\u7701 read\uFF09"}},required:["agentId"]}}},required:["docId","members"]}},re={name:"pencil_revoke_share",description:"\u64A4\u9500\u753B\u5E03\u5206\u4EAB\uFF08\u4EC5\u753B\u5E03\u62E5\u6709\u8005\u53EF\u8C03\u7528\uFF0C\u4E0E pencil_share_document \u914D\u5BF9\u4F7F\u7528\uFF09\u3002agentIds \u7701\u7565\u65F6\u6574\u4F53\u64A4\u9500\uFF0C\u753B\u5E03\u56DE\u5230\u4EC5\u672C Agent \u79C1\u6709\uFF1B\u63D0\u4F9B agentIds \u65F6\u4EC5\u79FB\u9664\u6307\u5B9A\u534F\u4F5C\u8005\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id"},agentIds:{type:"array",items:{type:"string"},description:"\u8981\u79FB\u9664\u7684\u534F\u4F5C\u8005 agentId \u5217\u8868\uFF08\u7701\u7565 = \u6574\u4F53\u64A4\u9500\u5206\u4EAB\uFF09"}},required:["docId"]}},pe={name:"pencil_export_image",description:"\u5BFC\u51FA\u8BBE\u8BA1\u753B\u5E03\u4E3A PNG \u56FE\u7247\u5230\u6587\u4EF6\u5E76\u8FD4\u56DE\u6587\u4EF6\u8DEF\u5F84\u7B49\u5143\u4FE1\u606F\uFF08\u4E0D\u8FD4\u56DE\u56FE\u7247\u5185\u5BB9\uFF0C\u907F\u514D\u5927\u4F53\u79EF base64 \u5360\u7528\u4E0A\u4E0B\u6587\uFF09\u3002\u9700\u8981\u67E5\u770B\u753B\u5E03\u6548\u679C\u65F6\uFF0C\u7528\u6587\u4EF6\u8BFB\u53D6\u5DE5\u5177\u8BFB\u53D6\u8FD4\u56DE\u8DEF\u5F84\u7684 PNG \u5373\u53EF\u3002savePath \u901A\u5E38\u7701\u7565\uFF1A\u81EA\u52A8\u5BFC\u51FA\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\uFF08\u4E34\u65F6\u6587\u4EF6\u53EF\u80FD\u88AB\u7CFB\u7EDF\u6E05\u7406\uFF0C\u4E0D\u8981\u957F\u671F\u5F15\u7528\uFF09\u3002\u4EC5\u5F53\u9700\u8981\u628A\u56FE\u7247\u4F5C\u4E3A\u4EA4\u4ED8\u7269\u4FDD\u5B58\u5230\u6307\u5B9A\u4F4D\u7F6E\u65F6\u624D\u4F20 savePath\u3002\u6E32\u67D3\u56FE\u7531 dashboard \u753B\u5E03\u9762\u677F\u81EA\u52A8\u751F\u6210\u5E76\u7F13\u5B58\uFF08\u753B\u5E03\u539F\u59CB\u5206\u8FA8\u7387\uFF0C\u6700\u957F\u8FB9 \u22648192 \u5185\u4E0D\u7F29\u653E\uFF09\uFF1B\u753B\u5E03\u521A\u88AB\u5DE5\u5177\u4FEE\u6539\u540E\u82E5\u7F13\u5B58\u843D\u540E\uFF0C\u4F1A\u7B49\u5F85\u9762\u677F\u8865\u6E32\uFF08\u7EA6\u6570\u79D2\uFF09\u3002\u753B\u5E03\u4ECE\u672A\u6E32\u67D3\u8FC7\uFF08dashboard \u9762\u677F\u672A\u6253\u5F00\u8FC7\uFF09\u4F1A\u8FD4\u56DE\u5931\u8D25\u5E76\u63D0\u793A\u5148\u6253\u5F00\u9762\u677F\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id\uFF08\u6765\u81EA pencil_create_document / pencil_list_documents\uFF09"},savePath:{type:"string",description:"\u53EF\u9009\uFF1APNG \u4FDD\u5B58\u8DEF\u5F84\uFF0C\u4E0D\u9650\u5236\u4FDD\u5B58\u4F4D\u7F6E\uFF08\u76F8\u5BF9\u8DEF\u5F84\u57FA\u4E8E\u5DE5\u4F5C\u533A\u6839\u89E3\u6790\uFF0C\u7EDD\u5BF9\u8DEF\u5F84\u76F4\u63A5\u4F7F\u7528\uFF09\uFF0C\u5982 design/hero.png \u6216 D:\\exports\\hero.png\u3002\u7701\u7565\u65F6\u5BFC\u51FA\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\u5E76\u8FD4\u56DE\u4E34\u65F6\u8DEF\u5F84"},waitMs:{type:"number",description:"\u53EF\u9009\uFF1A\u7B49\u5F85\u9762\u677F\u8865\u6E32\u7684\u6700\u957F\u6BEB\u79D2\u6570\uFF08\u9ED8\u8BA4 8000\uFF0C\u4E0A\u9650 20000\uFF09"}},required:["docId"]}},oe={name:"pencil_export_document",description:"\u628A\u8BBE\u8BA1\u753B\u5E03\u5BFC\u51FA\u4E3A\u6587\u4EF6\uFF08\u672C\u5730 headless \u5BFC\u51FA\u7BA1\u7EBF\uFF0C\u65E0\u9700\u6253\u5F00\u753B\u5E03\u9762\u677F\uFF09\u3002\u8FD4\u56DE\u5BFC\u51FA\u6587\u4EF6\u8DEF\u5F84\u7B49\u5143\u4FE1\u606F\uFF08\u4E0D\u8FD4\u56DE\u6587\u4EF6\u5185\u5BB9\uFF09\u3002format \u652F\u6301\u591A\u79CD\u6837\u5F0F\uFF1Asvg=\u77E2\u91CF\u56FE\uFF08\u63A8\u8350\uFF0C\u6587\u5B57\u4E3A\u771F\u6587\u672C\uFF09/ html=\u771F\u5B9E DOM+CSS \u7F51\u9875\uFF08standalone \u5355\u6587\u4EF6\uFF0C\u53EF\u76F4\u63A5\u6D4F\u89C8\u5668\u6253\u5F00\uFF09/ png|jpg|webp=\u4F4D\u56FE\uFF08scale \u63A7\u5236\u6E05\u6670\u5EA6\uFF09/ pptx=PowerPoint \u6F14\u793A\u7A3F / fig=Figma \u6587\u6863 / jsx=React \u7EC4\u4EF6\u4EE3\u7801\uFF08\u9700\u4F20 nodeId\uFF09\u3002\u7F3A\u7701\u5BFC\u51FA\u7B2C\u4E00\u9875\u5168\u90E8\u5185\u5BB9\uFF1B\u4F20 nodeId\uFF08\u6765\u81EA pencil_get_tree\uFF09\u53EF\u53EA\u5BFC\u51FA\u5355\u4E2A\u8282\u70B9\u3002",inputSchema:{type:"object",properties:{docId:{type:"string",description:"\u753B\u5E03\u6587\u6863 id\uFF08\u6765\u81EA pencil_create_document / pencil_list_documents\uFF09"},format:{type:"string",enum:["svg","html","png","jpg","webp","pptx","fig","jsx"],description:"\u5BFC\u51FA\u683C\u5F0F\uFF08\u9ED8\u8BA4 svg\uFF09"},nodeId:{type:"string",description:"\u53EF\u9009\uFF1A\u53EA\u5BFC\u51FA\u5355\u4E2A\u8282\u70B9\uFF08jsx \u5FC5\u586B\uFF09\uFF1B\u7701\u7565=\u5BFC\u51FA\u7B2C\u4E00\u9875\u5168\u90E8\u5185\u5BB9"},scale:{type:"number",description:"\u53EF\u9009\uFF1Apng/jpg/webp \u7F29\u653E\u500D\u6570\uFF08\u9ED8\u8BA4 1\uFF09"},quality:{type:"number",description:"\u53EF\u9009\uFF1Ajpg/webp \u8D28\u91CF 0-100\uFF08\u9ED8\u8BA4 90\uFF09"},savePath:{type:"string",description:"\u53EF\u9009\uFF1A\u5BFC\u51FA\u6587\u4EF6\u4FDD\u5B58\u8DEF\u5F84\uFF0C\u4E0D\u9650\u5236\u4FDD\u5B58\u4F4D\u7F6E\uFF08\u76F8\u5BF9\u8DEF\u5F84\u57FA\u4E8E\u5DE5\u4F5C\u533A\u6839\u89E3\u6790\uFF0C\u7EDD\u5BF9\u8DEF\u5F84\u76F4\u63A5\u4F7F\u7528\uFF09\uFF0C\u5982 design/hero.svg \u6216 D:\\exports\\hero.svg\u3002\u7701\u7565\u65F6\u4FDD\u5B58\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\u5E76\u8FD4\u56DE\u4E34\u65F6\u8DEF\u5F84"}},required:["docId"]}},me=new Set(["pencil_create_document","pencil_list_documents","pencil_open_document","pencil_close_document","pencil_get_tree","pencil_get_changes","pencil_create_nodes","pencil_update_nodes","pencil_delete_nodes","pencil_export_image","pencil_share_document","pencil_revoke_share","pencil_delete_document","pencil_rename_document","pencil_export_document"]),ge=[_,m,g,y,u,l,E,I,O,T,h,b,L,S,A,R,N,e,r,o,t,p,n,i,s,c,d,a,D,x,C,M,P,f,j,q,k,U,G,v,w,H,Y,F,K,B,V,J,W,z,X,$,Q,Z,ee,pe,ne,re,te,ie,oe];export{Se as ABANDON_MEMORY_UPDATE_TOOL,w as CREATE_MEETING_TOOL,le as CREATE_MEMORY_TOOL,b as CREATE_TASK_INSTANCE_COMMENT_TOOL,Ee as DELETE_MEMORY_TOOL,Y as END_MEETING_TOOL,A as FINISH_TASK_ROLLBACK_TOOL,_ as GET_COLLEAGUE_TOOL,D as GET_DEBUG_LOG_CONFIG_TOOL,O as GET_DM_HISTORY_TOOL,T as GET_GROUP_HISTORY_TOOL,m as GET_GROUP_ROOMS_TOOL,K as GET_MEETING_INFO_TOOL,Ie as GET_MEMORY_STATS_TOOL,I as GET_MESSAGE_TOOL,g as GET_PROFILE_TOOL,y as HIRE_COLLEAGUE_TOOL,ae as HIRE_TOOL_NAMES,P as LAUNCH_CONFIG_CREATE_TOOL,j as LAUNCH_CONFIG_DELETE_TOOL,M as LAUNCH_CONFIG_LIST_TOOL,G as LAUNCH_CONFIG_LOGS_TOOL,k as LAUNCH_CONFIG_RESTART_TOOL,q as LAUNCH_CONFIG_START_TOOL,v as LAUNCH_CONFIG_STATUS_TOOL,U as LAUNCH_CONFIG_STOP_TOOL,de as LAUNCH_CONFIG_TOOL_NAMES,f as LAUNCH_CONFIG_UPDATE_TOOL,H as LEAVE_MEETING_TOOL,Le as LIST_MEMORIES_BY_FILE_TOOL,Oe as LIST_MEMORIES_TOOL,ge as MCP_TOOLS,F as MEETING_SPEAK_TOOL,_e as MEETING_TOOL_NAMES,Re as MEMORY_RECURRENCE_COMPLETE_TOOL,Ae as MEMORY_RECURRENCE_TOOL,ce as MEMORY_TOOL_NAMES,B as MY_MEETINGS_TOOL,h as MY_TASK_TOOL,z as PENCIL_CLOSE_DOCUMENT_TOOL,V as PENCIL_CREATE_DOCUMENT_TOOL,Q as PENCIL_CREATE_NODES_TOOL,te as PENCIL_DELETE_DOCUMENT_TOOL,ee as PENCIL_DELETE_NODES_TOOL,oe as PENCIL_EXPORT_DOCUMENT_TOOL,pe as PENCIL_EXPORT_IMAGE_TOOL,$ as PENCIL_GET_CHANGES_TOOL,X as PENCIL_GET_TREE_TOOL,J as PENCIL_LIST_DOCUMENTS_TOOL,W as PENCIL_OPEN_DOCUMENT_TOOL,ie as PENCIL_RENAME_DOCUMENT_TOOL,re as PENCIL_REVOKE_SHARE_TOOL,ne as PENCIL_SHARE_DOCUMENT_TOOL,me as PENCIL_TOOL_NAMES,Z as PENCIL_UPDATE_NODES_TOOL,E as POLL_MESSAGE_TOOL,x as QUERY_DEBUG_LOGS_TOOL,C as QUERY_FILE_CHANGES_HISTORY_TOOL,Te as READ_MEMORY_TOOL,R as REJECT_TASK_TOOL,he as SEARCH_MEMORY_TOOL,u as SEND_GROUP_TOOL,l as SEND_PRIVATE_TOOL,S as START_TASK_ROLLBACK_TOOL,L as SUBMIT_TASK_RESULT_TOOL,N as TERMINATE_TASK_TOOL,be as UPDATE_MEMORY_TOOL};
|
|
42
42
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aws-runtime-bridge",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.149",
|
|
4
4
|
"description": "AgentsWorkStudio runtime bridge service for machine-level agent runtime integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"aws-runtime-bridge": "dist/index.js"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
+
"CHANGELOG.md",
|
|
13
14
|
"dist",
|
|
14
15
|
"scripts/ensure-bin-executable.mjs",
|
|
15
16
|
"scripts/ensure-playwright-browser.mjs",
|