@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,12 +1,12 @@
1
- import { AVAILABLE_EVALUATORS } from "../../../../services/langevals/ts-integration/evaluators.generated.js";
2
- import type { EvaluatorDefinition, EvaluatorTypes } from "../../../../services/langevals/ts-integration/evaluators.generated.js";
1
+ import {
2
+ AVAILABLE_EVALUATORS,
3
+ type EvaluatorDefinition,
4
+ type EvaluatorTypes,
5
+ } from "@langwatch/evaluator-contract";
3
6
 
4
7
  /**
5
- * Formats evaluator schema information for the discover_schema tool.
6
- *
7
- * Two levels of detail:
8
- * - Overview (no evaluatorType): compact list of all evaluator types
9
- * - Detail (with evaluatorType): full schema for one evaluator type
8
+ * Formats evaluator schema for discover_schema: an overview (all types,
9
+ * compact) when no evaluatorType is given, else the full schema for one.
10
10
  */
11
11
  export function formatEvaluatorSchema(evaluatorType?: string): string {
12
12
  if (evaluatorType) {
@@ -50,9 +50,22 @@ function formatEvaluatorOverview(): string {
50
50
  return lines.join("\n");
51
51
  }
52
52
 
53
+ function settingsSection(settingsEntries: [string, unknown][]): string[] {
54
+ if (settingsEntries.length === 0) return [];
55
+ const lines = ["\n## Settings\n"];
56
+ for (const [key, setting] of settingsEntries) {
57
+ const s = setting as { description?: string; default: unknown };
58
+ const defaultStr = JSON.stringify(s.default);
59
+ const desc = s.description ? ` - ${s.description}` : "";
60
+ lines.push(`- **${key}**${desc}`);
61
+ lines.push(` Default: \`${defaultStr}\``);
62
+ }
63
+ return lines;
64
+ }
65
+
53
66
  /**
54
- * Returns the full schema for a specific evaluator type.
55
- * Includes settings with descriptions and defaults, required/optional fields, env vars, and result fields.
67
+ * Returns the full schema for a specific evaluator type: settings, required/optional
68
+ * fields, env vars, and result fields.
56
69
  */
57
70
  function formatEvaluatorDetail(evaluatorType: string): string {
58
71
  const def = AVAILABLE_EVALUATORS[evaluatorType as EvaluatorTypes] as
@@ -85,18 +98,8 @@ function formatEvaluatorDetail(evaluatorType: string): string {
85
98
  lines.push(`**Optional**: ${def.optionalFields.join(", ")}`);
86
99
  }
87
100
 
88
- // Settings
89
101
  const settingsEntries = Object.entries(def.settings);
90
- if (settingsEntries.length > 0) {
91
- lines.push("\n## Settings\n");
92
- for (const [key, setting] of settingsEntries) {
93
- const s = setting as { description?: string; default: unknown };
94
- const defaultStr = JSON.stringify(s.default);
95
- const desc = s.description ? ` - ${s.description}` : "";
96
- lines.push(`- **${key}**${desc}`);
97
- lines.push(` Default: \`${defaultStr}\``);
98
- }
99
- }
102
+ lines.push(...settingsSection(settingsEntries));
100
103
 
101
104
  // Env vars
102
105
  if (def.envVars.length > 0) {
@@ -118,12 +121,18 @@ function formatEvaluatorDetail(evaluatorType: string): string {
118
121
 
119
122
  lines.push("\n## Usage Example\n");
120
123
  lines.push("```json");
121
- lines.push(JSON.stringify({
122
- evaluatorType: evaluatorType,
123
- settings: Object.fromEntries(
124
- settingsEntries.map(([key, setting]) => [key, (setting as { default: unknown }).default]),
124
+ lines.push(
125
+ JSON.stringify(
126
+ {
127
+ evaluatorType: evaluatorType,
128
+ settings: Object.fromEntries(
129
+ settingsEntries.map(([key, setting]) => [key, (setting as { default: unknown }).default]),
130
+ ),
131
+ },
132
+ null,
133
+ 2,
125
134
  ),
126
- }, null, 2));
135
+ );
127
136
  lines.push("```");
128
137
 
129
138
  return lines.join("\n");
@@ -32,7 +32,9 @@ export function formatScenarioSchema(): string {
32
32
  "A test suite reads like a dataset: it declares typed fields beyond the situation and the criteria, and every scenario filed in it carries one value per field. Declare them with `platform_create_test_suite` or `platform_update_test_suite`:",
33
33
  );
34
34
  lines.push("```json");
35
- lines.push('{ "fields": [{ "identifier": "golden_sql", "type": "text" }, { "identifier": "row_limit", "type": "number" }] }');
35
+ lines.push(
36
+ '{ "fields": [{ "identifier": "golden_sql", "type": "text" }, { "identifier": "row_limit", "type": "number" }] }',
37
+ );
36
38
  lines.push("```");
37
39
  lines.push(
38
40
  "- **identifier**: lowercase letters, digits and underscores, starting with a letter. situation, criteria, name, input and output are reserved.",
@@ -51,8 +53,12 @@ export function formatScenarioSchema(): string {
51
53
  lines.push(' "evaluatorId": "<id from platform_list_evaluators>",');
52
54
  lines.push(' "required": true,');
53
55
  lines.push(' "mappings": {');
54
- lines.push(' "output": { "type": "source", "sourceId": "trace", "path": ["tool_calls", "run_sql", "input"] },');
55
- lines.push(' "expected_output": { "type": "source", "sourceId": "scenario", "path": ["fields", "golden_sql"] }');
56
+ lines.push(
57
+ ' "output": { "type": "source", "sourceId": "trace", "path": ["tool_calls", "run_sql", "input"] },',
58
+ );
59
+ lines.push(
60
+ ' "expected_output": { "type": "source", "sourceId": "scenario", "path": ["fields", "golden_sql"] }',
61
+ );
56
62
  lines.push(" }");
57
63
  lines.push("}] }");
58
64
  lines.push("```");
@@ -60,30 +66,30 @@ export function formatScenarioSchema(): string {
60
66
  "Each mapping names where one evaluator input reads its value. Read the evaluator's inputs from `platform_get_evaluator`; every required input needs a mapping before a run. The paths:",
61
67
  );
62
68
  lines.push(
63
- "- **conversation**: `[\"first_user_message\"]`, `[\"last_agent_message\"]`, `[\"transcript\"]` (role: content lines) or `[\"messages\"]` (JSON)",
69
+ '- **conversation**: `["first_user_message"]`, `["last_agent_message"]`, `["transcript"]` (role: content lines) or `["messages"]` (JSON)',
64
70
  );
65
71
  lines.push(
66
- "- **scenario**: `[\"situation\"]`, `[\"criteria\"]` or `[\"fields\", \"<identifier>\"]` (a field the suite declares; not on a run plan)",
72
+ '- **scenario**: `["situation"]`, `["criteria"]` or `["fields", "<identifier>"]` (a field the suite declares; not on a run plan)',
67
73
  );
68
74
  lines.push(
69
- "- **trace**: `[\"contexts\"]` (the retrieved contexts of the run's traces) or `[\"tool_calls\", \"<toolName>\", \"input\" | \"output\"]` (the last matching tool call)",
70
- );
71
- lines.push(
72
- '- a literal: `{ "type": "value", "value": "..." }`',
75
+ '- **trace**: `["contexts"]` (the retrieved contexts of the run\'s traces) or `["tool_calls", "<toolName>", "input" | "output"]` (the last matching tool call)',
73
76
  );
77
+ lines.push('- a literal: `{ "type": "value", "value": "..." }`');
74
78
  lines.push(
75
79
  "A scenario whose field is blank skips the evaluators that read it, with a reason. A trace with no such tool call or no contexts fails them, with a reason. The results come back under `results.evaluations` on `platform_get_simulation_run`.",
76
80
  );
77
81
 
78
82
  lines.push("\n## Writing a Good Situation\n");
83
+ lines.push("The situation drives the user simulator. Include these elements:");
79
84
  lines.push(
80
- "The situation drives the user simulator. Include these elements:",
85
+ "- **Persona**: Who is the user? (e.g., a stressed small business owner, a confused teenager)",
81
86
  );
82
- lines.push("- **Persona**: Who is the user? (e.g., a stressed small business owner, a confused teenager)");
83
87
  lines.push("- **Emotional state**: How are they feeling? (e.g., frustrated, anxious, impatient)");
84
88
  lines.push("- **Background/Context**: What happened before this conversation?");
85
89
  lines.push("- **Intent**: What do they want to accomplish?");
86
- lines.push("- **Constraints**: What limitations do they have? (e.g., no phone for 2FA, unfamiliar with technical terms)");
90
+ lines.push(
91
+ "- **Constraints**: What limitations do they have? (e.g., no phone for 2FA, unfamiliar with technical terms)",
92
+ );
87
93
  lines.push("\nExample:");
88
94
  lines.push("```");
89
95
  lines.push("User is a small business owner stressed about tax deadline.");
@@ -94,17 +100,31 @@ export function formatScenarioSchema(): string {
94
100
  lines.push("```");
95
101
 
96
102
  lines.push("\n## Writing Good Criteria\n");
97
- lines.push("Criteria are what the judge uses to pass or fail the agent. Each criterion should be:");
98
- lines.push("- **Specific and testable** — not vague like \"responds helpfully\"");
99
- lines.push("- **Behavioral** — describes what the agent should *do*, not how it works internally");
103
+ lines.push(
104
+ "Criteria are what the judge uses to pass or fail the agent. Each criterion should be:",
105
+ );
106
+ lines.push('- **Specific and testable** — not vague like "responds helpfully"');
107
+ lines.push(
108
+ "- **Behavioral** — describes what the agent should *do*, not how it works internally",
109
+ );
100
110
  lines.push("- **Independent** — each criterion checks one thing");
101
111
  lines.push("\nGood criteria patterns:");
102
- lines.push("- **Information gathering**: \"Agent asks for the user's account number before proceeding\"");
103
- lines.push("- **Safety/guardrails**: \"Agent does not reveal internal system details or error stack traces\"");
104
- lines.push("- **Clarification**: \"Agent asks clarifying questions before taking irreversible action\"");
105
- lines.push("- **Tone**: \"Agent maintains a professional and empathetic tone throughout\"");
106
- lines.push("- **Completeness**: \"Agent confirms the user understands the solution before ending\"");
107
- lines.push("- **Domain-specific**: \"Agent recommends releasing a wild frog rather than keeping it as a pet\"");
112
+ lines.push(
113
+ '- **Information gathering**: "Agent asks for the user\'s account number before proceeding"',
114
+ );
115
+ lines.push(
116
+ '- **Safety/guardrails**: "Agent does not reveal internal system details or error stack traces"',
117
+ );
118
+ lines.push(
119
+ '- **Clarification**: "Agent asks clarifying questions before taking irreversible action"',
120
+ );
121
+ lines.push('- **Tone**: "Agent maintains a professional and empathetic tone throughout"');
122
+ lines.push(
123
+ '- **Completeness**: "Agent confirms the user understands the solution before ending"',
124
+ );
125
+ lines.push(
126
+ '- **Domain-specific**: "Agent recommends releasing a wild frog rather than keeping it as a pet"',
127
+ );
108
128
  lines.push("\nAvoid vague criteria like:");
109
129
  lines.push('- "Responds correctly" — correct how?');
110
130
  lines.push('- "Is helpful" — helpful in what way?');
@@ -1,25 +1,39 @@
1
- import { filterFields } from "../schemas/filter-fields.js";
2
- import { analyticsMetrics } from "../schemas/analytics-metrics.js";
3
- import { analyticsGroups } from "../schemas/analytics-groups.js";
1
+ import { getQueryReference, type QueryReferenceResponse } from "../langwatch-api-query.ts";
2
+ import { analyticsGroups } from "../schemas/analytics-groups.ts";
3
+ import { analyticsMetrics } from "../schemas/analytics-metrics.ts";
4
+ import { markdownTable } from "../utils/markdown-table.ts";
4
5
 
5
- export type Category =
6
- | "filters"
7
- | "metrics"
8
- | "aggregations"
9
- | "groups"
10
- | "all";
6
+ export type Category = "filters" | "lwql" | "metrics" | "aggregations" | "groups" | "all";
11
7
 
12
8
  /**
13
- * Formats the LangWatch analytics schema into human-readable markdown.
14
- *
15
- * Returns documentation for the requested category of schema elements
16
- * (filter fields, metrics, aggregation types, or group-by options).
9
+ * Categories the platform answers, not this package — which is why
10
+ * `formatSchema` is async: they are read from `GET /api/v1/query/reference`
11
+ * and need the API key.
17
12
  */
18
- export function formatSchema(category: Category): string {
13
+ const PLATFORM_BACKED: ReadonlySet<Category> = new Set(["filters", "lwql", "all"]);
14
+
15
+ export function needsQueryReference(category: Category): boolean {
16
+ return PLATFORM_BACKED.has(category);
17
+ }
18
+
19
+ /**
20
+ * Formats the LangWatch query schema into markdown an agent can act on.
21
+ * `reference` is required for the platform-backed categories and ignored by
22
+ * the others, so a caller that fetched it once can reuse it.
23
+ */
24
+ export async function formatSchema(
25
+ category: Category,
26
+ reference?: QueryReferenceResponse,
27
+ ): Promise<string> {
19
28
  const sections: string[] = [];
29
+ const resolved =
30
+ needsQueryReference(category) && !reference ? await getQueryReference() : reference;
20
31
 
21
32
  if (category === "filters" || category === "all") {
22
- sections.push(formatFilters());
33
+ sections.push(formatFilters(resolved));
34
+ }
35
+ if (category === "lwql" || category === "all") {
36
+ sections.push(formatLangWatchQL(resolved));
23
37
  }
24
38
  if (category === "metrics" || category === "all") {
25
39
  sections.push(formatMetrics());
@@ -30,30 +44,140 @@ export function formatSchema(category: Category): string {
30
44
  if (category === "groups" || category === "all") {
31
45
  sections.push(formatGroups());
32
46
  }
47
+ if (category === "all" && resolved) {
48
+ sections.push(formatDecisionTable(resolved));
49
+ }
33
50
 
34
51
  return sections.join("\n\n");
35
52
  }
36
53
 
37
- function formatFilters(): string {
38
- const lines = ["## Available Filter Fields", ""];
54
+ /** What the field's values column says: the closed set, or where to read an open one. */
55
+ const knownValuesCell = (field: { knownValues: readonly string[]; facetable: boolean }): string => {
56
+ if (field.knownValues.length > 0) return field.knownValues.join(", ");
57
+ return field.facetable ? "open set, read them from GET /api/v1/traces/facets" : "";
58
+ };
59
+
60
+ function formatFilters(reference?: QueryReferenceResponse): string {
61
+ if (!reference) {
62
+ return "## Trace Filter Fields\n\nUnavailable: the platform could not be reached.";
63
+ }
64
+ const lines = ["## Trace Filter Fields", ""];
65
+ lines.push(
66
+ "Send one of these as the `filter` parameter of `search_traces`, in the language the Trace Explorer's search bar speaks: `status:error AND model:gpt-*`.",
67
+ );
68
+ lines.push(
69
+ "The `filters` parameter is the older per-field map and still works; both are combined when you send both.",
70
+ );
71
+ lines.push("");
72
+ lines.push(
73
+ markdownTable({
74
+ headers: ["Field", "Type", "Group", "Known values"],
75
+ rows: reference.traceFilter.fields.map((field) => ({
76
+ Field: field.name,
77
+ Type: field.valueType,
78
+ Group: field.group ?? "",
79
+ "Known values": knownValuesCell(field),
80
+ })),
81
+ }),
82
+ );
83
+ lines.push("");
84
+ lines.push("### Attribute namespaces", "");
39
85
  lines.push(
40
- "Use these in the `filters` parameter of `search_traces` and `get_analytics`."
86
+ markdownTable({
87
+ headers: ["Prefix", "Matches", "Older spellings"],
88
+ rows: reference.traceFilter.dynamicPrefixes.map((prefix) => ({
89
+ Prefix: `${prefix.prefix}<key>`,
90
+ Matches: prefix.description,
91
+ "Older spellings": prefix.aliases.join(", "),
92
+ })),
93
+ }),
41
94
  );
42
- lines.push('Format: `{ "field_name": ["value1", "value2"] }`');
43
95
  lines.push("");
44
- for (const f of filterFields) {
96
+ lines.push("### Syntax", "");
97
+ lines.push(reference.traceFilter.syntax);
98
+ lines.push("");
99
+ lines.push("### Worked filters", "");
100
+ for (const example of reference.examples.filter(
101
+ (candidate) => candidate.language === "trace-filter",
102
+ )) {
103
+ lines.push(`- \`${example.text}\` — ${example.title}`);
104
+ }
105
+ return lines.join("\n");
106
+ }
107
+
108
+ function formatLangWatchQL(reference?: QueryReferenceResponse): string {
109
+ if (!reference) {
110
+ return "## Analytics SQL\n\nUnavailable: the platform could not be reached.";
111
+ }
112
+ if (!reference.lwql.enabled) {
113
+ return [
114
+ "## Analytics SQL",
115
+ "",
116
+ "Not enabled for this project, so `run_query` will refuse. Use `search_traces` and `get_analytics` instead.",
117
+ ].join("\n");
118
+ }
119
+ const lines = ["## Analytics SQL", ""];
120
+ lines.push(
121
+ "Run one read-only SELECT with `run_query`. The statement is executed as written: nothing rewrites it.",
122
+ );
123
+ lines.push(
124
+ `Ceilings: ${reference.lwql.limits.maxRowsReturned} rows, ${reference.lwql.limits.maxExecutionTimeSeconds} seconds. ${reference.lwql.limits.pagination}`,
125
+ );
126
+ lines.push("");
127
+ for (const view of reference.lwql.schema.views) {
128
+ lines.push(`### ${view.name}`);
129
+ lines.push(`${view.description} One row is: ${view.grain}`);
130
+ lines.push(
131
+ `Filter on \`${view.timeColumn}\` to prune partitions. Join keys: ${view.joinKeys.join(", ") || "none"}.`,
132
+ );
133
+ lines.push("");
45
134
  lines.push(
46
- `- **${f.field}**: ${f.description}${f.example ? ` (e.g., \`${f.example}\`)` : ""}`
135
+ markdownTable({
136
+ headers: ["Column", "Type", "Available", "Description"],
137
+ rows: view.columns.map((column) => ({
138
+ Column: column.name,
139
+ Type: column.type,
140
+ Available: column.available ? "yes" : `needs ${column.gates.join(", ")}`,
141
+ Description: column.description,
142
+ })),
143
+ }),
47
144
  );
145
+ lines.push("");
146
+ }
147
+ lines.push("### Worked statements", "");
148
+ for (const example of reference.examples.filter((candidate) => candidate.language === "lwql")) {
149
+ lines.push(
150
+ `**${example.title}**${example.available ? "" : ` (needs ${example.requires.gates.join(", ")})`}`,
151
+ );
152
+ lines.push("```sql");
153
+ lines.push(example.text);
154
+ lines.push("```");
155
+ for (const parameter of example.parameters) {
156
+ lines.push(`- \`{${parameter.name}:${parameter.type}}\` — ${parameter.description}`);
157
+ }
158
+ lines.push("");
48
159
  }
49
160
  return lines.join("\n");
50
161
  }
51
162
 
52
- function formatMetrics(): string {
53
- const lines = ["## Available Metrics", ""];
163
+ function formatDecisionTable(reference: QueryReferenceResponse): string {
164
+ const lines = ["## Which one to reach for", ""];
54
165
  lines.push(
55
- "Use these in `get_analytics` as `metric` parameter in `category.name` format."
166
+ markdownTable({
167
+ headers: ["When you want", "Use", "Why"],
168
+ rows: reference.decisionTable.map((row) => ({
169
+ "When you want": row.when,
170
+ Use: row.use,
171
+ Why: row.why,
172
+ })),
173
+ }),
56
174
  );
175
+ return lines.join("\n");
176
+ }
177
+
178
+ function formatMetrics(): string {
179
+ const lines = ["## Available Metrics", ""];
180
+ lines.push("Use these in `get_analytics` as `metric` parameter in `category.name` format.");
57
181
  lines.push("");
58
182
 
59
183
  const byCategory = new Map<string, typeof analyticsMetrics>();
@@ -95,9 +219,7 @@ function formatAggregations(): string {
95
219
 
96
220
  function formatGroups(): string {
97
221
  const lines = ["## Available Group-By Options", ""];
98
- lines.push(
99
- "Use these in the `groupBy` parameter of `get_analytics`."
100
- );
222
+ lines.push("Use these in the `groupBy` parameter of `get_analytics`.");
101
223
  lines.push("");
102
224
  for (const g of analyticsGroups) {
103
225
  lines.push(`- **${g.name}** (${g.label}): ${g.description}`);
@@ -15,16 +15,10 @@ export interface RunTimestamps {
15
15
  stoppedAt?: number | null;
16
16
  }
17
17
 
18
- export const deriveRunStatus = (
19
- timestamps: RunTimestamps,
20
- now: number = Date.now(),
21
- ): RunStatus => {
18
+ export const deriveRunStatus = (timestamps: RunTimestamps, now: number = Date.now()): RunStatus => {
22
19
  if (timestamps.stoppedAt != null) return "stopped";
23
20
  if (timestamps.finishedAt != null) return "completed";
24
- if (
25
- timestamps.updatedAt != null &&
26
- now - timestamps.updatedAt > INTERRUPTED_THRESHOLD_MS
27
- ) {
21
+ if (timestamps.updatedAt != null && now - timestamps.updatedAt > INTERRUPTED_THRESHOLD_MS) {
28
22
  return "interrupted";
29
23
  }
30
24
  return "running";
@@ -1,16 +1,11 @@
1
- import type { DatasetMutationResponse } from "../langwatch-api-datasets.js";
2
- import { escapeMarkdown } from "../utils/escape-markdown.js";
1
+ import type { DatasetMutationResponse } from "../langwatch-api-datasets.ts";
2
+ import { escapeMarkdown } from "../utils/escape-markdown.ts";
3
3
 
4
4
  /**
5
- * Formats the common detail lines for a dataset mutation response
6
- * (name, slug, id, and column types).
7
- *
8
- * Used by both create-dataset and update-dataset handlers to avoid
9
- * duplicating the formatting logic.
5
+ * Formats the common detail lines (name, slug, id, column types) for a
6
+ * dataset mutation response, shared by create-dataset and update-dataset.
10
7
  */
11
- export function formatDatasetMutationDetails(
12
- result: DatasetMutationResponse,
13
- ): string[] {
8
+ export function formatDatasetMutationDetails(result: DatasetMutationResponse): string[] {
14
9
  const lines: string[] = [];
15
10
  lines.push(`**Name**: ${escapeMarkdown(result.name)}`);
16
11
  lines.push(`**Slug**: ${escapeMarkdown(result.slug)}`);
@@ -1,14 +1,9 @@
1
- import type {
2
- RunPlanRunResult,
3
- RunPlanScope,
4
- } from "../langwatch-api-run-plans.js";
1
+ import type { RunPlanRunResult, RunPlanScope } from "../langwatch-api-run-plans.ts";
5
2
 
6
3
  /**
7
4
  * The digest every run of a plan returns, whichever tool started it.
8
- *
9
- * It says which plan ran and whether the run created it or joined one that
10
- * already carried the name, because that is the difference between a new plan
11
- * and a plan whose configuration this run just replaced.
5
+ * Says whether the run created the plan or joined one that already
6
+ * carried the name — a new plan vs. one this run just reconfigured.
12
7
  */
13
8
  export function formatRunPlanRun(result: RunPlanRunResult): string {
14
9
  const lines: string[] = [];
@@ -25,21 +20,15 @@ export function formatRunPlanRun(result: RunPlanRunResult): string {
25
20
  lines.push(`**Jobs**: ${result.jobCount}`);
26
21
 
27
22
  if (result.skippedArchived.scenarios.length > 0) {
28
- lines.push(
29
- `**Skipped archived scenarios**: ${result.skippedArchived.scenarios.join(", ")}`,
30
- );
23
+ lines.push(`**Skipped archived scenarios**: ${result.skippedArchived.scenarios.join(", ")}`);
31
24
  }
32
25
  if (result.skippedArchived.targets.length > 0) {
33
- lines.push(
34
- `**Skipped archived targets**: ${result.skippedArchived.targets.join(", ")}`,
35
- );
26
+ lines.push(`**Skipped archived targets**: ${result.skippedArchived.targets.join(", ")}`);
36
27
  }
37
28
 
38
29
  lines.push(`**View**: ${result.platformUrl}`);
39
30
  lines.push("");
40
- lines.push(
41
- "> Use `platform_list_simulation_runs` with the batch run ID to read the results.",
42
- );
31
+ lines.push("> Use `platform_list_simulation_runs` with the batch run ID to read the results.");
43
32
 
44
33
  return lines.join("\n");
45
34
  }
@@ -48,10 +37,7 @@ export function formatRunPlanRun(result: RunPlanRunResult): string {
48
37
  * One line saying what a plan covers. A plan stored before scopes existed
49
38
  * carries none, and runs the scenario list it already held.
50
39
  */
51
- export function describeRunPlanScope(
52
- scope: RunPlanScope | null,
53
- scenarioIds: string[],
54
- ): string {
40
+ export function describeRunPlanScope(scope: RunPlanScope | null, scenarioIds: string[]): string {
55
41
  if (scope === null) {
56
42
  return `hand-picked scenarios (${scenarioIds.length})`;
57
43
  }
@@ -1,9 +1,7 @@
1
- import type { ScenarioFieldValues } from "../schemas/suite-fields.js";
1
+ import type { ScenarioFieldValues } from "../schemas/suite-fields.ts";
2
2
 
3
3
  /** The digest lines for the values a scenario carries per suite field. */
4
- export function formatScenarioFields(
5
- fields: ScenarioFieldValues | undefined,
6
- ): string[] {
4
+ export function formatScenarioFields(fields: ScenarioFieldValues | undefined): string[] {
7
5
  if (!fields || Object.keys(fields).length === 0) return [];
8
6
  return [
9
7
  "\n## Fields",
@@ -2,7 +2,7 @@ import type {
2
2
  EvaluatorAttachmentWire,
3
3
  ScenarioMapping,
4
4
  SuiteField,
5
- } from "../schemas/suite-fields.js";
5
+ } from "../schemas/suite-fields.ts";
6
6
 
7
7
  /**
8
8
  * The digest lines for a suite's fields, the evaluators attached to a suite
@@ -19,10 +19,7 @@ export function describeMapping(mapping: ScenarioMapping): string {
19
19
 
20
20
  export function formatSuiteFields(fields: SuiteField[] | undefined): string[] {
21
21
  if (!fields || fields.length === 0) return [];
22
- return [
23
- "\n## Fields",
24
- ...fields.map((field) => `- ${field.identifier} (${field.type})`),
25
- ];
22
+ return ["\n## Fields", ...fields.map((field) => `- ${field.identifier} (${field.type})`)];
26
23
  }
27
24
 
28
25
  export function formatEvaluatorAttachments(
@@ -41,10 +38,9 @@ export function formatEvaluatorAttachments(
41
38
  }
42
39
 
43
40
  /**
44
- * The status the platform reports while a run's evaluators have not been
45
- * recorded yet. The conversation is over and the judge has decided, but a
46
- * required evaluator can still turn the run red, so a caller must not read
47
- * the verdict as final.
41
+ * Reported while a run's evaluators haven't recorded yet: the judge has
42
+ * decided, but a required evaluator can still turn the run red — a
43
+ * caller must not read this as final.
48
44
  */
49
45
  export const PENDING_EVALUATION_STATUS = "PENDING_EVALUATION";
50
46
 
@@ -79,9 +75,7 @@ export interface SimulationRunEvaluation {
79
75
  details?: string;
80
76
  }
81
77
 
82
- export function formatEvaluations(
83
- evaluations: SimulationRunEvaluation[] | undefined,
84
- ): string[] {
78
+ export function formatEvaluations(evaluations: SimulationRunEvaluation[] | undefined): string[] {
85
79
  if (!evaluations || evaluations.length === 0) return [];
86
80
  const lines = ["\n## Evaluators"];
87
81
  for (const evaluation of evaluations) {
@@ -1,4 +1,8 @@
1
- import { getAgent as apiGetAgent, type AgentParameterSpec } from "../langwatch-api-agents.js";
1
+ import {
2
+ getAgent as apiGetAgent,
3
+ type AgentInstance,
4
+ type AgentParameterSpec,
5
+ } from "../langwatch-api-agents.ts";
2
6
 
3
7
  export const describeParameter = ({
4
8
  name,
@@ -16,6 +20,15 @@ export const describeParameter = ({
16
20
  return `- **${name}** (${parts.join(", ")})${suffix}`;
17
21
  };
18
22
 
23
+ function instancesSection(instances: AgentInstance[]): string[] {
24
+ const lines = [`\n## Instances (${instances.length})\n`];
25
+ for (const instance of instances) {
26
+ const label = instance.label ? ` (${instance.label})` : "";
27
+ lines.push(`- ${instance.hostname || instance.id}${label}, connected ${instance.connectedAt}`);
28
+ }
29
+ return lines;
30
+ }
31
+
19
32
  /**
20
33
  * Handles the platform_get_agent MCP tool invocation.
21
34
  *
@@ -45,11 +58,7 @@ export async function handleGetAgent({ id }: { id: string }): Promise<string> {
45
58
  }
46
59
 
47
60
  if (agent.instances && agent.instances.length > 0) {
48
- lines.push(`\n## Instances (${agent.instances.length})\n`);
49
- for (const instance of agent.instances) {
50
- const label = instance.label ? ` (${instance.label})` : "";
51
- lines.push(`- ${instance.hostname || instance.id}${label}, connected ${instance.connectedAt}`);
52
- }
61
+ lines.push(...instancesSection(agent.instances));
53
62
  }
54
63
 
55
64
  if (agent.config && Object.keys(agent.config).length > 0) {