aws-runtime-bridge 1.9.169 → 1.9.170

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.
Files changed (82) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/adapter/AcodeSdkAdapter.d.ts +46 -0
  3. package/dist/adapter/AcodeSdkAdapter.js +4 -4
  4. package/dist/adapter/ClaudeSdkAdapter.js +2 -2
  5. package/dist/adapter/types.d.ts +7 -0
  6. package/dist/config.d.ts +6 -0
  7. package/dist/config.js +2 -2
  8. package/dist/index.js +1 -1
  9. package/dist/routes/agent-state.d.ts +2 -0
  10. package/dist/routes/agent-state.js +2 -0
  11. package/dist/routes/capabilities.js +1 -1
  12. package/dist/routes/debug-mount.d.ts +2 -0
  13. package/dist/routes/debug-mount.js +2 -0
  14. package/dist/routes/mcp.js +1 -1
  15. package/dist/routes/plugins.js +1 -1
  16. package/dist/routes/skills.js +1 -1
  17. package/dist/routes/terminal.js +28 -32
  18. package/dist/services/acode-bg-manager.d.ts +2 -0
  19. package/dist/services/agent-capability-sync.js +1 -1
  20. package/dist/services/debug-mount.d.ts +122 -0
  21. package/dist/services/debug-mount.js +2 -0
  22. package/dist/services/desktop-mcp-manager.js +1 -1
  23. package/dist/services/instance-ai-config-service.js +1 -1
  24. package/dist/services/instance-features.d.ts +4 -0
  25. package/dist/services/instance-features.js +1 -1
  26. package/dist/services/instance-init-service.js +1 -1
  27. package/dist/services/mcp-deploy.d.ts +31 -0
  28. package/dist/services/mcp-deploy.js +4 -3
  29. package/dist/services/mcp-env-injector.d.ts +24 -0
  30. package/dist/services/mcp-env-injector.js +1 -1
  31. package/dist/services/mcp-package.d.ts +35 -0
  32. package/dist/services/mcp-package.js +2 -0
  33. package/dist/services/mcp-probe-client.d.ts +25 -0
  34. package/dist/services/mcp-probe-client.js +2 -0
  35. package/dist/services/panel-env.d.ts +5 -0
  36. package/dist/services/panel-env.js +1 -1
  37. package/dist/services/plugin-deployment.d.ts +36 -0
  38. package/dist/services/plugin-deployment.js +3 -0
  39. package/dist/services/plugin-event-buffer.js +2 -1
  40. package/dist/services/plugin-fs.d.ts +5 -0
  41. package/dist/services/plugin-fs.js +2 -0
  42. package/dist/services/plugin-handler-adapter.d.ts +7 -0
  43. package/dist/services/plugin-handler-adapter.js +3 -0
  44. package/dist/services/plugin-listener-runner.d.ts +18 -0
  45. package/dist/services/plugin-listener-runner.js +8 -0
  46. package/dist/services/plugin-loader.d.ts +32 -0
  47. package/dist/services/plugin-loader.js +2 -0
  48. package/dist/services/plugin-manager.d.ts +17 -136
  49. package/dist/services/plugin-manager.js +4 -15
  50. package/dist/services/plugin-manifest.d.ts +83 -0
  51. package/dist/services/plugin-manifest.js +2 -0
  52. package/dist/services/plugin-runtime.d.ts +67 -0
  53. package/dist/services/plugin-runtime.js +1 -0
  54. package/dist/services/skill-manager.d.ts +15 -0
  55. package/dist/services/skill-manager.js +3 -2
  56. package/dist/types.d.ts +6 -0
  57. package/dist/utils/mcp-utils.js +1 -1
  58. package/package/acode/dist/compaction.d.ts +35 -1
  59. package/package/acode/dist/compaction.js +6 -6
  60. package/package/acode/dist/plugin-types.d.ts +6 -27
  61. package/package/acode/dist/runtime.d.ts +37 -0
  62. package/package/acode/dist/runtime.js +31 -30
  63. package/package/acode/dist/tool-group-manager.d.ts +10 -0
  64. package/package/acode/dist/tool-group-manager.js +5 -10
  65. package/package/acode/dist/types.d.ts +2 -0
  66. package/package/aws-client-agent-mcp/dist/ability-market-tools.d.ts +18 -0
  67. package/package/aws-client-agent-mcp/dist/ability-market-tools.js +2 -0
  68. package/package/aws-client-agent-mcp/dist/agent-client.d.ts +13 -4
  69. package/package/aws-client-agent-mcp/dist/agent-client.js +1 -1
  70. package/package/aws-client-agent-mcp/dist/http-client.d.ts +2 -0
  71. package/package/aws-client-agent-mcp/dist/http-client.js +1 -1
  72. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +0 -7
  73. package/package/aws-client-agent-mcp/dist/mcp-server.js +12 -12
  74. package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +1 -0
  75. package/package/aws-client-agent-mcp/dist/mcp-tools.js +20 -20
  76. package/package/aws-client-agent-mcp/dist/memory-store.d.ts +1 -1
  77. package/package/aws-client-agent-mcp/dist/memory-store.js +2 -2
  78. package/package/aws-client-agent-mcp/dist/memory-tools.js +7 -7
  79. package/package/aws-client-agent-mcp/dist/tool-groups.js +2 -2
  80. package/package/aws-client-agent-mcp/dist/types.d.ts +0 -21
  81. package/package.json +3 -2
  82. package/dist/services/builtin-commands/create-plugin.md +0 -44
@@ -15,6 +15,8 @@ export interface ToolGroupRegistration {
15
15
  toolNames?: readonly string[];
16
16
 
17
17
  serverName?: string;
18
+
19
+ pluginName?: string;
18
20
  }
19
21
  export interface ToolGroupManagerOptions {
20
22
 
@@ -26,6 +28,12 @@ export declare const MCP_GROUP_KEY_PREFIX = "mcp:";
26
28
  export declare function mcpGroupKeyOf(serverName: string): string;
27
29
 
28
30
  export declare function isMcpGroupKey(key: string): boolean;
31
+
32
+ export declare const PLUGIN_GROUP_KEY_PREFIX = "plugin:";
33
+
34
+ export declare function pluginGroupKeyOf(pluginName: string): string;
35
+
36
+ export declare function isPluginGroupKey(key: string): boolean;
29
37
  export declare class ToolGroupManager {
30
38
  private groups;
31
39
  private expandedGroups;
@@ -105,6 +113,8 @@ export interface ExpandToolsDeps {
105
113
  }>;
106
114
 
107
115
  capabilityToolRelay?: CapabilityToolRelay;
116
+
117
+ pluginBridge?: ACodePluginBridge;
108
118
  }
109
119
 
110
120
  export declare function createExpandToolsTool(deps: ExpandToolsDeps): ACodeBuiltInTool;
@@ -1,18 +1,13 @@
1
- const b="mcp:";function $(h){return`${b}${h}`}function S(h){return h.startsWith(b)}class N{constructor(e){this.groups=new Map,this.expandedGroups=new Set,this.stateOf=e.stateOf}register(e){this.groups.set(e.key,e)}unregister(e){this.groups.delete(e),this.expandedGroups.delete(e)}getRegistration(e){return this.groups.get(e)}getAllGroups(){return Array.from(this.groups.values())}getConfigState(e){return this.stateOf(e)??"disabled"}isEnabled(e){return this.getConfigState(e)!=="disabled"}isExpanded(e){return this.expandedGroups.has(e)}expand(e){return this.groups.has(e)?this.expandedGroups.has(e)?0:(this.expandedGroups.add(e),1):-1}collapse(e){return this.groups.has(e)?this.expandedGroups.delete(e)?1:0:-1}resetExpanded(){this.expandedGroups.clear()}shouldShowToLLM(e){if(!e)return!0;const o=this.groups.get(e);if(!o)return!0;const s=this.getConfigState(e);return s==="disabled"?!1:s==="collapsed"&&o.collapsible?this.expandedGroups.has(e):!0}getGroupForExposedName(e){const o=e.indexOf("__"),s=o>0?e.slice(0,o):void 0,c=o>=0&&o<e.length-2?e.slice(o+2):void 0,r=()=>[...this.groups].filter(([,t])=>!t.serverName);for(const[t,a]of r())if(!(!a.toolNames||a.toolNames.length===0)){for(const d of a.toolNames)if(e===d||c!==void 0&&c===d)return t}for(const[t,a]of r())if(e.startsWith(`${t}_`)||c!==void 0&&(c.startsWith(`${t}_`)||c===t))return t;if(s){for(const[t,a]of this.groups)if(a.serverName&&a.serverName===s)return t}}findGroupByServerName(e){for(const[o,s]of this.groups)if(s.serverName===e)return o}shouldShowToLLMByName(e){const o=this.getGroupForExposedName(e);return this.shouldShowToLLM(o)}claimedToolNamesBySubGroups(){const e=new Set;for(const o of this.groups.values())if(!o.serverName)for(const s of o.toolNames??[])e.add(s);return e}listToolManifests(e,o){const s=this.groups.get(e);if(!s)return[];if(s.toolNames&&s.toolNames.length>0)return o.filter(r=>{const t=r.exposedName.includes("__")?r.exposedName.slice(r.exposedName.indexOf("__")+2):r.exposedName;return s.toolNames.includes(t)}).map(r=>({name:r.exposedName,description:r.description,inputSchema:r.inputSchema}));const c=`${e}_`;return o.filter(r=>{const t=r.exposedName.includes("__")?r.exposedName.slice(r.exposedName.indexOf("__")+2):r.exposedName;return t===e||t.startsWith(c)}).map(r=>({name:r.exposedName,description:r.description,inputSchema:r.inputSchema}))}buildCapabilityPrompt(){const e=[],o=[],s=[];for(const t of this.groups.values()){const a=this.getConfigState(t.key);a==="disabled"?s.push(t):a==="collapsed"&&t.collapsible?o.push(t):e.push(t)}const c=t=>`- ${t.key}\uFF1A${t.label}${t.summary?` \u2014\u2014 ${t.summary}`:""}`,r=["## \u53EF\u7528\u80FD\u529B",""];if(e.length>0||o.length>0){r.push("\u5DF2\u5F00\u542F\uFF1A");for(const t of e)r.push(`${c(t)}\uFF08\u5DE5\u5177\u5DF2\u53EF\u76F4\u63A5\u8C03\u7528\uFF09`);for(const t of o)r.push(`${c(t)}\uFF08\u5DE5\u5177\u5DF2\u6536\u8D77\uFF09`);o.length>0&&(r.push(""),r.push('\u6807\u8BB0\u300C\u5DE5\u5177\u5DF2\u6536\u8D77\u300D\u7684\u80FD\u529B\uFF1A\u5DE5\u5177\u9ED8\u8BA4\u6536\u8D77\u4EE5\u4FDD\u6301\u5DE5\u5177\u5217\u8868\u7A33\u5B9A\u5E76\u8282\u7701\u4E0A\u4E0B\u6587\uFF0C\u4EFB\u52A1\u9700\u8981\u65F6\u5148\u8C03\u7528 expand_tools({ group: "<\u4E0A\u8FF0\u7EC4 key>" }) \u5C55\u5F00\uFF0C\u5DE5\u5177\u5B9A\u4E49\u968F\u7ED3\u679C\u8FD4\u56DE\u540E\u5373\u53EF\u7ECF call_tool \u8C03\u7528\u3002\u6BCF\u6B21\u53EA\u80FD\u5C55\u5F00\u4E00\u4E2A\u7EC4\u3002group \u53C2\u6570\u5FC5\u987B\u9010\u5B57\u53D6\u81EA\u4E0A\u65B9\u6E05\u5355\u91CC\u7684\u7EC4 key\uFF1B\u6E05\u5355\u5916\u7684 key\uFF08\u5305\u62EC\u6309 mcp:{server\u540D} \u81EA\u884C\u63A8\u6D4B\u62FC\u51FA\u7684\uFF09\u5E76\u4E0D\u5B58\u5728\uFF0Cexpand_tools \u53EA\u4F1A\u8FD4\u56DE\u300C\u672A\u77E5\u5DE5\u5177\u7EC4\u300D\u2014\u2014\u9700\u8981\u6E05\u5355\u5916\u7684\u80FD\u529B\u65F6\u8BF4\u660E\u5B83\u672A\u5F00\u542F\u6216\u4E0D\u53EF\u7528\uFF0C\u4E0D\u8981\u81C6\u9020 key \u91CD\u8BD5\u3002'))}else r.push("\u5F53\u524D\u6CA1\u6709\u5DF2\u5F00\u542F\u7684\u6269\u5C55\u80FD\u529B\u3002");if(s.length>0){r.push(""),r.push("\u672A\u5F00\u542F\uFF08\u5DE5\u5177\u4E0D\u5728\u4F60\u7684\u5217\u8868\u4E2D\uFF09\u3002\u82E5\u4EFB\u52A1\u786E\u5B9E\u9700\u8981\uFF0C\u8BF7\u544A\u77E5\u7528\u6237\u53BB\u300C\u80FD\u529B\u914D\u7F6E\u300D\u4E2D\u5F00\u542F\u5BF9\u5E94\u5F00\u5173\uFF0C\u4E0D\u8981\u81EA\u884C\u5047\u8BBE\u4F60\u6709\u8BE5\u80FD\u529B\uFF1A");for(const t of s)r.push(`${c(t)}\uFF08\u9700\u7528\u6237\u5728\u300C\u80FD\u529B\u914D\u7F6E\u300D\u4E2D\u5F00\u542F\uFF09`)}return r.join(`
2
- `)}registerFromMeta(e,o,s,c){this.groups.has(e)||this.register({key:e,label:o??e,summary:s??"",collapsible:!0})}addToolName(e,o){const s=this.groups.get(e);s&&(s.toolNames&&s.toolNames.includes(o)||(s.toolNames?s.toolNames.push(o):s.toolNames=[o]))}}function k(h){const{toolGroupManager:e,getAllTools:o,capabilityToolRelay:s}=h,c=()=>{const r=[];for(const t of e.getAllGroups())!t.collapsible||e.getConfigState(t.key)!=="collapsed"||r.push(`- ${t.key}\uFF1A${t.label}${t.summary?` \u2014\u2014 ${t.summary}`:""}`);return r.length===0?"":`
1
+ const $="mcp:";function S(d){return`${$}${d}`}function k(d){return d.startsWith($)}const _="plugin:";function b(d){return`${_}${d}`}function N(d){return d.startsWith(_)}class G{constructor(e){this.groups=new Map,this.expandedGroups=new Set,this.stateOf=e.stateOf}register(e){this.groups.set(e.key,e)}unregister(e){this.groups.delete(e),this.expandedGroups.delete(e)}getRegistration(e){return this.groups.get(e)}getAllGroups(){return Array.from(this.groups.values())}getConfigState(e){return this.stateOf(e)??"disabled"}isEnabled(e){return this.getConfigState(e)!=="disabled"}isExpanded(e){return this.expandedGroups.has(e)}expand(e){return this.groups.has(e)?this.expandedGroups.has(e)?0:(this.expandedGroups.add(e),1):-1}collapse(e){return this.groups.has(e)?this.expandedGroups.delete(e)?1:0:-1}resetExpanded(){this.expandedGroups.clear()}shouldShowToLLM(e){if(!e)return!0;const n=this.groups.get(e);if(!n)return!0;const s=this.getConfigState(e);return s==="disabled"?!1:s==="collapsed"&&n.collapsible?this.expandedGroups.has(e):!0}getGroupForExposedName(e){const n=e.indexOf("__"),s=n>0?e.slice(0,n):void 0,p=n>=0&&n<e.length-2?e.slice(n+2):void 0,o=()=>[...this.groups].filter(([,r])=>!r.serverName);for(const[r,t]of o())if(!(!t.toolNames||t.toolNames.length===0)){for(const f of t.toolNames)if(e===f||p!==void 0&&p===f)return r}for(const[r,t]of o())if(e.startsWith(`${r}_`)||p!==void 0&&(p.startsWith(`${r}_`)||p===r))return r;if(s){for(const[r,t]of this.groups)if(t.serverName&&t.serverName===s)return r}}findGroupByServerName(e){for(const[n,s]of this.groups)if(s.serverName===e)return n}shouldShowToLLMByName(e){const n=this.getGroupForExposedName(e);return this.shouldShowToLLM(n)}claimedToolNamesBySubGroups(){const e=new Set;for(const n of this.groups.values())if(!n.serverName)for(const s of n.toolNames??[])e.add(s);return e}listToolManifests(e,n){const s=this.groups.get(e);if(!s)return[];if(s.toolNames&&s.toolNames.length>0)return n.filter(o=>{const r=o.exposedName.includes("__")?o.exposedName.slice(o.exposedName.indexOf("__")+2):o.exposedName;return s.toolNames.includes(r)}).map(o=>({name:o.exposedName,description:o.description,inputSchema:o.inputSchema}));const p=`${e}_`;return n.filter(o=>{const r=o.exposedName.includes("__")?o.exposedName.slice(o.exposedName.indexOf("__")+2):o.exposedName;return r===e||r.startsWith(p)}).map(o=>({name:o.exposedName,description:o.description,inputSchema:o.inputSchema}))}buildCapabilityPrompt(){const e=[],n=[],s=[];for(const r of this.groups.values()){const t=this.getConfigState(r.key);t==="disabled"?s.push(r):t==="collapsed"&&r.collapsible?n.push(r):e.push(r)}const p=r=>`- ${r.key}\uFF1A${r.label}${r.summary?` \u2014\u2014 ${r.summary}`:""}`,o=["## \u53EF\u7528\u80FD\u529B",""];if(e.length>0||n.length>0){o.push("\u5DF2\u5F00\u542F\uFF1A");for(const r of e)o.push(`${p(r)}\uFF08\u5DE5\u5177\u5DF2\u53EF\u76F4\u63A5\u8C03\u7528\uFF09`);for(const r of n)o.push(`${p(r)}\uFF08\u5DE5\u5177\u5DF2\u6536\u8D77\uFF09`);n.length>0&&(o.push(""),o.push('\u6807\u8BB0\u300C\u5DE5\u5177\u5DF2\u6536\u8D77\u300D\u7684\u80FD\u529B\uFF1A\u5DE5\u5177\u9ED8\u8BA4\u6536\u8D77\u4EE5\u4FDD\u6301\u5DE5\u5177\u5217\u8868\u7A33\u5B9A\u5E76\u8282\u7701\u4E0A\u4E0B\u6587\uFF0C\u4EFB\u52A1\u9700\u8981\u65F6\u5148\u8C03\u7528 expand_tools({ group: "<\u4E0A\u8FF0\u7EC4 key>" }) \u5C55\u5F00\uFF0C\u5DE5\u5177\u5B9A\u4E49\u968F\u7ED3\u679C\u8FD4\u56DE\u540E\u5373\u53EF\u7ECF call_tool \u8C03\u7528\u3002\u6BCF\u6B21\u53EA\u80FD\u5C55\u5F00\u4E00\u4E2A\u7EC4\u3002group \u53C2\u6570\u5FC5\u987B\u9010\u5B57\u53D6\u81EA\u4E0A\u65B9\u6E05\u5355\u91CC\u7684\u7EC4 key\uFF1B\u6E05\u5355\u5916\u7684 key\uFF08\u5305\u62EC\u6309 mcp:{server\u540D} \u81EA\u884C\u63A8\u6D4B\u62FC\u51FA\u7684\uFF09\u5E76\u4E0D\u5B58\u5728\uFF0Cexpand_tools \u53EA\u4F1A\u8FD4\u56DE\u300C\u672A\u77E5\u5DE5\u5177\u7EC4\u300D\u2014\u2014\u9700\u8981\u6E05\u5355\u5916\u7684\u80FD\u529B\u65F6\u8BF4\u660E\u5B83\u672A\u5F00\u542F\u6216\u4E0D\u53EF\u7528\uFF0C\u4E0D\u8981\u81C6\u9020 key \u91CD\u8BD5\u3002'))}else o.push("\u5F53\u524D\u6CA1\u6709\u5DF2\u5F00\u542F\u7684\u6269\u5C55\u80FD\u529B\u3002");if(s.length>0){o.push(""),o.push("\u672A\u5F00\u542F\uFF08\u5DE5\u5177\u4E0D\u5728\u4F60\u7684\u5217\u8868\u4E2D\uFF09\u3002\u82E5\u4EFB\u52A1\u786E\u5B9E\u9700\u8981\uFF0C\u8BF7\u544A\u77E5\u7528\u6237\u53BB\u300C\u80FD\u529B\u914D\u7F6E\u300D\u4E2D\u5F00\u542F\u5BF9\u5E94\u5F00\u5173\uFF0C\u4E0D\u8981\u81EA\u884C\u5047\u8BBE\u4F60\u6709\u8BE5\u80FD\u529B\uFF1A");for(const r of s)o.push(`${p(r)}\uFF08\u9700\u7528\u6237\u5728\u300C\u80FD\u529B\u914D\u7F6E\u300D\u4E2D\u5F00\u542F\uFF09`)}return o.join(`
2
+ `)}registerFromMeta(e,n,s,p){this.groups.has(e)||this.register({key:e,label:n??e,summary:s??"",collapsible:!0})}addToolName(e,n){const s=this.groups.get(e);s&&(s.toolNames&&s.toolNames.includes(n)||(s.toolNames?s.toolNames.push(n):s.toolNames=[n]))}}function T(d){const{toolGroupManager:e,getAllTools:n,capabilityToolRelay:s,pluginBridge:p}=d,o=()=>{const r=[];for(const t of e.getAllGroups())!t.collapsible||e.getConfigState(t.key)!=="collapsed"||r.push(`- ${t.key}\uFF1A${t.label}${t.summary?` \u2014\u2014 ${t.summary}`:""}`);return r.length===0?"":`
3
3
 
4
4
  \u5F53\u524D\u53EF\u5C55\u5F00\u7684\u6536\u7EB3\u7EC4\uFF1A
5
5
  `+r.join(`
6
- `)};return{kind:"builtin",toolName:"expand_tools",exposedName:"expand_tools",description:'\u5C55\u5F00/\u6536\u8D77\u6536\u7EB3\u5DE5\u5177\u7EC4\u3002\u6536\u7EB3\u7EC4\u7684\u5DE5\u5177\u9ED8\u8BA4\u4E0D\u51FA\u73B0\u5728\u5DE5\u5177\u5217\u8868\u4E2D\uFF1B\u5C55\u5F00\u540E\u5DE5\u5177\u5B9A\u4E49\u968F\u672C\u5DE5\u5177\u7ED3\u679C\u8FD4\u56DE\uFF0C\u53EF\u7ECF call_tool \u8C03\u7528\u3002\u53C2\u6570\uFF1Agroup \u4E3A\u5177\u4F53\u7EC4 key\uFF08\u5982 pencil\u3001task\u3001mcp:my-server\uFF09\uFF0Caction \u4E3A "expand"\uFF08\u9ED8\u8BA4\uFF09\u6216 "collapse"\u3002\u4E0D\u652F\u6301\u6279\u91CF\u64CD\u4F5C\uFF1A\u6BCF\u6B21\u53EA\u80FD\u6307\u5B9A\u4E00\u4E2A\u7EC4\uFF0C\u591A\u7EC4\u9700\u5206\u6B21\u8C03\u7528\u3002',inputSchema:{type:"object",properties:{group:{type:"string",description:'\u7EC4 key\uFF08\u5982 pencil / task / mcp:my-server\uFF09\u3002\u5FC5\u987B\u6307\u5B9A\u5177\u4F53\u7EC4\uFF0C\u4E0D\u652F\u6301 "all" \u4E4B\u7C7B\u7684\u6279\u91CF\u53D6\u503C\u3002'},action:{type:"string",enum:["expand","collapse"],default:"expand",description:"expand=\u5C55\u5F00\uFF0Ccollapse=\u6536\u8D77"}},required:["group"],additionalProperties:!1},async execute(r){const t=String(r.group??"").trim(),a=String(r.action??"expand").trim();if(!t)return{ok:!1,error:"\u7F3A\u5C11 group \u53C2\u6570",hint:c()};if(a==="collapse"){const g=e.collapse(t);if(g<0)return{ok:!1,error:`\u672A\u77E5\u5DE5\u5177\u7EC4: ${t}`};if(s?.handlesGroup(t))try{await s.collapse(t)}catch{}return g===0?{ok:!0,status:"already-collapsed",group:t}:{ok:!0,status:"collapsed",group:t,hint:"\u5982\u9700\u91CD\u65B0\u4F7F\u7528\uFF0C\u8BF7\u518D\u6B21\u8C03\u7528 expand_tools\u3002"}}const d=e.getRegistration(t);if(!d){const g=c();return{ok:!1,error:`\u672A\u77E5\u5DE5\u5177\u7EC4: ${t}`,hint:g}}if(e.getConfigState(t)==="disabled")return{ok:!1,error:`\u80FD\u529B\u300C${d.label}\u300D\u672A\u5F00\u542F\uFF0C\u8BF7\u5728\u300C\u80FD\u529B\u914D\u7F6E\u300D\u4E2D\u5F00\u542F\u540E\u518D\u5C55\u5F00`};if(s?.handlesGroup(t)){let g;try{g=await s.expand(t)}catch(u){return{ok:!1,error:`\u5C55\u5F00\u300C${d.label}\u300D\u5931\u8D25: ${u instanceof Error?u.message:String(u)}`}}const n=e.expand(t);return{ok:!0,status:n===0?"already-expanded":"expanded",group:t,toolCount:g.length,tools:g,hint:n===0?"\u8BE5\u7EC4\u5DF2\u5728\u5C55\u5F00\u72B6\u6001\uFF0C\u53EF\u76F4\u63A5\u7ECF call_tool \u8C03\u7528\u3002":"\u5DE5\u5177\u5DF2\u5C55\u5F00\uFF0C\u4E0B\u4E00\u6761\u6D88\u606F\u5373\u53EF\u7ECF call_tool \u8C03\u7528\u3002"}}const i=e.expand(t);if(i<0)return{ok:!1,error:`\u672A\u77E5\u5DE5\u5177\u7EC4: ${t}`};const p=e.listToolManifests(t,o());return i===0?{ok:!0,status:"already-expanded",group:t,toolCount:p.length,tools:p,hint:"\u8BE5\u7EC4\u5DF2\u5728\u5C55\u5F00\u72B6\u6001\uFF0C\u53EF\u76F4\u63A5\u7ECF call_tool \u8C03\u7528\u3002"}:{ok:!0,status:"expanded",group:t,toolCount:p.length,tools:p,hint:"\u5DE5\u5177\u5DF2\u5C55\u5F00\uFF0C\u4E0B\u4E00\u6761\u6D88\u606F\u5373\u53EF\u7ECF call_tool \u8C03\u7528\u3002"}}}}function G(h){const{toolGroupManager:e,pluginBridge:o,findTool:s,dispatchTool:c,capabilityToolRelay:r}=h,t=(a,d)=>{if(r?.handlesTool(a))return!1;const f=d??e.getGroupForExposedName(a);return f&&!e.getRegistration(f)?!1:!f||!e.getRegistration(f).collapsible?!0:e.getConfigState(f)==="expanded"};return{kind:"builtin",toolName:"call_tool",exposedName:"call_tool",description:`\u4E2D\u8F6C\u8C03\u7528\u300C\u4E0D\u5728\u4F60\u7684\u5DE5\u5177\u5217\u8868\u4E2D\u300D\u7684\u5DE5\u5177\u3002\u4EC5\u6709\u4E24\u7C7B\u5DE5\u5177\u9700\u8981\u7ECF\u672C\u62A5\u6587\u53D1\u9001\uFF1A
6
+ `)};return{kind:"builtin",toolName:"expand_tools",exposedName:"expand_tools",description:'\u5C55\u5F00/\u6536\u8D77\u6536\u7EB3\u5DE5\u5177\u7EC4\u3002\u6536\u7EB3\u7EC4\u7684\u5DE5\u5177\u9ED8\u8BA4\u4E0D\u51FA\u73B0\u5728\u5DE5\u5177\u5217\u8868\u4E2D\uFF1B\u5C55\u5F00\u540E\u5DE5\u5177\u5B9A\u4E49\u968F\u672C\u5DE5\u5177\u7ED3\u679C\u8FD4\u56DE\uFF0C\u53EF\u7ECF call_tool \u8C03\u7528\u3002\u53C2\u6570\uFF1Agroup \u4E3A\u5177\u4F53\u7EC4 key\uFF08\u5982 pencil\u3001task\u3001mcp:my-server\u3001plugin:wechat-cli\uFF09\uFF0Caction \u4E3A "expand"\uFF08\u9ED8\u8BA4\uFF09\u6216 "collapse"\u3002\u4E0D\u652F\u6301\u6279\u91CF\u64CD\u4F5C\uFF1A\u6BCF\u6B21\u53EA\u80FD\u6307\u5B9A\u4E00\u4E2A\u7EC4\uFF0C\u591A\u7EC4\u9700\u5206\u6B21\u8C03\u7528\u3002',inputSchema:{type:"object",properties:{group:{type:"string",description:'\u7EC4 key\uFF08\u5982 pencil / task / mcp:my-server / plugin:wechat-cli\uFF09\u3002\u5FC5\u987B\u6307\u5B9A\u5177\u4F53\u7EC4\uFF0C\u4E0D\u652F\u6301 "all" \u4E4B\u7C7B\u7684\u6279\u91CF\u53D6\u503C\u3002'},action:{type:"string",enum:["expand","collapse"],default:"expand",description:"expand=\u5C55\u5F00\uFF0Ccollapse=\u6536\u8D77"}},required:["group"],additionalProperties:!1},async execute(r){const t=String(r.group??"").trim(),f=String(r.action??"expand").trim();if(!t)return{ok:!1,error:"\u7F3A\u5C11 group \u53C2\u6570",hint:o()};if(f==="collapse"){const l=e.collapse(t);if(l<0)return{ok:!1,error:`\u672A\u77E5\u5DE5\u5177\u7EC4: ${t}`};if(s?.handlesGroup(t))try{await s.collapse(t)}catch{}return l===0?{ok:!0,status:"already-collapsed",group:t}:{ok:!0,status:"collapsed",group:t,hint:"\u5982\u9700\u91CD\u65B0\u4F7F\u7528\uFF0C\u8BF7\u518D\u6B21\u8C03\u7528 expand_tools\u3002"}}const a=e.getRegistration(t);if(!a){const l=o();return{ok:!1,error:`\u672A\u77E5\u5DE5\u5177\u7EC4: ${t}`,hint:l}}if(e.getConfigState(t)==="disabled")return{ok:!1,error:`\u80FD\u529B\u300C${a.label}\u300D\u672A\u5F00\u542F\uFF0C\u8BF7\u5728\u300C\u80FD\u529B\u914D\u7F6E\u300D\u4E2D\u5F00\u542F\u540E\u518D\u5C55\u5F00`};if(N(t)){if(!p)return{ok:!1,error:"\u63D2\u4EF6\u7CFB\u7EDF\u672A\u542F\u7528"};const l=t.slice(_.length);let h;try{h=await p.getPluginTools(l)}catch(u){return{ok:!1,error:`\u5C55\u5F00\u63D2\u4EF6\u300C${l}\u300D\u5931\u8D25: ${u instanceof Error?u.message:String(u)}`}}const c=h.map(u=>({name:`${u.plugin}.${u.name}`,description:u.description,inputSchema:u.inputSchema})),g=e.expand(t);return{ok:!0,status:g===0?"already-expanded":"expanded",group:t,toolCount:c.length,tools:c,hint:g===0?"\u8BE5\u63D2\u4EF6\u5DF2\u5728\u5C55\u5F00\u72B6\u6001\uFF0C\u53EF\u76F4\u63A5\u7ECF call_tool \u8C03\u7528\u3002":"\u63D2\u4EF6\u5DE5\u5177\u5DF2\u5C55\u5F00\uFF0C\u4E0B\u4E00\u6761\u6D88\u606F\u5373\u53EF\u7ECF call_tool \u8C03\u7528\u3002"}}if(s?.handlesGroup(t)){let l;try{l=await s.expand(t)}catch(c){return{ok:!1,error:`\u5C55\u5F00\u300C${a.label}\u300D\u5931\u8D25: ${c instanceof Error?c.message:String(c)}`}}const h=e.expand(t);return{ok:!0,status:h===0?"already-expanded":"expanded",group:t,toolCount:l.length,tools:l,hint:h===0?"\u8BE5\u7EC4\u5DF2\u5728\u5C55\u5F00\u72B6\u6001\uFF0C\u53EF\u76F4\u63A5\u7ECF call_tool \u8C03\u7528\u3002":"\u5DE5\u5177\u5DF2\u5C55\u5F00\uFF0C\u4E0B\u4E00\u6761\u6D88\u606F\u5373\u53EF\u7ECF call_tool \u8C03\u7528\u3002"}}const x=e.expand(t);if(x<0)return{ok:!1,error:`\u672A\u77E5\u5DE5\u5177\u7EC4: ${t}`};const i=e.listToolManifests(t,n());return x===0?{ok:!0,status:"already-expanded",group:t,toolCount:i.length,tools:i,hint:"\u8BE5\u7EC4\u5DF2\u5728\u5C55\u5F00\u72B6\u6001\uFF0C\u53EF\u76F4\u63A5\u7ECF call_tool \u8C03\u7528\u3002"}:{ok:!0,status:"expanded",group:t,toolCount:i.length,tools:i,hint:"\u5DE5\u5177\u5DF2\u5C55\u5F00\uFF0C\u4E0B\u4E00\u6761\u6D88\u606F\u5373\u53EF\u7ECF call_tool \u8C03\u7528\u3002"}}}}function E(d){const{toolGroupManager:e,pluginBridge:n,findTool:s,dispatchTool:p,capabilityToolRelay:o}=d,r=(t,f)=>{if(o?.handlesTool(t))return!1;const a=f??e.getGroupForExposedName(t);return a&&!e.getRegistration(a)?!1:!a||!e.getRegistration(a).collapsible?!0:e.getConfigState(a)==="expanded"};return{kind:"builtin",toolName:"call_tool",exposedName:"call_tool",description:`\u4E2D\u8F6C\u8C03\u7528\u300C\u4E0D\u5728\u4F60\u7684\u5DE5\u5177\u5217\u8868\u4E2D\u300D\u7684\u5DE5\u5177\u3002\u4EC5\u6709\u4E24\u7C7B\u5DE5\u5177\u9700\u8981\u7ECF\u672C\u62A5\u6587\u53D1\u9001\uFF1A
7
7
  1) \u5DF2\u6536\u7EB3\u7684\u5DE5\u5177\u7EC4\uFF1A\u5148 expand_tools({ group }) \u5C55\u5F00\uFF0C\u518D\u7528 call_tool({ name: "<\u5DE5\u5177\u540D>", arguments: {...} }) \u8C03\u7528\uFF1B
8
- 2) \u63D2\u4EF6\u5DE5\u5177\uFF1Aname \u4E3A"\u63D2\u4EF6\u540D.\u5DE5\u5177\u540D"\u9650\u5B9A\u540D\uFF08\u5982 "wechat-cli.send_msg"\uFF09\u3002
8
+ 2) \u63D2\u4EF6\u5DE5\u5177\uFF1A\u5148 expand_tools({ group: "plugin:\u63D2\u4EF6\u540D" }) \u5C55\u5F00\u8BE5\u63D2\u4EF6\uFF0C\u518D\u7528 call_tool({ name: "\u63D2\u4EF6\u540D.\u5DE5\u5177\u540D", arguments: {...} }) \u8C03\u7528\u3002
9
9
 
10
10
  \u7981\u6B62\u7528\u9014\uFF08\u4F1A\u88AB\u62D2\u7EDD\uFF09\uFF1A\u5BF9\u5DE5\u5177\u5217\u8868\u4E2D**\u5DF2\u7ECF\u80FD\u76F4\u63A5\u8C03\u7528**\u7684\u5DE5\u5177\uFF08poll_message\u3001read_file\u3001browser_*\uFF08\u5C55\u5F00\u6001\u9664\u5916\uFF09\u7B49\uFF09\u8D70 call_tool\u3002\u76F4\u63A5\u8C03\u7528\u66F4\u7701\u4E00\u8F6E\u53C2\u6570\u6821\u9A8C\uFF0C\u4E14\u80FD\u4FDD\u6301\u5E76\u53D1/\u53EA\u8BFB\u8C03\u5EA6\u4E0E\u5DE5\u5177\u8C03\u7528\u7EDF\u8BA1\u7684\u51C6\u786E\u6027\u2014\u2014call_tool \u4E00\u5B9A\u662F\u72EC\u5360\u7684\uFF0C\u4F1A\u628A\u53EA\u8BFB\u5DE5\u5177\u964D\u7EA7\u4E3A\u4E32\u884C\u3002
11
11
 
12
- \u63D2\u4EF6\u5DE5\u5177\u6A21\u5F0F\uFF08\u53EF\u9009\u63D2\u4EF6\uFF09\uFF1A
13
- - action="catalog"\uFF1A\u8FD4\u56DE\u5F53\u524D\u5168\u90E8\u63D2\u4EF6\u76EE\u5F55\uFF08\u7D27\u51D1\uFF09
14
- - action="schema" + tool="\u63D2\u4EF6\u540D.\u5DE5\u5177\u540D"\uFF1A\u8FD4\u56DE\u8BE5\u5DE5\u5177\u7684\u5B8C\u6574 inputSchema
15
- - action="call"\uFF08\u9ED8\u8BA4\uFF09+ name="\u63D2\u4EF6\u540D.\u5DE5\u5177\u540D" + arguments={...}\uFF1A\u8C03\u7528\u63D2\u4EF6\u5DE5\u5177
16
-
17
- \u8BF4\u660E\uFF1A\u53EA\u8C03\u5EA6\u5DF2\u5C55\u5F00\u7684\u6536\u7EB3\u7EC4\u5DE5\u5177\u4E0E\u63D2\u4EF6\u5DE5\u5177\uFF1B\u672A\u5C55\u5F00\u7684\u6536\u7EB3\u7EC4\u88AB\u62D2\u7EDD\u5E76\u5F15\u5BFC\u8C03\u7528 expand_tools\uFF1B\u5DF2\u76F4\u63A5\u53EF\u89C1\u7684\u5DE5\u5177\u88AB\u62D2\u7EDD\u5E76\u5F15\u5BFC\u76F4\u63A5\u8C03\u7528\u3002`,inputSchema:{type:"object",properties:{name:{type:"string",description:"\u5DE5\u5177\u540D\uFF08\u4EC5\u9650\u5DF2\u6536\u7EB3/\u5DF2\u5C55\u5F00\u7684\u5DE5\u5177\u7EC4\u5185\u5DE5\u5177\uFF0C\u5982 pencil_create_document\uFF09\uFF0C\u6216\u63D2\u4EF6\u9650\u5B9A\u540D\uFF08\u5982 wechat-cli.send_msg\uFF09"},arguments:{type:"object",description:"\u5DE5\u5177\u53C2\u6570\uFF08\u5BF9\u8C61\uFF0C\u53EF\u7701\u7565\uFF09"},action:{type:"string",enum:["call","catalog","schema"],default:"call",description:"call=\u8C03\u7528\u5DE5\u5177\uFF1Bcatalog=\u53D6\u63D2\u4EF6\u76EE\u5F55\uFF1Bschema=\u53D6\u63D2\u4EF6\u5DE5\u5177\u5B8C\u6574\u5B9A\u4E49"},tool:{type:"string",description:'action=schema \u65F6\u6307\u5B9A\u63D2\u4EF6\u5DE5\u5177\u9650\u5B9A\u540D\uFF08\u5982 "wechat-cli.send_msg"\uFF09\uFF1B\u4E5F\u652F\u6301 "\u63D2\u4EF6\u540D.*"'}},additionalProperties:!1},async execute(a,d){const f=String(a.action??"call").trim();if(f==="catalog"){if(!o)return{error:"\u63D2\u4EF6\u7CFB\u7EDF\u672A\u542F\u7528"};try{return await o.getCatalog()}catch(n){return{error:`\u63D2\u4EF6\u76EE\u5F55\u67E5\u8BE2\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`}}}if(f==="schema"){if(!o)return{error:"\u63D2\u4EF6\u7CFB\u7EDF\u672A\u542F\u7528"};const n=String(a.tool??"").trim();if(!n)return{error:'\u7F3A\u5C11 tool \u53C2\u6570\uFF08\u9650\u5B9A\u540D "\u63D2\u4EF6\u540D.\u5DE5\u5177\u540D"\uFF09'};try{if(n.endsWith(".*")){const m=n.slice(0,-2),x=await o.getCatalog(),l=x.plugins.find(_=>_.plugin===m);if(!l)return{error:`\u63D2\u4EF6 ${m} \u672A\u5B89\u88C5\u6216\u5DF2\u505C\u7528`,catalog:x.plugins};const y=await Promise.all(l.tools.map(_=>o.getToolSchema(`${m}.${_.name}`)));return{plugin:m,schemas:y.filter(Boolean)}}const u=await o.getToolSchema(n);return u||{error:`\u672A\u77E5\u63D2\u4EF6\u5DE5\u5177: ${n}\uFF08\u53EF\u5148 action=catalog \u67E5\u770B\u76EE\u5F55\uFF09`}}catch(u){return{error:`\u63D2\u4EF6 schema \u67E5\u8BE2\u5931\u8D25: ${u instanceof Error?u.message:String(u)}`}}}const i=String(a.name??"").trim();if(!i)return{error:"\u7F3A\u5C11 name \u53C2\u6570\uFF08\u5DE5\u5177\u540D\u6216\u63D2\u4EF6\u9650\u5B9A\u540D\uFF09"};if(i.includes(".")){if(!o)return{error:"\u63D2\u4EF6\u7CFB\u7EDF\u672A\u542F\u7528"};const n=i.indexOf(".");if(n<=0||n>=i.length-1)return{error:`\u63D2\u4EF6\u9650\u5B9A\u540D\u4E0D\u5408\u6CD5: ${i}\uFF08\u5E94\u4E3A "\u63D2\u4EF6\u540D.\u5DE5\u5177\u540D"\uFF09`};const u=i.slice(0,n),m=i.slice(n+1);if(!m.trim())return{error:`\u63D2\u4EF6\u9650\u5B9A\u540D\u4E0D\u5408\u6CD5: ${i}\uFF08\u7F3A\u5C11\u5DE5\u5177\u540D\uFF09`};const x=a.arguments&&typeof a.arguments=="object"&&!Array.isArray(a.arguments)?a.arguments:{};try{const l=await o.invokeTool(u,m.trim(),x,{toolCallId:d?.toolCallId});if(l.ok)return l.result??{ok:!0};const y={error:l.error??"\u63D2\u4EF6\u5DE5\u5177\u8C03\u7528\u5931\u8D25"};return l.inputSchema!==void 0&&(y.inputSchema=l.inputSchema),typeof l.durationMs=="number"&&(y.durationMs=l.durationMs),y}catch(l){return{error:`\u63D2\u4EF6\u8C03\u7528\u5931\u8D25: ${l instanceof Error?l.message:String(l)}`}}}const p=s(i);if(!p){if(r?.handlesTool(i)){const n=e.getGroupForExposedName(i),u=n?e.getRegistration(n):void 0,m=n?e.getConfigState(n):"disabled";if(!n||!u||m==="disabled")return{error:`\u5DE5\u5177 ${i} \u6240\u5C5E\u7684\u80FD\u529B\u672A\u5F00\u542F\uFF0C\u8BF7\u544A\u77E5\u7528\u6237\u53BB\u300C\u80FD\u529B\u914D\u7F6E\u300D\u4E2D\u5F00\u542F`};if(!e.isExpanded(n))return{error:`\u5DE5\u5177\u96C6\u300C${u.label}\u300D\u5C1A\u672A\u5C55\u5F00\uFF0C\u8BF7\u5148\u8C03\u7528 expand_tools({ group: "${n}" }) \u5C55\u5F00\u540E\u518D\u8C03\u7528`,group:n};const x=a.arguments&&typeof a.arguments=="object"&&!Array.isArray(a.arguments)?a.arguments:{};try{const l=await r.call(i,x);return l.ok?l.result??{ok:!0}:{error:l.error??`\u8C03\u7528\u5DE5\u5177 ${i} \u5931\u8D25`}}catch(l){return{error:`\u8C03\u7528\u5DE5\u5177 ${i} \u5931\u8D25: ${l instanceof Error?l.message:String(l)}`}}}return{error:`\u672A\u77E5\u5DE5\u5177: ${i}\uFF08\u5DE5\u5177\u4E0D\u5728\u5F53\u524D\u4F1A\u8BDD\u7684\u5DE5\u5177\u5217\u8868\u4E2D\uFF09\u3002\u82E5\u5C5E\u4E8E\u5DF2\u5C55\u5F00\u7684\u6536\u7EB3\u7EC4\uFF0C\u68C0\u67E5\u5DE5\u5177\u540D\u662F\u5426\u6B63\u786E\u3002`}}if(t(i,p.group))return{error:`\u5DE5\u5177 ${i} \u672C\u5C31\u5728\u4F60\u7684\u5DE5\u5177\u5217\u8868\u4E2D\uFF0C\u53EF\u76F4\u63A5\u8C03\u7528\uFF0C\u65E0\u9700\u7ECF call_tool \u4E2D\u8F6C\u3002call_tool \u4EC5\u7528\u4E8E\uFF1A\u2460 expand_tools \u5C55\u5F00\u540E\u7684\u6536\u7EB3\u7EC4\u5DE5\u5177\uFF1B\u2461 \u63D2\u4EF6\u5DE5\u5177\uFF08"\u63D2\u4EF6\u540D.\u5DE5\u5177\u540D"\uFF09\u3002`};if(p.group){const n=e.getRegistration(p.group);if(n&&n.collapsible){const u=e.getConfigState(p.group);if(u==="disabled")return{error:`\u5DE5\u5177 ${i} \u6240\u5C5E\u7684\u80FD\u529B\u300C${n.label}\u300D\u672A\u5F00\u542F\uFF0C\u8BF7\u544A\u77E5\u7528\u6237\u53BB\u300C\u80FD\u529B\u914D\u7F6E\u300D\u4E2D\u5F00\u542F`};if(u==="collapsed"&&!e.isExpanded(p.group))return{error:`\u5DE5\u5177\u96C6\u300C${n.label}\u300D\u5C1A\u672A\u5C55\u5F00\uFF0C\u8BF7\u5148\u8C03\u7528 expand_tools({ group: "${p.group}" }) \u5C55\u5F00\u540E\u518D\u8C03\u7528`,group:p.group}}}const g=a.arguments&&typeof a.arguments=="object"&&!Array.isArray(a.arguments)?a.arguments:{};try{return await c(i,g,{toolCallId:d?.toolCallId})}catch(n){return{error:`\u8C03\u7528\u5DE5\u5177 ${i} \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`}}}}}export{b as MCP_GROUP_KEY_PREFIX,N as ToolGroupManager,G as createCallToolTool,k as createExpandToolsTool,S as isMcpGroupKey,$ as mcpGroupKeyOf};
12
+ \u8BF4\u660E\uFF1A\u53EA\u8C03\u5EA6\u5DF2\u5C55\u5F00\u7684\u6536\u7EB3\u7EC4\u5DE5\u5177\u4E0E\u63D2\u4EF6\u5DE5\u5177\uFF1B\u672A\u5C55\u5F00\u7684\u6536\u7EB3\u7EC4/\u63D2\u4EF6\u88AB\u62D2\u7EDD\u5E76\u5F15\u5BFC\u8C03\u7528 expand_tools\uFF1B\u5DF2\u76F4\u63A5\u53EF\u89C1\u7684\u5DE5\u5177\u88AB\u62D2\u7EDD\u5E76\u5F15\u5BFC\u76F4\u63A5\u8C03\u7528\u3002`,inputSchema:{type:"object",properties:{name:{type:"string",description:"\u5DE5\u5177\u540D\uFF08\u4EC5\u9650\u5DF2\u5C55\u5F00\u7684\u5DE5\u5177\u7EC4\u5185\u5DE5\u5177\uFF0C\u5982 pencil_create_document\uFF09\uFF0C\u6216\u63D2\u4EF6\u9650\u5B9A\u540D\uFF08\u5148\u5C55\u5F00 plugin:\u63D2\u4EF6\u540D\uFF0C\u5982 wechat-cli.send_msg\uFF09"},arguments:{type:"object",description:"\u5DE5\u5177\u53C2\u6570\uFF08\u5BF9\u8C61\uFF0C\u53EF\u7701\u7565\uFF09"}},additionalProperties:!1},async execute(t,f){const a=String(t.name??"").trim();if(!a)return{error:"\u7F3A\u5C11 name \u53C2\u6570\uFF08\u5DE5\u5177\u540D\u6216\u63D2\u4EF6\u9650\u5B9A\u540D\uFF09"};if(a.includes(".")){if(!n)return{error:"\u63D2\u4EF6\u7CFB\u7EDF\u672A\u542F\u7528"};const i=a.indexOf(".");if(i<=0||i>=a.length-1)return{error:`\u63D2\u4EF6\u9650\u5B9A\u540D\u4E0D\u5408\u6CD5: ${a}\uFF08\u5E94\u4E3A "\u63D2\u4EF6\u540D.\u5DE5\u5177\u540D"\uFF09`};const l=a.slice(0,i),h=a.slice(i+1);if(!h.trim())return{error:`\u63D2\u4EF6\u9650\u5B9A\u540D\u4E0D\u5408\u6CD5: ${a}\uFF08\u7F3A\u5C11\u5DE5\u5177\u540D\uFF09`};const c=b(l);if(e.getRegistration(c)&&!e.isExpanded(c))return{error:`\u63D2\u4EF6\u300C${l}\u300D\u5C1A\u672A\u5C55\u5F00\uFF0C\u8BF7\u5148\u8C03\u7528 expand_tools({ group: "${c}" }) \u5C55\u5F00\u540E\u518D\u8C03\u7528`,group:c};const g=t.arguments&&typeof t.arguments=="object"&&!Array.isArray(t.arguments)?t.arguments:{};try{const u=await n.invokeTool(l,h.trim(),g,{toolCallId:f?.toolCallId});if(u.ok)return u.result??{ok:!0};const y={error:u.error??"\u63D2\u4EF6\u5DE5\u5177\u8C03\u7528\u5931\u8D25"};return u.inputSchema!==void 0&&(y.inputSchema=u.inputSchema),typeof u.durationMs=="number"&&(y.durationMs=u.durationMs),y}catch(u){return{error:`\u63D2\u4EF6\u8C03\u7528\u5931\u8D25: ${u instanceof Error?u.message:String(u)}`}}}const m=s(a);if(!m){if(o?.handlesTool(a)){const i=e.getGroupForExposedName(a),l=i?e.getRegistration(i):void 0,h=i?e.getConfigState(i):"disabled";if(!i||!l||h==="disabled")return{error:`\u5DE5\u5177 ${a} \u6240\u5C5E\u7684\u80FD\u529B\u672A\u5F00\u542F\uFF0C\u8BF7\u544A\u77E5\u7528\u6237\u53BB\u300C\u80FD\u529B\u914D\u7F6E\u300D\u4E2D\u5F00\u542F`};if(!e.isExpanded(i))return{error:`\u5DE5\u5177\u96C6\u300C${l.label}\u300D\u5C1A\u672A\u5C55\u5F00\uFF0C\u8BF7\u5148\u8C03\u7528 expand_tools({ group: "${i}" }) \u5C55\u5F00\u540E\u518D\u8C03\u7528`,group:i};const c=t.arguments&&typeof t.arguments=="object"&&!Array.isArray(t.arguments)?t.arguments:{};try{const g=await o.call(a,c);return g.ok?g.result??{ok:!0}:{error:g.error??`\u8C03\u7528\u5DE5\u5177 ${a} \u5931\u8D25`}}catch(g){return{error:`\u8C03\u7528\u5DE5\u5177 ${a} \u5931\u8D25: ${g instanceof Error?g.message:String(g)}`}}}return{error:`\u672A\u77E5\u5DE5\u5177: ${a}\uFF08\u5DE5\u5177\u4E0D\u5728\u5F53\u524D\u4F1A\u8BDD\u7684\u5DE5\u5177\u5217\u8868\u4E2D\uFF09\u3002\u82E5\u5C5E\u4E8E\u5DF2\u5C55\u5F00\u7684\u6536\u7EB3\u7EC4\uFF0C\u68C0\u67E5\u5DE5\u5177\u540D\u662F\u5426\u6B63\u786E\u3002`}}if(r(a,m.group))return{error:`\u5DE5\u5177 ${a} \u672C\u5C31\u5728\u4F60\u7684\u5DE5\u5177\u5217\u8868\u4E2D\uFF0C\u53EF\u76F4\u63A5\u8C03\u7528\uFF0C\u65E0\u9700\u7ECF call_tool \u4E2D\u8F6C\u3002call_tool \u4EC5\u7528\u4E8E\uFF1A\u2460 expand_tools \u5C55\u5F00\u540E\u7684\u6536\u7EB3\u7EC4\u5DE5\u5177\uFF1B\u2461 \u63D2\u4EF6\u5DE5\u5177\uFF08"\u63D2\u4EF6\u540D.\u5DE5\u5177\u540D"\uFF09\u3002`};if(m.group){const i=e.getRegistration(m.group);if(i&&i.collapsible){const l=e.getConfigState(m.group);if(l==="disabled")return{error:`\u5DE5\u5177 ${a} \u6240\u5C5E\u7684\u80FD\u529B\u300C${i.label}\u300D\u672A\u5F00\u542F\uFF0C\u8BF7\u544A\u77E5\u7528\u6237\u53BB\u300C\u80FD\u529B\u914D\u7F6E\u300D\u4E2D\u5F00\u542F`};if(l==="collapsed"&&!e.isExpanded(m.group))return{error:`\u5DE5\u5177\u96C6\u300C${i.label}\u300D\u5C1A\u672A\u5C55\u5F00\uFF0C\u8BF7\u5148\u8C03\u7528 expand_tools({ group: "${m.group}" }) \u5C55\u5F00\u540E\u518D\u8C03\u7528`,group:m.group}}}const x=t.arguments&&typeof t.arguments=="object"&&!Array.isArray(t.arguments)?t.arguments:{};try{return await p(a,x,{toolCallId:f?.toolCallId})}catch(i){return{error:`\u8C03\u7528\u5DE5\u5177 ${a} \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`}}}}}export{$ as MCP_GROUP_KEY_PREFIX,_ as PLUGIN_GROUP_KEY_PREFIX,G as ToolGroupManager,E as createCallToolTool,T as createExpandToolsTool,k as isMcpGroupKey,N as isPluginGroupKey,S as mcpGroupKeyOf,b as pluginGroupKeyOf};
18
13
 
@@ -15,6 +15,8 @@ export interface ACodeMcpServerSpec {
15
15
  collapsed?: boolean;
16
16
 
17
17
  description?: string;
18
+
19
+ debugStderr?: boolean;
18
20
  [key: string]: unknown;
19
21
  }
20
22
  export interface ACodeConfigFile {
@@ -0,0 +1,18 @@
1
+
2
+ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
3
+
4
+ export declare const LIST_ABILITY_MARKET_TOOL: Tool;
5
+
6
+ export declare const INSTALL_ABILITY_MARKET_ITEM_TOOL: Tool;
7
+
8
+ export declare const UNINSTALL_ABILITY_MARKET_ITEM_TOOL: Tool;
9
+
10
+ export declare const ABILITY_MARKET_TOOL_NAMES: ReadonlySet<string>;
11
+
12
+ export declare const ABILITY_DEV_TOOL_NAMES: ReadonlySet<string>;
13
+
14
+ export declare const ABILITY_DEV_IDE_TOOL: Tool;
15
+
16
+ export declare const FORMAL_ABILITY_TOOL: Tool;
17
+
18
+ export declare const LIST_MY_ABILITIES_TOOL: Tool;
@@ -0,0 +1,2 @@
1
+ const e={name:"list_ability_market",description:"\u6D4F\u89C8\u80FD\u529B\u5E02\u573A\uFF08\u5BF9\u5F53\u524D\u8EAB\u4EFD\u53EF\u89C1\u7684 system + \u672C\u79DF\u6237\u6A21\u677F\uFF09\u3002\u8FD4\u56DE\u7D27\u51D1\u76EE\u5F55\uFF1Akind/name/displayName/description/transport/packageFileName/visibility/envSchema/installed\u3002envSchema \u5217\u51FA\u8BE5\u5236\u54C1\u53EF\u914D\u7F6E\u7684\u73AF\u5883\u53D8\u91CF\uFF08key/required/sensitive/description/example\uFF09\uFF0CMCP \u901A\u5E38\u9700\u8981\u5728\u5B89\u88C5\u65F6\u914D\u7F6E\uFF08API Key\u3001\u5165\u53E3\u8DEF\u5F84\u7B49\uFF09\u3002\u627E\u5230\u76EE\u6807\u540E\u7528 install_ability_market_item \u5B89\u88C5\uFF0C\u5E76\u628A envSchema \u4E2D\u7684\u53D6\u503C\u901A\u8FC7 env \u53C2\u6570\u4F20\u5165\uFF1B\u654F\u611F\u9879\uFF08sensitive=true\uFF09\u5982\u5BC6\u7801/API Key \u5FC5\u987B\u7531\u7528\u6237\u63D0\u4F9B\uFF0C\u5207\u52FF\u81EA\u884C\u731C\u6D4B\u6216\u4ECE\u5176\u5B83\u6765\u6E90\u63A8\u65AD\u3002",inputSchema:{type:"object",properties:{kind:{type:"string",enum:["mcp","skill","plugin"],description:"\u53EF\u9009\uFF1A\u6309\u5E02\u573A\u5236\u54C1\u7C7B\u578B\u8FC7\u6EE4"},keyword:{type:"string",description:"\u53EF\u9009\uFF1A\u6309\u540D\u79F0/\u5C55\u793A\u540D/\u8BF4\u660E\u6A21\u7CCA\u8FC7\u6EE4"},limit:{type:"number",description:"\u53EF\u9009\uFF1A\u8FD4\u56DE\u6761\u6570\u4E0A\u9650\uFF08\u9ED8\u8BA4 20\uFF0C\u6700\u5927 100\uFF09"}},required:[]}},i={name:"install_ability_market_item",description:"\u628A\u5E02\u573A\u4E2D\u7684 MCP\u3001Skill \u6216 Plugin \u5B89\u88C5\u5230\u6307\u5B9A\u843D\u70B9\uFF08scope\uFF09\uFF1Ainstance\uFF08\u4EC5\u5728\u663E\u5F0F\u6307\u5B9A\u65F6\u4F7F\u7528\uFF09= \u4F60\u81EA\u5DF1\u6240\u5728\u7684\u89D2\u8272\u5B9E\u4F8B\uFF0C\u5199\u5165\u7528\u6237\u5B9E\u4F8B\u6A21\u677F\u5E76\u521D\u59CB\u5316\u6240\u5728 bridge\uFF0C\u7ACB\u5373\u751F\u6548\uFF1Bglobal = \u53EA\u767B\u8BB0\u5230\u4F60\u7684\u300C\u5168\u5C40\u914D\u7F6E\u6A21\u677F\u300D\uFF08\u5B9E\u4F8B\u6A21\u677F\u76EE\u5F55\uFF09\uFF0C\u9ED8\u8BA4\u4E0D\u53C2\u4E0E\u5B9E\u4F8B\u521D\u59CB\u5316\uFF0C\u9700\u7528\u6237\u5728\u300C\u5168\u5C40\u914D\u7F6E \u2192 \u5B9E\u4F8B\u6A21\u677F\u300D\u5F00\u542F\u8BE5\u9879\u5F00\u5173\u540E\u624D\u968F\u521D\u59CB\u5316\u4E0B\u53D1\uFF08\u9002\u5408\u5148\u5728\u6A21\u677F\u4E2D\u96C6\u4E2D\u7BA1\u7406\u3001\u7A0D\u540E\u7EDF\u4E00\u542F\u7528\uFF09\uFF1Bprivate = \u4EC5\u5B89\u88C5\u5230\u4F60\u81EA\u5DF1\u6240\u5728\u7684\u89D2\u8272\u5B9E\u4F8B\uFF08per-agent \u79C1\u6709\uFF09\uFF0C\u4E0D\u6539\u5171\u4EAB\u5B9E\u4F8B\u6A21\u677F\uFF0C\u5176\u5B83\u89D2\u8272\u5B9E\u4F8B\u4E0D\u53EF\u89C1\uFF08\u9002\u5408\u81EA\u7814\u5236\u54C1\u300C\u53EA\u7ED9\u81EA\u5DF1\u7528\u300D\uFF09\u3002scope=instance \u65F6\u540C\u65F6\u5199\u5165\u5B9E\u4F8B\u80FD\u529B\u8986\u76D6\uFF0C\u5931\u8D25\u4F1A\u56DE\u6EDA\u6A21\u677F\u3001\u80FD\u529B\u548C bridge \u521D\u59CB\u5316\u3002env \u7528\u4E8E\u914D\u7F6E\u73AF\u5883\u53D8\u91CF\uFF08\u8303\u56F4=\u5F53\u524D\u5B9E\u4F8B\uFF09\uFF1A\u53EA\u9700\u63D0\u4F9B list_ability_market \u8FD4\u56DE\u7684 envSchema \u4E2D\u7684\u952E\uFF0C\u53D6\u503C\u5FC5\u987B\u7531\u7528\u6237\u63D0\u4F9B\uFF08\u5C24\u5176\u662F sensitive \u9879\uFF09\uFF0C\u4E0D\u8981\u4ECE\u5176\u5B83\u6765\u6E90\u63A8\u65AD\u6216\u590D\u7528\uFF1B\u91CD\u590D\u5B89\u88C5\u540C\u4E00\u5236\u54C1\u5373\u66F4\u65B0\u5176 env\u3002\u6210\u529F\u540E\u8FD4\u56DE templateConfig\u3001\u751F\u6548\u72B6\u6001\u3001\u53EF\u7528\u5DE5\u5177\u53CA\u8C03\u7528\u65B9\u5F0F\uFF1BMCP \u9ED8\u8BA4\u6536\u7EB3\uFF0C\u9700\u7ECF expand_tools \u5C55\u5F00\u540E\u7528 call_tool \u8C03\u7528\u3002\u6210\u529F\u72B6\u6001\u4E3A bridge-initialized\uFF0C\u8868\u793A\u6A21\u677F\u521D\u59CB\u5316\u4E0E\u80FD\u529B\u540C\u6B65\u5DF2\u5B8C\u6210\uFF0C\u53EF\u76F4\u63A5\u5C1D\u8BD5\u8C03\u7528\uFF1B\u4E0D\u8981\u5728\u540C\u4E00\u4F1A\u8BDD\u5185\u53CD\u590D\u91CD\u8BD5\u3002\u82E5\u6A21\u677F\u58F0\u660E\u4E86\u5FC5\u586B\u73AF\u5883\u53D8\u91CF\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5148\u4ECE\u7528\u6237\u5904\u53D6\u5F97\u8FD9\u4E9B\u503C\uFF08\u7F3A\u53C2\u65F6\u5DE5\u5177\u4F1A\u8FD4\u56DE errorCode=MCP_ENV_REQUIRED \u4E0E\u7F3A\u5931\u952E\u540D\uFF09\u3002",inputSchema:{type:"object",properties:{template:{type:"string",description:"\u5E02\u573A\u9879 id \u6216 name\uFF08list_ability_market \u8FD4\u56DE\u503C\u4E2D\u7684 name \u5B57\u6BB5\uFF09"},kind:{type:"string",enum:["mcp","skill","plugin"],description:"\u53EF\u9009\uFF1A\u5E02\u573A\u5236\u54C1\u7C7B\u578B\uFF0C\u7528\u4E8E\u540C\u540D\u9879\u6D88\u6B67"},scope:{type:"string",enum:["instance","global","private"],description:"\u53EF\u9009\uFF1A\u5B89\u88C5\u843D\u70B9\u3002instance = \u5F53\u524D\u6240\u5728\u89D2\u8272\u5B9E\u4F8B\uFF08\u7ACB\u5373\u751F\u6548\uFF09\uFF1Bglobal = \u53EA\u767B\u8BB0\u5230\u5168\u5C40\u914D\u7F6E\u6A21\u677F\uFF0C\u9ED8\u8BA4\u4E0D\u53C2\u4E0E\u5B9E\u4F8B\u521D\u59CB\u5316\uFF08\u5F85\u7528\u6237\u5728\u300C\u5168\u5C40\u914D\u7F6E \u2192 \u5B9E\u4F8B\u6A21\u677F\u300D\u5F00\u542F\u5F00\u5173\u540E\u751F\u6548\uFF09\uFF1Bprivate = \u4EC5\u5B89\u88C5\u5230\u5F53\u524D\u5B9E\u4F8B\uFF08per-agent \u79C1\u6709\uFF09\uFF0C\u4E0D\u6539\u5171\u4EAB\u5B9E\u4F8B\u6A21\u677F\u3001\u5176\u5B83\u5B9E\u4F8B\u4E0D\u53EF\u89C1\u3002"},env:{type:"object",description:"\u73AF\u5883\u53D8\u91CF\u53D6\u503C { KEY: value }\uFF0C\u8303\u56F4=\u5F53\u524D\u5B9E\u4F8B\u3002\u4EC5\u9700\u63D0\u4F9B envSchema \u4E2D\u7684\u952E\uFF1B\u4EC5 MCP \u4F7F\u7528\uFF1B\u654F\u611F\u503C\u7531\u7528\u6237\u63D0\u4F9B\uFF0C\u4E0D\u8981\u4ECE\u5176\u5B83\u6765\u6E90\u63A8\u65AD\u6216\u590D\u7528\u3002",additionalProperties:{type:"string"}},collapsed:{type:"boolean",description:"\u53EF\u9009\uFF1A\u4EC5 MCP\uFF0C\u662F\u5426\u6536\u7EB3\uFF08\u9ED8\u8BA4\u53D6\u6A21\u677F\u8BBE\u7F6E\uFF0C\u901A\u5E38\u4E3A true\uFF09\u3002true=\u5DE5\u5177\u9ED8\u8BA4\u9690\u85CF\uFF0C\u9700 expand_tools \u5C55\u5F00"}},required:["template"]}},t={name:"uninstall_ability_market_item",description:"\u4ECE\u300C\u4F60\u81EA\u5DF1\u6240\u5728\u7684\u89D2\u8272\u5B9E\u4F8B\u300D\u5378\u8F7D\u6307\u5B9A\u5E02\u573A\u9879\uFF1A\u4ECE\u7528\u6237\u5B9E\u4F8B\u6A21\u677F\u79FB\u9664\u914D\u7F6E\u3001\u6E05\u5B9E\u4F8B\u80FD\u529B\u8986\u76D6\u5E76\u91CD\u65B0\u521D\u59CB\u5316 bridge\u3002\u4E0D\u5F71\u54CD\u5E02\u573A\u9879\u672C\u8EAB\u6216\u540C bridge \u4E0A\u5176\u5B83\u5B9E\u4F8B\uFF1B\u6210\u529F\u540E\u8FD0\u884C\u4E2D\u5B9E\u4F8B\u7ACB\u5373\u505C\u6B62\u52A0\u8F7D\u8BE5\u9879\u3002\u5185\u7F6E\u901A\u8BAF MCP\uFF08agents-work-studio\u3001aws-mcp\u3001aws-mcp-dev\uFF09\u4E0D\u53EF\u5378\u8F7D\u3002",inputSchema:{type:"object",properties:{template:{type:"string",description:"\u5E02\u573A\u9879 id \u6216 name"},kind:{type:"string",enum:["mcp","skill","plugin"],description:"\u5E02\u573A\u5236\u54C1\u7C7B\u578B"}},required:["template","kind"]}},n=new Set(["list_ability_market","install_ability_market_item","uninstall_ability_market_item"]),p=new Set(["ability_dev_ide","formal_ability","list_my_abilities"]),l={name:"ability_dev_ide",description:"\u80FD\u529B\u5F00\u53D1 IDE\u2014\u2014\u81EA\u7814 MCP / \u63D2\u4EF6 / Skill \u7684\u7EDF\u4E00\u5165\u53E3\u3002action\uFF1Aguide=\u8BFB\u53D6\u5185\u7F6E\u5F00\u53D1\u6307\u5357\u539F\u6587\uFF08Markdown\uFF0C\u53EA\u8BFB\uFF1Bkind=plugin|mcp|skill\uFF0C\u7F3A\u7701 plugin\uFF09\uFF0C\u7F16\u5199/\u6539\u9020\u524D\u5148\u53D6\u6743\u5A01\u89C4\u8303\uFF08\u76EE\u5F55\u7ED3\u6784\u3001\u6E05\u5355\u5B57\u6BB5\u3001stdio \u534F\u8BAE\u7EA6\u5B9A\u3001\u5DE5\u5177\u4E0E\u76D1\u542C\u5668\u58F0\u660E\u3001\u6253\u5305\u4E0E\u5B89\u88C5\uFF09\uFF0C\u4E0D\u8981\u51ED\u8BB0\u5FC6\u731C\u6D4B\u6E05\u5355\u683C\u5F0F\u6216\u534F\u8BAE\u5E27\u683C\u5F0F\uFF1Bmount=\u628A\u5DE5\u4F5C\u533A\u5185\u6B63\u5728\u5F00\u53D1\u7684 MCP/\u63D2\u4EF6\u4E34\u65F6\u6302\u5230\u5F53\u524D\u4F1A\u8BDD\u8BD5\u7528\uFF08kind=mcp \u65F6 path \u6307\u5411\u5DE5\u4F5C\u533A\u5185 mcp.json \u6587\u4EF6\u6216\u5176\u5305\u76EE\u5F55\uFF1Bkind=plugin \u65F6 path \u6307\u5411\u542B plugin.json \u7684\u63D2\u4EF6\u76EE\u5F55\uFF1B\u6302\u8F7D\u540E\u6587\u4EF6\u53D8\u66F4\u81EA\u52A8\u91CD\u8F7D\uFF0C\u6539\u4EE3\u7801\u540E\u53EF\u91CD\u65B0 mount \u540C\u4E00\u8DEF\u5F84\u751F\u6548\uFF09\uFF1Bunmount=\u6458\u9664\u4E00\u4E2A\u6302\u8F7D\u9879\uFF08kind+name\uFF09\uFF1Blist=\u67E5\u770B\u5F53\u524D\u6302\u8F7D\u9879\uFF0C\u6BCF\u9879\u542B name/path/mounted/toolCount/tools/error\uFF08mounted=false \u8868\u793A\u672A\u6210\u529F\u6302\u8F7D\uFF0Cerror \u4E3A\u5931\u8D25\u539F\u56E0\uFF1BMCP \u5DE5\u5177\u540D\u5F62\u5982 <server>__<tool>\uFF0C\u53EF\u7528 call_tool \u8C03\u7528\uFF09\uFF1Blogs=\u8BFB\u53D6\u67D0\u6302\u8F7D\u9879\u6700\u8FD1\u8FD0\u884C\u65E5\u5FD7\uFF08kind+name\uFF0C\u53EF\u9009 tail\uFF1BMCP \u4E3A\u5B50\u8FDB\u7A0B stderr \u73AF\u5F62\u7F13\u51B2\uFF0C\u63D2\u4EF6\u4E3A\u8FD0\u884C\u65E5\u5FD7\uFF09\uFF0C\u7528\u4E8E\u6392\u67E5\u300C\u6302\u8F7D\u540E\u6CA1\u6709\u5DE5\u5177 / \u8C03\u7528\u62A5\u9519 / \u5B50\u8FDB\u7A0B\u5361\u6B7B\u300D\u3002mount/unmount/logs \u7684 path/name \u5FC5\u987B\u4F4D\u4E8E\u4F60\u81EA\u5DF1\u7684\u4F1A\u8BDD\u5DE5\u4F5C\u533A\u5185\uFF0C\u8C03\u8BD5\u6302\u8F7D\u4E0D\u6301\u4E45\u5316\uFF08bridge \u91CD\u542F\u5373\u5931\u6548\uFF09\uFF1BSkill \u65E0\u8C03\u8BD5\u6001\uFF0C\u8BFB\u89C4\u8303\u540E\u76F4\u63A5\u7528 formal_ability \u6216 install_ability_market_item\u3002\u6CE8\u610F\uFF1A\u6302\u8F7D\u5931\u8D25\u4E0D\u4F1A\u51FA\u73B0\u5728 list \u4E2D\uFF08mount \u54CD\u5E94\u76F4\u63A5\u8FD4\u56DE mounted=false \u4E0E error\uFF09\uFF0C\u67E5\u4E0D\u5230\u4E0D\u4EE3\u8868\u6CA1\u5C1D\u8BD5\u8FC7\u3002",inputSchema:{type:"object",properties:{action:{type:"string",enum:["guide","mount","unmount","list","logs"],description:"\u5F00\u53D1\u52A8\u4F5C"},kind:{type:"string",enum:["plugin","mcp","skill"],description:"guide\uFF1A\u89C4\u8303\u7C7B\u578B\uFF08plugin|mcp|skill\uFF0C\u7F3A\u7701 plugin\uFF09\uFF1Bmount/unmount/logs\uFF1A\u5236\u54C1\u7C7B\u578B\uFF08\u4EC5 mcp|plugin\uFF0C\u5FC5\u586B\uFF09\uFF1Blist\uFF1A\u53EF\u9009\u8FC7\u6EE4\uFF08\u7F3A\u7701\u5217\u51FA\u5168\u90E8\uFF09"},path:{type:"string",description:"\u4EC5 mount\uFF1A\u5DE5\u4F5C\u533A\u5185\u8DEF\u5F84\u3002kind=mcp \u4E3A mcp.json \u6587\u4EF6\u6216\u5176\u5305\u76EE\u5F55\uFF1Bkind=plugin \u4E3A\u542B plugin.json \u7684\u63D2\u4EF6\u76EE\u5F55\u3002\u652F\u6301\u76F8\u5BF9\u5DE5\u4F5C\u533A\u7684\u76F8\u5BF9\u8DEF\u5F84\u3002"},name:{type:"string",description:"\u8C03\u8BD5\u9879\u540D\uFF08unmount/logs \u5FC5\u586B\uFF1Bmount \u65F6 MCP \u53EF\u9009\u3001\u7F3A\u7701\u53D6\u8DEF\u5F84 basename\uFF0C\u63D2\u4EF6\u4EE5 plugin.json \u4E3A\u51C6\uFF09"},tail:{type:"number",description:"\u4EC5 logs\uFF1A\u8FD4\u56DE\u6700\u8FD1 N \u884C\uFF08\u9ED8\u8BA4 100\uFF0C\u4E0A\u9650 500\uFF09"}},required:["action"]}},s={name:"formal_ability",description:"\u628A\u5F00\u53D1\u597D\u7684\u5236\u54C1\u8F6C\u6B63\uFF08\u6301\u4E45\u5316\u5B89\u88C5\uFF09\u3002kind=mcp|plugin \u65F6\u4F20 path\uFF08\u5DE5\u4F5C\u533A\u5185\u5DF2\u8C03\u8BD5\u597D\u7684\u5236\u54C1\u8DEF\u5F84\uFF09\uFF0C\u670D\u52A1\u7AEF\u6253\u5305\u5E76\u8D70\u80FD\u529B\u5E02\u573A\u5B89\u88C5\u6D41\u7A0B\uFF1Bkind=skill \u65F6\u4F20 path\uFF08\u5DE5\u4F5C\u533A\u5185\u542B SKILL.md \u7684\u76EE\u5F55\uFF09\uFF0C\u76F4\u63A5\u6253\u5305\u767B\u8BB0\u5E76\u5B89\u88C5\uFF08Skill \u65E0\u8C03\u8BD5\u6001\uFF0C\u4E0D\u9700\u8981\u6302\u8F7D\uFF09\u3002scope \u7F3A\u7701\u4E3A global\uFF1A\u53EA\u767B\u8BB0\u5230\u300C\u5168\u5C40\u914D\u7F6E \u2192 \u5B9E\u4F8B\u6A21\u677F\u300D\u4E14 instantiate=false\uFF08\u9ED8\u8BA4\u5173\u95ED\u3001\u4E0D\u53C2\u4E0E\u5B9E\u4F8B\u521D\u59CB\u5316\uFF09\uFF0C\u9700\u7528\u6237\u5728\u9762\u677F\u5F00\u542F\u8BE5\u9879\u5F00\u5173\u540E\u624D\u968F\u521D\u59CB\u5316\u4E0B\u53D1\u2014\u2014\u8F6C\u6B63\u6210\u529F\u540E\u5E76\u4E0D\u7B49\u4E8E\u5F53\u524D\u5B9E\u4F8B\u5DF2\u751F\u6548\u3002\u663E\u5F0F\u4F20 scope=instance \u624D\u5B89\u88C5\u5230\u5F53\u524D\u5B9E\u4F8B\u5E76\u7ACB\u5373\u751F\u6548\uFF1Bscope=private \u4EC5\u5B89\u88C5\u5230\u5F53\u524D\u5B9E\u4F8B\uFF08per-agent \u79C1\u6709\uFF09\uFF0C\u4E0D\u6539\u5171\u4EAB\u5B9E\u4F8B\u6A21\u677F\u3001\u5176\u5B83\u5B9E\u4F8B\u4E0D\u53EF\u89C1\u3002",inputSchema:{type:"object",properties:{kind:{type:"string",enum:["mcp","plugin","skill"],description:"\u5236\u54C1\u7C7B\u578B"},path:{type:"string",description:"\u5DE5\u4F5C\u533A\u5185\u5236\u54C1\u8DEF\u5F84\uFF1Akind=mcp|plugin \u4E3A\u5DF2\u8C03\u8BD5\u597D\u7684\u5236\u54C1\u76EE\u5F55\uFF08MCP \u5305\u76EE\u5F55 / \u63D2\u4EF6\u76EE\u5F55\uFF09\uFF1Bkind=skill \u4E3A\u542B SKILL.md \u7684\u76EE\u5F55\u3002"},name:{type:"string",description:"\u53EF\u9009\uFF1A\u5236\u54C1\u540D\uFF08\u7F3A\u7701\u4ECE\u6E05\u5355\u6216 SKILL.md \u8BFB\u53D6\uFF09"},scope:{type:"string",enum:["global","instance","private"],description:"\u53EF\u9009\uFF1A\u5B89\u88C5\u843D\u70B9\uFF0C\u7F3A\u7701 global\uFF08\u53EA\u5165\u5168\u5C40\u914D\u7F6E\u6A21\u677F\u3001\u521D\u59CB\u5316\u5173\u95ED\uFF09\uFF1Binstance=\u5B89\u88C5\u5230\u5F53\u524D\u5B9E\u4F8B\u7ACB\u5373\u751F\u6548\uFF1Bprivate=\u4EC5\u5B89\u88C5\u5230\u5F53\u524D\u5B9E\u4F8B\uFF08per-agent \u79C1\u6709\uFF09\uFF0C\u4E0D\u6539\u5171\u4EAB\u5B9E\u4F8B\u6A21\u677F\u3001\u5176\u5B83\u5B9E\u4F8B\u4E0D\u53EF\u89C1"}},required:["kind","path"]}},a={name:"list_my_abilities",description:"\u67E5\u8BE2\u300C\u4F60\u81EA\u5DF1\u6240\u5728\u7684\u89D2\u8272\u5B9E\u4F8B\u300D\u5F53\u524D\u7684\u5168\u90E8\u80FD\u529B\u72B6\u6001\uFF08\u53EA\u8BFB\uFF09\u3002\u8FD4\u56DE\uFF1Amcp / skills / plugins\uFF08\u540D\u79F0\u3001\u542F\u7528\u72B6\u6001\u3001\u6765\u6E90\u5C42\u7EA7\uFF1B\u63D2\u4EF6\u53E6\u542B\u8FD0\u884C\u6001\u4E0E\u5DE5\u5177\u6570\uFF09\u3001tools\uFF08\u529F\u80FD\u5F00\u5173\u7684\u6709\u6548\u4E09\u6001\uFF1Adisabled/collapsed/expanded\uFF09\u3001debugMounts\uFF08\u5F53\u524D\u4F1A\u8BDD\u7684\u8C03\u8BD5\u6302\u8F7D\u9879\uFF0C\u4E0E\u6301\u4E45\u5316\u5B89\u88C5\u9694\u79BB\uFF09\u3002\u7528\u4E8E\u81EA\u7BA1\u7406\uFF1A\u786E\u8BA4\u5DF2\u5B89\u88C5\u80FD\u529B\u3001\u53D1\u73B0\u91CD\u590D\u5B89\u88C5\u3001\u8BC6\u522B\u4E0D\u7528\u7684\u80FD\u529B\u540E\u7528 uninstall_ability_market_item \u5378\u8F7D\u3002",inputSchema:{type:"object",properties:{},required:[]}};export{l as ABILITY_DEV_IDE_TOOL,p as ABILITY_DEV_TOOL_NAMES,n as ABILITY_MARKET_TOOL_NAMES,s as FORMAL_ABILITY_TOOL,i as INSTALL_ABILITY_MARKET_ITEM_TOOL,e as LIST_ABILITY_MARKET_TOOL,a as LIST_MY_ABILITIES_TOOL,t as UNINSTALL_ABILITY_MARKET_ITEM_TOOL};
2
+
@@ -1,7 +1,7 @@
1
1
 
2
2
  import type { MemoryStats } from "./memory-store.js";
3
3
  import { StatusReporter } from "./status-reporter.js";
4
- import type { AgentConfig, BrowserListenerEvent, Card, DirectMessage, DmHistoryResponse, FetchUnreadMessagesOptions, FinishTaskRollbackArgs, GroupHistoryResponse, GroupRoomsResponse, HireBatchResult, HireColleagueArgs, MessageHandler, OnlineListResponse, PluginCatalogSnapshot, ProfileInfo, ProjectMembersResponse, RegisterResult, ReplyToRef, ServerConfig, SendDmResult, SendMessageResult, StartTaskRollbackArgs, TaskInstanceCommentArgs, UnreadMessagesResult } from "./types.js";
4
+ import type { AgentConfig, BrowserListenerEvent, Card, DirectMessage, DmHistoryResponse, FetchUnreadMessagesOptions, FinishTaskRollbackArgs, GroupHistoryResponse, GroupRoomsResponse, HireBatchResult, HireColleagueArgs, MessageHandler, OnlineListResponse, ProfileInfo, ProjectMembersResponse, RegisterResult, ReplyToRef, ServerConfig, SendDmResult, SendMessageResult, StartTaskRollbackArgs, TaskInstanceCommentArgs, UnreadMessagesResult } from "./types.js";
5
5
  export type ProfileHandler = (profile: ProfileInfo) => void;
6
6
  export type AgentConfigHandler = (data: Record<string, unknown>) => void;
7
7
  export type SystemNotifyHandler = (data: Record<string, unknown>) => void;
@@ -97,9 +97,6 @@ export declare class AgentClient {
97
97
  fetchPluginEvents(): Promise<{
98
98
  revision: number;
99
99
  events: DirectMessage[];
100
- catalog: PluginCatalogSnapshot | null;
101
-
102
- compactionSeq: number;
103
100
  }>;
104
101
 
105
102
  notifyBridgeForceMessage(): Promise<void>;
@@ -157,6 +154,18 @@ export declare class AgentClient {
157
154
 
158
155
  listLaunchRuns(): Promise<unknown>;
159
156
 
157
+ listAbilityMarket(args?: Record<string, unknown>): Promise<unknown>;
158
+
159
+ installAbilityMarketItem(args: Record<string, unknown>): Promise<unknown>;
160
+
161
+ uninstallAbilityMarketItem(args: Record<string, unknown>): Promise<unknown>;
162
+
163
+ abilityDevIde(args: Record<string, unknown>): Promise<unknown>;
164
+
165
+ formalAbility(args: Record<string, unknown>): Promise<unknown>;
166
+
167
+ listMyAbilities(args?: Record<string, unknown>): Promise<unknown>;
168
+
160
169
  start(handler: MessageHandler, options?: {
161
170
  pollMode?: boolean;
162
171
  profileHandler?: ProfileHandler;
@@ -1,2 +1,2 @@
1
- import{configManager as c}from"./config.js";import{MESSAGE_POLL_INTERVAL_MS as I}from"./constants.js";import{HttpClient as f}from"./http-client.js";import{logger as i,setMcpNodeLogSink as w,updateStartupLogIdentity as u}from"./logger.js";import{claimRuntimeLaunchBindingDetailed as m}from"./runtime-launch-binding.js";import{StatusReporter as A}from"./status-reporter.js";import{WebSocketClient as p}from"./websocket-client.js";class T extends Error{constructor(e){super(e),this.name="PollLongPollTimeoutError"}}const C=27e4;class N{wsClient;httpClient;agentConfig;serverConfig;agentId=null;displayName=null;projectId=null;isRunning=!1;isDegradedMode=!1;messageHandler=null;profileHandler=null;configHandler=null;systemNotifyHandler=null;pollTimer=null;statusReporter=null;newCharacterHandler=null;runtimeTokenRefreshTimer=null;pendingLaunchBindingClaim=!1;cachedProfile=null;constructor(){c.loadConfig(),this.agentConfig=c.getAgentConfig(),this.serverConfig=c.getServerConfig(),this.wsClient=new p(this.serverConfig),this.httpClient=new f(this.serverConfig),this.setupWebSocketListeners()}async initialize(){const e=await m(this.agentConfig,this.serverConfig);if(e.status==="claimed"){this.applyLaunchBinding(e.binding);return}if(e.status==="unreachable"){this.pendingLaunchBindingClaim=!0,i.warn("[AgentClient] runtime-bridge \u672A\u5C31\u7EEA\uFF0C\u542F\u52A8\u7ED1\u5B9A\u8BA4\u9886\u5DF2\u6302\u8D77\uFF0C\u5C06\u5728\u6CE8\u518C\u91CD\u8BD5\u4E2D\u91CD\u65B0\u8BA4\u9886: %s",e.message);return}this.serverConfig.runtimeBridgeBaseUrl=void 0}applyLaunchBinding(e){c.applyRuntimeLaunchBinding(e),this.agentConfig=c.getAgentConfig(),this.serverConfig=c.getServerConfig(),this.wsClient=new p(this.serverConfig),this.httpClient=new f(this.serverConfig),this.setupWebSocketListeners()}async retryPendingLaunchBindingClaim(){if(!this.pendingLaunchBindingClaim)return!0;const e=await m(this.agentConfig,this.serverConfig);if(e.status==="claimed")return this.pendingLaunchBindingClaim=!1,i.info("[AgentClient] \u542F\u52A8\u7ED1\u5B9A\u8865\u8BA4\u9886\u6210\u529F\uFF0C\u7EE7\u7EED\u6CE8\u518C\u6D41\u7A0B"),this.applyLaunchBinding(e.binding),!0;if(e.status==="missing")return this.pendingLaunchBindingClaim=!1,this.serverConfig.runtimeBridgeBaseUrl=void 0,i.warn("[AgentClient] \u542F\u52A8\u7ED1\u5B9A\u8865\u8BA4\u9886\u672A\u627E\u5230\u5F85\u8BA4\u9886\u8BB0\u5F55\uFF0C\u6309\u65E0\u7ED1\u5B9A\u6A21\u5F0F\u7EE7\u7EED\u6CE8\u518C"),!1;const t=e.status==="unreachable"?e.message:e.reason;return i.warn("[AgentClient] \u542F\u52A8\u7ED1\u5B9A\u8865\u8BA4\u9886\u5931\u8D25\uFF0C\u4FDD\u7559\u6302\u8D77\u72B6\u6001\u7B49\u5F85\u4E0B\u6B21\u6CE8\u518C\u91CD\u8BD5: %s",t),!1}setupWebSocketListeners(){this.wsClient.on("directMessage",e=>{this.handleIncomingDm(e)}),this.wsClient.on("groupMessage",e=>{this.handleIncomingGroup(e)}),this.wsClient.on("meetingMessage",e=>{this.handleIncomingMeeting(e)}),this.wsClient.on("systemNotify",e=>{this.systemNotifyHandler?.(e)}),this.wsClient.on("profileInfo",e=>{i.info(`[AgentClient] WebSocket profileInfo \u4E8B\u4EF6\u89E6\u53D1\uFF0CdisplayName: ${e.displayName}`),this.handleProfileInfo(e)}),this.wsClient.on("agentConfig",e=>{i.info("[AgentClient] WebSocket agentConfig \u4E8B\u4EF6\u89E6\u53D1"),this.configHandler&&this.configHandler(e??{})}),this.wsClient.on("agentStatus",e=>{i.info(`[AgentClient] WebSocket agentStatus \u4E8B\u4EF6\u89E6\u53D1: ${e.status}`)}),this.wsClient.on("disconnected",(e,t)=>{const n=t?.toString()||"";i.warn("[AgentClient] WebSocket \u65AD\u5F00\u8FDE\u63A5: code=%s, reason=%s, agentId=%s, \u6B63\u5728\u81EA\u52A8\u91CD\u8FDE",e,n,this.agentId)}),this.wsClient.on("error",e=>{i.error("[AgentClient] WebSocket \u9519\u8BEF: %s, stack=%s",e.message,e.stack)}),this.wsClient.on("reconnectFailed",()=>{i.error("[AgentClient] \u91CD\u8FDE\u5931\u8D25\uFF08\u5DF2\u8FBE\u91CD\u8BD5\u4E0A\u9650\uFF09\uFF0C\u505C\u6B62\u6D88\u606F\u5FAA\u73AF, agentId=%s",this.agentId),this.stop()}),this.wsClient.on("tokenRejected",()=>{i.error("[AgentClient] runtime token \u88AB 1008 \u62D2\u7EDD\u4E14\u5237\u65B0\u65E0\u53D8\u5316\uFF0C\u8FDB\u5165\u6162\u901F\u91CD\u8BD5\u7B49\u5F85\u65B0 token \u7B7E\u53D1: agentId=%s",this.agentId)}),this.wsClient.on("tokenRefreshFailed",e=>{i.error("[AgentClient] runtime token \u5237\u65B0\u8FDE\u7EED\u5931\u8D25 %s \u6B21\uFF0C\u8FDB\u5165\u6162\u901F\u91CD\u8BD5\u7B49\u5F85 bridge \u6062\u590D: agentId=%s",e,this.agentId)})}async register(){return i.info("[AgentClient] \u6B63\u5728\u6CE8\u518C Agent..."),await this.retryPendingLaunchBindingClaim(),this.hasPresetAgentId()?await this.registerWithExistingAgentId():await this.registerAsNewAgent()}hasPresetAgentId(){return!!(this.agentConfig.agentId&&this.agentConfig.agentId.trim().length>0)}async registerWithExistingAgentId(){const e=this.agentConfig.agentId;if(!e)throw new Error("Preset agentId is missing");this.agentId=e.trim();let t;try{t=await this.getProfileByAgentId(this.agentId)}catch(r){throw i.error("[AgentClient] getProfileByAgentId \u5931\u8D25 (presetAgentId=%s): %s",this.agentId,r instanceof Error?r.message:String(r)),r}this.displayName=t.displayName,this.projectId=t.projectId||null,i.info(`[AgentClient] \u4F7F\u7528\u9884\u8BBE AgentID \u7ED1\u5B9A\u5B9E\u4F8B: ${this.displayName} (${this.agentId})`),i.info(`[AgentClient] \u6240\u5C5E\u9879\u76EE: ${this.projectId||"(\u672A\u8BBE\u7F6E)"}`);try{await this.wsClient.connect(this.agentId)}catch(r){throw i.error("[AgentClient] WebSocket \u8FDE\u63A5\u5931\u8D25 (agentId=%s): %s",this.agentId,r instanceof Error?r.message:String(r)),r}i.info("[AgentClient] WebSocket \u8FDE\u63A5\u5DF2\u5EFA\u7ACB\uFF0CAgent \u73B0\u5728\u5DF2\u4E0A\u7EBF"),this.initializeStatusReporter();const n=await this.getProfileByAgentId(this.agentId);return this.displayName=n.displayName,this.projectId=n.projectId||null,u(n.roleName||"unknown-role",n.instanceName||this.agentId),{agentId:this.agentId,displayName:this.displayName,status:n.isOnline?"online":"offline",projectId:n.projectId,workspacePath:n.workspacePath,runtimeStatus:n.runtimeStatus,runtimeSessionId:n.runtimeSessionId}}async registerAsNewAgent(){const e=await this.httpClient.callTool("register",{roleName:this.agentConfig.roleName,projectId:this.agentConfig.projectId,workspacePath:this.agentConfig.workspacePath,prompt:this.agentConfig.prompt,runtimeBridgeBaseUrl:this.serverConfig.runtimeBridgeBaseUrl}),t=e.agentId;if(!t)throw new Error("Registration failed: agentId was not returned");return this.agentId=t,this.displayName=e.displayName,this.projectId=e.projectId||null,u(this.agentConfig.roleName||"unknown-role",e.instanceName||t),i.info(`[AgentClient] \u6CE8\u518C\u6210\u529F: ${this.displayName} (${this.agentId})`),i.info(`[AgentClient] \u72B6\u6001: ${e.status}`),i.info(`[AgentClient] \u6240\u5C5E\u9879\u76EE: ${this.projectId||"(\u672A\u8BBE\u7F6E)"}`),await this.wsClient.connect(this.agentId),i.info("[AgentClient] WebSocket \u8FDE\u63A5\u5DF2\u5EFA\u7ACB\uFF0CAgent \u73B0\u5728\u5DF2\u4E0A\u7EBF"),this.initializeStatusReporter(),e.isExisting===!1&&this.newCharacterHandler&&this.newCharacterHandler(),e}async unregister(){i.info("[AgentClient] \u6B63\u5728\u6CE8\u9500 Agent..."),this.agentId&&await this.httpClient.callTool("unregister",{agentId:this.agentId}),this.stopRuntimeTokenRefresh(),this.wsClient.disconnect(),this.agentId=null,this.displayName=null,this.projectId=null,this.isRunning=!1,i.info("[AgentClient] \u5DF2\u6CE8\u9500")}async discoverColleagues(){return await this.httpClient.callTool("discover_colleague",{agentId:this.agentId})}async discoverGroupRooms(){return this.ensureRegistered(),await this.httpClient.callTool("discover_group_rooms",{agentId:this.agentId})}async listProjectMembers(){return this.ensureRegistered(),await this.httpClient.callTool("list_project_members",{agentId:this.agentId})}async hireColleague(e){return this.ensureRegistered(),await this.httpClient.callTool("hire_colleague",{...e,agentId:this.agentId})}async callAgentScopedTool(e,t){this.ensureRegistered();const n={...t,agentId:this.agentId};if(e==="create_meeting"){const r=typeof t.waitTimeoutMs=="number"?t.waitTimeoutMs:Number.NaN,s=Number.isFinite(r)&&r>0?Math.min(r,C):C;return await this.httpClient.callToolOnce(e,{...n,waitTimeoutMs:s},0)}return await this.httpClient.callTool(e,n)}async reportMemoryStats(e){await this.callAgentScopedTool("report_memory_stats",{memoryStats:e})}async sendGroupMessage(e,t,n,r,s){this.ensureRegistered();const a=t||this.projectId||this.agentConfig.projectId;return await this.httpClient.callTool("send_group_message",{agentId:this.agentId,projectId:a,roomId:n,content:e,card:r,replyTo:s})}async sendDirectMessage(e,t,n=!1,r,s,a,h){this.ensureRegistered();const g={agentId:this.agentId,targetId:e,content:t,requireReply:n,waitReply:n,replyToCallId:r,card:a,replyTo:h};if(typeof s=="number"&&s>0&&(g.timeoutMs=s),n){const o=typeof s=="number"&&s>0?s+3e4:0;return await this.httpClient.callToolOnce("send_dm",g,o)}return await this.httpClient.callTool("send_dm",g)}async sendCallAndWaitReply(e,t,n=6e4){const r=await this.sendDirectMessage(e,t,!0,void 0,n);if(r.reply)return r.reply;throw new Error("No reply received for call-style direct message before timeout")}async replyToCall(e,t,n){return await this.sendDirectMessage(t,n,!1,e)}async sendEmail(e){return await this.callAgentScopedTool("send_email",e)}async listEmails(e){return await this.callAgentScopedTool("list_emails",e)}async readEmail(e){return await this.callAgentScopedTool("read_email",{mailId:e})}async replyEmail(e){return await this.callAgentScopedTool("reply_email",e)}async ackEmail(e){return await this.callAgentScopedTool("ack_email",{mailId:e})}async getDmHistory(e,t=50,n){this.ensureRegistered();const r={agentId:this.agentId,targetUserId:e,limit:t};return n&&(r.since=n),await this.httpClient.callTool("get_dm_history",r)}async getGroupHistory(e=50,t,n){if(this.ensureRegistered(),t){const o={projectId:this.projectId||this.agentConfig.projectId,roomId:t,limit:e};return n&&(o.since=n),await this.httpClient.callTool("get_group_history",o)}const r=await this.discoverGroupRooms(),s=this.projectId||this.agentConfig.projectId,a=this.collectRoomIds(r,s);if(a.length===0)return{messages:[],count:0};const g=(await Promise.all(a.map(async o=>{const l={projectId:s,roomId:o,limit:e};return n&&(l.since=n),await this.httpClient.callTool("get_group_history",l)}))).flatMap(o=>o.messages).sort((o,l)=>new Date(o.timestamp).getTime()-new Date(l.timestamp).getTime());return{messages:g,count:g.length}}async fetchUnreadMessages(e={}){this.ensureRegistered();const t=this.projectId||this.agentConfig.projectId,n={agentId:this.agentId,blockIfEmpty:e.blockIfEmpty??!1};e.since&&(n.since=e.since),e.blockTimeoutMs&&e.blockTimeoutMs>0&&(n.blockTimeoutMs=e.blockTimeoutMs),e.preemptiveJoinWaitMs!==void 0&&e.preemptiveJoinWaitMs!==null&&e.preemptiveJoinWaitMs>=0&&(n.preemptiveJoinWaitMs=e.preemptiveJoinWaitMs);const r=e.includePipelineTasks?"poll_message":"get_dm_messages";i.info("[AgentClient] fetchUnreadMessages \u5165\u53E3: tool=%s, blockIfEmpty=%s, blockTimeoutMs=%s, pollMessageTimeoutMs=%s, skipGroupMessages=%s, preemptiveJoinWaitMs=%s, agentId=%s",r,String(e.blockIfEmpty??!1),String(e.blockTimeoutMs??"-"),String(e.pollMessageTimeoutMs??"-"),String(e.skipGroupMessages??!1),String(e.preemptiveJoinWaitMs??"-"),this.agentId);const s=await this.fetchDirectMessagesWithRecovery(r,n,e.pollMessageTimeoutMs,e.propagatePollTimeout===!0);if(i.info("[AgentClient] fetchUnreadMessages \u79C1\u4FE1\u9636\u6BB5\u8FD4\u56DE: %s \u6761",Array.isArray(s.messages)?s.messages.length:0),e.skipGroupMessages)return i.info("[AgentClient] \u4F1A\u8BAE\u5FEB\u901F hydrate \u5DF2\u53D6\u5F97\u79C1\u4FE1\u54CD\u5E94\uFF0C\u8DF3\u8FC7\u7FA4\u804A\u53D1\u73B0\u5E76\u7ACB\u5373\u8FD4\u56DE: directMessages=%s",Array.isArray(s.messages)?s.messages.length:0),{directMessages:Array.isArray(s.messages)?s.messages:[],groupMessages:[]};let a;try{a=await this.discoverGroupRooms()}catch(o){i.warn("[AgentClient] \u53D1\u73B0\u7FA4\u623F\u95F4\u5931\u8D25\uFF0C\u672C\u6B21\u6309\u65E0\u7FA4\u6D88\u606F\u5904\u7406\uFF08\u5DF2\u53D6\u5230\u7684\u79C1\u4FE1\u4E0D\u53D7\u5F71\u54CD\uFF09: %s",o instanceof Error?o.message:String(o)),a={groups:[]}}const h=this.collectRoomIds(a,t),g=await Promise.all(h.map(async o=>{const l={agentId:this.agentId,projectId:t,roomId:o};e.since&&(l.since=e.since);try{return await this.httpClient.callTool("get_group_messages",l)}catch(d){return i.warn("[AgentClient] \u8DF3\u8FC7\u7FA4\u623F\u95F4\u672A\u8BFB\u8865\u62C9\u5931\u8D25: roomId=%s, error=%s",o,d instanceof Error?d.message:String(d)),{messages:[],currentReadPos:0,hasMore:!1}}}));return{directMessages:Array.isArray(s.messages)?s.messages:[],groupMessages:g.flatMap(o=>this.normalizeGroupMessages(o)).sort((o,l)=>new Date(o.timestamp).getTime()-new Date(l.timestamp).getTime())}}async markDmRead(e){if(e.length===0)return new Set;this.ensureRegistered();try{const t=await this.httpClient.callTool("mark_dm_read",{agentId:this.agentId,msgIds:e}),n=new Set(Array.isArray(t?.deliverableMsgIds)?t.deliverableMsgIds:[]),r=e.filter(s=>!n.has(s));return r.length>0?i.warn("[AgentClient] mark_dm_read \u786E\u8BA4\u540E\u5C06\u6709 %d \u6761\u6D88\u606F\u88AB\u4E22\u5F03\u4E0D\u4EA4\u4ED8: \u8BF7\u6C42=%s, \u53EF\u4EA4\u4ED8=%s, \u88AB\u4E22\u5F03=%s",r.length,JSON.stringify(e),JSON.stringify([...n]),JSON.stringify(r)):i.info("[AgentClient] mark_dm_read \u786E\u8BA4\u5B8C\u6210: %d \u6761\u5168\u90E8\u53EF\u4EA4\u4ED8",e.length),n}catch(t){throw i.warn("[AgentClient] mark_dm_read \u8BF7\u6C42\u5931\u8D25\uFF08\u5C06\u964D\u7EA7\u4E3A\u76F4\u63A5\u4EA4\u4ED8\uFF09: %s",t instanceof Error?t.message:String(t)),t}}async markGroupRead(e,t){if(t.length===0)return new Set;this.ensureRegistered();const n=await this.httpClient.callTool("mark_group_read",{agentId:this.agentId,roomId:e,msgIds:t});return new Set(Array.isArray(n?.deliverableMsgIds)?n.deliverableMsgIds:[])}async markNotificationRead(e){if(e.length!==0){this.ensureRegistered();try{await this.httpClient.callTool("mark_notification_read",{agentId:this.agentId,msgIds:e})}catch{}}}async markMeetingRead(e){if(e.length!==0){this.ensureRegistered();try{await this.httpClient.callTool("mark_meeting_read",{agentId:this.agentId,msgIds:e})}catch{}}}async fetchBrowserListenerEvents(){const e=this.serverConfig.runtimeBridgeBaseUrl,t=this.agentId;if(!e||!t)return i.info("[AgentClient] fetchBrowserListenerEvents \u8DF3\u8FC7: bridgeBaseUrl=%s, agentId=%s",e||"(\u7A7A)",t||"(\u7A7A)"),[];try{const n=`${e}/runtime/browser-listeners/${encodeURIComponent(t)}/events`,r=this.serverConfig.runtimeAccessToken||"";i.debug("[AgentClient] \u62C9\u53D6\u76D1\u542C\u5668\u4E8B\u4EF6: url=%s, tokenLen=%d",n,r.length);const s=await fetch(n,{method:"GET",headers:{"X-Runtime-Token":r},signal:AbortSignal.timeout(3e3)});if(!s.ok)return i.warn("[AgentClient] \u62C9\u53D6\u76D1\u542C\u5668\u4E8B\u4EF6\u5931\u8D25: HTTP %s, url=%s",s.status,n),[];const a=await s.json();return!a.ok||!Array.isArray(a.events)?(i.warn("[AgentClient] \u62C9\u53D6\u76D1\u542C\u5668\u4E8B\u4EF6\u54CD\u5E94\u5F02\u5E38: ok=%s, eventsType=%s",a.ok,Array.isArray(a.events)?"array":typeof a.events),[]):(i.debug("[AgentClient] \u62C9\u53D6\u76D1\u542C\u5668\u4E8B\u4EF6\u6210\u529F: %d \u6761\u4E8B\u4EF6",a.events.length),a.events)}catch(n){return i.warn("[AgentClient] \u62C9\u53D6\u76D1\u542C\u5668\u4E8B\u4EF6\u5F02\u5E38: %s",n instanceof Error?n.message:String(n)),[]}}async fetchPluginEvents(){const e=this.serverConfig.runtimeBridgeBaseUrl,t=this.agentId;if(!e||!t)return{revision:0,events:[],catalog:null,compactionSeq:0};try{const n=`${e}/runtime/plugin-events/${encodeURIComponent(t)}/events`,r=this.serverConfig.runtimeAccessToken||"",s=await fetch(n,{method:"GET",headers:{"X-Runtime-Token":r},signal:AbortSignal.timeout(3e3)});if(!s.ok)return i.warn("[AgentClient] \u62C9\u53D6\u63D2\u4EF6\u4E8B\u4EF6\u5931\u8D25: HTTP %s, url=%s",s.status,n),{revision:0,events:[],catalog:null,compactionSeq:0};const a=await s.json();return!a.ok||!Array.isArray(a.events)?(i.warn("[AgentClient] \u62C9\u53D6\u63D2\u4EF6\u4E8B\u4EF6\u54CD\u5E94\u5F02\u5E38: ok=%s",String(a.ok)),{revision:0,events:[],catalog:null,compactionSeq:0}):(i.debug("[AgentClient] \u62C9\u53D6\u63D2\u4EF6\u4E8B\u4EF6\u6210\u529F: %d \u6761\u4E8B\u4EF6, revision=%s, catalog=%s, compactionSeq=%s",a.events.length,String(a.revision??0),a.catalog?`${a.catalog.plugins.length} \u4E2A\u63D2\u4EF6`:"null",String(a.compactionSeq??0)),{revision:a.revision??0,events:a.events,catalog:a.catalog??null,compactionSeq:typeof a.compactionSeq=="number"&&Number.isFinite(a.compactionSeq)?a.compactionSeq:0})}catch(n){return i.warn("[AgentClient] \u62C9\u53D6\u63D2\u4EF6\u4E8B\u4EF6\u5F02\u5E38: %s",n instanceof Error?n.message:String(n)),{revision:0,events:[],catalog:null,compactionSeq:0}}}async notifyBridgeForceMessage(){const e=this.serverConfig.runtimeBridgeBaseUrl,t=this.agentId;if(!(!e||!t))try{const n=`${e}/runtime/sessions/${encodeURIComponent(t)}/notify-force-message`,r=this.serverConfig.runtimeAccessToken||"",s=await fetch(n,{method:"POST",headers:{"X-Runtime-Token":r},signal:AbortSignal.timeout(3e3)});s.ok||i.warn("[AgentClient] \u901A\u77E5 bridge \u5F3A\u5236\u6D88\u606F\u5931\u8D25: HTTP %s, url=%s",s.status,n)}catch(n){i.warn("[AgentClient] \u901A\u77E5 bridge \u5F3A\u5236\u6D88\u606F\u5F02\u5E38: %s",n instanceof Error?n.message:String(n))}}async fetchDirectMessagesWithRecovery(e,t,n,r=!1){if(e==="poll_message"){i.info("[AgentClient] fetchDirectMessagesWithRecovery \u5165\u53E3: tool=poll_message, pollMessageTimeoutMs=%s, agentId=%s",String(n??"(\u9ED8\u8BA4)"),String(t?.agentId??""));try{const s=await this.httpClient.callToolOnce(e,t,n);return i.info("[AgentClient] fetchDirectMessagesWithRecovery poll_message \u6210\u529F\u8FD4\u56DE: %s \u6761",Array.isArray(s?.messages)?s.messages.length:0),s}catch(s){if(this.isRecoverableLongPollError(s)){if(r)throw new T(s instanceof Error?s.message:String(s));return i.warn("[AgentClient] poll_message \u5355\u6B21\u957F\u8F6E\u8BE2\u8D85\u65F6\uFF0C\u6309\u7A7A\u7ED3\u679C\u9000\u907F\u540E\u7EE7\u7EED\u7B49\u5F85:",s),{messages:[]}}throw s}}return await this.httpClient.callTool(e,t)}isRecoverableLongPollError(e){return e instanceof Error?/MCP tool poll_message call failed: 503(?:\s|$)/.test(e.message)||/MCP tool poll_message timed out after \d+ms/.test(e.message):!1}normalizeGroupMessages(e){return Array.isArray(e.messages)?e.messages.filter(t=>!!(t&&typeof t=="object"&&typeof t.msgId=="number"&&typeof t.senderId=="string"&&typeof t.content=="string"&&typeof t.timestamp=="string")):[]}collectRoomIds(e,t){const n=e.groups.filter(r=>r.projectId===t).map(r=>r.id);return Array.from(new Set(n))}async getProfile(){this.ensureRegistered();const e=this.agentId;if(!e)throw new Error("Agent is not registered");return{...await this.getProfileByAgentId(e),describe:this.agentConfig.describe}}async getProfileByAgentId(e){return await this.httpClient.callTool("get_profile",{agentId:e})}async getMyTasks(){return this.ensureRegistered(),await this.httpClient.callTool("my_task",{agentId:this.agentId})}async listTaskNodeIterations(e={}){return this.ensureRegistered(),await this.httpClient.callTool("list_task_node_iterations",{agentId:this.agentId,...e})}async createTaskInstanceComment(e){this.ensureRegistered();const t={agentId:this.agentId,...e};return await this.httpClient.callTool("create_task_instance_comment",t)}async submitTaskResult(e,t,n,r,s){this.ensureRegistered();const a={agentId:this.agentId,nodeId:e,outputPayload:t};return(Array.isArray(n)&&n.length>0||typeof n=="string"&&n.trim().length>0)&&(a.changeLog=n),typeof r=="string"&&r.trim().length>0&&(a.handoverNote=r),s&&Array.isArray(s)&&s.length>0&&(a.deliverables=s),await this.httpClient.callTool("submit_task_result",a)}async startTaskRollback(e){return this.ensureRegistered(),await this.httpClient.callTool("start_task_rollback",{agentId:this.agentId,...e})}async finishTaskRollback(e){return this.ensureRegistered(),await this.httpClient.callTool("finish_task_rollback",{agentId:this.agentId,...e})}async getDebugLogConfig(){return await this.httpClient.callTool("get_debug_log_config",{agentId:this.agentId})}async queryDebugLogs(e){return this.ensureRegistered(),await this.httpClient.callTool("query_debug_logs",{...e})}async queryFileChangesHistory(e){return this.ensureRegistered(),await this.httpClient.callTool("query_file_changes_history",{...e})}async getRuntimeFeatures(){return await this.httpClient.fetchRuntimeFeatures()}async listLaunchConfigs(){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_list",{})}async createLaunchConfig(e){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_create",{...e})}async updateLaunchConfig(e){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_update",{...e})}async deleteLaunchConfig(e){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_delete",{configId:e})}async startLaunchConfig(e){this.ensureRegistered();const t=Math.max(0,Math.min(3e5,Number(e.wait_timeout_ms)||0));return t>0?await this.httpClient.callToolOnce("launch_config_start",e,t+6e4):await this.httpClient.callTool("launch_config_start",{...e})}async restartLaunchConfig(e){this.ensureRegistered();const t=Math.max(0,Math.min(3e5,Number(e.wait_timeout_ms)||0));return t>0?await this.httpClient.callToolOnce("launch_config_restart",e,t+6e4):await this.httpClient.callTool("launch_config_restart",{...e})}async stopLaunchConfig(e){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_stop",{configId:e})}async getLaunchLogs(e){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_logs",{...e})}async listLaunchRuns(){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_status",{})}start(e,t){if(this.isRunning){i.warn("[AgentClient] \u6D88\u606F\u5FAA\u73AF\u5DF2\u5728\u8FD0\u884C\u4E2D");return}this.isDegradedMode||this.ensureRegistered(),this.messageHandler=e,this.profileHandler=t?.profileHandler||null,this.configHandler=t?.configHandler||null,this.systemNotifyHandler=t?.systemNotifyHandler||null,this.isRunning=!0,i.info(`[AgentClient] start() \u88AB\u8C03\u7528\uFF0CcachedProfile: ${this.cachedProfile?"\u5B58\u5728":"\u4E0D\u5B58\u5728"}, profileHandler: ${this.profileHandler?"\u5DF2\u8BBE\u7F6E":"\u672A\u8BBE\u7F6E"}, \u964D\u7EA7\u6A21\u5F0F: ${this.isDegradedMode?"\u662F":"\u5426"}`),this.cachedProfile&&this.profileHandler&&(i.info(`[AgentClient] \u5904\u7406\u7F13\u5B58\u7684 Profile \u4FE1\u606F: ${this.cachedProfile.displayName}`),this.profileHandler(this.cachedProfile),this.cachedProfile=null),t?.pollMode??!1?(i.warn("[AgentClient] \u542F\u52A8\u6D88\u606F\u4E3B\u5FAA\u73AF\uFF08HTTP\u8F6E\u8BE2\u6A21\u5F0F - \u4E0D\u63A8\u8350\uFF09"),this.messageLoop()):i.info("[AgentClient] \u542F\u52A8\u6D88\u606F\u4E3B\u5FAA\u73AF\uFF08WebSocket\u63A8\u9001\u6A21\u5F0F - \u63A8\u8350\uFF09")}stop(){this.isRunning=!1,this.pollTimer&&(clearTimeout(this.pollTimer),this.pollTimer=null),this.stopRuntimeTokenRefresh(),i.info("[AgentClient] \u6D88\u606F\u4E3B\u5FAA\u73AF\u5DF2\u505C\u6B62")}async messageLoop(){for(;this.isRunning;)try{await this.delay(I)}catch(e){i.error("[AgentClient] \u6D88\u606F\u5FAA\u73AF\u9519\u8BEF:",e),await this.delay(5e3)}}handleIncomingDm(e){e.senderId!==this.agentId&&this.processMessage(e)}handleIncomingGroup(e){e.senderId!==this.agentId&&this.processMessage(e)}handleIncomingMeeting(e){!e||e.senderId===this.agentId||this.processMessage(e)}handleProfileInfo(e){i.info(`[AgentClient] \u6536\u5230 Profile \u4FE1\u606F: ${e.displayName} (${e.roleName})`),e.projectId&&(this.projectId=e.projectId,i.info(`[AgentClient] \u66F4\u65B0\u6240\u5C5E\u9879\u76EE: ${this.projectId}`)),e.roleName&&e.roleName!==this.agentConfig.roleName&&(i.info(`[AgentClient] \u540C\u6B65\u89D2\u8272\u540D: "${this.agentConfig.roleName||"(\u7A7A)"}" -> "${e.roleName}"`),this.agentConfig.roleName=e.roleName),e.roleName&&u(e.roleName,e.instanceName||this.agentId||""),this.profileHandler?this.profileHandler(e):(i.info("[AgentClient] profileHandler \u672A\u8BBE\u7F6E\uFF0C\u7F13\u5B58 Profile \u4FE1\u606F"),this.cachedProfile=e)}async processMessage(e){if(!this.messageHandler)return;const t=typeof e.msgId=="string";i.info(`[AgentClient] \u6536\u5230${t?"\u79C1\u4FE1":"\u7FA4\u6D88\u606F"}\u6765\u81EA ${e.senderName}: ${e.content.substring(0,50)}...`);try{const n=await this.messageHandler(e);if(t){const r=e;r.requireReply&&r.callId&&await this.replyToCall(r.callId,r.senderId,n||"\u5DF2\u6536\u5230\u6D88\u606F\uFF0C\u6B63\u5728\u5904\u7406\u4E2D...")}}catch(n){const r=typeof e.msgId=="string";if(i.error("[AgentClient] \u5904\u7406\u6D88\u606F\u5931\u8D25: type=%s, senderId=%s, senderName=%s, msgId=%s, error=%s",r?"\u79C1\u4FE1":"\u7FA4\u6D88\u606F",e.senderId,e.senderName,e.msgId,n instanceof Error?n.message:String(n)),r){const s=e;s.requireReply&&s.callId&&await this.replyToCall(s.callId,s.senderId,`\u5904\u7406\u5931\u8D25: ${n}`)}}}ensureRegistered(){if(!this.agentId)throw new Error("Agent is not registered")}delay(e){return new Promise(t=>{this.pollTimer=setTimeout(t,e)})}onNewCharacter(e){this.newCharacterHandler=e}getState(){return{agentId:this.agentId,displayName:this.displayName,projectId:this.projectId,isConnected:this.wsClient.isConnected(),isRunning:this.isRunning}}getAgentConfig(){return this.agentConfig}getServerConfig(){return this.serverConfig}reloadConfig(){c.loadConfig(),this.agentConfig=c.getAgentConfig(),i.info(`[AgentClient] \u914D\u7F6E\u5DF2\u91CD\u65B0\u52A0\u8F7D\uFF0C\u89D2\u8272: ${this.agentConfig.roleName}`)}enterDegradedMode(){this.isDegradedMode=!0,i.warn("[AgentClient] \u8FDB\u5165\u964D\u7EA7\u6A21\u5F0F\uFF0C\u5C06\u5728\u540E\u53F0\u6301\u7EED\u5C1D\u8BD5\u91CD\u8FDE")}exitDegradedMode(){this.isDegradedMode=!1,i.info("[AgentClient] \u9000\u51FA\u964D\u7EA7\u6A21\u5F0F")}isInDegradedMode(){return this.isDegradedMode}async retryRegistrationInBackground(e,t){let n=0;(async()=>{for(;this.isDegradedMode;)try{i.info(`[AgentClient] \u964D\u7EA7\u6A21\u5F0F\uFF1A\u5C1D\u8BD5\u91CD\u65B0\u6CE8\u518C (${n+1}/${t===-1?"\u65E0\u9650":t})`);const s=await this.register();i.info(`[AgentClient] \u964D\u7EA7\u6A21\u5F0F\uFF1A\u6CE8\u518C\u6210\u529F - ${s.displayName} (${s.agentId})`),this.exitDegradedMode(),this.messageHandler&&this.start(this.messageHandler);return}catch(s){n++;const a=s instanceof Error?s.message:String(s);if(i.warn(`[AgentClient] \u964D\u7EA7\u6A21\u5F0F\uFF1A\u6CE8\u518C\u5931\u8D25 (${n}/${t===-1?"\u65E0\u9650":t}): ${a}`),t>0&&n>=t){i.error("[AgentClient] \u964D\u7EA7\u6A21\u5F0F\uFF1A\u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570\uFF0C\u505C\u6B62\u91CD\u8FDE"),this.isDegradedMode=!1;return}await new Promise(h=>setTimeout(h,e))}})().catch(s=>{i.error("[AgentClient] \u964D\u7EA7\u6A21\u5F0F\u540E\u53F0\u91CD\u8BD5\u5FAA\u73AF\u5F02\u5E38\u9000\u51FA: error=%s, stack=%s",s instanceof Error?s.message:String(s),s instanceof Error?s.stack:"(no stack)")})}initializeStatusReporter(){if(!this.agentId){i.warn("[AgentClient] \u65E0\u6CD5\u521D\u59CB\u5316\u72B6\u6001\u62A5\u544A\u5668\uFF1AagentId \u4E3A\u7A7A");return}this.statusReporter=new A({agentId:this.agentId,sendStatusUpdate:e=>{this.wsClient.send({type:"AGENT_STATUS",data:e,timestamp:new Date().toISOString()})}}),w(e=>this.reportMcpNodeLog(e)),this.startRuntimeTokenRefresh(),i.info("[AgentClient] \u72B6\u6001\u62A5\u544A\u5668\u5DF2\u521D\u59CB\u5316")}startRuntimeTokenRefresh(){this.stopRuntimeTokenRefresh();const e=this.serverConfig.runtimeTokenRefreshIntervalMs;if(!e||e<=0){i.warn("[AgentClient] runtimeTokenRefreshIntervalMs \u672A\u914D\u7F6E\u6216\u65E0\u6548\uFF0C\u8DF3\u8FC7\u4E3B\u52A8\u7EED\u671F");return}const t=this.agentId;if(!t){i.warn("[AgentClient] agentId \u4E3A\u7A7A\uFF0C\u8DF3\u8FC7\u4E3B\u52A8\u7EED\u671F");return}this.runtimeTokenRefreshTimer=setInterval(async()=>{try{await this.httpClient.refreshRuntimeAccessToken(t)&&i.info("[AgentClient] runtimeAccessToken \u5DF2\u4E3B\u52A8\u7EED\u671F")}catch(n){i.warn("[AgentClient] \u4E3B\u52A8\u7EED\u671F runtimeAccessToken \u5931\u8D25: %s",n instanceof Error?n.message:String(n)),n instanceof Error&&n.stack&&i.warn("[AgentClient] \u4E3B\u52A8\u7EED\u671F\u5F02\u5E38\u5806\u6808:",n.stack)}},e),this.runtimeTokenRefreshTimer.unref?.(),i.info(`[AgentClient] runtime token \u4E3B\u52A8\u7EED\u671F\u5DF2\u542F\u52A8\uFF0C\u95F4\u9694 ${e}ms`)}stopRuntimeTokenRefresh(){this.runtimeTokenRefreshTimer&&(clearInterval(this.runtimeTokenRefreshTimer),this.runtimeTokenRefreshTimer=null)}reportMcpNodeLog(e){const t=this.wsClient;!this.agentId||!this.wsClient.isConnected()||typeof t.sendMcpNodeLog!="function"||t.sendMcpNodeLog(e)}getStatusReporter(){return this.statusReporter}}export{N as AgentClient,T as PollLongPollTimeoutError};
1
+ import{configManager as h}from"./config.js";import{MESSAGE_POLL_INTERVAL_MS as I}from"./constants.js";import{HttpClient as f}from"./http-client.js";import{logger as i,setMcpNodeLogSink as w,updateStartupLogIdentity as u}from"./logger.js";import{claimRuntimeLaunchBindingDetailed as m}from"./runtime-launch-binding.js";import{StatusReporter as A}from"./status-reporter.js";import{WebSocketClient as p}from"./websocket-client.js";class T extends Error{constructor(e){super(e),this.name="PollLongPollTimeoutError"}}const C=27e4;class N{wsClient;httpClient;agentConfig;serverConfig;agentId=null;displayName=null;projectId=null;isRunning=!1;isDegradedMode=!1;messageHandler=null;profileHandler=null;configHandler=null;systemNotifyHandler=null;pollTimer=null;statusReporter=null;newCharacterHandler=null;runtimeTokenRefreshTimer=null;pendingLaunchBindingClaim=!1;cachedProfile=null;constructor(){h.loadConfig(),this.agentConfig=h.getAgentConfig(),this.serverConfig=h.getServerConfig(),this.wsClient=new p(this.serverConfig),this.httpClient=new f(this.serverConfig),this.setupWebSocketListeners()}async initialize(){const e=await m(this.agentConfig,this.serverConfig);if(e.status==="claimed"){this.applyLaunchBinding(e.binding);return}if(e.status==="unreachable"){this.pendingLaunchBindingClaim=!0,i.warn("[AgentClient] runtime-bridge \u672A\u5C31\u7EEA\uFF0C\u542F\u52A8\u7ED1\u5B9A\u8BA4\u9886\u5DF2\u6302\u8D77\uFF0C\u5C06\u5728\u6CE8\u518C\u91CD\u8BD5\u4E2D\u91CD\u65B0\u8BA4\u9886: %s",e.message);return}this.serverConfig.runtimeBridgeBaseUrl=void 0}applyLaunchBinding(e){h.applyRuntimeLaunchBinding(e),this.agentConfig=h.getAgentConfig(),this.serverConfig=h.getServerConfig(),this.wsClient=new p(this.serverConfig),this.httpClient=new f(this.serverConfig),this.setupWebSocketListeners()}async retryPendingLaunchBindingClaim(){if(!this.pendingLaunchBindingClaim)return!0;const e=await m(this.agentConfig,this.serverConfig);if(e.status==="claimed")return this.pendingLaunchBindingClaim=!1,i.info("[AgentClient] \u542F\u52A8\u7ED1\u5B9A\u8865\u8BA4\u9886\u6210\u529F\uFF0C\u7EE7\u7EED\u6CE8\u518C\u6D41\u7A0B"),this.applyLaunchBinding(e.binding),!0;if(e.status==="missing")return this.pendingLaunchBindingClaim=!1,this.serverConfig.runtimeBridgeBaseUrl=void 0,i.warn("[AgentClient] \u542F\u52A8\u7ED1\u5B9A\u8865\u8BA4\u9886\u672A\u627E\u5230\u5F85\u8BA4\u9886\u8BB0\u5F55\uFF0C\u6309\u65E0\u7ED1\u5B9A\u6A21\u5F0F\u7EE7\u7EED\u6CE8\u518C"),!1;const t=e.status==="unreachable"?e.message:e.reason;return i.warn("[AgentClient] \u542F\u52A8\u7ED1\u5B9A\u8865\u8BA4\u9886\u5931\u8D25\uFF0C\u4FDD\u7559\u6302\u8D77\u72B6\u6001\u7B49\u5F85\u4E0B\u6B21\u6CE8\u518C\u91CD\u8BD5: %s",t),!1}setupWebSocketListeners(){this.wsClient.on("directMessage",e=>{this.handleIncomingDm(e)}),this.wsClient.on("groupMessage",e=>{this.handleIncomingGroup(e)}),this.wsClient.on("meetingMessage",e=>{this.handleIncomingMeeting(e)}),this.wsClient.on("systemNotify",e=>{this.systemNotifyHandler?.(e)}),this.wsClient.on("profileInfo",e=>{i.info(`[AgentClient] WebSocket profileInfo \u4E8B\u4EF6\u89E6\u53D1\uFF0CdisplayName: ${e.displayName}`),this.handleProfileInfo(e)}),this.wsClient.on("agentConfig",e=>{i.info("[AgentClient] WebSocket agentConfig \u4E8B\u4EF6\u89E6\u53D1"),this.configHandler&&this.configHandler(e??{})}),this.wsClient.on("agentStatus",e=>{i.info(`[AgentClient] WebSocket agentStatus \u4E8B\u4EF6\u89E6\u53D1: ${e.status}`)}),this.wsClient.on("disconnected",(e,t)=>{const n=t?.toString()||"";i.warn("[AgentClient] WebSocket \u65AD\u5F00\u8FDE\u63A5: code=%s, reason=%s, agentId=%s, \u6B63\u5728\u81EA\u52A8\u91CD\u8FDE",e,n,this.agentId)}),this.wsClient.on("error",e=>{i.error("[AgentClient] WebSocket \u9519\u8BEF: %s, stack=%s",e.message,e.stack)}),this.wsClient.on("reconnectFailed",()=>{i.error("[AgentClient] \u91CD\u8FDE\u5931\u8D25\uFF08\u5DF2\u8FBE\u91CD\u8BD5\u4E0A\u9650\uFF09\uFF0C\u505C\u6B62\u6D88\u606F\u5FAA\u73AF, agentId=%s",this.agentId),this.stop()}),this.wsClient.on("tokenRejected",()=>{i.error("[AgentClient] runtime token \u88AB 1008 \u62D2\u7EDD\u4E14\u5237\u65B0\u65E0\u53D8\u5316\uFF0C\u8FDB\u5165\u6162\u901F\u91CD\u8BD5\u7B49\u5F85\u65B0 token \u7B7E\u53D1: agentId=%s",this.agentId)}),this.wsClient.on("tokenRefreshFailed",e=>{i.error("[AgentClient] runtime token \u5237\u65B0\u8FDE\u7EED\u5931\u8D25 %s \u6B21\uFF0C\u8FDB\u5165\u6162\u901F\u91CD\u8BD5\u7B49\u5F85 bridge \u6062\u590D: agentId=%s",e,this.agentId)})}async register(){return i.info("[AgentClient] \u6B63\u5728\u6CE8\u518C Agent..."),await this.retryPendingLaunchBindingClaim(),this.hasPresetAgentId()?await this.registerWithExistingAgentId():await this.registerAsNewAgent()}hasPresetAgentId(){return!!(this.agentConfig.agentId&&this.agentConfig.agentId.trim().length>0)}async registerWithExistingAgentId(){const e=this.agentConfig.agentId;if(!e)throw new Error("Preset agentId is missing");this.agentId=e.trim();let t;try{t=await this.getProfileByAgentId(this.agentId)}catch(r){throw i.error("[AgentClient] getProfileByAgentId \u5931\u8D25 (presetAgentId=%s): %s",this.agentId,r instanceof Error?r.message:String(r)),r}this.displayName=t.displayName,this.projectId=t.projectId||null,i.info(`[AgentClient] \u4F7F\u7528\u9884\u8BBE AgentID \u7ED1\u5B9A\u5B9E\u4F8B: ${this.displayName} (${this.agentId})`),i.info(`[AgentClient] \u6240\u5C5E\u9879\u76EE: ${this.projectId||"(\u672A\u8BBE\u7F6E)"}`);try{await this.wsClient.connect(this.agentId)}catch(r){throw i.error("[AgentClient] WebSocket \u8FDE\u63A5\u5931\u8D25 (agentId=%s): %s",this.agentId,r instanceof Error?r.message:String(r)),r}i.info("[AgentClient] WebSocket \u8FDE\u63A5\u5DF2\u5EFA\u7ACB\uFF0CAgent \u73B0\u5728\u5DF2\u4E0A\u7EBF"),this.initializeStatusReporter();const n=await this.getProfileByAgentId(this.agentId);return this.displayName=n.displayName,this.projectId=n.projectId||null,u(n.roleName||"unknown-role",n.instanceName||this.agentId),{agentId:this.agentId,displayName:this.displayName,status:n.isOnline?"online":"offline",projectId:n.projectId,workspacePath:n.workspacePath,runtimeStatus:n.runtimeStatus,runtimeSessionId:n.runtimeSessionId}}async registerAsNewAgent(){const e=await this.httpClient.callTool("register",{roleName:this.agentConfig.roleName,projectId:this.agentConfig.projectId,workspacePath:this.agentConfig.workspacePath,prompt:this.agentConfig.prompt,runtimeBridgeBaseUrl:this.serverConfig.runtimeBridgeBaseUrl}),t=e.agentId;if(!t)throw new Error("Registration failed: agentId was not returned");return this.agentId=t,this.displayName=e.displayName,this.projectId=e.projectId||null,u(this.agentConfig.roleName||"unknown-role",e.instanceName||t),i.info(`[AgentClient] \u6CE8\u518C\u6210\u529F: ${this.displayName} (${this.agentId})`),i.info(`[AgentClient] \u72B6\u6001: ${e.status}`),i.info(`[AgentClient] \u6240\u5C5E\u9879\u76EE: ${this.projectId||"(\u672A\u8BBE\u7F6E)"}`),await this.wsClient.connect(this.agentId),i.info("[AgentClient] WebSocket \u8FDE\u63A5\u5DF2\u5EFA\u7ACB\uFF0CAgent \u73B0\u5728\u5DF2\u4E0A\u7EBF"),this.initializeStatusReporter(),e.isExisting===!1&&this.newCharacterHandler&&this.newCharacterHandler(),e}async unregister(){i.info("[AgentClient] \u6B63\u5728\u6CE8\u9500 Agent..."),this.agentId&&await this.httpClient.callTool("unregister",{agentId:this.agentId}),this.stopRuntimeTokenRefresh(),this.wsClient.disconnect(),this.agentId=null,this.displayName=null,this.projectId=null,this.isRunning=!1,i.info("[AgentClient] \u5DF2\u6CE8\u9500")}async discoverColleagues(){return await this.httpClient.callTool("discover_colleague",{agentId:this.agentId})}async discoverGroupRooms(){return this.ensureRegistered(),await this.httpClient.callTool("discover_group_rooms",{agentId:this.agentId})}async listProjectMembers(){return this.ensureRegistered(),await this.httpClient.callTool("list_project_members",{agentId:this.agentId})}async hireColleague(e){return this.ensureRegistered(),await this.httpClient.callTool("hire_colleague",{...e,agentId:this.agentId})}async callAgentScopedTool(e,t){this.ensureRegistered();const n={...t,agentId:this.agentId};if(e==="create_meeting"){const r=typeof t.waitTimeoutMs=="number"?t.waitTimeoutMs:Number.NaN,s=Number.isFinite(r)&&r>0?Math.min(r,C):C;return await this.httpClient.callToolOnce(e,{...n,waitTimeoutMs:s},0)}return await this.httpClient.callTool(e,n)}async reportMemoryStats(e){await this.callAgentScopedTool("report_memory_stats",{memoryStats:e})}async sendGroupMessage(e,t,n,r,s){this.ensureRegistered();const a=t||this.projectId||this.agentConfig.projectId;return await this.httpClient.callTool("send_group_message",{agentId:this.agentId,projectId:a,roomId:n,content:e,card:r,replyTo:s})}async sendDirectMessage(e,t,n=!1,r,s,a,c){this.ensureRegistered();const g={agentId:this.agentId,targetId:e,content:t,requireReply:n,waitReply:n,replyToCallId:r,card:a,replyTo:c};if(typeof s=="number"&&s>0&&(g.timeoutMs=s),n){const o=typeof s=="number"&&s>0?s+3e4:0;return await this.httpClient.callToolOnce("send_dm",g,o)}return await this.httpClient.callTool("send_dm",g)}async sendCallAndWaitReply(e,t,n=6e4){const r=await this.sendDirectMessage(e,t,!0,void 0,n);if(r.reply)return r.reply;throw new Error("No reply received for call-style direct message before timeout")}async replyToCall(e,t,n){return await this.sendDirectMessage(t,n,!1,e)}async sendEmail(e){return await this.callAgentScopedTool("send_email",e)}async listEmails(e){return await this.callAgentScopedTool("list_emails",e)}async readEmail(e){return await this.callAgentScopedTool("read_email",{mailId:e})}async replyEmail(e){return await this.callAgentScopedTool("reply_email",e)}async ackEmail(e){return await this.callAgentScopedTool("ack_email",{mailId:e})}async getDmHistory(e,t=50,n){this.ensureRegistered();const r={agentId:this.agentId,targetUserId:e,limit:t};return n&&(r.since=n),await this.httpClient.callTool("get_dm_history",r)}async getGroupHistory(e=50,t,n){if(this.ensureRegistered(),t){const o={projectId:this.projectId||this.agentConfig.projectId,roomId:t,limit:e};return n&&(o.since=n),await this.httpClient.callTool("get_group_history",o)}const r=await this.discoverGroupRooms(),s=this.projectId||this.agentConfig.projectId,a=this.collectRoomIds(r,s);if(a.length===0)return{messages:[],count:0};const g=(await Promise.all(a.map(async o=>{const l={projectId:s,roomId:o,limit:e};return n&&(l.since=n),await this.httpClient.callTool("get_group_history",l)}))).flatMap(o=>o.messages).sort((o,l)=>new Date(o.timestamp).getTime()-new Date(l.timestamp).getTime());return{messages:g,count:g.length}}async fetchUnreadMessages(e={}){this.ensureRegistered();const t=this.projectId||this.agentConfig.projectId,n={agentId:this.agentId,blockIfEmpty:e.blockIfEmpty??!1};e.since&&(n.since=e.since),e.blockTimeoutMs&&e.blockTimeoutMs>0&&(n.blockTimeoutMs=e.blockTimeoutMs),e.preemptiveJoinWaitMs!==void 0&&e.preemptiveJoinWaitMs!==null&&e.preemptiveJoinWaitMs>=0&&(n.preemptiveJoinWaitMs=e.preemptiveJoinWaitMs);const r=e.includePipelineTasks?"poll_message":"get_dm_messages";i.info("[AgentClient] fetchUnreadMessages \u5165\u53E3: tool=%s, blockIfEmpty=%s, blockTimeoutMs=%s, pollMessageTimeoutMs=%s, skipGroupMessages=%s, preemptiveJoinWaitMs=%s, agentId=%s",r,String(e.blockIfEmpty??!1),String(e.blockTimeoutMs??"-"),String(e.pollMessageTimeoutMs??"-"),String(e.skipGroupMessages??!1),String(e.preemptiveJoinWaitMs??"-"),this.agentId);const s=await this.fetchDirectMessagesWithRecovery(r,n,e.pollMessageTimeoutMs,e.propagatePollTimeout===!0);if(i.info("[AgentClient] fetchUnreadMessages \u79C1\u4FE1\u9636\u6BB5\u8FD4\u56DE: %s \u6761",Array.isArray(s.messages)?s.messages.length:0),e.skipGroupMessages)return i.info("[AgentClient] \u4F1A\u8BAE\u5FEB\u901F hydrate \u5DF2\u53D6\u5F97\u79C1\u4FE1\u54CD\u5E94\uFF0C\u8DF3\u8FC7\u7FA4\u804A\u53D1\u73B0\u5E76\u7ACB\u5373\u8FD4\u56DE: directMessages=%s",Array.isArray(s.messages)?s.messages.length:0),{directMessages:Array.isArray(s.messages)?s.messages:[],groupMessages:[]};let a;try{a=await this.discoverGroupRooms()}catch(o){i.warn("[AgentClient] \u53D1\u73B0\u7FA4\u623F\u95F4\u5931\u8D25\uFF0C\u672C\u6B21\u6309\u65E0\u7FA4\u6D88\u606F\u5904\u7406\uFF08\u5DF2\u53D6\u5230\u7684\u79C1\u4FE1\u4E0D\u53D7\u5F71\u54CD\uFF09: %s",o instanceof Error?o.message:String(o)),a={groups:[]}}const c=this.collectRoomIds(a,t),g=await Promise.all(c.map(async o=>{const l={agentId:this.agentId,projectId:t,roomId:o};e.since&&(l.since=e.since);try{return await this.httpClient.callTool("get_group_messages",l)}catch(d){return i.warn("[AgentClient] \u8DF3\u8FC7\u7FA4\u623F\u95F4\u672A\u8BFB\u8865\u62C9\u5931\u8D25: roomId=%s, error=%s",o,d instanceof Error?d.message:String(d)),{messages:[],currentReadPos:0,hasMore:!1}}}));return{directMessages:Array.isArray(s.messages)?s.messages:[],groupMessages:g.flatMap(o=>this.normalizeGroupMessages(o)).sort((o,l)=>new Date(o.timestamp).getTime()-new Date(l.timestamp).getTime())}}async markDmRead(e){if(e.length===0)return new Set;this.ensureRegistered();try{const t=await this.httpClient.callTool("mark_dm_read",{agentId:this.agentId,msgIds:e}),n=new Set(Array.isArray(t?.deliverableMsgIds)?t.deliverableMsgIds:[]),r=e.filter(s=>!n.has(s));return r.length>0?i.warn("[AgentClient] mark_dm_read \u786E\u8BA4\u540E\u5C06\u6709 %d \u6761\u6D88\u606F\u88AB\u4E22\u5F03\u4E0D\u4EA4\u4ED8: \u8BF7\u6C42=%s, \u53EF\u4EA4\u4ED8=%s, \u88AB\u4E22\u5F03=%s",r.length,JSON.stringify(e),JSON.stringify([...n]),JSON.stringify(r)):i.info("[AgentClient] mark_dm_read \u786E\u8BA4\u5B8C\u6210: %d \u6761\u5168\u90E8\u53EF\u4EA4\u4ED8",e.length),n}catch(t){throw i.warn("[AgentClient] mark_dm_read \u8BF7\u6C42\u5931\u8D25\uFF08\u5C06\u964D\u7EA7\u4E3A\u76F4\u63A5\u4EA4\u4ED8\uFF09: %s",t instanceof Error?t.message:String(t)),t}}async markGroupRead(e,t){if(t.length===0)return new Set;this.ensureRegistered();const n=await this.httpClient.callTool("mark_group_read",{agentId:this.agentId,roomId:e,msgIds:t});return new Set(Array.isArray(n?.deliverableMsgIds)?n.deliverableMsgIds:[])}async markNotificationRead(e){if(e.length!==0){this.ensureRegistered();try{await this.httpClient.callTool("mark_notification_read",{agentId:this.agentId,msgIds:e})}catch{}}}async markMeetingRead(e){if(e.length!==0){this.ensureRegistered();try{await this.httpClient.callTool("mark_meeting_read",{agentId:this.agentId,msgIds:e})}catch{}}}async fetchBrowserListenerEvents(){const e=this.serverConfig.runtimeBridgeBaseUrl,t=this.agentId;if(!e||!t)return i.info("[AgentClient] fetchBrowserListenerEvents \u8DF3\u8FC7: bridgeBaseUrl=%s, agentId=%s",e||"(\u7A7A)",t||"(\u7A7A)"),[];try{const n=`${e}/runtime/browser-listeners/${encodeURIComponent(t)}/events`,r=this.serverConfig.runtimeAccessToken||"";i.debug("[AgentClient] \u62C9\u53D6\u76D1\u542C\u5668\u4E8B\u4EF6: url=%s, tokenLen=%d",n,r.length);const s=await fetch(n,{method:"GET",headers:{"X-Runtime-Token":r},signal:AbortSignal.timeout(3e3)});if(!s.ok)return i.warn("[AgentClient] \u62C9\u53D6\u76D1\u542C\u5668\u4E8B\u4EF6\u5931\u8D25: HTTP %s, url=%s",s.status,n),[];const a=await s.json();return!a.ok||!Array.isArray(a.events)?(i.warn("[AgentClient] \u62C9\u53D6\u76D1\u542C\u5668\u4E8B\u4EF6\u54CD\u5E94\u5F02\u5E38: ok=%s, eventsType=%s",a.ok,Array.isArray(a.events)?"array":typeof a.events),[]):(i.debug("[AgentClient] \u62C9\u53D6\u76D1\u542C\u5668\u4E8B\u4EF6\u6210\u529F: %d \u6761\u4E8B\u4EF6",a.events.length),a.events)}catch(n){return i.warn("[AgentClient] \u62C9\u53D6\u76D1\u542C\u5668\u4E8B\u4EF6\u5F02\u5E38: %s",n instanceof Error?n.message:String(n)),[]}}async fetchPluginEvents(){const e=this.serverConfig.runtimeBridgeBaseUrl,t=this.agentId;if(!e||!t)return{revision:0,events:[]};try{const n=`${e}/runtime/plugin-events/${encodeURIComponent(t)}/events`,r=this.serverConfig.runtimeAccessToken||"",s=await fetch(n,{method:"GET",headers:{"X-Runtime-Token":r},signal:AbortSignal.timeout(3e3)});if(!s.ok)return i.warn("[AgentClient] \u62C9\u53D6\u63D2\u4EF6\u4E8B\u4EF6\u5931\u8D25: HTTP %s, url=%s",s.status,n),{revision:0,events:[]};const a=await s.json();return!a.ok||!Array.isArray(a.events)?(i.warn("[AgentClient] \u62C9\u53D6\u63D2\u4EF6\u4E8B\u4EF6\u54CD\u5E94\u5F02\u5E38: ok=%s",String(a.ok)),{revision:0,events:[]}):(i.debug("[AgentClient] \u62C9\u53D6\u63D2\u4EF6\u4E8B\u4EF6\u6210\u529F: %d \u6761\u4E8B\u4EF6, revision=%s",a.events.length,String(a.revision??0)),{revision:a.revision??0,events:a.events})}catch(n){return i.warn("[AgentClient] \u62C9\u53D6\u63D2\u4EF6\u4E8B\u4EF6\u5F02\u5E38: %s",n instanceof Error?n.message:String(n)),{revision:0,events:[]}}}async notifyBridgeForceMessage(){const e=this.serverConfig.runtimeBridgeBaseUrl,t=this.agentId;if(!(!e||!t))try{const n=`${e}/runtime/sessions/${encodeURIComponent(t)}/notify-force-message`,r=this.serverConfig.runtimeAccessToken||"",s=await fetch(n,{method:"POST",headers:{"X-Runtime-Token":r},signal:AbortSignal.timeout(3e3)});s.ok||i.warn("[AgentClient] \u901A\u77E5 bridge \u5F3A\u5236\u6D88\u606F\u5931\u8D25: HTTP %s, url=%s",s.status,n)}catch(n){i.warn("[AgentClient] \u901A\u77E5 bridge \u5F3A\u5236\u6D88\u606F\u5F02\u5E38: %s",n instanceof Error?n.message:String(n))}}async fetchDirectMessagesWithRecovery(e,t,n,r=!1){if(e==="poll_message"){i.info("[AgentClient] fetchDirectMessagesWithRecovery \u5165\u53E3: tool=poll_message, pollMessageTimeoutMs=%s, agentId=%s",String(n??"(\u9ED8\u8BA4)"),String(t?.agentId??""));try{const s=await this.httpClient.callToolOnce(e,t,n);return i.info("[AgentClient] fetchDirectMessagesWithRecovery poll_message \u6210\u529F\u8FD4\u56DE: %s \u6761",Array.isArray(s?.messages)?s.messages.length:0),s}catch(s){if(this.isRecoverableLongPollError(s)){if(r)throw new T(s instanceof Error?s.message:String(s));return i.warn("[AgentClient] poll_message \u5355\u6B21\u957F\u8F6E\u8BE2\u8D85\u65F6\uFF0C\u6309\u7A7A\u7ED3\u679C\u9000\u907F\u540E\u7EE7\u7EED\u7B49\u5F85:",s),{messages:[]}}throw s}}return await this.httpClient.callTool(e,t)}isRecoverableLongPollError(e){return e instanceof Error?/MCP tool poll_message call failed: 503(?:\s|$)/.test(e.message)||/MCP tool poll_message timed out after \d+ms/.test(e.message):!1}normalizeGroupMessages(e){return Array.isArray(e.messages)?e.messages.filter(t=>!!(t&&typeof t=="object"&&typeof t.msgId=="number"&&typeof t.senderId=="string"&&typeof t.content=="string"&&typeof t.timestamp=="string")):[]}collectRoomIds(e,t){const n=e.groups.filter(r=>r.projectId===t).map(r=>r.id);return Array.from(new Set(n))}async getProfile(){this.ensureRegistered();const e=this.agentId;if(!e)throw new Error("Agent is not registered");return{...await this.getProfileByAgentId(e),describe:this.agentConfig.describe}}async getProfileByAgentId(e){return await this.httpClient.callTool("get_profile",{agentId:e})}async getMyTasks(){return this.ensureRegistered(),await this.httpClient.callTool("my_task",{agentId:this.agentId})}async listTaskNodeIterations(e={}){return this.ensureRegistered(),await this.httpClient.callTool("list_task_node_iterations",{agentId:this.agentId,...e})}async createTaskInstanceComment(e){this.ensureRegistered();const t={agentId:this.agentId,...e};return await this.httpClient.callTool("create_task_instance_comment",t)}async submitTaskResult(e,t,n,r,s){this.ensureRegistered();const a={agentId:this.agentId,nodeId:e,outputPayload:t};return(Array.isArray(n)&&n.length>0||typeof n=="string"&&n.trim().length>0)&&(a.changeLog=n),typeof r=="string"&&r.trim().length>0&&(a.handoverNote=r),s&&Array.isArray(s)&&s.length>0&&(a.deliverables=s),await this.httpClient.callTool("submit_task_result",a)}async startTaskRollback(e){return this.ensureRegistered(),await this.httpClient.callTool("start_task_rollback",{agentId:this.agentId,...e})}async finishTaskRollback(e){return this.ensureRegistered(),await this.httpClient.callTool("finish_task_rollback",{agentId:this.agentId,...e})}async getDebugLogConfig(){return await this.httpClient.callTool("get_debug_log_config",{agentId:this.agentId})}async queryDebugLogs(e){return this.ensureRegistered(),await this.httpClient.callTool("query_debug_logs",{...e})}async queryFileChangesHistory(e){return this.ensureRegistered(),await this.httpClient.callTool("query_file_changes_history",{...e})}async getRuntimeFeatures(){return await this.httpClient.fetchRuntimeFeatures()}async listLaunchConfigs(){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_list",{})}async createLaunchConfig(e){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_create",{...e})}async updateLaunchConfig(e){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_update",{...e})}async deleteLaunchConfig(e){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_delete",{configId:e})}async startLaunchConfig(e){this.ensureRegistered();const t=Math.max(0,Math.min(3e5,Number(e.wait_timeout_ms)||0));return t>0?await this.httpClient.callToolOnce("launch_config_start",e,t+6e4):await this.httpClient.callTool("launch_config_start",{...e})}async restartLaunchConfig(e){this.ensureRegistered();const t=Math.max(0,Math.min(3e5,Number(e.wait_timeout_ms)||0));return t>0?await this.httpClient.callToolOnce("launch_config_restart",e,t+6e4):await this.httpClient.callTool("launch_config_restart",{...e})}async stopLaunchConfig(e){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_stop",{configId:e})}async getLaunchLogs(e){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_logs",{...e})}async listLaunchRuns(){return this.ensureRegistered(),await this.httpClient.callTool("launch_config_status",{})}async listAbilityMarket(e={}){return this.ensureRegistered(),await this.httpClient.callTool("list_ability_market",{...e})}async installAbilityMarketItem(e){return this.ensureRegistered(),await this.httpClient.callTool("install_ability_market_item",{...e})}async uninstallAbilityMarketItem(e){return this.ensureRegistered(),await this.httpClient.callTool("uninstall_ability_market_item",{...e})}async abilityDevIde(e){return this.ensureRegistered(),await this.httpClient.callTool("ability_dev_ide",{...e})}async formalAbility(e){return this.ensureRegistered(),await this.httpClient.callTool("formal_ability",{...e})}async listMyAbilities(e={}){return this.ensureRegistered(),await this.httpClient.callTool("list_my_abilities",{...e})}start(e,t){if(this.isRunning){i.warn("[AgentClient] \u6D88\u606F\u5FAA\u73AF\u5DF2\u5728\u8FD0\u884C\u4E2D");return}this.isDegradedMode||this.ensureRegistered(),this.messageHandler=e,this.profileHandler=t?.profileHandler||null,this.configHandler=t?.configHandler||null,this.systemNotifyHandler=t?.systemNotifyHandler||null,this.isRunning=!0,i.info(`[AgentClient] start() \u88AB\u8C03\u7528\uFF0CcachedProfile: ${this.cachedProfile?"\u5B58\u5728":"\u4E0D\u5B58\u5728"}, profileHandler: ${this.profileHandler?"\u5DF2\u8BBE\u7F6E":"\u672A\u8BBE\u7F6E"}, \u964D\u7EA7\u6A21\u5F0F: ${this.isDegradedMode?"\u662F":"\u5426"}`),this.cachedProfile&&this.profileHandler&&(i.info(`[AgentClient] \u5904\u7406\u7F13\u5B58\u7684 Profile \u4FE1\u606F: ${this.cachedProfile.displayName}`),this.profileHandler(this.cachedProfile),this.cachedProfile=null),t?.pollMode??!1?(i.warn("[AgentClient] \u542F\u52A8\u6D88\u606F\u4E3B\u5FAA\u73AF\uFF08HTTP\u8F6E\u8BE2\u6A21\u5F0F - \u4E0D\u63A8\u8350\uFF09"),this.messageLoop()):i.info("[AgentClient] \u542F\u52A8\u6D88\u606F\u4E3B\u5FAA\u73AF\uFF08WebSocket\u63A8\u9001\u6A21\u5F0F - \u63A8\u8350\uFF09")}stop(){this.isRunning=!1,this.pollTimer&&(clearTimeout(this.pollTimer),this.pollTimer=null),this.stopRuntimeTokenRefresh(),i.info("[AgentClient] \u6D88\u606F\u4E3B\u5FAA\u73AF\u5DF2\u505C\u6B62")}async messageLoop(){for(;this.isRunning;)try{await this.delay(I)}catch(e){i.error("[AgentClient] \u6D88\u606F\u5FAA\u73AF\u9519\u8BEF:",e),await this.delay(5e3)}}handleIncomingDm(e){e.senderId!==this.agentId&&this.processMessage(e)}handleIncomingGroup(e){e.senderId!==this.agentId&&this.processMessage(e)}handleIncomingMeeting(e){!e||e.senderId===this.agentId||this.processMessage(e)}handleProfileInfo(e){i.info(`[AgentClient] \u6536\u5230 Profile \u4FE1\u606F: ${e.displayName} (${e.roleName})`),e.projectId&&(this.projectId=e.projectId,i.info(`[AgentClient] \u66F4\u65B0\u6240\u5C5E\u9879\u76EE: ${this.projectId}`)),e.roleName&&e.roleName!==this.agentConfig.roleName&&(i.info(`[AgentClient] \u540C\u6B65\u89D2\u8272\u540D: "${this.agentConfig.roleName||"(\u7A7A)"}" -> "${e.roleName}"`),this.agentConfig.roleName=e.roleName),e.roleName&&u(e.roleName,e.instanceName||this.agentId||""),this.profileHandler?this.profileHandler(e):(i.info("[AgentClient] profileHandler \u672A\u8BBE\u7F6E\uFF0C\u7F13\u5B58 Profile \u4FE1\u606F"),this.cachedProfile=e)}async processMessage(e){if(!this.messageHandler)return;const t=typeof e.msgId=="string";i.info(`[AgentClient] \u6536\u5230${t?"\u79C1\u4FE1":"\u7FA4\u6D88\u606F"}\u6765\u81EA ${e.senderName}: ${e.content.substring(0,50)}...`);try{const n=await this.messageHandler(e);if(t){const r=e;r.requireReply&&r.callId&&await this.replyToCall(r.callId,r.senderId,n||"\u5DF2\u6536\u5230\u6D88\u606F\uFF0C\u6B63\u5728\u5904\u7406\u4E2D...")}}catch(n){const r=typeof e.msgId=="string";if(i.error("[AgentClient] \u5904\u7406\u6D88\u606F\u5931\u8D25: type=%s, senderId=%s, senderName=%s, msgId=%s, error=%s",r?"\u79C1\u4FE1":"\u7FA4\u6D88\u606F",e.senderId,e.senderName,e.msgId,n instanceof Error?n.message:String(n)),r){const s=e;s.requireReply&&s.callId&&await this.replyToCall(s.callId,s.senderId,`\u5904\u7406\u5931\u8D25: ${n}`)}}}ensureRegistered(){if(!this.agentId)throw new Error("Agent is not registered")}delay(e){return new Promise(t=>{this.pollTimer=setTimeout(t,e)})}onNewCharacter(e){this.newCharacterHandler=e}getState(){return{agentId:this.agentId,displayName:this.displayName,projectId:this.projectId,isConnected:this.wsClient.isConnected(),isRunning:this.isRunning}}getAgentConfig(){return this.agentConfig}getServerConfig(){return this.serverConfig}reloadConfig(){h.loadConfig(),this.agentConfig=h.getAgentConfig(),i.info(`[AgentClient] \u914D\u7F6E\u5DF2\u91CD\u65B0\u52A0\u8F7D\uFF0C\u89D2\u8272: ${this.agentConfig.roleName}`)}enterDegradedMode(){this.isDegradedMode=!0,i.warn("[AgentClient] \u8FDB\u5165\u964D\u7EA7\u6A21\u5F0F\uFF0C\u5C06\u5728\u540E\u53F0\u6301\u7EED\u5C1D\u8BD5\u91CD\u8FDE")}exitDegradedMode(){this.isDegradedMode=!1,i.info("[AgentClient] \u9000\u51FA\u964D\u7EA7\u6A21\u5F0F")}isInDegradedMode(){return this.isDegradedMode}async retryRegistrationInBackground(e,t){let n=0;(async()=>{for(;this.isDegradedMode;)try{i.info(`[AgentClient] \u964D\u7EA7\u6A21\u5F0F\uFF1A\u5C1D\u8BD5\u91CD\u65B0\u6CE8\u518C (${n+1}/${t===-1?"\u65E0\u9650":t})`);const s=await this.register();i.info(`[AgentClient] \u964D\u7EA7\u6A21\u5F0F\uFF1A\u6CE8\u518C\u6210\u529F - ${s.displayName} (${s.agentId})`),this.exitDegradedMode(),this.messageHandler&&this.start(this.messageHandler);return}catch(s){n++;const a=s instanceof Error?s.message:String(s);if(i.warn(`[AgentClient] \u964D\u7EA7\u6A21\u5F0F\uFF1A\u6CE8\u518C\u5931\u8D25 (${n}/${t===-1?"\u65E0\u9650":t}): ${a}`),t>0&&n>=t){i.error("[AgentClient] \u964D\u7EA7\u6A21\u5F0F\uFF1A\u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570\uFF0C\u505C\u6B62\u91CD\u8FDE"),this.isDegradedMode=!1;return}await new Promise(c=>setTimeout(c,e))}})().catch(s=>{i.error("[AgentClient] \u964D\u7EA7\u6A21\u5F0F\u540E\u53F0\u91CD\u8BD5\u5FAA\u73AF\u5F02\u5E38\u9000\u51FA: error=%s, stack=%s",s instanceof Error?s.message:String(s),s instanceof Error?s.stack:"(no stack)")})}initializeStatusReporter(){if(!this.agentId){i.warn("[AgentClient] \u65E0\u6CD5\u521D\u59CB\u5316\u72B6\u6001\u62A5\u544A\u5668\uFF1AagentId \u4E3A\u7A7A");return}this.statusReporter=new A({agentId:this.agentId,sendStatusUpdate:e=>{this.wsClient.send({type:"AGENT_STATUS",data:e,timestamp:new Date().toISOString()})}}),w(e=>this.reportMcpNodeLog(e)),this.startRuntimeTokenRefresh(),i.info("[AgentClient] \u72B6\u6001\u62A5\u544A\u5668\u5DF2\u521D\u59CB\u5316")}startRuntimeTokenRefresh(){this.stopRuntimeTokenRefresh();const e=this.serverConfig.runtimeTokenRefreshIntervalMs;if(!e||e<=0){i.warn("[AgentClient] runtimeTokenRefreshIntervalMs \u672A\u914D\u7F6E\u6216\u65E0\u6548\uFF0C\u8DF3\u8FC7\u4E3B\u52A8\u7EED\u671F");return}const t=this.agentId;if(!t){i.warn("[AgentClient] agentId \u4E3A\u7A7A\uFF0C\u8DF3\u8FC7\u4E3B\u52A8\u7EED\u671F");return}this.runtimeTokenRefreshTimer=setInterval(async()=>{try{await this.httpClient.refreshRuntimeAccessToken(t)&&i.info("[AgentClient] runtimeAccessToken \u5DF2\u4E3B\u52A8\u7EED\u671F")}catch(n){i.warn("[AgentClient] \u4E3B\u52A8\u7EED\u671F runtimeAccessToken \u5931\u8D25: %s",n instanceof Error?n.message:String(n)),n instanceof Error&&n.stack&&i.warn("[AgentClient] \u4E3B\u52A8\u7EED\u671F\u5F02\u5E38\u5806\u6808:",n.stack)}},e),this.runtimeTokenRefreshTimer.unref?.(),i.info(`[AgentClient] runtime token \u4E3B\u52A8\u7EED\u671F\u5DF2\u542F\u52A8\uFF0C\u95F4\u9694 ${e}ms`)}stopRuntimeTokenRefresh(){this.runtimeTokenRefreshTimer&&(clearInterval(this.runtimeTokenRefreshTimer),this.runtimeTokenRefreshTimer=null)}reportMcpNodeLog(e){const t=this.wsClient;!this.agentId||!this.wsClient.isConnected()||typeof t.sendMcpNodeLog!="function"||t.sendMcpNodeLog(e)}getStatusReporter(){return this.statusReporter}}export{N as AgentClient,T as PollLongPollTimeoutError};
2
2
 
@@ -27,6 +27,8 @@ export declare class HttpClient {
27
27
 
28
28
  callTool<T = unknown>(toolName: string, args: Record<string, unknown>): Promise<T>;
29
29
 
30
+ private buildBusinessError;
31
+
30
32
  fetchRuntimeFeatures(): Promise<Record<string, unknown>>;
31
33
 
32
34
  callToolOnce<T = unknown>(toolName: string, args: Record<string, unknown>, timeoutMs?: number): Promise<T>;
@@ -1,2 +1,2 @@
1
- import{logger as c}from"./logger.js";import{meetingDebugLog as h}from"./meeting-debug-log.js";class g extends Error{errorCode;field;constructor(e,r,s){super(e),this.name="McpToolError",this.errorCode=r,this.field=s}}const w=12e4,T=5e3,y=3e4,p=1e3;function d(l){const e=l.trim();return e?e.length<=p?e:`${e.slice(0,p)}...(truncated)`:""}function C(l){return l.replace(/^((?:https?|wss?):\/\/(?:\[[^\]]+\]|[^/:?#]+):\d+):\d+(?=\/|$)/i,"$1")}function k(l){const e=l.toLowerCase();return e==="localhost"||e==="::1"||e==="[::1]"?"127.0.0.1":e}function m(l,e={}){const r=$(l,e);if(r)try{const s=new URL(r);return s.pathname=s.pathname.includes("/mcp/call")?s.pathname:`${s.pathname.replace(/\/$/,"")}/mcp/call`,s.search="",s.hash="",s.toString()}catch{return r.endsWith("/mcp/call")?r:`${r}/mcp/call`}}function $(l,e={}){const r=String(l||"").trim();if(!r)return;const s=C(r);try{const t=new URL(s);t.protocol==="ws:"?t.protocol="http:":t.protocol==="wss:"?t.protocol="https:":t.protocol=t.protocol.toLowerCase(),t.hostname=k(t.hostname);const n=e.fromAgentWebSocketUrl?t.pathname.replace(/\/ws\/agent\/?$/,""):t.pathname;return t.pathname=n,t.search="",t.hash="",t.toString().replace(/\/+$/,"")}catch{return(e.fromAgentWebSocketUrl?s.replace(/\/ws\/agent\/?$/i,""):s).replace(/\/+$/,"")||void 0}}const R=6e5;class M{serverConfig;mcpHttpUrl;tokenRefreshPromise=null;constructor(e){this.serverConfig=e,this.mcpHttpUrl=this.resolveMcpHttpUrl()}async callTool(e,r){await this.ensureRuntimeAccessToken();const s=Date.now()+this.resolveRetryMaxAccumulatedMs();let t=0;for(;;){t++;let n;try{n=await this.executeToolRequest(e,r)}catch(o){if(Date.now()<s&&this.isTransientError(o)){await this.delayForRetry(s,e,t);continue}throw c.warn("[HttpClient] MCP tool %s \u8BF7\u6C42\u4E0D\u53EF\u6062\u590D\u5F02\u5E38 (attempt=%s): %s",e,t,o instanceof Error?o.message:String(o)),o}if(n.status===401){if(c.warn(`[HttpClient] MCP Tool ${e} \u8FD4\u56DE 401\uFF0C\u5C1D\u8BD5\u5411 bridge \u5237\u65B0 token`),await this.tryRefreshToken(r)){let a;try{a=await this.executeToolRequest(e,r)}catch(f){if(Date.now()<s&&this.isTransientError(f)){await this.delayForRetry(s,e,t);continue}throw c.warn("[HttpClient] MCP tool %s 401\u91CD\u8BD5\u5F02\u5E38 (attempt=%s): %s",e,t,f instanceof Error?f.message:String(f)),f}if(!a.ok){if(Date.now()<s&&this.isRetryableHttpStatus(a.status)){a.body&&await a.body.cancel().catch(()=>{}),await this.delayForRetry(s,e,t);continue}const f=typeof a.text=="function"?d(await a.text().catch(()=>"")):"";throw new Error(`MCP tool ${e} call failed: ${a.status} ${a.statusText}${f?` - ${f}`:""}`)}const u=await a.json();if(typeof u.error=="string"&&u.error.trim().length>0)throw new Error(`MCP tool ${e} failed: ${u.error}`);return u}c.warn("[HttpClient] token \u5237\u65B0\u5931\u8D25\u6216\u65E0\u65B0 token\uFF0C\u8FD4\u56DE\u539F\u59CB 401 \u9519\u8BEF")}if(!n.ok){if(Date.now()<s&&this.isRetryableHttpStatus(n.status)){n.body&&await n.body.cancel().catch(()=>{}),await this.delayForRetry(s,e,t);continue}const o=typeof n.text=="function"?d(await n.text().catch(()=>"")):"";throw new Error(`MCP tool ${e} call failed: ${n.status} ${n.statusText}${o?` - ${o}`:""}`)}const i=await n.json();if(typeof i.error=="string"&&i.error.trim().length>0)throw new Error(`MCP tool ${e} failed: ${i.error}`);return i}}async fetchRuntimeFeatures(){if(!this.serverConfig.runtimeAccessToken)throw new Error("fetch runtime features skipped: runtimeAccessToken not ready");const e=this.mcpHttpUrl.replace(/\/mcp\/call(\/)?$/,"/mcp/features$1");let r;try{r=await fetch(e,{method:"POST",headers:this.buildRequestHeaders(),body:JSON.stringify({}),signal:AbortSignal.timeout(5e3)})}catch(t){throw c.warn("[HttpClient] \u67E5\u8BE2\u80FD\u529B\u5F00\u5173\u8BF7\u6C42\u5931\u8D25: %s",t instanceof Error?t.message:String(t)),new Error(`fetch runtime features failed: ${t instanceof Error?t.message:String(t)}`)}if(!r.ok)throw c.warn("[HttpClient] \u67E5\u8BE2\u80FD\u529B\u5F00\u5173\u5931\u8D25: status=%s, statusText=%s",r.status,r.statusText),new Error(`fetch runtime features failed: ${r.status} ${r.statusText}`);const s=await r.json();return!s||typeof s.features!="object"||s.features===null?{}:s.features}async callToolOnce(e,r,s=R){await this.ensureRuntimeAccessToken(),c.info("[HttpClient] callToolOnce \u5F00\u59CB: tool=%s, timeoutMs=%d, url=%s, agentId=%s",e,s,this.mcpHttpUrl,String(r?.agentId??"")),e==="poll_message"&&h("http.callToolOnce.start",`tool=${e} timeoutMs=${s} preemptiveJoinWaitMs=${String(r?.preemptiveJoinWaitMs??"-")}`);const t=a=>fetch(this.mcpHttpUrl,{method:"POST",headers:this.buildRequestHeaders(),body:JSON.stringify({tool:e,arguments:r}),signal:a}),n=Date.now();let i=await this.singleFetchWithTimeout(t,s,e);if(c.info("[HttpClient] callToolOnce \u6536\u5230\u54CD\u5E94: tool=%s, status=%d, \u8017\u65F6=%dms",e,i.status,Date.now()-n),e==="poll_message"&&h("http.callToolOnce.response",`status=${i.status} elapsedMs=${Date.now()-n}`),i.status===401&&(c.warn(`[HttpClient] MCP Tool ${e} \u8FD4\u56DE 401\uFF0C\u5C1D\u8BD5\u5411 bridge \u5237\u65B0 token`),await this.tryRefreshToken(r)&&(i=await this.singleFetchWithTimeout(t,s,e),c.info("[HttpClient] callToolOnce token \u5237\u65B0\u540E\u91CD\u8BD5\u6536\u5230\u54CD\u5E94: tool=%s, status=%d, \u7D2F\u8BA1\u8017\u65F6=%dms",e,i.status,Date.now()-n))),!i.ok){const a=typeof i.text=="function"?d(await this.readTextWithTimeout(i,s,e).catch(()=>"")):"";throw c.info("[HttpClient] callToolOnce \u975E 2xx \u54CD\u5E94: tool=%s, status=%d, body=%s",e,i.status,a||"(\u7A7A)"),new Error(`MCP tool ${e} call failed: ${i.status} ${i.statusText}${a?` - ${a}`:""}`)}const o=await this.parseJsonWithTimeout(i,s,e);if(c.info("[HttpClient] callToolOnce \u5B8C\u6210: tool=%s, \u603B\u8017\u65F6=%dms, error=%s",e,Date.now()-n,typeof o.error=="string"?o.error:"(\u65E0)"),e==="poll_message"){const a=Array.isArray(o.messages)?o.messages:[];h("http.callToolOnce.parsed",`totalElapsedMs=${Date.now()-n} serverMessages=${a.length} `+JSON.stringify(a.map(u=>({msgId:u.msgId,channel:u.channel,sender:u.senderId}))))}if(typeof o.error=="string"&&o.error.trim().length>0){const a=typeof o.errorCode=="string"?o.errorCode:void 0,u=typeof o.field=="string"?o.field:void 0;throw new g(`MCP tool ${e} failed: ${o.error}`,a,u)}return o}async readTextWithTimeout(e,r,s){if(r<=0)return await e.text();let t;try{return await Promise.race([e.text(),new Promise((n,i)=>{t=setTimeout(()=>i(new Error(`MCP tool ${s} timed out after ${r}ms`)),r)})])}finally{t!==void 0&&clearTimeout(t)}}async parseJsonWithTimeout(e,r,s){if(r<=0)return await e.json();let t;try{return await Promise.race([e.json(),new Promise((n,i)=>{t=setTimeout(()=>i(new Error(`MCP tool ${s} timed out after ${r}ms`)),r)})])}finally{t!==void 0&&clearTimeout(t)}}async singleFetchWithTimeout(e,r,s){const t=new AbortController;let n;r>0&&(n=setTimeout(()=>t.abort(),r));try{return await e(t.signal)}catch(i){throw t.signal.aborted?(s==="poll_message"&&h("http.callToolOnce.timeout",`timeoutMs=${r} \u670D\u52A1\u7AEF\u53EF\u80FD\u4ECD\u5728\u6267\u884C\u540C\u4E00\u8BF7\u6C42\uFF08Callable \u5360\u7EBF\u81F3\u9884\u7B97\u7ED3\u675F\uFF09`),new Error(`MCP tool ${s} timed out after ${r}ms`)):i}finally{n!==void 0&&clearTimeout(n)}}async executeToolRequest(e,r){return await this.fetchWithTimeout(this.mcpHttpUrl,{method:"POST",headers:this.buildRequestHeaders(),body:JSON.stringify({tool:e,arguments:r})},`MCP tool ${e}`)}async fetchWithTimeout(e,r,s){const t=this.resolveRequestTimeoutMs(),n=new AbortController,i=setTimeout(()=>n.abort(),t);try{return await fetch(e,{...r,signal:n.signal})}catch(o){throw n.signal.aborted?new Error(`${s} timed out after ${t}ms`):o}finally{clearTimeout(i)}}resolveRequestTimeoutMs(){const e=this.serverConfig.mcpHttpRequestTimeoutMs;return typeof e=="number"&&Number.isFinite(e)&&e>0?e:w}resolveRetryIntervalMs(){const e=this.serverConfig.mcpRetryIntervalMs;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:T}resolveRetryMaxAccumulatedMs(){const e=this.serverConfig.mcpRetryMaxAccumulatedMs;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:y}isTransientError(e){if(!(e instanceof Error))return!1;const r=e.message;return!!(/timed out after \d+ms/.test(r)||/fetch failed/i.test(r)||/network/i.test(r)||/ECONNREFUSED/i.test(r)||/ECONNRESET/i.test(r))}isRetryableHttpStatus(e){return e>=500||e===429}async delayForRetry(e,r,s){const t=e-Date.now(),n=Math.min(this.resolveRetryIntervalMs(),Math.max(0,t));c.warn(`[HttpClient] MCP tool ${r} \u8BF7\u6C42\u5931\u8D25\uFF0C${n}ms \u540E\u91CD\u8BD5 (\u7B2C${s}\u6B21)`),n>0&&await new Promise(i=>setTimeout(i,n))}buildRequestHeaders(){const e={"Content-Type":"application/json"};return this.serverConfig.runtimeAccessToken&&(e["X-Runtime-Token"]=this.serverConfig.runtimeAccessToken,e.Authorization=`Bearer ${this.serverConfig.runtimeAccessToken}`),e}async ensureRuntimeAccessToken(){if(this.serverConfig.runtimeAccessToken||!this.serverConfig.runtimeBridgeBaseUrl){c.info("[HttpClient] ensureRuntimeAccessToken: tokenLen=%d, bridgeBaseUrl=%s",(this.serverConfig.runtimeAccessToken||"").length,this.serverConfig.runtimeBridgeBaseUrl||"(\u7A7A)");return}throw new Error("runtimeAccessToken is required; MCP nodes must claim a session token from launch binding")}async tryRefreshToken(e){if(this.tokenRefreshPromise)return this.tokenRefreshPromise;this.tokenRefreshPromise=this.doRefreshToken(e);try{return await this.tokenRefreshPromise}finally{this.tokenRefreshPromise=null}}async doRefreshToken(e){const r=this.serverConfig.runtimeBridgeBaseUrl;if(!r)return c.warn("[HttpClient] \u65E0 runtimeBridgeBaseUrl\uFF0C\u65E0\u6CD5\u5237\u65B0 token"),!1;const s=String(e?.agentId||"").trim();if(!s)return c.warn("[HttpClient] \u65E0 agentId\uFF0C\u65E0\u6CD5\u5237\u65B0 token"),!1;try{const t=await fetch(`${r}/runtime/binding/refresh-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agentId:s,currentToken:this.serverConfig.runtimeAccessToken||""})});if(!t.ok)return c.warn(`[HttpClient] bridge refresh-token \u8FD4\u56DE ${t.status}\uFF0C\u65E0\u6CD5\u5237\u65B0`),!1;const i=(await t.json()).runtimeAccessToken;return i?i===this.serverConfig.runtimeAccessToken?!1:(this.serverConfig.runtimeAccessToken=i,c.info("[HttpClient] runtimeAccessToken \u5DF2\u901A\u8FC7 bridge refresh \u66F4\u65B0"),!0):(c.warn("[HttpClient] bridge \u672A\u8FD4\u56DE\u65B0 token"),!1)}catch(t){return c.warn("[HttpClient] \u5237\u65B0 token \u5931\u8D25: %s",t instanceof Error?t.message:String(t)),t instanceof Error&&t.stack&&c.warn("[HttpClient] \u5237\u65B0 token \u5F02\u5E38\u5806\u6808:",t.stack),!1}}async refreshRuntimeAccessToken(e){return this.tryRefreshToken({agentId:e})}resolveMcpHttpUrl(){const e=this.serverConfig.mcpHttpUrl;if(e&&e.trim().length>0){const s=m(e);if(s)return s}const r=m(this.serverConfig.serverUrl,{fromAgentWebSocketUrl:!0});return r||this.serverConfig.serverUrl}getMcpHttpUrl(){return this.mcpHttpUrl}}export{M as HttpClient,g as McpToolError,$ as normalizeServerHttpBase};
1
+ import{logger as o}from"./logger.js";import{meetingDebugLog as h}from"./meeting-debug-log.js";class g extends Error{errorCode;field;constructor(e,t,s){super(e),this.name="McpToolError",this.errorCode=t,this.field=s}}const w=12e4,T=5e3,y=3e4,p=1e3;function d(l){const e=l.trim();return e?e.length<=p?e:`${e.slice(0,p)}...(truncated)`:""}function C(l){return l.replace(/^((?:https?|wss?):\/\/(?:\[[^\]]+\]|[^/:?#]+):\d+):\d+(?=\/|$)/i,"$1")}function k(l){const e=l.toLowerCase();return e==="localhost"||e==="::1"||e==="[::1]"?"127.0.0.1":e}function m(l,e={}){const t=R(l,e);if(t)try{const s=new URL(t);return s.pathname=s.pathname.includes("/mcp/call")?s.pathname:`${s.pathname.replace(/\/$/,"")}/mcp/call`,s.search="",s.hash="",s.toString()}catch{return t.endsWith("/mcp/call")?t:`${t}/mcp/call`}}function R(l,e={}){const t=String(l||"").trim();if(!t)return;const s=C(t);try{const r=new URL(s);r.protocol==="ws:"?r.protocol="http:":r.protocol==="wss:"?r.protocol="https:":r.protocol=r.protocol.toLowerCase(),r.hostname=k(r.hostname);const n=e.fromAgentWebSocketUrl?r.pathname.replace(/\/ws\/agent\/?$/,""):r.pathname;return r.pathname=n,r.search="",r.hash="",r.toString().replace(/\/+$/,"")}catch{return(e.fromAgentWebSocketUrl?s.replace(/\/ws\/agent\/?$/i,""):s).replace(/\/+$/,"")||void 0}}const $=6e5;class H{serverConfig;mcpHttpUrl;tokenRefreshPromise=null;constructor(e){this.serverConfig=e,this.mcpHttpUrl=this.resolveMcpHttpUrl()}async callTool(e,t){await this.ensureRuntimeAccessToken();const s=Date.now()+this.resolveRetryMaxAccumulatedMs();let r=0;for(;;){r++;let n;try{n=await this.executeToolRequest(e,t)}catch(a){if(Date.now()<s&&this.isTransientError(a)){await this.delayForRetry(s,e,r);continue}throw o.warn("[HttpClient] MCP tool %s \u8BF7\u6C42\u4E0D\u53EF\u6062\u590D\u5F02\u5E38 (attempt=%s): %s",e,r,a instanceof Error?a.message:String(a)),a}if(n.status===401){if(o.warn(`[HttpClient] MCP Tool ${e} \u8FD4\u56DE 401\uFF0C\u5C1D\u8BD5\u5411 bridge \u5237\u65B0 token`),await this.tryRefreshToken(t)){let c;try{c=await this.executeToolRequest(e,t)}catch(f){if(Date.now()<s&&this.isTransientError(f)){await this.delayForRetry(s,e,r);continue}throw o.warn("[HttpClient] MCP tool %s 401\u91CD\u8BD5\u5F02\u5E38 (attempt=%s): %s",e,r,f instanceof Error?f.message:String(f)),f}if(!c.ok){if(Date.now()<s&&this.isRetryableHttpStatus(c.status)){c.body&&await c.body.cancel().catch(()=>{}),await this.delayForRetry(s,e,r);continue}const f=typeof c.text=="function"?d(await c.text().catch(()=>"")):"";throw new Error(`MCP tool ${e} call failed: ${c.status} ${c.statusText}${f?` - ${f}`:""}`)}const u=await c.json();if(typeof u.error=="string"&&u.error.trim().length>0)throw this.buildBusinessError(e,u);return u}o.warn("[HttpClient] token \u5237\u65B0\u5931\u8D25\u6216\u65E0\u65B0 token\uFF0C\u8FD4\u56DE\u539F\u59CB 401 \u9519\u8BEF")}if(!n.ok){if(Date.now()<s&&this.isRetryableHttpStatus(n.status)){n.body&&await n.body.cancel().catch(()=>{}),await this.delayForRetry(s,e,r);continue}const a=typeof n.text=="function"?d(await n.text().catch(()=>"")):"";throw new Error(`MCP tool ${e} call failed: ${n.status} ${n.statusText}${a?` - ${a}`:""}`)}const i=await n.json();if(typeof i.error=="string"&&i.error.trim().length>0)throw this.buildBusinessError(e,i);return i}}buildBusinessError(e,t){const s=typeof t.errorCode=="string"?t.errorCode:void 0,r=typeof t.field=="string"?t.field:void 0;return new g(`MCP tool ${e} failed: ${t.error}`,s,r)}async fetchRuntimeFeatures(){if(!this.serverConfig.runtimeAccessToken)throw new Error("fetch runtime features skipped: runtimeAccessToken not ready");const e=this.mcpHttpUrl.replace(/\/mcp\/call(\/)?$/,"/mcp/features$1");let t;try{t=await fetch(e,{method:"POST",headers:this.buildRequestHeaders(),body:JSON.stringify({}),signal:AbortSignal.timeout(5e3)})}catch(r){throw o.warn("[HttpClient] \u67E5\u8BE2\u80FD\u529B\u5F00\u5173\u8BF7\u6C42\u5931\u8D25: %s",r instanceof Error?r.message:String(r)),new Error(`fetch runtime features failed: ${r instanceof Error?r.message:String(r)}`)}if(!t.ok)throw o.warn("[HttpClient] \u67E5\u8BE2\u80FD\u529B\u5F00\u5173\u5931\u8D25: status=%s, statusText=%s",t.status,t.statusText),new Error(`fetch runtime features failed: ${t.status} ${t.statusText}`);const s=await t.json();return!s||typeof s.features!="object"||s.features===null?{}:s.features}async callToolOnce(e,t,s=$){await this.ensureRuntimeAccessToken(),o.info("[HttpClient] callToolOnce \u5F00\u59CB: tool=%s, timeoutMs=%d, url=%s, agentId=%s",e,s,this.mcpHttpUrl,String(t?.agentId??"")),e==="poll_message"&&h("http.callToolOnce.start",`tool=${e} timeoutMs=${s} preemptiveJoinWaitMs=${String(t?.preemptiveJoinWaitMs??"-")}`);const r=c=>fetch(this.mcpHttpUrl,{method:"POST",headers:this.buildRequestHeaders(),body:JSON.stringify({tool:e,arguments:t}),signal:c}),n=Date.now();let i=await this.singleFetchWithTimeout(r,s,e);if(o.info("[HttpClient] callToolOnce \u6536\u5230\u54CD\u5E94: tool=%s, status=%d, \u8017\u65F6=%dms",e,i.status,Date.now()-n),e==="poll_message"&&h("http.callToolOnce.response",`status=${i.status} elapsedMs=${Date.now()-n}`),i.status===401&&(o.warn(`[HttpClient] MCP Tool ${e} \u8FD4\u56DE 401\uFF0C\u5C1D\u8BD5\u5411 bridge \u5237\u65B0 token`),await this.tryRefreshToken(t)&&(i=await this.singleFetchWithTimeout(r,s,e),o.info("[HttpClient] callToolOnce token \u5237\u65B0\u540E\u91CD\u8BD5\u6536\u5230\u54CD\u5E94: tool=%s, status=%d, \u7D2F\u8BA1\u8017\u65F6=%dms",e,i.status,Date.now()-n))),!i.ok){const c=typeof i.text=="function"?d(await this.readTextWithTimeout(i,s,e).catch(()=>"")):"";throw o.info("[HttpClient] callToolOnce \u975E 2xx \u54CD\u5E94: tool=%s, status=%d, body=%s",e,i.status,c||"(\u7A7A)"),new Error(`MCP tool ${e} call failed: ${i.status} ${i.statusText}${c?` - ${c}`:""}`)}const a=await this.parseJsonWithTimeout(i,s,e);if(o.info("[HttpClient] callToolOnce \u5B8C\u6210: tool=%s, \u603B\u8017\u65F6=%dms, error=%s",e,Date.now()-n,typeof a.error=="string"?a.error:"(\u65E0)"),e==="poll_message"){const c=Array.isArray(a.messages)?a.messages:[];h("http.callToolOnce.parsed",`totalElapsedMs=${Date.now()-n} serverMessages=${c.length} `+JSON.stringify(c.map(u=>({msgId:u.msgId,channel:u.channel,sender:u.senderId}))))}if(typeof a.error=="string"&&a.error.trim().length>0)throw this.buildBusinessError(e,a);return a}async readTextWithTimeout(e,t,s){if(t<=0)return await e.text();let r;try{return await Promise.race([e.text(),new Promise((n,i)=>{r=setTimeout(()=>i(new Error(`MCP tool ${s} timed out after ${t}ms`)),t)})])}finally{r!==void 0&&clearTimeout(r)}}async parseJsonWithTimeout(e,t,s){if(t<=0)return await e.json();let r;try{return await Promise.race([e.json(),new Promise((n,i)=>{r=setTimeout(()=>i(new Error(`MCP tool ${s} timed out after ${t}ms`)),t)})])}finally{r!==void 0&&clearTimeout(r)}}async singleFetchWithTimeout(e,t,s){const r=new AbortController;let n;t>0&&(n=setTimeout(()=>r.abort(),t));try{return await e(r.signal)}catch(i){throw r.signal.aborted?(s==="poll_message"&&h("http.callToolOnce.timeout",`timeoutMs=${t} \u670D\u52A1\u7AEF\u53EF\u80FD\u4ECD\u5728\u6267\u884C\u540C\u4E00\u8BF7\u6C42\uFF08Callable \u5360\u7EBF\u81F3\u9884\u7B97\u7ED3\u675F\uFF09`),new Error(`MCP tool ${s} timed out after ${t}ms`)):i}finally{n!==void 0&&clearTimeout(n)}}async executeToolRequest(e,t){return await this.fetchWithTimeout(this.mcpHttpUrl,{method:"POST",headers:this.buildRequestHeaders(),body:JSON.stringify({tool:e,arguments:t})},`MCP tool ${e}`)}async fetchWithTimeout(e,t,s){const r=this.resolveRequestTimeoutMs(),n=new AbortController,i=setTimeout(()=>n.abort(),r);try{return await fetch(e,{...t,signal:n.signal})}catch(a){throw n.signal.aborted?new Error(`${s} timed out after ${r}ms`):a}finally{clearTimeout(i)}}resolveRequestTimeoutMs(){const e=this.serverConfig.mcpHttpRequestTimeoutMs;return typeof e=="number"&&Number.isFinite(e)&&e>0?e:w}resolveRetryIntervalMs(){const e=this.serverConfig.mcpRetryIntervalMs;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:T}resolveRetryMaxAccumulatedMs(){const e=this.serverConfig.mcpRetryMaxAccumulatedMs;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:y}isTransientError(e){if(!(e instanceof Error))return!1;const t=e.message;return!!(/timed out after \d+ms/.test(t)||/fetch failed/i.test(t)||/network/i.test(t)||/ECONNREFUSED/i.test(t)||/ECONNRESET/i.test(t))}isRetryableHttpStatus(e){return e>=500||e===429}async delayForRetry(e,t,s){const r=e-Date.now(),n=Math.min(this.resolveRetryIntervalMs(),Math.max(0,r));o.warn(`[HttpClient] MCP tool ${t} \u8BF7\u6C42\u5931\u8D25\uFF0C${n}ms \u540E\u91CD\u8BD5 (\u7B2C${s}\u6B21)`),n>0&&await new Promise(i=>setTimeout(i,n))}buildRequestHeaders(){const e={"Content-Type":"application/json"};return this.serverConfig.runtimeAccessToken&&(e["X-Runtime-Token"]=this.serverConfig.runtimeAccessToken,e.Authorization=`Bearer ${this.serverConfig.runtimeAccessToken}`),e}async ensureRuntimeAccessToken(){if(this.serverConfig.runtimeAccessToken||!this.serverConfig.runtimeBridgeBaseUrl){o.info("[HttpClient] ensureRuntimeAccessToken: tokenLen=%d, bridgeBaseUrl=%s",(this.serverConfig.runtimeAccessToken||"").length,this.serverConfig.runtimeBridgeBaseUrl||"(\u7A7A)");return}throw new Error("runtimeAccessToken is required; MCP nodes must claim a session token from launch binding")}async tryRefreshToken(e){if(this.tokenRefreshPromise)return this.tokenRefreshPromise;this.tokenRefreshPromise=this.doRefreshToken(e);try{return await this.tokenRefreshPromise}finally{this.tokenRefreshPromise=null}}async doRefreshToken(e){const t=this.serverConfig.runtimeBridgeBaseUrl;if(!t)return o.warn("[HttpClient] \u65E0 runtimeBridgeBaseUrl\uFF0C\u65E0\u6CD5\u5237\u65B0 token"),!1;const s=String(e?.agentId||"").trim();if(!s)return o.warn("[HttpClient] \u65E0 agentId\uFF0C\u65E0\u6CD5\u5237\u65B0 token"),!1;try{const r=await fetch(`${t}/runtime/binding/refresh-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agentId:s,currentToken:this.serverConfig.runtimeAccessToken||""})});if(!r.ok)return o.warn(`[HttpClient] bridge refresh-token \u8FD4\u56DE ${r.status}\uFF0C\u65E0\u6CD5\u5237\u65B0`),!1;const i=(await r.json()).runtimeAccessToken;return i?i===this.serverConfig.runtimeAccessToken?!1:(this.serverConfig.runtimeAccessToken=i,o.info("[HttpClient] runtimeAccessToken \u5DF2\u901A\u8FC7 bridge refresh \u66F4\u65B0"),!0):(o.warn("[HttpClient] bridge \u672A\u8FD4\u56DE\u65B0 token"),!1)}catch(r){return o.warn("[HttpClient] \u5237\u65B0 token \u5931\u8D25: %s",r instanceof Error?r.message:String(r)),r instanceof Error&&r.stack&&o.warn("[HttpClient] \u5237\u65B0 token \u5F02\u5E38\u5806\u6808:",r.stack),!1}}async refreshRuntimeAccessToken(e){return this.tryRefreshToken({agentId:e})}resolveMcpHttpUrl(){const e=this.serverConfig.mcpHttpUrl;if(e&&e.trim().length>0){const s=m(e);if(s)return s}const t=m(this.serverConfig.serverUrl,{fromAgentWebSocketUrl:!0});return t||this.serverConfig.serverUrl}getMcpHttpUrl(){return this.mcpHttpUrl}}export{H as HttpClient,g as McpToolError,R as normalizeServerHttpBase};
2
2
 
@@ -45,11 +45,6 @@ export declare class McpServer {
45
45
  private urgentTaskHydrateRequested;
46
46
  private taskHydrateRetryBudget;
47
47
 
48
- private cachedPluginCatalog;
49
-
50
- private deliveredPluginNames;
51
- private pluginCatalogDrainCompactionSeq;
52
- private pluginCatalogLastSeenCompactionSeq;
53
48
  private static readonly MEETING_HYDRATE_RETRY_COUNT;
54
49
  private static readonly MEETING_HYDRATE_RETRY_DELAY_MS;
55
50
 
@@ -264,8 +259,6 @@ export declare class McpServer {
264
259
  private checkAllLocalNonUrgentNotifications;
265
260
  private buildPollResult;
266
261
 
267
- private shouldDeliverPluginCatalog;
268
-
269
262
  private parsePositiveIntegerEnv;
270
263
  private sleep;
271
264