@miller-tech/uap 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 (660) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +888 -0
  3. package/dist/analyzers/index.d.ts +3 -0
  4. package/dist/analyzers/index.d.ts.map +1 -0
  5. package/dist/analyzers/index.js +684 -0
  6. package/dist/analyzers/index.js.map +1 -0
  7. package/dist/benchmarks/agents/naive-agent.d.ts +60 -0
  8. package/dist/benchmarks/agents/naive-agent.d.ts.map +1 -0
  9. package/dist/benchmarks/agents/naive-agent.js +144 -0
  10. package/dist/benchmarks/agents/naive-agent.js.map +1 -0
  11. package/dist/benchmarks/agents/uap-agent.d.ts +167 -0
  12. package/dist/benchmarks/agents/uap-agent.d.ts.map +1 -0
  13. package/dist/benchmarks/agents/uap-agent.js +437 -0
  14. package/dist/benchmarks/agents/uap-agent.js.map +1 -0
  15. package/dist/benchmarks/benchmark.d.ts +328 -0
  16. package/dist/benchmarks/benchmark.d.ts.map +1 -0
  17. package/dist/benchmarks/benchmark.js +112 -0
  18. package/dist/benchmarks/benchmark.js.map +1 -0
  19. package/dist/benchmarks/execution-verifier.d.ts +41 -0
  20. package/dist/benchmarks/execution-verifier.d.ts.map +1 -0
  21. package/dist/benchmarks/execution-verifier.js +340 -0
  22. package/dist/benchmarks/execution-verifier.js.map +1 -0
  23. package/dist/benchmarks/hierarchical-prompting.d.ts +37 -0
  24. package/dist/benchmarks/hierarchical-prompting.d.ts.map +1 -0
  25. package/dist/benchmarks/hierarchical-prompting.js +246 -0
  26. package/dist/benchmarks/hierarchical-prompting.js.map +1 -0
  27. package/dist/benchmarks/improved-benchmark.d.ts +89 -0
  28. package/dist/benchmarks/improved-benchmark.d.ts.map +1 -0
  29. package/dist/benchmarks/improved-benchmark.js +585 -0
  30. package/dist/benchmarks/improved-benchmark.js.map +1 -0
  31. package/dist/benchmarks/index.d.ts +11 -0
  32. package/dist/benchmarks/index.d.ts.map +1 -0
  33. package/dist/benchmarks/index.js +11 -0
  34. package/dist/benchmarks/index.js.map +1 -0
  35. package/dist/benchmarks/model-integration.d.ts +111 -0
  36. package/dist/benchmarks/model-integration.d.ts.map +1 -0
  37. package/dist/benchmarks/model-integration.js +904 -0
  38. package/dist/benchmarks/model-integration.js.map +1 -0
  39. package/dist/benchmarks/multi-turn-agent.d.ts +44 -0
  40. package/dist/benchmarks/multi-turn-agent.d.ts.map +1 -0
  41. package/dist/benchmarks/multi-turn-agent.js +254 -0
  42. package/dist/benchmarks/multi-turn-agent.js.map +1 -0
  43. package/dist/benchmarks/multi-turn-loop.d.ts +57 -0
  44. package/dist/benchmarks/multi-turn-loop.d.ts.map +1 -0
  45. package/dist/benchmarks/multi-turn-loop.js +167 -0
  46. package/dist/benchmarks/multi-turn-loop.js.map +1 -0
  47. package/dist/benchmarks/tasks.d.ts +19 -0
  48. package/dist/benchmarks/tasks.d.ts.map +1 -0
  49. package/dist/benchmarks/tasks.js +435 -0
  50. package/dist/benchmarks/tasks.js.map +1 -0
  51. package/dist/bin/cli.d.ts +3 -0
  52. package/dist/bin/cli.d.ts.map +1 -0
  53. package/dist/bin/cli.js +546 -0
  54. package/dist/bin/cli.js.map +1 -0
  55. package/dist/bin/llama-server-optimize.d.ts +18 -0
  56. package/dist/bin/llama-server-optimize.d.ts.map +1 -0
  57. package/dist/bin/llama-server-optimize.js +708 -0
  58. package/dist/bin/llama-server-optimize.js.map +1 -0
  59. package/dist/bin/policy.d.ts +3 -0
  60. package/dist/bin/policy.d.ts.map +1 -0
  61. package/dist/bin/policy.js +143 -0
  62. package/dist/bin/policy.js.map +1 -0
  63. package/dist/bin/tool-calls.d.ts +3 -0
  64. package/dist/bin/tool-calls.d.ts.map +1 -0
  65. package/dist/bin/tool-calls.js +4 -0
  66. package/dist/bin/tool-calls.js.map +1 -0
  67. package/dist/browser/index.d.ts +2 -0
  68. package/dist/browser/index.d.ts.map +1 -0
  69. package/dist/browser/index.js +2 -0
  70. package/dist/browser/index.js.map +1 -0
  71. package/dist/browser/web-browser.d.ts +30 -0
  72. package/dist/browser/web-browser.d.ts.map +1 -0
  73. package/dist/browser/web-browser.js +93 -0
  74. package/dist/browser/web-browser.js.map +1 -0
  75. package/dist/cli/agent.d.ts +20 -0
  76. package/dist/cli/agent.d.ts.map +1 -0
  77. package/dist/cli/agent.js +474 -0
  78. package/dist/cli/agent.js.map +1 -0
  79. package/dist/cli/analyze.d.ts +7 -0
  80. package/dist/cli/analyze.d.ts.map +1 -0
  81. package/dist/cli/analyze.js +103 -0
  82. package/dist/cli/analyze.js.map +1 -0
  83. package/dist/cli/completion-gates.d.ts +51 -0
  84. package/dist/cli/completion-gates.d.ts.map +1 -0
  85. package/dist/cli/completion-gates.js +201 -0
  86. package/dist/cli/completion-gates.js.map +1 -0
  87. package/dist/cli/compliance.d.ts +8 -0
  88. package/dist/cli/compliance.d.ts.map +1 -0
  89. package/dist/cli/compliance.js +509 -0
  90. package/dist/cli/compliance.js.map +1 -0
  91. package/dist/cli/coord.d.ts +7 -0
  92. package/dist/cli/coord.d.ts.map +1 -0
  93. package/dist/cli/coord.js +138 -0
  94. package/dist/cli/coord.js.map +1 -0
  95. package/dist/cli/dashboard.d.ts +21 -0
  96. package/dist/cli/dashboard.d.ts.map +1 -0
  97. package/dist/cli/dashboard.js +1508 -0
  98. package/dist/cli/dashboard.js.map +1 -0
  99. package/dist/cli/deploy.d.ts +19 -0
  100. package/dist/cli/deploy.d.ts.map +1 -0
  101. package/dist/cli/deploy.js +387 -0
  102. package/dist/cli/deploy.js.map +1 -0
  103. package/dist/cli/droids.d.ts +9 -0
  104. package/dist/cli/droids.d.ts.map +1 -0
  105. package/dist/cli/droids.js +227 -0
  106. package/dist/cli/droids.js.map +1 -0
  107. package/dist/cli/generate.d.ts +17 -0
  108. package/dist/cli/generate.d.ts.map +1 -0
  109. package/dist/cli/generate.js +432 -0
  110. package/dist/cli/generate.js.map +1 -0
  111. package/dist/cli/hooks.d.ts +9 -0
  112. package/dist/cli/hooks.d.ts.map +1 -0
  113. package/dist/cli/hooks.js +464 -0
  114. package/dist/cli/hooks.js.map +1 -0
  115. package/dist/cli/init.d.ts +12 -0
  116. package/dist/cli/init.d.ts.map +1 -0
  117. package/dist/cli/init.js +364 -0
  118. package/dist/cli/init.js.map +1 -0
  119. package/dist/cli/mcp-router.d.ts +16 -0
  120. package/dist/cli/mcp-router.d.ts.map +1 -0
  121. package/dist/cli/mcp-router.js +143 -0
  122. package/dist/cli/mcp-router.js.map +1 -0
  123. package/dist/cli/memory.d.ts +24 -0
  124. package/dist/cli/memory.d.ts.map +1 -0
  125. package/dist/cli/memory.js +885 -0
  126. package/dist/cli/memory.js.map +1 -0
  127. package/dist/cli/model.d.ts +15 -0
  128. package/dist/cli/model.d.ts.map +1 -0
  129. package/dist/cli/model.js +290 -0
  130. package/dist/cli/model.js.map +1 -0
  131. package/dist/cli/patterns.d.ts +26 -0
  132. package/dist/cli/patterns.d.ts.map +1 -0
  133. package/dist/cli/patterns.js +862 -0
  134. package/dist/cli/patterns.js.map +1 -0
  135. package/dist/cli/rtk-validation.d.ts +9 -0
  136. package/dist/cli/rtk-validation.d.ts.map +1 -0
  137. package/dist/cli/rtk-validation.js +9 -0
  138. package/dist/cli/rtk-validation.js.map +1 -0
  139. package/dist/cli/rtk.d.ts +34 -0
  140. package/dist/cli/rtk.d.ts.map +1 -0
  141. package/dist/cli/rtk.js +401 -0
  142. package/dist/cli/rtk.js.map +1 -0
  143. package/dist/cli/schema-diff.d.ts +7 -0
  144. package/dist/cli/schema-diff.d.ts.map +1 -0
  145. package/dist/cli/schema-diff.js +11 -0
  146. package/dist/cli/schema-diff.js.map +1 -0
  147. package/dist/cli/setup-mcp-router.d.ts +8 -0
  148. package/dist/cli/setup-mcp-router.d.ts.map +1 -0
  149. package/dist/cli/setup-mcp-router.js +163 -0
  150. package/dist/cli/setup-mcp-router.js.map +1 -0
  151. package/dist/cli/setup-wizard.d.ts +2 -0
  152. package/dist/cli/setup-wizard.d.ts.map +1 -0
  153. package/dist/cli/setup-wizard.js +806 -0
  154. package/dist/cli/setup-wizard.js.map +1 -0
  155. package/dist/cli/setup.d.ts +15 -0
  156. package/dist/cli/setup.d.ts.map +1 -0
  157. package/dist/cli/setup.js +154 -0
  158. package/dist/cli/setup.js.map +1 -0
  159. package/dist/cli/sync.d.ts +8 -0
  160. package/dist/cli/sync.d.ts.map +1 -0
  161. package/dist/cli/sync.js +395 -0
  162. package/dist/cli/sync.js.map +1 -0
  163. package/dist/cli/task.d.ts +33 -0
  164. package/dist/cli/task.d.ts.map +1 -0
  165. package/dist/cli/task.js +672 -0
  166. package/dist/cli/task.js.map +1 -0
  167. package/dist/cli/tool-calls.d.ts +20 -0
  168. package/dist/cli/tool-calls.d.ts.map +1 -0
  169. package/dist/cli/tool-calls.js +605 -0
  170. package/dist/cli/tool-calls.js.map +1 -0
  171. package/dist/cli/uap.d.ts +10 -0
  172. package/dist/cli/uap.d.ts.map +1 -0
  173. package/dist/cli/uap.js +398 -0
  174. package/dist/cli/uap.js.map +1 -0
  175. package/dist/cli/update.d.ts +10 -0
  176. package/dist/cli/update.d.ts.map +1 -0
  177. package/dist/cli/update.js +300 -0
  178. package/dist/cli/update.js.map +1 -0
  179. package/dist/cli/visualize.d.ts +77 -0
  180. package/dist/cli/visualize.d.ts.map +1 -0
  181. package/dist/cli/visualize.js +287 -0
  182. package/dist/cli/visualize.js.map +1 -0
  183. package/dist/cli/worktree.d.ts +9 -0
  184. package/dist/cli/worktree.d.ts.map +1 -0
  185. package/dist/cli/worktree.js +213 -0
  186. package/dist/cli/worktree.js.map +1 -0
  187. package/dist/coordination/adaptive-patterns.d.ts +65 -0
  188. package/dist/coordination/adaptive-patterns.d.ts.map +1 -0
  189. package/dist/coordination/adaptive-patterns.js +108 -0
  190. package/dist/coordination/adaptive-patterns.js.map +1 -0
  191. package/dist/coordination/auto-agent.d.ts +82 -0
  192. package/dist/coordination/auto-agent.d.ts.map +1 -0
  193. package/dist/coordination/auto-agent.js +145 -0
  194. package/dist/coordination/auto-agent.js.map +1 -0
  195. package/dist/coordination/capability-router.d.ts +79 -0
  196. package/dist/coordination/capability-router.d.ts.map +1 -0
  197. package/dist/coordination/capability-router.js +334 -0
  198. package/dist/coordination/capability-router.js.map +1 -0
  199. package/dist/coordination/database.d.ts +13 -0
  200. package/dist/coordination/database.d.ts.map +1 -0
  201. package/dist/coordination/database.js +136 -0
  202. package/dist/coordination/database.js.map +1 -0
  203. package/dist/coordination/deploy-batcher.d.ts +122 -0
  204. package/dist/coordination/deploy-batcher.d.ts.map +1 -0
  205. package/dist/coordination/deploy-batcher.js +718 -0
  206. package/dist/coordination/deploy-batcher.js.map +1 -0
  207. package/dist/coordination/droid-validator.d.ts +59 -0
  208. package/dist/coordination/droid-validator.d.ts.map +1 -0
  209. package/dist/coordination/droid-validator.js +142 -0
  210. package/dist/coordination/droid-validator.js.map +1 -0
  211. package/dist/coordination/index.d.ts +10 -0
  212. package/dist/coordination/index.d.ts.map +1 -0
  213. package/dist/coordination/index.js +10 -0
  214. package/dist/coordination/index.js.map +1 -0
  215. package/dist/coordination/pattern-router.d.ts +50 -0
  216. package/dist/coordination/pattern-router.d.ts.map +1 -0
  217. package/dist/coordination/pattern-router.js +118 -0
  218. package/dist/coordination/pattern-router.js.map +1 -0
  219. package/dist/coordination/service.d.ts +81 -0
  220. package/dist/coordination/service.d.ts.map +1 -0
  221. package/dist/coordination/service.js +619 -0
  222. package/dist/coordination/service.js.map +1 -0
  223. package/dist/coordination/worktree-enforcer.d.ts +22 -0
  224. package/dist/coordination/worktree-enforcer.d.ts.map +1 -0
  225. package/dist/coordination/worktree-enforcer.js +71 -0
  226. package/dist/coordination/worktree-enforcer.js.map +1 -0
  227. package/dist/generators/claude-md.d.ts +3 -0
  228. package/dist/generators/claude-md.d.ts.map +1 -0
  229. package/dist/generators/claude-md.js +1020 -0
  230. package/dist/generators/claude-md.js.map +1 -0
  231. package/dist/generators/template-loader.d.ts +105 -0
  232. package/dist/generators/template-loader.d.ts.map +1 -0
  233. package/dist/generators/template-loader.js +291 -0
  234. package/dist/generators/template-loader.js.map +1 -0
  235. package/dist/index.d.ts +49 -0
  236. package/dist/index.d.ts.map +1 -0
  237. package/dist/index.js +63 -0
  238. package/dist/index.js.map +1 -0
  239. package/dist/mcp-router/config/parser.d.ts +9 -0
  240. package/dist/mcp-router/config/parser.d.ts.map +1 -0
  241. package/dist/mcp-router/config/parser.js +174 -0
  242. package/dist/mcp-router/config/parser.js.map +1 -0
  243. package/dist/mcp-router/executor/client.d.ts +31 -0
  244. package/dist/mcp-router/executor/client.d.ts.map +1 -0
  245. package/dist/mcp-router/executor/client.js +189 -0
  246. package/dist/mcp-router/executor/client.js.map +1 -0
  247. package/dist/mcp-router/index.d.ts +22 -0
  248. package/dist/mcp-router/index.d.ts.map +1 -0
  249. package/dist/mcp-router/index.js +18 -0
  250. package/dist/mcp-router/index.js.map +1 -0
  251. package/dist/mcp-router/output-compressor.d.ts +26 -0
  252. package/dist/mcp-router/output-compressor.d.ts.map +1 -0
  253. package/dist/mcp-router/output-compressor.js +236 -0
  254. package/dist/mcp-router/output-compressor.js.map +1 -0
  255. package/dist/mcp-router/search/fuzzy.d.ts +26 -0
  256. package/dist/mcp-router/search/fuzzy.d.ts.map +1 -0
  257. package/dist/mcp-router/search/fuzzy.js +94 -0
  258. package/dist/mcp-router/search/fuzzy.js.map +1 -0
  259. package/dist/mcp-router/server.d.ts +50 -0
  260. package/dist/mcp-router/server.d.ts.map +1 -0
  261. package/dist/mcp-router/server.js +229 -0
  262. package/dist/mcp-router/server.js.map +1 -0
  263. package/dist/mcp-router/session-stats.d.ts +37 -0
  264. package/dist/mcp-router/session-stats.d.ts.map +1 -0
  265. package/dist/mcp-router/session-stats.js +56 -0
  266. package/dist/mcp-router/session-stats.js.map +1 -0
  267. package/dist/mcp-router/tools/discover.d.ts +37 -0
  268. package/dist/mcp-router/tools/discover.d.ts.map +1 -0
  269. package/dist/mcp-router/tools/discover.js +65 -0
  270. package/dist/mcp-router/tools/discover.js.map +1 -0
  271. package/dist/mcp-router/tools/execute.d.ts +43 -0
  272. package/dist/mcp-router/tools/execute.d.ts.map +1 -0
  273. package/dist/mcp-router/tools/execute.js +144 -0
  274. package/dist/mcp-router/tools/execute.js.map +1 -0
  275. package/dist/mcp-router/types.d.ts +62 -0
  276. package/dist/mcp-router/types.d.ts.map +1 -0
  277. package/dist/mcp-router/types.js +6 -0
  278. package/dist/mcp-router/types.js.map +1 -0
  279. package/dist/memory/adaptive-context.d.ts +149 -0
  280. package/dist/memory/adaptive-context.d.ts.map +1 -0
  281. package/dist/memory/adaptive-context.js +1095 -0
  282. package/dist/memory/adaptive-context.js.map +1 -0
  283. package/dist/memory/agent-scoped-memory.d.ts +67 -0
  284. package/dist/memory/agent-scoped-memory.d.ts.map +1 -0
  285. package/dist/memory/agent-scoped-memory.js +126 -0
  286. package/dist/memory/agent-scoped-memory.js.map +1 -0
  287. package/dist/memory/ambiguity-detector.d.ts +54 -0
  288. package/dist/memory/ambiguity-detector.d.ts.map +1 -0
  289. package/dist/memory/ambiguity-detector.js +401 -0
  290. package/dist/memory/ambiguity-detector.js.map +1 -0
  291. package/dist/memory/backends/base.d.ts +18 -0
  292. package/dist/memory/backends/base.d.ts.map +1 -0
  293. package/dist/memory/backends/base.js +2 -0
  294. package/dist/memory/backends/base.js.map +1 -0
  295. package/dist/memory/backends/factory.d.ts +4 -0
  296. package/dist/memory/backends/factory.d.ts.map +1 -0
  297. package/dist/memory/backends/factory.js +53 -0
  298. package/dist/memory/backends/factory.js.map +1 -0
  299. package/dist/memory/backends/github.d.ts +27 -0
  300. package/dist/memory/backends/github.d.ts.map +1 -0
  301. package/dist/memory/backends/github.js +134 -0
  302. package/dist/memory/backends/github.js.map +1 -0
  303. package/dist/memory/backends/qdrant-cloud.d.ts +32 -0
  304. package/dist/memory/backends/qdrant-cloud.d.ts.map +1 -0
  305. package/dist/memory/backends/qdrant-cloud.js +167 -0
  306. package/dist/memory/backends/qdrant-cloud.js.map +1 -0
  307. package/dist/memory/context-compressor.d.ts +116 -0
  308. package/dist/memory/context-compressor.d.ts.map +1 -0
  309. package/dist/memory/context-compressor.js +430 -0
  310. package/dist/memory/context-compressor.js.map +1 -0
  311. package/dist/memory/context-pruner.d.ts +55 -0
  312. package/dist/memory/context-pruner.d.ts.map +1 -0
  313. package/dist/memory/context-pruner.js +85 -0
  314. package/dist/memory/context-pruner.js.map +1 -0
  315. package/dist/memory/correction-propagator.d.ts +44 -0
  316. package/dist/memory/correction-propagator.d.ts.map +1 -0
  317. package/dist/memory/correction-propagator.js +156 -0
  318. package/dist/memory/correction-propagator.js.map +1 -0
  319. package/dist/memory/daily-log.d.ts +67 -0
  320. package/dist/memory/daily-log.d.ts.map +1 -0
  321. package/dist/memory/daily-log.js +143 -0
  322. package/dist/memory/daily-log.js.map +1 -0
  323. package/dist/memory/dynamic-retrieval.d.ts +112 -0
  324. package/dist/memory/dynamic-retrieval.d.ts.map +1 -0
  325. package/dist/memory/dynamic-retrieval.js +908 -0
  326. package/dist/memory/dynamic-retrieval.js.map +1 -0
  327. package/dist/memory/embeddings.d.ts +172 -0
  328. package/dist/memory/embeddings.d.ts.map +1 -0
  329. package/dist/memory/embeddings.js +780 -0
  330. package/dist/memory/embeddings.js.map +1 -0
  331. package/dist/memory/generic-uap-patterns.d.ts +7 -0
  332. package/dist/memory/generic-uap-patterns.d.ts.map +1 -0
  333. package/dist/memory/generic-uap-patterns.js +43 -0
  334. package/dist/memory/generic-uap-patterns.js.map +1 -0
  335. package/dist/memory/hierarchical-memory.d.ts +141 -0
  336. package/dist/memory/hierarchical-memory.d.ts.map +1 -0
  337. package/dist/memory/hierarchical-memory.js +485 -0
  338. package/dist/memory/hierarchical-memory.js.map +1 -0
  339. package/dist/memory/knowledge-graph.d.ts +98 -0
  340. package/dist/memory/knowledge-graph.d.ts.map +1 -0
  341. package/dist/memory/knowledge-graph.js +275 -0
  342. package/dist/memory/knowledge-graph.js.map +1 -0
  343. package/dist/memory/memory-consolidator.d.ts +124 -0
  344. package/dist/memory/memory-consolidator.d.ts.map +1 -0
  345. package/dist/memory/memory-consolidator.js +514 -0
  346. package/dist/memory/memory-consolidator.js.map +1 -0
  347. package/dist/memory/memory-maintenance.d.ts +39 -0
  348. package/dist/memory/memory-maintenance.d.ts.map +1 -0
  349. package/dist/memory/memory-maintenance.js +336 -0
  350. package/dist/memory/memory-maintenance.js.map +1 -0
  351. package/dist/memory/model-router.d.ts +105 -0
  352. package/dist/memory/model-router.d.ts.map +1 -0
  353. package/dist/memory/model-router.js +474 -0
  354. package/dist/memory/model-router.js.map +1 -0
  355. package/dist/memory/multi-view-memory.d.ts +134 -0
  356. package/dist/memory/multi-view-memory.d.ts.map +1 -0
  357. package/dist/memory/multi-view-memory.js +430 -0
  358. package/dist/memory/multi-view-memory.js.map +1 -0
  359. package/dist/memory/predictive-memory.d.ts +79 -0
  360. package/dist/memory/predictive-memory.d.ts.map +1 -0
  361. package/dist/memory/predictive-memory.js +294 -0
  362. package/dist/memory/predictive-memory.js.map +1 -0
  363. package/dist/memory/prepopulate.d.ts +76 -0
  364. package/dist/memory/prepopulate.d.ts.map +1 -0
  365. package/dist/memory/prepopulate.js +832 -0
  366. package/dist/memory/prepopulate.js.map +1 -0
  367. package/dist/memory/semantic-compression.d.ts +77 -0
  368. package/dist/memory/semantic-compression.d.ts.map +1 -0
  369. package/dist/memory/semantic-compression.js +359 -0
  370. package/dist/memory/semantic-compression.js.map +1 -0
  371. package/dist/memory/serverless-qdrant.d.ts +102 -0
  372. package/dist/memory/serverless-qdrant.d.ts.map +1 -0
  373. package/dist/memory/serverless-qdrant.js +369 -0
  374. package/dist/memory/serverless-qdrant.js.map +1 -0
  375. package/dist/memory/short-term/factory.d.ts +26 -0
  376. package/dist/memory/short-term/factory.d.ts.map +1 -0
  377. package/dist/memory/short-term/factory.js +28 -0
  378. package/dist/memory/short-term/factory.js.map +1 -0
  379. package/dist/memory/short-term/indexeddb.d.ts +25 -0
  380. package/dist/memory/short-term/indexeddb.d.ts.map +1 -0
  381. package/dist/memory/short-term/indexeddb.js +64 -0
  382. package/dist/memory/short-term/indexeddb.js.map +1 -0
  383. package/dist/memory/short-term/schema.d.ts +6 -0
  384. package/dist/memory/short-term/schema.d.ts.map +1 -0
  385. package/dist/memory/short-term/schema.js +141 -0
  386. package/dist/memory/short-term/schema.js.map +1 -0
  387. package/dist/memory/short-term/sqlite.d.ts +64 -0
  388. package/dist/memory/short-term/sqlite.d.ts.map +1 -0
  389. package/dist/memory/short-term/sqlite.js +274 -0
  390. package/dist/memory/short-term/sqlite.js.map +1 -0
  391. package/dist/memory/speculative-cache.d.ts +111 -0
  392. package/dist/memory/speculative-cache.d.ts.map +1 -0
  393. package/dist/memory/speculative-cache.js +457 -0
  394. package/dist/memory/speculative-cache.js.map +1 -0
  395. package/dist/memory/task-classifier.d.ts +40 -0
  396. package/dist/memory/task-classifier.d.ts.map +1 -0
  397. package/dist/memory/task-classifier.js +342 -0
  398. package/dist/memory/task-classifier.js.map +1 -0
  399. package/dist/memory/terminal-bench-knowledge.d.ts +48 -0
  400. package/dist/memory/terminal-bench-knowledge.d.ts.map +1 -0
  401. package/dist/memory/terminal-bench-knowledge.js +622 -0
  402. package/dist/memory/terminal-bench-knowledge.js.map +1 -0
  403. package/dist/memory/write-gate.d.ts +39 -0
  404. package/dist/memory/write-gate.d.ts.map +1 -0
  405. package/dist/memory/write-gate.js +190 -0
  406. package/dist/memory/write-gate.js.map +1 -0
  407. package/dist/models/api-client.d.ts +46 -0
  408. package/dist/models/api-client.d.ts.map +1 -0
  409. package/dist/models/api-client.js +182 -0
  410. package/dist/models/api-client.js.map +1 -0
  411. package/dist/models/execution-profiles.d.ts +64 -0
  412. package/dist/models/execution-profiles.d.ts.map +1 -0
  413. package/dist/models/execution-profiles.js +403 -0
  414. package/dist/models/execution-profiles.js.map +1 -0
  415. package/dist/models/executor.d.ts +130 -0
  416. package/dist/models/executor.d.ts.map +1 -0
  417. package/dist/models/executor.js +382 -0
  418. package/dist/models/executor.js.map +1 -0
  419. package/dist/models/index.d.ts +19 -0
  420. package/dist/models/index.d.ts.map +1 -0
  421. package/dist/models/index.js +23 -0
  422. package/dist/models/index.js.map +1 -0
  423. package/dist/models/plan-validator.d.ts +37 -0
  424. package/dist/models/plan-validator.d.ts.map +1 -0
  425. package/dist/models/plan-validator.js +179 -0
  426. package/dist/models/plan-validator.js.map +1 -0
  427. package/dist/models/planner.d.ts +73 -0
  428. package/dist/models/planner.d.ts.map +1 -0
  429. package/dist/models/planner.js +375 -0
  430. package/dist/models/planner.js.map +1 -0
  431. package/dist/models/router.d.ts +96 -0
  432. package/dist/models/router.d.ts.map +1 -0
  433. package/dist/models/router.js +523 -0
  434. package/dist/models/router.js.map +1 -0
  435. package/dist/models/types.d.ts +370 -0
  436. package/dist/models/types.d.ts.map +1 -0
  437. package/dist/models/types.js +232 -0
  438. package/dist/models/types.js.map +1 -0
  439. package/dist/models/unified-router.d.ts +152 -0
  440. package/dist/models/unified-router.d.ts.map +1 -0
  441. package/dist/models/unified-router.js +313 -0
  442. package/dist/models/unified-router.js.map +1 -0
  443. package/dist/policies/convert-policy-to-claude.d.ts +3 -0
  444. package/dist/policies/convert-policy-to-claude.d.ts.map +1 -0
  445. package/dist/policies/convert-policy-to-claude.js +87 -0
  446. package/dist/policies/convert-policy-to-claude.js.map +1 -0
  447. package/dist/policies/database-manager.d.ts +27 -0
  448. package/dist/policies/database-manager.d.ts.map +1 -0
  449. package/dist/policies/database-manager.js +198 -0
  450. package/dist/policies/database-manager.js.map +1 -0
  451. package/dist/policies/enforced-tool-router.d.ts +53 -0
  452. package/dist/policies/enforced-tool-router.d.ts.map +1 -0
  453. package/dist/policies/enforced-tool-router.js +80 -0
  454. package/dist/policies/enforced-tool-router.js.map +1 -0
  455. package/dist/policies/index.d.ts +10 -0
  456. package/dist/policies/index.d.ts.map +1 -0
  457. package/dist/policies/index.js +8 -0
  458. package/dist/policies/index.js.map +1 -0
  459. package/dist/policies/policy-gate.d.ts +59 -0
  460. package/dist/policies/policy-gate.d.ts.map +1 -0
  461. package/dist/policies/policy-gate.js +171 -0
  462. package/dist/policies/policy-gate.js.map +1 -0
  463. package/dist/policies/policy-memory.d.ts +18 -0
  464. package/dist/policies/policy-memory.d.ts.map +1 -0
  465. package/dist/policies/policy-memory.js +126 -0
  466. package/dist/policies/policy-memory.js.map +1 -0
  467. package/dist/policies/policy-tools.d.ts +11 -0
  468. package/dist/policies/policy-tools.d.ts.map +1 -0
  469. package/dist/policies/policy-tools.js +66 -0
  470. package/dist/policies/policy-tools.js.map +1 -0
  471. package/dist/policies/schemas/policy.d.ts +69 -0
  472. package/dist/policies/schemas/policy.d.ts.map +1 -0
  473. package/dist/policies/schemas/policy.js +31 -0
  474. package/dist/policies/schemas/policy.js.map +1 -0
  475. package/dist/tasks/coordination.d.ts +83 -0
  476. package/dist/tasks/coordination.d.ts.map +1 -0
  477. package/dist/tasks/coordination.js +291 -0
  478. package/dist/tasks/coordination.js.map +1 -0
  479. package/dist/tasks/database.d.ts +19 -0
  480. package/dist/tasks/database.d.ts.map +1 -0
  481. package/dist/tasks/database.js +149 -0
  482. package/dist/tasks/database.js.map +1 -0
  483. package/dist/tasks/decoder-gate.d.ts +64 -0
  484. package/dist/tasks/decoder-gate.d.ts.map +1 -0
  485. package/dist/tasks/decoder-gate.js +268 -0
  486. package/dist/tasks/decoder-gate.js.map +1 -0
  487. package/dist/tasks/index.d.ts +6 -0
  488. package/dist/tasks/index.d.ts.map +1 -0
  489. package/dist/tasks/index.js +6 -0
  490. package/dist/tasks/index.js.map +1 -0
  491. package/dist/tasks/service.d.ts +40 -0
  492. package/dist/tasks/service.d.ts.map +1 -0
  493. package/dist/tasks/service.js +671 -0
  494. package/dist/tasks/service.js.map +1 -0
  495. package/dist/tasks/types.d.ts +238 -0
  496. package/dist/tasks/types.d.ts.map +1 -0
  497. package/dist/tasks/types.js +74 -0
  498. package/dist/tasks/types.js.map +1 -0
  499. package/dist/telemetry/index.d.ts +2 -0
  500. package/dist/telemetry/index.d.ts.map +1 -0
  501. package/dist/telemetry/index.js +2 -0
  502. package/dist/telemetry/index.js.map +1 -0
  503. package/dist/telemetry/session-telemetry.d.ts +56 -0
  504. package/dist/telemetry/session-telemetry.d.ts.map +1 -0
  505. package/dist/telemetry/session-telemetry.js +807 -0
  506. package/dist/telemetry/session-telemetry.js.map +1 -0
  507. package/dist/types/analysis.d.ts +82 -0
  508. package/dist/types/analysis.d.ts.map +1 -0
  509. package/dist/types/analysis.js +2 -0
  510. package/dist/types/analysis.js.map +1 -0
  511. package/dist/types/config.d.ts +3324 -0
  512. package/dist/types/config.d.ts.map +1 -0
  513. package/dist/types/config.js +418 -0
  514. package/dist/types/config.js.map +1 -0
  515. package/dist/types/coordination.d.ts +240 -0
  516. package/dist/types/coordination.d.ts.map +1 -0
  517. package/dist/types/coordination.js +43 -0
  518. package/dist/types/coordination.js.map +1 -0
  519. package/dist/types/index.d.ts +4 -0
  520. package/dist/types/index.d.ts.map +1 -0
  521. package/dist/types/index.js +4 -0
  522. package/dist/types/index.js.map +1 -0
  523. package/dist/uap-droids-strict.d.ts +59 -0
  524. package/dist/uap-droids-strict.d.ts.map +1 -0
  525. package/dist/uap-droids-strict.js +200 -0
  526. package/dist/uap-droids-strict.js.map +1 -0
  527. package/dist/utils/config-manager.d.ts +30 -0
  528. package/dist/utils/config-manager.d.ts.map +1 -0
  529. package/dist/utils/config-manager.js +41 -0
  530. package/dist/utils/config-manager.js.map +1 -0
  531. package/dist/utils/fetch-with-retry.d.ts +5 -0
  532. package/dist/utils/fetch-with-retry.d.ts.map +1 -0
  533. package/dist/utils/fetch-with-retry.js +61 -0
  534. package/dist/utils/fetch-with-retry.js.map +1 -0
  535. package/dist/utils/merge-claude-md.d.ts +28 -0
  536. package/dist/utils/merge-claude-md.d.ts.map +1 -0
  537. package/dist/utils/merge-claude-md.js +342 -0
  538. package/dist/utils/merge-claude-md.js.map +1 -0
  539. package/dist/utils/rate-limiter.d.ts +58 -0
  540. package/dist/utils/rate-limiter.d.ts.map +1 -0
  541. package/dist/utils/rate-limiter.js +100 -0
  542. package/dist/utils/rate-limiter.js.map +1 -0
  543. package/dist/utils/string-similarity.d.ts +37 -0
  544. package/dist/utils/string-similarity.d.ts.map +1 -0
  545. package/dist/utils/string-similarity.js +114 -0
  546. package/dist/utils/string-similarity.js.map +1 -0
  547. package/dist/utils/validate-json.d.ts +51 -0
  548. package/dist/utils/validate-json.d.ts.map +1 -0
  549. package/dist/utils/validate-json.js +94 -0
  550. package/dist/utils/validate-json.js.map +1 -0
  551. package/docs/INDEX.md +66 -0
  552. package/docs/architecture/MULTI_MODEL.md +224 -0
  553. package/docs/architecture/SYSTEM_ANALYSIS.md +1117 -0
  554. package/docs/architecture/UAP_COMPLIANCE.md +217 -0
  555. package/docs/architecture/UAP_PROTOCOL.md +339 -0
  556. package/docs/architecture/UAP_STRICT_DROIDS.md +172 -0
  557. package/docs/archive/BALLS_MODE_SELF_ANALYSIS.md +260 -0
  558. package/docs/archive/FAILING_TASKS_SOLUTION_PLAN.md +668 -0
  559. package/docs/archive/JINJA2-SYSTEM-MESSAGE-FIX.md +209 -0
  560. package/docs/archive/NPM-PUBLISH-V0.9.1.md +240 -0
  561. package/docs/archive/OPTIMIZATION_OPTIONS.md +334 -0
  562. package/docs/archive/SETUP_IMPROVEMENTS.md +213 -0
  563. package/docs/archive/UAP_GENERIC_OPTIMIZATION_PLAN.md +270 -0
  564. package/docs/archive/UAP_V103_PATTERN_DESIGN.md +315 -0
  565. package/docs/archive/UAP_V104_COMPLIANCE_DESIGN.md +223 -0
  566. package/docs/archive/changelog/2026-03-10_uap-100-compliance.md +77 -0
  567. package/docs/archive/changelog/2026-03-10_uap-full-system-verification.md +109 -0
  568. package/docs/benchmarks/ACCURACY_ANALYSIS.md +471 -0
  569. package/docs/benchmarks/TOKEN_OPTIMIZATION.md +572 -0
  570. package/docs/benchmarks/VALIDATION_PLAN.md +568 -0
  571. package/docs/benchmarks/VALIDATION_RESULTS.md +161 -0
  572. package/docs/deployment/DEPLOYMENT.md +895 -0
  573. package/docs/deployment/DEPLOYMENT_STRATEGIES.md +518 -0
  574. package/docs/deployment/DEPLOY_BATCHER_ANALYSIS.md +856 -0
  575. package/docs/deployment/DEPLOY_BATCHING.md +273 -0
  576. package/docs/deployment/DEPLOY_BUCKETING_ANALYSIS.md +420 -0
  577. package/docs/deployment/QWEN35_LLAMA_CPP.md +265 -0
  578. package/docs/getting-started/INTEGRATION.md +449 -0
  579. package/docs/getting-started/OVERVIEW.md +344 -0
  580. package/docs/getting-started/SETUP.md +203 -0
  581. package/docs/integrations/MCP_ROUTER_SETUP.md +445 -0
  582. package/docs/integrations/RTK_INTEGRATION.md +468 -0
  583. package/docs/operations/TROUBLESHOOTING.md +660 -0
  584. package/docs/reference/API_REFERENCE.md +903 -0
  585. package/docs/reference/FEATURES.md +472 -0
  586. package/docs/reference/HARNESS-MATRIX.md +318 -0
  587. package/docs/reference/UAP_CLI_REFERENCE.md +600 -0
  588. package/docs/research/BEHAVIORAL_PATTERNS.md +228 -0
  589. package/docs/research/DOMAIN_STRATEGIES.md +316 -0
  590. package/docs/research/MEMORY_SYSTEMS_COMPARISON.md +812 -0
  591. package/docs/research/PATTERN_ANALYSIS_2026-01-18.md +436 -0
  592. package/docs/research/PERFORMANCE_ANALYSIS_2026-01-18.md +209 -0
  593. package/docs/research/PERFORMANCE_TEST_PLAN.md +383 -0
  594. package/docs/research/TERMINAL_BENCH_LEARNINGS.md +217 -0
  595. package/package.json +113 -0
  596. package/scripts/README.md +161 -0
  597. package/templates/CLAUDE.template.md +10 -0
  598. package/templates/CLAUDE_ARCHITECTURE.template.md +103 -0
  599. package/templates/CLAUDE_CODING.template.md +127 -0
  600. package/templates/CLAUDE_DROIDS.template.md +109 -0
  601. package/templates/CLAUDE_MEMORY.template.md +131 -0
  602. package/templates/CLAUDE_WORKFLOWS.template.md +139 -0
  603. package/templates/PROJECT.template.md +209 -0
  604. package/templates/SCHEMA.md +57 -0
  605. package/templates/archive/CLAUDE.template.root-v6.md +534 -0
  606. package/templates/archive/CLAUDE.template.v6.md +534 -0
  607. package/templates/hooks/forgecode/pre-compact.sh +68 -0
  608. package/templates/hooks/forgecode/session-start.sh +169 -0
  609. package/templates/hooks/forgecode.plugin.sh +128 -0
  610. package/templates/hooks/pre-compact.sh +74 -0
  611. package/templates/hooks/session-start.sh +366 -0
  612. package/tools/agents/README.md +224 -0
  613. package/tools/agents/UAP/README.md +386 -0
  614. package/tools/agents/UAP/__init__.py +9 -0
  615. package/tools/agents/UAP/cli.py +901 -0
  616. package/tools/agents/UAP/compliance_verify.sh +108 -0
  617. package/tools/agents/UAP/full_verification.sh +126 -0
  618. package/tools/agents/UAP/version.py +32 -0
  619. package/tools/agents/benchmarks/benchmark_memory_systems.py +730 -0
  620. package/tools/agents/benchmarks/results/benchmark_20260106_064817.json +170 -0
  621. package/tools/agents/benchmarks/results/benchmark_20260106_064817.md +51 -0
  622. package/tools/agents/config/chat_template.jinja +77 -0
  623. package/tools/agents/config/tool-call-schema.json +19 -0
  624. package/tools/agents/config/tool-call.gbnf +58 -0
  625. package/tools/agents/docker/Dockerfile.python +52 -0
  626. package/tools/agents/docker/Dockerfile.ubuntu +55 -0
  627. package/tools/agents/docker-compose.qdrant.yml +24 -0
  628. package/tools/agents/install-opencode-local.sh.j2 +135 -0
  629. package/tools/agents/migrations/apply.py +256 -0
  630. package/tools/agents/opencode_uap_agent.py +1505 -0
  631. package/tools/agents/plugin/README.md +91 -0
  632. package/tools/agents/plugin/index.ts +46 -0
  633. package/tools/agents/plugin/pre-compact.sh +68 -0
  634. package/tools/agents/plugin/session-start.sh +175 -0
  635. package/tools/agents/plugin/uap-commands.ts +45 -0
  636. package/tools/agents/plugin/uap-droids.ts +54 -0
  637. package/tools/agents/plugin/uap-patterns.ts +54 -0
  638. package/tools/agents/plugin/uap-skills.ts +52 -0
  639. package/tools/agents/plugins/uap-enforce.ts +314 -0
  640. package/tools/agents/scripts/__pycache__/tool_call_wrapper.cpython-313.pyc +0 -0
  641. package/tools/agents/scripts/chat_template_verifier.py +343 -0
  642. package/tools/agents/scripts/fix-qwen-template.js +38 -0
  643. package/tools/agents/scripts/fix_qwen_chat_template.py +316 -0
  644. package/tools/agents/scripts/generate_lora_training_data.py +412 -0
  645. package/tools/agents/scripts/init_qdrant.py +151 -0
  646. package/tools/agents/scripts/memory_migration.py +560 -0
  647. package/tools/agents/scripts/migrate_memory_to_qdrant.py +110 -0
  648. package/tools/agents/scripts/prepare_lora.sh +512 -0
  649. package/tools/agents/scripts/query_memory.py +200 -0
  650. package/tools/agents/scripts/qwen-tool-call-test.js +38 -0
  651. package/tools/agents/scripts/qwen-tool-call-wrapper.js +38 -0
  652. package/tools/agents/scripts/qwen_tool_call_test.py +464 -0
  653. package/tools/agents/scripts/qwen_tool_call_wrapper.py +686 -0
  654. package/tools/agents/scripts/start-services.sh +96 -0
  655. package/tools/agents/scripts/tool-choice-proxy.cjs +296 -0
  656. package/tools/agents/scripts/tool_call_test.py +656 -0
  657. package/tools/agents/scripts/tool_call_wrapper.py +799 -0
  658. package/tools/agents/tests/test_uap_compliance.py +257 -0
  659. package/tools/agents/uap_agent.py +122 -0
  660. package/tools/agents/uap_agent_install.sh +12 -0
@@ -0,0 +1,656 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ UAP Tool Call Reliability Test Suite
4
+
5
+ Model-agnostic test suite for tool calling reliability across different
6
+ scenarios. Uses model profiles for model-specific tuning.
7
+
8
+ Tests:
9
+ 1. Single tool call with per-tool choice
10
+ 2. Two parallel tool calls
11
+ 3. Three parallel tool calls
12
+ 4. Five parallel tool calls (stress test)
13
+ 5. Reasoning content suppression
14
+ 6. Invalid format recovery via escalation
15
+
16
+ Usage:
17
+ python3 tool_call_test.py [--verbose] [--output results.json] [--profile qwen35]
18
+ """
19
+
20
+ import sys
21
+ import time
22
+ import os
23
+ import argparse
24
+ import logging
25
+ from pathlib import Path
26
+ from typing import List, Dict, Any, Tuple
27
+ from dataclasses import dataclass, asdict
28
+ from datetime import datetime
29
+ import json
30
+
31
+ # Add script directory to path for imports (works regardless of cwd)
32
+ _script_dir = str(Path(__file__).resolve().parent)
33
+ if _script_dir not in sys.path:
34
+ sys.path.insert(0, _script_dir)
35
+
36
+ try:
37
+ from tool_call_wrapper import ToolCallClient, ToolCallError
38
+ except ImportError as _e1:
39
+ try:
40
+ # Fall back to legacy name
41
+ from qwen_tool_call_wrapper import (
42
+ Qwen35ToolCallClient as ToolCallClient,
43
+ Qwen35ToolCallError as ToolCallError,
44
+ )
45
+ except ImportError as _e2:
46
+ print(f"Error: Failed to import tool_call_wrapper")
47
+ print(f" Primary import error: {_e1}")
48
+ print(f" Legacy import error: {_e2}")
49
+ print(f" Script directory: {_script_dir}")
50
+ print(f" sys.path: {sys.path[:5]}")
51
+ print()
52
+ print(" Fix: pip install openai (if missing dependency)")
53
+ print(" Or: run from tools/agents/scripts/")
54
+ sys.exit(1)
55
+
56
+ # Configure logging
57
+ logging.basicConfig(
58
+ level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
59
+ )
60
+ logger = logging.getLogger("uap_tool_test")
61
+
62
+
63
+ @dataclass
64
+ class TestResult:
65
+ """Result of a single test"""
66
+
67
+ test_name: str
68
+ success: bool
69
+ latency_ms: float
70
+ attempts: int
71
+ tool_calls_received: int = 0
72
+ tool_calls_expected: int = 0
73
+ error: str = ""
74
+
75
+
76
+ @dataclass
77
+ class TestSummary:
78
+ """Summary of test results"""
79
+
80
+ total_tests: int
81
+ passed_tests: int
82
+ failed_tests: int
83
+ results: List[TestResult]
84
+
85
+ @property
86
+ def success_rate(self) -> float:
87
+ if self.total_tests == 0:
88
+ return 0.0
89
+ return self.passed_tests / self.total_tests * 100
90
+
91
+
92
+ class ToolCallTestSuite:
93
+ """Test suite for tool calling reliability"""
94
+
95
+ def __init__(self, client: ToolCallClient, verbose: bool = False):
96
+ self.client = client
97
+ self.verbose = verbose
98
+ self.results: List[TestResult] = []
99
+
100
+ # Define test tools
101
+ self.tools = [
102
+ {
103
+ "type": "function",
104
+ "function": {
105
+ "name": "read_file",
106
+ "description": "Read file contents from specified path",
107
+ "parameters": {
108
+ "type": "object",
109
+ "properties": {
110
+ "path": {
111
+ "type": "string",
112
+ "description": "Absolute file path",
113
+ }
114
+ },
115
+ "required": ["path"],
116
+ },
117
+ },
118
+ },
119
+ {
120
+ "type": "function",
121
+ "function": {
122
+ "name": "calculate",
123
+ "description": "Perform mathematical calculation",
124
+ "parameters": {
125
+ "type": "object",
126
+ "properties": {
127
+ "operation": {
128
+ "type": "string",
129
+ "enum": ["add", "subtract", "multiply", "divide"],
130
+ },
131
+ "a": {"type": "number"},
132
+ "b": {"type": "number"},
133
+ },
134
+ "required": ["operation", "a", "b"],
135
+ },
136
+ },
137
+ },
138
+ {
139
+ "type": "function",
140
+ "function": {
141
+ "name": "get_system_info",
142
+ "description": "Get system information",
143
+ "parameters": {
144
+ "type": "object",
145
+ "properties": {
146
+ "info_type": {
147
+ "type": "string",
148
+ "enum": ["cpu", "memory", "disk", "all"],
149
+ }
150
+ },
151
+ "required": ["info_type"],
152
+ },
153
+ },
154
+ },
155
+ ]
156
+
157
+ def run_test(
158
+ self,
159
+ test_name: str,
160
+ messages: List[Dict],
161
+ expected_tool_calls: int = 1,
162
+ expected_tool: str = None,
163
+ timeout: int = 60,
164
+ ) -> TestResult:
165
+ """Run a single test with multi-turn accumulation.
166
+
167
+ For servers that emit one tool call per response (e.g. llama.cpp with
168
+ GBNF grammar), this accumulates tool calls across multiple turns by
169
+ feeding synthetic tool results back into the conversation.
170
+ """
171
+ start_time = time.time()
172
+ attempts = 0
173
+ success = False
174
+ error = ""
175
+ latency_ms = 0
176
+ tool_calls_received = 0
177
+
178
+ try:
179
+ # Multi-turn accumulation: collect tool calls across turns
180
+ current_messages = [m.copy() for m in messages]
181
+ collected_tool_names: List[str] = []
182
+ max_turns = expected_tool_calls + 2 # Allow extra turns for convergence
183
+
184
+ for turn in range(max_turns):
185
+ attempts += 1
186
+
187
+ response = self.client.chat_with_tools(
188
+ messages=current_messages,
189
+ tools=self.tools,
190
+ timeout=timeout,
191
+ expected_tool=expected_tool if turn == 0 else None,
192
+ expected_tool_calls=expected_tool_calls,
193
+ )
194
+
195
+ tool_calls = response.choices[0].message.tool_calls
196
+ turn_count = len(tool_calls) if tool_calls else 0
197
+
198
+ if tool_calls:
199
+ for tc in tool_calls:
200
+ collected_tool_names.append(tc.function.name)
201
+
202
+ tool_calls_received = len(collected_tool_names)
203
+
204
+ # Check if we have enough
205
+ if tool_calls_received >= expected_tool_calls:
206
+ success = True
207
+ break
208
+
209
+ # Feed synthetic tool results back for next turn
210
+ # Add assistant message with tool calls
211
+ current_messages.append(
212
+ {
213
+ "role": "assistant",
214
+ "content": None,
215
+ "tool_calls": [
216
+ {
217
+ "id": tc.id,
218
+ "type": "function",
219
+ "function": {
220
+ "name": tc.function.name,
221
+ "arguments": tc.function.arguments,
222
+ },
223
+ }
224
+ for tc in tool_calls
225
+ ],
226
+ }
227
+ )
228
+
229
+ # Add synthetic tool results
230
+ for tc in tool_calls:
231
+ current_messages.append(
232
+ {
233
+ "role": "tool",
234
+ "tool_call_id": tc.id,
235
+ "content": json.dumps(
236
+ {
237
+ "status": "ok",
238
+ "result": f"mock result for {tc.function.name}",
239
+ }
240
+ ),
241
+ }
242
+ )
243
+ else:
244
+ # No tool calls returned - model is done
245
+ break
246
+
247
+ if self.verbose and not success:
248
+ logger.info(
249
+ f"Test '{test_name}' turn {turn + 1}: "
250
+ f"collected {tool_calls_received}/{expected_tool_calls} tool calls"
251
+ )
252
+
253
+ latency_ms = (time.time() - start_time) * 1000
254
+
255
+ except ToolCallError as e:
256
+ error = str(e)
257
+ latency_ms = (time.time() - start_time) * 1000
258
+ if self.verbose:
259
+ logger.error(f"Test '{test_name}' failed: {error}")
260
+
261
+ result = TestResult(
262
+ test_name=test_name,
263
+ success=success,
264
+ latency_ms=latency_ms,
265
+ attempts=attempts,
266
+ tool_calls_received=tool_calls_received,
267
+ tool_calls_expected=expected_tool_calls,
268
+ error=error,
269
+ )
270
+
271
+ self.results.append(result)
272
+
273
+ status = "PASS" if success else "FAIL"
274
+ tc_info = f"{tool_calls_received}/{expected_tool_calls} calls"
275
+ logger.info(
276
+ f"{status} - {test_name} ({latency_ms:.0f}ms, {attempts} attempt(s), {tc_info})"
277
+ )
278
+
279
+ return result
280
+
281
+ def test_single_tool_call(self) -> TestResult:
282
+ """Test 1: Single tool call with per-tool choice"""
283
+ return self.run_test(
284
+ "Single Tool Call (per-tool choice)",
285
+ [{"role": "user", "content": "Read file at /etc/hostname"}],
286
+ expected_tool_calls=1,
287
+ expected_tool="read_file",
288
+ )
289
+
290
+ def test_two_consecutive_tool_calls(self) -> TestResult:
291
+ """Test 2: Two parallel tool calls"""
292
+ return self.run_test(
293
+ "Two Parallel Tool Calls",
294
+ [{"role": "user", "content": "Read /etc/hostname and calculate 5 + 3"}],
295
+ expected_tool_calls=2,
296
+ )
297
+
298
+ def test_three_tool_calls(self) -> TestResult:
299
+ """Test 3: Three parallel tool calls"""
300
+ return self.run_test(
301
+ "Three Parallel Tool Calls",
302
+ [
303
+ {
304
+ "role": "user",
305
+ "content": "Read /etc/hostname, calculate 10 * 5, and get system info for cpu",
306
+ }
307
+ ],
308
+ expected_tool_calls=3,
309
+ )
310
+
311
+ def test_five_tool_calls(self) -> TestResult:
312
+ """Test 4: Five parallel tool calls (stress test)"""
313
+ return self.run_test(
314
+ "Five Tool Calls (Stress)",
315
+ [
316
+ {
317
+ "role": "user",
318
+ "content": (
319
+ "Perform all of these operations:\n"
320
+ "1. Read /etc/hostname\n"
321
+ "2. Calculate 100 / 4\n"
322
+ "3. Calculate 7 * 8\n"
323
+ "4. Get system info for memory\n"
324
+ "5. Get system info for disk"
325
+ ),
326
+ }
327
+ ],
328
+ expected_tool_calls=5,
329
+ )
330
+
331
+ def test_with_reasoning_content(self) -> TestResult:
332
+ """Test 5: Thinking mode disabled, tool call still works"""
333
+ messages = [
334
+ {"role": "system", "content": "Think step by step before answering"},
335
+ {"role": "user", "content": "Read /etc/hosts"},
336
+ ]
337
+
338
+ return self.run_test(
339
+ "Reasoning Content Test",
340
+ messages,
341
+ expected_tool_calls=1,
342
+ expected_tool="read_file",
343
+ )
344
+
345
+ def test_invalid_tool_format_recovery(self) -> TestResult:
346
+ """Test 6: Recovery from invalid format via escalation"""
347
+ return self.run_test(
348
+ "Invalid Format Recovery (escalation)",
349
+ [{"role": "user", "content": "Call read_file with path /test.txt"}],
350
+ expected_tool_calls=1,
351
+ expected_tool="read_file",
352
+ )
353
+
354
+ def run_all_tests(self) -> TestSummary:
355
+ """Run all tests"""
356
+ profile = getattr(self.client, "profile_name", "unknown")
357
+ logger.info("=" * 70)
358
+ logger.info("UAP Tool Call Reliability Test Suite")
359
+ logger.info("=" * 70)
360
+ logger.info(f"Profile: {profile}")
361
+ logger.info(f"Model: {self.client.config['model']}")
362
+ logger.info(f"Base URL: {self.client.config['base_url']}")
363
+ logger.info(f"Temperature: {self.client.config['temperature']}")
364
+ logger.info(f"Default tool_choice: {self.client.config['default_tool_choice']}")
365
+ logger.info(f"parallel_tool_calls: {self.client.config['parallel_tool_calls']}")
366
+ logger.info(
367
+ f"Escalation: {self.client.config.get('escalate_tool_choice', False)}"
368
+ )
369
+ logger.info(
370
+ f"Per-tool choice: {self.client.config.get('use_per_tool_choice', False)}"
371
+ )
372
+ logger.info("=" * 70)
373
+ logger.info("")
374
+
375
+ # Run tests
376
+ tests = [
377
+ self.test_single_tool_call,
378
+ self.test_two_consecutive_tool_calls,
379
+ self.test_three_tool_calls,
380
+ self.test_five_tool_calls,
381
+ self.test_with_reasoning_content,
382
+ self.test_invalid_tool_format_recovery,
383
+ ]
384
+
385
+ for test in tests:
386
+ test()
387
+ if self.verbose:
388
+ time.sleep(1) # Small delay between tests
389
+
390
+ # Calculate summary
391
+ passed = sum(1 for r in self.results if r.success)
392
+ failed = len(self.results) - passed
393
+
394
+ summary = TestSummary(
395
+ total_tests=len(self.results),
396
+ passed_tests=passed,
397
+ failed_tests=failed,
398
+ results=self.results,
399
+ )
400
+
401
+ return summary
402
+
403
+ def print_summary(self, summary: TestSummary):
404
+ """Print test summary"""
405
+ print("\n" + "=" * 70)
406
+ print("TEST SUMMARY")
407
+ print("=" * 70)
408
+ print(f"Total Tests: {summary.total_tests}")
409
+ print(f"Passed: {summary.passed_tests}")
410
+ print(f"Failed: {summary.failed_tests}")
411
+ print(f"Success Rate: {summary.success_rate:.1f}%")
412
+ print("=" * 70)
413
+
414
+ print("\nDetailed Results:")
415
+ print("-" * 70)
416
+
417
+ for result in summary.results:
418
+ status = "PASS" if result.success else "FAIL"
419
+ print(f"{status} {result.test_name}")
420
+ print(
421
+ f" Latency: {result.latency_ms:.0f}ms | "
422
+ f"Attempts: {result.attempts} | "
423
+ f"Tool calls: {result.tool_calls_received}/{result.tool_calls_expected}"
424
+ )
425
+ if result.error:
426
+ print(f" Error: {result.error[:100]}...")
427
+ print()
428
+
429
+ print("-" * 70)
430
+
431
+ # Performance analysis
432
+ if summary.success_rate >= 90:
433
+ print("EXCELLENT: Tool calling is highly reliable")
434
+ elif summary.success_rate >= 70:
435
+ print("GOOD: Tool calling is reliable with minor issues")
436
+ elif summary.success_rate >= 50:
437
+ print("NEEDS IMPROVEMENT: Apply template fixes and retry logic")
438
+ else:
439
+ print("CRITICAL: Tool calling is unreliable, review configuration")
440
+
441
+ print("=" * 70)
442
+
443
+ # Client metrics
444
+ metrics = self.client.get_metrics()
445
+ print("\nClient Metrics:")
446
+ print(f" Total Attempts: {metrics.total_attempts}")
447
+ print(f" Successful Calls: {metrics.successful_calls}")
448
+ print(f" Failed Calls: {metrics.failed_calls}")
449
+ print(f" Retries: {metrics.retries}")
450
+ print(f" Escalations: {metrics.tool_choice_escalations}")
451
+ print(f" Parallel Requested: {metrics.parallel_calls_requested}")
452
+ print(f" Parallel Received: {metrics.parallel_calls_received}")
453
+ print(f" Avg Latency: {metrics.avg_latency_ms:.0f}ms")
454
+ print("=" * 70)
455
+
456
+ return summary.success_rate >= 90
457
+
458
+ def save_results(self, filename: str = None):
459
+ """Save test results to JSON file"""
460
+ if not filename:
461
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
462
+ filename = f"tool_call_test_results_{timestamp}.json"
463
+
464
+ profile = getattr(self.client, "profile_name", "unknown")
465
+ data = {
466
+ "timestamp": datetime.now().isoformat(),
467
+ "profile": profile,
468
+ "model": self.client.config["model"],
469
+ "strategies": {
470
+ "tool_choice": self.client.config.get("default_tool_choice"),
471
+ "parallel_tool_calls": self.client.config.get("parallel_tool_calls"),
472
+ "escalation": self.client.config.get("escalate_tool_choice"),
473
+ "per_tool_choice": self.client.config.get("use_per_tool_choice"),
474
+ "batch_tool_calls": self.client.config.get("batch_tool_calls"),
475
+ "dynamic_temperature": self.client.config.get("dynamic_temperature"),
476
+ "suppress_thinking": self.client.config.get("suppress_thinking"),
477
+ },
478
+ "config": self.client.get_status(),
479
+ "summary": {
480
+ "total_tests": len(self.results),
481
+ "passed_tests": sum(1 for r in self.results if r.success),
482
+ "failed_tests": sum(1 for r in self.results if not r.success),
483
+ "success_rate": sum(1 for r in self.results if r.success)
484
+ / len(self.results)
485
+ * 100
486
+ if self.results
487
+ else 0,
488
+ },
489
+ "results": [asdict(r) for r in self.results],
490
+ "metrics": self.client.get_metrics().to_dict(),
491
+ }
492
+
493
+ with open(filename, "w") as f:
494
+ json.dump(data, f, indent=2)
495
+
496
+ logger.info(f"Results saved to: {filename}")
497
+
498
+
499
+ def run_setup_check(profile: str) -> bool:
500
+ """Validate setup without requiring a running inference server."""
501
+ print("=" * 70)
502
+ print("UAP Tool Call Setup Check")
503
+ print("=" * 70)
504
+ print(f"\nProfile: {profile}")
505
+
506
+ all_ok = True
507
+
508
+ # Check 1: openai package
509
+ try:
510
+ import openai
511
+
512
+ print(f" [OK] openai package: {openai.__version__}")
513
+ except ImportError:
514
+ print(" [FAIL] openai package not installed")
515
+ print(" Fix: pip install openai")
516
+ all_ok = False
517
+
518
+ # Check 2: tool_call_wrapper import
519
+ try:
520
+ from tool_call_wrapper import ToolCallClient as _TC
521
+
522
+ print(" [OK] tool_call_wrapper: importable")
523
+ except ImportError as e:
524
+ print(f" [FAIL] tool_call_wrapper: {e}")
525
+ all_ok = False
526
+
527
+ # Check 3: Profile config
528
+ script_dir = Path(__file__).resolve().parent
529
+ project_root = script_dir.parent.parent.parent
530
+ profile_path = project_root / "config" / "model-profiles" / f"{profile}.json"
531
+ if profile_path.exists():
532
+ print(f" [OK] Profile config: {profile_path.name}")
533
+ try:
534
+ with open(profile_path) as f:
535
+ cfg = json.load(f)
536
+ print(f" Model: {cfg.get('model', '?')}")
537
+ print(f" Context: {cfg.get('context_window', '?')}")
538
+ except Exception:
539
+ pass
540
+ else:
541
+ legacy_path = project_root / "config" / f"{profile}-settings.json"
542
+ if legacy_path.exists():
543
+ print(f" [OK] Profile config: {legacy_path.name} (legacy)")
544
+ else:
545
+ print(f" [INFO] No profile config for '{profile}' (using defaults)")
546
+
547
+ # Check 4: Inference server connectivity
548
+ base_url = os.environ.get("TARGET_URL", "http://127.0.0.1:8080")
549
+ try:
550
+ import urllib.request
551
+
552
+ req = urllib.request.Request(f"{base_url}/v1/models", method="GET")
553
+ req.add_header("Connection", "close")
554
+ with urllib.request.urlopen(req, timeout=3) as resp:
555
+ print(f" [OK] Inference server: {base_url} (status {resp.status})")
556
+ except Exception as e:
557
+ print(
558
+ f" [WARN] Inference server: {base_url} not reachable ({type(e).__name__})"
559
+ )
560
+ print(" Tests require a running inference server.")
561
+ print(f" Set TARGET_URL env var if server is on a different address.")
562
+
563
+ # Check 5: Python scripts
564
+ for script in [
565
+ "tool_call_wrapper.py",
566
+ "tool_call_test.py",
567
+ "chat_template_verifier.py",
568
+ ]:
569
+ path = script_dir / script
570
+ if path.exists():
571
+ print(f" [OK] Script: {script}")
572
+ else:
573
+ # Check legacy name
574
+ legacy = {
575
+ "tool_call_wrapper.py": "qwen_tool_call_wrapper.py",
576
+ "tool_call_test.py": "qwen_tool_call_test.py",
577
+ "chat_template_verifier.py": "fix_qwen_chat_template.py",
578
+ }.get(script)
579
+ if legacy and (script_dir / legacy).exists():
580
+ print(f" [OK] Script: {legacy} (legacy)")
581
+ else:
582
+ print(f" [MISS] Script: {script}")
583
+
584
+ print("\n" + "=" * 70)
585
+ if all_ok:
586
+ print("Setup check PASSED. Run without --check to execute tests.")
587
+ else:
588
+ print("Setup check FAILED. Fix the issues above before running tests.")
589
+ print("=" * 70)
590
+ return all_ok
591
+
592
+
593
+ def main():
594
+ """Main test execution"""
595
+ parser = argparse.ArgumentParser(description="UAP Tool Call Reliability Test")
596
+ parser.add_argument("--verbose", "-v", action="store_true", help="Verbose output")
597
+ parser.add_argument("--output", "-o", type=str, help="Output results to JSON file")
598
+ parser.add_argument(
599
+ "--check",
600
+ action="store_true",
601
+ help="Validate setup without running tests (no server needed)",
602
+ )
603
+ parser.add_argument(
604
+ "--profile",
605
+ "-p",
606
+ type=str,
607
+ default=None,
608
+ help="Model profile (default: auto-detect from UAP_MODEL_PROFILE env var)",
609
+ )
610
+ args = parser.parse_args()
611
+
612
+ # Set profile from CLI arg if provided
613
+ if args.profile:
614
+ os.environ["UAP_MODEL_PROFILE"] = args.profile
615
+
616
+ profile = os.environ.get("UAP_MODEL_PROFILE", "generic")
617
+
618
+ # Setup check mode -- validate without needing a server
619
+ if args.check:
620
+ ok = run_setup_check(profile)
621
+ sys.exit(0 if ok else 1)
622
+
623
+ try:
624
+ # Initialize client
625
+ logger.info(f"Initializing tool call client (profile: {profile})...")
626
+ client = ToolCallClient()
627
+
628
+ # Create test suite
629
+ test_suite = ToolCallTestSuite(client, verbose=args.verbose)
630
+
631
+ # Run tests
632
+ summary = test_suite.run_all_tests()
633
+
634
+ # Print summary
635
+ passed = test_suite.print_summary(summary)
636
+
637
+ # Save results
638
+ if args.output:
639
+ test_suite.save_results(args.output)
640
+
641
+ # Exit with appropriate code
642
+ sys.exit(0 if passed else 1)
643
+
644
+ except KeyboardInterrupt:
645
+ print("\nTest interrupted by user")
646
+ sys.exit(1)
647
+ except Exception as e:
648
+ logger.error(f"Test failed with error: {e}")
649
+ import traceback
650
+
651
+ traceback.print_exc()
652
+ sys.exit(1)
653
+
654
+
655
+ if __name__ == "__main__":
656
+ main()