@fllf/agent-sdk 0.1.2 → 0.1.3

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 (266) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/README.md +824 -198
  3. package/dist/agent/Agent.d.ts +16 -5
  4. package/dist/agent/Agent.d.ts.map +1 -1
  5. package/dist/agent/Agent.js +283 -2
  6. package/dist/agent/Agent.js.map +1 -1
  7. package/dist/agent/index.d.ts +1 -1
  8. package/dist/agent/index.d.ts.map +1 -1
  9. package/dist/agent/types.d.ts +27 -3
  10. package/dist/agent/types.d.ts.map +1 -1
  11. package/dist/config/config.d.ts +22 -3
  12. package/dist/config/config.d.ts.map +1 -1
  13. package/dist/config/config.js +194 -47
  14. package/dist/config/config.js.map +1 -1
  15. package/dist/config/index.d.ts +1 -1
  16. package/dist/config/index.d.ts.map +1 -1
  17. package/dist/errors.d.ts +74 -0
  18. package/dist/errors.d.ts.map +1 -0
  19. package/dist/errors.js +186 -0
  20. package/dist/errors.js.map +1 -0
  21. package/dist/executors/base-executor.d.ts +14 -0
  22. package/dist/executors/base-executor.d.ts.map +1 -0
  23. package/dist/executors/base-executor.js +31 -0
  24. package/dist/executors/base-executor.js.map +1 -0
  25. package/dist/executors/base.d.ts +36 -5
  26. package/dist/executors/base.d.ts.map +1 -1
  27. package/dist/executors/chat-request-builder.d.ts +10 -0
  28. package/dist/executors/chat-request-builder.d.ts.map +1 -0
  29. package/dist/executors/chat-request-builder.js +96 -0
  30. package/dist/executors/chat-request-builder.js.map +1 -0
  31. package/dist/executors/index.d.ts +4 -1
  32. package/dist/executors/index.d.ts.map +1 -1
  33. package/dist/executors/index.js +6 -1
  34. package/dist/executors/index.js.map +1 -1
  35. package/dist/executors/rag-executor.js +1 -1
  36. package/dist/executors/rag-executor.js.map +1 -1
  37. package/dist/executors/simple-chat-executor.d.ts +4 -2
  38. package/dist/executors/simple-chat-executor.d.ts.map +1 -1
  39. package/dist/executors/simple-chat-executor.js +59 -57
  40. package/dist/executors/simple-chat-executor.js.map +1 -1
  41. package/dist/executors/tool-calling-executor.d.ts +20 -2
  42. package/dist/executors/tool-calling-executor.d.ts.map +1 -1
  43. package/dist/executors/tool-calling-executor.js +189 -91
  44. package/dist/executors/tool-calling-executor.js.map +1 -1
  45. package/dist/history/base.d.ts +55 -2
  46. package/dist/history/base.d.ts.map +1 -1
  47. package/dist/history/base.js +49 -0
  48. package/dist/history/base.js.map +1 -1
  49. package/dist/history/compression.d.ts +49 -0
  50. package/dist/history/compression.d.ts.map +1 -0
  51. package/dist/history/compression.js +53 -0
  52. package/dist/history/compression.js.map +1 -0
  53. package/dist/history/context-window.d.ts +33 -0
  54. package/dist/history/context-window.d.ts.map +1 -0
  55. package/dist/history/context-window.js +68 -0
  56. package/dist/history/context-window.js.map +1 -0
  57. package/dist/history/in-memory.d.ts +6 -4
  58. package/dist/history/in-memory.d.ts.map +1 -1
  59. package/dist/history/in-memory.js +25 -39
  60. package/dist/history/in-memory.js.map +1 -1
  61. package/dist/history/index.d.ts +9 -2
  62. package/dist/history/index.d.ts.map +1 -1
  63. package/dist/history/index.js +18 -1
  64. package/dist/history/index.js.map +1 -1
  65. package/dist/history/postgres/index.d.ts +4 -0
  66. package/dist/history/postgres/index.d.ts.map +1 -0
  67. package/dist/history/postgres/index.js +20 -0
  68. package/dist/history/postgres/index.js.map +1 -0
  69. package/dist/history/postgres/postgres-message-history-store.d.ts +35 -0
  70. package/dist/history/postgres/postgres-message-history-store.d.ts.map +1 -0
  71. package/dist/history/postgres/postgres-message-history-store.js +195 -0
  72. package/dist/history/postgres/postgres-message-history-store.js.map +1 -0
  73. package/dist/history/postgres/schema.d.ts +18 -0
  74. package/dist/history/postgres/schema.d.ts.map +1 -0
  75. package/dist/history/postgres/schema.js +46 -0
  76. package/dist/history/postgres/schema.js.map +1 -0
  77. package/dist/history/postgres/sql.d.ts +29 -0
  78. package/dist/history/postgres/sql.d.ts.map +1 -0
  79. package/dist/history/postgres/sql.js +102 -0
  80. package/dist/history/postgres/sql.js.map +1 -0
  81. package/dist/history/postgres/types.d.ts +20 -0
  82. package/dist/history/postgres/types.d.ts.map +1 -0
  83. package/dist/history/postgres/types.js +3 -0
  84. package/dist/history/postgres/types.js.map +1 -0
  85. package/dist/history/tool-pairing.d.ts +11 -0
  86. package/dist/history/tool-pairing.d.ts.map +1 -0
  87. package/dist/history/tool-pairing.js +52 -0
  88. package/dist/history/tool-pairing.js.map +1 -0
  89. package/dist/index.d.ts +2 -0
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +2 -0
  92. package/dist/index.js.map +1 -1
  93. package/dist/llm/LLM.d.ts +1 -0
  94. package/dist/llm/LLM.d.ts.map +1 -1
  95. package/dist/llm/LLM.js +136 -26
  96. package/dist/llm/LLM.js.map +1 -1
  97. package/dist/llm/errors.d.ts +11 -1
  98. package/dist/llm/errors.d.ts.map +1 -1
  99. package/dist/llm/errors.js +50 -1
  100. package/dist/llm/errors.js.map +1 -1
  101. package/dist/llm/factory.d.ts +14 -2
  102. package/dist/llm/factory.d.ts.map +1 -1
  103. package/dist/llm/factory.js +48 -9
  104. package/dist/llm/factory.js.map +1 -1
  105. package/dist/llm/index.d.ts +8 -3
  106. package/dist/llm/index.d.ts.map +1 -1
  107. package/dist/llm/index.js +10 -1
  108. package/dist/llm/index.js.map +1 -1
  109. package/dist/llm/providers/anthropic.d.ts +14 -0
  110. package/dist/llm/providers/anthropic.d.ts.map +1 -0
  111. package/dist/llm/providers/anthropic.js +336 -0
  112. package/dist/llm/providers/anthropic.js.map +1 -0
  113. package/dist/llm/providers/openai-compatible.d.ts +7 -0
  114. package/dist/llm/providers/openai-compatible.d.ts.map +1 -1
  115. package/dist/llm/providers/openai-compatible.js +151 -47
  116. package/dist/llm/providers/openai-compatible.js.map +1 -1
  117. package/dist/llm/stream-accumulator.d.ts +17 -0
  118. package/dist/llm/stream-accumulator.d.ts.map +1 -0
  119. package/dist/llm/stream-accumulator.js +83 -0
  120. package/dist/llm/stream-accumulator.js.map +1 -0
  121. package/dist/llm/tool-arguments.d.ts +6 -0
  122. package/dist/llm/tool-arguments.d.ts.map +1 -0
  123. package/dist/llm/tool-arguments.js +20 -0
  124. package/dist/llm/tool-arguments.js.map +1 -0
  125. package/dist/llm/types.d.ts +76 -4
  126. package/dist/llm/types.d.ts.map +1 -1
  127. package/dist/messages/content.d.ts +36 -0
  128. package/dist/messages/content.d.ts.map +1 -0
  129. package/dist/messages/content.js +70 -0
  130. package/dist/messages/content.js.map +1 -0
  131. package/dist/messages/index.d.ts +4 -2
  132. package/dist/messages/index.d.ts.map +1 -1
  133. package/dist/messages/index.js +10 -1
  134. package/dist/messages/index.js.map +1 -1
  135. package/dist/messages/message.d.ts +11 -9
  136. package/dist/messages/message.d.ts.map +1 -1
  137. package/dist/messages/message.js +69 -4
  138. package/dist/messages/message.js.map +1 -1
  139. package/dist/messages/types.d.ts +12 -0
  140. package/dist/messages/types.d.ts.map +1 -1
  141. package/dist/observability/collecting-observer.d.ts +8 -0
  142. package/dist/observability/collecting-observer.d.ts.map +1 -0
  143. package/dist/observability/collecting-observer.js +15 -0
  144. package/dist/observability/collecting-observer.js.map +1 -0
  145. package/dist/observability/index.d.ts +1 -0
  146. package/dist/observability/index.d.ts.map +1 -1
  147. package/dist/observability/index.js +3 -1
  148. package/dist/observability/index.js.map +1 -1
  149. package/dist/observability/observer.d.ts.map +1 -1
  150. package/dist/observability/observer.js +14 -1
  151. package/dist/observability/observer.js.map +1 -1
  152. package/dist/observability/types.d.ts +16 -1
  153. package/dist/observability/types.d.ts.map +1 -1
  154. package/dist/rag/chunking/auto-chunker.d.ts +7 -0
  155. package/dist/rag/chunking/auto-chunker.d.ts.map +1 -1
  156. package/dist/rag/chunking/auto-chunker.js +13 -0
  157. package/dist/rag/chunking/auto-chunker.js.map +1 -1
  158. package/dist/rag/chunking/chunker.d.ts.map +1 -1
  159. package/dist/rag/chunking/chunker.js +29 -5
  160. package/dist/rag/chunking/chunker.js.map +1 -1
  161. package/dist/rag/chunking/index.d.ts +2 -0
  162. package/dist/rag/chunking/index.d.ts.map +1 -1
  163. package/dist/rag/chunking/index.js +2 -0
  164. package/dist/rag/chunking/index.js.map +1 -1
  165. package/dist/rag/chunking/markdown-chunker.d.ts.map +1 -1
  166. package/dist/rag/chunking/markdown-chunker.js.map +1 -1
  167. package/dist/rag/chunking/qa-pair-chunker.d.ts +23 -0
  168. package/dist/rag/chunking/qa-pair-chunker.d.ts.map +1 -0
  169. package/dist/rag/chunking/qa-pair-chunker.js +162 -0
  170. package/dist/rag/chunking/qa-pair-chunker.js.map +1 -0
  171. package/dist/rag/chunking/semantic-chunker.d.ts +19 -0
  172. package/dist/rag/chunking/semantic-chunker.d.ts.map +1 -0
  173. package/dist/rag/chunking/semantic-chunker.js +291 -0
  174. package/dist/rag/chunking/semantic-chunker.js.map +1 -0
  175. package/dist/rag/embeddings/embedder.d.ts.map +1 -1
  176. package/dist/rag/embeddings/embedder.js +6 -0
  177. package/dist/rag/embeddings/embedder.js.map +1 -1
  178. package/dist/rag/generation/context-builder.d.ts +7 -0
  179. package/dist/rag/generation/context-builder.d.ts.map +1 -1
  180. package/dist/rag/generation/context-builder.js +4 -1
  181. package/dist/rag/generation/context-builder.js.map +1 -1
  182. package/dist/rag/ingestion/metadata.d.ts +6 -1
  183. package/dist/rag/ingestion/metadata.d.ts.map +1 -1
  184. package/dist/rag/ingestion/metadata.js +6 -2
  185. package/dist/rag/ingestion/metadata.js.map +1 -1
  186. package/dist/rag/pipeline.d.ts.map +1 -1
  187. package/dist/rag/pipeline.js +34 -11
  188. package/dist/rag/pipeline.js.map +1 -1
  189. package/dist/rag/retrieval/index.d.ts +1 -0
  190. package/dist/rag/retrieval/index.d.ts.map +1 -1
  191. package/dist/rag/retrieval/index.js +1 -0
  192. package/dist/rag/retrieval/index.js.map +1 -1
  193. package/dist/rag/retrieval/parent-child-expanding-retriever.d.ts +31 -0
  194. package/dist/rag/retrieval/parent-child-expanding-retriever.d.ts.map +1 -0
  195. package/dist/rag/retrieval/parent-child-expanding-retriever.js +194 -0
  196. package/dist/rag/retrieval/parent-child-expanding-retriever.js.map +1 -0
  197. package/dist/rag/stores/in-memory-keyword-store.d.ts.map +1 -1
  198. package/dist/rag/stores/in-memory-keyword-store.js +3 -8
  199. package/dist/rag/stores/in-memory-keyword-store.js.map +1 -1
  200. package/dist/rag/stores/keyword-tokenizer.d.ts +4 -0
  201. package/dist/rag/stores/keyword-tokenizer.d.ts.map +1 -0
  202. package/dist/rag/stores/keyword-tokenizer.js +113 -0
  203. package/dist/rag/stores/keyword-tokenizer.js.map +1 -0
  204. package/dist/rag/stores/postgres/pg-vector-store.d.ts.map +1 -1
  205. package/dist/rag/stores/postgres/pg-vector-store.js +21 -8
  206. package/dist/rag/stores/postgres/pg-vector-store.js.map +1 -1
  207. package/dist/rag/stores/postgres/postgres-document-store.d.ts.map +1 -1
  208. package/dist/rag/stores/postgres/postgres-document-store.js +26 -13
  209. package/dist/rag/stores/postgres/postgres-document-store.js.map +1 -1
  210. package/dist/rag/stores/postgres/postgres-keyword-store.d.ts.map +1 -1
  211. package/dist/rag/stores/postgres/postgres-keyword-store.js +43 -43
  212. package/dist/rag/stores/postgres/postgres-keyword-store.js.map +1 -1
  213. package/dist/rag/stores/postgres/sql.d.ts +22 -0
  214. package/dist/rag/stores/postgres/sql.d.ts.map +1 -1
  215. package/dist/rag/stores/postgres/sql.js +42 -0
  216. package/dist/rag/stores/postgres/sql.js.map +1 -1
  217. package/dist/rag/stores/types.d.ts +5 -0
  218. package/dist/rag/stores/types.d.ts.map +1 -1
  219. package/dist/rag/types.d.ts +6 -0
  220. package/dist/rag/types.d.ts.map +1 -1
  221. package/dist/testing/agent.d.ts +11 -0
  222. package/dist/testing/agent.d.ts.map +1 -0
  223. package/dist/testing/agent.js +45 -0
  224. package/dist/testing/agent.js.map +1 -0
  225. package/dist/testing/history-contract.d.ts +12 -0
  226. package/dist/testing/history-contract.d.ts.map +1 -0
  227. package/dist/testing/history-contract.js +111 -0
  228. package/dist/testing/history-contract.js.map +1 -0
  229. package/dist/testing/index.d.ts +11 -0
  230. package/dist/testing/index.d.ts.map +1 -0
  231. package/dist/testing/index.js +16 -0
  232. package/dist/testing/index.js.map +1 -0
  233. package/dist/testing/models.d.ts +34 -0
  234. package/dist/testing/models.d.ts.map +1 -0
  235. package/dist/testing/models.js +74 -0
  236. package/dist/testing/models.js.map +1 -0
  237. package/dist/testing/tool-schema.d.ts +6 -0
  238. package/dist/testing/tool-schema.d.ts.map +1 -0
  239. package/dist/testing/tool-schema.js +29 -0
  240. package/dist/testing/tool-schema.js.map +1 -0
  241. package/dist/testing/tools.d.ts +21 -0
  242. package/dist/testing/tools.d.ts.map +1 -0
  243. package/dist/testing/tools.js +43 -0
  244. package/dist/testing/tools.js.map +1 -0
  245. package/dist/tools/base.d.ts +38 -7
  246. package/dist/tools/base.d.ts.map +1 -1
  247. package/dist/tools/base.js +238 -11
  248. package/dist/tools/base.js.map +1 -1
  249. package/dist/tools/builtin/advancedSearchTool.d.ts.map +1 -1
  250. package/dist/tools/builtin/advancedSearchTool.js +30 -4
  251. package/dist/tools/builtin/advancedSearchTool.js.map +1 -1
  252. package/dist/tools/builtin/ragSearchTool.d.ts +6 -3
  253. package/dist/tools/builtin/ragSearchTool.d.ts.map +1 -1
  254. package/dist/tools/builtin/ragSearchTool.js +8 -6
  255. package/dist/tools/builtin/ragSearchTool.js.map +1 -1
  256. package/dist/tools/executor.d.ts +30 -2
  257. package/dist/tools/executor.d.ts.map +1 -1
  258. package/dist/tools/executor.js +83 -15
  259. package/dist/tools/executor.js.map +1 -1
  260. package/dist/tools/index.d.ts +3 -1
  261. package/dist/tools/index.d.ts.map +1 -1
  262. package/dist/tools/registry.d.ts +15 -3
  263. package/dist/tools/registry.d.ts.map +1 -1
  264. package/dist/tools/registry.js +21 -2
  265. package/dist/tools/registry.js.map +1 -1
  266. package/package.json +58 -4
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createToolSchemaSnapshot = exports.assertToolSchemaSnapshot = exports.assertMessageHistoryStoreContract = exports.createTestAgent = exports.FakeTool = exports.ScriptedChatModel = exports.FakeChatModel = void 0;
4
+ var models_1 = require("./models");
5
+ Object.defineProperty(exports, "FakeChatModel", { enumerable: true, get: function () { return models_1.FakeChatModel; } });
6
+ Object.defineProperty(exports, "ScriptedChatModel", { enumerable: true, get: function () { return models_1.ScriptedChatModel; } });
7
+ var tools_1 = require("./tools");
8
+ Object.defineProperty(exports, "FakeTool", { enumerable: true, get: function () { return tools_1.FakeTool; } });
9
+ var agent_1 = require("./agent");
10
+ Object.defineProperty(exports, "createTestAgent", { enumerable: true, get: function () { return agent_1.createTestAgent; } });
11
+ var history_contract_1 = require("./history-contract");
12
+ Object.defineProperty(exports, "assertMessageHistoryStoreContract", { enumerable: true, get: function () { return history_contract_1.assertMessageHistoryStoreContract; } });
13
+ var tool_schema_1 = require("./tool-schema");
14
+ Object.defineProperty(exports, "assertToolSchemaSnapshot", { enumerable: true, get: function () { return tool_schema_1.assertToolSchemaSnapshot; } });
15
+ Object.defineProperty(exports, "createToolSchemaSnapshot", { enumerable: true, get: function () { return tool_schema_1.createToolSchemaSnapshot; } });
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":";;;AAAA,mCAGkB;AAFd,uGAAA,aAAa,OAAA;AACb,2GAAA,iBAAiB,OAAA;AAOrB,iCAEiB;AADb,iGAAA,QAAQ,OAAA;AAMZ,iCAEiB;AADb,wGAAA,eAAe,OAAA;AAKnB,uDAE4B;AADxB,qIAAA,iCAAiC,OAAA;AAMrC,6CAGuB;AAFnB,uHAAA,wBAAwB,OAAA;AACxB,uHAAA,wBAAwB,OAAA"}
@@ -0,0 +1,34 @@
1
+ import type { ChatModel, ChatRequest, ChatResponse, ModelCapabilities, ModelProviderName } from '../llm';
2
+ export type ScriptedChatResponse = ChatResponse | ((request: ChatRequest) => ChatResponse | Promise<ChatResponse>);
3
+ export interface ScriptedChatModelOptions {
4
+ name?: ModelProviderName;
5
+ model?: string;
6
+ capabilities?: Partial<ModelCapabilities>;
7
+ responses?: ScriptedChatResponse[];
8
+ }
9
+ export declare class ScriptedChatModel implements ChatModel {
10
+ readonly name: ModelProviderName;
11
+ readonly model: string;
12
+ readonly requests: ChatRequest[];
13
+ private readonly scriptedResponses;
14
+ private readonly modelCapabilities;
15
+ constructor(options?: ScriptedChatModelOptions);
16
+ capabilities(): ModelCapabilities;
17
+ queueResponse(response: ScriptedChatResponse): void;
18
+ chat(request: ChatRequest): Promise<ChatResponse>;
19
+ }
20
+ export interface FakeChatModelOptions {
21
+ name?: ModelProviderName;
22
+ model?: string;
23
+ prefix?: string;
24
+ }
25
+ export declare class FakeChatModel implements ChatModel {
26
+ readonly name: ModelProviderName;
27
+ readonly model: string;
28
+ readonly requests: ChatRequest[];
29
+ private readonly prefix;
30
+ constructor(options?: FakeChatModelOptions);
31
+ capabilities(): ModelCapabilities;
32
+ chat(request: ChatRequest): Promise<ChatResponse>;
33
+ }
34
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/testing/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,SAAS,EACT,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACpB,MAAM,QAAQ,CAAC;AAIhB,MAAM,MAAM,oBAAoB,GAC1B,YAAY,GACZ,CAAC,CAAC,OAAO,EAAE,WAAW,KAAK,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;AAEvE,MAAM,WAAW,wBAAwB;IACrC,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC1C,SAAS,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACtC;AAED,qBAAa,iBAAkB,YAAW,SAAS;IAC/C,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAM;IACtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyB;IAC3D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;gBAE1C,OAAO,GAAE,wBAA6B;IAalD,YAAY,IAAI,iBAAiB;IAIjC,aAAa,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAI7C,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAY1D;AAED,MAAM,WAAW,oBAAoB;IACjC,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,aAAc,YAAW,SAAS;IAC3C,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAM;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,GAAE,oBAAyB;IAM9C,YAAY,IAAI,iBAAiB;IAS3B,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAY1D"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FakeChatModel = exports.ScriptedChatModel = void 0;
4
+ const llm_1 = require("../llm");
5
+ const messages_1 = require("../messages");
6
+ class ScriptedChatModel {
7
+ name;
8
+ model;
9
+ requests = [];
10
+ scriptedResponses;
11
+ modelCapabilities;
12
+ constructor(options = {}) {
13
+ this.name = options.name ?? 'scripted';
14
+ this.model = options.model ?? 'scripted-model';
15
+ this.scriptedResponses = [...(options.responses ?? [])];
16
+ this.modelCapabilities = {
17
+ streaming: false,
18
+ toolCalling: true,
19
+ structuredOutput: false,
20
+ vision: false,
21
+ ...options.capabilities,
22
+ };
23
+ }
24
+ capabilities() {
25
+ return { ...this.modelCapabilities };
26
+ }
27
+ queueResponse(response) {
28
+ this.scriptedResponses.push(response);
29
+ }
30
+ async chat(request) {
31
+ this.requests.push(request);
32
+ const response = this.scriptedResponses.shift();
33
+ if (response === undefined) {
34
+ throw new llm_1.LLMProviderError('ScriptedChatModel has no queued response.', {
35
+ provider: this.name,
36
+ retryable: false,
37
+ });
38
+ }
39
+ return typeof response === 'function' ? await response(request) : response;
40
+ }
41
+ }
42
+ exports.ScriptedChatModel = ScriptedChatModel;
43
+ class FakeChatModel {
44
+ name;
45
+ model;
46
+ requests = [];
47
+ prefix;
48
+ constructor(options = {}) {
49
+ this.name = options.name ?? 'fake';
50
+ this.model = options.model ?? 'fake-model';
51
+ this.prefix = options.prefix ?? 'reply:';
52
+ }
53
+ capabilities() {
54
+ return {
55
+ streaming: false,
56
+ toolCalling: true,
57
+ structuredOutput: false,
58
+ vision: false,
59
+ };
60
+ }
61
+ async chat(request) {
62
+ this.requests.push(request);
63
+ const lastUserMessage = [...request.messages]
64
+ .reverse()
65
+ .find((message) => message.role === 'user');
66
+ return {
67
+ role: 'assistant',
68
+ content: `${this.prefix}${lastUserMessage ? (0, messages_1.contentToText)(lastUserMessage.content) : ''}`,
69
+ toolCalls: [],
70
+ };
71
+ }
72
+ }
73
+ exports.FakeChatModel = FakeChatModel;
74
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/testing/models.ts"],"names":[],"mappings":";;;AAOA,gCAA0C;AAC1C,0CAA4C;AAa5C,MAAa,iBAAiB;IACjB,IAAI,CAAoB;IACxB,KAAK,CAAS;IACd,QAAQ,GAAkB,EAAE,CAAC;IACrB,iBAAiB,CAAyB;IAC1C,iBAAiB,CAAoB;IAEtD,YAAY,UAAoC,EAAE;QAC9C,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,UAAU,CAAC;QACvC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,gBAAgB,CAAC;QAC/C,IAAI,CAAC,iBAAiB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC;QACxD,IAAI,CAAC,iBAAiB,GAAG;YACrB,SAAS,EAAE,KAAK;YAChB,WAAW,EAAE,IAAI;YACjB,gBAAgB,EAAE,KAAK;YACvB,MAAM,EAAE,KAAK;YACb,GAAG,OAAO,CAAC,YAAY;SAC1B,CAAC;IACN,CAAC;IAED,YAAY;QACR,OAAO,EAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACzC,CAAC;IAED,aAAa,CAAC,QAA8B;QACxC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAoB;QAC3B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAChD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,sBAAgB,CAAC,2CAA2C,EAAE;gBACpE,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,SAAS,EAAE,KAAK;aACnB,CAAC,CAAC;QACP,CAAC;QAED,OAAO,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC/E,CAAC;CACJ;AAxCD,8CAwCC;AAQD,MAAa,aAAa;IACb,IAAI,CAAoB;IACxB,KAAK,CAAS;IACd,QAAQ,GAAkB,EAAE,CAAC;IACrB,MAAM,CAAS;IAEhC,YAAY,UAAgC,EAAE;QAC1C,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;QAC3C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC;IAC7C,CAAC;IAED,YAAY;QACR,OAAO;YACH,SAAS,EAAE,KAAK;YAChB,WAAW,EAAE,IAAI;YACjB,gBAAgB,EAAE,KAAK;YACvB,MAAM,EAAE,KAAK;SAChB,CAAC;IACN,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAoB;QAC3B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,eAAe,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;aACxC,OAAO,EAAE;aACT,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QAEhD,OAAO;YACH,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,IAAA,wBAAa,EAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;YACzF,SAAS,EAAE,EAAE;SAChB,CAAC;IACN,CAAC;CACJ;AAjCD,sCAiCC"}
@@ -0,0 +1,6 @@
1
+ import type { ChatToolSchema } from '../llm';
2
+ import type { Tool } from '../tools';
3
+ export type ToolSchemaSnapshot = ChatToolSchema;
4
+ export declare function createToolSchemaSnapshot(tool: Tool): ToolSchemaSnapshot;
5
+ export declare function assertToolSchemaSnapshot(tool: Tool, expected: ToolSchemaSnapshot): void;
6
+ //# sourceMappingURL=tool-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-schema.d.ts","sourceRoot":"","sources":["../../src/testing/tool-schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAErC,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAEhD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,IAAI,GAAG,kBAAkB,CAEvE;AAED,wBAAgB,wBAAwB,CACpC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,kBAAkB,GAC7B,IAAI,CAEN"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createToolSchemaSnapshot = createToolSchemaSnapshot;
7
+ exports.assertToolSchemaSnapshot = assertToolSchemaSnapshot;
8
+ const strict_1 = __importDefault(require("node:assert/strict"));
9
+ function createToolSchemaSnapshot(tool) {
10
+ return sortJson(tool.toOpenAISchema());
11
+ }
12
+ function assertToolSchemaSnapshot(tool, expected) {
13
+ strict_1.default.deepEqual(createToolSchemaSnapshot(tool), sortJson(expected));
14
+ }
15
+ function sortJson(value) {
16
+ if (Array.isArray(value)) {
17
+ return value.map(sortJson);
18
+ }
19
+ if (!isRecord(value)) {
20
+ return value;
21
+ }
22
+ return Object.fromEntries(Object.entries(value)
23
+ .sort(([left], [right]) => left.localeCompare(right))
24
+ .map(([key, nestedValue]) => [key, sortJson(nestedValue)]));
25
+ }
26
+ function isRecord(value) {
27
+ return typeof value === 'object' && value !== null;
28
+ }
29
+ //# sourceMappingURL=tool-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-schema.js","sourceRoot":"","sources":["../../src/testing/tool-schema.ts"],"names":[],"mappings":";;;;;AAMA,4DAEC;AAED,4DAKC;AAfD,gEAAwC;AAMxC,SAAgB,wBAAwB,CAAC,IAAU;IAC/C,OAAO,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,CAAuB,CAAC;AACjE,CAAC;AAED,SAAgB,wBAAwB,CACpC,IAAU,EACV,QAA4B;IAE5B,gBAAM,CAAC,SAAS,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,OAAO,MAAM,CAAC,WAAW,CACrB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;SAChB,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;SACpD,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CACjE,CAAC;AACN,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC5B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACvD,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { z } from 'zod';
2
+ import { Tool } from '../tools';
3
+ import type { ToolInput, ToolInputSchema, ToolOptions, ToolRunContext } from '../tools';
4
+ declare const EmptyToolSchema: z.ZodObject<{}, z.core.$strip>;
5
+ export interface FakeToolCall<TInput = unknown> {
6
+ input: TInput;
7
+ context: ToolRunContext;
8
+ }
9
+ export interface FakeToolOptions<TSchema extends ToolInputSchema, TResult> extends ToolOptions<TSchema, TResult> {
10
+ result?: TResult;
11
+ handler?: (input: ToolInput<TSchema>, context: ToolRunContext) => TResult | Promise<TResult>;
12
+ }
13
+ export declare class FakeTool<TSchema extends ToolInputSchema = typeof EmptyToolSchema, TResult = string> extends Tool<TSchema, TResult> {
14
+ readonly calls: Array<FakeToolCall<ToolInput<TSchema>>>;
15
+ private readonly result;
16
+ private readonly handler;
17
+ constructor(options?: Partial<FakeToolOptions<TSchema, TResult>>);
18
+ protected run(input: ToolInput<TSchema>, context: ToolRunContext): Promise<TResult>;
19
+ }
20
+ export {};
21
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/testing/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACH,IAAI,EACP,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EACR,SAAS,EACT,eAAe,EACf,WAAW,EACX,cAAc,EACjB,MAAM,UAAU,CAAC;AAElB,QAAA,MAAM,eAAe,gCAAe,CAAC;AAErC,MAAM,WAAW,YAAY,CAAC,MAAM,GAAG,OAAO;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe,CAC5B,OAAO,SAAS,eAAe,EAC/B,OAAO,CACT,SAAQ,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,CACN,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,EACzB,OAAO,EAAE,cAAc,KACtB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnC;AAED,qBAAa,QAAQ,CACjB,OAAO,SAAS,eAAe,GAAG,OAAO,eAAe,EACxD,OAAO,GAAG,MAAM,CAClB,SAAQ,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAM;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+C;gBAE3D,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;cAyBhD,GAAG,CACf,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,EACzB,OAAO,EAAE,cAAc,GACxB,OAAO,CAAC,OAAO,CAAC;CAQtB"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FakeTool = void 0;
4
+ const zod_1 = require("zod");
5
+ const tools_1 = require("../tools");
6
+ const EmptyToolSchema = zod_1.z.object({});
7
+ class FakeTool extends tools_1.Tool {
8
+ calls = [];
9
+ result;
10
+ handler;
11
+ constructor(options) {
12
+ const schema = (options?.schema ?? EmptyToolSchema);
13
+ const toolOptions = {
14
+ name: options?.name ?? 'fake_tool',
15
+ description: options?.description ?? 'A fake tool for tests.',
16
+ schema,
17
+ };
18
+ if (options?.timeoutMs !== undefined) {
19
+ toolOptions.timeoutMs = options.timeoutMs;
20
+ }
21
+ if (options?.errorMode !== undefined) {
22
+ toolOptions.errorMode = options.errorMode;
23
+ }
24
+ if (options?.canExecute !== undefined) {
25
+ toolOptions.canExecute = options.canExecute;
26
+ }
27
+ if (options?.serializeResult !== undefined) {
28
+ toolOptions.serializeResult = options.serializeResult;
29
+ }
30
+ super(toolOptions);
31
+ this.result = options?.result;
32
+ this.handler = options?.handler;
33
+ }
34
+ async run(input, context) {
35
+ this.calls.push({ input, context });
36
+ if (this.handler) {
37
+ return await this.handler(input, context);
38
+ }
39
+ return (this.result ?? 'ok');
40
+ }
41
+ }
42
+ exports.FakeTool = FakeTool;
43
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/testing/tools.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AACxB,oCAEkB;AAQlB,MAAM,eAAe,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAkBrC,MAAa,QAGX,SAAQ,YAAsB;IACnB,KAAK,GAA4C,EAAE,CAAC;IAC5C,MAAM,CAAsB;IAC5B,OAAO,CAA+C;IAEvE,YAAY,OAAoD;QAC5D,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,IAAI,eAAe,CAAY,CAAC;QAC/D,MAAM,WAAW,GAAkC;YAC/C,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,WAAW;YAClC,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,wBAAwB;YAC7D,MAAM;SACT,CAAC;QACF,IAAI,OAAO,EAAE,SAAS,KAAK,SAAS,EAAE,CAAC;YACnC,WAAW,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QAC9C,CAAC;QACD,IAAI,OAAO,EAAE,SAAS,KAAK,SAAS,EAAE,CAAC;YACnC,WAAW,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QAC9C,CAAC;QACD,IAAI,OAAO,EAAE,UAAU,KAAK,SAAS,EAAE,CAAC;YACpC,WAAW,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QAChD,CAAC;QACD,IAAI,OAAO,EAAE,eAAe,KAAK,SAAS,EAAE,CAAC;YACzC,WAAW,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC1D,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,CAAC;IACpC,CAAC;IAES,KAAK,CAAC,GAAG,CACf,KAAyB,EACzB,OAAuB;QAEvB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACpC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAY,CAAC;IAC5C,CAAC;CACJ;AA5CD,4BA4CC"}
@@ -1,14 +1,28 @@
1
1
  import { z } from 'zod';
2
- import type { ChatToolSchema } from '../llm/types';
2
+ import { ToolError } from '../errors';
3
+ import type { ChatToolSchema, ToolDefinition } from '../llm/types';
4
+ import type { MessageContent } from '../messages/content';
3
5
  export type ToolInputSchema = z.ZodType;
4
6
  export type ToolInput<TSchema extends ToolInputSchema> = z.infer<TSchema>;
5
- export interface ToolOptions<TSchema extends ToolInputSchema> {
7
+ export type ToolErrorMode = 'return_to_model' | 'throw';
8
+ export type ToolPermissionChecker = (context: ToolRunContext) => boolean | Promise<boolean>;
9
+ export interface ToolRunContext {
10
+ runId: string;
11
+ agentName?: string | undefined;
12
+ sessionId?: string | undefined;
13
+ metadata?: Record<string, unknown> | undefined;
14
+ signal?: AbortSignal | undefined;
15
+ }
16
+ export interface ToolOptions<TSchema extends ToolInputSchema, TResult = unknown> {
6
17
  name: string;
7
18
  description: string;
8
19
  schema: TSchema;
20
+ timeoutMs?: number;
21
+ errorMode?: ToolErrorMode;
22
+ canExecute?: ToolPermissionChecker;
23
+ serializeResult?: (result: TResult) => MessageContent;
9
24
  }
10
- export declare class ToolValidationError extends Error {
11
- readonly toolName: string;
25
+ export declare class ToolValidationError extends ToolError {
12
26
  readonly issues: readonly z.core.$ZodIssue[];
13
27
  constructor(toolName: string, error: z.ZodError);
14
28
  }
@@ -16,13 +30,30 @@ export declare abstract class Tool<TSchema extends ToolInputSchema = ToolInputSc
16
30
  readonly name: string;
17
31
  readonly description: string;
18
32
  readonly schema: TSchema;
19
- protected constructor(options: ToolOptions<TSchema>);
33
+ readonly timeoutMs: number | undefined;
34
+ readonly errorMode: ToolErrorMode;
35
+ private readonly permissionChecker;
36
+ private readonly resultSerializer;
37
+ protected constructor(options: ToolOptions<TSchema, TResult>);
20
38
  /**
21
39
  * 模型返回的是未可信的 JSON 参数,进入具体工具前必须先通过 schema。
22
40
  * 子类只实现 run(validatedInput),不用重复写参数校验样板代码。
23
41
  */
24
- execute(parameters: unknown): Promise<TResult>;
42
+ execute(parameters: unknown, context?: Partial<ToolRunContext>): Promise<TResult>;
43
+ /**
44
+ * 工具结果最终要作为消息内容反馈给模型。
45
+ * 默认策略:字符串与 content block 数组原样透传,其余值用 JSON 序列化,
46
+ * 避免对象被降级成 "[object Object]" 这类对模型无意义的文本。
47
+ */
48
+ serializeResult(result: TResult): MessageContent;
49
+ toToolSchema(): ToolDefinition;
50
+ /**
51
+ * @deprecated 请使用 toToolSchema();此方法返回 OpenAI 专有形状。
52
+ */
25
53
  toOpenAISchema(): ChatToolSchema;
26
- protected abstract run(parameters: ToolInput<TSchema>): TResult | Promise<TResult>;
54
+ protected abstract run(parameters: ToolInput<TSchema>, context: ToolRunContext): TResult | Promise<TResult>;
55
+ protected canExecute(_context: ToolRunContext): boolean | Promise<boolean>;
56
+ private ensureCanExecute;
57
+ private runWithControls;
27
58
  }
28
59
  //# sourceMappingURL=base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/tools/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,OAAO,CAAC;AACxC,MAAM,MAAM,SAAS,CAAC,OAAO,SAAS,eAAe,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAE1E,MAAM,WAAW,WAAW,CAAC,OAAO,SAAS,eAAe;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBAEjC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ;CAMlD;AAED,8BAAsB,IAAI,CACtB,OAAO,SAAS,eAAe,GAAG,eAAe,EACjD,OAAO,GAAG,OAAO;IAEjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB,SAAS,aAAa,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC;IAMnD;;;OAGG;IACG,OAAO,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IASpD,cAAc,IAAI,cAAc;IAYhC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CACrF"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/tools/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAGH,SAAS,EAGZ,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,OAAO,CAAC;AACxC,MAAM,MAAM,SAAS,CAAC,OAAO,SAAS,eAAe,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC1E,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,OAAO,CAAC;AACxD,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAI5F,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC/C,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CACpC;AAED,MAAM,WAAW,WAAW,CAAC,OAAO,SAAS,eAAe,EAAE,OAAO,GAAG,OAAO;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,cAAc,CAAC;CACzD;AAED,qBAAa,mBAAoB,SAAQ,SAAS;IAC9C,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBAEjC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ;CAalD;AAED,8BAAsB,IAAI,CACtB,OAAO,SAAS,eAAe,GAAG,eAAe,EACjD,OAAO,GAAG,OAAO;IAEjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoC;IACtE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoD;IAErF,SAAS,aAAa,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC;IAY5D;;;OAGG;IACG,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAUvF;;;;OAIG;IACH,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc;IAwBhD,YAAY,IAAI,cAAc;IAS9B;;OAEG;IACH,cAAc,IAAI,cAAc;IAahC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAClB,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC,EAC9B,OAAO,EAAE,cAAc,GACxB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAE7B,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;YAI5D,gBAAgB;YAWhB,eAAe;CAyDhC"}
@@ -2,13 +2,22 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Tool = exports.ToolValidationError = void 0;
4
4
  const zod_1 = require("zod");
5
- class ToolValidationError extends Error {
6
- toolName;
5
+ const errors_1 = require("../errors");
6
+ const content_1 = require("../messages/content");
7
+ const TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,64}$/;
8
+ class ToolValidationError extends errors_1.ToolError {
7
9
  issues;
8
10
  constructor(toolName, error) {
9
- super(`Tool "${toolName}" received invalid parameters.`);
10
- this.name = 'ToolValidationError';
11
- this.toolName = toolName;
11
+ super(`Tool "${toolName}" received invalid parameters.`, {
12
+ code: 'tool_validation',
13
+ retryable: false,
14
+ toolName,
15
+ cause: error,
16
+ metadata: {
17
+ toolName,
18
+ issueCount: error.issues.length,
19
+ },
20
+ });
12
21
  this.issues = error.issues;
13
22
  }
14
23
  }
@@ -17,35 +26,253 @@ class Tool {
17
26
  name;
18
27
  description;
19
28
  schema;
29
+ timeoutMs;
30
+ errorMode;
31
+ permissionChecker;
32
+ resultSerializer;
20
33
  constructor(options) {
34
+ validateToolOptions(options);
21
35
  this.name = options.name;
22
36
  this.description = options.description;
23
37
  this.schema = options.schema;
38
+ this.timeoutMs = options.timeoutMs;
39
+ this.errorMode = options.errorMode ?? 'return_to_model';
40
+ this.permissionChecker = options.canExecute;
41
+ this.resultSerializer = options.serializeResult;
24
42
  }
25
43
  /**
26
44
  * 模型返回的是未可信的 JSON 参数,进入具体工具前必须先通过 schema。
27
45
  * 子类只实现 run(validatedInput),不用重复写参数校验样板代码。
28
46
  */
29
- async execute(parameters) {
47
+ async execute(parameters, context) {
30
48
  const parsed = await this.schema.safeParseAsync(parameters);
31
49
  if (!parsed.success) {
32
50
  throw new ToolValidationError(this.name, parsed.error);
33
51
  }
34
- return await this.run(parsed.data);
52
+ const runContext = createToolRunContext(context);
53
+ return await this.runWithControls(parsed.data, runContext);
35
54
  }
55
+ /**
56
+ * 工具结果最终要作为消息内容反馈给模型。
57
+ * 默认策略:字符串与 content block 数组原样透传,其余值用 JSON 序列化,
58
+ * 避免对象被降级成 "[object Object]" 这类对模型无意义的文本。
59
+ */
60
+ serializeResult(result) {
61
+ if (this.resultSerializer) {
62
+ return this.resultSerializer(result);
63
+ }
64
+ if (typeof result === 'string') {
65
+ return result;
66
+ }
67
+ if ((0, content_1.isMessageContent)(result)) {
68
+ return result;
69
+ }
70
+ if (result === undefined) {
71
+ return '';
72
+ }
73
+ try {
74
+ return JSON.stringify(result) ?? String(result);
75
+ }
76
+ catch {
77
+ return String(result);
78
+ }
79
+ }
80
+ toToolSchema() {
81
+ return {
82
+ name: this.name,
83
+ description: this.description,
84
+ strict: true,
85
+ parameters: toStrictObjectSchema(this.schema),
86
+ };
87
+ }
88
+ /**
89
+ * @deprecated 请使用 toToolSchema();此方法返回 OpenAI 专有形状。
90
+ */
36
91
  toOpenAISchema() {
92
+ const schema = this.toToolSchema();
37
93
  return {
38
94
  type: 'function',
39
95
  function: {
40
- name: this.name,
41
- description: this.description,
42
- strict: true,
43
- parameters: toStrictObjectSchema(this.schema),
96
+ name: schema.name,
97
+ description: schema.description,
98
+ strict: schema.strict ?? true,
99
+ parameters: schema.parameters,
44
100
  },
45
101
  };
46
102
  }
103
+ canExecute(_context) {
104
+ return true;
105
+ }
106
+ async ensureCanExecute(context) {
107
+ const allowedBySubclass = await this.canExecute(context);
108
+ const allowedByOptions = this.permissionChecker
109
+ ? await this.permissionChecker(context)
110
+ : true;
111
+ if (!allowedBySubclass || !allowedByOptions) {
112
+ throw new errors_1.ToolPermissionError(this.name);
113
+ }
114
+ }
115
+ async runWithControls(parameters, context) {
116
+ const attemptSignal = createToolAttemptSignal(this.name, context.signal, this.timeoutMs);
117
+ const startedAt = Date.now();
118
+ let timeoutId;
119
+ let abortCleanup;
120
+ try {
121
+ const controlledContext = withToolSignal(context, attemptSignal.signal);
122
+ const operation = (async () => {
123
+ await this.ensureCanExecute(controlledContext);
124
+ return await this.run(parameters, controlledContext);
125
+ })();
126
+ const race = [operation];
127
+ if (this.timeoutMs !== undefined && this.timeoutMs > 0) {
128
+ race.push(new Promise((_resolve, reject) => {
129
+ timeoutId = setTimeout(() => {
130
+ attemptSignal.abortForTimeout();
131
+ reject(new errors_1.ToolTimeoutError(this.name, this.timeoutMs));
132
+ }, this.timeoutMs);
133
+ }));
134
+ }
135
+ const abortRace = createToolAbortRace(this.name, attemptSignal.signal, attemptSignal.abortedByCaller);
136
+ if (abortRace !== undefined) {
137
+ race.push(abortRace.promise);
138
+ abortCleanup = abortRace.cleanup;
139
+ }
140
+ return await Promise.race(race);
141
+ }
142
+ catch (error) {
143
+ if (attemptSignal.timedOut()) {
144
+ throw new errors_1.ToolTimeoutError(this.name, this.timeoutMs ?? Date.now() - startedAt, {
145
+ cause: error,
146
+ });
147
+ }
148
+ if (attemptSignal.abortedByCaller()) {
149
+ throw new errors_1.ToolAbortError(this.name, { cause: error });
150
+ }
151
+ throw error;
152
+ }
153
+ finally {
154
+ if (timeoutId !== undefined) {
155
+ clearTimeout(timeoutId);
156
+ }
157
+ abortCleanup?.();
158
+ attemptSignal.cleanup();
159
+ }
160
+ }
47
161
  }
48
162
  exports.Tool = Tool;
163
+ function validateToolOptions(options) {
164
+ if (typeof options.name !== 'string' || !TOOL_NAME_PATTERN.test(options.name)) {
165
+ throwInvalidToolOption('name', 'must be 1-64 characters and contain only letters, numbers, underscores, or hyphens', typeof options.name === 'string' ? options.name : '<invalid>');
166
+ }
167
+ if (typeof options.description !== 'string' || options.description.trim().length === 0) {
168
+ throwInvalidToolOption('description', 'must be a non-empty string', options.name);
169
+ }
170
+ if (!isZodSchema(options.schema)) {
171
+ throwInvalidToolOption('schema', 'must be a Zod schema', options.name);
172
+ }
173
+ if (options.timeoutMs !== undefined
174
+ && (!Number.isFinite(options.timeoutMs) || options.timeoutMs < 0)) {
175
+ throwInvalidToolOption('timeoutMs', 'must be a non-negative finite number', options.name);
176
+ }
177
+ if (options.errorMode !== undefined
178
+ && options.errorMode !== 'return_to_model'
179
+ && options.errorMode !== 'throw') {
180
+ throwInvalidToolOption('errorMode', 'must be "return_to_model" or "throw"', options.name);
181
+ }
182
+ if (options.canExecute !== undefined && typeof options.canExecute !== 'function') {
183
+ throwInvalidToolOption('canExecute', 'must be a function', options.name);
184
+ }
185
+ if (options.serializeResult !== undefined && typeof options.serializeResult !== 'function') {
186
+ throwInvalidToolOption('serializeResult', 'must be a function', options.name);
187
+ }
188
+ }
189
+ function throwInvalidToolOption(option, reason, toolName) {
190
+ throw new errors_1.ToolConfigurationError(`Invalid ToolOptions.${option}: ${reason}.`, {
191
+ toolName,
192
+ metadata: {
193
+ option,
194
+ toolName,
195
+ },
196
+ });
197
+ }
198
+ function isZodSchema(value) {
199
+ return typeof value === 'object'
200
+ && value !== null
201
+ && 'safeParseAsync' in value
202
+ && typeof value.safeParseAsync === 'function';
203
+ }
204
+ function createToolRunContext(context) {
205
+ return {
206
+ runId: context?.runId ?? 'standalone',
207
+ agentName: context?.agentName,
208
+ sessionId: context?.sessionId,
209
+ metadata: context?.metadata,
210
+ signal: context?.signal,
211
+ };
212
+ }
213
+ function createToolAttemptSignal(toolName, callerSignal, timeoutMs) {
214
+ if (callerSignal?.aborted) {
215
+ throw new errors_1.ToolAbortError(toolName, { cause: callerSignal.reason });
216
+ }
217
+ const needsSignal = callerSignal !== undefined || (timeoutMs !== undefined && timeoutMs > 0);
218
+ if (!needsSignal) {
219
+ return {
220
+ signal: undefined,
221
+ timedOut: () => false,
222
+ abortedByCaller: () => false,
223
+ abortForTimeout: () => undefined,
224
+ cleanup: () => undefined,
225
+ };
226
+ }
227
+ const controller = new AbortController();
228
+ let timedOut = false;
229
+ let abortedByCaller = false;
230
+ const onCallerAbort = () => {
231
+ abortedByCaller = true;
232
+ controller.abort(callerSignal?.reason);
233
+ };
234
+ callerSignal?.addEventListener('abort', onCallerAbort, { once: true });
235
+ return {
236
+ signal: controller.signal,
237
+ timedOut: () => timedOut,
238
+ abortedByCaller: () => abortedByCaller,
239
+ abortForTimeout: () => {
240
+ timedOut = true;
241
+ controller.abort();
242
+ },
243
+ cleanup: () => {
244
+ callerSignal?.removeEventListener('abort', onCallerAbort);
245
+ },
246
+ };
247
+ }
248
+ function withToolSignal(context, signal) {
249
+ return {
250
+ ...context,
251
+ signal,
252
+ };
253
+ }
254
+ function createToolAbortRace(toolName, signal, abortedByCaller) {
255
+ if (signal === undefined) {
256
+ return undefined;
257
+ }
258
+ let onAbort;
259
+ const promise = new Promise((_resolve, reject) => {
260
+ onAbort = () => {
261
+ if (abortedByCaller()) {
262
+ reject(new errors_1.ToolAbortError(toolName));
263
+ }
264
+ };
265
+ signal.addEventListener('abort', onAbort, { once: true });
266
+ });
267
+ return {
268
+ promise,
269
+ cleanup: () => {
270
+ if (onAbort !== undefined) {
271
+ signal.removeEventListener('abort', onAbort);
272
+ }
273
+ },
274
+ };
275
+ }
49
276
  function toStrictObjectSchema(schema) {
50
277
  const jsonSchema = zod_1.z.toJSONSchema(schema);
51
278
  const normalizedSchema = stripUnsupportedJsonSchemaFields(jsonSchema);