spec-gen-cli 1.0.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 (303) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1078 -0
  3. package/dist/api/analyze.d.ts +17 -0
  4. package/dist/api/analyze.d.ts.map +1 -0
  5. package/dist/api/analyze.js +109 -0
  6. package/dist/api/analyze.js.map +1 -0
  7. package/dist/api/drift.d.ts +21 -0
  8. package/dist/api/drift.d.ts.map +1 -0
  9. package/dist/api/drift.js +145 -0
  10. package/dist/api/drift.js.map +1 -0
  11. package/dist/api/generate.d.ts +18 -0
  12. package/dist/api/generate.d.ts.map +1 -0
  13. package/dist/api/generate.js +251 -0
  14. package/dist/api/generate.js.map +1 -0
  15. package/dist/api/index.d.ts +39 -0
  16. package/dist/api/index.d.ts.map +1 -0
  17. package/dist/api/index.js +32 -0
  18. package/dist/api/index.js.map +1 -0
  19. package/dist/api/init.d.ts +18 -0
  20. package/dist/api/init.d.ts.map +1 -0
  21. package/dist/api/init.js +82 -0
  22. package/dist/api/init.js.map +1 -0
  23. package/dist/api/run.d.ts +19 -0
  24. package/dist/api/run.d.ts.map +1 -0
  25. package/dist/api/run.js +291 -0
  26. package/dist/api/run.js.map +1 -0
  27. package/dist/api/specs.d.ts +49 -0
  28. package/dist/api/specs.d.ts.map +1 -0
  29. package/dist/api/specs.js +136 -0
  30. package/dist/api/specs.js.map +1 -0
  31. package/dist/api/types.d.ts +176 -0
  32. package/dist/api/types.d.ts.map +1 -0
  33. package/dist/api/types.js +9 -0
  34. package/dist/api/types.js.map +1 -0
  35. package/dist/api/verify.d.ts +20 -0
  36. package/dist/api/verify.d.ts.map +1 -0
  37. package/dist/api/verify.js +117 -0
  38. package/dist/api/verify.js.map +1 -0
  39. package/dist/cli/commands/analyze.d.ts +27 -0
  40. package/dist/cli/commands/analyze.d.ts.map +1 -0
  41. package/dist/cli/commands/analyze.js +485 -0
  42. package/dist/cli/commands/analyze.js.map +1 -0
  43. package/dist/cli/commands/drift.d.ts +9 -0
  44. package/dist/cli/commands/drift.d.ts.map +1 -0
  45. package/dist/cli/commands/drift.js +540 -0
  46. package/dist/cli/commands/drift.js.map +1 -0
  47. package/dist/cli/commands/generate.d.ts +9 -0
  48. package/dist/cli/commands/generate.d.ts.map +1 -0
  49. package/dist/cli/commands/generate.js +633 -0
  50. package/dist/cli/commands/generate.js.map +1 -0
  51. package/dist/cli/commands/init.d.ts +9 -0
  52. package/dist/cli/commands/init.d.ts.map +1 -0
  53. package/dist/cli/commands/init.js +171 -0
  54. package/dist/cli/commands/init.js.map +1 -0
  55. package/dist/cli/commands/mcp.d.ts +638 -0
  56. package/dist/cli/commands/mcp.d.ts.map +1 -0
  57. package/dist/cli/commands/mcp.js +574 -0
  58. package/dist/cli/commands/mcp.js.map +1 -0
  59. package/dist/cli/commands/run.d.ts +24 -0
  60. package/dist/cli/commands/run.d.ts.map +1 -0
  61. package/dist/cli/commands/run.js +546 -0
  62. package/dist/cli/commands/run.js.map +1 -0
  63. package/dist/cli/commands/verify.d.ts +9 -0
  64. package/dist/cli/commands/verify.d.ts.map +1 -0
  65. package/dist/cli/commands/verify.js +417 -0
  66. package/dist/cli/commands/verify.js.map +1 -0
  67. package/dist/cli/commands/view.d.ts +9 -0
  68. package/dist/cli/commands/view.d.ts.map +1 -0
  69. package/dist/cli/commands/view.js +511 -0
  70. package/dist/cli/commands/view.js.map +1 -0
  71. package/dist/cli/index.d.ts +9 -0
  72. package/dist/cli/index.d.ts.map +1 -0
  73. package/dist/cli/index.js +83 -0
  74. package/dist/cli/index.js.map +1 -0
  75. package/dist/core/analyzer/architecture-writer.d.ts +67 -0
  76. package/dist/core/analyzer/architecture-writer.d.ts.map +1 -0
  77. package/dist/core/analyzer/architecture-writer.js +209 -0
  78. package/dist/core/analyzer/architecture-writer.js.map +1 -0
  79. package/dist/core/analyzer/artifact-generator.d.ts +222 -0
  80. package/dist/core/analyzer/artifact-generator.d.ts.map +1 -0
  81. package/dist/core/analyzer/artifact-generator.js +726 -0
  82. package/dist/core/analyzer/artifact-generator.js.map +1 -0
  83. package/dist/core/analyzer/call-graph.d.ts +83 -0
  84. package/dist/core/analyzer/call-graph.d.ts.map +1 -0
  85. package/dist/core/analyzer/call-graph.js +827 -0
  86. package/dist/core/analyzer/call-graph.js.map +1 -0
  87. package/dist/core/analyzer/code-shaper.d.ts +33 -0
  88. package/dist/core/analyzer/code-shaper.d.ts.map +1 -0
  89. package/dist/core/analyzer/code-shaper.js +149 -0
  90. package/dist/core/analyzer/code-shaper.js.map +1 -0
  91. package/dist/core/analyzer/dependency-graph.d.ts +179 -0
  92. package/dist/core/analyzer/dependency-graph.d.ts.map +1 -0
  93. package/dist/core/analyzer/dependency-graph.js +574 -0
  94. package/dist/core/analyzer/dependency-graph.js.map +1 -0
  95. package/dist/core/analyzer/duplicate-detector.d.ts +52 -0
  96. package/dist/core/analyzer/duplicate-detector.d.ts.map +1 -0
  97. package/dist/core/analyzer/duplicate-detector.js +279 -0
  98. package/dist/core/analyzer/duplicate-detector.js.map +1 -0
  99. package/dist/core/analyzer/embedding-service.d.ts +50 -0
  100. package/dist/core/analyzer/embedding-service.d.ts.map +1 -0
  101. package/dist/core/analyzer/embedding-service.js +104 -0
  102. package/dist/core/analyzer/embedding-service.js.map +1 -0
  103. package/dist/core/analyzer/file-walker.d.ts +78 -0
  104. package/dist/core/analyzer/file-walker.d.ts.map +1 -0
  105. package/dist/core/analyzer/file-walker.js +531 -0
  106. package/dist/core/analyzer/file-walker.js.map +1 -0
  107. package/dist/core/analyzer/import-parser.d.ts +91 -0
  108. package/dist/core/analyzer/import-parser.d.ts.map +1 -0
  109. package/dist/core/analyzer/import-parser.js +720 -0
  110. package/dist/core/analyzer/import-parser.js.map +1 -0
  111. package/dist/core/analyzer/index.d.ts +10 -0
  112. package/dist/core/analyzer/index.d.ts.map +1 -0
  113. package/dist/core/analyzer/index.js +10 -0
  114. package/dist/core/analyzer/index.js.map +1 -0
  115. package/dist/core/analyzer/refactor-analyzer.d.ts +80 -0
  116. package/dist/core/analyzer/refactor-analyzer.d.ts.map +1 -0
  117. package/dist/core/analyzer/refactor-analyzer.js +339 -0
  118. package/dist/core/analyzer/refactor-analyzer.js.map +1 -0
  119. package/dist/core/analyzer/repository-mapper.d.ts +150 -0
  120. package/dist/core/analyzer/repository-mapper.d.ts.map +1 -0
  121. package/dist/core/analyzer/repository-mapper.js +731 -0
  122. package/dist/core/analyzer/repository-mapper.js.map +1 -0
  123. package/dist/core/analyzer/signature-extractor.d.ts +31 -0
  124. package/dist/core/analyzer/signature-extractor.d.ts.map +1 -0
  125. package/dist/core/analyzer/signature-extractor.js +387 -0
  126. package/dist/core/analyzer/signature-extractor.js.map +1 -0
  127. package/dist/core/analyzer/significance-scorer.d.ts +79 -0
  128. package/dist/core/analyzer/significance-scorer.d.ts.map +1 -0
  129. package/dist/core/analyzer/significance-scorer.js +407 -0
  130. package/dist/core/analyzer/significance-scorer.js.map +1 -0
  131. package/dist/core/analyzer/subgraph-extractor.d.ts +43 -0
  132. package/dist/core/analyzer/subgraph-extractor.d.ts.map +1 -0
  133. package/dist/core/analyzer/subgraph-extractor.js +129 -0
  134. package/dist/core/analyzer/subgraph-extractor.js.map +1 -0
  135. package/dist/core/analyzer/vector-index.d.ts +63 -0
  136. package/dist/core/analyzer/vector-index.d.ts.map +1 -0
  137. package/dist/core/analyzer/vector-index.js +169 -0
  138. package/dist/core/analyzer/vector-index.js.map +1 -0
  139. package/dist/core/drift/drift-detector.d.ts +102 -0
  140. package/dist/core/drift/drift-detector.d.ts.map +1 -0
  141. package/dist/core/drift/drift-detector.js +597 -0
  142. package/dist/core/drift/drift-detector.js.map +1 -0
  143. package/dist/core/drift/git-diff.d.ts +55 -0
  144. package/dist/core/drift/git-diff.d.ts.map +1 -0
  145. package/dist/core/drift/git-diff.js +356 -0
  146. package/dist/core/drift/git-diff.js.map +1 -0
  147. package/dist/core/drift/index.d.ts +12 -0
  148. package/dist/core/drift/index.d.ts.map +1 -0
  149. package/dist/core/drift/index.js +9 -0
  150. package/dist/core/drift/index.js.map +1 -0
  151. package/dist/core/drift/spec-mapper.d.ts +73 -0
  152. package/dist/core/drift/spec-mapper.d.ts.map +1 -0
  153. package/dist/core/drift/spec-mapper.js +353 -0
  154. package/dist/core/drift/spec-mapper.js.map +1 -0
  155. package/dist/core/generator/adr-generator.d.ts +32 -0
  156. package/dist/core/generator/adr-generator.d.ts.map +1 -0
  157. package/dist/core/generator/adr-generator.js +192 -0
  158. package/dist/core/generator/adr-generator.js.map +1 -0
  159. package/dist/core/generator/index.d.ts +9 -0
  160. package/dist/core/generator/index.d.ts.map +1 -0
  161. package/dist/core/generator/index.js +12 -0
  162. package/dist/core/generator/index.js.map +1 -0
  163. package/dist/core/generator/mapping-generator.d.ts +54 -0
  164. package/dist/core/generator/mapping-generator.d.ts.map +1 -0
  165. package/dist/core/generator/mapping-generator.js +239 -0
  166. package/dist/core/generator/mapping-generator.js.map +1 -0
  167. package/dist/core/generator/openspec-compat.d.ts +160 -0
  168. package/dist/core/generator/openspec-compat.d.ts.map +1 -0
  169. package/dist/core/generator/openspec-compat.js +523 -0
  170. package/dist/core/generator/openspec-compat.js.map +1 -0
  171. package/dist/core/generator/openspec-format-generator.d.ts +111 -0
  172. package/dist/core/generator/openspec-format-generator.d.ts.map +1 -0
  173. package/dist/core/generator/openspec-format-generator.js +817 -0
  174. package/dist/core/generator/openspec-format-generator.js.map +1 -0
  175. package/dist/core/generator/openspec-writer.d.ts +131 -0
  176. package/dist/core/generator/openspec-writer.d.ts.map +1 -0
  177. package/dist/core/generator/openspec-writer.js +379 -0
  178. package/dist/core/generator/openspec-writer.js.map +1 -0
  179. package/dist/core/generator/prompts.d.ts +35 -0
  180. package/dist/core/generator/prompts.d.ts.map +1 -0
  181. package/dist/core/generator/prompts.js +212 -0
  182. package/dist/core/generator/prompts.js.map +1 -0
  183. package/dist/core/generator/spec-pipeline.d.ts +94 -0
  184. package/dist/core/generator/spec-pipeline.d.ts.map +1 -0
  185. package/dist/core/generator/spec-pipeline.js +474 -0
  186. package/dist/core/generator/spec-pipeline.js.map +1 -0
  187. package/dist/core/generator/stages/stage1-survey.d.ts +19 -0
  188. package/dist/core/generator/stages/stage1-survey.d.ts.map +1 -0
  189. package/dist/core/generator/stages/stage1-survey.js +105 -0
  190. package/dist/core/generator/stages/stage1-survey.js.map +1 -0
  191. package/dist/core/generator/stages/stage2-entities.d.ts +11 -0
  192. package/dist/core/generator/stages/stage2-entities.d.ts.map +1 -0
  193. package/dist/core/generator/stages/stage2-entities.js +67 -0
  194. package/dist/core/generator/stages/stage2-entities.js.map +1 -0
  195. package/dist/core/generator/stages/stage3-services.d.ts +11 -0
  196. package/dist/core/generator/stages/stage3-services.d.ts.map +1 -0
  197. package/dist/core/generator/stages/stage3-services.js +75 -0
  198. package/dist/core/generator/stages/stage3-services.js.map +1 -0
  199. package/dist/core/generator/stages/stage4-api.d.ts +11 -0
  200. package/dist/core/generator/stages/stage4-api.d.ts.map +1 -0
  201. package/dist/core/generator/stages/stage4-api.js +65 -0
  202. package/dist/core/generator/stages/stage4-api.js.map +1 -0
  203. package/dist/core/generator/stages/stage5-architecture.d.ts +10 -0
  204. package/dist/core/generator/stages/stage5-architecture.d.ts.map +1 -0
  205. package/dist/core/generator/stages/stage5-architecture.js +62 -0
  206. package/dist/core/generator/stages/stage5-architecture.js.map +1 -0
  207. package/dist/core/generator/stages/stage6-adr.d.ts +8 -0
  208. package/dist/core/generator/stages/stage6-adr.d.ts.map +1 -0
  209. package/dist/core/generator/stages/stage6-adr.js +41 -0
  210. package/dist/core/generator/stages/stage6-adr.js.map +1 -0
  211. package/dist/core/services/chat-agent.d.ts +45 -0
  212. package/dist/core/services/chat-agent.d.ts.map +1 -0
  213. package/dist/core/services/chat-agent.js +310 -0
  214. package/dist/core/services/chat-agent.js.map +1 -0
  215. package/dist/core/services/chat-tools.d.ts +32 -0
  216. package/dist/core/services/chat-tools.d.ts.map +1 -0
  217. package/dist/core/services/chat-tools.js +270 -0
  218. package/dist/core/services/chat-tools.js.map +1 -0
  219. package/dist/core/services/config-manager.d.ts +61 -0
  220. package/dist/core/services/config-manager.d.ts.map +1 -0
  221. package/dist/core/services/config-manager.js +143 -0
  222. package/dist/core/services/config-manager.js.map +1 -0
  223. package/dist/core/services/gitignore-manager.d.ts +29 -0
  224. package/dist/core/services/gitignore-manager.d.ts.map +1 -0
  225. package/dist/core/services/gitignore-manager.js +106 -0
  226. package/dist/core/services/gitignore-manager.js.map +1 -0
  227. package/dist/core/services/index.d.ts +8 -0
  228. package/dist/core/services/index.d.ts.map +1 -0
  229. package/dist/core/services/index.js +8 -0
  230. package/dist/core/services/index.js.map +1 -0
  231. package/dist/core/services/llm-service.d.ts +336 -0
  232. package/dist/core/services/llm-service.d.ts.map +1 -0
  233. package/dist/core/services/llm-service.js +1155 -0
  234. package/dist/core/services/llm-service.js.map +1 -0
  235. package/dist/core/services/mcp-handlers/analysis.d.ts +42 -0
  236. package/dist/core/services/mcp-handlers/analysis.d.ts.map +1 -0
  237. package/dist/core/services/mcp-handlers/analysis.js +300 -0
  238. package/dist/core/services/mcp-handlers/analysis.js.map +1 -0
  239. package/dist/core/services/mcp-handlers/graph.d.ts +65 -0
  240. package/dist/core/services/mcp-handlers/graph.d.ts.map +1 -0
  241. package/dist/core/services/mcp-handlers/graph.js +509 -0
  242. package/dist/core/services/mcp-handlers/graph.js.map +1 -0
  243. package/dist/core/services/mcp-handlers/semantic.d.ts +38 -0
  244. package/dist/core/services/mcp-handlers/semantic.d.ts.map +1 -0
  245. package/dist/core/services/mcp-handlers/semantic.js +172 -0
  246. package/dist/core/services/mcp-handlers/semantic.js.map +1 -0
  247. package/dist/core/services/mcp-handlers/utils.d.ts +21 -0
  248. package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -0
  249. package/dist/core/services/mcp-handlers/utils.js +62 -0
  250. package/dist/core/services/mcp-handlers/utils.js.map +1 -0
  251. package/dist/core/services/project-detector.d.ts +32 -0
  252. package/dist/core/services/project-detector.d.ts.map +1 -0
  253. package/dist/core/services/project-detector.js +111 -0
  254. package/dist/core/services/project-detector.js.map +1 -0
  255. package/dist/core/verifier/index.d.ts +5 -0
  256. package/dist/core/verifier/index.d.ts.map +1 -0
  257. package/dist/core/verifier/index.js +5 -0
  258. package/dist/core/verifier/index.js.map +1 -0
  259. package/dist/core/verifier/verification-engine.d.ts +226 -0
  260. package/dist/core/verifier/verification-engine.d.ts.map +1 -0
  261. package/dist/core/verifier/verification-engine.js +681 -0
  262. package/dist/core/verifier/verification-engine.js.map +1 -0
  263. package/dist/types/index.d.ts +252 -0
  264. package/dist/types/index.d.ts.map +1 -0
  265. package/dist/types/index.js +5 -0
  266. package/dist/types/index.js.map +1 -0
  267. package/dist/types/pipeline.d.ts +148 -0
  268. package/dist/types/pipeline.d.ts.map +1 -0
  269. package/dist/types/pipeline.js +5 -0
  270. package/dist/types/pipeline.js.map +1 -0
  271. package/dist/utils/errors.d.ts +51 -0
  272. package/dist/utils/errors.d.ts.map +1 -0
  273. package/dist/utils/errors.js +128 -0
  274. package/dist/utils/errors.js.map +1 -0
  275. package/dist/utils/logger.d.ts +149 -0
  276. package/dist/utils/logger.d.ts.map +1 -0
  277. package/dist/utils/logger.js +331 -0
  278. package/dist/utils/logger.js.map +1 -0
  279. package/dist/utils/progress.d.ts +142 -0
  280. package/dist/utils/progress.d.ts.map +1 -0
  281. package/dist/utils/progress.js +280 -0
  282. package/dist/utils/progress.js.map +1 -0
  283. package/dist/utils/prompts.d.ts +53 -0
  284. package/dist/utils/prompts.d.ts.map +1 -0
  285. package/dist/utils/prompts.js +199 -0
  286. package/dist/utils/prompts.js.map +1 -0
  287. package/dist/utils/shutdown.d.ts +89 -0
  288. package/dist/utils/shutdown.d.ts.map +1 -0
  289. package/dist/utils/shutdown.js +237 -0
  290. package/dist/utils/shutdown.js.map +1 -0
  291. package/package.json +114 -0
  292. package/src/viewer/InteractiveGraphViewer.jsx +1486 -0
  293. package/src/viewer/app/index.html +17 -0
  294. package/src/viewer/app/main.jsx +13 -0
  295. package/src/viewer/components/ArchitectureView.jsx +177 -0
  296. package/src/viewer/components/ChatPanel.jsx +448 -0
  297. package/src/viewer/components/ClusterGraph.jsx +441 -0
  298. package/src/viewer/components/FilterBar.jsx +179 -0
  299. package/src/viewer/components/FlatGraph.jsx +275 -0
  300. package/src/viewer/components/MicroComponents.jsx +83 -0
  301. package/src/viewer/hooks/usePanZoom.js +79 -0
  302. package/src/viewer/utils/constants.js +47 -0
  303. package/src/viewer/utils/graph-helpers.js +291 -0
@@ -0,0 +1,310 @@
1
+ /**
2
+ * ChatAgent — agentic tool-use loop for the diagram chatbot.
3
+ *
4
+ * Supports three provider formats:
5
+ * - Anthropic Claude (tool_use / tool_result via /v1/messages)
6
+ * - OpenAI-compatible (function calling via /chat/completions)
7
+ * - Google Gemini (function calling via generateContent)
8
+ *
9
+ * Provider resolution (same priority as generate.ts):
10
+ * 1. GEMINI_API_KEY → Gemini
11
+ * 2. ANTHROPIC_API_KEY → Anthropic Claude
12
+ * 3. OPENAI_COMPAT_BASE_URL → any OpenAI-compatible endpoint
13
+ * 4. specGenConfig.generation → reads provider + openaiCompatBaseUrl from config
14
+ * 5. OPENAI_API_KEY → OpenAI directly
15
+ *
16
+ * Model: OPENAI_COMPAT_MODEL env var → specGenConfig.generation.model → provider default.
17
+ *
18
+ * Max iterations: 8 (prevents runaway loops).
19
+ */
20
+ import { CHAT_TOOLS, toChatToolDefinitions } from './chat-tools.js';
21
+ import { readSpecGenConfig } from './config-manager.js';
22
+ export async function resolveProviderConfig(directory) {
23
+ const geminiKey = process.env.GEMINI_API_KEY ?? '';
24
+ const anthropicKey = process.env.ANTHROPIC_API_KEY ?? '';
25
+ const compatBase = process.env.OPENAI_COMPAT_BASE_URL ?? '';
26
+ const compatKey = process.env.OPENAI_COMPAT_API_KEY ?? '';
27
+ const openaiKey = process.env.OPENAI_API_KEY ?? '';
28
+ const envModel = process.env.OPENAI_COMPAT_MODEL ?? '';
29
+ // Load project config once
30
+ let cfgProvider;
31
+ let cfgBase;
32
+ let cfgModel;
33
+ try {
34
+ const cfg = await readSpecGenConfig(directory);
35
+ cfgProvider = cfg?.generation?.provider;
36
+ cfgBase = cfg?.generation?.openaiCompatBaseUrl;
37
+ cfgModel = cfg?.generation?.model;
38
+ }
39
+ catch { /* ignore */ }
40
+ // Priority: explicit config provider > env key signals > fallback openai-compat
41
+ // Explicit config always wins so users can override a globally-set env key.
42
+ if (cfgProvider === 'gemini' || (!cfgProvider && geminiKey)) {
43
+ return {
44
+ kind: 'gemini',
45
+ baseUrl: 'https://generativelanguage.googleapis.com/v1beta/models',
46
+ apiKey: geminiKey,
47
+ model: envModel || cfgModel || 'gemini-2.0-flash',
48
+ };
49
+ }
50
+ if (cfgProvider === 'anthropic' || (!cfgProvider && anthropicKey)) {
51
+ return {
52
+ kind: 'anthropic',
53
+ baseUrl: 'https://api.anthropic.com/v1',
54
+ apiKey: anthropicKey,
55
+ model: envModel || cfgModel || 'claude-sonnet-4-6',
56
+ };
57
+ }
58
+ const base = compatBase || cfgBase || 'https://api.openai.com/v1';
59
+ const key = compatKey || openaiKey;
60
+ return {
61
+ kind: 'openai-compat',
62
+ baseUrl: base.replace(/\/$/, ''),
63
+ apiKey: key,
64
+ model: envModel || cfgModel || 'gpt-4o-mini',
65
+ };
66
+ }
67
+ const MAX_ITERATIONS = 8;
68
+ function buildSystemPrompt(directory) {
69
+ return `You are a code analysis assistant embedded in a dependency diagram viewer.
70
+ The project directory is: ${directory}
71
+ You have access to tools that query the codebase's static analysis data.
72
+ When calling tools, always pass directory="${directory}" -- never ask the user for it.
73
+ When the user asks a question, use the appropriate tools to gather information,
74
+ then synthesise a clear, concise answer. Always explain what the highlighted files/functions are.
75
+ Keep replies focused and actionable. Use markdown for code and lists.`;
76
+ }
77
+ async function executeTool(toolMap, directory, name, args, callbacks) {
78
+ callbacks?.onToolStart?.(name);
79
+ const tool = toolMap.get(name);
80
+ if (!tool) {
81
+ return { content: JSON.stringify({ error: `Unknown tool: ${name}` }), filePaths: [] };
82
+ }
83
+ try {
84
+ const { result, filePaths } = await tool.execute(directory, args);
85
+ const content = typeof result === 'string' ? result : JSON.stringify(result, null, 2);
86
+ callbacks?.onToolEnd?.(name);
87
+ return { content, filePaths };
88
+ }
89
+ catch (err) {
90
+ callbacks?.onToolEnd?.(name);
91
+ return {
92
+ content: JSON.stringify({ error: err instanceof Error ? err.message : String(err) }),
93
+ filePaths: [],
94
+ };
95
+ }
96
+ }
97
+ // ============================================================================
98
+ // OPENAI-COMPATIBLE LOOP
99
+ // ============================================================================
100
+ async function runOpenAILoop(cfg, directory, messages, callbacks, signal) {
101
+ const toolDefs = toChatToolDefinitions();
102
+ const toolMap = new Map(CHAT_TOOLS.map(t => [t.name, t]));
103
+ const allFilePaths = [];
104
+ const history = [
105
+ { role: 'system', content: buildSystemPrompt(directory) },
106
+ ...messages.map(m => ({ role: m.role, content: m.content })),
107
+ ];
108
+ const headers = { 'Content-Type': 'application/json' };
109
+ if (cfg.apiKey)
110
+ headers['Authorization'] = `Bearer ${cfg.apiKey}`;
111
+ for (let iter = 0; iter < MAX_ITERATIONS; iter++) {
112
+ if (signal?.aborted)
113
+ break;
114
+ const response = await fetch(`${cfg.baseUrl}/chat/completions`, {
115
+ method: 'POST',
116
+ headers,
117
+ body: JSON.stringify({ model: cfg.model, messages: history, tools: toolDefs, tool_choice: 'auto' }),
118
+ signal,
119
+ });
120
+ if (!response.ok) {
121
+ const errText = await response.text().catch(() => '');
122
+ throw new Error(`Chat API error ${response.status}: ${errText.slice(0, 300)}`);
123
+ }
124
+ const data = (await response.json());
125
+ const choice = data.choices[0];
126
+ if (!choice)
127
+ throw new Error('Empty response from chat API');
128
+ const msg = choice.message;
129
+ history.push({ role: 'assistant', content: msg.content ?? null, tool_calls: msg.tool_calls });
130
+ if (!msg.tool_calls || msg.tool_calls.length === 0) {
131
+ return { reply: msg.content ?? '(no response)', filePaths: [...new Set(allFilePaths)] };
132
+ }
133
+ for (const tc of msg.tool_calls) {
134
+ let args;
135
+ try {
136
+ args = JSON.parse(tc.function.arguments);
137
+ }
138
+ catch {
139
+ args = {};
140
+ }
141
+ const { content, filePaths } = await executeTool(toolMap, directory, tc.function.name, args, callbacks);
142
+ allFilePaths.push(...filePaths);
143
+ history.push({ role: 'tool', tool_call_id: tc.id, content });
144
+ }
145
+ }
146
+ const lastAssistant = [...history].reverse().find(m => m.role === 'assistant' && m.content);
147
+ return {
148
+ reply: lastAssistant?.content ?? 'Analysis complete. Check highlighted nodes.',
149
+ filePaths: [...new Set(allFilePaths)],
150
+ };
151
+ }
152
+ // ============================================================================
153
+ // GEMINI LOOP
154
+ // ============================================================================
155
+ async function runGeminiLoop(cfg, directory, messages, callbacks, signal) {
156
+ const toolMap = new Map(CHAT_TOOLS.map(t => [t.name, t]));
157
+ const allFilePaths = [];
158
+ // Build function declarations for Gemini
159
+ const functionDeclarations = CHAT_TOOLS.map(t => ({
160
+ name: t.name,
161
+ description: t.description,
162
+ parameters: t.inputSchema,
163
+ }));
164
+ // Convert history to Gemini content format (no system role — handled separately)
165
+ const contents = messages.map(m => ({
166
+ role: m.role === 'assistant' ? 'model' : 'user',
167
+ parts: [{ text: m.content }],
168
+ }));
169
+ const url = `${cfg.baseUrl}/${cfg.model}:generateContent?key=${cfg.apiKey}`;
170
+ const headers = { 'Content-Type': 'application/json' };
171
+ for (let iter = 0; iter < MAX_ITERATIONS; iter++) {
172
+ if (signal?.aborted)
173
+ break;
174
+ const body = {
175
+ systemInstruction: { parts: [{ text: buildSystemPrompt(directory) }] },
176
+ contents,
177
+ tools: [{ function_declarations: functionDeclarations }],
178
+ tool_config: { function_calling_config: { mode: 'AUTO' } },
179
+ };
180
+ const response = await fetch(url, { method: 'POST', headers, body: JSON.stringify(body), signal });
181
+ if (!response.ok) {
182
+ const errText = await response.text().catch(() => '');
183
+ throw new Error(`Gemini API error ${response.status}: ${errText.slice(0, 300)}`);
184
+ }
185
+ const data = (await response.json());
186
+ const candidate = data.candidates?.[0];
187
+ if (!candidate)
188
+ throw new Error('Empty response from Gemini API');
189
+ const parts = candidate.content.parts;
190
+ // Collect text and function calls from this turn
191
+ const textParts = parts.filter((p) => 'text' in p);
192
+ const fnCalls = parts.filter((p) => 'functionCall' in p);
193
+ // Append model turn
194
+ contents.push({ role: 'model', parts });
195
+ if (fnCalls.length === 0) {
196
+ // Final answer — join all text parts
197
+ const reply = textParts.map(p => p.text).join('').trim();
198
+ return { reply: reply || '(no response)', filePaths: [...new Set(allFilePaths)] };
199
+ }
200
+ // Execute tool calls and build a single user turn with all responses
201
+ const responseParts = [];
202
+ for (const fc of fnCalls) {
203
+ const { content, filePaths } = await executeTool(toolMap, directory, fc.functionCall.name, fc.functionCall.args, callbacks);
204
+ allFilePaths.push(...filePaths);
205
+ let parsed;
206
+ try {
207
+ parsed = JSON.parse(content);
208
+ }
209
+ catch {
210
+ parsed = { result: content };
211
+ }
212
+ responseParts.push({ functionResponse: { name: fc.functionCall.name, response: parsed } });
213
+ }
214
+ contents.push({ role: 'user', parts: responseParts });
215
+ }
216
+ // Max iterations — extract last model text
217
+ const lastModel = [...contents].reverse().find(c => c.role === 'model');
218
+ const lastText = lastModel?.parts.filter((p) => 'text' in p).map(p => p.text).join('') ?? '';
219
+ return {
220
+ reply: lastText || 'Analysis complete. Check highlighted nodes.',
221
+ filePaths: [...new Set(allFilePaths)],
222
+ };
223
+ }
224
+ // ============================================================================
225
+ // ANTHROPIC LOOP
226
+ // ============================================================================
227
+ async function runAnthropicLoop(cfg, directory, messages, callbacks, signal) {
228
+ const toolMap = new Map(CHAT_TOOLS.map(t => [t.name, t]));
229
+ const allFilePaths = [];
230
+ const tools = CHAT_TOOLS.map(t => ({
231
+ name: t.name,
232
+ description: t.description,
233
+ input_schema: t.inputSchema,
234
+ }));
235
+ const history = messages.map(m => ({
236
+ role: m.role,
237
+ content: m.content,
238
+ }));
239
+ const headers = {
240
+ 'Content-Type': 'application/json',
241
+ 'anthropic-version': '2023-06-01',
242
+ 'x-api-key': cfg.apiKey,
243
+ };
244
+ for (let iter = 0; iter < MAX_ITERATIONS; iter++) {
245
+ if (signal?.aborted)
246
+ break;
247
+ const response = await fetch(`${cfg.baseUrl}/messages`, {
248
+ method: 'POST',
249
+ headers,
250
+ body: JSON.stringify({
251
+ model: cfg.model,
252
+ max_tokens: 4096,
253
+ system: buildSystemPrompt(directory),
254
+ tools,
255
+ messages: history,
256
+ }),
257
+ signal,
258
+ });
259
+ if (!response.ok) {
260
+ const errText = await response.text().catch(() => '');
261
+ throw new Error(`Anthropic API error ${response.status}: ${errText.slice(0, 300)}`);
262
+ }
263
+ const data = (await response.json());
264
+ // Append assistant turn
265
+ history.push({ role: 'assistant', content: data.content });
266
+ if (data.stop_reason !== 'tool_use') {
267
+ const text = data.content
268
+ .filter((b) => b.type === 'text')
269
+ .map(b => b.text)
270
+ .join('');
271
+ return { reply: text || '(no response)', filePaths: [...new Set(allFilePaths)] };
272
+ }
273
+ // Execute all tool_use blocks and collect results in a single user turn
274
+ const toolUseBlocks = data.content.filter((b) => b.type === 'tool_use');
275
+ const resultBlocks = [];
276
+ for (const tu of toolUseBlocks) {
277
+ const { content, filePaths } = await executeTool(toolMap, directory, tu.name, tu.input, callbacks);
278
+ allFilePaths.push(...filePaths);
279
+ resultBlocks.push({ type: 'tool_result', tool_use_id: tu.id, content });
280
+ }
281
+ history.push({ role: 'user', content: resultBlocks });
282
+ }
283
+ // Max iterations — extract last assistant text
284
+ const lastAssistant = [...history].reverse().find(m => m.role === 'assistant');
285
+ const lastText = Array.isArray(lastAssistant?.content)
286
+ ? lastAssistant.content
287
+ .filter((b) => b.type === 'text')
288
+ .map(b => b.text).join('')
289
+ : lastAssistant?.content ?? '';
290
+ return {
291
+ reply: lastText || 'Analysis complete. Check highlighted nodes.',
292
+ filePaths: [...new Set(allFilePaths)],
293
+ };
294
+ }
295
+ // ============================================================================
296
+ // ENTRY POINT
297
+ // ============================================================================
298
+ export async function runChatAgent(options) {
299
+ const { directory, messages, modelOverride, signal, onToolStart, onToolEnd } = options;
300
+ const cfg = await resolveProviderConfig(directory);
301
+ if (modelOverride)
302
+ cfg.model = modelOverride;
303
+ const callbacks = { onToolStart, onToolEnd };
304
+ if (cfg.kind === 'gemini')
305
+ return runGeminiLoop(cfg, directory, messages, callbacks, signal);
306
+ if (cfg.kind === 'anthropic')
307
+ return runAnthropicLoop(cfg, directory, messages, callbacks, signal);
308
+ return runOpenAILoop(cfg, directory, messages, callbacks, signal);
309
+ }
310
+ //# sourceMappingURL=chat-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-agent.js","sourceRoot":"","sources":["../../../src/core/services/chat-agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Tool registry for the diagram chatbot.
3
+ *
4
+ * Each entry in CHAT_TOOLS maps a tool name to:
5
+ * - description / inputSchema — forwarded to the LLM as tool definitions
6
+ * - execute() — calls the matching handler and returns
7
+ * { result, filePaths } where filePaths is
8
+ * the list of source files to highlight in
9
+ * the dependency graph.
10
+ *
11
+ * To add a future MCP tool: add one entry here pointing to any handler.
12
+ */
13
+ export interface ChatTool {
14
+ name: string;
15
+ description: string;
16
+ inputSchema: object;
17
+ execute(directory: string, args: Record<string, unknown>): Promise<{
18
+ result: unknown;
19
+ filePaths: string[];
20
+ }>;
21
+ }
22
+ export declare const CHAT_TOOLS: ChatTool[];
23
+ /** Convert CHAT_TOOLS to the OpenAI function-calling format. */
24
+ export declare function toChatToolDefinitions(): {
25
+ type: "function";
26
+ function: {
27
+ name: string;
28
+ description: string;
29
+ parameters: object;
30
+ };
31
+ }[];
32
+ //# sourceMappingURL=chat-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-tools.d.ts","sourceRoot":"","sources":["../../../src/core/services/chat-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAwBH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CACL,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACtD;AAmCD,eAAO,MAAM,UAAU,EAAE,QAAQ,EAqPhC,CAAC;AAMF,gEAAgE;AAChE,wBAAgB,qBAAqB;;;;;;;IASpC"}
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Tool registry for the diagram chatbot.
3
+ *
4
+ * Each entry in CHAT_TOOLS maps a tool name to:
5
+ * - description / inputSchema — forwarded to the LLM as tool definitions
6
+ * - execute() — calls the matching handler and returns
7
+ * { result, filePaths } where filePaths is
8
+ * the list of source files to highlight in
9
+ * the dependency graph.
10
+ *
11
+ * To add a future MCP tool: add one entry here pointing to any handler.
12
+ */
13
+ import { handleGetCallGraph, handleGetSubgraph, handleAnalyzeImpact, handleGetCriticalHubs, handleGetGodFunctions, } from './mcp-handlers/graph.js';
14
+ import { handleSearchCode, handleSuggestInsertionPoints, } from './mcp-handlers/semantic.js';
15
+ import { handleGetArchitectureOverview, handleGetRefactorReport, } from './mcp-handlers/analysis.js';
16
+ // ============================================================================
17
+ // HELPERS
18
+ // ============================================================================
19
+ /** Recursively extract file-path-looking values from tool results for highlighting. */
20
+ function extractFilePaths(obj) {
21
+ if (!obj || typeof obj !== 'object')
22
+ return [];
23
+ const paths = [];
24
+ const push = (v) => {
25
+ if (typeof v === 'string' && v.includes('/'))
26
+ paths.push(v);
27
+ };
28
+ const rec = (o) => {
29
+ if (!o || typeof o !== 'object')
30
+ return;
31
+ if (Array.isArray(o)) {
32
+ o.forEach(rec);
33
+ return;
34
+ }
35
+ const r = o;
36
+ for (const [k, v] of Object.entries(r)) {
37
+ if (k === 'file' || k === 'filePath' || k === 'callerFile' || k === 'calleeFile') {
38
+ push(v);
39
+ }
40
+ else if (typeof v === 'object') {
41
+ rec(v);
42
+ }
43
+ }
44
+ };
45
+ rec(obj);
46
+ return [...new Set(paths)];
47
+ }
48
+ // ============================================================================
49
+ // TOOL REGISTRY
50
+ // ============================================================================
51
+ export const CHAT_TOOLS = [
52
+ // ── Architecture overview ────────────────────────────────────────────────
53
+ {
54
+ name: 'get_architecture_overview',
55
+ description: 'Return a high-level architecture map: domain clusters, cross-cluster dependencies, ' +
56
+ 'global entry points, and critical hubs. Use this as the first call when the user asks ' +
57
+ 'about the project architecture or wants a broad overview.',
58
+ inputSchema: {
59
+ type: 'object',
60
+ properties: {
61
+ directory: { type: 'string', description: 'Absolute path to the project directory' },
62
+ },
63
+ required: ['directory'],
64
+ },
65
+ async execute(directory, args) {
66
+ const result = await handleGetArchitectureOverview(args.directory ?? directory);
67
+ const paths = [];
68
+ if (result && typeof result === 'object') {
69
+ const r = result;
70
+ for (const ep of r.globalEntryPoints ?? []) {
71
+ if (ep.file)
72
+ paths.push(ep.file);
73
+ }
74
+ for (const hub of r.criticalHubs ?? []) {
75
+ if (hub.file)
76
+ paths.push(hub.file);
77
+ }
78
+ }
79
+ return { result, filePaths: [...new Set(paths)] };
80
+ },
81
+ },
82
+ // ── Call graph ───────────────────────────────────────────────────────────
83
+ {
84
+ name: 'get_call_graph',
85
+ description: 'Return hub functions (high fan-in), entry points, and layer violations. ' +
86
+ 'Use this when the user asks about which functions are most critical or most called.',
87
+ inputSchema: {
88
+ type: 'object',
89
+ properties: {
90
+ directory: { type: 'string', description: 'Absolute path to the project directory' },
91
+ },
92
+ required: ['directory'],
93
+ },
94
+ async execute(directory, args) {
95
+ const result = await handleGetCallGraph(args.directory ?? directory);
96
+ return { result, filePaths: extractFilePaths(result) };
97
+ },
98
+ },
99
+ // ── Subgraph ─────────────────────────────────────────────────────────────
100
+ {
101
+ name: 'get_subgraph',
102
+ description: 'Extract the call subgraph around a function. Use this to show what a function calls ' +
103
+ '(downstream) or who calls it (upstream), or both.',
104
+ inputSchema: {
105
+ type: 'object',
106
+ properties: {
107
+ directory: { type: 'string', description: 'Absolute path to the project directory' },
108
+ functionName: { type: 'string', description: 'Function name (exact or partial match)' },
109
+ direction: {
110
+ type: 'string',
111
+ enum: ['downstream', 'upstream', 'both'],
112
+ description: 'Direction (default: downstream)',
113
+ },
114
+ maxDepth: { type: 'number', description: 'BFS depth limit (default: 3)' },
115
+ },
116
+ required: ['directory', 'functionName'],
117
+ },
118
+ async execute(directory, args) {
119
+ const result = await handleGetSubgraph(args.directory ?? directory, args.functionName, args.direction ?? 'downstream', args.maxDepth ?? 3, 'json');
120
+ return { result, filePaths: extractFilePaths(result) };
121
+ },
122
+ },
123
+ // ── Impact analysis ──────────────────────────────────────────────────────
124
+ {
125
+ name: 'analyze_impact',
126
+ description: 'Deep impact analysis for a function: fan-in, fan-out, blast radius, risk score, ' +
127
+ 'upstream/downstream chains. Use this when the user asks about the impact of changing ' +
128
+ 'or adding something.',
129
+ inputSchema: {
130
+ type: 'object',
131
+ properties: {
132
+ directory: { type: 'string', description: 'Absolute path to the project directory' },
133
+ symbol: { type: 'string', description: 'Function name to analyse (exact or partial)' },
134
+ depth: { type: 'number', description: 'Chain depth (default: 2)' },
135
+ },
136
+ required: ['directory', 'symbol'],
137
+ },
138
+ async execute(directory, args) {
139
+ const result = await handleAnalyzeImpact(args.directory ?? directory, args.symbol, args.depth ?? 2);
140
+ return { result, filePaths: extractFilePaths(result) };
141
+ },
142
+ },
143
+ // ── Critical hubs ────────────────────────────────────────────────────────
144
+ {
145
+ name: 'get_critical_hubs',
146
+ description: 'Return the most critical hub functions (high fan-in). Use this when the user asks ' +
147
+ 'about bottlenecks, central functions, or what to refactor.',
148
+ inputSchema: {
149
+ type: 'object',
150
+ properties: {
151
+ directory: { type: 'string', description: 'Absolute path to the project directory' },
152
+ limit: { type: 'number', description: 'Maximum hubs to return (default: 10)' },
153
+ minFanIn: { type: 'number', description: 'Minimum fan-in threshold (default: 3)' },
154
+ },
155
+ required: ['directory'],
156
+ },
157
+ async execute(directory, args) {
158
+ const result = await handleGetCriticalHubs(args.directory ?? directory, args.limit ?? 10, args.minFanIn ?? 3);
159
+ return { result, filePaths: extractFilePaths(result) };
160
+ },
161
+ },
162
+ // ── God functions ────────────────────────────────────────────────────────
163
+ {
164
+ name: 'get_god_functions',
165
+ description: 'Find god functions (high fan-out orchestrators). Use this when the user asks ' +
166
+ 'about complex or oversized functions that do too much.',
167
+ inputSchema: {
168
+ type: 'object',
169
+ properties: {
170
+ directory: { type: 'string', description: 'Absolute path to the project directory' },
171
+ filePath: { type: 'string', description: 'Optional: restrict to a specific file' },
172
+ fanOutThreshold: { type: 'number', description: 'Minimum fan-out (default: 8)' },
173
+ },
174
+ required: ['directory'],
175
+ },
176
+ async execute(directory, args) {
177
+ const result = await handleGetGodFunctions(args.directory ?? directory, args.filePath, args.fanOutThreshold ?? 8);
178
+ return { result, filePaths: extractFilePaths(result) };
179
+ },
180
+ },
181
+ // ── Suggest insertion points ─────────────────────────────────────────────
182
+ {
183
+ name: 'suggest_insertion_points',
184
+ description: 'Find the best places to implement a new feature using semantic + structural analysis. ' +
185
+ 'Use this when the user asks where to add a feature or how to integrate something new. ' +
186
+ 'Requires a vector index (spec-gen analyze --embed).',
187
+ inputSchema: {
188
+ type: 'object',
189
+ properties: {
190
+ directory: { type: 'string', description: 'Absolute path to the project directory' },
191
+ description: { type: 'string', description: 'Natural language description of the feature' },
192
+ limit: { type: 'number', description: 'Number of candidates (default: 5)' },
193
+ },
194
+ required: ['directory', 'description'],
195
+ },
196
+ async execute(directory, args) {
197
+ const result = await handleSuggestInsertionPoints(args.directory ?? directory, args.description, args.limit ?? 5);
198
+ const paths = [];
199
+ if (result && typeof result === 'object') {
200
+ const r = result;
201
+ for (const c of r.candidates ?? []) {
202
+ if (c.filePath)
203
+ paths.push(c.filePath);
204
+ }
205
+ }
206
+ return { result, filePaths: [...new Set(paths)] };
207
+ },
208
+ },
209
+ // ── Semantic code search ─────────────────────────────────────────────────
210
+ {
211
+ name: 'search_code',
212
+ description: 'Semantic search over the codebase to find functions by meaning. ' +
213
+ 'Use this when the user asks "where is X implemented?" or "which code handles Y?". ' +
214
+ 'Requires a vector index (spec-gen analyze --embed).',
215
+ inputSchema: {
216
+ type: 'object',
217
+ properties: {
218
+ directory: { type: 'string', description: 'Absolute path to the project directory' },
219
+ query: { type: 'string', description: 'Natural language search query' },
220
+ limit: { type: 'number', description: 'Results to return (default: 10)' },
221
+ },
222
+ required: ['directory', 'query'],
223
+ },
224
+ async execute(directory, args) {
225
+ const result = await handleSearchCode(args.directory ?? directory, args.query, args.limit ?? 10);
226
+ const paths = [];
227
+ if (result && typeof result === 'object') {
228
+ const r = result;
229
+ for (const res of r.results ?? []) {
230
+ if (res.filePath)
231
+ paths.push(res.filePath);
232
+ }
233
+ }
234
+ return { result, filePaths: [...new Set(paths)] };
235
+ },
236
+ },
237
+ // ── Refactor report ──────────────────────────────────────────────────────
238
+ {
239
+ name: 'get_refactor_report',
240
+ description: 'Return a prioritized refactor report: unreachable code, hub overload, god functions, ' +
241
+ 'SRP violations, cyclic dependencies. Use this when the user asks about code quality ' +
242
+ 'or what to improve.',
243
+ inputSchema: {
244
+ type: 'object',
245
+ properties: {
246
+ directory: { type: 'string', description: 'Absolute path to the project directory' },
247
+ },
248
+ required: ['directory'],
249
+ },
250
+ async execute(directory, args) {
251
+ const result = await handleGetRefactorReport(args.directory ?? directory);
252
+ return { result, filePaths: extractFilePaths(result) };
253
+ },
254
+ },
255
+ ];
256
+ // ============================================================================
257
+ // HELPERS
258
+ // ============================================================================
259
+ /** Convert CHAT_TOOLS to the OpenAI function-calling format. */
260
+ export function toChatToolDefinitions() {
261
+ return CHAT_TOOLS.map(t => ({
262
+ type: 'function',
263
+ function: {
264
+ name: t.name,
265
+ description: t.description,
266
+ parameters: t.inputSchema,
267
+ },
268
+ }));
269
+ }
270
+ //# sourceMappingURL=chat-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-tools.js","sourceRoot":"","sources":["../../../src/core/services/chat-tools.ts"],"names":[],"mappings":"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"}