@tachu/extensions 1.0.0-alpha.1

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 (210) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/LICENSE +201 -0
  3. package/README.md +1104 -0
  4. package/README_ZH.md +1082 -0
  5. package/dist/backends/file.d.ts +18 -0
  6. package/dist/backends/file.d.ts.map +1 -0
  7. package/dist/backends/file.js +85 -0
  8. package/dist/backends/file.js.map +1 -0
  9. package/dist/backends/index.d.ts +4 -0
  10. package/dist/backends/index.d.ts.map +1 -0
  11. package/dist/backends/index.js +4 -0
  12. package/dist/backends/index.js.map +1 -0
  13. package/dist/backends/terminal.d.ts +18 -0
  14. package/dist/backends/terminal.d.ts.map +1 -0
  15. package/dist/backends/terminal.js +81 -0
  16. package/dist/backends/terminal.js.map +1 -0
  17. package/dist/backends/web.d.ts +18 -0
  18. package/dist/backends/web.d.ts.map +1 -0
  19. package/dist/backends/web.js +55 -0
  20. package/dist/backends/web.js.map +1 -0
  21. package/dist/common/net.d.ts +39 -0
  22. package/dist/common/net.d.ts.map +1 -0
  23. package/dist/common/net.js +177 -0
  24. package/dist/common/net.js.map +1 -0
  25. package/dist/common/path.d.ts +51 -0
  26. package/dist/common/path.d.ts.map +1 -0
  27. package/dist/common/path.js +76 -0
  28. package/dist/common/path.js.map +1 -0
  29. package/dist/common/process.d.ts +19 -0
  30. package/dist/common/process.d.ts.map +1 -0
  31. package/dist/common/process.js +67 -0
  32. package/dist/common/process.js.map +1 -0
  33. package/dist/index.d.ts +13 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +13 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/mcp/index.d.ts +3 -0
  38. package/dist/mcp/index.d.ts.map +1 -0
  39. package/dist/mcp/index.js +3 -0
  40. package/dist/mcp/index.js.map +1 -0
  41. package/dist/mcp/sse-adapter.d.ts +82 -0
  42. package/dist/mcp/sse-adapter.d.ts.map +1 -0
  43. package/dist/mcp/sse-adapter.js +201 -0
  44. package/dist/mcp/sse-adapter.js.map +1 -0
  45. package/dist/mcp/stdio-adapter.d.ts +85 -0
  46. package/dist/mcp/stdio-adapter.d.ts.map +1 -0
  47. package/dist/mcp/stdio-adapter.js +203 -0
  48. package/dist/mcp/stdio-adapter.js.map +1 -0
  49. package/dist/memory/fs-memory-system.d.ts +147 -0
  50. package/dist/memory/fs-memory-system.d.ts.map +1 -0
  51. package/dist/memory/fs-memory-system.js +266 -0
  52. package/dist/memory/fs-memory-system.js.map +1 -0
  53. package/dist/memory/index.d.ts +2 -0
  54. package/dist/memory/index.d.ts.map +1 -0
  55. package/dist/memory/index.js +2 -0
  56. package/dist/memory/index.js.map +1 -0
  57. package/dist/observability/index.d.ts +3 -0
  58. package/dist/observability/index.d.ts.map +1 -0
  59. package/dist/observability/index.js +3 -0
  60. package/dist/observability/index.js.map +1 -0
  61. package/dist/observability/jsonl-emitter.d.ts +58 -0
  62. package/dist/observability/jsonl-emitter.d.ts.map +1 -0
  63. package/dist/observability/jsonl-emitter.js +96 -0
  64. package/dist/observability/jsonl-emitter.js.map +1 -0
  65. package/dist/observability/otel-emitter.d.ts +52 -0
  66. package/dist/observability/otel-emitter.d.ts.map +1 -0
  67. package/dist/observability/otel-emitter.js +143 -0
  68. package/dist/observability/otel-emitter.js.map +1 -0
  69. package/dist/providers/anthropic.d.ts +73 -0
  70. package/dist/providers/anthropic.d.ts.map +1 -0
  71. package/dist/providers/anthropic.js +521 -0
  72. package/dist/providers/anthropic.js.map +1 -0
  73. package/dist/providers/index.d.ts +5 -0
  74. package/dist/providers/index.d.ts.map +1 -0
  75. package/dist/providers/index.js +5 -0
  76. package/dist/providers/index.js.map +1 -0
  77. package/dist/providers/mock.d.ts +81 -0
  78. package/dist/providers/mock.d.ts.map +1 -0
  79. package/dist/providers/mock.js +160 -0
  80. package/dist/providers/mock.js.map +1 -0
  81. package/dist/providers/openai.d.ts +95 -0
  82. package/dist/providers/openai.d.ts.map +1 -0
  83. package/dist/providers/openai.js +529 -0
  84. package/dist/providers/openai.js.map +1 -0
  85. package/dist/providers/qwen.d.ts +145 -0
  86. package/dist/providers/qwen.d.ts.map +1 -0
  87. package/dist/providers/qwen.js +669 -0
  88. package/dist/providers/qwen.js.map +1 -0
  89. package/dist/rules/index.d.ts +9 -0
  90. package/dist/rules/index.d.ts.map +1 -0
  91. package/dist/rules/index.js +15 -0
  92. package/dist/rules/index.js.map +1 -0
  93. package/dist/rules/no-hallucination.md +11 -0
  94. package/dist/rules/no-sensitive-output.md +11 -0
  95. package/dist/rules/prefer-concise-response.md +11 -0
  96. package/dist/rules/require-tool-verification.md +11 -0
  97. package/dist/safety/default-gate.d.ts +112 -0
  98. package/dist/safety/default-gate.d.ts.map +1 -0
  99. package/dist/safety/default-gate.js +188 -0
  100. package/dist/safety/default-gate.js.map +1 -0
  101. package/dist/safety/index.d.ts +2 -0
  102. package/dist/safety/index.d.ts.map +1 -0
  103. package/dist/safety/index.js +2 -0
  104. package/dist/safety/index.js.map +1 -0
  105. package/dist/tools/_shared/web-client.d.ts +18 -0
  106. package/dist/tools/_shared/web-client.d.ts.map +1 -0
  107. package/dist/tools/_shared/web-client.js +46 -0
  108. package/dist/tools/_shared/web-client.js.map +1 -0
  109. package/dist/tools/apply-patch/descriptor.md +27 -0
  110. package/dist/tools/apply-patch/executor.d.ts +19 -0
  111. package/dist/tools/apply-patch/executor.d.ts.map +1 -0
  112. package/dist/tools/apply-patch/executor.js +193 -0
  113. package/dist/tools/apply-patch/executor.js.map +1 -0
  114. package/dist/tools/fetch-url/descriptor.md +44 -0
  115. package/dist/tools/fetch-url/executor.d.ts +28 -0
  116. package/dist/tools/fetch-url/executor.d.ts.map +1 -0
  117. package/dist/tools/fetch-url/executor.js +115 -0
  118. package/dist/tools/fetch-url/executor.js.map +1 -0
  119. package/dist/tools/index.d.ts +12 -0
  120. package/dist/tools/index.d.ts.map +1 -0
  121. package/dist/tools/index.js +286 -0
  122. package/dist/tools/index.js.map +1 -0
  123. package/dist/tools/list-dir/descriptor.md +29 -0
  124. package/dist/tools/list-dir/executor.d.ts +22 -0
  125. package/dist/tools/list-dir/executor.d.ts.map +1 -0
  126. package/dist/tools/list-dir/executor.js +48 -0
  127. package/dist/tools/list-dir/executor.js.map +1 -0
  128. package/dist/tools/read-file/descriptor.md +28 -0
  129. package/dist/tools/read-file/executor.d.ts +15 -0
  130. package/dist/tools/read-file/executor.d.ts.map +1 -0
  131. package/dist/tools/read-file/executor.js +22 -0
  132. package/dist/tools/read-file/executor.js.map +1 -0
  133. package/dist/tools/run-shell/descriptor.md +39 -0
  134. package/dist/tools/run-shell/executor.d.ts +20 -0
  135. package/dist/tools/run-shell/executor.d.ts.map +1 -0
  136. package/dist/tools/run-shell/executor.js +76 -0
  137. package/dist/tools/run-shell/executor.js.map +1 -0
  138. package/dist/tools/search-code/descriptor.md +31 -0
  139. package/dist/tools/search-code/executor.d.ts +23 -0
  140. package/dist/tools/search-code/executor.d.ts.map +1 -0
  141. package/dist/tools/search-code/executor.js +122 -0
  142. package/dist/tools/search-code/executor.js.map +1 -0
  143. package/dist/tools/shared.d.ts +47 -0
  144. package/dist/tools/shared.d.ts.map +1 -0
  145. package/dist/tools/shared.js +27 -0
  146. package/dist/tools/shared.js.map +1 -0
  147. package/dist/tools/web-fetch/descriptor.md +198 -0
  148. package/dist/tools/web-fetch/errors.d.ts +32 -0
  149. package/dist/tools/web-fetch/errors.d.ts.map +1 -0
  150. package/dist/tools/web-fetch/errors.js +91 -0
  151. package/dist/tools/web-fetch/errors.js.map +1 -0
  152. package/dist/tools/web-fetch/executor.d.ts +10 -0
  153. package/dist/tools/web-fetch/executor.d.ts.map +1 -0
  154. package/dist/tools/web-fetch/executor.js +191 -0
  155. package/dist/tools/web-fetch/executor.js.map +1 -0
  156. package/dist/tools/web-fetch/index.d.ts +4 -0
  157. package/dist/tools/web-fetch/index.d.ts.map +1 -0
  158. package/dist/tools/web-fetch/index.js +3 -0
  159. package/dist/tools/web-fetch/index.js.map +1 -0
  160. package/dist/tools/web-fetch/types.d.ts +157 -0
  161. package/dist/tools/web-fetch/types.d.ts.map +1 -0
  162. package/dist/tools/web-fetch/types.js +7 -0
  163. package/dist/tools/web-fetch/types.js.map +1 -0
  164. package/dist/tools/web-search/descriptor.md +89 -0
  165. package/dist/tools/web-search/errors.d.ts +33 -0
  166. package/dist/tools/web-search/errors.d.ts.map +1 -0
  167. package/dist/tools/web-search/errors.js +45 -0
  168. package/dist/tools/web-search/errors.js.map +1 -0
  169. package/dist/tools/web-search/executor.d.ts +10 -0
  170. package/dist/tools/web-search/executor.d.ts.map +1 -0
  171. package/dist/tools/web-search/executor.js +185 -0
  172. package/dist/tools/web-search/executor.js.map +1 -0
  173. package/dist/tools/web-search/index.d.ts +4 -0
  174. package/dist/tools/web-search/index.d.ts.map +1 -0
  175. package/dist/tools/web-search/index.js +3 -0
  176. package/dist/tools/web-search/index.js.map +1 -0
  177. package/dist/tools/web-search/types.d.ts +86 -0
  178. package/dist/tools/web-search/types.d.ts.map +1 -0
  179. package/dist/tools/web-search/types.js +7 -0
  180. package/dist/tools/web-search/types.js.map +1 -0
  181. package/dist/tools/write-file/descriptor.md +30 -0
  182. package/dist/tools/write-file/executor.d.ts +16 -0
  183. package/dist/tools/write-file/executor.d.ts.map +1 -0
  184. package/dist/tools/write-file/executor.js +18 -0
  185. package/dist/tools/write-file/executor.js.map +1 -0
  186. package/dist/transformers/document-to-text.d.ts +23 -0
  187. package/dist/transformers/document-to-text.d.ts.map +1 -0
  188. package/dist/transformers/document-to-text.js +69 -0
  189. package/dist/transformers/document-to-text.js.map +1 -0
  190. package/dist/transformers/image-to-text.d.ts +38 -0
  191. package/dist/transformers/image-to-text.d.ts.map +1 -0
  192. package/dist/transformers/image-to-text.js +82 -0
  193. package/dist/transformers/image-to-text.js.map +1 -0
  194. package/dist/transformers/index.d.ts +3 -0
  195. package/dist/transformers/index.d.ts.map +1 -0
  196. package/dist/transformers/index.js +3 -0
  197. package/dist/transformers/index.js.map +1 -0
  198. package/dist/vector/index.d.ts +3 -0
  199. package/dist/vector/index.d.ts.map +1 -0
  200. package/dist/vector/index.js +3 -0
  201. package/dist/vector/index.js.map +1 -0
  202. package/dist/vector/local-fs.d.ts +76 -0
  203. package/dist/vector/local-fs.d.ts.map +1 -0
  204. package/dist/vector/local-fs.js +153 -0
  205. package/dist/vector/local-fs.js.map +1 -0
  206. package/dist/vector/qdrant.d.ts +85 -0
  207. package/dist/vector/qdrant.d.ts.map +1 -0
  208. package/dist/vector/qdrant.js +208 -0
  209. package/dist/vector/qdrant.js.map +1 -0
  210. package/package.json +74 -0
@@ -0,0 +1,76 @@
1
+ import { resolve, relative, isAbsolute } from "node:path";
2
+ import { ValidationError } from "@tachu/core";
3
+ const PARENT_DIR_PREFIX = `..${"/"}`;
4
+ /**
5
+ * 把用户输入路径规范化到允许的根目录集合之一。
6
+ *
7
+ * 沙箱层级自上而下:
8
+ * 1. `sandboxWaived === true` → 本次调用豁免,直接返回 `resolve(...)` 后的绝对路径;
9
+ * 2. 否则检查候选路径是否落在任意 `allowedRoots` 之下;全部不满足时抛出
10
+ * `ValidationError(VALIDATION_PATH_ESCAPE)`。
11
+ *
12
+ * 该函数对"同时传入了相对路径与绝对路径"的语义:相对路径基于
13
+ * `allowedRoots[0]` 展开(通常就是 workspaceRoot),因为模型给出相对路径时
14
+ * 默认意图"相对工作区";绝对路径则直接 resolve 后再做白名单判定。
15
+ *
16
+ * @throws ValidationError 当沙箱未豁免且候选路径不在任何允许的根下
17
+ */
18
+ export const resolveAllowedPath = (targetPath, options) => {
19
+ const { allowedRoots, sandboxWaived } = options;
20
+ if (allowedRoots.length === 0) {
21
+ throw new ValidationError("VALIDATION_PATH_ESCAPE", "未配置任何允许的根目录:请检查宿主是否正确注入 allowedRoots。", { context: { targetPath } });
22
+ }
23
+ const primaryRoot = allowedRoots[0];
24
+ const candidate = isAbsolute(targetPath)
25
+ ? resolve(targetPath)
26
+ : resolve(primaryRoot, targetPath);
27
+ if (sandboxWaived === true) {
28
+ return candidate;
29
+ }
30
+ for (const root of allowedRoots) {
31
+ if (isInsideRoot(root, candidate)) {
32
+ return candidate;
33
+ }
34
+ }
35
+ throw new ValidationError("VALIDATION_PATH_ESCAPE", [
36
+ `路径越界:${targetPath} 不在任何允许的根目录内。`,
37
+ `允许的根:${allowedRoots.join(", ")}。`,
38
+ "可按以下任一方式放开该路径:",
39
+ " 1) 把目标改为相对路径(如 ./cat.txt)或上述根下的绝对路径;",
40
+ " 2) 在 tachu.config.ts 的 safety.allowedWriteRoots 追加该位置(静态白名单);",
41
+ " 3) 如果该工具本身需要用户确认(requiresApproval),审批通过会一次性放行本次调用。",
42
+ ].join("\n"), {
43
+ context: { allowedRoots: [...allowedRoots], targetPath, candidate },
44
+ });
45
+ };
46
+ const isInsideRoot = (root, candidate) => {
47
+ const rel = relative(root, candidate);
48
+ if (rel.length === 0)
49
+ return true; // candidate === root
50
+ if (rel.startsWith(".."))
51
+ return false;
52
+ if (rel.includes(PARENT_DIR_PREFIX))
53
+ return false;
54
+ return true;
55
+ };
56
+ /**
57
+ * 旧签名兼容层:仅允许 `workspaceRoot` 一个根,不走审批豁免。
58
+ *
59
+ * @deprecated 新代码请改用 {@link resolveAllowedPath},通过 `ToolExecutionContext.allowedRoots`
60
+ * 和 `ToolExecutionContext.sandboxWaived` 传递完整的白名单/审批状态。
61
+ */
62
+ export const resolveWorkspacePath = (workspaceRoot, targetPath) => {
63
+ return resolveAllowedPath(targetPath, { allowedRoots: [workspaceRoot] });
64
+ };
65
+ /**
66
+ * 将绝对路径转换为相对工作区路径。
67
+ *
68
+ * @param workspaceRoot 工作区根目录
69
+ * @param absPath 绝对路径
70
+ * @returns 相对路径(POSIX 风格)
71
+ */
72
+ export const toWorkspaceRelativePath = (workspaceRoot, absPath) => {
73
+ const rel = relative(workspaceRoot, absPath).replaceAll("\\", "/");
74
+ return rel.length === 0 ? "." : rel;
75
+ };
76
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/common/path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAuB9C,MAAM,iBAAiB,GAAG,KAAK,GAAG,EAAE,CAAC;AAErC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,UAAkB,EAClB,OAAkC,EAC1B,EAAE;IACV,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAChD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,eAAe,CACvB,wBAAwB,EACxB,uCAAuC,EACvC,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,EAAE,CAC5B,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAE,CAAC;IACrC,MAAM,SAAS,GAAG,UAAU,CAAC,UAAU,CAAC;QACtC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;QACrB,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAErC,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,IAAI,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;YAClC,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,eAAe,CACvB,wBAAwB,EACxB;QACE,QAAQ,UAAU,eAAe;QACjC,QAAQ,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QAClC,gBAAgB;QAChB,wCAAwC;QACxC,iEAAiE;QACjE,sDAAsD;KACvD,CAAC,IAAI,CAAC,IAAI,CAAC,EACZ;QACE,OAAO,EAAE,EAAE,YAAY,EAAE,CAAC,GAAG,YAAY,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE;KACpE,CACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,SAAiB,EAAW,EAAE;IAChE,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACtC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,qBAAqB;IACxD,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,IAAI,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,KAAK,CAAC;IAClD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,aAAqB,EAAE,UAAkB,EAAU,EAAE;IACxF,OAAO,kBAAkB,CAAC,UAAU,EAAE,EAAE,YAAY,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;AAC3E,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,aAAqB,EAAE,OAAe,EAAU,EAAE;IACxF,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACnE,OAAO,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AACtC,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 将流内容读取为字符串并限制最大字节数。
3
+ *
4
+ * @param stream 可读流
5
+ * @param maxBytes 最大字节数
6
+ * @returns 文本与截断标识
7
+ */
8
+ export declare const readStreamWithLimit: (stream: ReadableStream<Uint8Array> | null | undefined, maxBytes: number) => Promise<{
9
+ text: string;
10
+ truncated: boolean;
11
+ }>;
12
+ /**
13
+ * 尝试优雅结束子进程,必要时强制杀死。
14
+ *
15
+ * @param pid 进程 PID
16
+ * @param graceMs SIGTERM 后等待时长
17
+ */
18
+ export declare const terminateProcess: (pid: number, graceMs?: number) => Promise<void>;
19
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/common/process.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,SAAS,EACrD,UAAU,MAAM,KACf,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAwC9C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAU,KAAK,MAAM,EAAE,gBAAc,KAAG,OAAO,CAAC,IAAI,CAYhF,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * 将流内容读取为字符串并限制最大字节数。
3
+ *
4
+ * @param stream 可读流
5
+ * @param maxBytes 最大字节数
6
+ * @returns 文本与截断标识
7
+ */
8
+ export const readStreamWithLimit = async (stream, maxBytes) => {
9
+ if (!stream) {
10
+ return { text: "", truncated: false };
11
+ }
12
+ const reader = stream.getReader();
13
+ const chunks = [];
14
+ let total = 0;
15
+ let truncated = false;
16
+ while (true) {
17
+ const { done, value } = await reader.read();
18
+ if (done) {
19
+ break;
20
+ }
21
+ if (!value) {
22
+ continue;
23
+ }
24
+ const room = maxBytes - total;
25
+ if (room <= 0) {
26
+ truncated = true;
27
+ break;
28
+ }
29
+ if (value.byteLength > room) {
30
+ chunks.push(value.subarray(0, room));
31
+ total += room;
32
+ truncated = true;
33
+ break;
34
+ }
35
+ chunks.push(value);
36
+ total += value.byteLength;
37
+ }
38
+ const merged = new Uint8Array(total);
39
+ let offset = 0;
40
+ for (const chunk of chunks) {
41
+ merged.set(chunk, offset);
42
+ offset += chunk.byteLength;
43
+ }
44
+ return { text: new TextDecoder().decode(merged), truncated };
45
+ };
46
+ /**
47
+ * 尝试优雅结束子进程,必要时强制杀死。
48
+ *
49
+ * @param pid 进程 PID
50
+ * @param graceMs SIGTERM 后等待时长
51
+ */
52
+ export const terminateProcess = async (pid, graceMs = 3000) => {
53
+ try {
54
+ process.kill(pid, "SIGTERM");
55
+ }
56
+ catch {
57
+ return;
58
+ }
59
+ await new Promise((resolve) => setTimeout(resolve, graceMs));
60
+ try {
61
+ process.kill(pid, "SIGKILL");
62
+ }
63
+ catch {
64
+ // 进程已结束
65
+ }
66
+ };
67
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/common/process.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACtC,MAAqD,EACrD,QAAgB,EAC+B,EAAE;IACjD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAClC,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,IAAI,EAAE,CAAC;YACT,MAAM;QACR,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,QAAQ,GAAG,KAAK,CAAC;QAC9B,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACd,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM;QACR,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YACrC,KAAK,IAAI,IAAI,CAAC;YACd,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM;QACR,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnB,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC;IAC5B,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;AAC/D,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,GAAW,EAAE,OAAO,GAAG,IAAI,EAAiB,EAAE;IACnF,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACnE,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ;IACV,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ export { OpenAIProviderAdapter, AnthropicProviderAdapter, MockProviderAdapter, QwenProviderAdapter, type QwenChatRequest, type QwenImageParameters, } from "./providers";
2
+ export { toolDescriptors, toolExecutors, type ToolExecutor, type ToolExecutionContext, } from "./tools";
3
+ export { TerminalBackend, FileBackend, WebBackend } from "./backends";
4
+ export { LocalFsVectorStore, QdrantVectorStore } from "./vector";
5
+ export { ImageToTextTransformer, DocumentToTextTransformer } from "./transformers";
6
+ export { McpStdioAdapter, McpSseAdapter } from "./mcp";
7
+ export { OtelEmitter, JsonlEmitter } from "./observability";
8
+ export { BUILTIN_RULE_DESCRIPTOR_PATHS } from "./rules";
9
+ export { FsMemorySystem, sanitizeSessionId, type FsMemorySystemOptions } from "./memory";
10
+ export { DEFAULT_SHELL_COMMAND_DENYLIST, matchesShellDenylist, withDefaultGate, type ApprovalProvider, type DefaultGatePolicies, type GateViolation, type GateViolationReason, type ShellCommandCheckInput, } from "./safety";
11
+ export { configureNetSafety } from "./common/net";
12
+ export { resolveAllowedPath, resolveWorkspacePath, toWorkspaceRelativePath, type ResolveAllowedPathOptions, } from "./common/path";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,mBAAmB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,eAAe,EACf,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,oBAAoB,GAC1B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,6BAA6B,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACzF,OAAO,EACL,8BAA8B,EAC9B,oBAAoB,EACpB,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,GAC5B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,KAAK,yBAAyB,GAC/B,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ export { OpenAIProviderAdapter, AnthropicProviderAdapter, MockProviderAdapter, QwenProviderAdapter, } from "./providers";
2
+ export { toolDescriptors, toolExecutors, } from "./tools";
3
+ export { TerminalBackend, FileBackend, WebBackend } from "./backends";
4
+ export { LocalFsVectorStore, QdrantVectorStore } from "./vector";
5
+ export { ImageToTextTransformer, DocumentToTextTransformer } from "./transformers";
6
+ export { McpStdioAdapter, McpSseAdapter } from "./mcp";
7
+ export { OtelEmitter, JsonlEmitter } from "./observability";
8
+ export { BUILTIN_RULE_DESCRIPTOR_PATHS } from "./rules";
9
+ export { FsMemorySystem, sanitizeSessionId } from "./memory";
10
+ export { DEFAULT_SHELL_COMMAND_DENYLIST, matchesShellDenylist, withDefaultGate, } from "./safety";
11
+ export { configureNetSafety } from "./common/net";
12
+ export { resolveAllowedPath, resolveWorkspacePath, toWorkspaceRelativePath, } from "./common/path";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,GAGpB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,eAAe,EACf,aAAa,GAGd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,6BAA6B,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAA8B,MAAM,UAAU,CAAC;AACzF,OAAO,EACL,8BAA8B,EAC9B,oBAAoB,EACpB,eAAe,GAMhB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,GAExB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { McpStdioAdapter } from "./stdio-adapter";
2
+ export { McpSseAdapter } from "./sse-adapter";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { McpStdioAdapter } from "./stdio-adapter";
2
+ export { McpSseAdapter } from "./sse-adapter";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,82 @@
1
+ import type { McpToolAdapter, ToolDescriptor } from "@tachu/core";
2
+ interface McpSseAdapterOptions {
3
+ url: string;
4
+ headers?: Record<string, string>;
5
+ serverId?: string;
6
+ /**
7
+ * 单次 `callTool` 的默认超时(毫秒)。到期后会在 adapter 层 abort 下游请求
8
+ * 并抛出 "MCP sse request timed out" 错误。宿主显式传入 `0` 可关闭默认超时,
9
+ * 此时仅依赖调用方传入的 `AbortSignal`。详见 D1-LOW-08。
10
+ *
11
+ * @default 30_000
12
+ */
13
+ defaultTimeoutMs?: number;
14
+ }
15
+ /**
16
+ * MCP SSE 传输适配器。
17
+ */
18
+ export declare class McpSseAdapter implements McpToolAdapter {
19
+ readonly transport: "sse";
20
+ private readonly options;
21
+ private readonly maxReconnectAttempts;
22
+ private readonly defaultTimeoutMs;
23
+ private client;
24
+ private transportImpl;
25
+ private reconnecting;
26
+ private closedManually;
27
+ private serverUri;
28
+ private readonly pendingRequests;
29
+ /**
30
+ * 创建 SSE MCP 适配器。
31
+ *
32
+ * @param options 连接配置
33
+ */
34
+ constructor(options: McpSseAdapterOptions);
35
+ /**
36
+ * 建立 SSE MCP 连接。
37
+ *
38
+ * @param serverUri 服务端地址(可覆盖构造参数)
39
+ */
40
+ connect(serverUri: string): Promise<void>;
41
+ /**
42
+ * 断开连接。
43
+ */
44
+ disconnect(): Promise<void>;
45
+ /**
46
+ * 列出远端工具并转换为 ToolDescriptor。
47
+ *
48
+ * @returns 工具描述符列表
49
+ */
50
+ listTools(): Promise<ToolDescriptor[]>;
51
+ /**
52
+ * 调用远端工具(core 协议方法)。
53
+ *
54
+ * @param name 工具名
55
+ * @param input 入参
56
+ * @returns 工具执行结果
57
+ */
58
+ executeTool(name: string, input: unknown, options?: {
59
+ signal?: AbortSignal;
60
+ requestId?: string;
61
+ }): Promise<unknown>;
62
+ /**
63
+ * 调用远端工具(支持 AbortSignal)。
64
+ *
65
+ * @param name 工具名
66
+ * @param input 入参
67
+ * @param signal 取消信号
68
+ * @param requestId 请求 ID(可选;用于后续 cancel 显式取消)
69
+ * @returns 执行结果
70
+ */
71
+ callTool(name: string, input: unknown, signal?: AbortSignal, requestId?: string): Promise<unknown>;
72
+ /**
73
+ * 取消请求(由调用方通过 signal 传播)。
74
+ *
75
+ * @param _requestId 请求 ID
76
+ */
77
+ cancel(requestId: string): Promise<void>;
78
+ private connectInternal;
79
+ private reconnectWithBackoff;
80
+ }
81
+ export {};
82
+ //# sourceMappingURL=sse-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-adapter.d.ts","sourceRoot":"","sources":["../../src/mcp/sse-adapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElE,UAAU,oBAAoB;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAQD;;GAEG;AACH,qBAAa,aAAc,YAAW,cAAc;IAClD,QAAQ,CAAC,SAAS,EAAG,KAAK,CAAU;IAEpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAK;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAsC;IAEtE;;;;OAIG;gBACS,OAAO,EAAE,oBAAoB;IAQzC;;;;OAIG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAWjC;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAuB5C;;;;;;OAMG;IACG,WAAW,CACf,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GACrD,OAAO,CAAC,OAAO,CAAC;IAInB;;;;;;;;OAQG;IACG,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,WAAW,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC;IA0DnB;;;;OAIG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAQhC,eAAe;YAoBf,oBAAoB;CAoBnC"}
@@ -0,0 +1,201 @@
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
3
+ /** D1-LOW-08:默认 30s 的工具调用超时窗口。 */
4
+ const DEFAULT_CALL_TIMEOUT_MS = 30_000;
5
+ const createRequestId = () => `mcp-sse-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
6
+ /**
7
+ * MCP SSE 传输适配器。
8
+ */
9
+ export class McpSseAdapter {
10
+ transport = "sse";
11
+ options;
12
+ maxReconnectAttempts = 3;
13
+ defaultTimeoutMs;
14
+ client = null;
15
+ transportImpl = null;
16
+ reconnecting = false;
17
+ closedManually = false;
18
+ serverUri = "";
19
+ pendingRequests = new Map();
20
+ /**
21
+ * 创建 SSE MCP 适配器。
22
+ *
23
+ * @param options 连接配置
24
+ */
25
+ constructor(options) {
26
+ this.options = options;
27
+ this.defaultTimeoutMs =
28
+ options.defaultTimeoutMs === undefined
29
+ ? DEFAULT_CALL_TIMEOUT_MS
30
+ : Math.max(0, options.defaultTimeoutMs);
31
+ }
32
+ /**
33
+ * 建立 SSE MCP 连接。
34
+ *
35
+ * @param serverUri 服务端地址(可覆盖构造参数)
36
+ */
37
+ async connect(serverUri) {
38
+ this.serverUri = serverUri || this.options.url;
39
+ this.closedManually = false;
40
+ await this.connectInternal();
41
+ }
42
+ /**
43
+ * 断开连接。
44
+ */
45
+ async disconnect() {
46
+ this.closedManually = true;
47
+ for (const controller of this.pendingRequests.values()) {
48
+ controller.abort(new Error("MCP sse adapter disconnected"));
49
+ }
50
+ this.pendingRequests.clear();
51
+ await this.transportImpl?.close().catch(() => undefined);
52
+ this.transportImpl = null;
53
+ this.client = null;
54
+ }
55
+ /**
56
+ * 列出远端工具并转换为 ToolDescriptor。
57
+ *
58
+ * @returns 工具描述符列表
59
+ */
60
+ async listTools() {
61
+ if (!this.client) {
62
+ throw new Error("MCP sse adapter not connected");
63
+ }
64
+ const response = await this.client.listTools();
65
+ return response.tools.map((tool) => ({
66
+ kind: "tool",
67
+ name: tool.name,
68
+ description: tool.description ?? `mcp tool: ${tool.name}`,
69
+ sideEffect: tool.annotations?.readOnlyHint
70
+ ? "readonly"
71
+ : tool.annotations?.destructiveHint
72
+ ? "irreversible"
73
+ : "write",
74
+ idempotent: tool.annotations?.idempotentHint ?? false,
75
+ requiresApproval: tool.annotations?.destructiveHint ?? false,
76
+ timeout: 30_000,
77
+ inputSchema: tool.inputSchema,
78
+ outputSchema: tool.outputSchema,
79
+ execute: `mcp:${this.options.serverId ?? "sse"}:${tool.name}`,
80
+ }));
81
+ }
82
+ /**
83
+ * 调用远端工具(core 协议方法)。
84
+ *
85
+ * @param name 工具名
86
+ * @param input 入参
87
+ * @returns 工具执行结果
88
+ */
89
+ async executeTool(name, input, options) {
90
+ return this.callTool(name, input, options?.signal, options?.requestId);
91
+ }
92
+ /**
93
+ * 调用远端工具(支持 AbortSignal)。
94
+ *
95
+ * @param name 工具名
96
+ * @param input 入参
97
+ * @param signal 取消信号
98
+ * @param requestId 请求 ID(可选;用于后续 cancel 显式取消)
99
+ * @returns 执行结果
100
+ */
101
+ async callTool(name, input, signal, requestId) {
102
+ if (!this.client) {
103
+ throw new Error("MCP sse adapter not connected");
104
+ }
105
+ const mappedRequestId = requestId?.trim() ? requestId : createRequestId();
106
+ if (this.pendingRequests.has(mappedRequestId)) {
107
+ throw new Error(`MCP sse request already in progress: ${mappedRequestId}`);
108
+ }
109
+ const controller = new AbortController();
110
+ const onAbort = () => {
111
+ controller.abort(signal?.reason ?? new Error(`MCP sse request aborted: ${mappedRequestId}`));
112
+ };
113
+ if (signal?.aborted) {
114
+ onAbort();
115
+ }
116
+ else {
117
+ signal?.addEventListener("abort", onAbort, { once: true });
118
+ }
119
+ // D1-LOW-08:为 callTool 套上 adapter 层默认超时,避免远端挂起拖垮引擎。
120
+ let timeoutHandle = null;
121
+ let timedOut = false;
122
+ if (this.defaultTimeoutMs > 0) {
123
+ timeoutHandle = setTimeout(() => {
124
+ timedOut = true;
125
+ controller.abort(new Error(`MCP sse request timed out after ${this.defaultTimeoutMs}ms: ${mappedRequestId}`));
126
+ }, this.defaultTimeoutMs);
127
+ }
128
+ this.pendingRequests.set(mappedRequestId, controller);
129
+ try {
130
+ const result = await this.client.callTool({ name, arguments: (input ?? {}) }, undefined, { signal: controller.signal });
131
+ return result;
132
+ }
133
+ catch (error) {
134
+ if (timedOut) {
135
+ throw new Error(`MCP sse request timed out after ${this.defaultTimeoutMs}ms: ${mappedRequestId}`);
136
+ }
137
+ throw error;
138
+ }
139
+ finally {
140
+ if (timeoutHandle !== null) {
141
+ clearTimeout(timeoutHandle);
142
+ }
143
+ signal?.removeEventListener("abort", onAbort);
144
+ this.pendingRequests.delete(mappedRequestId);
145
+ }
146
+ }
147
+ /**
148
+ * 取消请求(由调用方通过 signal 传播)。
149
+ *
150
+ * @param _requestId 请求 ID
151
+ */
152
+ async cancel(requestId) {
153
+ const controller = this.pendingRequests.get(requestId);
154
+ if (!controller) {
155
+ return;
156
+ }
157
+ controller.abort(new Error(`MCP sse request cancelled: ${requestId}`));
158
+ }
159
+ async connectInternal() {
160
+ const target = this.serverUri || this.options.url;
161
+ this.client = new Client({ name: "tachu-mcp-sse", version: "1.0.0" });
162
+ this.transportImpl = new SSEClientTransport(new URL(target), {
163
+ ...(this.options.headers
164
+ ? {
165
+ requestInit: {
166
+ headers: this.options.headers,
167
+ },
168
+ }
169
+ : {}),
170
+ });
171
+ this.transportImpl.onclose = () => {
172
+ if (!this.closedManually) {
173
+ void this.reconnectWithBackoff();
174
+ }
175
+ };
176
+ await this.client.connect(this.transportImpl);
177
+ }
178
+ async reconnectWithBackoff() {
179
+ if (this.reconnecting || this.closedManually) {
180
+ return;
181
+ }
182
+ this.reconnecting = true;
183
+ try {
184
+ for (let attempt = 0; attempt < this.maxReconnectAttempts; attempt += 1) {
185
+ const delay = 200 * 2 ** attempt;
186
+ await new Promise((resolve) => setTimeout(resolve, delay));
187
+ try {
188
+ await this.connectInternal();
189
+ return;
190
+ }
191
+ catch {
192
+ // retry
193
+ }
194
+ }
195
+ }
196
+ finally {
197
+ this.reconnecting = false;
198
+ }
199
+ }
200
+ }
201
+ //# sourceMappingURL=sse-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-adapter.js","sourceRoot":"","sources":["../../src/mcp/sse-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ import type { McpToolAdapter, ToolDescriptor } from "@tachu/core";
2
+ interface McpStdioAdapterOptions {
3
+ command: string;
4
+ args?: string[];
5
+ env?: Record<string, string>;
6
+ cwd?: string;
7
+ serverId?: string;
8
+ /**
9
+ * 单次 `callTool` 的默认超时(毫秒)。到期后会在 adapter 层 abort 下游请求
10
+ * 并抛出 "MCP stdio request timed out" 错误。宿主显式传入 `0` 可关闭默认超时,
11
+ * 此时仅依赖调用方传入的 `AbortSignal`。详见 D1-LOW-08。
12
+ *
13
+ * @default 30_000
14
+ */
15
+ defaultTimeoutMs?: number;
16
+ }
17
+ /**
18
+ * MCP stdio 传输适配器。
19
+ */
20
+ export declare class McpStdioAdapter implements McpToolAdapter {
21
+ readonly transport: "stdio";
22
+ private readonly options;
23
+ private readonly maxReconnectAttempts;
24
+ private readonly defaultTimeoutMs;
25
+ private client;
26
+ private transportImpl;
27
+ private reconnecting;
28
+ private closedManually;
29
+ private connected;
30
+ private serverUri;
31
+ private readonly pendingRequests;
32
+ /**
33
+ * 创建 stdio MCP 适配器。
34
+ *
35
+ * @param options stdio 启动参数
36
+ */
37
+ constructor(options: McpStdioAdapterOptions);
38
+ /**
39
+ * 建立 MCP 连接。
40
+ *
41
+ * @param serverUri 服务端 URI(可留空)
42
+ */
43
+ connect(serverUri: string): Promise<void>;
44
+ /**
45
+ * 断开连接。
46
+ */
47
+ disconnect(): Promise<void>;
48
+ /**
49
+ * 列出远端工具并映射为引擎 ToolDescriptor。
50
+ *
51
+ * @returns 工具描述符数组
52
+ */
53
+ listTools(): Promise<ToolDescriptor[]>;
54
+ /**
55
+ * 调用远端工具(core 协议方法)。
56
+ *
57
+ * @param name 工具名
58
+ * @param input 入参
59
+ * @returns 工具执行结果
60
+ */
61
+ executeTool(name: string, input: unknown, options?: {
62
+ signal?: AbortSignal;
63
+ requestId?: string;
64
+ }): Promise<unknown>;
65
+ /**
66
+ * 调用远端工具(支持 AbortSignal)。
67
+ *
68
+ * @param name 工具名
69
+ * @param input 入参
70
+ * @param signal 取消信号
71
+ * @param requestId 请求 ID(可选;用于后续 cancel 显式取消)
72
+ * @returns 工具执行结果
73
+ */
74
+ callTool(name: string, input: unknown, signal?: AbortSignal, requestId?: string): Promise<unknown>;
75
+ /**
76
+ * 按 requestId 取消请求(通过信号机制由调用方透传)。
77
+ *
78
+ * @param _requestId 请求 ID
79
+ */
80
+ cancel(requestId: string): Promise<void>;
81
+ private connectInternal;
82
+ private reconnectWithBackoff;
83
+ }
84
+ export {};
85
+ //# sourceMappingURL=stdio-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio-adapter.d.ts","sourceRoot":"","sources":["../../src/mcp/stdio-adapter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElE,UAAU,sBAAsB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAQD;;GAEG;AACH,qBAAa,eAAgB,YAAW,cAAc;IACpD,QAAQ,CAAC,SAAS,EAAG,OAAO,CAAU;IAEtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAK;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAsC;IAEtE;;;;OAIG;gBACS,OAAO,EAAE,sBAAsB;IAQ3C;;;;OAIG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAYjC;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAuB5C;;;;;;OAMG;IACG,WAAW,CACf,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GACrD,OAAO,CAAC,OAAO,CAAC;IAInB;;;;;;;;OAQG;IACG,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,WAAW,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC;IA0DnB;;;;OAIG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAQhC,eAAe;YAqBf,oBAAoB;CAoBnC"}