@langwatch/mcp-server 2.1.0 → 2.2.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 (415) hide show
  1. package/.gitignore +7 -0
  2. package/.npmignore +41 -0
  3. package/CHANGELOG.md +192 -201
  4. package/CONTRIBUTING.md +10 -0
  5. package/README.md +70 -68
  6. package/dist/add-dashboard-widget-4ZC5UN73.js +50 -0
  7. package/dist/add-dashboard-widget-ACC6QYBG.js +49 -0
  8. package/dist/archive-project-KWFM3I5Z.js +19 -0
  9. package/dist/{archive-project-W3IKI7UL.js → archive-project-SPVHXK6A.js} +4 -4
  10. package/dist/{archive-run-plan-474OKHHU.js → archive-run-plan-65QN3XRX.js} +4 -4
  11. package/dist/archive-run-plan-Z4SYE6BP.js +15 -0
  12. package/dist/{archive-scenario-V5UNYK26.js → archive-scenario-A6QV5LOW.js} +4 -4
  13. package/dist/archive-scenario-FXEYQNEH.js +19 -0
  14. package/dist/archive-test-suite-5ADQ3KPQ.js +15 -0
  15. package/dist/{archive-test-suite-O7FLDMXK.js → archive-test-suite-NKZDZY3D.js} +4 -4
  16. package/dist/assign-prompt-tag-5IUZXJ2T.js +23 -0
  17. package/dist/{assign-prompt-tag-Q46WRB6P.js → assign-prompt-tag-HBZLBIFD.js} +8 -4
  18. package/dist/{chunk-OJLYYJWI.js → chunk-3OCG3QPU.js} +7 -10
  19. package/dist/chunk-3YLN3ATJ.js +241 -0
  20. package/dist/chunk-5FNCQRCX.js +91 -0
  21. package/dist/{chunk-UF6XIGYR.js → chunk-6YZUOD34.js} +2 -5
  22. package/dist/{chunk-WVI5CJ6S.js → chunk-7AQLPVFL.js} +2 -2
  23. package/dist/chunk-7VNSRCXO.js +129 -0
  24. package/dist/{chunk-G4ZAZTZW.js → chunk-B4J3PJLX.js} +11 -10
  25. package/dist/{chunk-ZXKLPC2E.js → chunk-BIIKE3EI.js} +1 -1
  26. package/dist/{chunk-37SMPMQS.js → chunk-DMM3JQ42.js} +7 -2
  27. package/dist/{chunk-NUFPTHKU.js → chunk-FOKVY3BK.js} +1 -1
  28. package/dist/{chunk-WT4PO4A3.js → chunk-H6WGMG2T.js} +10 -7
  29. package/dist/{chunk-EYXMLE5X.js → chunk-HGELNIVY.js} +56 -47
  30. package/dist/{chunk-UJPXFA26.js → chunk-HHMNZAPD.js} +101 -74
  31. package/dist/{chunk-RVAE2MEA.js → chunk-I7ATIZED.js} +7 -7
  32. package/dist/{chunk-S4GVX36W.js → chunk-ILZDO25L.js} +7 -10
  33. package/dist/{chunk-QRO35SOM.js → chunk-J7PQKBLD.js} +652 -528
  34. package/dist/{chunk-SR6QPRIE.js → chunk-JRJPH75H.js} +7 -13
  35. package/dist/chunk-K2I7Z3LZ.js +28 -0
  36. package/dist/{chunk-UFOYFYI7.js → chunk-NKMTIHIJ.js} +6 -9
  37. package/dist/{chunk-HV4DWKBI.js → chunk-O7EMWEVJ.js} +2 -4
  38. package/dist/{chunk-56OGTS24.js → chunk-PTDR56Z3.js} +4 -11
  39. package/dist/{chunk-JR6DJZOU.js → chunk-RABYBFX5.js} +4 -10
  40. package/dist/chunk-SUPUUC4W.js +64 -0
  41. package/dist/{chunk-JTQJRNFJ.js → chunk-SXFC3FNH.js} +4 -4
  42. package/dist/{chunk-CKNAH5TG.js → chunk-U24EACC4.js} +3 -10
  43. package/dist/chunk-UNJM3BIL.js +21 -0
  44. package/dist/{chunk-QAMP3CGR.js → chunk-UTJCWXPZ.js} +4 -4
  45. package/dist/chunk-UWLE5T2F.js +312 -0
  46. package/dist/{chunk-6DJDEXET.js → chunk-VMWJD732.js} +6 -12
  47. package/dist/{chunk-7E4FZIYJ.js → chunk-XUIJYNRJ.js} +1 -1
  48. package/dist/chunk-Y34DHR5K.js +67 -0
  49. package/dist/chunk-YCARO42Z.js +516 -0
  50. package/dist/config-EAKW6F26.js +16 -0
  51. package/dist/config.cjs +109 -0
  52. package/dist/config.js +5 -4
  53. package/dist/{create-agent-JFJ2K6X3.js → create-agent-AYZ3LB3V.js} +4 -4
  54. package/dist/create-agent-S5ZBCEFT.js +23 -0
  55. package/dist/create-annotation-LHNCLHYP.js +29 -0
  56. package/dist/{create-annotation-EUXXQ6NS.js → create-annotation-VUSXULQK.js} +10 -5
  57. package/dist/{create-api-key-BGBB76JX.js → create-api-key-NNYKARMG.js} +5 -7
  58. package/dist/create-api-key-T4KSNPKB.js +24 -0
  59. package/dist/create-dashboard-DHVFMEU4.js +18 -0
  60. package/dist/{create-dashboard-Z76AIPLS.js → create-dashboard-WTKKS5Z6.js} +4 -4
  61. package/dist/{create-dataset-FD5VAXU4.js → create-dataset-2MC4SD4O.js} +6 -6
  62. package/dist/create-dataset-LUP5PVDM.js +22 -0
  63. package/dist/create-dataset-records-NSKBZP3G.js +20 -0
  64. package/dist/{create-dataset-records-WQUXXOHI.js → create-dataset-records-W4GLN2FV.js} +5 -7
  65. package/dist/{create-evaluator-6NV33Z52.js → create-evaluator-643G6LXL.js} +4 -4
  66. package/dist/create-evaluator-HMTYO5SS.js +27 -0
  67. package/dist/create-mcp-server.cjs +9513 -0
  68. package/dist/create-mcp-server.js +2647 -10
  69. package/dist/create-project-6N7PIYRY.js +44 -0
  70. package/dist/{create-project-ZQ7TFIO2.js → create-project-KAIC46UY.js} +4 -4
  71. package/dist/{create-prompt-BS6QRCUU.js → create-prompt-E67LXIYT.js} +5 -7
  72. package/dist/create-prompt-PKJ7EDRR.js +37 -0
  73. package/dist/create-prompt-tag-4YO3FSJ3.js +17 -0
  74. package/dist/{create-prompt-tag-FCQ5ELSQ.js → create-prompt-tag-OPQUEXWB.js} +3 -3
  75. package/dist/create-scenario-5PJBMAXO.js +33 -0
  76. package/dist/{create-scenario-DRPTPXU3.js → create-scenario-UEM77OE7.js} +5 -5
  77. package/dist/{create-test-suite-ZIZCCFJ4.js → create-test-suite-4IPXVSFQ.js} +6 -6
  78. package/dist/create-test-suite-SZEPVXSE.js +36 -0
  79. package/dist/create-trigger-5HZSCRAN.js +49 -0
  80. package/dist/create-trigger-PRELMT6J.js +48 -0
  81. package/dist/delete-agent-JUIZWAXG.js +18 -0
  82. package/dist/{delete-agent-SA4JMUZF.js → delete-agent-QMEK3XHK.js} +4 -4
  83. package/dist/delete-annotation-HY3O2OGR.js +17 -0
  84. package/dist/{delete-annotation-X3KKK7QY.js → delete-annotation-VKIQWUYW.js} +4 -4
  85. package/dist/delete-dashboard-76N66XXL.js +18 -0
  86. package/dist/{delete-dashboard-LYMRPF27.js → delete-dashboard-JVIVHNJM.js} +4 -4
  87. package/dist/delete-dataset-HQCR66MG.js +18 -0
  88. package/dist/{delete-dataset-W6EZ44HY.js → delete-dataset-WKRUW4FP.js} +5 -7
  89. package/dist/{delete-dataset-records-7CNOTALB.js → delete-dataset-records-C2IQFFVQ.js} +5 -7
  90. package/dist/delete-dataset-records-SDUHQLLM.js +19 -0
  91. package/dist/delete-evaluator-4SNSCLEE.js +16 -0
  92. package/dist/delete-evaluator-QP3QHTLN.js +15 -0
  93. package/dist/delete-prompt-tag-NZ4JQMYG.js +17 -0
  94. package/dist/{delete-prompt-tag-QB3OCZUV.js → delete-prompt-tag-YYQ4VMAD.js} +3 -3
  95. package/dist/{delete-workflow-NG2VXYYM.js → delete-workflow-5J46T73T.js} +4 -4
  96. package/dist/delete-workflow-JSWABL5F.js +17 -0
  97. package/dist/discover-evaluator-schema-UHWA5HVL.js +120 -0
  98. package/dist/discover-evaluator-schema-XKCLLCB3.js +118 -0
  99. package/dist/discover-scenario-schema-NOJY6S7E.js +137 -0
  100. package/dist/{discover-scenario-schema-W7KBXA4J.js → discover-scenario-schema-OOFIQKOG.js} +37 -17
  101. package/dist/{discover-schema-L6QDPON3.js → discover-schema-55YJBFGQ.js} +181 -186
  102. package/dist/discover-schema-A33SLMXW.js +442 -0
  103. package/dist/get-agent-LJQX7OF4.js +69 -0
  104. package/dist/{get-agent-7THF7HCU.js → get-agent-OTIYUFZA.js} +15 -11
  105. package/dist/get-analytics-DCS72353.js +80 -0
  106. package/dist/get-analytics-IQZKJHLW.js +79 -0
  107. package/dist/get-dashboard-5NYJEIX2.js +29 -0
  108. package/dist/{get-dashboard-P4WWVHFU.js → get-dashboard-QMTYDQAZ.js} +4 -4
  109. package/dist/get-dataset-ALSP7RTX.js +64 -0
  110. package/dist/get-dataset-X4B5JDG2.js +63 -0
  111. package/dist/{get-evaluator-RZ44UIN6.js → get-evaluator-ISMC4LLI.js} +4 -4
  112. package/dist/get-evaluator-XEUZGZCH.js +47 -0
  113. package/dist/{get-project-QSQEAB33.js → get-project-5VKROSDH.js} +4 -4
  114. package/dist/get-project-RM6FRCBK.js +26 -0
  115. package/dist/{get-prompt-GVKXF5NL.js → get-prompt-OWXJZHQQ.js} +53 -58
  116. package/dist/get-prompt-W52DY36E.js +94 -0
  117. package/dist/{get-run-plan-NY7J5GRE.js → get-run-plan-BE3M2AUX.js} +7 -9
  118. package/dist/get-run-plan-RUXQ6PAX.js +58 -0
  119. package/dist/get-scenario-RNM7BAX2.js +37 -0
  120. package/dist/{get-scenario-Q3LLQE4T.js → get-scenario-YM4ODWW6.js} +5 -5
  121. package/dist/get-simulation-run-6GIATQE5.js +69 -0
  122. package/dist/{get-simulation-run-WINEYDMK.js → get-simulation-run-LCFSMPGQ.js} +26 -22
  123. package/dist/{get-test-suite-4HKA7OKS.js → get-test-suite-GC2O7YH6.js} +5 -5
  124. package/dist/get-test-suite-P5LJ6VLF.js +48 -0
  125. package/dist/get-trace-KBRVV4NN.js +45 -0
  126. package/dist/{get-trace-RCUV7N4O.js → get-trace-SEF3FMR5.js} +11 -13
  127. package/dist/get-workflow-7PVED7JE.js +25 -0
  128. package/dist/{get-workflow-EEOC7Y45.js → get-workflow-YXULW4GC.js} +4 -4
  129. package/dist/{http-security-EU3CHTY7.js → http-security-DNLBNQZL.js} +2 -2
  130. package/dist/{http-server-WCDUARTH.js → http-server-IR4QOS43.js} +4071 -347
  131. package/dist/index.js +58671 -37983
  132. package/dist/langwatch-api-annotations-6SA4OB4C.js +17 -0
  133. package/dist/{langwatch-api-annotations-6DHVZWUK.js → langwatch-api-annotations-TBHLCQ5R.js} +4 -4
  134. package/dist/langwatch-api-dashboards-6EO2VVZW.js +17 -0
  135. package/dist/{langwatch-api-dashboards-2KJL2M42.js → langwatch-api-dashboards-NHU5BZD7.js} +4 -4
  136. package/dist/langwatch-api-monitors-CBF3FGIM.js +47 -0
  137. package/dist/{langwatch-api-monitors-6ISFJ7WX.js → langwatch-api-monitors-YNWA2M5Y.js} +11 -16
  138. package/dist/langwatch-api-secrets-ADTOJELP.js +56 -0
  139. package/dist/langwatch-api-secrets-RNFO4LF2.js +55 -0
  140. package/dist/langwatch-api-triggers-KQDQC6L5.js +22 -0
  141. package/dist/langwatch-api-triggers-QS7HDIVW.js +23 -0
  142. package/dist/{langwatch-api-workflows-6UJL5U4Z.js → langwatch-api-workflows-OKC4FXIF.js} +4 -4
  143. package/dist/langwatch-api-workflows-XGJE6SR5.js +15 -0
  144. package/dist/{list-agents-AMVDQPQL.js → list-agents-HVYWEQMI.js} +4 -4
  145. package/dist/list-agents-RBAOCF53.js +42 -0
  146. package/dist/list-annotations-HJH4NBLD.js +38 -0
  147. package/dist/{list-annotations-6PR5NLIC.js → list-annotations-J4UAHSUN.js} +10 -5
  148. package/dist/{list-api-keys-GVPNBIHQ.js → list-api-keys-7UTJRZDG.js} +10 -5
  149. package/dist/list-api-keys-A2PMV435.js +42 -0
  150. package/dist/list-dashboard-boards-OPWROHMG.js +33 -0
  151. package/dist/list-dashboard-boards-U2GJ7GC5.js +34 -0
  152. package/dist/{list-dashboards-Z3BZKDGF.js → list-dashboards-ROSYFLDQ.js} +4 -4
  153. package/dist/list-dashboards-RQ635ZU7.js +32 -0
  154. package/dist/{list-dataset-records-O67HZ35Y.js → list-dataset-records-M5TKA6LK.js} +14 -10
  155. package/dist/list-dataset-records-WFM7F33C.js +43 -0
  156. package/dist/{list-datasets-WXZL6UMP.js → list-datasets-B5X4P7BQ.js} +9 -13
  157. package/dist/list-datasets-THUKQHPX.js +56 -0
  158. package/dist/{list-evaluators-PAX72WCN.js → list-evaluators-MYH2OVCI.js} +5 -7
  159. package/dist/list-evaluators-NLVWF6K7.js +32 -0
  160. package/dist/{list-model-providers-VVLZMLCX.js → list-model-providers-3JUGP4YI.js} +4 -4
  161. package/dist/list-model-providers-H3XKORFO.js +35 -0
  162. package/dist/{list-projects-AQVI6SUK.js → list-projects-6EJ5YYEW.js} +5 -7
  163. package/dist/list-projects-YNNSRMLC.js +40 -0
  164. package/dist/{list-prompt-tags-WZFBJOHG.js → list-prompt-tags-NVFQO6WX.js} +3 -3
  165. package/dist/list-prompt-tags-XUQTTAH4.js +23 -0
  166. package/dist/{list-prompts-BQOHRHYT.js → list-prompts-HSIMMHTF.js} +4 -6
  167. package/dist/list-prompts-IRI6AIXO.js +30 -0
  168. package/dist/{list-run-plans-UBAU2DGH.js → list-run-plans-PX2XI6EK.js} +5 -5
  169. package/dist/list-run-plans-QALLCN2K.js +45 -0
  170. package/dist/{list-scenarios-MS4IUIVM.js → list-scenarios-QZRPVHS4.js} +13 -11
  171. package/dist/list-scenarios-SSJQEMJP.js +45 -0
  172. package/dist/list-simulation-runs-KNOLGMDV.js +53 -0
  173. package/dist/{list-simulation-runs-D6YF4ZOU.js → list-simulation-runs-OEADLLQR.js} +12 -8
  174. package/dist/list-test-suites-ANAQBLDG.js +34 -0
  175. package/dist/{list-test-suites-L7R2O6DR.js → list-test-suites-N4WVLBKK.js} +4 -4
  176. package/dist/list-trigger-fires-JV3WFYYG.js +19 -0
  177. package/dist/list-trigger-fires-WTW4DVIW.js +20 -0
  178. package/dist/list-triggers-SQNIG35Q.js +45 -0
  179. package/dist/list-triggers-V4Y356AK.js +46 -0
  180. package/dist/{list-workflows-6MV4XJHF.js → list-workflows-IMSX7SXU.js} +5 -7
  181. package/dist/list-workflows-ZHTX5LCL.js +33 -0
  182. package/dist/{rename-prompt-tag-K5LQ4CY6.js → rename-prompt-tag-IQI7MHOI.js} +3 -3
  183. package/dist/rename-prompt-tag-PA2BRIE6.js +18 -0
  184. package/dist/{rename-test-suite-NTYHAO5X.js → rename-test-suite-4J7UX5S2.js} +4 -4
  185. package/dist/rename-test-suite-NNVLMLKY.js +20 -0
  186. package/dist/report-issue-AS34ZMJF.js +898 -0
  187. package/dist/{report-issue-RHZZ33IS.js → report-issue-DCZFLGDO.js} +81 -67
  188. package/dist/{rerun-run-plan-MUDWJBE4.js → rerun-run-plan-TG2V4WM4.js} +5 -5
  189. package/dist/rerun-run-plan-ZI5OY3VA.js +21 -0
  190. package/dist/revoke-api-key-3J3ZA4UB.js +15 -0
  191. package/dist/{revoke-api-key-6LAZ3QZZ.js → revoke-api-key-SFMEFWJC.js} +4 -4
  192. package/dist/run-agent-W4VJP72Z.js +75 -0
  193. package/dist/run-agent-YNV6ZHW4.js +74 -0
  194. package/dist/run-plan-6C77GWG4.js +38 -0
  195. package/dist/{run-plan-T4ZYOZGA.js → run-plan-PAARQSI4.js} +7 -7
  196. package/dist/run-query-KJDH544C.js +47 -0
  197. package/dist/run-query-T4QW2Z5O.js +46 -0
  198. package/dist/{run-test-suite-L4MZ7G4D.js → run-test-suite-SQJELEZX.js} +6 -6
  199. package/dist/run-test-suite-STB6NUJM.js +25 -0
  200. package/dist/{run-workflow-DFIS23AP.js → run-workflow-D6PQNBI6.js} +4 -4
  201. package/dist/run-workflow-SP32SO5M.js +36 -0
  202. package/dist/search-traces-HCBGOG6R.js +170 -0
  203. package/dist/search-traces-HSTQ6WTQ.js +171 -0
  204. package/dist/{set-model-provider-XRNMFOVR.js → set-model-provider-GF7NXUJA.js} +4 -4
  205. package/dist/set-model-provider-KDQ7C4EZ.js +33 -0
  206. package/dist/{update-agent-DUWNYBNA.js → update-agent-DWG43T2P.js} +4 -4
  207. package/dist/update-agent-MXNOBS4H.js +20 -0
  208. package/dist/update-dashboard-widget-CJKJLCDY.js +71 -0
  209. package/dist/update-dashboard-widget-CYQDS2NR.js +70 -0
  210. package/dist/update-dataset-DQH3OHOU.js +22 -0
  211. package/dist/{update-dataset-YSOMDCOB.js → update-dataset-SQZ6T4WX.js} +6 -6
  212. package/dist/{update-dataset-record-DEA2ITYR.js → update-dataset-record-3AT4IPBC.js} +4 -4
  213. package/dist/update-dataset-record-7PLDGTMR.js +19 -0
  214. package/dist/update-evaluator-4LFTKFPT.js +24 -0
  215. package/dist/{update-evaluator-NH7Q5GWV.js → update-evaluator-IGTX6PX4.js} +4 -4
  216. package/dist/{update-project-Q26FBSYH.js → update-project-PLJIOZS6.js} +4 -4
  217. package/dist/update-project-QVHSJRUP.js +24 -0
  218. package/dist/update-prompt-GDKRYJI3.js +140 -0
  219. package/dist/{update-prompt-ZQQ2C3KU.js → update-prompt-MY263DYF.js} +27 -29
  220. package/dist/update-scenario-7KA3JDXA.js +34 -0
  221. package/dist/{update-scenario-WUX34JAR.js → update-scenario-MOHRQKAQ.js} +5 -5
  222. package/package.json +35 -39
  223. package/pyproject.toml +8 -8
  224. package/src/config.d.ts +4 -0
  225. package/src/config.ts +20 -29
  226. package/src/create-mcp-server.ts +755 -609
  227. package/src/documentation-fetch.ts +21 -20
  228. package/src/http-security.ts +166 -135
  229. package/src/http-server.ts +189 -224
  230. package/src/index.ts +14 -16
  231. package/src/langwatch-api-agents.ts +18 -21
  232. package/src/langwatch-api-annotations.ts +11 -12
  233. package/src/langwatch-api-api-keys.ts +8 -9
  234. package/src/langwatch-api-boards.ts +46 -0
  235. package/src/langwatch-api-dashboard-widgets.ts +112 -0
  236. package/src/langwatch-api-dashboards.ts +13 -10
  237. package/src/langwatch-api-datasets.ts +98 -32
  238. package/src/langwatch-api-evaluators.ts +13 -19
  239. package/src/langwatch-api-model-providers.ts +4 -4
  240. package/src/langwatch-api-monitors.ts +14 -18
  241. package/src/langwatch-api-projects.ts +27 -9
  242. package/src/langwatch-api-query.ts +114 -0
  243. package/src/langwatch-api-run-plans.ts +12 -29
  244. package/src/langwatch-api-scenarios.ts +9 -11
  245. package/src/langwatch-api-secrets.ts +31 -24
  246. package/src/langwatch-api-simulation-runs.ts +6 -8
  247. package/src/langwatch-api-test-suites.ts +14 -33
  248. package/src/langwatch-api-triggers.ts +96 -34
  249. package/src/langwatch-api-workflows.ts +9 -9
  250. package/src/langwatch-api.ts +108 -124
  251. package/src/public-http-request.ts +21 -12
  252. package/src/schemas/analytics-metrics.ts +3 -15
  253. package/src/schemas/create-dataset.ts +3 -4
  254. package/src/schemas/run-plan.ts +13 -29
  255. package/src/schemas/suite-fields.ts +6 -23
  256. package/src/schemas/triggers.ts +365 -0
  257. package/src/tools/add-dashboard-widget.ts +63 -0
  258. package/src/tools/archive-project.ts +2 -4
  259. package/src/tools/archive-run-plan.ts +2 -4
  260. package/src/tools/archive-scenario.ts +2 -4
  261. package/src/tools/archive-test-suite.ts +2 -4
  262. package/src/tools/assign-prompt-tag.ts +6 -2
  263. package/src/tools/create-agent.ts +1 -1
  264. package/src/tools/create-annotation.ts +7 -2
  265. package/src/tools/create-api-key.ts +4 -6
  266. package/src/tools/create-dashboard.ts +1 -1
  267. package/src/tools/create-dataset-records.ts +4 -8
  268. package/src/tools/create-dataset.ts +5 -7
  269. package/src/tools/create-evaluator.ts +3 -5
  270. package/src/tools/create-project.ts +2 -2
  271. package/src/tools/create-prompt-tag.ts +2 -4
  272. package/src/tools/create-prompt.ts +9 -18
  273. package/src/tools/create-scenario.ts +5 -7
  274. package/src/tools/create-test-suite.ts +4 -9
  275. package/src/tools/create-trigger.ts +55 -0
  276. package/src/tools/dashboard-exists.ts +25 -0
  277. package/src/tools/dashboard-widget-queries.ts +32 -0
  278. package/src/tools/delete-agent.ts +1 -1
  279. package/src/tools/delete-annotation.ts +1 -1
  280. package/src/tools/delete-dashboard.ts +1 -1
  281. package/src/tools/delete-dataset-records.ts +4 -8
  282. package/src/tools/delete-dataset.ts +3 -7
  283. package/src/tools/delete-evaluator.ts +4 -6
  284. package/src/tools/delete-prompt-tag.ts +2 -4
  285. package/src/tools/delete-workflow.ts +1 -1
  286. package/src/tools/discover-evaluator-schema.ts +34 -25
  287. package/src/tools/discover-scenario-schema.ts +41 -21
  288. package/src/tools/discover-schema.ts +149 -27
  289. package/src/tools/experiment-run-status.ts +2 -8
  290. package/src/tools/format-dataset-mutation.ts +5 -10
  291. package/src/tools/format-run-plan.ts +7 -21
  292. package/src/tools/format-scenario.ts +2 -4
  293. package/src/tools/format-suite-details.ts +6 -12
  294. package/src/tools/get-agent.ts +15 -6
  295. package/src/tools/get-analytics.ts +52 -46
  296. package/src/tools/get-dashboard.ts +1 -1
  297. package/src/tools/get-dataset.ts +34 -16
  298. package/src/tools/get-evaluator.ts +4 -11
  299. package/src/tools/get-experiment-results.ts +219 -186
  300. package/src/tools/get-project.ts +2 -4
  301. package/src/tools/get-prompt.ts +63 -84
  302. package/src/tools/get-run-plan.ts +4 -6
  303. package/src/tools/get-scenario.ts +4 -6
  304. package/src/tools/get-simulation-run.ts +27 -24
  305. package/src/tools/get-test-suite.ts +2 -5
  306. package/src/tools/get-trace.ts +16 -17
  307. package/src/tools/get-workflow.ts +1 -1
  308. package/src/tools/list-agents.ts +1 -1
  309. package/src/tools/list-annotations.ts +8 -5
  310. package/src/tools/list-api-keys.ts +7 -2
  311. package/src/tools/list-dashboard-boards.ts +28 -0
  312. package/src/tools/list-dashboards.ts +1 -1
  313. package/src/tools/list-dataset-records.ts +8 -6
  314. package/src/tools/list-datasets.ts +12 -23
  315. package/src/tools/list-evaluators.ts +4 -8
  316. package/src/tools/list-experiment-runs.ts +5 -9
  317. package/src/tools/list-experiments.ts +5 -11
  318. package/src/tools/list-model-providers.ts +3 -5
  319. package/src/tools/list-projects.ts +2 -4
  320. package/src/tools/list-prompt-tags.ts +3 -3
  321. package/src/tools/list-prompts.ts +4 -8
  322. package/src/tools/list-run-plans.ts +2 -2
  323. package/src/tools/list-scenarios.ts +14 -15
  324. package/src/tools/list-simulation-runs.ts +8 -4
  325. package/src/tools/list-test-suites.ts +1 -1
  326. package/src/tools/list-trigger-fires.ts +17 -0
  327. package/src/tools/list-triggers.ts +39 -0
  328. package/src/tools/list-workflows.ts +2 -4
  329. package/src/tools/rename-prompt-tag.ts +1 -1
  330. package/src/tools/rename-test-suite.ts +2 -5
  331. package/src/tools/report-issue.ts +5 -9
  332. package/src/tools/rerun-run-plan.ts +2 -5
  333. package/src/tools/revoke-api-key.ts +2 -4
  334. package/src/tools/run-agent.ts +29 -26
  335. package/src/tools/run-experiment.ts +36 -37
  336. package/src/tools/run-plan.ts +4 -7
  337. package/src/tools/run-query.ts +47 -0
  338. package/src/tools/run-test-suite.ts +4 -7
  339. package/src/tools/run-workflow.ts +2 -5
  340. package/src/tools/search-traces.ts +161 -47
  341. package/src/tools/set-model-provider.ts +4 -6
  342. package/src/tools/test-agent.ts +2 -2
  343. package/src/tools/update-agent.ts +1 -1
  344. package/src/tools/update-dashboard-widget.ts +97 -0
  345. package/src/tools/update-dataset-record.ts +1 -1
  346. package/src/tools/update-dataset.ts +5 -7
  347. package/src/tools/update-evaluator.ts +3 -5
  348. package/src/tools/update-project.ts +1 -1
  349. package/src/tools/update-prompt.ts +44 -59
  350. package/src/tools/update-scenario.ts +5 -7
  351. package/src/tools/update-test-suite.ts +6 -11
  352. package/src/utils/date-parsing.ts +1 -1
  353. package/src/utils/escape-markdown.ts +3 -8
  354. package/src/utils/format-evaluations.ts +6 -6
  355. package/src/utils/markdown-table.ts +58 -0
  356. package/src/utils/trace-id-shape.ts +20 -0
  357. package/tsconfig.app.json +24 -0
  358. package/tsconfig.json +14 -12
  359. package/vitest.integration.config.js +10 -0
  360. package/vitest.scenario.config.js +9 -0
  361. package/.eslintrc.cjs +0 -36
  362. package/dist/chunk-AN4OUA4D.js +0 -86
  363. package/dist/chunk-GELJ2MQR.js +0 -226
  364. package/dist/chunk-K37ZNPXK.js +0 -24
  365. package/dist/config.d.ts +0 -17
  366. package/dist/create-mcp-server.d.ts +0 -10
  367. package/dist/delete-evaluator-RKYC4TNB.js +0 -16
  368. package/dist/discover-evaluator-schema-ESSHQGPY.js +0 -1912
  369. package/dist/get-analytics-R6AZD3AW.js +0 -73
  370. package/dist/get-dataset-AKTYSQDI.js +0 -49
  371. package/dist/index.d.ts +0 -2
  372. package/dist/langwatch-api-secrets-OEBD6GBU.js +0 -41
  373. package/dist/langwatch-api-triggers-5E6DDGX6.js +0 -31
  374. package/dist/run-agent-CAGWGTYT.js +0 -72
  375. package/dist/search-traces-4XTJYXIK.js +0 -79
  376. package/src/__tests__/agent-tools.unit.test.ts +0 -257
  377. package/src/__tests__/all-tools.integration.test.ts +0 -1872
  378. package/src/__tests__/config.unit.test.ts +0 -202
  379. package/src/__tests__/datasets.integration.test.ts +0 -620
  380. package/src/__tests__/datasets.unit.test.ts +0 -244
  381. package/src/__tests__/date-parsing.unit.test.ts +0 -78
  382. package/src/__tests__/discover-evaluator-schema.unit.test.ts +0 -89
  383. package/src/__tests__/discover-schema.unit.test.ts +0 -118
  384. package/src/__tests__/docker.integration.test.ts +0 -318
  385. package/src/__tests__/documentation-fetch-security.integration.test.ts +0 -182
  386. package/src/__tests__/evaluator-tools.unit.test.ts +0 -262
  387. package/src/__tests__/experiment-list-tools.unit.test.ts +0 -157
  388. package/src/__tests__/experiment-status.unit.test.ts +0 -194
  389. package/src/__tests__/feature-map-tool-drift.unit.test.ts +0 -93
  390. package/src/__tests__/get-experiment-results.unit.test.ts +0 -313
  391. package/src/__tests__/http-security-origin.unit.test.ts +0 -97
  392. package/src/__tests__/http-security-sessions.unit.test.ts +0 -209
  393. package/src/__tests__/http-security-verifier.unit.test.ts +0 -248
  394. package/src/__tests__/http-server-allocation.integration.test.ts +0 -279
  395. package/src/__tests__/http-server-origin.integration.test.ts +0 -169
  396. package/src/__tests__/http-server-session-auth.integration.test.ts +0 -341
  397. package/src/__tests__/http-transport.integration.test.ts +0 -395
  398. package/src/__tests__/integration.integration.test.ts +0 -284
  399. package/src/__tests__/langwatch-api.unit.test.ts +0 -661
  400. package/src/__tests__/model-provider-tools.unit.test.ts +0 -190
  401. package/src/__tests__/project-api-key-tools.unit.test.ts +0 -451
  402. package/src/__tests__/prompt-response-types.unit.test.ts +0 -51
  403. package/src/__tests__/prompts.integration.test.ts +0 -736
  404. package/src/__tests__/public-http-request-security.integration.test.ts +0 -118
  405. package/src/__tests__/report-issue.integration.test.ts +0 -147
  406. package/src/__tests__/run-plan-tools.unit.test.ts +0 -565
  407. package/src/__tests__/scenario-tools.integration.test.ts +0 -286
  408. package/src/__tests__/scenario-tools.unit.test.ts +0 -207
  409. package/src/__tests__/schemas.unit.test.ts +0 -85
  410. package/src/__tests__/simulation-run-tools.unit.test.ts +0 -116
  411. package/src/__tests__/support/http-server-harness.ts +0 -138
  412. package/src/__tests__/test-suite-tools.unit.test.ts +0 -615
  413. package/src/__tests__/tools.integration.test.ts +0 -896
  414. package/src/schemas/filter-fields.ts +0 -119
  415. package/src/schemas/index.ts +0 -9
@@ -1,620 +0,0 @@
1
- import { createServer, type Server } from "http";
2
- import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest";
3
- import { initConfig } from "../config.js";
4
-
5
- // --- Canned responses for dataset API endpoints ---
6
-
7
- const CANNED_DATASETS_LIST = {
8
- data: [
9
- {
10
- id: "ds_abc123",
11
- name: "User Feedback",
12
- slug: "user-feedback",
13
- columnTypes: [
14
- { name: "input", type: "string" },
15
- { name: "output", type: "string" },
16
- ],
17
- recordCount: 25,
18
- createdAt: "2025-01-01T00:00:00.000Z",
19
- updatedAt: "2025-01-02T00:00:00.000Z",
20
- },
21
- {
22
- id: "ds_def456",
23
- name: "Training Data",
24
- slug: "training-data",
25
- columnTypes: [{ name: "prompt", type: "string" }],
26
- recordCount: 100,
27
- createdAt: "2025-01-03T00:00:00.000Z",
28
- updatedAt: "2025-01-04T00:00:00.000Z",
29
- },
30
- ],
31
- pagination: { total: 2, page: 1, limit: 50, totalPages: 1 },
32
- };
33
-
34
- const CANNED_DATASETS_EMPTY = {
35
- data: [],
36
- pagination: { total: 0, page: 1, limit: 50, totalPages: 0 },
37
- };
38
-
39
- const CANNED_DATASET_DETAIL = {
40
- id: "ds_abc123",
41
- name: "My Dataset",
42
- slug: "my-dataset",
43
- columnTypes: [
44
- { name: "input", type: "string" },
45
- { name: "output", type: "string" },
46
- ],
47
- createdAt: "2025-01-01T00:00:00.000Z",
48
- updatedAt: "2025-01-02T00:00:00.000Z",
49
- data: [
50
- { id: "rec-1", entry: { input: "hello", output: "world" } },
51
- { id: "rec-2", entry: { input: "foo", output: "bar" } },
52
- ],
53
- };
54
-
55
- const CANNED_DATASET_CREATED = {
56
- id: "ds_new789",
57
- name: "Test Data",
58
- slug: "test-data",
59
- columnTypes: [
60
- { name: "input", type: "string" },
61
- { name: "output", type: "string" },
62
- ],
63
- createdAt: "2025-01-01T00:00:00.000Z",
64
- updatedAt: "2025-01-01T00:00:00.000Z",
65
- };
66
-
67
- const CANNED_DATASET_CREATED_EMPTY = {
68
- id: "ds_new790",
69
- name: "Empty Schema",
70
- slug: "empty-schema",
71
- columnTypes: [],
72
- createdAt: "2025-01-01T00:00:00.000Z",
73
- updatedAt: "2025-01-01T00:00:00.000Z",
74
- };
75
-
76
- const CANNED_DATASET_UPDATED = {
77
- id: "ds_abc123",
78
- name: "New Name",
79
- slug: "new-name",
80
- columnTypes: [
81
- { name: "input", type: "string" },
82
- { name: "output", type: "string" },
83
- ],
84
- createdAt: "2025-01-01T00:00:00.000Z",
85
- updatedAt: "2025-01-05T00:00:00.000Z",
86
- };
87
-
88
- const CANNED_DATASET_UPDATED_COLUMNS = {
89
- id: "ds_abc123",
90
- name: "My Dataset",
91
- slug: "my-dataset",
92
- columnTypes: [{ name: "question", type: "string" }],
93
- createdAt: "2025-01-01T00:00:00.000Z",
94
- updatedAt: "2025-01-05T00:00:00.000Z",
95
- };
96
-
97
- const CANNED_DATASET_ARCHIVED = {
98
- id: "ds_abc123",
99
- archived: true,
100
- };
101
-
102
- const CANNED_RECORDS_CREATED = {
103
- data: [
104
- { id: "rec-new-1", entry: { input: "hello", output: "world" } },
105
- { id: "rec-new-2", entry: { input: "foo", output: "bar" } },
106
- ],
107
- };
108
-
109
- const CANNED_RECORD_UPDATED = {
110
- id: "rec-123",
111
- entry: { input: "updated" },
112
- };
113
-
114
- const CANNED_RECORDS_DELETED = {
115
- deletedCount: 2,
116
- };
117
-
118
- // --- Mock HTTP Server ---
119
-
120
- let emptyListMode = false;
121
-
122
- function createMockServer(): Server {
123
- return createServer((req, res) => {
124
- const authToken = req.headers["x-auth-token"];
125
- if (authToken !== "test-integration-key") {
126
- res.writeHead(401, { "Content-Type": "application/json" });
127
- res.end(JSON.stringify({ message: "Invalid auth token." }));
128
- return;
129
- }
130
-
131
- let body = "";
132
- req.on("data", (chunk: string) => (body += chunk));
133
- req.on("end", () => {
134
- const url = req.url ?? "";
135
- res.setHeader("Content-Type", "application/json");
136
-
137
- // GET /api/dataset - list datasets
138
- if (url.match(/^\/api\/dataset(\?|$)/) && req.method === "GET") {
139
- if (emptyListMode) {
140
- res.writeHead(200);
141
- res.end(JSON.stringify(CANNED_DATASETS_EMPTY));
142
- } else {
143
- res.writeHead(200);
144
- res.end(JSON.stringify(CANNED_DATASETS_LIST));
145
- }
146
- }
147
- // GET /api/dataset/my-dataset - get dataset detail
148
- else if (
149
- url.match(/^\/api\/dataset\/my-dataset(\?|$)/) &&
150
- req.method === "GET"
151
- ) {
152
- res.writeHead(200);
153
- res.end(JSON.stringify(CANNED_DATASET_DETAIL));
154
- }
155
- // GET /api/dataset/does-not-exist - not found
156
- else if (
157
- url.match(/^\/api\/dataset\/does-not-exist(\?|$)/) &&
158
- req.method === "GET"
159
- ) {
160
- res.writeHead(404);
161
- res.end(JSON.stringify({ message: "Dataset not found" }));
162
- }
163
- // POST /api/dataset - create dataset
164
- else if (url === "/api/dataset" && req.method === "POST") {
165
- const parsed = JSON.parse(body);
166
- if (
167
- parsed.columnTypes &&
168
- Array.isArray(parsed.columnTypes) &&
169
- parsed.columnTypes.length > 0
170
- ) {
171
- res.writeHead(201);
172
- res.end(JSON.stringify(CANNED_DATASET_CREATED));
173
- } else {
174
- res.writeHead(201);
175
- res.end(JSON.stringify(CANNED_DATASET_CREATED_EMPTY));
176
- }
177
- }
178
- // PATCH /api/dataset/old-name - update dataset name
179
- else if (
180
- url.match(/^\/api\/dataset\/old-name$/) &&
181
- req.method === "PATCH"
182
- ) {
183
- res.writeHead(200);
184
- res.end(JSON.stringify(CANNED_DATASET_UPDATED));
185
- }
186
- // PATCH /api/dataset/my-dataset - update dataset columns
187
- else if (
188
- url.match(/^\/api\/dataset\/my-dataset$/) &&
189
- req.method === "PATCH"
190
- ) {
191
- res.writeHead(200);
192
- res.end(JSON.stringify(CANNED_DATASET_UPDATED_COLUMNS));
193
- }
194
- // PATCH /api/dataset/ghost - not found
195
- else if (
196
- url.match(/^\/api\/dataset\/ghost$/) &&
197
- req.method === "PATCH"
198
- ) {
199
- res.writeHead(404);
200
- res.end(JSON.stringify({ message: "Dataset not found" }));
201
- }
202
- // DELETE /api/dataset/to-delete - archive dataset
203
- else if (
204
- url.match(/^\/api\/dataset\/to-delete$/) &&
205
- req.method === "DELETE"
206
- ) {
207
- res.writeHead(200);
208
- res.end(JSON.stringify(CANNED_DATASET_ARCHIVED));
209
- }
210
- // DELETE /api/dataset/ghost - not found
211
- else if (
212
- url.match(/^\/api\/dataset\/ghost$/) &&
213
- req.method === "DELETE"
214
- ) {
215
- res.writeHead(404);
216
- res.end(JSON.stringify({ message: "Dataset not found" }));
217
- }
218
- // POST /api/dataset/my-dataset/records - create records
219
- else if (
220
- url.match(/^\/api\/dataset\/my-dataset\/records$/) &&
221
- req.method === "POST"
222
- ) {
223
- res.writeHead(201);
224
- res.end(JSON.stringify(CANNED_RECORDS_CREATED));
225
- }
226
- // POST /api/dataset/ghost/records - not found
227
- else if (
228
- url.match(/^\/api\/dataset\/ghost\/records$/) &&
229
- req.method === "POST"
230
- ) {
231
- res.writeHead(404);
232
- res.end(JSON.stringify({ message: "Dataset not found" }));
233
- }
234
- // PATCH /api/dataset/my-dataset/records/rec-123 - update record
235
- else if (
236
- url.match(/^\/api\/dataset\/my-dataset\/records\/rec-123$/) &&
237
- req.method === "PATCH"
238
- ) {
239
- res.writeHead(200);
240
- res.end(JSON.stringify(CANNED_RECORD_UPDATED));
241
- }
242
- // PATCH /api/dataset/ghost/records/rec-1 - not found
243
- else if (
244
- url.match(/^\/api\/dataset\/ghost\/records\//) &&
245
- req.method === "PATCH"
246
- ) {
247
- res.writeHead(404);
248
- res.end(JSON.stringify({ message: "Dataset not found" }));
249
- }
250
- // DELETE /api/dataset/my-dataset/records - delete records
251
- else if (
252
- url.match(/^\/api\/dataset\/my-dataset\/records$/) &&
253
- req.method === "DELETE"
254
- ) {
255
- res.writeHead(200);
256
- res.end(JSON.stringify(CANNED_RECORDS_DELETED));
257
- }
258
- // DELETE /api/dataset/ghost/records - not found
259
- else if (
260
- url.match(/^\/api\/dataset\/ghost\/records$/) &&
261
- req.method === "DELETE"
262
- ) {
263
- res.writeHead(404);
264
- res.end(JSON.stringify({ message: "Dataset not found" }));
265
- } else {
266
- res.writeHead(404);
267
- res.end(
268
- JSON.stringify({ message: `Not found: ${req.method} ${url}` }),
269
- );
270
- }
271
- });
272
- });
273
- }
274
-
275
- // --- Integration Tests ---
276
-
277
- describe("MCP dataset tools integration", () => {
278
- let server: Server;
279
- let port: number;
280
-
281
- beforeEach(() => {
282
- emptyListMode = false;
283
- });
284
-
285
- beforeAll(async () => {
286
- server = createMockServer();
287
- await new Promise<void>((resolve) => {
288
- server.listen(0, () => {
289
- const addr = server.address();
290
- port = typeof addr === "object" && addr ? addr.port : 0;
291
- initConfig({
292
- apiKey: "test-integration-key",
293
- endpoint: `http://localhost:${port}`,
294
- });
295
- resolve();
296
- });
297
- });
298
- });
299
-
300
- afterAll(async () => {
301
- await new Promise<void>((resolve) => server.close(() => resolve()));
302
- });
303
-
304
- // ── List Datasets ──────────────────────────────────────────────
305
-
306
- describe("platform_list_datasets", () => {
307
- describe("when the project has datasets", () => {
308
- /** @scenario "List datasets returns a formatted summary of all datasets" */
309
- it("returns a formatted list showing both datasets with their names, slugs, and record counts", async () => {
310
- const { handleListDatasets } = await import(
311
- "../tools/list-datasets.js"
312
- );
313
- const result = await handleListDatasets();
314
- expect(result).toContain("User Feedback");
315
- expect(result).toContain("Training Data");
316
- expect(result).toContain("user-feedback");
317
- expect(result).toContain("training-data");
318
- expect(result).toContain("25");
319
- expect(result).toContain("100");
320
- });
321
- });
322
-
323
- describe("when the project has no datasets", () => {
324
- /** @scenario "List datasets returns a helpful message when none exist" */
325
- it("returns a helpful message indicating no datasets were found", async () => {
326
- emptyListMode = true;
327
- const { handleListDatasets } = await import(
328
- "../tools/list-datasets.js"
329
- );
330
- const result = await handleListDatasets();
331
- expect(result).toContain("No datasets found");
332
- });
333
-
334
- it("suggests using platform_create_dataset", async () => {
335
- emptyListMode = true;
336
- const { handleListDatasets } = await import(
337
- "../tools/list-datasets.js"
338
- );
339
- const result = await handleListDatasets();
340
- expect(result).toContain("platform_create_dataset");
341
- });
342
- });
343
-
344
- describe("when format is json", () => {
345
- it("returns parseable JSON containing all datasets and total", async () => {
346
- const { handleListDatasets } = await import(
347
- "../tools/list-datasets.js"
348
- );
349
- const result = await handleListDatasets({ format: "json" });
350
- const parsed = JSON.parse(result);
351
- expect(parsed.data).toEqual(CANNED_DATASETS_LIST.data);
352
- expect(parsed.total).toBe(CANNED_DATASETS_LIST.pagination.total);
353
- });
354
- });
355
- });
356
-
357
- // ── Get Dataset ────────────────────────────────────────────────
358
-
359
- describe("platform_get_dataset", () => {
360
- describe("when the dataset exists", () => {
361
- /** @scenario "Get dataset by slug returns metadata and a preview of records" */
362
- it("returns the dataset name, slug, and column definitions", async () => {
363
- const { handleGetDataset } = await import(
364
- "../tools/get-dataset.js"
365
- );
366
- const result = await handleGetDataset({ slugOrId: "my-dataset" });
367
- expect(result).toContain("My Dataset");
368
- expect(result).toContain("my-dataset");
369
- expect(result).toContain("input");
370
- expect(result).toContain("output");
371
- });
372
-
373
- it("returns a preview of records", async () => {
374
- const { handleGetDataset } = await import(
375
- "../tools/get-dataset.js"
376
- );
377
- const result = await handleGetDataset({ slugOrId: "my-dataset" });
378
- expect(result).toContain("hello");
379
- expect(result).toContain("world");
380
- });
381
- });
382
-
383
- describe("when format is json", () => {
384
- it("returns parseable JSON matching the API response", async () => {
385
- const { handleGetDataset } = await import(
386
- "../tools/get-dataset.js"
387
- );
388
- const result = await handleGetDataset({ slugOrId: "my-dataset", format: "json" });
389
- expect(JSON.parse(result)).toEqual(CANNED_DATASET_DETAIL);
390
- });
391
- });
392
-
393
- describe("when the dataset does not exist", () => {
394
- /** @scenario "Get dataset with non-existent slug returns an error" */
395
- it("propagates the 404 error", async () => {
396
- const { handleGetDataset } = await import(
397
- "../tools/get-dataset.js"
398
- );
399
- await expect(
400
- handleGetDataset({ slugOrId: "does-not-exist" }),
401
- ).rejects.toThrow("404");
402
- });
403
- });
404
- });
405
-
406
- // ── Create Dataset ─────────────────────────────────────────────
407
-
408
- describe("platform_create_dataset", () => {
409
- describe("when creating with name and columns", () => {
410
- /** @scenario "Create a dataset with name and columns" */
411
- it("returns confirmation including the generated slug", async () => {
412
- const { handleCreateDataset } = await import(
413
- "../tools/create-dataset.js"
414
- );
415
- const result = await handleCreateDataset({
416
- name: "Test Data",
417
- columnTypes: [
418
- { name: "input", type: "string" },
419
- { name: "output", type: "string" },
420
- ],
421
- });
422
- expect(result).toContain("test-data");
423
- expect(result).toContain("created");
424
- });
425
- });
426
-
427
- describe("when creating with only a name", () => {
428
- /** @scenario "Create a dataset with only a name and no columns" */
429
- it("returns confirmation including the slug", async () => {
430
- const { handleCreateDataset } = await import(
431
- "../tools/create-dataset.js"
432
- );
433
- const result = await handleCreateDataset({
434
- name: "Empty Schema",
435
- });
436
- expect(result).toContain("empty-schema");
437
- expect(result).toContain("created");
438
- });
439
- });
440
- });
441
-
442
- // ── Update Dataset ─────────────────────────────────────────────
443
-
444
- describe("platform_update_dataset", () => {
445
- describe("when updating the dataset name", () => {
446
- /** @scenario "Update a dataset name" */
447
- it("returns confirmation reflecting the new name", async () => {
448
- const { handleUpdateDataset } = await import(
449
- "../tools/update-dataset.js"
450
- );
451
- const result = await handleUpdateDataset({
452
- slugOrId: "old-name",
453
- name: "New Name",
454
- });
455
- expect(result).toContain("New Name");
456
- expect(result).toContain("updated");
457
- });
458
- });
459
-
460
- describe("when updating dataset column types", () => {
461
- /** @scenario "Update a dataset column types" */
462
- it("returns confirmation reflecting the new columns", async () => {
463
- const { handleUpdateDataset } = await import(
464
- "../tools/update-dataset.js"
465
- );
466
- const result = await handleUpdateDataset({
467
- slugOrId: "my-dataset",
468
- columnTypes: [{ name: "question", type: "string" }],
469
- });
470
- expect(result).toContain("question");
471
- expect(result).toContain("updated");
472
- });
473
- });
474
-
475
- describe("when the dataset does not exist", () => {
476
- /** @scenario "Update a non-existent dataset returns an error" */
477
- it("propagates the 404 error", async () => {
478
- const { handleUpdateDataset } = await import(
479
- "../tools/update-dataset.js"
480
- );
481
- await expect(
482
- handleUpdateDataset({ slugOrId: "ghost", name: "Whatever" }),
483
- ).rejects.toThrow("404");
484
- });
485
- });
486
- });
487
-
488
- // ── Delete Dataset ─────────────────────────────────────────────
489
-
490
- describe("platform_delete_dataset", () => {
491
- describe("when the dataset exists", () => {
492
- /** @scenario "Delete a dataset archives it" */
493
- it("returns confirmation that the dataset was deleted", async () => {
494
- const { handleDeleteDataset } = await import(
495
- "../tools/delete-dataset.js"
496
- );
497
- const result = await handleDeleteDataset({ slugOrId: "to-delete" });
498
- expect(result).toContain("deleted");
499
- });
500
- });
501
-
502
- describe("when the dataset does not exist", () => {
503
- /** @scenario "Delete a non-existent dataset returns an error" */
504
- it("propagates the 404 error", async () => {
505
- const { handleDeleteDataset } = await import(
506
- "../tools/delete-dataset.js"
507
- );
508
- await expect(
509
- handleDeleteDataset({ slugOrId: "ghost" }),
510
- ).rejects.toThrow("404");
511
- });
512
- });
513
- });
514
-
515
- // ── Create Records ─────────────────────────────────────────────
516
-
517
- describe("platform_create_dataset_records", () => {
518
- describe("when the dataset exists", () => {
519
- /** @scenario "Add records to a dataset" */
520
- it("returns confirmation with the count of records created", async () => {
521
- const { handleCreateDatasetRecords } = await import(
522
- "../tools/create-dataset-records.js"
523
- );
524
- const result = await handleCreateDatasetRecords({
525
- slugOrId: "my-dataset",
526
- entries: [
527
- { input: "hello", output: "world" },
528
- { input: "foo", output: "bar" },
529
- ],
530
- });
531
- expect(result).toContain("2");
532
- expect(result).toContain("created");
533
- });
534
- });
535
-
536
- describe("when the dataset does not exist", () => {
537
- /** @scenario "Add records to a non-existent dataset returns an error" */
538
- it("propagates the 404 error", async () => {
539
- const { handleCreateDatasetRecords } = await import(
540
- "../tools/create-dataset-records.js"
541
- );
542
- await expect(
543
- handleCreateDatasetRecords({
544
- slugOrId: "ghost",
545
- entries: [{ input: "hello" }],
546
- }),
547
- ).rejects.toThrow("404");
548
- });
549
- });
550
- });
551
-
552
- // ── Update Record ──────────────────────────────────────────────
553
-
554
- describe("platform_update_dataset_record", () => {
555
- describe("when the record exists", () => {
556
- /** @scenario "Update a single record entry" */
557
- it("returns confirmation that the record was updated", async () => {
558
- const { handleUpdateDatasetRecord } = await import(
559
- "../tools/update-dataset-record.js"
560
- );
561
- const result = await handleUpdateDatasetRecord({
562
- slugOrId: "my-dataset",
563
- recordId: "rec-123",
564
- entry: { input: "updated" },
565
- });
566
- expect(result).toContain("updated");
567
- });
568
- });
569
-
570
- describe("when the dataset does not exist", () => {
571
- /** @scenario "Update a record in a non-existent dataset returns an error" */
572
- it("propagates the 404 error", async () => {
573
- const { handleUpdateDatasetRecord } = await import(
574
- "../tools/update-dataset-record.js"
575
- );
576
- await expect(
577
- handleUpdateDatasetRecord({
578
- slugOrId: "ghost",
579
- recordId: "rec-1",
580
- entry: { input: "x" },
581
- }),
582
- ).rejects.toThrow("404");
583
- });
584
- });
585
- });
586
-
587
- // ── Delete Records ─────────────────────────────────────────────
588
-
589
- describe("platform_delete_dataset_records", () => {
590
- describe("when the dataset exists", () => {
591
- /** @scenario "Delete records by IDs" */
592
- it("returns confirmation with the count of records deleted", async () => {
593
- const { handleDeleteDatasetRecords } = await import(
594
- "../tools/delete-dataset-records.js"
595
- );
596
- const result = await handleDeleteDatasetRecords({
597
- slugOrId: "my-dataset",
598
- recordIds: ["rec-1", "rec-2"],
599
- });
600
- expect(result).toContain("2");
601
- expect(result).toContain("deleted");
602
- });
603
- });
604
-
605
- describe("when the dataset does not exist", () => {
606
- /** @scenario "Delete records from a non-existent dataset returns an error" */
607
- it("propagates the 404 error", async () => {
608
- const { handleDeleteDatasetRecords } = await import(
609
- "../tools/delete-dataset-records.js"
610
- );
611
- await expect(
612
- handleDeleteDatasetRecords({
613
- slugOrId: "ghost",
614
- recordIds: ["rec-1"],
615
- }),
616
- ).rejects.toThrow("404");
617
- });
618
- });
619
- });
620
- });