agentdog 1.1.0

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 (291) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +244 -0
  3. package/dist/adapters/adapter-factory.d.ts +21 -0
  4. package/dist/adapters/adapter-factory.d.ts.map +1 -0
  5. package/dist/adapters/adapter-factory.js +157 -0
  6. package/dist/adapters/adapter-factory.js.map +1 -0
  7. package/dist/adapters/http-sse-adapter.d.ts +49 -0
  8. package/dist/adapters/http-sse-adapter.d.ts.map +1 -0
  9. package/dist/adapters/http-sse-adapter.js +485 -0
  10. package/dist/adapters/http-sse-adapter.js.map +1 -0
  11. package/dist/adapters/stdio-adapter.d.ts +69 -0
  12. package/dist/adapters/stdio-adapter.d.ts.map +1 -0
  13. package/dist/adapters/stdio-adapter.js +664 -0
  14. package/dist/adapters/stdio-adapter.js.map +1 -0
  15. package/dist/adapters/streamable-http-adapter.d.ts +38 -0
  16. package/dist/adapters/streamable-http-adapter.d.ts.map +1 -0
  17. package/dist/adapters/streamable-http-adapter.js +321 -0
  18. package/dist/adapters/streamable-http-adapter.js.map +1 -0
  19. package/dist/ai-gateway/anthropic-errors.d.ts +4 -0
  20. package/dist/ai-gateway/anthropic-errors.d.ts.map +1 -0
  21. package/dist/ai-gateway/anthropic-errors.js +17 -0
  22. package/dist/ai-gateway/anthropic-errors.js.map +1 -0
  23. package/dist/ai-gateway/auth.d.ts +3 -0
  24. package/dist/ai-gateway/auth.d.ts.map +1 -0
  25. package/dist/ai-gateway/auth.js +14 -0
  26. package/dist/ai-gateway/auth.js.map +1 -0
  27. package/dist/ai-gateway/auth.test.d.ts +2 -0
  28. package/dist/ai-gateway/auth.test.d.ts.map +1 -0
  29. package/dist/ai-gateway/auth.test.js +57 -0
  30. package/dist/ai-gateway/auth.test.js.map +1 -0
  31. package/dist/ai-gateway/count-tokens.d.ts +5 -0
  32. package/dist/ai-gateway/count-tokens.d.ts.map +1 -0
  33. package/dist/ai-gateway/count-tokens.js +37 -0
  34. package/dist/ai-gateway/count-tokens.js.map +1 -0
  35. package/dist/ai-gateway/count-tokens.test.d.ts +2 -0
  36. package/dist/ai-gateway/count-tokens.test.d.ts.map +1 -0
  37. package/dist/ai-gateway/count-tokens.test.js +19 -0
  38. package/dist/ai-gateway/count-tokens.test.js.map +1 -0
  39. package/dist/ai-gateway/dialects.d.ts +4 -0
  40. package/dist/ai-gateway/dialects.d.ts.map +1 -0
  41. package/dist/ai-gateway/dialects.js +15 -0
  42. package/dist/ai-gateway/dialects.js.map +1 -0
  43. package/dist/ai-gateway/gateway-server.d.ts +15 -0
  44. package/dist/ai-gateway/gateway-server.d.ts.map +1 -0
  45. package/dist/ai-gateway/gateway-server.js +121 -0
  46. package/dist/ai-gateway/gateway-server.js.map +1 -0
  47. package/dist/ai-gateway/integration.test.d.ts +2 -0
  48. package/dist/ai-gateway/integration.test.d.ts.map +1 -0
  49. package/dist/ai-gateway/integration.test.js +205 -0
  50. package/dist/ai-gateway/integration.test.js.map +1 -0
  51. package/dist/ai-gateway/ir/anthropic-in.d.ts +3 -0
  52. package/dist/ai-gateway/ir/anthropic-in.d.ts.map +1 -0
  53. package/dist/ai-gateway/ir/anthropic-in.js +121 -0
  54. package/dist/ai-gateway/ir/anthropic-in.js.map +1 -0
  55. package/dist/ai-gateway/ir/anthropic-in.test.d.ts +2 -0
  56. package/dist/ai-gateway/ir/anthropic-in.test.d.ts.map +1 -0
  57. package/dist/ai-gateway/ir/anthropic-in.test.js +93 -0
  58. package/dist/ai-gateway/ir/anthropic-in.test.js.map +1 -0
  59. package/dist/ai-gateway/ir/anthropic-sse.d.ts +22 -0
  60. package/dist/ai-gateway/ir/anthropic-sse.d.ts.map +1 -0
  61. package/dist/ai-gateway/ir/anthropic-sse.js +200 -0
  62. package/dist/ai-gateway/ir/anthropic-sse.js.map +1 -0
  63. package/dist/ai-gateway/ir/anthropic-sse.test.d.ts +2 -0
  64. package/dist/ai-gateway/ir/anthropic-sse.test.d.ts.map +1 -0
  65. package/dist/ai-gateway/ir/anthropic-sse.test.js +101 -0
  66. package/dist/ai-gateway/ir/anthropic-sse.test.js.map +1 -0
  67. package/dist/ai-gateway/ir/gemini-out.d.ts +20 -0
  68. package/dist/ai-gateway/ir/gemini-out.d.ts.map +1 -0
  69. package/dist/ai-gateway/ir/gemini-out.js +218 -0
  70. package/dist/ai-gateway/ir/gemini-out.js.map +1 -0
  71. package/dist/ai-gateway/ir/gemini-out.test.d.ts +2 -0
  72. package/dist/ai-gateway/ir/gemini-out.test.d.ts.map +1 -0
  73. package/dist/ai-gateway/ir/gemini-out.test.js +125 -0
  74. package/dist/ai-gateway/ir/gemini-out.test.js.map +1 -0
  75. package/dist/ai-gateway/ir/openai-out.d.ts +17 -0
  76. package/dist/ai-gateway/ir/openai-out.d.ts.map +1 -0
  77. package/dist/ai-gateway/ir/openai-out.js +226 -0
  78. package/dist/ai-gateway/ir/openai-out.js.map +1 -0
  79. package/dist/ai-gateway/ir/openai-out.test.d.ts +2 -0
  80. package/dist/ai-gateway/ir/openai-out.test.d.ts.map +1 -0
  81. package/dist/ai-gateway/ir/openai-out.test.js +144 -0
  82. package/dist/ai-gateway/ir/openai-out.test.js.map +1 -0
  83. package/dist/ai-gateway/ir/types.d.ts +77 -0
  84. package/dist/ai-gateway/ir/types.d.ts.map +1 -0
  85. package/dist/ai-gateway/ir/types.js +4 -0
  86. package/dist/ai-gateway/ir/types.js.map +1 -0
  87. package/dist/ai-gateway/ir-channel.d.ts +15 -0
  88. package/dist/ai-gateway/ir-channel.d.ts.map +1 -0
  89. package/dist/ai-gateway/ir-channel.js +120 -0
  90. package/dist/ai-gateway/ir-channel.js.map +1 -0
  91. package/dist/ai-gateway/model-router.d.ts +11 -0
  92. package/dist/ai-gateway/model-router.d.ts.map +1 -0
  93. package/dist/ai-gateway/model-router.js +27 -0
  94. package/dist/ai-gateway/model-router.js.map +1 -0
  95. package/dist/ai-gateway/model-router.test.d.ts +2 -0
  96. package/dist/ai-gateway/model-router.test.d.ts.map +1 -0
  97. package/dist/ai-gateway/model-router.test.js +43 -0
  98. package/dist/ai-gateway/model-router.test.js.map +1 -0
  99. package/dist/ai-gateway/passthrough.d.ts +9 -0
  100. package/dist/ai-gateway/passthrough.d.ts.map +1 -0
  101. package/dist/ai-gateway/passthrough.js +81 -0
  102. package/dist/ai-gateway/passthrough.js.map +1 -0
  103. package/dist/ai-gateway/passthrough.test.d.ts +2 -0
  104. package/dist/ai-gateway/passthrough.test.d.ts.map +1 -0
  105. package/dist/ai-gateway/passthrough.test.js +108 -0
  106. package/dist/ai-gateway/passthrough.test.js.map +1 -0
  107. package/dist/ai-gateway/upstream/model-lister.d.ts +13 -0
  108. package/dist/ai-gateway/upstream/model-lister.d.ts.map +1 -0
  109. package/dist/ai-gateway/upstream/model-lister.js +61 -0
  110. package/dist/ai-gateway/upstream/model-lister.js.map +1 -0
  111. package/dist/ai-gateway/upstream/provider-client.d.ts +20 -0
  112. package/dist/ai-gateway/upstream/provider-client.d.ts.map +1 -0
  113. package/dist/ai-gateway/upstream/provider-client.js +76 -0
  114. package/dist/ai-gateway/upstream/provider-client.js.map +1 -0
  115. package/dist/ai-gateway/upstream/provider-client.test.d.ts +2 -0
  116. package/dist/ai-gateway/upstream/provider-client.test.d.ts.map +1 -0
  117. package/dist/ai-gateway/upstream/provider-client.test.js +69 -0
  118. package/dist/ai-gateway/upstream/provider-client.test.js.map +1 -0
  119. package/dist/cli/cli-main.d.ts +7 -0
  120. package/dist/cli/cli-main.d.ts.map +1 -0
  121. package/dist/cli/cli-main.js +116 -0
  122. package/dist/cli/cli-main.js.map +1 -0
  123. package/dist/cli/cli-router.d.ts +20 -0
  124. package/dist/cli/cli-router.d.ts.map +1 -0
  125. package/dist/cli/cli-router.js +271 -0
  126. package/dist/cli/cli-router.js.map +1 -0
  127. package/dist/cli/cli-utils.d.ts +30 -0
  128. package/dist/cli/cli-utils.d.ts.map +1 -0
  129. package/dist/cli/cli-utils.js +219 -0
  130. package/dist/cli/cli-utils.js.map +1 -0
  131. package/dist/cli/commands/audit-commands.d.ts +30 -0
  132. package/dist/cli/commands/audit-commands.d.ts.map +1 -0
  133. package/dist/cli/commands/audit-commands.js +417 -0
  134. package/dist/cli/commands/audit-commands.js.map +1 -0
  135. package/dist/cli/commands/autostart-command.d.ts +21 -0
  136. package/dist/cli/commands/autostart-command.d.ts.map +1 -0
  137. package/dist/cli/commands/autostart-command.js +243 -0
  138. package/dist/cli/commands/autostart-command.js.map +1 -0
  139. package/dist/cli/commands/autostart-command.test.d.ts +2 -0
  140. package/dist/cli/commands/autostart-command.test.d.ts.map +1 -0
  141. package/dist/cli/commands/autostart-command.test.js +35 -0
  142. package/dist/cli/commands/autostart-command.test.js.map +1 -0
  143. package/dist/cli/commands/config-commands.d.ts +30 -0
  144. package/dist/cli/commands/config-commands.d.ts.map +1 -0
  145. package/dist/cli/commands/config-commands.js +1013 -0
  146. package/dist/cli/commands/config-commands.js.map +1 -0
  147. package/dist/cli/commands/daemon-commands.d.ts +76 -0
  148. package/dist/cli/commands/daemon-commands.d.ts.map +1 -0
  149. package/dist/cli/commands/daemon-commands.js +451 -0
  150. package/dist/cli/commands/daemon-commands.js.map +1 -0
  151. package/dist/cli/commands/detect-commands.d.ts +17 -0
  152. package/dist/cli/commands/detect-commands.d.ts.map +1 -0
  153. package/dist/cli/commands/detect-commands.js +293 -0
  154. package/dist/cli/commands/detect-commands.js.map +1 -0
  155. package/dist/cli/commands/diagnose-commands.d.ts +19 -0
  156. package/dist/cli/commands/diagnose-commands.d.ts.map +1 -0
  157. package/dist/cli/commands/diagnose-commands.js +326 -0
  158. package/dist/cli/commands/diagnose-commands.js.map +1 -0
  159. package/dist/cli/commands/optimize-commands.d.ts +14 -0
  160. package/dist/cli/commands/optimize-commands.d.ts.map +1 -0
  161. package/dist/cli/commands/optimize-commands.js +189 -0
  162. package/dist/cli/commands/optimize-commands.js.map +1 -0
  163. package/dist/cli/commands/proxy-command.d.ts +27 -0
  164. package/dist/cli/commands/proxy-command.d.ts.map +1 -0
  165. package/dist/cli/commands/proxy-command.js +212 -0
  166. package/dist/cli/commands/proxy-command.js.map +1 -0
  167. package/dist/cli/commands/start-command.d.ts +22 -0
  168. package/dist/cli/commands/start-command.d.ts.map +1 -0
  169. package/dist/cli/commands/start-command.js +275 -0
  170. package/dist/cli/commands/start-command.js.map +1 -0
  171. package/dist/config/config-manager.d.ts +125 -0
  172. package/dist/config/config-manager.d.ts.map +1 -0
  173. package/dist/config/config-manager.js +569 -0
  174. package/dist/config/config-manager.js.map +1 -0
  175. package/dist/config/config-manager.test.d.ts +2 -0
  176. package/dist/config/config-manager.test.d.ts.map +1 -0
  177. package/dist/config/config-manager.test.js +209 -0
  178. package/dist/config/config-manager.test.js.map +1 -0
  179. package/dist/core/auto-config-generator.d.ts +55 -0
  180. package/dist/core/auto-config-generator.d.ts.map +1 -0
  181. package/dist/core/auto-config-generator.js +278 -0
  182. package/dist/core/auto-config-generator.js.map +1 -0
  183. package/dist/core/mcpdog-server.d.ts +49 -0
  184. package/dist/core/mcpdog-server.d.ts.map +1 -0
  185. package/dist/core/mcpdog-server.js +552 -0
  186. package/dist/core/mcpdog-server.js.map +1 -0
  187. package/dist/core/protocol-detector.d.ts +56 -0
  188. package/dist/core/protocol-detector.d.ts.map +1 -0
  189. package/dist/core/protocol-detector.js +365 -0
  190. package/dist/core/protocol-detector.js.map +1 -0
  191. package/dist/daemon/daemon-client.d.ts +34 -0
  192. package/dist/daemon/daemon-client.d.ts.map +1 -0
  193. package/dist/daemon/daemon-client.js +130 -0
  194. package/dist/daemon/daemon-client.js.map +1 -0
  195. package/dist/daemon/daemon-client.test.d.ts +2 -0
  196. package/dist/daemon/daemon-client.test.d.ts.map +1 -0
  197. package/dist/daemon/daemon-client.test.js +77 -0
  198. package/dist/daemon/daemon-client.test.js.map +1 -0
  199. package/dist/daemon/daemon-info.d.ts +7 -0
  200. package/dist/daemon/daemon-info.d.ts.map +1 -0
  201. package/dist/daemon/daemon-info.js +34 -0
  202. package/dist/daemon/daemon-info.js.map +1 -0
  203. package/dist/daemon/daemon-info.test.d.ts +2 -0
  204. package/dist/daemon/daemon-info.test.d.ts.map +1 -0
  205. package/dist/daemon/daemon-info.test.js +57 -0
  206. package/dist/daemon/daemon-info.test.js.map +1 -0
  207. package/dist/daemon/daemon-web-server.ai.test.d.ts +2 -0
  208. package/dist/daemon/daemon-web-server.ai.test.d.ts.map +1 -0
  209. package/dist/daemon/daemon-web-server.ai.test.js +119 -0
  210. package/dist/daemon/daemon-web-server.ai.test.js.map +1 -0
  211. package/dist/daemon/daemon-web-server.d.ts +59 -0
  212. package/dist/daemon/daemon-web-server.d.ts.map +1 -0
  213. package/dist/daemon/daemon-web-server.js +1236 -0
  214. package/dist/daemon/daemon-web-server.js.map +1 -0
  215. package/dist/daemon/daemon-web-server.test.d.ts +2 -0
  216. package/dist/daemon/daemon-web-server.test.d.ts.map +1 -0
  217. package/dist/daemon/daemon-web-server.test.js +93 -0
  218. package/dist/daemon/daemon-web-server.test.js.map +1 -0
  219. package/dist/daemon/mcpdog-daemon.d.ts +42 -0
  220. package/dist/daemon/mcpdog-daemon.d.ts.map +1 -0
  221. package/dist/daemon/mcpdog-daemon.js +302 -0
  222. package/dist/daemon/mcpdog-daemon.js.map +1 -0
  223. package/dist/daemon/stdio-proxy.d.ts +17 -0
  224. package/dist/daemon/stdio-proxy.d.ts.map +1 -0
  225. package/dist/daemon/stdio-proxy.js +143 -0
  226. package/dist/daemon/stdio-proxy.js.map +1 -0
  227. package/dist/index.d.ts +14 -0
  228. package/dist/index.d.ts.map +1 -0
  229. package/dist/index.js +198 -0
  230. package/dist/index.js.map +1 -0
  231. package/dist/intent-analyzer.d.ts +27 -0
  232. package/dist/intent-analyzer.d.ts.map +1 -0
  233. package/dist/intent-analyzer.js +140 -0
  234. package/dist/intent-analyzer.js.map +1 -0
  235. package/dist/logging/server-log-manager.d.ts +75 -0
  236. package/dist/logging/server-log-manager.d.ts.map +1 -0
  237. package/dist/logging/server-log-manager.js +185 -0
  238. package/dist/logging/server-log-manager.js.map +1 -0
  239. package/dist/mcp-registry.d.ts +35 -0
  240. package/dist/mcp-registry.d.ts.map +1 -0
  241. package/dist/mcp-registry.js +166 -0
  242. package/dist/mcp-registry.js.map +1 -0
  243. package/dist/middleware/auth.d.ts +5 -0
  244. package/dist/middleware/auth.d.ts.map +1 -0
  245. package/dist/middleware/auth.js +81 -0
  246. package/dist/middleware/auth.js.map +1 -0
  247. package/dist/mock-tool-database.d.ts +41 -0
  248. package/dist/mock-tool-database.d.ts.map +1 -0
  249. package/dist/mock-tool-database.js +461 -0
  250. package/dist/mock-tool-database.js.map +1 -0
  251. package/dist/proxy-server-manager.d.ts +11 -0
  252. package/dist/proxy-server-manager.d.ts.map +1 -0
  253. package/dist/proxy-server-manager.js +144 -0
  254. package/dist/proxy-server-manager.js.map +1 -0
  255. package/dist/router/tool-router.d.ts +61 -0
  256. package/dist/router/tool-router.d.ts.map +1 -0
  257. package/dist/router/tool-router.js +539 -0
  258. package/dist/router/tool-router.js.map +1 -0
  259. package/dist/router/tool-router.test.d.ts +2 -0
  260. package/dist/router/tool-router.test.d.ts.map +1 -0
  261. package/dist/router/tool-router.test.js +113 -0
  262. package/dist/router/tool-router.test.js.map +1 -0
  263. package/dist/streamable-http-server.d.ts +27 -0
  264. package/dist/streamable-http-server.d.ts.map +1 -0
  265. package/dist/streamable-http-server.js +302 -0
  266. package/dist/streamable-http-server.js.map +1 -0
  267. package/dist/tool-finder.d.ts +21 -0
  268. package/dist/tool-finder.d.ts.map +1 -0
  269. package/dist/tool-finder.js +86 -0
  270. package/dist/tool-finder.js.map +1 -0
  271. package/dist/tool-recommender.d.ts +23 -0
  272. package/dist/tool-recommender.d.ts.map +1 -0
  273. package/dist/tool-recommender.js +200 -0
  274. package/dist/tool-recommender.js.map +1 -0
  275. package/dist/types/index.d.ts +145 -0
  276. package/dist/types/index.d.ts.map +1 -0
  277. package/dist/types/index.js +2 -0
  278. package/dist/types/index.js.map +1 -0
  279. package/dist/utils/server-name-validator.d.ts +47 -0
  280. package/dist/utils/server-name-validator.d.ts.map +1 -0
  281. package/dist/utils/server-name-validator.js +156 -0
  282. package/dist/utils/server-name-validator.js.map +1 -0
  283. package/dist/web/web-server.d.ts +44 -0
  284. package/dist/web/web-server.d.ts.map +1 -0
  285. package/dist/web/web-server.js +500 -0
  286. package/dist/web/web-server.js.map +1 -0
  287. package/package.json +68 -0
  288. package/web/dist/assets/index-DMVhVtNU.css +1 -0
  289. package/web/dist/assets/index-VMXIgcOH.js +92 -0
  290. package/web/dist/assets/index-VMXIgcOH.js.map +1 -0
  291. package/web/dist/index.html +14 -0
@@ -0,0 +1,113 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
2
+ import { ToolRouter } from './tool-router';
3
+ import { EventEmitter } from 'events';
4
+ // Mock ServerAdapter
5
+ class MockAdapter extends EventEmitter {
6
+ name;
7
+ config;
8
+ isConnected = false;
9
+ tools;
10
+ constructor(name, tools) {
11
+ super();
12
+ this.name = name;
13
+ this.tools = tools;
14
+ this.config = {};
15
+ }
16
+ connect = vi.fn(async () => {
17
+ this.isConnected = true;
18
+ this.emit('connected');
19
+ });
20
+ disconnect = vi.fn(async () => {
21
+ this.isConnected = false;
22
+ this.emit('disconnected');
23
+ });
24
+ getTools = vi.fn(async () => {
25
+ if (!this.isConnected)
26
+ throw new Error('Not connected');
27
+ return this.tools;
28
+ });
29
+ callTool = vi.fn(async (toolName, args) => {
30
+ if (!this.isConnected)
31
+ throw new Error('Not connected');
32
+ return {
33
+ jsonrpc: '2.0',
34
+ id: 1,
35
+ result: { content: `Result from ${this.name}.${toolName}` },
36
+ };
37
+ });
38
+ // Added to satisfy ServerAdapter interface
39
+ sendRequest = vi.fn(async (request) => {
40
+ return {
41
+ jsonrpc: '2.0',
42
+ id: request.id,
43
+ result: { message: 'Mocked sendRequest' }
44
+ };
45
+ });
46
+ }
47
+ describe('ToolRouter', () => {
48
+ let toolRouter;
49
+ beforeEach(() => {
50
+ toolRouter = new ToolRouter();
51
+ });
52
+ it('should add an adapter and refresh routes on connect', async () => {
53
+ const mockTools = [{ name: 'tool1', description: 'desc1', inputSchema: { type: 'object' } }];
54
+ const adapter = new MockAdapter('server1', mockTools);
55
+ toolRouter.addAdapter(adapter);
56
+ await adapter.connect();
57
+ const allTools = await toolRouter.getAllTools();
58
+ expect(allTools).toHaveLength(1);
59
+ expect(allTools[0].name).toBe('tool1');
60
+ expect(toolRouter.getAdapter('server1')).toBe(adapter);
61
+ });
62
+ it('should handle tool name conflicts by prefixing', async () => {
63
+ const tools1 = [{ name: 'shared_tool', description: 'desc1', inputSchema: { type: 'object' } }];
64
+ const tools2 = [{ name: 'shared_tool', description: 'desc2', inputSchema: { type: 'object' } }];
65
+ const adapter1 = new MockAdapter('server1', tools1);
66
+ const adapter2 = new MockAdapter('server2', tools2);
67
+ toolRouter.addAdapter(adapter1);
68
+ toolRouter.addAdapter(adapter2);
69
+ await adapter1.connect();
70
+ await adapter2.connect();
71
+ const allTools = await toolRouter.getAllTools();
72
+ expect(allTools).toHaveLength(2);
73
+ const toolNames = allTools.map(t => t.name).sort();
74
+ expect(toolNames).toEqual(['server1-shared_tool', 'server2-shared_tool']);
75
+ });
76
+ it('should route a tool call to the correct adapter', async () => {
77
+ const tools1 = [{ name: 'tool1', description: 'desc1', inputSchema: { type: 'object' } }];
78
+ const tools2 = [{ name: 'tool2', description: 'desc2', inputSchema: { type: 'object' } }];
79
+ const adapter1 = new MockAdapter('server1', tools1);
80
+ const adapter2 = new MockAdapter('server2', tools2);
81
+ toolRouter.addAdapter(adapter1);
82
+ toolRouter.addAdapter(adapter2);
83
+ await adapter1.connect();
84
+ await adapter2.connect();
85
+ // Need to manually trigger route creation for testing since it happens on 'connect' event
86
+ // @ts-ignore - access private method for test
87
+ await toolRouter.refreshToolRoutes('server1');
88
+ // @ts-ignore
89
+ await toolRouter.refreshToolRoutes('server2');
90
+ const response = await toolRouter.callTool('tool2', {});
91
+ expect(response.result.content).toBe('Result from server2.tool2');
92
+ expect(adapter2.callTool).toHaveBeenCalledWith('tool2', {});
93
+ expect(adapter1.callTool).not.toHaveBeenCalled();
94
+ });
95
+ it('should return an error if a tool is not found', async () => {
96
+ const response = await toolRouter.callTool('non_existent_tool', {});
97
+ expect(response.error).toBeDefined();
98
+ expect(response.error?.code).toBe(-32601);
99
+ expect(response.error?.message).toContain('Tool not found');
100
+ });
101
+ it('should remove routes when an adapter disconnects', async () => {
102
+ const mockTools = [{ name: 'tool1', description: 'desc1', inputSchema: { type: 'object' } }];
103
+ const adapter = new MockAdapter('server1', mockTools);
104
+ toolRouter.addAdapter(adapter);
105
+ await adapter.connect();
106
+ let allTools = await toolRouter.getAllTools();
107
+ expect(allTools).toHaveLength(1);
108
+ adapter.emit('disconnected');
109
+ const route = toolRouter.findToolRoute('tool1');
110
+ expect(route).toBeUndefined();
111
+ });
112
+ });
113
+ //# sourceMappingURL=tool-router.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-router.test.js","sourceRoot":"","sources":["../../src/router/tool-router.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { EventEmitter } from 'events';
2
+ import { ConfigManager } from './config/config-manager.js';
3
+ export declare class StreamableHttpMCPServer extends EventEmitter {
4
+ private server;
5
+ private httpServer;
6
+ private port;
7
+ private authToken?;
8
+ private authMiddleware?;
9
+ private sessions;
10
+ private sessionTimeout;
11
+ constructor(configManager: ConfigManager, port?: number, authToken?: string);
12
+ private setupServer;
13
+ private setupHttpServer;
14
+ private handleAuthenticatedRequest;
15
+ private handleHealthCheck;
16
+ private handleHttpRequest;
17
+ private sendMCPResponse;
18
+ private shouldUseStreaming;
19
+ private sendErrorResponse;
20
+ private createSession;
21
+ private validateSession;
22
+ private updateSessionActivity;
23
+ private cleanupExpiredSessions;
24
+ start(): Promise<void>;
25
+ private shutdown;
26
+ }
27
+ //# sourceMappingURL=streamable-http-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streamable-http-server.d.ts","sourceRoot":"","sources":["../src/streamable-http-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAG3D,qBAAa,uBAAwB,SAAQ,YAAY;IACvD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAC,CAAwE;IAC/F,OAAO,CAAC,QAAQ,CAKD;IACf,OAAO,CAAC,cAAc,CAA0B;gBAEpC,aAAa,EAAE,aAAa,EAAE,IAAI,GAAE,MAAa,EAAE,SAAS,CAAC,EAAE,MAAM;IAgBjF,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,eAAe;IAuCvB,OAAO,CAAC,0BAA0B;IAWlC,OAAO,CAAC,iBAAiB;YAUX,iBAAiB;IA6F/B,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,sBAAsB;IAUxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAgCd,QAAQ;CA4BvB"}
@@ -0,0 +1,302 @@
1
+ import { createServer } from 'http';
2
+ import { EventEmitter } from 'events';
3
+ import { randomUUID } from 'crypto';
4
+ import { MCPDogServer } from './core/mcpdog-server.js';
5
+ import { createAuthMiddleware } from './middleware/auth.js';
6
+ export class StreamableHttpMCPServer extends EventEmitter {
7
+ server;
8
+ httpServer;
9
+ port;
10
+ authToken;
11
+ authMiddleware;
12
+ sessions = new Map();
13
+ sessionTimeout = 30 * 60 * 1000; // 30 minutes
14
+ constructor(configManager, port = 4000, authToken) {
15
+ super();
16
+ console.error(`[HTTP] Creating StreamableHttpMCPServer instance on port ${port}${authToken ? ' with authentication' : ''}`);
17
+ this.port = port;
18
+ this.authToken = authToken;
19
+ this.server = new MCPDogServer(configManager);
20
+ // Setup auth middleware if token is provided
21
+ if (this.authToken) {
22
+ this.authMiddleware = createAuthMiddleware(this.authToken);
23
+ }
24
+ this.setupServer();
25
+ this.setupHttpServer();
26
+ }
27
+ setupServer() {
28
+ this.server.on('notification', (notification) => {
29
+ // HTTP mode doesn't push notifications like stdio, they're request-response based
30
+ console.error(`[HTTP] Received notification: ${notification.method}`);
31
+ });
32
+ this.server.on('error', ({ error, context }) => {
33
+ console.error(`MCPDog error [${context}]:`, error);
34
+ });
35
+ this.server.on('started', () => {
36
+ console.error('MCPDog Server started (HTTP streamable mode)');
37
+ });
38
+ this.server.on('stopped', () => {
39
+ console.error('MCPDog Server stopped');
40
+ });
41
+ }
42
+ setupHttpServer() {
43
+ this.httpServer = createServer();
44
+ // Enable CORS for web-based MCP clients
45
+ this.httpServer.on('request', (req, res) => {
46
+ // Set CORS headers
47
+ res.setHeader('Access-Control-Allow-Origin', '*');
48
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
49
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, mcp-session-id');
50
+ if (req.method === 'OPTIONS') {
51
+ res.writeHead(200);
52
+ res.end();
53
+ return;
54
+ }
55
+ // Apply authentication middleware if configured
56
+ if (this.authMiddleware) {
57
+ this.authMiddleware(req, res, () => {
58
+ this.handleAuthenticatedRequest(req, res);
59
+ });
60
+ }
61
+ else {
62
+ this.handleAuthenticatedRequest(req, res);
63
+ }
64
+ });
65
+ this.httpServer.on('error', (error) => {
66
+ console.error('HTTP server error:', error);
67
+ });
68
+ // Handle process signals
69
+ process.on('SIGINT', () => this.shutdown());
70
+ process.on('SIGTERM', () => this.shutdown());
71
+ process.on('uncaughtException', (error) => {
72
+ console.error('Uncaught exception:', error);
73
+ this.shutdown();
74
+ });
75
+ }
76
+ handleAuthenticatedRequest(req, res) {
77
+ if (req.method === 'POST') {
78
+ this.handleHttpRequest(req, res);
79
+ }
80
+ else if (req.method === 'GET') {
81
+ this.handleHealthCheck(req, res);
82
+ }
83
+ else {
84
+ res.writeHead(405, { 'Content-Type': 'application/json' });
85
+ res.end(JSON.stringify({ error: 'Method not allowed' }));
86
+ }
87
+ }
88
+ handleHealthCheck(req, res) {
89
+ res.writeHead(200, { 'Content-Type': 'application/json' });
90
+ res.end(JSON.stringify({
91
+ status: 'healthy',
92
+ service: 'mcpdog-streamable-http',
93
+ version: '2.0.15',
94
+ timestamp: new Date().toISOString()
95
+ }));
96
+ }
97
+ async handleHttpRequest(req, res) {
98
+ let body = '';
99
+ req.on('data', (chunk) => {
100
+ body += chunk.toString();
101
+ });
102
+ req.on('end', async () => {
103
+ try {
104
+ console.error(`[HTTP] Received request: ${body.substring(0, 100)}...`);
105
+ if (!body.trim()) {
106
+ this.sendErrorResponse(res, 400, 'Empty request body');
107
+ return;
108
+ }
109
+ const message = JSON.parse(body);
110
+ // Extract session ID from headers
111
+ const sessionId = req.headers['mcp-session-id'];
112
+ // Check if it's a notification message (no id field)
113
+ if (!('id' in message)) {
114
+ const notification = message;
115
+ console.error(`[HTTP] Handling notification: ${notification.method}`);
116
+ // Validate session for non-initialize notifications
117
+ if (sessionId && !this.validateSession(sessionId)) {
118
+ this.sendErrorResponse(res, 401, 'Invalid or expired session');
119
+ return;
120
+ }
121
+ // Notifications get 204 No Content response
122
+ res.writeHead(204);
123
+ res.end();
124
+ return;
125
+ }
126
+ // Handle regular requests
127
+ const request = message;
128
+ console.error(`[HTTP] Processing request: ${request.method} (id: ${request.id})`);
129
+ // Handle initialize request - create new session
130
+ if (request.method === 'initialize') {
131
+ const response = await this.server.handleRequest(request, 'http-client');
132
+ if (!response.error) {
133
+ // Create new session
134
+ const newSessionId = this.createSession(req.socket?.remoteAddress || 'unknown');
135
+ console.error(`[HTTP] Created new session: ${newSessionId}`);
136
+ // Add session ID to response headers
137
+ res.setHeader('mcp-session-id', newSessionId);
138
+ this.sendMCPResponse(res, response);
139
+ }
140
+ else {
141
+ this.sendMCPResponse(res, response);
142
+ }
143
+ return;
144
+ }
145
+ // For non-initialize requests, validate session
146
+ if (!sessionId) {
147
+ this.sendErrorResponse(res, 400, 'Missing mcp-session-id header');
148
+ return;
149
+ }
150
+ if (!this.validateSession(sessionId)) {
151
+ this.sendErrorResponse(res, 401, 'Invalid or expired session');
152
+ return;
153
+ }
154
+ // Update session activity
155
+ this.updateSessionActivity(sessionId);
156
+ const response = await this.server.handleRequest(request, sessionId);
157
+ console.error(`[HTTP] Sending response for: ${request.method} (id: ${request.id})`);
158
+ this.sendMCPResponse(res, response);
159
+ }
160
+ catch (error) {
161
+ console.error('[HTTP] Error processing request:', error);
162
+ this.sendErrorResponse(res, 500, 'Internal server error');
163
+ }
164
+ });
165
+ req.on('error', (error) => {
166
+ console.error('[HTTP] Request error:', error);
167
+ this.sendErrorResponse(res, 400, 'Bad request');
168
+ });
169
+ }
170
+ sendMCPResponse(res, response) {
171
+ const responseBody = JSON.stringify(response);
172
+ // Check if this could be a streaming response (for future SSE support)
173
+ const isStreamingRequest = this.shouldUseStreaming(response);
174
+ if (isStreamingRequest) {
175
+ // Send as Server-Sent Events for streaming responses
176
+ res.writeHead(200, {
177
+ 'Content-Type': 'text/event-stream',
178
+ 'Cache-Control': 'no-cache',
179
+ 'Connection': 'keep-alive'
180
+ });
181
+ res.write(`event: message\n`);
182
+ res.write(`data: ${responseBody}\n\n`);
183
+ res.end();
184
+ }
185
+ else {
186
+ // Send as regular JSON response
187
+ res.writeHead(200, {
188
+ 'Content-Type': 'application/json'
189
+ });
190
+ res.end(responseBody);
191
+ }
192
+ }
193
+ shouldUseStreaming(response) {
194
+ // For now, always use JSON responses
195
+ // In the future, we could detect streaming scenarios (e.g., tool calls that take time)
196
+ return false;
197
+ }
198
+ sendErrorResponse(res, statusCode, message) {
199
+ res.writeHead(statusCode, { 'Content-Type': 'application/json' });
200
+ res.end(JSON.stringify({
201
+ error: {
202
+ code: statusCode,
203
+ message: message
204
+ }
205
+ }));
206
+ }
207
+ createSession(clientId) {
208
+ const sessionId = randomUUID();
209
+ const now = new Date();
210
+ this.sessions.set(sessionId, {
211
+ id: sessionId,
212
+ clientId: clientId,
213
+ created: now,
214
+ lastActivity: now
215
+ });
216
+ return sessionId;
217
+ }
218
+ validateSession(sessionId) {
219
+ const session = this.sessions.get(sessionId);
220
+ if (!session) {
221
+ return false;
222
+ }
223
+ // Check if session has expired
224
+ const now = new Date();
225
+ if (now.getTime() - session.lastActivity.getTime() > this.sessionTimeout) {
226
+ this.sessions.delete(sessionId);
227
+ return false;
228
+ }
229
+ return true;
230
+ }
231
+ updateSessionActivity(sessionId) {
232
+ const session = this.sessions.get(sessionId);
233
+ if (session) {
234
+ session.lastActivity = new Date();
235
+ }
236
+ }
237
+ cleanupExpiredSessions() {
238
+ const now = new Date();
239
+ for (const [sessionId, session] of this.sessions) {
240
+ if (now.getTime() - session.lastActivity.getTime() > this.sessionTimeout) {
241
+ console.error(`[HTTP] Cleaning up expired session: ${sessionId}`);
242
+ this.sessions.delete(sessionId);
243
+ }
244
+ }
245
+ }
246
+ async start() {
247
+ try {
248
+ console.error(`[HTTP] Starting StreamableHttpMCPServer...`);
249
+ await this.server.start();
250
+ // Start session cleanup timer
251
+ const cleanupInterval = setInterval(() => {
252
+ this.cleanupExpiredSessions();
253
+ }, 5 * 60 * 1000); // Clean up every 5 minutes
254
+ // Store cleanup interval for shutdown
255
+ this.cleanupInterval = cleanupInterval;
256
+ return new Promise((resolve, reject) => {
257
+ this.httpServer.listen(this.port, (error) => {
258
+ if (error) {
259
+ reject(error);
260
+ }
261
+ else {
262
+ console.error(`[HTTP] StreamableHttpMCPServer started successfully on port ${this.port}`);
263
+ console.error(`[HTTP] Health check endpoint: http://localhost:${this.port}/`);
264
+ console.error(`[HTTP] MCP endpoint: POST http://localhost:${this.port}/`);
265
+ console.error(`[HTTP] Session management enabled with ${this.sessionTimeout / 1000}s timeout`);
266
+ resolve();
267
+ }
268
+ });
269
+ });
270
+ }
271
+ catch (error) {
272
+ console.error('Failed to start HTTP server:', error);
273
+ process.exit(1);
274
+ }
275
+ }
276
+ async shutdown() {
277
+ console.error('Shutting down StreamableHttpMCPServer...');
278
+ try {
279
+ // Clean up session cleanup timer
280
+ if (this.cleanupInterval) {
281
+ clearInterval(this.cleanupInterval);
282
+ }
283
+ // Clear all sessions
284
+ this.sessions.clear();
285
+ if (this.httpServer) {
286
+ await new Promise((resolve) => {
287
+ this.httpServer.close(() => {
288
+ console.error('HTTP server closed');
289
+ resolve();
290
+ });
291
+ });
292
+ }
293
+ await this.server.stop();
294
+ process.exit(0);
295
+ }
296
+ catch (error) {
297
+ console.error('Error during shutdown:', error);
298
+ process.exit(1);
299
+ }
300
+ }
301
+ }
302
+ //# sourceMappingURL=streamable-http-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streamable-http-server.js","sourceRoot":"","sources":["../src/streamable-http-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { MCPTool } from './mcp-registry.js';
2
+ import { UserIntent } from './intent-analyzer.js';
3
+ export interface ToolMatch {
4
+ server: string;
5
+ tool: MCPTool;
6
+ matchScore: number;
7
+ suggestedCall?: {
8
+ toolName: string;
9
+ parameters: any;
10
+ reasoning: string;
11
+ };
12
+ }
13
+ export declare class ToolFinder {
14
+ private registry;
15
+ constructor();
16
+ findMatchingTools(intent: UserIntent): Promise<ToolMatch[]>;
17
+ private generateToolCall;
18
+ getServerConfig(serverName: string): import("./mcp-registry.js").MCPServerConfig | undefined;
19
+ getAllServers(): import("./mcp-registry.js").MCPServerInfo[];
20
+ }
21
+ //# sourceMappingURL=tool-finder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-finder.d.ts","sourceRoot":"","sources":["../src/tool-finder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,GAAG,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAc;;IAMxB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAoBjE,OAAO,CAAC,gBAAgB;IAiExB,eAAe,CAAC,UAAU,EAAE,MAAM;IAKlC,aAAa;CAGd"}
@@ -0,0 +1,86 @@
1
+ import { MCPRegistry } from './mcp-registry.js';
2
+ export class ToolFinder {
3
+ registry;
4
+ constructor() {
5
+ this.registry = new MCPRegistry();
6
+ }
7
+ async findMatchingTools(intent) {
8
+ // Use keyword matching to find tools
9
+ const matches = this.registry.findToolsByKeywords(intent.keywords);
10
+ // Generate call suggestions for each matched tool
11
+ const toolMatches = matches.map(match => {
12
+ const suggestedCall = this.generateToolCall(match.tool, intent);
13
+ return {
14
+ server: match.server,
15
+ tool: match.tool,
16
+ matchScore: match.matchScore,
17
+ suggestedCall
18
+ };
19
+ });
20
+ // Return top 3 best matches
21
+ return toolMatches.slice(0, 3);
22
+ }
23
+ generateToolCall(tool, intent) {
24
+ const parameters = {};
25
+ let reasoning = `Based on your request "${intent.description}", `;
26
+ // Intelligently fill parameters based on tool type and user intent
27
+ switch (tool.name) {
28
+ case 'browser_navigate':
29
+ if (intent.extractedData.url) {
30
+ parameters.url = intent.extractedData.url;
31
+ reasoning += `I have prepared a call to navigate to ${intent.extractedData.url}.`;
32
+ }
33
+ else {
34
+ parameters.url = 'https://www.google.com';
35
+ reasoning += `I suggest navigating to Google homepage first.`;
36
+ }
37
+ break;
38
+ case 'browser_type':
39
+ if (intent.extractedData.text) {
40
+ parameters.text = intent.extractedData.text;
41
+ parameters.submit = true;
42
+ reasoning += `I will input the text "${intent.extractedData.text}" and submit.`;
43
+ }
44
+ else {
45
+ parameters.text = 'Sample text';
46
+ parameters.submit = false;
47
+ reasoning += `This is a sample call for text input.`;
48
+ }
49
+ // Need to get page snapshot first to find input element
50
+ parameters.element = 'Need to get page snapshot to determine input element';
51
+ parameters.ref = 'Need to get element reference from snapshot';
52
+ break;
53
+ case 'browser_click':
54
+ parameters.element = 'Need to get page snapshot to determine click element';
55
+ parameters.ref = 'Need to get element reference from snapshot';
56
+ reasoning += `Need to get page snapshot to determine which element to click.`;
57
+ break;
58
+ case 'browser_screenshot':
59
+ case 'browser_snapshot':
60
+ case 'browser_go_back':
61
+ case 'browser_go_forward':
62
+ // These tools don't need parameters
63
+ reasoning += `This tool can be called directly.`;
64
+ break;
65
+ case 'browser_wait':
66
+ parameters.time = 2;
67
+ reasoning += `I suggest waiting 2 seconds.`;
68
+ break;
69
+ default:
70
+ reasoning += `This is a generic tool call.`;
71
+ }
72
+ return {
73
+ toolName: tool.name,
74
+ parameters,
75
+ reasoning
76
+ };
77
+ }
78
+ getServerConfig(serverName) {
79
+ const serverInfo = this.registry.getServerByName(serverName);
80
+ return serverInfo?.config;
81
+ }
82
+ getAllServers() {
83
+ return this.registry.getAllServers();
84
+ }
85
+ }
86
+ //# sourceMappingURL=tool-finder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-finder.js","sourceRoot":"","sources":["../src/tool-finder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { UserIntent } from "./intent-analyzer.js";
2
+ import { MockToolDatabase, MCPTool } from "./mock-tool-database.js";
3
+ export interface ToolRecommendation {
4
+ tool: MCPTool;
5
+ score: number;
6
+ rating: number;
7
+ reasoning: string;
8
+ usageInstructions: string[];
9
+ configurationSteps: string[];
10
+ }
11
+ export declare class ToolRecommendationEngine {
12
+ private toolDatabase;
13
+ constructor(toolDatabase: MockToolDatabase);
14
+ getRecommendations(intent: UserIntent): Promise<ToolRecommendation[]>;
15
+ private calculateRecommendationScore;
16
+ private hasRequiredData;
17
+ private calculateDisplayRating;
18
+ private generateReasoning;
19
+ private generateUsageInstructions;
20
+ private generateContextualExample;
21
+ private generateConfigurationSteps;
22
+ }
23
+ //# sourceMappingURL=tool-recommender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-recommender.d.ts","sourceRoot":"","sources":["../src/tool-recommender.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEpE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,qBAAa,wBAAwB;IACvB,OAAO,CAAC,YAAY;gBAAZ,YAAY,EAAE,gBAAgB;IAE5C,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAkC3E,OAAO,CAAC,4BAA4B;IAqDpC,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,sBAAsB;IAO9B,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,yBAAyB;IA8BjC,OAAO,CAAC,yBAAyB;IAwBjC,OAAO,CAAC,0BAA0B;CAoCnC"}