@langwatch/mcp-server 2.1.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitignore +7 -0
- package/.npmignore +41 -0
- package/CHANGELOG.md +218 -201
- package/CONTRIBUTING.md +10 -0
- package/README.md +70 -68
- package/dist/add-dashboard-widget-55UI6H22.js +44 -0
- package/dist/add-dashboard-widget-MJHIC3CC.js +45 -0
- package/dist/{archive-project-W3IKI7UL.js → archive-project-K5UD7A6X.js} +4 -4
- package/dist/archive-project-L4PAKT34.js +19 -0
- package/dist/{archive-run-plan-474OKHHU.js → archive-run-plan-5HSQG2HX.js} +4 -4
- package/dist/archive-run-plan-AOKNYQIO.js +15 -0
- package/dist/archive-scenario-2CWJW2VD.js +19 -0
- package/dist/{archive-scenario-V5UNYK26.js → archive-scenario-5IJQESHH.js} +4 -4
- package/dist/{archive-test-suite-O7FLDMXK.js → archive-test-suite-OPB7NFI7.js} +4 -4
- package/dist/archive-test-suite-ZC3TN6VH.js +15 -0
- package/dist/assign-prompt-tag-6DDE6ZZ5.js +23 -0
- package/dist/{assign-prompt-tag-Q46WRB6P.js → assign-prompt-tag-D7O23MJM.js} +8 -4
- package/dist/chunk-3YLN3ATJ.js +241 -0
- package/dist/{chunk-EYXMLE5X.js → chunk-4RX3G62A.js} +56 -47
- package/dist/{chunk-UF6XIGYR.js → chunk-6YZUOD34.js} +2 -5
- package/dist/{chunk-WVI5CJ6S.js → chunk-7AQLPVFL.js} +2 -2
- package/dist/chunk-7CZQDZ2K.js +319 -0
- package/dist/{chunk-RVAE2MEA.js → chunk-7GETGE6B.js} +7 -7
- package/dist/{chunk-OJLYYJWI.js → chunk-AASW2TO2.js} +7 -10
- package/dist/{chunk-QAMP3CGR.js → chunk-B4RFWIUP.js} +4 -4
- package/dist/{chunk-ZXKLPC2E.js → chunk-BIIKE3EI.js} +1 -1
- package/dist/{chunk-G4ZAZTZW.js → chunk-D2HS73VI.js} +7 -10
- package/dist/{chunk-37SMPMQS.js → chunk-DMM3JQ42.js} +7 -2
- package/dist/{chunk-WT4PO4A3.js → chunk-DULFP3MK.js} +10 -7
- package/dist/chunk-EYPJBL7P.js +516 -0
- package/dist/{chunk-NUFPTHKU.js → chunk-FOKVY3BK.js} +1 -1
- package/dist/chunk-GA5JUSPT.js +64 -0
- package/dist/{chunk-UJPXFA26.js → chunk-HHMNZAPD.js} +101 -74
- package/dist/chunk-HLQJXUR6.js +67 -0
- package/dist/{chunk-JTQJRNFJ.js → chunk-KILVK3FS.js} +4 -4
- package/dist/chunk-MOCU5XWF.js +79 -0
- package/dist/chunk-O2WGVCED.js +41 -0
- package/dist/{chunk-HV4DWKBI.js → chunk-O7EMWEVJ.js} +2 -4
- package/dist/{chunk-UFOYFYI7.js → chunk-QXLMHLRC.js} +6 -9
- package/dist/{chunk-QRO35SOM.js → chunk-R5YJIYPF.js} +981 -747
- package/dist/{chunk-JR6DJZOU.js → chunk-RABYBFX5.js} +4 -10
- package/dist/{chunk-SR6QPRIE.js → chunk-RFC2SBEX.js} +7 -13
- package/dist/chunk-SHSVN3SE.js +21 -0
- package/dist/{chunk-CKNAH5TG.js → chunk-U24EACC4.js} +3 -10
- package/dist/{chunk-56OGTS24.js → chunk-VOUGDY2O.js} +4 -11
- package/dist/chunk-WCKZDOGF.js +31 -0
- package/dist/chunk-XQYH52SI.js +129 -0
- package/dist/{chunk-7E4FZIYJ.js → chunk-XUIJYNRJ.js} +1 -1
- package/dist/{chunk-6DJDEXET.js → chunk-YCIUEZVK.js} +6 -12
- package/dist/config-2WQGMAEN.js +16 -0
- package/dist/config.cjs +109 -0
- package/dist/config.js +5 -4
- package/dist/{create-agent-JFJ2K6X3.js → create-agent-6JNLMYQD.js} +4 -4
- package/dist/create-agent-IRZOU4R5.js +23 -0
- package/dist/create-analytics-report-N4L4V5QL.js +19 -0
- package/dist/create-analytics-report-QEHXG7FU.js +18 -0
- package/dist/{create-annotation-EUXXQ6NS.js → create-annotation-CCEGIZ67.js} +10 -5
- package/dist/create-annotation-DTHCMWHB.js +29 -0
- package/dist/{create-api-key-BGBB76JX.js → create-api-key-JKM2DSZO.js} +5 -7
- package/dist/create-api-key-JPEUIXGM.js +24 -0
- package/dist/create-dataset-DJNXYJ5B.js +22 -0
- package/dist/{create-dataset-FD5VAXU4.js → create-dataset-WON4SOTC.js} +6 -6
- package/dist/create-dataset-records-TMEOTLTO.js +20 -0
- package/dist/{create-dataset-records-WQUXXOHI.js → create-dataset-records-UJBW3C7C.js} +5 -7
- package/dist/create-evaluator-N5AEHI4K.js +27 -0
- package/dist/{create-evaluator-6NV33Z52.js → create-evaluator-XYNY2YFY.js} +4 -4
- package/dist/create-mcp-server.cjs +9712 -0
- package/dist/create-mcp-server.js +2757 -10
- package/dist/{create-project-ZQ7TFIO2.js → create-project-EY4XZ7TH.js} +4 -4
- package/dist/create-project-YL345T5L.js +44 -0
- package/dist/{create-prompt-BS6QRCUU.js → create-prompt-JZQNQ7I3.js} +5 -7
- package/dist/create-prompt-ZUMQHHX7.js +37 -0
- package/dist/create-prompt-tag-CJ5FZ436.js +17 -0
- package/dist/{create-prompt-tag-FCQ5ELSQ.js → create-prompt-tag-JFP2Q3PO.js} +3 -3
- package/dist/create-scenario-CQU2SSFB.js +33 -0
- package/dist/{create-scenario-DRPTPXU3.js → create-scenario-S6OWWKJO.js} +5 -5
- package/dist/create-test-suite-OLGCAGJA.js +36 -0
- package/dist/{create-test-suite-ZIZCCFJ4.js → create-test-suite-Y7P2RI4L.js} +6 -6
- package/dist/create-trigger-4CNBTISJ.js +48 -0
- package/dist/create-trigger-RQ653WYF.js +49 -0
- package/dist/dashboards-BA7M6CMO.js +90 -0
- package/dist/dashboards-U663GUIB.js +91 -0
- package/dist/{delete-agent-SA4JMUZF.js → delete-agent-J2Q4DRZ2.js} +4 -4
- package/dist/delete-agent-ZAU4LTXB.js +18 -0
- package/dist/delete-analytics-report-QK6X7P4S.js +19 -0
- package/dist/delete-analytics-report-YUYLDHLL.js +18 -0
- package/dist/delete-annotation-7X4NYXXM.js +17 -0
- package/dist/{delete-annotation-X3KKK7QY.js → delete-annotation-KJOCDLV3.js} +4 -4
- package/dist/{delete-dataset-W6EZ44HY.js → delete-dataset-NXP7ZPPV.js} +5 -7
- package/dist/delete-dataset-RUTZBBVD.js +18 -0
- package/dist/{delete-dataset-records-7CNOTALB.js → delete-dataset-records-4Z7DZCDW.js} +5 -7
- package/dist/delete-dataset-records-75UAR5IS.js +19 -0
- package/dist/delete-evaluator-E3CUNGTQ.js +16 -0
- package/dist/delete-evaluator-RI4GALGX.js +15 -0
- package/dist/delete-prompt-tag-LE3WJPKS.js +17 -0
- package/dist/{delete-prompt-tag-QB3OCZUV.js → delete-prompt-tag-S4KBZTNG.js} +3 -3
- package/dist/delete-workflow-4CZFIQCQ.js +17 -0
- package/dist/{delete-workflow-NG2VXYYM.js → delete-workflow-PWQPDW6H.js} +4 -4
- package/dist/discover-evaluator-schema-UHWA5HVL.js +120 -0
- package/dist/discover-evaluator-schema-XKCLLCB3.js +118 -0
- package/dist/discover-scenario-schema-NOJY6S7E.js +137 -0
- package/dist/{discover-scenario-schema-W7KBXA4J.js → discover-scenario-schema-OOFIQKOG.js} +37 -17
- package/dist/discover-schema-7WHIIATI.js +442 -0
- package/dist/{discover-schema-L6QDPON3.js → discover-schema-J2ANOBKO.js} +181 -186
- package/dist/get-agent-5T3CXQOR.js +69 -0
- package/dist/{get-agent-7THF7HCU.js → get-agent-ZKYQJUQ7.js} +15 -11
- package/dist/get-analytics-4MPEK4KV.js +79 -0
- package/dist/get-analytics-ZLI3A4F5.js +80 -0
- package/dist/get-analytics-report-JCKYMA2S.js +29 -0
- package/dist/get-analytics-report-SKIP2JWH.js +30 -0
- package/dist/get-dataset-APGZBYMH.js +64 -0
- package/dist/get-dataset-LWXDVMVE.js +63 -0
- package/dist/get-evaluator-3A7BJBAB.js +47 -0
- package/dist/{get-evaluator-RZ44UIN6.js → get-evaluator-IWNJINRY.js} +4 -4
- package/dist/get-project-EQVB4LEL.js +26 -0
- package/dist/{get-project-QSQEAB33.js → get-project-RK6AJTEP.js} +4 -4
- package/dist/{get-prompt-GVKXF5NL.js → get-prompt-TLG2T2DS.js} +53 -58
- package/dist/get-prompt-ZER557X3.js +94 -0
- package/dist/get-run-plan-5X7DDJRN.js +58 -0
- package/dist/{get-run-plan-NY7J5GRE.js → get-run-plan-PEHRO5M3.js} +7 -9
- package/dist/{get-scenario-Q3LLQE4T.js → get-scenario-375W5D6I.js} +5 -5
- package/dist/get-scenario-UQX45ZZO.js +37 -0
- package/dist/{get-simulation-run-WINEYDMK.js → get-simulation-run-2NBXJADG.js} +26 -22
- package/dist/get-simulation-run-QZTLGL7W.js +69 -0
- package/dist/{get-test-suite-4HKA7OKS.js → get-test-suite-GVIBDG7K.js} +5 -5
- package/dist/get-test-suite-OODIR3RI.js +48 -0
- package/dist/{get-trace-RCUV7N4O.js → get-trace-AGCHVPJK.js} +11 -13
- package/dist/get-trace-KJLYAZRC.js +45 -0
- package/dist/get-workflow-3TV2YYC5.js +25 -0
- package/dist/{get-workflow-EEOC7Y45.js → get-workflow-7LZSVPP2.js} +4 -4
- package/dist/{http-security-EU3CHTY7.js → http-security-DNLBNQZL.js} +2 -2
- package/dist/{http-server-WCDUARTH.js → http-server-7CCN3EHJ.js} +4249 -325
- package/dist/index.js +59595 -38027
- package/dist/langwatch-api-analytics-reports-6CF6KUET.js +17 -0
- package/dist/langwatch-api-analytics-reports-RPFB5AO5.js +18 -0
- package/dist/{langwatch-api-annotations-6DHVZWUK.js → langwatch-api-annotations-H4AI4TKG.js} +4 -4
- package/dist/langwatch-api-annotations-QSJNUQQS.js +17 -0
- package/dist/langwatch-api-monitors-ENHLOL3S.js +47 -0
- package/dist/{langwatch-api-monitors-6ISFJ7WX.js → langwatch-api-monitors-OHSGADTH.js} +11 -16
- package/dist/langwatch-api-secrets-AGW6UUMD.js +55 -0
- package/dist/langwatch-api-secrets-CLTS766Q.js +56 -0
- package/dist/langwatch-api-triggers-G5UWFNN2.js +22 -0
- package/dist/langwatch-api-triggers-QMR7KEXW.js +23 -0
- package/dist/langwatch-api-workflows-HKTBIKKY.js +15 -0
- package/dist/{langwatch-api-workflows-6UJL5U4Z.js → langwatch-api-workflows-OMROZH2O.js} +4 -4
- package/dist/{list-agents-AMVDQPQL.js → list-agents-BYWDNAHT.js} +4 -4
- package/dist/list-agents-MG24MHZE.js +42 -0
- package/dist/list-analytics-reports-G3EPWGSQ.js +32 -0
- package/dist/list-analytics-reports-PPWIFRES.js +33 -0
- package/dist/list-annotations-QCLGEK5A.js +38 -0
- package/dist/{list-annotations-6PR5NLIC.js → list-annotations-Y4EUBJHG.js} +10 -5
- package/dist/list-api-keys-DAVOBPFK.js +42 -0
- package/dist/{list-api-keys-GVPNBIHQ.js → list-api-keys-JMW5WRXX.js} +10 -5
- package/dist/list-dashboards-2P3VJFRS.js +29 -0
- package/dist/list-dashboards-MW5O3MKH.js +30 -0
- package/dist/list-dataset-records-KEHT7G6Q.js +43 -0
- package/dist/{list-dataset-records-O67HZ35Y.js → list-dataset-records-KMLLMZAZ.js} +14 -10
- package/dist/{list-datasets-WXZL6UMP.js → list-datasets-P3JK2ZHS.js} +9 -13
- package/dist/list-datasets-Z7OOE4KI.js +56 -0
- package/dist/{list-evaluators-PAX72WCN.js → list-evaluators-7RRESBOU.js} +5 -7
- package/dist/list-evaluators-VATJVOHR.js +32 -0
- package/dist/{list-model-providers-VVLZMLCX.js → list-model-providers-OXDRPUCJ.js} +4 -4
- package/dist/list-model-providers-VXQJWDXU.js +35 -0
- package/dist/{list-projects-AQVI6SUK.js → list-projects-HUVK7L3W.js} +5 -7
- package/dist/list-projects-X72ZXVY5.js +40 -0
- package/dist/{list-prompt-tags-WZFBJOHG.js → list-prompt-tags-3I3LWFIR.js} +3 -3
- package/dist/list-prompt-tags-DRHUH2ND.js +23 -0
- package/dist/list-prompts-6DX3QECJ.js +30 -0
- package/dist/{list-prompts-BQOHRHYT.js → list-prompts-PS423RU3.js} +4 -6
- package/dist/list-run-plans-5SXPOV3X.js +45 -0
- package/dist/{list-run-plans-UBAU2DGH.js → list-run-plans-6VNHINPY.js} +5 -5
- package/dist/list-scenarios-EQWCW7Q4.js +45 -0
- package/dist/{list-scenarios-MS4IUIVM.js → list-scenarios-GKNH3YND.js} +13 -11
- package/dist/{list-simulation-runs-D6YF4ZOU.js → list-simulation-runs-KHY7KALI.js} +12 -8
- package/dist/list-simulation-runs-PUDK32C2.js +53 -0
- package/dist/list-test-suites-7H2DRILK.js +34 -0
- package/dist/{list-test-suites-L7R2O6DR.js → list-test-suites-GY56LGLY.js} +4 -4
- package/dist/list-trigger-fires-7RZUP54Y.js +19 -0
- package/dist/list-trigger-fires-OZUF65LI.js +20 -0
- package/dist/list-triggers-BGUCUXTJ.js +45 -0
- package/dist/list-triggers-XC5KMX4C.js +46 -0
- package/dist/list-workflows-55NYC3PC.js +33 -0
- package/dist/{list-workflows-6MV4XJHF.js → list-workflows-HV7FUWZA.js} +5 -7
- package/dist/{rename-prompt-tag-K5LQ4CY6.js → rename-prompt-tag-2I7Z5FCY.js} +3 -3
- package/dist/rename-prompt-tag-SZYTOWDX.js +18 -0
- package/dist/{rename-test-suite-NTYHAO5X.js → rename-test-suite-27AYY33K.js} +4 -4
- package/dist/rename-test-suite-CLIEPZDO.js +20 -0
- package/dist/report-issue-5HSL7CNB.js +924 -0
- package/dist/{report-issue-RHZZ33IS.js → report-issue-N7ND5TM6.js} +107 -67
- package/dist/{rerun-run-plan-MUDWJBE4.js → rerun-run-plan-O3VUZ6CG.js} +5 -5
- package/dist/rerun-run-plan-OJTVVGJI.js +21 -0
- package/dist/{revoke-api-key-6LAZ3QZZ.js → revoke-api-key-BU6BKGCG.js} +4 -4
- package/dist/revoke-api-key-NZNCFOIR.js +15 -0
- package/dist/run-agent-244O4Y5M.js +75 -0
- package/dist/run-agent-HPCGZGYW.js +74 -0
- package/dist/run-plan-2ZPGGZ4H.js +38 -0
- package/dist/{run-plan-T4ZYOZGA.js → run-plan-KSXUYQT3.js} +7 -7
- package/dist/run-query-4LMOQ5UW.js +47 -0
- package/dist/run-query-BQUHIUC2.js +46 -0
- package/dist/{run-test-suite-L4MZ7G4D.js → run-test-suite-P3WLVPXC.js} +6 -6
- package/dist/run-test-suite-UEOMCON6.js +25 -0
- package/dist/run-workflow-EFZ6HG5B.js +36 -0
- package/dist/{run-workflow-DFIS23AP.js → run-workflow-I4IHEN54.js} +4 -4
- package/dist/search-traces-6IR7PR4L.js +170 -0
- package/dist/search-traces-BYML2NQ4.js +171 -0
- package/dist/set-model-provider-RBNGWFVI.js +33 -0
- package/dist/{set-model-provider-XRNMFOVR.js → set-model-provider-SHEVKWRC.js} +4 -4
- package/dist/{update-agent-DUWNYBNA.js → update-agent-PTKTM2B5.js} +4 -4
- package/dist/update-agent-ZPXWRMS2.js +20 -0
- package/dist/update-dashboard-widget-HKCBXH7X.js +62 -0
- package/dist/update-dashboard-widget-IP2TTQ5G.js +63 -0
- package/dist/update-dataset-GHIN6JR3.js +22 -0
- package/dist/{update-dataset-YSOMDCOB.js → update-dataset-IRVMY5PF.js} +6 -6
- package/dist/update-dataset-record-6VI7K2CL.js +19 -0
- package/dist/{update-dataset-record-DEA2ITYR.js → update-dataset-record-Z3L7ACNF.js} +4 -4
- package/dist/update-evaluator-5NLNE6VY.js +24 -0
- package/dist/{update-evaluator-NH7Q5GWV.js → update-evaluator-FEH7H6NS.js} +4 -4
- package/dist/update-project-75H3LDQT.js +24 -0
- package/dist/{update-project-Q26FBSYH.js → update-project-QPR3QX55.js} +4 -4
- package/dist/update-prompt-BCDFTNLK.js +140 -0
- package/dist/{update-prompt-ZQQ2C3KU.js → update-prompt-NPRXYSWA.js} +27 -29
- package/dist/update-scenario-BNOMDCMV.js +34 -0
- package/dist/{update-scenario-WUX34JAR.js → update-scenario-EM5XGMB7.js} +5 -5
- package/package.json +35 -39
- package/pyproject.toml +23 -8
- package/src/config.d.ts +6 -0
- package/src/config.ts +22 -29
- package/src/create-mcp-server.ts +887 -634
- package/src/documentation-fetch.ts +21 -20
- package/src/http-security.ts +166 -135
- package/src/http-server.ts +189 -224
- package/src/index.ts +14 -16
- package/src/langwatch-api-agents.ts +18 -21
- package/src/langwatch-api-analytics-reports.ts +62 -0
- package/src/langwatch-api-annotations.ts +11 -12
- package/src/langwatch-api-api-keys.ts +8 -9
- package/src/langwatch-api-dashboard-widgets.ts +47 -0
- package/src/langwatch-api-dashboards.ts +109 -24
- package/src/langwatch-api-datasets.ts +98 -32
- package/src/langwatch-api-evaluators.ts +13 -19
- package/src/langwatch-api-model-providers.ts +4 -4
- package/src/langwatch-api-monitors.ts +14 -18
- package/src/langwatch-api-projects.ts +10 -9
- package/src/langwatch-api-query.ts +114 -0
- package/src/langwatch-api-run-plans.ts +12 -29
- package/src/langwatch-api-scenarios.ts +9 -11
- package/src/langwatch-api-secrets.ts +31 -24
- package/src/langwatch-api-simulation-runs.ts +6 -8
- package/src/langwatch-api-test-suites.ts +14 -33
- package/src/langwatch-api-triggers.ts +96 -34
- package/src/langwatch-api-workflows.ts +9 -9
- package/src/langwatch-api.ts +118 -124
- package/src/public-http-request.ts +21 -12
- package/src/schemas/analytics-metrics.ts +3 -15
- package/src/schemas/create-dataset.ts +3 -4
- package/src/schemas/run-plan.ts +13 -29
- package/src/schemas/suite-fields.ts +6 -23
- package/src/schemas/triggers.ts +365 -0
- package/src/schemas/widget-sources.ts +33 -0
- package/src/tools/add-dashboard-widget.ts +51 -0
- package/src/tools/archive-project.ts +2 -4
- package/src/tools/archive-run-plan.ts +2 -4
- package/src/tools/archive-scenario.ts +2 -4
- package/src/tools/archive-test-suite.ts +2 -4
- package/src/tools/assign-prompt-tag.ts +6 -2
- package/src/tools/create-agent.ts +1 -1
- package/src/tools/create-analytics-report.ts +7 -0
- package/src/tools/create-annotation.ts +7 -2
- package/src/tools/create-api-key.ts +4 -6
- package/src/tools/create-dataset-records.ts +4 -8
- package/src/tools/create-dataset.ts +5 -7
- package/src/tools/create-evaluator.ts +3 -5
- package/src/tools/create-project.ts +2 -2
- package/src/tools/create-prompt-tag.ts +2 -4
- package/src/tools/create-prompt.ts +9 -18
- package/src/tools/create-scenario.ts +5 -7
- package/src/tools/create-test-suite.ts +4 -9
- package/src/tools/create-trigger.ts +55 -0
- package/src/tools/dashboard-widget-queries.ts +45 -0
- package/src/tools/dashboards.ts +104 -0
- package/src/tools/delete-agent.ts +1 -1
- package/src/tools/delete-analytics-report.ts +7 -0
- package/src/tools/delete-annotation.ts +1 -1
- package/src/tools/delete-dataset-records.ts +4 -8
- package/src/tools/delete-dataset.ts +3 -7
- package/src/tools/delete-evaluator.ts +4 -6
- package/src/tools/delete-prompt-tag.ts +2 -4
- package/src/tools/delete-workflow.ts +1 -1
- package/src/tools/discover-evaluator-schema.ts +34 -25
- package/src/tools/discover-scenario-schema.ts +41 -21
- package/src/tools/discover-schema.ts +149 -27
- package/src/tools/experiment-run-status.ts +2 -8
- package/src/tools/format-dataset-mutation.ts +5 -10
- package/src/tools/format-run-plan.ts +7 -21
- package/src/tools/format-scenario.ts +2 -4
- package/src/tools/format-suite-details.ts +6 -12
- package/src/tools/get-agent.ts +15 -6
- package/src/tools/get-analytics-report.ts +23 -0
- package/src/tools/get-analytics.ts +52 -46
- package/src/tools/get-dataset.ts +34 -16
- package/src/tools/get-evaluator.ts +4 -11
- package/src/tools/get-experiment-results.ts +219 -186
- package/src/tools/get-project.ts +2 -4
- package/src/tools/get-prompt.ts +63 -84
- package/src/tools/get-run-plan.ts +4 -6
- package/src/tools/get-scenario.ts +4 -6
- package/src/tools/get-simulation-run.ts +27 -24
- package/src/tools/get-test-suite.ts +2 -5
- package/src/tools/get-trace.ts +16 -17
- package/src/tools/get-workflow.ts +1 -1
- package/src/tools/list-agents.ts +1 -1
- package/src/tools/list-analytics-reports.ts +27 -0
- package/src/tools/list-annotations.ts +8 -5
- package/src/tools/list-api-keys.ts +7 -2
- package/src/tools/list-dashboards.ts +20 -21
- package/src/tools/list-dataset-records.ts +8 -6
- package/src/tools/list-datasets.ts +12 -23
- package/src/tools/list-evaluators.ts +4 -8
- package/src/tools/list-experiment-runs.ts +5 -9
- package/src/tools/list-experiments.ts +5 -11
- package/src/tools/list-model-providers.ts +3 -5
- package/src/tools/list-projects.ts +2 -4
- package/src/tools/list-prompt-tags.ts +3 -3
- package/src/tools/list-prompts.ts +4 -8
- package/src/tools/list-run-plans.ts +2 -2
- package/src/tools/list-scenarios.ts +14 -15
- package/src/tools/list-simulation-runs.ts +8 -4
- package/src/tools/list-test-suites.ts +1 -1
- package/src/tools/list-trigger-fires.ts +17 -0
- package/src/tools/list-triggers.ts +39 -0
- package/src/tools/list-workflows.ts +2 -4
- package/src/tools/rename-prompt-tag.ts +1 -1
- package/src/tools/rename-test-suite.ts +2 -5
- package/src/tools/report-issue.ts +7 -9
- package/src/tools/rerun-run-plan.ts +2 -5
- package/src/tools/revoke-api-key.ts +2 -4
- package/src/tools/run-agent.ts +29 -26
- package/src/tools/run-experiment.ts +37 -34
- package/src/tools/run-plan.ts +4 -7
- package/src/tools/run-query.ts +47 -0
- package/src/tools/run-test-suite.ts +4 -7
- package/src/tools/run-workflow.ts +2 -5
- package/src/tools/search-traces.ts +161 -47
- package/src/tools/set-model-provider.ts +4 -6
- package/src/tools/test-agent.ts +2 -2
- package/src/tools/update-agent.ts +1 -1
- package/src/tools/update-dashboard-widget.ts +86 -0
- package/src/tools/update-dataset-record.ts +1 -1
- package/src/tools/update-dataset.ts +5 -7
- package/src/tools/update-evaluator.ts +3 -5
- package/src/tools/update-project.ts +1 -1
- package/src/tools/update-prompt.ts +44 -59
- package/src/tools/update-scenario.ts +5 -7
- package/src/tools/update-test-suite.ts +6 -11
- package/src/utils/date-parsing.ts +1 -1
- package/src/utils/escape-markdown.ts +3 -8
- package/src/utils/format-evaluations.ts +6 -6
- package/src/utils/markdown-table.ts +58 -0
- package/src/utils/trace-id-shape.ts +20 -0
- package/tsconfig.app.json +24 -0
- package/tsconfig.json +14 -12
- package/uv.lock +667 -341
- package/vitest.integration.config.js +10 -0
- package/vitest.scenario.config.js +9 -0
- package/.eslintrc.cjs +0 -36
- package/dist/chunk-AN4OUA4D.js +0 -86
- package/dist/chunk-GELJ2MQR.js +0 -226
- package/dist/chunk-K37ZNPXK.js +0 -24
- package/dist/chunk-S4GVX36W.js +0 -39
- package/dist/config.d.ts +0 -17
- package/dist/create-dashboard-Z76AIPLS.js +0 -19
- package/dist/create-mcp-server.d.ts +0 -10
- package/dist/delete-dashboard-LYMRPF27.js +0 -19
- package/dist/delete-evaluator-RKYC4TNB.js +0 -16
- package/dist/discover-evaluator-schema-ESSHQGPY.js +0 -1912
- package/dist/get-analytics-R6AZD3AW.js +0 -73
- package/dist/get-dashboard-P4WWVHFU.js +0 -30
- package/dist/get-dataset-AKTYSQDI.js +0 -49
- package/dist/index.d.ts +0 -2
- package/dist/langwatch-api-dashboards-2KJL2M42.js +0 -18
- package/dist/langwatch-api-secrets-OEBD6GBU.js +0 -41
- package/dist/langwatch-api-triggers-5E6DDGX6.js +0 -31
- package/dist/list-dashboards-Z3BZKDGF.js +0 -33
- package/dist/run-agent-CAGWGTYT.js +0 -72
- package/dist/search-traces-4XTJYXIK.js +0 -79
- package/src/__tests__/agent-tools.unit.test.ts +0 -257
- package/src/__tests__/all-tools.integration.test.ts +0 -1872
- package/src/__tests__/config.unit.test.ts +0 -202
- package/src/__tests__/datasets.integration.test.ts +0 -620
- package/src/__tests__/datasets.unit.test.ts +0 -244
- package/src/__tests__/date-parsing.unit.test.ts +0 -78
- package/src/__tests__/discover-evaluator-schema.unit.test.ts +0 -89
- package/src/__tests__/discover-schema.unit.test.ts +0 -118
- package/src/__tests__/docker.integration.test.ts +0 -318
- package/src/__tests__/documentation-fetch-security.integration.test.ts +0 -182
- package/src/__tests__/evaluator-tools.unit.test.ts +0 -262
- package/src/__tests__/experiment-list-tools.unit.test.ts +0 -157
- package/src/__tests__/experiment-status.unit.test.ts +0 -194
- package/src/__tests__/feature-map-tool-drift.unit.test.ts +0 -93
- package/src/__tests__/get-experiment-results.unit.test.ts +0 -313
- package/src/__tests__/http-security-origin.unit.test.ts +0 -97
- package/src/__tests__/http-security-sessions.unit.test.ts +0 -209
- package/src/__tests__/http-security-verifier.unit.test.ts +0 -248
- package/src/__tests__/http-server-allocation.integration.test.ts +0 -279
- package/src/__tests__/http-server-origin.integration.test.ts +0 -169
- package/src/__tests__/http-server-session-auth.integration.test.ts +0 -341
- package/src/__tests__/http-transport.integration.test.ts +0 -395
- package/src/__tests__/integration.integration.test.ts +0 -284
- package/src/__tests__/langwatch-api.unit.test.ts +0 -661
- package/src/__tests__/model-provider-tools.unit.test.ts +0 -190
- package/src/__tests__/project-api-key-tools.unit.test.ts +0 -451
- package/src/__tests__/prompt-response-types.unit.test.ts +0 -51
- package/src/__tests__/prompts.integration.test.ts +0 -736
- package/src/__tests__/public-http-request-security.integration.test.ts +0 -118
- package/src/__tests__/report-issue.integration.test.ts +0 -147
- package/src/__tests__/run-plan-tools.unit.test.ts +0 -565
- package/src/__tests__/scenario-tools.integration.test.ts +0 -286
- package/src/__tests__/scenario-tools.unit.test.ts +0 -207
- package/src/__tests__/schemas.unit.test.ts +0 -85
- package/src/__tests__/simulation-run-tools.unit.test.ts +0 -116
- package/src/__tests__/support/http-server-harness.ts +0 -138
- package/src/__tests__/test-suite-tools.unit.test.ts +0 -615
- package/src/__tests__/tools.integration.test.ts +0 -896
- package/src/schemas/filter-fields.ts +0 -119
- package/src/schemas/index.ts +0 -9
- package/src/tools/create-dashboard.ts +0 -7
- package/src/tools/delete-dashboard.ts +0 -7
- package/src/tools/get-dashboard.ts +0 -22
package/src/langwatch-api.ts
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "
|
|
5
|
-
import {
|
|
6
|
-
|
|
1
|
+
import type { HandledErrorFault, SerializedReason } from "@langwatch/handled-error";
|
|
2
|
+
|
|
3
|
+
import packageJson from "../package.json" with { type: "json" };
|
|
4
|
+
import { getConfig, requireApiKey } from "./config.ts";
|
|
5
|
+
import type { EvaluationSummary } from "./utils/format-evaluations.ts";
|
|
6
|
+
|
|
7
|
+
/** Every request names itself so the platform attributes it. */
|
|
8
|
+
// See specs/observability/traffic-attribution.feature.
|
|
9
|
+
export const MCP_IDENTITY_HEADERS: Record<string, string> = {
|
|
10
|
+
"User-Agent": `langwatch-mcp/${packageJson.version}`,
|
|
11
|
+
"X-LangWatch-SDK-Name": "langwatch-mcp",
|
|
12
|
+
"X-LangWatch-SDK-Language": "typescript",
|
|
13
|
+
"X-LangWatch-SDK-Version": packageJson.version,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/** The dated API version every request names (specs/api-reference/client-api-version.feature). */
|
|
17
|
+
export const LANGWATCH_API_VERSION = "2026-10-26";
|
|
18
|
+
|
|
19
|
+
/** Names the hosted MCP server's calls apart from a local server's. */
|
|
20
|
+
export const HOSTED_MCP_HEADER = "X-LangWatch-MCP-Host";
|
|
7
21
|
|
|
8
22
|
// --- Response types ---
|
|
9
23
|
|
|
@@ -46,7 +60,7 @@ export interface TraceDetailResponse {
|
|
|
46
60
|
error?: Record<string, unknown>;
|
|
47
61
|
ascii_tree?: string;
|
|
48
62
|
evaluations?: EvaluationSummary[];
|
|
49
|
-
spans?:
|
|
63
|
+
spans?: {
|
|
50
64
|
span_id: string;
|
|
51
65
|
name?: string;
|
|
52
66
|
type?: string;
|
|
@@ -61,7 +75,7 @@ export interface TraceDetailResponse {
|
|
|
61
75
|
tokens_estimated?: boolean;
|
|
62
76
|
cost?: number;
|
|
63
77
|
};
|
|
64
|
-
}
|
|
78
|
+
}[];
|
|
65
79
|
}
|
|
66
80
|
|
|
67
81
|
export interface AnalyticsBucket {
|
|
@@ -87,14 +101,10 @@ export interface PromptTag {
|
|
|
87
101
|
versionId: string;
|
|
88
102
|
}
|
|
89
103
|
|
|
90
|
-
export type PromptFieldList =
|
|
104
|
+
export type PromptFieldList = { identifier: string; type: string }[];
|
|
91
105
|
|
|
92
106
|
/**
|
|
93
|
-
* A single versioned prompt payload.
|
|
94
|
-
* requested version's data flattened to the top level (merged with the base
|
|
95
|
-
* prompt data), and `GET /api/prompts/:id/versions` returns an array of
|
|
96
|
-
* entries in this same shape — there is no nested `versions` array on the
|
|
97
|
-
* detail response.
|
|
107
|
+
* A single versioned prompt payload.
|
|
98
108
|
*/
|
|
99
109
|
export interface PromptVersion {
|
|
100
110
|
versionId?: string;
|
|
@@ -103,7 +113,7 @@ export interface PromptVersion {
|
|
|
103
113
|
model?: string;
|
|
104
114
|
/** Legacy single-text prompt body. */
|
|
105
115
|
prompt?: string;
|
|
106
|
-
messages?:
|
|
116
|
+
messages?: { role: string; content: string }[];
|
|
107
117
|
temperature?: number;
|
|
108
118
|
maxTokens?: number;
|
|
109
119
|
responseFormat?: Record<string, unknown> | null;
|
|
@@ -134,10 +144,9 @@ export class LangWatchApiError extends Error {
|
|
|
134
144
|
readonly docsUrl?: string;
|
|
135
145
|
readonly fault?: HandledErrorFault;
|
|
136
146
|
/**
|
|
137
|
-
* The per-field failures behind this error, verbatim from the envelope.
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
* request and an agent guessing again.
|
|
147
|
+
* The per-field failures behind this error, verbatim from the envelope. A validation failure
|
|
148
|
+
* carries the offending field and the values it would have accepted here — the difference
|
|
149
|
+
* between an agent correcting its own request and an agent guessing again.
|
|
141
150
|
*/
|
|
142
151
|
readonly reasons?: SerializedReason[];
|
|
143
152
|
|
|
@@ -173,56 +182,42 @@ interface ParsedErrorBody {
|
|
|
173
182
|
reasons?: SerializedReason[];
|
|
174
183
|
}
|
|
175
184
|
|
|
176
|
-
const VALID_FAULTS: readonly HandledErrorFault[] = [
|
|
185
|
+
const VALID_FAULTS: readonly HandledErrorFault[] = [
|
|
186
|
+
"customer",
|
|
187
|
+
"platform",
|
|
188
|
+
"provider",
|
|
189
|
+
"presumed_platform",
|
|
190
|
+
];
|
|
177
191
|
|
|
178
192
|
/**
|
|
179
|
-
* Parses an error response body as a handled-error envelope.
|
|
180
|
-
* shapes: the canonical v1 envelope
|
|
181
|
-
* (`{ error: { type, code, message, meta?, trace_id } }`), the legacy REST
|
|
182
|
-
* shape (`{ error: "<code>", message, tips?, docsUrl?, fault? }`) and the
|
|
183
|
-
* serialized tRPC shape (`{ code, message?, tips?, docsUrl?, fault?, ... }`).
|
|
184
|
-
* Returns an empty object when the body is not a recognizable error envelope.
|
|
193
|
+
* Parses an error response body as a handled-error envelope.
|
|
185
194
|
*/
|
|
186
195
|
function parseErrorBody(responseBody: string): ParsedErrorBody {
|
|
187
196
|
try {
|
|
188
197
|
const parsed: unknown = JSON.parse(responseBody);
|
|
189
|
-
if (
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
const envelope = parsed as Record<string, unknown>;
|
|
198
|
+
if (!isRecord(parsed)) return {};
|
|
199
|
+
const envelope = parsed;
|
|
193
200
|
// The canonical v1 envelope nests everything under `error`. Read the
|
|
194
201
|
// nested object as the body so one parser serves both generations.
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
envelope.error !== null &&
|
|
198
|
-
!Array.isArray(envelope.error)
|
|
199
|
-
? (envelope.error as Record<string, unknown>)
|
|
200
|
-
: null;
|
|
202
|
+
const nestedValue = envelope.error;
|
|
203
|
+
const nested = isRecord(nestedValue) ? nestedValue : null;
|
|
201
204
|
const body = nested ?? envelope;
|
|
202
|
-
//
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
? body.code
|
|
208
|
-
: typeof body.error === "string"
|
|
209
|
-
? body.error
|
|
210
|
-
: undefined;
|
|
205
|
+
// `code` is the domain discriminant. The `error` fallback reads the
|
|
206
|
+
// legacy envelope some non-framework families still send; the framework's
|
|
207
|
+
// own unversioned union envelope, which used `error` for the HTTP status
|
|
208
|
+
// text, is gone (packages/api/adrs/002).
|
|
209
|
+
const code = readErrorCode(body);
|
|
211
210
|
const message = typeof body.message === "string" ? body.message : undefined;
|
|
212
211
|
if (code === undefined && message === undefined) {
|
|
213
212
|
return {};
|
|
214
213
|
}
|
|
215
|
-
const tips =
|
|
216
|
-
Array.isArray(body.tips) && body.tips.every((t) => typeof t === "string")
|
|
217
|
-
? (body.tips as string[])
|
|
218
|
-
: undefined;
|
|
214
|
+
const tips = readStringArray(body.tips);
|
|
219
215
|
const docsUrl = typeof body.docsUrl === "string" ? body.docsUrl : undefined;
|
|
220
216
|
const fault = VALID_FAULTS.includes(body.fault as HandledErrorFault)
|
|
221
217
|
? (body.fault as HandledErrorFault)
|
|
222
218
|
: undefined;
|
|
223
219
|
const reasons =
|
|
224
|
-
Array.isArray(body.reasons) &&
|
|
225
|
-
body.reasons.every((r) => !!r && typeof r === "object")
|
|
220
|
+
Array.isArray(body.reasons) && body.reasons.every((r) => !!r && typeof r === "object")
|
|
226
221
|
? (body.reasons as SerializedReason[])
|
|
227
222
|
: undefined;
|
|
228
223
|
return { code, message, tips, docsUrl, fault, reasons };
|
|
@@ -231,14 +226,29 @@ function parseErrorBody(responseBody: string): ParsedErrorBody {
|
|
|
231
226
|
}
|
|
232
227
|
}
|
|
233
228
|
|
|
229
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
230
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function readErrorCode(body: Record<string, unknown>): string | undefined {
|
|
234
|
+
if (typeof body.code === "string") return body.code;
|
|
235
|
+
if (typeof body.error === "string") return body.error;
|
|
236
|
+
return undefined;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function readStringArray(value: unknown): string[] | undefined {
|
|
240
|
+
if (!Array.isArray(value) || !value.every(isString)) return undefined;
|
|
241
|
+
return value;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function isString(value: unknown): value is string {
|
|
245
|
+
return typeof value === "string";
|
|
246
|
+
}
|
|
247
|
+
|
|
234
248
|
/**
|
|
235
|
-
* The human line for one per-field failure: the field, what it would have
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
* This exists because the MCP transport's only channel to the caller is the
|
|
240
|
-
* error MESSAGE — an agent never sees the `reasons` array itself, so a
|
|
241
|
-
* rejection whose remedy lives only there is unfollowable.
|
|
249
|
+
* The human line for one per-field failure: the field, what it would have accepted, and what it
|
|
250
|
+
* got. Returns null when a reason names no field, so a generic nested error adds no noise to
|
|
251
|
+
* the message.
|
|
242
252
|
*/
|
|
243
253
|
function describeReason(reason: SerializedReason): string | null {
|
|
244
254
|
const meta = reason.meta;
|
|
@@ -258,27 +268,28 @@ function describeReason(reason: SerializedReason): string | null {
|
|
|
258
268
|
}
|
|
259
269
|
|
|
260
270
|
/**
|
|
261
|
-
* Sends an HTTP request to the LangWatch API.
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
* and handles JSON serialization/deserialization.
|
|
265
|
-
*
|
|
266
|
-
* @throws LangWatchApiError with status code and response body when the
|
|
267
|
-
* response is not OK.
|
|
271
|
+
* Sends an HTTP request to the LangWatch API. Builds the full URL from the configured endpoint,
|
|
272
|
+
* adds authentication, and handles JSON serialization/deserialization. @throws
|
|
273
|
+
* LangWatchApiError with status code and response body when the response is not OK.
|
|
268
274
|
*/
|
|
269
275
|
export async function makeRequest(
|
|
270
276
|
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE",
|
|
271
277
|
path: string,
|
|
272
|
-
body?: unknown
|
|
278
|
+
body?: unknown,
|
|
273
279
|
): Promise<unknown> {
|
|
274
280
|
const config = getConfig();
|
|
275
281
|
const url = config.endpoint + path;
|
|
276
282
|
const headers: Record<string, string> = {
|
|
283
|
+
...MCP_IDENTITY_HEADERS,
|
|
284
|
+
"X-API-Version": LANGWATCH_API_VERSION,
|
|
277
285
|
"X-Auth-Token": requireApiKey(),
|
|
278
286
|
};
|
|
279
287
|
if (config.projectId) {
|
|
280
288
|
headers["X-Project-Id"] = config.projectId;
|
|
281
289
|
}
|
|
290
|
+
if (config.hosted) {
|
|
291
|
+
headers[HOSTED_MCP_HEADER] = "hosted";
|
|
292
|
+
}
|
|
282
293
|
|
|
283
294
|
if (body !== undefined) {
|
|
284
295
|
headers["Content-Type"] = "application/json";
|
|
@@ -293,9 +304,7 @@ export async function makeRequest(
|
|
|
293
304
|
if (!response.ok) {
|
|
294
305
|
const responseBody = await response.text();
|
|
295
306
|
const parsed = parseErrorBody(responseBody);
|
|
296
|
-
const lines = [
|
|
297
|
-
`LangWatch API error ${response.status}: ${parsed.message ?? responseBody}`,
|
|
298
|
-
];
|
|
307
|
+
const lines = [`LangWatch API error ${response.status}: ${parsed.message ?? responseBody}`];
|
|
299
308
|
const reasonLines = (parsed.reasons ?? [])
|
|
300
309
|
.map(describeReason)
|
|
301
310
|
.filter((line): line is string => line !== null);
|
|
@@ -308,18 +317,13 @@ export async function makeRequest(
|
|
|
308
317
|
if (parsed.docsUrl) {
|
|
309
318
|
lines.push(`Docs: ${parsed.docsUrl}`);
|
|
310
319
|
}
|
|
311
|
-
throw new LangWatchApiError(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
docsUrl: parsed.docsUrl,
|
|
319
|
-
fault: parsed.fault,
|
|
320
|
-
reasons: parsed.reasons,
|
|
321
|
-
},
|
|
322
|
-
);
|
|
320
|
+
throw new LangWatchApiError(lines.join("\n"), response.status, responseBody, {
|
|
321
|
+
code: parsed.code,
|
|
322
|
+
tips: parsed.tips,
|
|
323
|
+
docsUrl: parsed.docsUrl,
|
|
324
|
+
fault: parsed.fault,
|
|
325
|
+
reasons: parsed.reasons,
|
|
326
|
+
});
|
|
323
327
|
}
|
|
324
328
|
|
|
325
329
|
if (response.status === 204 || response.headers?.get("content-length") === "0") {
|
|
@@ -329,16 +333,19 @@ export async function makeRequest(
|
|
|
329
333
|
}
|
|
330
334
|
|
|
331
335
|
/**
|
|
332
|
-
* Searches traces with optional filters and pagination.
|
|
333
|
-
*
|
|
334
|
-
* Paging is by `scrollId` only: pass the one the previous response returned,
|
|
335
|
-
* and stop when a response carries none. `pageOffset` used to be accepted here
|
|
336
|
-
* but was never read by the server, so an offset walk silently re-served the
|
|
337
|
-
* first page; it is rejected at the boundary now (#6808).
|
|
336
|
+
* Searches traces with optional filters and pagination. Paging is by `scrollId` only: pass the
|
|
337
|
+
* one the previous response returned, and stop when a response carries none.
|
|
338
338
|
*/
|
|
339
339
|
export async function searchTraces(params: {
|
|
340
340
|
query?: string;
|
|
341
|
+
/** Exact trace ids: a primary-key seek on trace_summaries, not a scan (ADR-164). */
|
|
342
|
+
traceIds?: string[];
|
|
341
343
|
filters?: Record<string, string[]>;
|
|
344
|
+
/**
|
|
345
|
+
* The Trace Explorer's query language, as one string. Combined server-side
|
|
346
|
+
* with `filters`, `query` and `traceIds` rather than replacing any of them.
|
|
347
|
+
*/
|
|
348
|
+
filter?: string;
|
|
342
349
|
startDate: number;
|
|
343
350
|
endDate: number;
|
|
344
351
|
pageSize?: number;
|
|
@@ -346,7 +353,7 @@ export async function searchTraces(params: {
|
|
|
346
353
|
format?: "digest" | "json";
|
|
347
354
|
}): Promise<SearchTracesResponse> {
|
|
348
355
|
const { format = "digest", ...rest } = params;
|
|
349
|
-
return makeRequest("POST", "/api/traces/search", {
|
|
356
|
+
return makeRequest("POST", "/api/v1/traces/search", {
|
|
350
357
|
...rest,
|
|
351
358
|
format,
|
|
352
359
|
}) as Promise<SearchTracesResponse>;
|
|
@@ -355,22 +362,22 @@ export async function searchTraces(params: {
|
|
|
355
362
|
/** Retrieves a single trace by its ID. */
|
|
356
363
|
export async function getTraceById(
|
|
357
364
|
traceId: string,
|
|
358
|
-
format: "digest" | "json" = "digest"
|
|
365
|
+
format: "digest" | "json" = "digest",
|
|
359
366
|
): Promise<TraceDetailResponse> {
|
|
360
367
|
return makeRequest(
|
|
361
368
|
"GET",
|
|
362
|
-
`/api/traces/${encodeURIComponent(traceId)}?format=${format}
|
|
369
|
+
`/api/v1/traces/${encodeURIComponent(traceId)}?format=${format}`,
|
|
363
370
|
) as Promise<TraceDetailResponse>;
|
|
364
371
|
}
|
|
365
372
|
|
|
366
373
|
/** Fetches analytics timeseries data for the given metrics and date range. */
|
|
367
374
|
export async function getAnalyticsTimeseries(params: {
|
|
368
|
-
series:
|
|
375
|
+
series: {
|
|
369
376
|
metric: string;
|
|
370
377
|
aggregation: string;
|
|
371
378
|
key?: string;
|
|
372
379
|
subkey?: string;
|
|
373
|
-
}
|
|
380
|
+
}[];
|
|
374
381
|
startDate: number;
|
|
375
382
|
endDate: number;
|
|
376
383
|
timeZone?: string;
|
|
@@ -380,20 +387,20 @@ export async function getAnalyticsTimeseries(params: {
|
|
|
380
387
|
}): Promise<AnalyticsTimeseriesResponse> {
|
|
381
388
|
return makeRequest(
|
|
382
389
|
"POST",
|
|
383
|
-
"/api/analytics/timeseries",
|
|
384
|
-
params
|
|
390
|
+
"/api/v1/analytics/timeseries",
|
|
391
|
+
params,
|
|
385
392
|
) as Promise<AnalyticsTimeseriesResponse>;
|
|
386
393
|
}
|
|
387
394
|
|
|
388
395
|
/** Lists all prompts in the project. */
|
|
389
396
|
export async function listPrompts(): Promise<PromptSummary[]> {
|
|
390
|
-
return makeRequest("GET", "/api/prompts") as Promise<PromptSummary[]>;
|
|
397
|
+
return makeRequest("GET", "/api/v1/prompts") as Promise<PromptSummary[]>;
|
|
391
398
|
}
|
|
392
399
|
|
|
393
400
|
/** Retrieves a single prompt by ID or handle. */
|
|
394
401
|
export async function getPrompt(
|
|
395
402
|
idOrHandle: string,
|
|
396
|
-
options?: { version?: number; tag?: string }
|
|
403
|
+
options?: { version?: number; tag?: string },
|
|
397
404
|
): Promise<PromptDetailResponse> {
|
|
398
405
|
const params = new URLSearchParams();
|
|
399
406
|
if (options?.version != null) params.set("version", String(options.version));
|
|
@@ -401,48 +408,42 @@ export async function getPrompt(
|
|
|
401
408
|
const query = params.toString() ? `?${params}` : "";
|
|
402
409
|
return makeRequest(
|
|
403
410
|
"GET",
|
|
404
|
-
`/api/prompts/${encodeURIComponent(idOrHandle)}${query}
|
|
411
|
+
`/api/v1/prompts/${encodeURIComponent(idOrHandle)}${query}`,
|
|
405
412
|
) as Promise<PromptDetailResponse>;
|
|
406
413
|
}
|
|
407
414
|
|
|
408
415
|
/** Lists all versions of a prompt (versioned data only). */
|
|
409
|
-
export async function getPromptVersions(
|
|
410
|
-
idOrHandle: string
|
|
411
|
-
): Promise<PromptVersion[]> {
|
|
416
|
+
export async function getPromptVersions(idOrHandle: string): Promise<PromptVersion[]> {
|
|
412
417
|
return makeRequest(
|
|
413
418
|
"GET",
|
|
414
|
-
`/api/prompts/${encodeURIComponent(idOrHandle)}/versions
|
|
419
|
+
`/api/v1/prompts/${encodeURIComponent(idOrHandle)}/versions`,
|
|
415
420
|
) as Promise<PromptVersion[]>;
|
|
416
421
|
}
|
|
417
422
|
|
|
418
423
|
/** Creates a new prompt. */
|
|
419
424
|
export async function createPrompt(data: {
|
|
420
425
|
handle: string;
|
|
421
|
-
messages:
|
|
426
|
+
messages: { role: string; content: string }[];
|
|
422
427
|
model: string;
|
|
423
428
|
tags?: string[];
|
|
424
429
|
}): Promise<PromptMutationResponse> {
|
|
425
|
-
return makeRequest(
|
|
426
|
-
"POST",
|
|
427
|
-
"/api/prompts",
|
|
428
|
-
data
|
|
429
|
-
) as Promise<PromptMutationResponse>;
|
|
430
|
+
return makeRequest("POST", "/api/v1/prompts", data) as Promise<PromptMutationResponse>;
|
|
430
431
|
}
|
|
431
432
|
|
|
432
433
|
/** Updates an existing prompt by ID or handle. */
|
|
433
434
|
export async function updatePrompt(
|
|
434
435
|
idOrHandle: string,
|
|
435
436
|
data: {
|
|
436
|
-
messages?:
|
|
437
|
+
messages?: { role: string; content: string }[];
|
|
437
438
|
model?: string;
|
|
438
439
|
commitMessage: string;
|
|
439
440
|
tags?: string[];
|
|
440
|
-
}
|
|
441
|
+
},
|
|
441
442
|
): Promise<PromptMutationResponse> {
|
|
442
443
|
return makeRequest(
|
|
443
444
|
"PUT",
|
|
444
|
-
`/api/prompts/${encodeURIComponent(idOrHandle)}`,
|
|
445
|
-
data
|
|
445
|
+
`/api/v1/prompts/${encodeURIComponent(idOrHandle)}`,
|
|
446
|
+
data,
|
|
446
447
|
) as Promise<PromptMutationResponse>;
|
|
447
448
|
}
|
|
448
449
|
|
|
@@ -458,19 +459,19 @@ export async function assignPromptTag({
|
|
|
458
459
|
}): Promise<unknown> {
|
|
459
460
|
return makeRequest(
|
|
460
461
|
"PUT",
|
|
461
|
-
`/api/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,
|
|
462
|
-
{ versionId }
|
|
462
|
+
`/api/v1/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,
|
|
463
|
+
{ versionId },
|
|
463
464
|
);
|
|
464
465
|
}
|
|
465
466
|
|
|
466
467
|
/** Lists all prompt tag definitions for the organization. */
|
|
467
468
|
export async function listPromptTags(): Promise<unknown> {
|
|
468
|
-
return makeRequest("GET", "/api/prompts/tags");
|
|
469
|
+
return makeRequest("GET", "/api/v1/prompts/tags");
|
|
469
470
|
}
|
|
470
471
|
|
|
471
472
|
/** Creates a custom prompt tag definition. */
|
|
472
473
|
export async function createPromptTag(name: string): Promise<unknown> {
|
|
473
|
-
return makeRequest("POST", "/api/prompts/tags", { name });
|
|
474
|
+
return makeRequest("POST", "/api/v1/prompts/tags", { name });
|
|
474
475
|
}
|
|
475
476
|
|
|
476
477
|
/** Renames an existing prompt tag. */
|
|
@@ -481,17 +482,10 @@ export async function renamePromptTag({
|
|
|
481
482
|
tag: string;
|
|
482
483
|
name: string;
|
|
483
484
|
}): Promise<unknown> {
|
|
484
|
-
return makeRequest(
|
|
485
|
-
"PUT",
|
|
486
|
-
`/api/prompts/tags/${encodeURIComponent(tag)}`,
|
|
487
|
-
{ name }
|
|
488
|
-
);
|
|
485
|
+
return makeRequest("PUT", `/api/v1/prompts/tags/${encodeURIComponent(tag)}`, { name });
|
|
489
486
|
}
|
|
490
487
|
|
|
491
488
|
/** Deletes a prompt tag and all its assignments. */
|
|
492
489
|
export async function deletePromptTag(tag: string): Promise<unknown> {
|
|
493
|
-
return makeRequest(
|
|
494
|
-
"DELETE",
|
|
495
|
-
`/api/prompts/tags/${encodeURIComponent(tag)}`
|
|
496
|
-
);
|
|
490
|
+
return makeRequest("DELETE", `/api/v1/prompts/tags/${encodeURIComponent(tag)}`);
|
|
497
491
|
}
|
|
@@ -3,7 +3,7 @@ import { request as httpRequest, type RequestOptions } from "node:http";
|
|
|
3
3
|
import { request as httpsRequest } from "node:https";
|
|
4
4
|
import { isIP } from "node:net";
|
|
5
5
|
|
|
6
|
-
import { classify } from "@langwatch/ssrf";
|
|
6
|
+
import { classify } from "@langwatch/egress/ssrf";
|
|
7
7
|
|
|
8
8
|
const MAX_REDIRECTS = 5;
|
|
9
9
|
const MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
@@ -20,7 +20,10 @@ const SENSITIVE_REDIRECT_HEADERS = new Set([
|
|
|
20
20
|
"x-access-token",
|
|
21
21
|
]);
|
|
22
22
|
|
|
23
|
-
type DnsResolver = (
|
|
23
|
+
type DnsResolver = (
|
|
24
|
+
hostname: string,
|
|
25
|
+
options: { all: true; verbatim: true },
|
|
26
|
+
) => Promise<ResolvedAddress[]>;
|
|
24
27
|
|
|
25
28
|
interface ResolvedAddress {
|
|
26
29
|
address: string;
|
|
@@ -34,7 +37,9 @@ export interface PublicDestination {
|
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
function unsafeDestinationError(): Error {
|
|
37
|
-
return new Error(
|
|
40
|
+
return new Error(
|
|
41
|
+
"HTTP agent destinations must resolve only to globally routable public addresses",
|
|
42
|
+
);
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
function hostnameWithoutBrackets(hostname: string): string {
|
|
@@ -66,21 +71,21 @@ async function withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T
|
|
|
66
71
|
|
|
67
72
|
export function headersForRedirect(
|
|
68
73
|
headers: Record<string, string> | undefined,
|
|
69
|
-
crossOrigin: boolean
|
|
74
|
+
crossOrigin: boolean,
|
|
70
75
|
): Record<string, string> | undefined {
|
|
71
76
|
if (!headers || !crossOrigin) {
|
|
72
77
|
return headers;
|
|
73
78
|
}
|
|
74
79
|
|
|
75
80
|
const safeHeaders = Object.fromEntries(
|
|
76
|
-
Object.entries(headers).filter(([name]) => !SENSITIVE_REDIRECT_HEADERS.has(name.toLowerCase()))
|
|
81
|
+
Object.entries(headers).filter(([name]) => !SENSITIVE_REDIRECT_HEADERS.has(name.toLowerCase())),
|
|
77
82
|
);
|
|
78
83
|
return Object.keys(safeHeaders).length > 0 ? safeHeaders : undefined;
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
export async function resolvePublicDestination(
|
|
82
87
|
input: string,
|
|
83
|
-
resolver: DnsResolver = dnsLookup
|
|
88
|
+
resolver: DnsResolver = dnsLookup,
|
|
84
89
|
): Promise<PublicDestination> {
|
|
85
90
|
let url: URL;
|
|
86
91
|
try {
|
|
@@ -89,7 +94,11 @@ export async function resolvePublicDestination(
|
|
|
89
94
|
throw new Error("HTTP agent URL is invalid");
|
|
90
95
|
}
|
|
91
96
|
|
|
92
|
-
if (
|
|
97
|
+
if (
|
|
98
|
+
(url.protocol !== "http:" && url.protocol !== "https:") ||
|
|
99
|
+
url.username !== "" ||
|
|
100
|
+
url.password !== ""
|
|
101
|
+
) {
|
|
93
102
|
throw unsafeDestinationError();
|
|
94
103
|
}
|
|
95
104
|
|
|
@@ -104,7 +113,7 @@ export async function resolvePublicDestination(
|
|
|
104
113
|
try {
|
|
105
114
|
addresses = await withTimeout(
|
|
106
115
|
resolver(hostname, { all: true, verbatim: true }),
|
|
107
|
-
REQUEST_TIMEOUT_MS
|
|
116
|
+
REQUEST_TIMEOUT_MS,
|
|
108
117
|
);
|
|
109
118
|
} catch {
|
|
110
119
|
throw new Error("HTTP agent destination could not be resolved");
|
|
@@ -135,7 +144,7 @@ interface PublicJsonRequestOptions {
|
|
|
135
144
|
|
|
136
145
|
function requestBody(
|
|
137
146
|
destination: PublicDestination,
|
|
138
|
-
options: PublicJsonRequestOptions
|
|
147
|
+
options: PublicJsonRequestOptions,
|
|
139
148
|
): Promise<{ body: string; location?: string; statusCode: number }> {
|
|
140
149
|
return new Promise((resolve, reject) => {
|
|
141
150
|
const hostname = hostnameWithoutBrackets(destination.url.hostname);
|
|
@@ -198,7 +207,7 @@ function requestBody(
|
|
|
198
207
|
export async function requestPublicJson(
|
|
199
208
|
input: string,
|
|
200
209
|
options: PublicJsonRequestOptions = {},
|
|
201
|
-
redirectCount = 0
|
|
210
|
+
redirectCount = 0,
|
|
202
211
|
): Promise<Record<string, unknown>> {
|
|
203
212
|
const destination = await resolvePublicDestination(input);
|
|
204
213
|
const response = await requestBody(destination, options);
|
|
@@ -210,7 +219,7 @@ export async function requestPublicJson(
|
|
|
210
219
|
const redirectUrl = new URL(response.location, destination.url);
|
|
211
220
|
const redirectHeaders = headersForRedirect(
|
|
212
221
|
options.headers,
|
|
213
|
-
redirectUrl.origin !== destination.url.origin
|
|
222
|
+
redirectUrl.origin !== destination.url.origin,
|
|
214
223
|
);
|
|
215
224
|
const preserveBody = response.statusCode === 307 || response.statusCode === 308;
|
|
216
225
|
return requestPublicJson(
|
|
@@ -223,7 +232,7 @@ export async function requestPublicJson(
|
|
|
223
232
|
headers: redirectHeaders,
|
|
224
233
|
method: "GET",
|
|
225
234
|
},
|
|
226
|
-
redirectCount + 1
|
|
235
|
+
redirectCount + 1,
|
|
227
236
|
);
|
|
228
237
|
}
|
|
229
238
|
|
|
@@ -124,17 +124,7 @@ export const analyticsMetrics: MetricInfo[] = [
|
|
|
124
124
|
category: "events",
|
|
125
125
|
name: "event_score",
|
|
126
126
|
label: "Event Score",
|
|
127
|
-
allowedAggregations: [
|
|
128
|
-
"terms",
|
|
129
|
-
"avg",
|
|
130
|
-
"sum",
|
|
131
|
-
"min",
|
|
132
|
-
"max",
|
|
133
|
-
"median",
|
|
134
|
-
"p99",
|
|
135
|
-
"p95",
|
|
136
|
-
"p90",
|
|
137
|
-
],
|
|
127
|
+
allowedAggregations: ["terms", "avg", "sum", "min", "max", "median", "p99", "p95", "p90"],
|
|
138
128
|
description: "Numeric score from events (requires event_type key and metrics key)",
|
|
139
129
|
},
|
|
140
130
|
{
|
|
@@ -142,8 +132,7 @@ export const analyticsMetrics: MetricInfo[] = [
|
|
|
142
132
|
name: "event_details",
|
|
143
133
|
label: "Event Details",
|
|
144
134
|
allowedAggregations: ["cardinality"],
|
|
145
|
-
description:
|
|
146
|
-
"Event detail key/value distribution (requires event_type key and details key)",
|
|
135
|
+
description: "Event detail key/value distribution (requires event_type key and details key)",
|
|
147
136
|
},
|
|
148
137
|
// evaluations
|
|
149
138
|
{
|
|
@@ -158,8 +147,7 @@ export const analyticsMetrics: MetricInfo[] = [
|
|
|
158
147
|
name: "evaluation_pass_rate",
|
|
159
148
|
label: "Evaluation Pass Rate",
|
|
160
149
|
allowedAggregations: ["avg", "sum", "min", "max", "median", "p99", "p95", "p90"],
|
|
161
|
-
description:
|
|
162
|
-
"Percentage of traces passing evaluation (requires evaluator_id key)",
|
|
150
|
+
description: "Percentage of traces passing evaluation (requires evaluator_id key)",
|
|
163
151
|
},
|
|
164
152
|
{
|
|
165
153
|
category: "evaluations",
|
|
@@ -16,6 +16,7 @@ export const DATASET_COLUMN_TYPES = [
|
|
|
16
16
|
"annotations",
|
|
17
17
|
"evaluations",
|
|
18
18
|
"image",
|
|
19
|
+
"file",
|
|
19
20
|
] as const;
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -34,10 +35,8 @@ export const datasetColumnDefinitionSchema = z.object({
|
|
|
34
35
|
});
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
|
-
* Zod schema for the platform_create_dataset MCP tool parameters
|
|
38
|
-
*
|
|
39
|
-
* Extracted so it can be shared between the MCP tool registration
|
|
40
|
-
* (create-mcp-server.ts) and unit tests.
|
|
38
|
+
* Zod schema for the platform_create_dataset MCP tool parameters,
|
|
39
|
+
* extracted so it's shared between create-mcp-server.ts and unit tests.
|
|
41
40
|
*/
|
|
42
41
|
export const createDatasetSchema = z.object({
|
|
43
42
|
name: z.string().min(1).describe("Dataset name"),
|