@mcp-abap-adt/llm-agent-server 10.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 (566) hide show
  1. package/README.md +13 -0
  2. package/bin/llm-agent +2 -0
  3. package/bin/llm-agent-check +2 -0
  4. package/dist/agent.d.ts +49 -0
  5. package/dist/agent.d.ts.map +1 -0
  6. package/dist/agent.js +97 -0
  7. package/dist/agent.js.map +1 -0
  8. package/dist/agents/anthropic-agent.d.ts +33 -0
  9. package/dist/agents/anthropic-agent.d.ts.map +1 -0
  10. package/dist/agents/anthropic-agent.js +138 -0
  11. package/dist/agents/anthropic-agent.js.map +1 -0
  12. package/dist/agents/base.d.ts +90 -0
  13. package/dist/agents/base.d.ts.map +1 -0
  14. package/dist/agents/base.js +107 -0
  15. package/dist/agents/base.js.map +1 -0
  16. package/dist/agents/deepseek-agent.d.ts +31 -0
  17. package/dist/agents/deepseek-agent.d.ts.map +1 -0
  18. package/dist/agents/deepseek-agent.js +121 -0
  19. package/dist/agents/deepseek-agent.js.map +1 -0
  20. package/dist/agents/index.d.ts +10 -0
  21. package/dist/agents/index.d.ts.map +1 -0
  22. package/dist/agents/index.js +10 -0
  23. package/dist/agents/index.js.map +1 -0
  24. package/dist/agents/openai-agent.d.ts +32 -0
  25. package/dist/agents/openai-agent.d.ts.map +1 -0
  26. package/dist/agents/openai-agent.js +122 -0
  27. package/dist/agents/openai-agent.js.map +1 -0
  28. package/dist/agents/prompt-based-agent.d.ts +29 -0
  29. package/dist/agents/prompt-based-agent.d.ts.map +1 -0
  30. package/dist/agents/prompt-based-agent.js +67 -0
  31. package/dist/agents/prompt-based-agent.js.map +1 -0
  32. package/dist/agents/sap-core-ai-agent.d.ts +41 -0
  33. package/dist/agents/sap-core-ai-agent.d.ts.map +1 -0
  34. package/dist/agents/sap-core-ai-agent.js +151 -0
  35. package/dist/agents/sap-core-ai-agent.js.map +1 -0
  36. package/dist/cli.d.ts +53 -0
  37. package/dist/cli.d.ts.map +1 -0
  38. package/dist/cli.js +338 -0
  39. package/dist/cli.js.map +1 -0
  40. package/dist/generated/version.d.ts +2 -0
  41. package/dist/generated/version.d.ts.map +1 -0
  42. package/dist/generated/version.js +3 -0
  43. package/dist/generated/version.js.map +1 -0
  44. package/dist/index.d.ts +75 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +78 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/llm-providers/anthropic.d.ts +25 -0
  49. package/dist/llm-providers/anthropic.d.ts.map +1 -0
  50. package/dist/llm-providers/anthropic.js +202 -0
  51. package/dist/llm-providers/anthropic.js.map +1 -0
  52. package/dist/llm-providers/base.d.ts +33 -0
  53. package/dist/llm-providers/base.d.ts.map +1 -0
  54. package/dist/llm-providers/base.js +18 -0
  55. package/dist/llm-providers/base.js.map +1 -0
  56. package/dist/llm-providers/deepseek.d.ts +24 -0
  57. package/dist/llm-providers/deepseek.d.ts.map +1 -0
  58. package/dist/llm-providers/deepseek.js +60 -0
  59. package/dist/llm-providers/deepseek.js.map +1 -0
  60. package/dist/llm-providers/index.d.ts +13 -0
  61. package/dist/llm-providers/index.d.ts.map +1 -0
  62. package/dist/llm-providers/index.js +15 -0
  63. package/dist/llm-providers/index.js.map +1 -0
  64. package/dist/llm-providers/openai.d.ts +34 -0
  65. package/dist/llm-providers/openai.d.ts.map +1 -0
  66. package/dist/llm-providers/openai.js +193 -0
  67. package/dist/llm-providers/openai.js.map +1 -0
  68. package/dist/llm-providers/sap-core-ai.d.ts +90 -0
  69. package/dist/llm-providers/sap-core-ai.d.ts.map +1 -0
  70. package/dist/llm-providers/sap-core-ai.js +394 -0
  71. package/dist/llm-providers/sap-core-ai.js.map +1 -0
  72. package/dist/mcp/client.d.ts +133 -0
  73. package/dist/mcp/client.d.ts.map +1 -0
  74. package/dist/mcp/client.js +314 -0
  75. package/dist/mcp/client.js.map +1 -0
  76. package/dist/smart-agent/adapters/cline-client-adapter.d.ts +18 -0
  77. package/dist/smart-agent/adapters/cline-client-adapter.d.ts.map +1 -0
  78. package/dist/smart-agent/adapters/cline-client-adapter.js +21 -0
  79. package/dist/smart-agent/adapters/cline-client-adapter.js.map +1 -0
  80. package/dist/smart-agent/adapters/index.d.ts +3 -0
  81. package/dist/smart-agent/adapters/index.d.ts.map +1 -0
  82. package/dist/smart-agent/adapters/index.js +3 -0
  83. package/dist/smart-agent/adapters/index.js.map +1 -0
  84. package/dist/smart-agent/adapters/llm-adapter.d.ts +24 -0
  85. package/dist/smart-agent/adapters/llm-adapter.d.ts.map +1 -0
  86. package/dist/smart-agent/adapters/llm-adapter.js +345 -0
  87. package/dist/smart-agent/adapters/llm-adapter.js.map +1 -0
  88. package/dist/smart-agent/adapters/mcp-client-adapter.d.ts +16 -0
  89. package/dist/smart-agent/adapters/mcp-client-adapter.d.ts.map +1 -0
  90. package/dist/smart-agent/adapters/mcp-client-adapter.js +95 -0
  91. package/dist/smart-agent/adapters/mcp-client-adapter.js.map +1 -0
  92. package/dist/smart-agent/adapters/non-streaming-llm.d.ts +18 -0
  93. package/dist/smart-agent/adapters/non-streaming-llm.d.ts.map +1 -0
  94. package/dist/smart-agent/adapters/non-streaming-llm.js +44 -0
  95. package/dist/smart-agent/adapters/non-streaming-llm.js.map +1 -0
  96. package/dist/smart-agent/agent.d.ts +229 -0
  97. package/dist/smart-agent/agent.d.ts.map +1 -0
  98. package/dist/smart-agent/agent.js +1538 -0
  99. package/dist/smart-agent/agent.js.map +1 -0
  100. package/dist/smart-agent/api-adapters/anthropic-adapter.d.ts +10 -0
  101. package/dist/smart-agent/api-adapters/anthropic-adapter.d.ts.map +1 -0
  102. package/dist/smart-agent/api-adapters/anthropic-adapter.js +356 -0
  103. package/dist/smart-agent/api-adapters/anthropic-adapter.js.map +1 -0
  104. package/dist/smart-agent/api-adapters/index.d.ts +3 -0
  105. package/dist/smart-agent/api-adapters/index.d.ts.map +1 -0
  106. package/dist/smart-agent/api-adapters/index.js +3 -0
  107. package/dist/smart-agent/api-adapters/index.js.map +1 -0
  108. package/dist/smart-agent/api-adapters/openai-adapter.d.ts +10 -0
  109. package/dist/smart-agent/api-adapters/openai-adapter.d.ts.map +1 -0
  110. package/dist/smart-agent/api-adapters/openai-adapter.js +277 -0
  111. package/dist/smart-agent/api-adapters/openai-adapter.js.map +1 -0
  112. package/dist/smart-agent/builder.d.ts +281 -0
  113. package/dist/smart-agent/builder.d.ts.map +1 -0
  114. package/dist/smart-agent/builder.js +942 -0
  115. package/dist/smart-agent/builder.js.map +1 -0
  116. package/dist/smart-agent/cache/index.d.ts +4 -0
  117. package/dist/smart-agent/cache/index.d.ts.map +1 -0
  118. package/dist/smart-agent/cache/index.js +3 -0
  119. package/dist/smart-agent/cache/index.js.map +1 -0
  120. package/dist/smart-agent/cache/noop-tool-cache.d.ts +7 -0
  121. package/dist/smart-agent/cache/noop-tool-cache.d.ts.map +1 -0
  122. package/dist/smart-agent/cache/noop-tool-cache.js +8 -0
  123. package/dist/smart-agent/cache/noop-tool-cache.js.map +1 -0
  124. package/dist/smart-agent/cache/tool-cache.d.ts +14 -0
  125. package/dist/smart-agent/cache/tool-cache.d.ts.map +1 -0
  126. package/dist/smart-agent/cache/tool-cache.js +32 -0
  127. package/dist/smart-agent/cache/tool-cache.js.map +1 -0
  128. package/dist/smart-agent/cache/types.d.ts +7 -0
  129. package/dist/smart-agent/cache/types.d.ts.map +1 -0
  130. package/dist/smart-agent/cache/types.js +2 -0
  131. package/dist/smart-agent/cache/types.js.map +1 -0
  132. package/dist/smart-agent/check-models-cli.d.ts +14 -0
  133. package/dist/smart-agent/check-models-cli.d.ts.map +1 -0
  134. package/dist/smart-agent/check-models-cli.js +237 -0
  135. package/dist/smart-agent/check-models-cli.js.map +1 -0
  136. package/dist/smart-agent/classifier/index.d.ts +3 -0
  137. package/dist/smart-agent/classifier/index.d.ts.map +1 -0
  138. package/dist/smart-agent/classifier/index.js +2 -0
  139. package/dist/smart-agent/classifier/index.js.map +1 -0
  140. package/dist/smart-agent/classifier/llm-classifier.d.ts +20 -0
  141. package/dist/smart-agent/classifier/llm-classifier.d.ts.map +1 -0
  142. package/dist/smart-agent/classifier/llm-classifier.js +128 -0
  143. package/dist/smart-agent/classifier/llm-classifier.js.map +1 -0
  144. package/dist/smart-agent/cli.d.ts +65 -0
  145. package/dist/smart-agent/cli.d.ts.map +1 -0
  146. package/dist/smart-agent/cli.js +199 -0
  147. package/dist/smart-agent/cli.js.map +1 -0
  148. package/dist/smart-agent/config/config-watcher.d.ts +54 -0
  149. package/dist/smart-agent/config/config-watcher.d.ts.map +1 -0
  150. package/dist/smart-agent/config/config-watcher.js +107 -0
  151. package/dist/smart-agent/config/config-watcher.js.map +1 -0
  152. package/dist/smart-agent/config/index.d.ts +2 -0
  153. package/dist/smart-agent/config/index.d.ts.map +1 -0
  154. package/dist/smart-agent/config/index.js +2 -0
  155. package/dist/smart-agent/config/index.js.map +1 -0
  156. package/dist/smart-agent/config.d.ts +35 -0
  157. package/dist/smart-agent/config.d.ts.map +1 -0
  158. package/dist/smart-agent/config.js +360 -0
  159. package/dist/smart-agent/config.js.map +1 -0
  160. package/dist/smart-agent/context/context-assembler.d.ts +49 -0
  161. package/dist/smart-agent/context/context-assembler.d.ts.map +1 -0
  162. package/dist/smart-agent/context/context-assembler.js +184 -0
  163. package/dist/smart-agent/context/context-assembler.js.map +1 -0
  164. package/dist/smart-agent/context/index.d.ts +3 -0
  165. package/dist/smart-agent/context/index.d.ts.map +1 -0
  166. package/dist/smart-agent/context/index.js +2 -0
  167. package/dist/smart-agent/context/index.js.map +1 -0
  168. package/dist/smart-agent/health/health-checker.d.ts +21 -0
  169. package/dist/smart-agent/health/health-checker.d.ts.map +1 -0
  170. package/dist/smart-agent/health/health-checker.js +52 -0
  171. package/dist/smart-agent/health/health-checker.js.map +1 -0
  172. package/dist/smart-agent/health/index.d.ts +3 -0
  173. package/dist/smart-agent/health/index.d.ts.map +1 -0
  174. package/dist/smart-agent/health/index.js +2 -0
  175. package/dist/smart-agent/health/index.js.map +1 -0
  176. package/dist/smart-agent/health/types.d.ts +25 -0
  177. package/dist/smart-agent/health/types.d.ts.map +1 -0
  178. package/dist/smart-agent/health/types.js +2 -0
  179. package/dist/smart-agent/health/types.js.map +1 -0
  180. package/dist/smart-agent/history/history-memory.d.ts +12 -0
  181. package/dist/smart-agent/history/history-memory.d.ts.map +1 -0
  182. package/dist/smart-agent/history/history-memory.js +26 -0
  183. package/dist/smart-agent/history/history-memory.js.map +1 -0
  184. package/dist/smart-agent/history/history-summarizer.d.ts +10 -0
  185. package/dist/smart-agent/history/history-summarizer.d.ts.map +1 -0
  186. package/dist/smart-agent/history/history-summarizer.js +27 -0
  187. package/dist/smart-agent/history/history-summarizer.js.map +1 -0
  188. package/dist/smart-agent/history/index.d.ts +3 -0
  189. package/dist/smart-agent/history/index.d.ts.map +1 -0
  190. package/dist/smart-agent/history/index.js +3 -0
  191. package/dist/smart-agent/history/index.js.map +1 -0
  192. package/dist/smart-agent/interfaces/api-adapter.d.ts +36 -0
  193. package/dist/smart-agent/interfaces/api-adapter.d.ts.map +1 -0
  194. package/dist/smart-agent/interfaces/api-adapter.js +9 -0
  195. package/dist/smart-agent/interfaces/api-adapter.js.map +1 -0
  196. package/dist/smart-agent/interfaces/client-adapter.d.ts +23 -0
  197. package/dist/smart-agent/interfaces/client-adapter.d.ts.map +1 -0
  198. package/dist/smart-agent/interfaces/client-adapter.js +10 -0
  199. package/dist/smart-agent/interfaces/client-adapter.js.map +1 -0
  200. package/dist/smart-agent/interfaces/mcp-connection-strategy.d.ts +27 -0
  201. package/dist/smart-agent/interfaces/mcp-connection-strategy.d.ts.map +1 -0
  202. package/dist/smart-agent/interfaces/mcp-connection-strategy.js +2 -0
  203. package/dist/smart-agent/interfaces/mcp-connection-strategy.js.map +1 -0
  204. package/dist/smart-agent/interfaces/model-resolver.d.ts +9 -0
  205. package/dist/smart-agent/interfaces/model-resolver.d.ts.map +1 -0
  206. package/dist/smart-agent/interfaces/model-resolver.js +2 -0
  207. package/dist/smart-agent/interfaces/model-resolver.js.map +1 -0
  208. package/dist/smart-agent/interfaces/pipeline.d.ts +125 -0
  209. package/dist/smart-agent/interfaces/pipeline.d.ts.map +1 -0
  210. package/dist/smart-agent/interfaces/pipeline.js +13 -0
  211. package/dist/smart-agent/interfaces/pipeline.js.map +1 -0
  212. package/dist/smart-agent/logger/console-logger.d.ts +7 -0
  213. package/dist/smart-agent/logger/console-logger.d.ts.map +1 -0
  214. package/dist/smart-agent/logger/console-logger.js +12 -0
  215. package/dist/smart-agent/logger/console-logger.js.map +1 -0
  216. package/dist/smart-agent/logger/default-request-logger.d.ts +17 -0
  217. package/dist/smart-agent/logger/default-request-logger.d.ts.map +1 -0
  218. package/dist/smart-agent/logger/default-request-logger.js +86 -0
  219. package/dist/smart-agent/logger/default-request-logger.js.map +1 -0
  220. package/dist/smart-agent/logger/index.d.ts +3 -0
  221. package/dist/smart-agent/logger/index.d.ts.map +1 -0
  222. package/dist/smart-agent/logger/index.js +2 -0
  223. package/dist/smart-agent/logger/index.js.map +1 -0
  224. package/dist/smart-agent/logger/noop-request-logger.d.ts +11 -0
  225. package/dist/smart-agent/logger/noop-request-logger.d.ts.map +1 -0
  226. package/dist/smart-agent/logger/noop-request-logger.js +20 -0
  227. package/dist/smart-agent/logger/noop-request-logger.js.map +1 -0
  228. package/dist/smart-agent/logger/session-logger.d.ts +10 -0
  229. package/dist/smart-agent/logger/session-logger.d.ts.map +1 -0
  230. package/dist/smart-agent/logger/session-logger.js +40 -0
  231. package/dist/smart-agent/logger/session-logger.js.map +1 -0
  232. package/dist/smart-agent/logger/types.d.ts +63 -0
  233. package/dist/smart-agent/logger/types.d.ts.map +1 -0
  234. package/dist/smart-agent/logger/types.js +2 -0
  235. package/dist/smart-agent/logger/types.js.map +1 -0
  236. package/dist/smart-agent/mcp-client-factory.d.ts +3 -0
  237. package/dist/smart-agent/mcp-client-factory.d.ts.map +1 -0
  238. package/dist/smart-agent/mcp-client-factory.js +21 -0
  239. package/dist/smart-agent/mcp-client-factory.js.map +1 -0
  240. package/dist/smart-agent/metrics/in-memory-metrics.d.ts +58 -0
  241. package/dist/smart-agent/metrics/in-memory-metrics.d.ts.map +1 -0
  242. package/dist/smart-agent/metrics/in-memory-metrics.js +78 -0
  243. package/dist/smart-agent/metrics/in-memory-metrics.js.map +1 -0
  244. package/dist/smart-agent/metrics/index.d.ts +4 -0
  245. package/dist/smart-agent/metrics/index.d.ts.map +1 -0
  246. package/dist/smart-agent/metrics/index.js +3 -0
  247. package/dist/smart-agent/metrics/index.js.map +1 -0
  248. package/dist/smart-agent/metrics/noop-metrics.d.ts +17 -0
  249. package/dist/smart-agent/metrics/noop-metrics.d.ts.map +1 -0
  250. package/dist/smart-agent/metrics/noop-metrics.js +22 -0
  251. package/dist/smart-agent/metrics/noop-metrics.js.map +1 -0
  252. package/dist/smart-agent/metrics/types.d.ts +36 -0
  253. package/dist/smart-agent/metrics/types.d.ts.map +1 -0
  254. package/dist/smart-agent/metrics/types.js +9 -0
  255. package/dist/smart-agent/metrics/types.js.map +1 -0
  256. package/dist/smart-agent/otel/index.d.ts +2 -0
  257. package/dist/smart-agent/otel/index.d.ts.map +1 -0
  258. package/dist/smart-agent/otel/index.js +2 -0
  259. package/dist/smart-agent/otel/index.js.map +1 -0
  260. package/dist/smart-agent/otel/otel-tracer-adapter.d.ts +15 -0
  261. package/dist/smart-agent/otel/otel-tracer-adapter.d.ts.map +1 -0
  262. package/dist/smart-agent/otel/otel-tracer-adapter.js +62 -0
  263. package/dist/smart-agent/otel/otel-tracer-adapter.js.map +1 -0
  264. package/dist/smart-agent/pipeline/condition-evaluator.d.ts +35 -0
  265. package/dist/smart-agent/pipeline/condition-evaluator.d.ts.map +1 -0
  266. package/dist/smart-agent/pipeline/condition-evaluator.js +143 -0
  267. package/dist/smart-agent/pipeline/condition-evaluator.js.map +1 -0
  268. package/dist/smart-agent/pipeline/context.d.ts +121 -0
  269. package/dist/smart-agent/pipeline/context.d.ts.map +1 -0
  270. package/dist/smart-agent/pipeline/context.js +19 -0
  271. package/dist/smart-agent/pipeline/context.js.map +1 -0
  272. package/dist/smart-agent/pipeline/default-pipeline.d.ts +69 -0
  273. package/dist/smart-agent/pipeline/default-pipeline.d.ts.map +1 -0
  274. package/dist/smart-agent/pipeline/default-pipeline.js +278 -0
  275. package/dist/smart-agent/pipeline/default-pipeline.js.map +1 -0
  276. package/dist/smart-agent/pipeline/executor.d.ts +54 -0
  277. package/dist/smart-agent/pipeline/executor.d.ts.map +1 -0
  278. package/dist/smart-agent/pipeline/executor.js +133 -0
  279. package/dist/smart-agent/pipeline/executor.js.map +1 -0
  280. package/dist/smart-agent/pipeline/handlers/assemble.d.ts +16 -0
  281. package/dist/smart-agent/pipeline/handlers/assemble.d.ts.map +1 -0
  282. package/dist/smart-agent/pipeline/handlers/assemble.js +72 -0
  283. package/dist/smart-agent/pipeline/handlers/assemble.js.map +1 -0
  284. package/dist/smart-agent/pipeline/handlers/build-tool-query.d.ts +30 -0
  285. package/dist/smart-agent/pipeline/handlers/build-tool-query.d.ts.map +1 -0
  286. package/dist/smart-agent/pipeline/handlers/build-tool-query.js +80 -0
  287. package/dist/smart-agent/pipeline/handlers/build-tool-query.js.map +1 -0
  288. package/dist/smart-agent/pipeline/handlers/classify.d.ts +21 -0
  289. package/dist/smart-agent/pipeline/handlers/classify.d.ts.map +1 -0
  290. package/dist/smart-agent/pipeline/handlers/classify.js +60 -0
  291. package/dist/smart-agent/pipeline/handlers/classify.js.map +1 -0
  292. package/dist/smart-agent/pipeline/handlers/expand.d.ts +16 -0
  293. package/dist/smart-agent/pipeline/handlers/expand.d.ts.map +1 -0
  294. package/dist/smart-agent/pipeline/handlers/expand.js +24 -0
  295. package/dist/smart-agent/pipeline/handlers/expand.js.map +1 -0
  296. package/dist/smart-agent/pipeline/handlers/history-upsert.d.ts +29 -0
  297. package/dist/smart-agent/pipeline/handlers/history-upsert.d.ts.map +1 -0
  298. package/dist/smart-agent/pipeline/handlers/history-upsert.js +75 -0
  299. package/dist/smart-agent/pipeline/handlers/history-upsert.js.map +1 -0
  300. package/dist/smart-agent/pipeline/handlers/index.d.ts +31 -0
  301. package/dist/smart-agent/pipeline/handlers/index.d.ts.map +1 -0
  302. package/dist/smart-agent/pipeline/handlers/index.js +44 -0
  303. package/dist/smart-agent/pipeline/handlers/index.js.map +1 -0
  304. package/dist/smart-agent/pipeline/handlers/rag-query.d.ts +27 -0
  305. package/dist/smart-agent/pipeline/handlers/rag-query.d.ts.map +1 -0
  306. package/dist/smart-agent/pipeline/handlers/rag-query.js +117 -0
  307. package/dist/smart-agent/pipeline/handlers/rag-query.js.map +1 -0
  308. package/dist/smart-agent/pipeline/handlers/rerank.d.ts +16 -0
  309. package/dist/smart-agent/pipeline/handlers/rerank.d.ts.map +1 -0
  310. package/dist/smart-agent/pipeline/handlers/rerank.js +27 -0
  311. package/dist/smart-agent/pipeline/handlers/rerank.js.map +1 -0
  312. package/dist/smart-agent/pipeline/handlers/skill-select.d.ts +18 -0
  313. package/dist/smart-agent/pipeline/handlers/skill-select.d.ts.map +1 -0
  314. package/dist/smart-agent/pipeline/handlers/skill-select.js +88 -0
  315. package/dist/smart-agent/pipeline/handlers/skill-select.js.map +1 -0
  316. package/dist/smart-agent/pipeline/handlers/summarize.d.ts +17 -0
  317. package/dist/smart-agent/pipeline/handlers/summarize.d.ts.map +1 -0
  318. package/dist/smart-agent/pipeline/handlers/summarize.js +56 -0
  319. package/dist/smart-agent/pipeline/handlers/summarize.js.map +1 -0
  320. package/dist/smart-agent/pipeline/handlers/tool-loop.d.ts +32 -0
  321. package/dist/smart-agent/pipeline/handlers/tool-loop.d.ts.map +1 -0
  322. package/dist/smart-agent/pipeline/handlers/tool-loop.js +734 -0
  323. package/dist/smart-agent/pipeline/handlers/tool-loop.js.map +1 -0
  324. package/dist/smart-agent/pipeline/handlers/tool-select.d.ts +21 -0
  325. package/dist/smart-agent/pipeline/handlers/tool-select.d.ts.map +1 -0
  326. package/dist/smart-agent/pipeline/handlers/tool-select.js +109 -0
  327. package/dist/smart-agent/pipeline/handlers/tool-select.js.map +1 -0
  328. package/dist/smart-agent/pipeline/handlers/translate.d.ts +17 -0
  329. package/dist/smart-agent/pipeline/handlers/translate.d.ts.map +1 -0
  330. package/dist/smart-agent/pipeline/handlers/translate.js +42 -0
  331. package/dist/smart-agent/pipeline/handlers/translate.js.map +1 -0
  332. package/dist/smart-agent/pipeline/index.d.ts +14 -0
  333. package/dist/smart-agent/pipeline/index.d.ts.map +1 -0
  334. package/dist/smart-agent/pipeline/index.js +16 -0
  335. package/dist/smart-agent/pipeline/index.js.map +1 -0
  336. package/dist/smart-agent/pipeline/stage-handler.d.ts +36 -0
  337. package/dist/smart-agent/pipeline/stage-handler.d.ts.map +1 -0
  338. package/dist/smart-agent/pipeline/stage-handler.js +24 -0
  339. package/dist/smart-agent/pipeline/stage-handler.js.map +1 -0
  340. package/dist/smart-agent/pipeline/types.d.ts +116 -0
  341. package/dist/smart-agent/pipeline/types.d.ts.map +1 -0
  342. package/dist/smart-agent/pipeline/types.js +54 -0
  343. package/dist/smart-agent/pipeline/types.js.map +1 -0
  344. package/dist/smart-agent/pipeline.d.ts +82 -0
  345. package/dist/smart-agent/pipeline.d.ts.map +1 -0
  346. package/dist/smart-agent/pipeline.js +8 -0
  347. package/dist/smart-agent/pipeline.js.map +1 -0
  348. package/dist/smart-agent/plugins/index.d.ts +4 -0
  349. package/dist/smart-agent/plugins/index.d.ts.map +1 -0
  350. package/dist/smart-agent/plugins/index.js +3 -0
  351. package/dist/smart-agent/plugins/index.js.map +1 -0
  352. package/dist/smart-agent/plugins/loader.d.ts +67 -0
  353. package/dist/smart-agent/plugins/loader.d.ts.map +1 -0
  354. package/dist/smart-agent/plugins/loader.js +114 -0
  355. package/dist/smart-agent/plugins/loader.js.map +1 -0
  356. package/dist/smart-agent/plugins/types.d.ts +164 -0
  357. package/dist/smart-agent/plugins/types.d.ts.map +1 -0
  358. package/dist/smart-agent/plugins/types.js +136 -0
  359. package/dist/smart-agent/plugins/types.js.map +1 -0
  360. package/dist/smart-agent/policy/fallback-llm-call-strategy.d.ts +16 -0
  361. package/dist/smart-agent/policy/fallback-llm-call-strategy.d.ts.map +1 -0
  362. package/dist/smart-agent/policy/fallback-llm-call-strategy.js +66 -0
  363. package/dist/smart-agent/policy/fallback-llm-call-strategy.js.map +1 -0
  364. package/dist/smart-agent/policy/heuristic-injection-detector.d.ts +5 -0
  365. package/dist/smart-agent/policy/heuristic-injection-detector.d.ts.map +1 -0
  366. package/dist/smart-agent/policy/heuristic-injection-detector.js +36 -0
  367. package/dist/smart-agent/policy/heuristic-injection-detector.js.map +1 -0
  368. package/dist/smart-agent/policy/index.d.ts +6 -0
  369. package/dist/smart-agent/policy/index.d.ts.map +1 -0
  370. package/dist/smart-agent/policy/index.js +5 -0
  371. package/dist/smart-agent/policy/index.js.map +1 -0
  372. package/dist/smart-agent/policy/mixed-tool-call-handler.d.ts +16 -0
  373. package/dist/smart-agent/policy/mixed-tool-call-handler.d.ts.map +1 -0
  374. package/dist/smart-agent/policy/mixed-tool-call-handler.js +49 -0
  375. package/dist/smart-agent/policy/mixed-tool-call-handler.js.map +1 -0
  376. package/dist/smart-agent/policy/non-streaming-llm-call-strategy.d.ts +6 -0
  377. package/dist/smart-agent/policy/non-streaming-llm-call-strategy.d.ts.map +1 -0
  378. package/dist/smart-agent/policy/non-streaming-llm-call-strategy.js +21 -0
  379. package/dist/smart-agent/policy/non-streaming-llm-call-strategy.js.map +1 -0
  380. package/dist/smart-agent/policy/pending-tool-results-registry.d.ts +25 -0
  381. package/dist/smart-agent/policy/pending-tool-results-registry.d.ts.map +1 -0
  382. package/dist/smart-agent/policy/pending-tool-results-registry.js +50 -0
  383. package/dist/smart-agent/policy/pending-tool-results-registry.js.map +1 -0
  384. package/dist/smart-agent/policy/streaming-llm-call-strategy.d.ts +6 -0
  385. package/dist/smart-agent/policy/streaming-llm-call-strategy.d.ts.map +1 -0
  386. package/dist/smart-agent/policy/streaming-llm-call-strategy.js +7 -0
  387. package/dist/smart-agent/policy/streaming-llm-call-strategy.js.map +1 -0
  388. package/dist/smart-agent/policy/tool-availability-registry.d.ts +21 -0
  389. package/dist/smart-agent/policy/tool-availability-registry.d.ts.map +1 -0
  390. package/dist/smart-agent/policy/tool-availability-registry.js +77 -0
  391. package/dist/smart-agent/policy/tool-availability-registry.js.map +1 -0
  392. package/dist/smart-agent/policy/tool-policy-guard.d.ts +8 -0
  393. package/dist/smart-agent/policy/tool-policy-guard.d.ts.map +1 -0
  394. package/dist/smart-agent/policy/tool-policy-guard.js +40 -0
  395. package/dist/smart-agent/policy/tool-policy-guard.js.map +1 -0
  396. package/dist/smart-agent/policy/types.d.ts +51 -0
  397. package/dist/smart-agent/policy/types.d.ts.map +1 -0
  398. package/dist/smart-agent/policy/types.js +17 -0
  399. package/dist/smart-agent/policy/types.js.map +1 -0
  400. package/dist/smart-agent/providers.d.ts +98 -0
  401. package/dist/smart-agent/providers.d.ts.map +1 -0
  402. package/dist/smart-agent/providers.js +245 -0
  403. package/dist/smart-agent/providers.js.map +1 -0
  404. package/dist/smart-agent/reranker/index.d.ts +4 -0
  405. package/dist/smart-agent/reranker/index.d.ts.map +1 -0
  406. package/dist/smart-agent/reranker/index.js +3 -0
  407. package/dist/smart-agent/reranker/index.js.map +1 -0
  408. package/dist/smart-agent/reranker/llm-reranker.d.ts +10 -0
  409. package/dist/smart-agent/reranker/llm-reranker.d.ts.map +1 -0
  410. package/dist/smart-agent/reranker/llm-reranker.js +55 -0
  411. package/dist/smart-agent/reranker/llm-reranker.js.map +1 -0
  412. package/dist/smart-agent/reranker/noop-reranker.d.ts +6 -0
  413. package/dist/smart-agent/reranker/noop-reranker.d.ts.map +1 -0
  414. package/dist/smart-agent/reranker/noop-reranker.js +6 -0
  415. package/dist/smart-agent/reranker/noop-reranker.js.map +1 -0
  416. package/dist/smart-agent/reranker/types.d.ts +5 -0
  417. package/dist/smart-agent/reranker/types.d.ts.map +1 -0
  418. package/dist/smart-agent/reranker/types.js +2 -0
  419. package/dist/smart-agent/reranker/types.js.map +1 -0
  420. package/dist/smart-agent/resilience/circuit-breaker-embedder.d.ts +16 -0
  421. package/dist/smart-agent/resilience/circuit-breaker-embedder.d.ts.map +1 -0
  422. package/dist/smart-agent/resilience/circuit-breaker-embedder.js +47 -0
  423. package/dist/smart-agent/resilience/circuit-breaker-embedder.js.map +1 -0
  424. package/dist/smart-agent/resilience/circuit-breaker-llm.d.ts +19 -0
  425. package/dist/smart-agent/resilience/circuit-breaker-llm.d.ts.map +1 -0
  426. package/dist/smart-agent/resilience/circuit-breaker-llm.js +72 -0
  427. package/dist/smart-agent/resilience/circuit-breaker-llm.js.map +1 -0
  428. package/dist/smart-agent/resilience/circuit-breaker.d.ts +36 -0
  429. package/dist/smart-agent/resilience/circuit-breaker.d.ts.map +1 -0
  430. package/dist/smart-agent/resilience/circuit-breaker.js +60 -0
  431. package/dist/smart-agent/resilience/circuit-breaker.js.map +1 -0
  432. package/dist/smart-agent/resilience/fallback-rag.d.ts +21 -0
  433. package/dist/smart-agent/resilience/fallback-rag.d.ts.map +1 -0
  434. package/dist/smart-agent/resilience/fallback-rag.js +80 -0
  435. package/dist/smart-agent/resilience/fallback-rag.js.map +1 -0
  436. package/dist/smart-agent/resilience/index.d.ts +5 -0
  437. package/dist/smart-agent/resilience/index.d.ts.map +1 -0
  438. package/dist/smart-agent/resilience/index.js +5 -0
  439. package/dist/smart-agent/resilience/index.js.map +1 -0
  440. package/dist/smart-agent/resilience/rate-limiter-llm.d.ts +17 -0
  441. package/dist/smart-agent/resilience/rate-limiter-llm.d.ts.map +1 -0
  442. package/dist/smart-agent/resilience/rate-limiter-llm.js +30 -0
  443. package/dist/smart-agent/resilience/rate-limiter-llm.js.map +1 -0
  444. package/dist/smart-agent/resilience/retry-llm.d.ts +32 -0
  445. package/dist/smart-agent/resilience/retry-llm.d.ts.map +1 -0
  446. package/dist/smart-agent/resilience/retry-llm.js +103 -0
  447. package/dist/smart-agent/resilience/retry-llm.js.map +1 -0
  448. package/dist/smart-agent/resilience/token-bucket-rate-limiter.d.ts +21 -0
  449. package/dist/smart-agent/resilience/token-bucket-rate-limiter.d.ts.map +1 -0
  450. package/dist/smart-agent/resilience/token-bucket-rate-limiter.js +32 -0
  451. package/dist/smart-agent/resilience/token-bucket-rate-limiter.js.map +1 -0
  452. package/dist/smart-agent/server.d.ts +19 -0
  453. package/dist/smart-agent/server.d.ts.map +1 -0
  454. package/dist/smart-agent/server.js +349 -0
  455. package/dist/smart-agent/server.js.map +1 -0
  456. package/dist/smart-agent/session/index.d.ts +4 -0
  457. package/dist/smart-agent/session/index.d.ts.map +1 -0
  458. package/dist/smart-agent/session/index.js +3 -0
  459. package/dist/smart-agent/session/index.js.map +1 -0
  460. package/dist/smart-agent/session/noop-session-manager.d.ts +8 -0
  461. package/dist/smart-agent/session/noop-session-manager.d.ts.map +1 -0
  462. package/dist/smart-agent/session/noop-session-manager.js +11 -0
  463. package/dist/smart-agent/session/noop-session-manager.js.map +1 -0
  464. package/dist/smart-agent/session/session-manager.d.ts +13 -0
  465. package/dist/smart-agent/session/session-manager.d.ts.map +1 -0
  466. package/dist/smart-agent/session/session-manager.js +20 -0
  467. package/dist/smart-agent/session/session-manager.js.map +1 -0
  468. package/dist/smart-agent/session/types.d.ts +7 -0
  469. package/dist/smart-agent/session/types.d.ts.map +1 -0
  470. package/dist/smart-agent/session/types.js +2 -0
  471. package/dist/smart-agent/session/types.js.map +1 -0
  472. package/dist/smart-agent/skills/claude-skill-manager.d.ts +24 -0
  473. package/dist/smart-agent/skills/claude-skill-manager.d.ts.map +1 -0
  474. package/dist/smart-agent/skills/claude-skill-manager.js +81 -0
  475. package/dist/smart-agent/skills/claude-skill-manager.js.map +1 -0
  476. package/dist/smart-agent/skills/codex-skill-manager.d.ts +20 -0
  477. package/dist/smart-agent/skills/codex-skill-manager.d.ts.map +1 -0
  478. package/dist/smart-agent/skills/codex-skill-manager.js +75 -0
  479. package/dist/smart-agent/skills/codex-skill-manager.js.map +1 -0
  480. package/dist/smart-agent/skills/filesystem-skill-manager.d.ts +17 -0
  481. package/dist/smart-agent/skills/filesystem-skill-manager.d.ts.map +1 -0
  482. package/dist/smart-agent/skills/filesystem-skill-manager.js +48 -0
  483. package/dist/smart-agent/skills/filesystem-skill-manager.js.map +1 -0
  484. package/dist/smart-agent/skills/filesystem-skill.d.ts +25 -0
  485. package/dist/smart-agent/skills/filesystem-skill.d.ts.map +1 -0
  486. package/dist/smart-agent/skills/filesystem-skill.js +110 -0
  487. package/dist/smart-agent/skills/filesystem-skill.js.map +1 -0
  488. package/dist/smart-agent/skills/index.d.ts +9 -0
  489. package/dist/smart-agent/skills/index.d.ts.map +1 -0
  490. package/dist/smart-agent/skills/index.js +9 -0
  491. package/dist/smart-agent/skills/index.js.map +1 -0
  492. package/dist/smart-agent/skills/skill-utils.d.ts +15 -0
  493. package/dist/smart-agent/skills/skill-utils.d.ts.map +1 -0
  494. package/dist/smart-agent/skills/skill-utils.js +46 -0
  495. package/dist/smart-agent/skills/skill-utils.js.map +1 -0
  496. package/dist/smart-agent/smart-server.d.ts +150 -0
  497. package/dist/smart-agent/smart-server.d.ts.map +1 -0
  498. package/dist/smart-agent/smart-server.js +903 -0
  499. package/dist/smart-agent/smart-server.js.map +1 -0
  500. package/dist/smart-agent/strategies/index.d.ts +4 -0
  501. package/dist/smart-agent/strategies/index.d.ts.map +1 -0
  502. package/dist/smart-agent/strategies/index.js +4 -0
  503. package/dist/smart-agent/strategies/index.js.map +1 -0
  504. package/dist/smart-agent/strategies/lazy-connection-strategy.d.ts +15 -0
  505. package/dist/smart-agent/strategies/lazy-connection-strategy.d.ts.map +1 -0
  506. package/dist/smart-agent/strategies/lazy-connection-strategy.js +82 -0
  507. package/dist/smart-agent/strategies/lazy-connection-strategy.js.map +1 -0
  508. package/dist/smart-agent/strategies/noop-connection-strategy.d.ts +6 -0
  509. package/dist/smart-agent/strategies/noop-connection-strategy.d.ts.map +1 -0
  510. package/dist/smart-agent/strategies/noop-connection-strategy.js +6 -0
  511. package/dist/smart-agent/strategies/noop-connection-strategy.js.map +1 -0
  512. package/dist/smart-agent/strategies/periodic-connection-strategy.d.ts +13 -0
  513. package/dist/smart-agent/strategies/periodic-connection-strategy.d.ts.map +1 -0
  514. package/dist/smart-agent/strategies/periodic-connection-strategy.js +40 -0
  515. package/dist/smart-agent/strategies/periodic-connection-strategy.js.map +1 -0
  516. package/dist/smart-agent/testing/index.d.ts +121 -0
  517. package/dist/smart-agent/testing/index.d.ts.map +1 -0
  518. package/dist/smart-agent/testing/index.js +354 -0
  519. package/dist/smart-agent/testing/index.js.map +1 -0
  520. package/dist/smart-agent/tracer/index.d.ts +3 -0
  521. package/dist/smart-agent/tracer/index.d.ts.map +1 -0
  522. package/dist/smart-agent/tracer/index.js +2 -0
  523. package/dist/smart-agent/tracer/index.js.map +1 -0
  524. package/dist/smart-agent/tracer/noop-tracer.d.ts +5 -0
  525. package/dist/smart-agent/tracer/noop-tracer.d.ts.map +1 -0
  526. package/dist/smart-agent/tracer/noop-tracer.js +16 -0
  527. package/dist/smart-agent/tracer/noop-tracer.js.map +1 -0
  528. package/dist/smart-agent/tracer/types.d.ts +17 -0
  529. package/dist/smart-agent/tracer/types.d.ts.map +1 -0
  530. package/dist/smart-agent/tracer/types.js +2 -0
  531. package/dist/smart-agent/tracer/types.js.map +1 -0
  532. package/dist/smart-agent/utils/external-tools-normalizer.d.ts +15 -0
  533. package/dist/smart-agent/utils/external-tools-normalizer.d.ts.map +1 -0
  534. package/dist/smart-agent/utils/external-tools-normalizer.js +146 -0
  535. package/dist/smart-agent/utils/external-tools-normalizer.js.map +1 -0
  536. package/dist/smart-agent/utils/lazy.d.ts +51 -0
  537. package/dist/smart-agent/utils/lazy.d.ts.map +1 -0
  538. package/dist/smart-agent/utils/lazy.js +127 -0
  539. package/dist/smart-agent/utils/lazy.js.map +1 -0
  540. package/dist/smart-agent/utils/parse-frontmatter.d.ts +15 -0
  541. package/dist/smart-agent/utils/parse-frontmatter.d.ts.map +1 -0
  542. package/dist/smart-agent/utils/parse-frontmatter.js +22 -0
  543. package/dist/smart-agent/utils/parse-frontmatter.js.map +1 -0
  544. package/dist/smart-agent/utils/tool-call-deltas.d.ts +4 -0
  545. package/dist/smart-agent/utils/tool-call-deltas.d.ts.map +1 -0
  546. package/dist/smart-agent/utils/tool-call-deltas.js +25 -0
  547. package/dist/smart-agent/utils/tool-call-deltas.js.map +1 -0
  548. package/dist/smart-agent/validator/index.d.ts +3 -0
  549. package/dist/smart-agent/validator/index.d.ts.map +1 -0
  550. package/dist/smart-agent/validator/index.js +2 -0
  551. package/dist/smart-agent/validator/index.js.map +1 -0
  552. package/dist/smart-agent/validator/noop-validator.d.ts +6 -0
  553. package/dist/smart-agent/validator/noop-validator.d.ts.map +1 -0
  554. package/dist/smart-agent/validator/noop-validator.js +6 -0
  555. package/dist/smart-agent/validator/noop-validator.js.map +1 -0
  556. package/dist/smart-agent/validator/types.d.ts +17 -0
  557. package/dist/smart-agent/validator/types.d.ts.map +1 -0
  558. package/dist/smart-agent/validator/types.js +8 -0
  559. package/dist/smart-agent/validator/types.js.map +1 -0
  560. package/dist/smoke-adapters.d.ts +17 -0
  561. package/dist/smoke-adapters.d.ts.map +1 -0
  562. package/dist/smoke-adapters.js +178 -0
  563. package/dist/smoke-adapters.js.map +1 -0
  564. package/package.json +89 -0
  565. package/tools/claude-via-agent.ps1 +83 -0
  566. package/tools/claude-via-agent.sh +96 -0
@@ -0,0 +1,903 @@
1
+ /**
2
+ * SmartServer — embeddable OpenAI-compatible HTTP server backed by SmartAgent.
3
+ */
4
+ import { randomUUID } from 'node:crypto';
5
+ import http from 'node:http';
6
+ import { PACKAGE_VERSION } from '../generated/version.js';
7
+ import { SmartAgentBuilder } from './builder.js';
8
+ import { ConfigWatcher, } from './config/config-watcher.js';
9
+ import { HealthChecker } from './health/health-checker.js';
10
+ import { AdapterValidationError } from './interfaces/api-adapter.js';
11
+ import { SessionLogger } from './logger/session-logger.js';
12
+ import { FileSystemPluginLoader, getDefaultPluginDirs, } from './plugins/index.js';
13
+ import { makeDefaultLlm, makeLlm, makeRag } from './providers.js';
14
+ import { ClaudeSkillManager } from './skills/claude-skill-manager.js';
15
+ import { CodexSkillManager } from './skills/codex-skill-manager.js';
16
+ import { FileSystemSkillManager } from './skills/filesystem-skill-manager.js';
17
+ import { normalizeAndValidateExternalTools, } from './utils/external-tools-normalizer.js';
18
+ import { toToolCallDelta } from './utils/tool-call-deltas.js';
19
+ // ---------------------------------------------------------------------------
20
+ // Helpers
21
+ // ---------------------------------------------------------------------------
22
+ function mapStopReason(r) {
23
+ if (r === 'stop')
24
+ return 'stop';
25
+ if (r === 'tool_calls')
26
+ return 'tool_calls';
27
+ return 'length';
28
+ }
29
+ function jsonError(message, type, code) {
30
+ return JSON.stringify({
31
+ error: { message, type, ...(code ? { code } : {}) },
32
+ });
33
+ }
34
+ function jsonValidationError(message, code, param) {
35
+ return JSON.stringify({
36
+ error: {
37
+ message,
38
+ type: 'invalid_request_error',
39
+ code,
40
+ param,
41
+ },
42
+ });
43
+ }
44
+ function readBody(req) {
45
+ return new Promise((resolve, reject) => {
46
+ const chunks = [];
47
+ req.on('data', (c) => chunks.push(c));
48
+ req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
49
+ req.on('error', reject);
50
+ });
51
+ }
52
+ function resolveSkillManager(cfg) {
53
+ if (!cfg)
54
+ return undefined;
55
+ const type = cfg.type ?? 'claude';
56
+ const root = cfg.projectRoot ?? process.cwd();
57
+ switch (type) {
58
+ case 'claude':
59
+ return new ClaudeSkillManager(root);
60
+ case 'codex':
61
+ return new CodexSkillManager(root);
62
+ case 'filesystem':
63
+ return new FileSystemSkillManager(cfg.dirs ?? []);
64
+ default:
65
+ return undefined;
66
+ }
67
+ }
68
+ const CORS_HEADERS = {
69
+ 'Access-Control-Allow-Origin': '*',
70
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, OPTIONS',
71
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
72
+ };
73
+ // ---------------------------------------------------------------------------
74
+ // SmartServer
75
+ // ---------------------------------------------------------------------------
76
+ export { generateConfigTemplate, loadYamlConfig, resolveEnvVars, resolveSmartServerConfig, YAML_TEMPLATE, } from './config.js';
77
+ export class SmartServer {
78
+ cfg;
79
+ noop = () => { };
80
+ constructor(config) {
81
+ this.cfg = config;
82
+ }
83
+ async start() {
84
+ const log = this.cfg.log ?? this.noop;
85
+ const fileLogger = {
86
+ log: (e) => log(e),
87
+ };
88
+ const pipeline = this.cfg.pipeline;
89
+ // ---- Composition root: resolve config → interfaces --------------------
90
+ // LLM resolution
91
+ const mainTemp = Number(pipeline?.llm?.main?.temperature ?? this.cfg.llm.temperature ?? 0.7);
92
+ const mainLlm = pipeline?.llm?.main
93
+ ? makeLlm(pipeline.llm.main, mainTemp)
94
+ : makeDefaultLlm(this.cfg.llm.apiKey, this.cfg.llm.model ?? 'deepseek-chat', mainTemp);
95
+ const classifierTemp = Number(pipeline?.llm?.classifier?.temperature ??
96
+ this.cfg.llm.classifierTemperature ??
97
+ 0.1);
98
+ const classifierLlm = pipeline?.llm?.classifier
99
+ ? makeLlm(pipeline.llm.classifier, classifierTemp)
100
+ : pipeline?.llm?.main
101
+ ? makeLlm(pipeline.llm.main, classifierTemp)
102
+ : makeDefaultLlm(this.cfg.llm.apiKey, this.cfg.llm.model ?? 'deepseek-chat', classifierTemp);
103
+ const helperLlm = pipeline?.llm?.helper
104
+ ? makeLlm(pipeline.llm.helper, Number(pipeline.llm.helper.temperature ?? 0.1))
105
+ : undefined;
106
+ // ---- Plugin loader -------------------------------------------------------
107
+ const pluginLoader = this.cfg.pluginLoader ??
108
+ (() => {
109
+ const dirs = getDefaultPluginDirs();
110
+ if (this.cfg.pluginDir)
111
+ dirs.push(this.cfg.pluginDir);
112
+ return new FileSystemPluginLoader({
113
+ dirs,
114
+ log: (msg) => log({ event: 'plugin_loader', message: msg }),
115
+ });
116
+ })();
117
+ // Pre-load to extract embedder factories (needed before RAG resolution)
118
+ const plugins = await pluginLoader.load();
119
+ if (plugins.loadedFiles.length > 0) {
120
+ log({
121
+ event: 'plugins_loaded',
122
+ files: plugins.loadedFiles,
123
+ stageHandlers: [...plugins.stageHandlers.keys()],
124
+ embedderFactories: Object.keys(plugins.embedderFactories),
125
+ hasReranker: !!plugins.reranker,
126
+ hasQueryExpander: !!plugins.queryExpander,
127
+ hasOutputValidator: !!plugins.outputValidator,
128
+ mcpClients: plugins.mcpClients.length,
129
+ });
130
+ }
131
+ if (plugins.errors.length > 0) {
132
+ log({ event: 'plugin_errors', errors: plugins.errors });
133
+ }
134
+ // Merge plugin embedder factories with config-provided ones
135
+ const mergedEmbedderFactories = {
136
+ ...plugins.embedderFactories,
137
+ ...this.cfg.embedderFactories, // config takes precedence over plugins
138
+ };
139
+ // ---- Build agent via Builder (interface-only) -------------------------
140
+ let builder = new SmartAgentBuilder({
141
+ mcp: pipeline?.mcp ?? this.cfg.mcp,
142
+ agent: this.cfg.agent,
143
+ prompts: this.cfg.prompts,
144
+ skipModelValidation: this.cfg.skipModelValidation,
145
+ })
146
+ .withMainLlm(mainLlm)
147
+ .withClassifierLlm(classifierLlm)
148
+ .withLogger(fileLogger)
149
+ .withMode(this.cfg.mode ?? 'smart');
150
+ if (helperLlm) {
151
+ builder = builder.withHelperLlm(helperLlm);
152
+ }
153
+ if (this.cfg.rag) {
154
+ const ragOptions = {
155
+ injectedEmbedder: this.cfg.embedder,
156
+ extraFactories: mergedEmbedderFactories,
157
+ };
158
+ builder = builder.setToolsRag(makeRag(this.cfg.rag, ragOptions));
159
+ builder = builder.setHistoryRag(makeRag({ ...this.cfg.rag }, ragOptions));
160
+ }
161
+ if (this.cfg.circuitBreaker) {
162
+ builder = builder.withCircuitBreaker(this.cfg.circuitBreaker);
163
+ }
164
+ if (plugins.reranker) {
165
+ builder = builder.withReranker(plugins.reranker);
166
+ }
167
+ if (plugins.queryExpander) {
168
+ builder = builder.withQueryExpander(plugins.queryExpander);
169
+ }
170
+ if (plugins.outputValidator) {
171
+ builder = builder.withOutputValidator(plugins.outputValidator);
172
+ }
173
+ // Skill manager (DI > YAML config > plugin)
174
+ const skillManager = this.cfg.skillManager ??
175
+ plugins.skillManager ??
176
+ resolveSkillManager(this.cfg.skills);
177
+ if (skillManager) {
178
+ builder = builder.withSkillManager(skillManager);
179
+ }
180
+ // LLM call strategy (from agent config)
181
+ const strategyName = this.cfg.agent?.llmCallStrategy;
182
+ if (strategyName) {
183
+ const { StreamingLlmCallStrategy } = await import('./policy/streaming-llm-call-strategy.js');
184
+ const { NonStreamingLlmCallStrategy } = await import('./policy/non-streaming-llm-call-strategy.js');
185
+ const { FallbackLlmCallStrategy } = await import('./policy/fallback-llm-call-strategy.js');
186
+ const strategies = {
187
+ streaming: () => new StreamingLlmCallStrategy(),
188
+ 'non-streaming': () => new NonStreamingLlmCallStrategy(),
189
+ fallback: () => new FallbackLlmCallStrategy(fileLogger),
190
+ };
191
+ const factory = strategies[strategyName];
192
+ if (factory) {
193
+ builder = builder.withLlmCallStrategy(factory());
194
+ }
195
+ }
196
+ // MCP clients (DI > plugin; YAML fallback handled by builder)
197
+ const mcpClients = this.cfg.mcpClients ??
198
+ (plugins.mcpClients.length > 0 ? plugins.mcpClients : undefined);
199
+ if (mcpClients) {
200
+ builder = builder.withMcpClients(mcpClients);
201
+ }
202
+ // Client adapters (DI > plugin; ClineClientAdapter is always registered as default)
203
+ const { ClineClientAdapter } = await import('./adapters/cline-client-adapter.js');
204
+ const adapterSources = [
205
+ ...(this.cfg.clientAdapters ?? []),
206
+ ...plugins.clientAdapters,
207
+ new ClineClientAdapter(),
208
+ ];
209
+ for (const adapter of adapterSources) {
210
+ builder = builder.withClientAdapter(adapter);
211
+ }
212
+ const agentHandle = await builder.build();
213
+ const { agent: smartAgent, chat, streamChat, close: closeAgent, circuitBreakers, ragStores, modelProvider, } = agentHandle;
214
+ // ---- API adapter map (built-in → config DI; DI wins) --------------------
215
+ const { OpenAiApiAdapter } = await import('./api-adapters/openai-adapter.js');
216
+ const { AnthropicApiAdapter } = await import('./api-adapters/anthropic-adapter.js');
217
+ const adapterMap = new Map();
218
+ if (!this.cfg.disableBuiltInAdapters) {
219
+ const openai = new OpenAiApiAdapter();
220
+ const anthropic = new AnthropicApiAdapter();
221
+ adapterMap.set(openai.name, openai);
222
+ adapterMap.set(anthropic.name, anthropic);
223
+ }
224
+ if (this.cfg.apiAdapters) {
225
+ for (const adapter of this.cfg.apiAdapters) {
226
+ adapterMap.set(adapter.name, adapter);
227
+ }
228
+ }
229
+ const closeFns = [closeAgent];
230
+ const startTime = Date.now();
231
+ const healthChecker = new HealthChecker({
232
+ agent: smartAgent,
233
+ startTime,
234
+ version: this.cfg.version ?? PACKAGE_VERSION,
235
+ circuitBreakers,
236
+ });
237
+ // Startup health check removed — use llm-agent-check CLI for diagnostics.
238
+ // Running health check at startup wastes rate-limit budget when combined
239
+ // with tool vectorization (146+ embedding calls).
240
+ // ---- Config hot-reload (optional) ------------------------------------
241
+ if (this.cfg.configFile) {
242
+ const watcher = new ConfigWatcher(this.cfg.configFile);
243
+ watcher.on('reload', (update) => {
244
+ log({ event: 'config_reload', update });
245
+ // Apply agent config updates
246
+ const agentUpdate = {};
247
+ if (update.maxIterations !== undefined)
248
+ agentUpdate.maxIterations = update.maxIterations;
249
+ if (update.maxToolCalls !== undefined)
250
+ agentUpdate.maxToolCalls = update.maxToolCalls;
251
+ if (update.ragQueryK !== undefined)
252
+ agentUpdate.ragQueryK = update.ragQueryK;
253
+ if (update.toolUnavailableTtlMs !== undefined)
254
+ agentUpdate.toolUnavailableTtlMs = update.toolUnavailableTtlMs;
255
+ if (update.showReasoning !== undefined)
256
+ agentUpdate.showReasoning = update.showReasoning;
257
+ if (update.historyAutoSummarizeLimit !== undefined)
258
+ agentUpdate.historyAutoSummarizeLimit =
259
+ update.historyAutoSummarizeLimit;
260
+ if (update.prompts?.ragTranslate !== undefined)
261
+ agentUpdate.ragTranslatePrompt = update.prompts.ragTranslate;
262
+ if (update.prompts?.historySummary !== undefined)
263
+ agentUpdate.historySummaryPrompt = update.prompts.historySummary;
264
+ if (update.classificationEnabled !== undefined)
265
+ agentUpdate.classificationEnabled = update.classificationEnabled;
266
+ if (Object.keys(agentUpdate).length > 0) {
267
+ smartAgent.applyConfigUpdate(agentUpdate);
268
+ }
269
+ // Apply RAG weight updates
270
+ if (update.vectorWeight !== undefined ||
271
+ update.keywordWeight !== undefined) {
272
+ for (const store of Object.values(ragStores)) {
273
+ if (store &&
274
+ typeof store.updateWeights === 'function') {
275
+ store.updateWeights({
276
+ vectorWeight: update.vectorWeight,
277
+ keywordWeight: update.keywordWeight,
278
+ });
279
+ }
280
+ }
281
+ }
282
+ });
283
+ watcher.on('error', (err) => {
284
+ log({ event: 'config_reload_error', error: String(err) });
285
+ });
286
+ watcher.start();
287
+ closeFns.push(() => watcher.stop());
288
+ }
289
+ const { requestLogger } = agentHandle;
290
+ const server = http.createServer((req, res) => this._handle(req, res, requestLogger, smartAgent, chat, streamChat, log, healthChecker, modelProvider, adapterMap).catch((err) => {
291
+ if (!res.headersSent) {
292
+ res.writeHead(500, { 'Content-Type': 'application/json' });
293
+ res.end(jsonError(String(err), 'server_error'));
294
+ }
295
+ }));
296
+ return new Promise((resolve, reject) => {
297
+ const port = this.cfg.port ?? 4004;
298
+ const host = this.cfg.host ?? '0.0.0.0';
299
+ server.on('error', reject);
300
+ server.listen(port, host, () => {
301
+ const addr = server.address();
302
+ const actualPort = typeof addr === 'object' && addr !== null ? addr.port : port;
303
+ log({ event: 'server_started', port: actualPort, host });
304
+ resolve({
305
+ port: actualPort,
306
+ close: async () => {
307
+ for (const fn of closeFns)
308
+ await fn();
309
+ await new Promise((res, rej) => server.close((e) => (e ? rej(e) : res())));
310
+ },
311
+ requestLogger,
312
+ });
313
+ });
314
+ });
315
+ }
316
+ async _handle(req, res, requestLogger, smartAgent, chat, streamChat, log, healthChecker, modelProvider, adapterMap) {
317
+ const rawUrl = req.url ?? '/';
318
+ const urlPath = rawUrl.split('?')[0].replace(/\/$/, '') || '/';
319
+ for (const [k, v] of Object.entries(CORS_HEADERS))
320
+ res.setHeader(k, v);
321
+ if (req.method === 'OPTIONS') {
322
+ res.writeHead(204);
323
+ res.end();
324
+ return;
325
+ }
326
+ log({
327
+ event: 'http_request',
328
+ method: req.method,
329
+ url: rawUrl,
330
+ normalizedPath: urlPath,
331
+ });
332
+ if (req.method === 'GET' &&
333
+ (urlPath === '/v1/models' || urlPath === '/models')) {
334
+ const queryString = rawUrl.includes('?') ? rawUrl.split('?')[1] : '';
335
+ const queryParams = new URLSearchParams(queryString);
336
+ const excludeEmbedding = queryParams.get('exclude_embedding') === 'true';
337
+ let data = [
338
+ { id: 'smart-agent', object: 'model', owned_by: 'smart-agent' },
339
+ ];
340
+ if (modelProvider) {
341
+ const result = await modelProvider.getModels({ excludeEmbedding });
342
+ if (result.ok) {
343
+ data = result.value.map((m) => ({
344
+ id: m.id,
345
+ object: 'model',
346
+ owned_by: m.owned_by ?? 'unknown',
347
+ ...(m.displayName ? { display_name: m.displayName } : {}),
348
+ ...(m.provider ? { provider: m.provider } : {}),
349
+ ...(m.capabilities ? { capabilities: m.capabilities } : {}),
350
+ ...(m.contextLength ? { context_length: m.contextLength } : {}),
351
+ ...(m.streamingSupported !== undefined
352
+ ? { streaming_supported: m.streamingSupported }
353
+ : {}),
354
+ ...(m.deprecated !== undefined ? { deprecated: m.deprecated } : {}),
355
+ }));
356
+ }
357
+ }
358
+ res.writeHead(200, { 'Content-Type': 'application/json' });
359
+ res.end(JSON.stringify({ object: 'list', data }));
360
+ return;
361
+ }
362
+ if (req.method === 'GET' &&
363
+ (urlPath === '/v1/embedding-models' || urlPath === '/embedding-models')) {
364
+ let data = [];
365
+ if (modelProvider?.getEmbeddingModels) {
366
+ const result = await modelProvider.getEmbeddingModels();
367
+ if (result.ok) {
368
+ data = result.value.map((m) => ({
369
+ id: m.id,
370
+ object: 'model',
371
+ owned_by: m.owned_by ?? 'unknown',
372
+ ...(m.displayName ? { display_name: m.displayName } : {}),
373
+ ...(m.provider ? { provider: m.provider } : {}),
374
+ ...(m.capabilities ? { capabilities: m.capabilities } : {}),
375
+ ...(m.contextLength ? { context_length: m.contextLength } : {}),
376
+ ...(m.streamingSupported !== undefined
377
+ ? { streaming_supported: m.streamingSupported }
378
+ : {}),
379
+ ...(m.deprecated !== undefined ? { deprecated: m.deprecated } : {}),
380
+ }));
381
+ }
382
+ }
383
+ res.writeHead(200, { 'Content-Type': 'application/json' });
384
+ res.end(JSON.stringify({ object: 'list', data }));
385
+ return;
386
+ }
387
+ if (req.method === 'GET' && urlPath === '/v1/usage') {
388
+ res.writeHead(200, { 'Content-Type': 'application/json' });
389
+ res.end(JSON.stringify(requestLogger.getSummary()));
390
+ return;
391
+ }
392
+ // /v1/config or /config
393
+ if (urlPath === '/v1/config' || urlPath === '/config') {
394
+ if (req.method === 'GET') {
395
+ const models = smartAgent.getActiveConfig();
396
+ const agent = smartAgent.getAgentConfig();
397
+ const body = { models, agent };
398
+ res.writeHead(200, { 'Content-Type': 'application/json' });
399
+ res.end(JSON.stringify(body));
400
+ return;
401
+ }
402
+ if (req.method === 'PUT') {
403
+ await this._handleConfigUpdate(req, res, smartAgent);
404
+ return;
405
+ }
406
+ // 405 for other methods
407
+ res.setHeader('Allow', 'GET, PUT, OPTIONS');
408
+ res.writeHead(405, { 'Content-Type': 'application/json' });
409
+ res.end(jsonError(`Method ${req.method} not allowed on ${urlPath}`, 'invalid_request_error'));
410
+ return;
411
+ }
412
+ if (req.method === 'GET' &&
413
+ (urlPath === '/health' || urlPath === '/v1/health')) {
414
+ const status = await healthChecker.check();
415
+ const httpCode = status.status === 'unhealthy' ? 503 : 200;
416
+ res.writeHead(httpCode, { 'Content-Type': 'application/json' });
417
+ res.end(JSON.stringify(status));
418
+ return;
419
+ }
420
+ // POST /v1/messages or /messages → Anthropic adapter
421
+ if (req.method === 'POST' &&
422
+ (urlPath === '/v1/messages' || urlPath === '/messages')) {
423
+ const anthropicAdapter = adapterMap?.get('anthropic');
424
+ if (!anthropicAdapter) {
425
+ res.writeHead(404, { 'Content-Type': 'application/json' });
426
+ res.end(jsonError('Anthropic adapter not registered', 'not_found'));
427
+ return;
428
+ }
429
+ await this._handleAdapterRequest(req, res, smartAgent, anthropicAdapter);
430
+ return;
431
+ }
432
+ if (req.method === 'POST' &&
433
+ (urlPath === '/v1/chat/completions' || urlPath === '/chat/completions')) {
434
+ await this._handleChat(req, res, requestLogger, smartAgent, chat, streamChat, log, modelProvider);
435
+ return;
436
+ }
437
+ res.writeHead(404, { 'Content-Type': 'application/json' });
438
+ res.end(jsonError(`Cannot ${req.method} ${urlPath}`, 'invalid_request_error'));
439
+ }
440
+ async _handleAdapterRequest(req, res, agent, adapter) {
441
+ const raw = await readBody(req);
442
+ let body;
443
+ try {
444
+ body = JSON.parse(raw);
445
+ }
446
+ catch {
447
+ res.writeHead(400, { 'Content-Type': 'application/json' });
448
+ res.end(jsonError('Invalid JSON', 'invalid_request_error'));
449
+ return;
450
+ }
451
+ let normalized;
452
+ try {
453
+ normalized = adapter.normalizeRequest(body);
454
+ }
455
+ catch (err) {
456
+ if (err instanceof AdapterValidationError) {
457
+ res.writeHead(err.statusCode, { 'Content-Type': 'application/json' });
458
+ res.end(jsonError(err.message, 'invalid_request_error'));
459
+ return;
460
+ }
461
+ throw err;
462
+ }
463
+ if (normalized.stream) {
464
+ res.writeHead(200, {
465
+ 'Content-Type': 'text/event-stream',
466
+ 'Cache-Control': 'no-cache',
467
+ Connection: 'keep-alive',
468
+ });
469
+ for await (const event of adapter.transformStream(agent.streamProcess(normalized.messages, normalized.options), normalized.context)) {
470
+ const eventLine = event.event ? `event: ${event.event}\n` : '';
471
+ res.write(`${eventLine}data: ${event.data}\n\n`);
472
+ }
473
+ res.end();
474
+ return;
475
+ }
476
+ // Non-streaming
477
+ const result = await agent.process(normalized.messages, normalized.options);
478
+ res.setHeader('Content-Type', 'application/json');
479
+ if (!result.ok) {
480
+ res.writeHead(500);
481
+ res.end(JSON.stringify(adapter.formatError?.(result.error, normalized.context) ?? {
482
+ error: {
483
+ message: result.error.message,
484
+ type: result.error.code,
485
+ },
486
+ }));
487
+ return;
488
+ }
489
+ res.writeHead(200);
490
+ res.end(JSON.stringify(adapter.formatResult(result.value, normalized.context)));
491
+ }
492
+ async _handleChat(req, res, _requestLogger, smartAgent, _chat, _streamChat, log, modelProvider) {
493
+ const rawBody = await readBody(req);
494
+ let parsed;
495
+ try {
496
+ parsed = JSON.parse(rawBody);
497
+ }
498
+ catch {
499
+ res.writeHead(400, { 'Content-Type': 'application/json' });
500
+ res.end(jsonError('Invalid JSON body', 'invalid_request_error'));
501
+ return;
502
+ }
503
+ if (typeof parsed !== 'object' ||
504
+ parsed === null ||
505
+ !Array.isArray(parsed.messages)) {
506
+ res.writeHead(400, { 'Content-Type': 'application/json' });
507
+ res.end(jsonError('messages must be a non-empty array', 'invalid_request_error'));
508
+ return;
509
+ }
510
+ const body = parsed;
511
+ const extractText = (c) => {
512
+ if (c === null || c === undefined)
513
+ return '';
514
+ if (typeof c === 'string')
515
+ return c;
516
+ if (!Array.isArray(c))
517
+ return '';
518
+ return c
519
+ .filter((b) => typeof b === 'object' &&
520
+ b !== null &&
521
+ b.type === 'text' &&
522
+ typeof b.text === 'string')
523
+ .map((b) => b.text)
524
+ .join('\n');
525
+ };
526
+ const userMessages = body.messages.filter((m) => m.role === 'user');
527
+ if (userMessages.length === 0) {
528
+ res.writeHead(400, { 'Content-Type': 'application/json' });
529
+ res.end(jsonError('at least one message with role "user" is required', 'invalid_request_error'));
530
+ return;
531
+ }
532
+ const traceId = randomUUID();
533
+ const sessionId = req.headers['x-session-id'] || 'default';
534
+ const sessionLogger = new SessionLogger(this.cfg.logDir || null, sessionId, traceId);
535
+ const toolsValidationMode = this.cfg.agent?.externalToolsValidationMode ?? 'permissive';
536
+ const externalToolsValidation = normalizeAndValidateExternalTools(body.tools);
537
+ const externalTools = externalToolsValidation.tools;
538
+ if (externalToolsValidation.errors.length > 0) {
539
+ log({
540
+ event: 'invalid_external_tools_detected',
541
+ traceId,
542
+ sessionId,
543
+ mode: toolsValidationMode,
544
+ count: externalToolsValidation.errors.length,
545
+ errors: externalToolsValidation.errors,
546
+ });
547
+ sessionLogger.logStep('invalid_external_tools_detected', {
548
+ mode: toolsValidationMode,
549
+ count: externalToolsValidation.errors.length,
550
+ errors: externalToolsValidation.errors,
551
+ });
552
+ if (toolsValidationMode === 'strict') {
553
+ const firstError = externalToolsValidation.errors[0];
554
+ res.writeHead(400, { 'Content-Type': 'application/json' });
555
+ res.end(jsonValidationError(firstError.message, firstError.code, firstError.param));
556
+ return;
557
+ }
558
+ }
559
+ const t0 = Date.now();
560
+ log({ event: 'request_start', stream: body.stream ?? false, traceId });
561
+ const opts = {
562
+ stream: body.stream,
563
+ externalTools,
564
+ sessionId,
565
+ trace: { traceId },
566
+ sessionLogger,
567
+ model: body.model,
568
+ ...(body.temperature !== undefined
569
+ ? { temperature: body.temperature }
570
+ : {}),
571
+ ...(body.max_tokens !== undefined ? { maxTokens: body.max_tokens } : {}),
572
+ ...(body.top_p !== undefined ? { topP: body.top_p } : {}),
573
+ ...(body.stop !== undefined
574
+ ? { stop: Array.isArray(body.stop) ? body.stop : [body.stop] }
575
+ : {}),
576
+ };
577
+ const responseModel = body.model ?? modelProvider?.getModel() ?? 'smart-agent';
578
+ const normalizedMessages = body.messages
579
+ .map((m) => {
580
+ const role = m.role;
581
+ const normalizedMessage = {
582
+ role,
583
+ content: extractText(m.content),
584
+ };
585
+ if (role === 'tool') {
586
+ if (typeof m.tool_call_id === 'string' && m.tool_call_id.trim()) {
587
+ normalizedMessage.tool_call_id = m.tool_call_id;
588
+ }
589
+ else {
590
+ sessionLogger.logStep('drop_orphan_tool_message', {
591
+ reason: 'missing_tool_call_id',
592
+ });
593
+ return null;
594
+ }
595
+ }
596
+ if (role === 'assistant' && Array.isArray(m.tool_calls)) {
597
+ const toolCalls = m.tool_calls
598
+ .filter((tc) => typeof tc === 'object' &&
599
+ tc !== null &&
600
+ typeof tc.id === 'string' &&
601
+ tc.type === 'function' &&
602
+ typeof tc.function
603
+ ?.name === 'string' &&
604
+ typeof tc.function
605
+ ?.arguments === 'string')
606
+ .map((tc) => ({
607
+ id: tc.id,
608
+ type: 'function',
609
+ function: {
610
+ name: tc.function.name,
611
+ arguments: tc.function.arguments,
612
+ },
613
+ }));
614
+ if (toolCalls.length > 0) {
615
+ normalizedMessage.tool_calls = toolCalls;
616
+ if (!normalizedMessage.content)
617
+ normalizedMessage.content = null;
618
+ }
619
+ }
620
+ return normalizedMessage;
621
+ })
622
+ .filter((m) => m !== null);
623
+ const invalidToolsHeader = externalToolsValidation.errors.length > 0
624
+ ? {
625
+ 'x-smartagent-invalid-tools': String(externalToolsValidation.errors.length),
626
+ }
627
+ : {};
628
+ if (body.stream) {
629
+ res.writeHead(200, {
630
+ 'Content-Type': 'text/event-stream',
631
+ 'Cache-Control': 'no-cache',
632
+ Connection: 'keep-alive',
633
+ ...invalidToolsHeader,
634
+ });
635
+ const id = `chatcmpl-${randomUUID()}`;
636
+ const created = Math.floor(Date.now() / 1000);
637
+ const stream = smartAgent.streamProcess(normalizedMessages, opts);
638
+ let firstChunk = true;
639
+ let finishReasonSent = false;
640
+ let lastUsage = null;
641
+ for await (const chunk of stream) {
642
+ if (!chunk.ok) {
643
+ const errorChunk = {
644
+ id,
645
+ object: 'chat.completion.chunk',
646
+ created,
647
+ model: responseModel,
648
+ choices: [
649
+ {
650
+ index: 0,
651
+ delta: { content: `[Error] ${chunk.error.message}` },
652
+ finish_reason: 'stop',
653
+ },
654
+ ],
655
+ };
656
+ res.write(`data: ${JSON.stringify(errorChunk)}\n\n`);
657
+ finishReasonSent = true;
658
+ break;
659
+ }
660
+ // SSE heartbeat comment — keeps connection alive, ignored by clients
661
+ if (chunk.value.heartbeat) {
662
+ const hb = chunk.value.heartbeat;
663
+ res.write(`: heartbeat tool=${hb.tool} elapsed=${hb.elapsed}ms\n\n`);
664
+ continue;
665
+ }
666
+ // SSE timing breakdown comment — sent with the final chunk
667
+ if (chunk.value.timing) {
668
+ const parts = chunk.value.timing.map((t) => `${t.phase}=${t.duration}ms`);
669
+ res.write(`: timing ${parts.join(' ')}\n\n`);
670
+ }
671
+ if (chunk.value.usage) {
672
+ lastUsage = {
673
+ prompt_tokens: chunk.value.usage.promptTokens,
674
+ completion_tokens: chunk.value.usage.completionTokens,
675
+ total_tokens: chunk.value.usage.totalTokens,
676
+ };
677
+ }
678
+ const baseResponse = {
679
+ id,
680
+ object: 'chat.completion.chunk',
681
+ created,
682
+ model: responseModel,
683
+ usage: null,
684
+ };
685
+ if (firstChunk) {
686
+ res.write(`data: ${JSON.stringify({ ...baseResponse, choices: [{ index: 0, delta: { role: 'assistant', content: chunk.value.content || '' }, finish_reason: null }] })}\n\n`);
687
+ firstChunk = false;
688
+ if (!chunk.value.finishReason && !chunk.value.toolCalls)
689
+ continue;
690
+ }
691
+ if (chunk.value.content || chunk.value.toolCalls) {
692
+ const delta = {};
693
+ if (chunk.value.content)
694
+ delta.content = chunk.value.content;
695
+ if (chunk.value.toolCalls) {
696
+ delta.tool_calls = chunk.value.toolCalls.map((call, index) => {
697
+ const tc = toToolCallDelta(call, index);
698
+ return {
699
+ index: tc.index,
700
+ id: tc.id,
701
+ type: 'function',
702
+ function: {
703
+ name: tc.name,
704
+ arguments: tc.arguments || '',
705
+ },
706
+ };
707
+ });
708
+ }
709
+ res.write(`data: ${JSON.stringify({ ...baseResponse, choices: [{ index: 0, delta, finish_reason: null }] })}\n\n`);
710
+ }
711
+ if (chunk.value.finishReason) {
712
+ res.write(`data: ${JSON.stringify({ ...baseResponse, choices: [{ index: 0, delta: {}, finish_reason: mapStopReason(chunk.value.finishReason) }] })}\n\n`);
713
+ finishReasonSent = true;
714
+ }
715
+ }
716
+ if (!finishReasonSent) {
717
+ const baseResponse = {
718
+ id,
719
+ object: 'chat.completion.chunk',
720
+ created,
721
+ model: responseModel,
722
+ usage: null,
723
+ };
724
+ res.write(`data: ${JSON.stringify({ ...baseResponse, choices: [{ index: 0, delta: {}, finish_reason: 'stop' }] })}\n\n`);
725
+ }
726
+ if ((this.cfg.reportUsage !== false ||
727
+ body.stream_options?.include_usage) &&
728
+ lastUsage) {
729
+ res.write(`data: ${JSON.stringify({ id, object: 'chat.completion.chunk', created, model: responseModel, choices: [], usage: lastUsage })}\n\n`);
730
+ }
731
+ res.write('data: [DONE]\n\n');
732
+ res.end();
733
+ log({
734
+ event: 'request_done',
735
+ ok: true,
736
+ stream: true,
737
+ finishReason: finishReasonSent ? 'sent' : 'fallback_stop',
738
+ durationMs: Date.now() - t0,
739
+ });
740
+ return;
741
+ }
742
+ const result = await smartAgent.process(normalizedMessages, opts);
743
+ log({ event: 'request_done', ok: result.ok, durationMs: Date.now() - t0 });
744
+ const finalContent = result.ok
745
+ ? result.value.content ||
746
+ (result.value.toolCalls ? null : '(no response)')
747
+ : `Error: ${result.error.message}`;
748
+ const finalFinishReason = result.ok
749
+ ? mapStopReason(result.value.stopReason)
750
+ : 'stop';
751
+ let finalUsage = null;
752
+ if (result.ok && result.value.usage) {
753
+ finalUsage = {
754
+ prompt_tokens: result.value.usage.promptTokens,
755
+ completion_tokens: result.value.usage.completionTokens,
756
+ total_tokens: result.value.usage.totalTokens,
757
+ };
758
+ }
759
+ const message = {
760
+ role: 'assistant',
761
+ content: finalContent,
762
+ };
763
+ if (result.ok && result.value.toolCalls) {
764
+ message.tool_calls = result.value.toolCalls;
765
+ }
766
+ res.writeHead(200, {
767
+ 'Content-Type': 'application/json',
768
+ ...invalidToolsHeader,
769
+ });
770
+ res.end(JSON.stringify({
771
+ id: `chatcmpl-${randomUUID()}`,
772
+ object: 'chat.completion',
773
+ created: Math.floor(Date.now() / 1000),
774
+ model: responseModel,
775
+ choices: [
776
+ {
777
+ index: 0,
778
+ message,
779
+ finish_reason: finalFinishReason,
780
+ },
781
+ ],
782
+ usage: finalUsage || {
783
+ prompt_tokens: 0,
784
+ completion_tokens: 0,
785
+ total_tokens: 0,
786
+ },
787
+ }));
788
+ }
789
+ /** Whitelisted agent config fields allowed via PUT /v1/config. */
790
+ static AGENT_CONFIG_FIELDS = new Set([
791
+ 'maxIterations',
792
+ 'maxToolCalls',
793
+ 'ragQueryK',
794
+ 'toolUnavailableTtlMs',
795
+ 'showReasoning',
796
+ 'historyAutoSummarizeLimit',
797
+ 'classificationEnabled',
798
+ ]);
799
+ async _handleConfigUpdate(req, res, smartAgent) {
800
+ const raw = await readBody(req);
801
+ let parsed;
802
+ try {
803
+ parsed = JSON.parse(raw);
804
+ }
805
+ catch {
806
+ res.writeHead(400, { 'Content-Type': 'application/json' });
807
+ res.end(jsonError('Invalid JSON body', 'invalid_request_error'));
808
+ return;
809
+ }
810
+ if (typeof parsed !== 'object' ||
811
+ parsed === null ||
812
+ Array.isArray(parsed)) {
813
+ res.writeHead(400, { 'Content-Type': 'application/json' });
814
+ res.end(jsonError('Request body must be a JSON object', 'invalid_request_error'));
815
+ return;
816
+ }
817
+ const body = parsed;
818
+ // --- Validate agent fields against whitelist ---
819
+ if (body.agent !== undefined) {
820
+ if (typeof body.agent !== 'object' ||
821
+ body.agent === null ||
822
+ Array.isArray(body.agent)) {
823
+ res.writeHead(400, { 'Content-Type': 'application/json' });
824
+ res.end(jsonError('"agent" must be a JSON object', 'invalid_request_error'));
825
+ return;
826
+ }
827
+ const agentFields = body.agent;
828
+ const unsupported = Object.keys(agentFields).filter((k) => !SmartServer.AGENT_CONFIG_FIELDS.has(k));
829
+ if (unsupported.length > 0) {
830
+ res.writeHead(400, { 'Content-Type': 'application/json' });
831
+ res.end(jsonError(`Unsupported agent config fields: ${unsupported.join(', ')}`, 'invalid_request_error'));
832
+ return;
833
+ }
834
+ }
835
+ // --- Validate and resolve models (atomic: resolve ALL before mutating) ---
836
+ let resolvedModels;
837
+ if (body.models !== undefined) {
838
+ if (typeof body.models !== 'object' ||
839
+ body.models === null ||
840
+ Array.isArray(body.models)) {
841
+ res.writeHead(400, { 'Content-Type': 'application/json' });
842
+ res.end(jsonError('"models" must be a JSON object', 'invalid_request_error'));
843
+ return;
844
+ }
845
+ if (!this.cfg.modelResolver) {
846
+ res.writeHead(400, { 'Content-Type': 'application/json' });
847
+ res.end(jsonError('model resolver not configured', 'invalid_request_error'));
848
+ return;
849
+ }
850
+ const modelFields = body.models;
851
+ const validKeys = new Set([
852
+ 'mainModel',
853
+ 'classifierModel',
854
+ 'helperModel',
855
+ ]);
856
+ const unknownKeys = Object.keys(modelFields).filter((k) => !validKeys.has(k));
857
+ if (unknownKeys.length > 0) {
858
+ res.writeHead(400, { 'Content-Type': 'application/json' });
859
+ res.end(jsonError(`Unknown model fields: ${unknownKeys.join(', ')}`, 'invalid_request_error'));
860
+ return;
861
+ }
862
+ try {
863
+ const resolver = this.cfg.modelResolver;
864
+ const [mainLlm, classifierLlm, helperLlm] = await Promise.all([
865
+ modelFields.mainModel
866
+ ? resolver.resolve(String(modelFields.mainModel), 'main')
867
+ : undefined,
868
+ modelFields.classifierModel
869
+ ? resolver.resolve(String(modelFields.classifierModel), 'classifier')
870
+ : undefined,
871
+ modelFields.helperModel
872
+ ? resolver.resolve(String(modelFields.helperModel), 'helper')
873
+ : undefined,
874
+ ]);
875
+ resolvedModels = {};
876
+ if (mainLlm)
877
+ resolvedModels.mainLlm = mainLlm;
878
+ if (classifierLlm)
879
+ resolvedModels.classifierLlm = classifierLlm;
880
+ if (helperLlm)
881
+ resolvedModels.helperLlm = helperLlm;
882
+ }
883
+ catch (err) {
884
+ res.writeHead(500, { 'Content-Type': 'application/json' });
885
+ res.end(jsonError(String(err), 'server_error'));
886
+ return;
887
+ }
888
+ }
889
+ // --- All validation passed — apply mutations ---
890
+ if (resolvedModels) {
891
+ smartAgent.reconfigure(resolvedModels);
892
+ }
893
+ if (body.agent) {
894
+ smartAgent.applyConfigUpdate(body.agent);
895
+ }
896
+ // --- Return updated config ---
897
+ const models = smartAgent.getActiveConfig();
898
+ const agent = smartAgent.getAgentConfig();
899
+ res.writeHead(200, { 'Content-Type': 'application/json' });
900
+ res.end(JSON.stringify({ models, agent }));
901
+ }
902
+ }
903
+ //# sourceMappingURL=smart-server.js.map