@langwatch/mcp-server 2.0.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.
- package/.gitignore +7 -0
- package/.npmignore +41 -0
- package/CHANGELOG.md +280 -200
- package/CONTRIBUTING.md +10 -0
- package/README.md +82 -52
- package/dist/add-dashboard-widget-4ZC5UN73.js +50 -0
- package/dist/add-dashboard-widget-ACC6QYBG.js +49 -0
- package/dist/archive-project-KWFM3I5Z.js +19 -0
- package/dist/{archive-project-4EQGLBJJ.js → archive-project-SPVHXK6A.js} +4 -4
- package/dist/archive-run-plan-65QN3XRX.js +16 -0
- package/dist/archive-run-plan-Z4SYE6BP.js +15 -0
- package/dist/{archive-scenario-W6BXYDZ3.js → archive-scenario-A6QV5LOW.js} +4 -4
- package/dist/archive-scenario-FXEYQNEH.js +19 -0
- package/dist/archive-test-suite-5ADQ3KPQ.js +15 -0
- package/dist/archive-test-suite-NKZDZY3D.js +16 -0
- package/dist/assign-prompt-tag-5IUZXJ2T.js +23 -0
- package/dist/{assign-prompt-tag-VLXUWEKU.js → assign-prompt-tag-HBZLBIFD.js} +8 -4
- package/dist/{chunk-CDYQOY5U.js → chunk-3OCG3QPU.js} +7 -10
- package/dist/chunk-3YLN3ATJ.js +241 -0
- package/dist/chunk-5FNCQRCX.js +91 -0
- package/dist/chunk-6YZUOD34.js +55 -0
- package/dist/{chunk-WVI5CJ6S.js → chunk-7AQLPVFL.js} +2 -2
- package/dist/chunk-7VNSRCXO.js +129 -0
- package/dist/{chunk-7RHG56OH.js → chunk-B4J3PJLX.js} +11 -10
- package/dist/{chunk-ZXKLPC2E.js → chunk-BIIKE3EI.js} +1 -1
- package/dist/{chunk-37SMPMQS.js → chunk-DMM3JQ42.js} +7 -2
- package/dist/{chunk-NUFPTHKU.js → chunk-FOKVY3BK.js} +1 -1
- package/dist/{chunk-WT4PO4A3.js → chunk-H6WGMG2T.js} +10 -7
- package/dist/{chunk-TOXJQDIZ.js → chunk-HGELNIVY.js} +135 -51
- package/dist/{chunk-UJPXFA26.js → chunk-HHMNZAPD.js} +101 -74
- package/dist/{chunk-J42FWRJ2.js → chunk-I7ATIZED.js} +7 -7
- package/dist/{chunk-AQJO2EI5.js → chunk-ILZDO25L.js} +7 -10
- package/dist/{chunk-4QC7SA2L.js → chunk-J7PQKBLD.js} +884 -559
- package/dist/{chunk-YX3A3CFM.js → chunk-JRJPH75H.js} +7 -13
- package/dist/chunk-K2I7Z3LZ.js +28 -0
- package/dist/{chunk-5CCZFUXS.js → chunk-NKMTIHIJ.js} +6 -9
- package/dist/chunk-O7EMWEVJ.js +44 -0
- package/dist/chunk-PTDR56Z3.js +37 -0
- package/dist/chunk-RABYBFX5.js +43 -0
- package/dist/chunk-SUPUUC4W.js +64 -0
- package/dist/{chunk-SFB4MU6H.js → chunk-SXFC3FNH.js} +4 -4
- package/dist/chunk-U24EACC4.js +67 -0
- package/dist/chunk-UNJM3BIL.js +21 -0
- package/dist/{chunk-ZWIL4EFL.js → chunk-UTJCWXPZ.js} +4 -4
- package/dist/chunk-UWLE5T2F.js +312 -0
- package/dist/chunk-VMWJD732.js +57 -0
- package/dist/chunk-XUIJYNRJ.js +15 -0
- package/dist/chunk-Y34DHR5K.js +67 -0
- package/dist/chunk-YCARO42Z.js +516 -0
- package/dist/config-EAKW6F26.js +16 -0
- package/dist/config.cjs +109 -0
- package/dist/config.js +5 -4
- package/dist/{create-agent-7XHO6UIS.js → create-agent-AYZ3LB3V.js} +4 -4
- package/dist/create-agent-S5ZBCEFT.js +23 -0
- package/dist/create-annotation-LHNCLHYP.js +29 -0
- package/dist/{create-annotation-YQXRQC6A.js → create-annotation-VUSXULQK.js} +10 -5
- package/dist/{create-api-key-YUS36KBU.js → create-api-key-NNYKARMG.js} +5 -7
- package/dist/create-api-key-T4KSNPKB.js +24 -0
- package/dist/create-dashboard-DHVFMEU4.js +18 -0
- package/dist/{create-dashboard-4Z5JO5LB.js → create-dashboard-WTKKS5Z6.js} +4 -4
- package/dist/{create-dataset-E6NMSVX7.js → create-dataset-2MC4SD4O.js} +6 -6
- package/dist/create-dataset-LUP5PVDM.js +22 -0
- package/dist/create-dataset-records-NSKBZP3G.js +20 -0
- package/dist/{create-dataset-records-SKHPRD2K.js → create-dataset-records-W4GLN2FV.js} +5 -7
- package/dist/{create-evaluator-JXF5PF33.js → create-evaluator-643G6LXL.js} +4 -4
- package/dist/create-evaluator-HMTYO5SS.js +27 -0
- package/dist/create-mcp-server.cjs +9513 -0
- package/dist/create-mcp-server.js +2647 -5
- package/dist/create-project-6N7PIYRY.js +44 -0
- package/dist/{create-project-CS2CB57Y.js → create-project-KAIC46UY.js} +4 -4
- package/dist/{create-prompt-F5RMX3L3.js → create-prompt-E67LXIYT.js} +5 -7
- package/dist/create-prompt-PKJ7EDRR.js +37 -0
- package/dist/create-prompt-tag-4YO3FSJ3.js +17 -0
- package/dist/{create-prompt-tag-GMRWTEFR.js → create-prompt-tag-OPQUEXWB.js} +3 -3
- package/dist/create-scenario-5PJBMAXO.js +33 -0
- package/dist/{create-scenario-JDR2VB2H.js → create-scenario-UEM77OE7.js} +11 -4
- package/dist/create-test-suite-4IPXVSFQ.js +37 -0
- package/dist/create-test-suite-SZEPVXSE.js +36 -0
- package/dist/create-trigger-5HZSCRAN.js +49 -0
- package/dist/create-trigger-PRELMT6J.js +48 -0
- package/dist/delete-agent-JUIZWAXG.js +18 -0
- package/dist/{delete-agent-O3EEH4S5.js → delete-agent-QMEK3XHK.js} +4 -4
- package/dist/delete-annotation-HY3O2OGR.js +17 -0
- package/dist/{delete-annotation-XP6FQM7A.js → delete-annotation-VKIQWUYW.js} +4 -4
- package/dist/delete-dashboard-76N66XXL.js +18 -0
- package/dist/{delete-dashboard-RFUNYCNP.js → delete-dashboard-JVIVHNJM.js} +4 -4
- package/dist/delete-dataset-HQCR66MG.js +18 -0
- package/dist/{delete-dataset-3MJFRDLP.js → delete-dataset-WKRUW4FP.js} +5 -7
- package/dist/{delete-dataset-records-WPMU5GL5.js → delete-dataset-records-C2IQFFVQ.js} +5 -7
- package/dist/delete-dataset-records-SDUHQLLM.js +19 -0
- package/dist/delete-evaluator-4SNSCLEE.js +16 -0
- package/dist/delete-evaluator-QP3QHTLN.js +15 -0
- package/dist/delete-prompt-tag-NZ4JQMYG.js +17 -0
- package/dist/{delete-prompt-tag-KNMZVSPB.js → delete-prompt-tag-YYQ4VMAD.js} +3 -3
- package/dist/{delete-workflow-3NUXO46U.js → delete-workflow-5J46T73T.js} +4 -4
- package/dist/delete-workflow-JSWABL5F.js +17 -0
- 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-OOFIQKOG.js +139 -0
- package/dist/{discover-schema-L6QDPON3.js → discover-schema-55YJBFGQ.js} +181 -186
- package/dist/discover-schema-A33SLMXW.js +442 -0
- package/dist/get-agent-LJQX7OF4.js +69 -0
- package/dist/get-agent-OTIYUFZA.js +70 -0
- package/dist/get-analytics-DCS72353.js +80 -0
- package/dist/get-analytics-IQZKJHLW.js +79 -0
- package/dist/get-dashboard-5NYJEIX2.js +29 -0
- package/dist/{get-dashboard-KHBEGZGL.js → get-dashboard-QMTYDQAZ.js} +4 -4
- package/dist/get-dataset-ALSP7RTX.js +64 -0
- package/dist/get-dataset-X4B5JDG2.js +63 -0
- package/dist/{get-evaluator-ADMKVWYZ.js → get-evaluator-ISMC4LLI.js} +4 -4
- package/dist/get-evaluator-XEUZGZCH.js +47 -0
- package/dist/{get-project-RAK7URQJ.js → get-project-5VKROSDH.js} +4 -4
- package/dist/get-project-RM6FRCBK.js +26 -0
- package/dist/get-prompt-OWXJZHQQ.js +95 -0
- package/dist/get-prompt-W52DY36E.js +94 -0
- package/dist/get-run-plan-BE3M2AUX.js +59 -0
- package/dist/get-run-plan-RUXQ6PAX.js +58 -0
- package/dist/get-scenario-RNM7BAX2.js +37 -0
- package/dist/{get-scenario-ZTAJJL5T.js → get-scenario-YM4ODWW6.js} +8 -4
- package/dist/get-simulation-run-6GIATQE5.js +69 -0
- package/dist/{get-simulation-run-T2ZQWYH2.js → get-simulation-run-LCFSMPGQ.js} +33 -20
- package/dist/get-test-suite-GC2O7YH6.js +49 -0
- package/dist/get-test-suite-P5LJ6VLF.js +48 -0
- package/dist/get-trace-KBRVV4NN.js +45 -0
- package/dist/{get-trace-K7U234Q4.js → get-trace-SEF3FMR5.js} +11 -13
- package/dist/get-workflow-7PVED7JE.js +25 -0
- package/dist/{get-workflow-L5L2PSK3.js → get-workflow-YXULW4GC.js} +4 -4
- package/dist/{http-security-EU3CHTY7.js → http-security-DNLBNQZL.js} +2 -2
- package/dist/{http-server-YXHFPPGA.js → http-server-IR4QOS43.js} +4071 -342
- package/dist/index.js +60221 -38077
- package/dist/langwatch-api-annotations-6SA4OB4C.js +17 -0
- package/dist/{langwatch-api-annotations-FDAS6NQ7.js → langwatch-api-annotations-TBHLCQ5R.js} +4 -4
- package/dist/langwatch-api-dashboards-6EO2VVZW.js +17 -0
- package/dist/{langwatch-api-dashboards-JTVCS7ZJ.js → langwatch-api-dashboards-NHU5BZD7.js} +4 -4
- package/dist/langwatch-api-monitors-CBF3FGIM.js +47 -0
- package/dist/{langwatch-api-monitors-3J7UIQME.js → langwatch-api-monitors-YNWA2M5Y.js} +11 -16
- package/dist/langwatch-api-secrets-ADTOJELP.js +56 -0
- package/dist/langwatch-api-secrets-RNFO4LF2.js +55 -0
- package/dist/langwatch-api-triggers-KQDQC6L5.js +22 -0
- package/dist/langwatch-api-triggers-QS7HDIVW.js +23 -0
- package/dist/{langwatch-api-workflows-NBJX5KOG.js → langwatch-api-workflows-OKC4FXIF.js} +4 -4
- package/dist/langwatch-api-workflows-XGJE6SR5.js +15 -0
- package/dist/list-agents-HVYWEQMI.js +43 -0
- package/dist/list-agents-RBAOCF53.js +42 -0
- package/dist/list-annotations-HJH4NBLD.js +38 -0
- package/dist/{list-annotations-ZTVP4EEL.js → list-annotations-J4UAHSUN.js} +10 -5
- package/dist/{list-api-keys-CWD4UQT5.js → list-api-keys-7UTJRZDG.js} +10 -5
- package/dist/list-api-keys-A2PMV435.js +42 -0
- package/dist/list-dashboard-boards-OPWROHMG.js +33 -0
- package/dist/list-dashboard-boards-U2GJ7GC5.js +34 -0
- package/dist/{list-dashboards-PWG6P6KR.js → list-dashboards-ROSYFLDQ.js} +4 -4
- package/dist/list-dashboards-RQ635ZU7.js +32 -0
- package/dist/{list-dataset-records-IOE7LQXS.js → list-dataset-records-M5TKA6LK.js} +14 -10
- package/dist/list-dataset-records-WFM7F33C.js +43 -0
- package/dist/{list-datasets-ZT4JYUDT.js → list-datasets-B5X4P7BQ.js} +9 -13
- package/dist/list-datasets-THUKQHPX.js +56 -0
- package/dist/{list-evaluators-SJHC7VBH.js → list-evaluators-MYH2OVCI.js} +5 -7
- package/dist/list-evaluators-NLVWF6K7.js +32 -0
- package/dist/{list-model-providers-PPD2WPD2.js → list-model-providers-3JUGP4YI.js} +4 -4
- package/dist/list-model-providers-H3XKORFO.js +35 -0
- package/dist/{list-projects-K7QAIX2I.js → list-projects-6EJ5YYEW.js} +5 -7
- package/dist/list-projects-YNNSRMLC.js +40 -0
- package/dist/{list-prompt-tags-FOO6TNHB.js → list-prompt-tags-NVFQO6WX.js} +3 -3
- package/dist/list-prompt-tags-XUQTTAH4.js +23 -0
- package/dist/{list-prompts-SC2HAUFG.js → list-prompts-HSIMMHTF.js} +4 -6
- package/dist/list-prompts-IRI6AIXO.js +30 -0
- package/dist/list-run-plans-PX2XI6EK.js +46 -0
- package/dist/list-run-plans-QALLCN2K.js +45 -0
- package/dist/list-scenarios-QZRPVHS4.js +46 -0
- package/dist/list-scenarios-SSJQEMJP.js +45 -0
- package/dist/list-simulation-runs-KNOLGMDV.js +53 -0
- package/dist/{list-simulation-runs-KF5THG5H.js → list-simulation-runs-OEADLLQR.js} +19 -9
- package/dist/list-test-suites-ANAQBLDG.js +34 -0
- package/dist/list-test-suites-N4WVLBKK.js +35 -0
- package/dist/list-trigger-fires-JV3WFYYG.js +19 -0
- package/dist/list-trigger-fires-WTW4DVIW.js +20 -0
- package/dist/list-triggers-SQNIG35Q.js +45 -0
- package/dist/list-triggers-V4Y356AK.js +46 -0
- package/dist/{list-workflows-QSJWURCK.js → list-workflows-IMSX7SXU.js} +5 -7
- package/dist/list-workflows-ZHTX5LCL.js +33 -0
- package/dist/{rename-prompt-tag-EKWU5QF3.js → rename-prompt-tag-IQI7MHOI.js} +3 -3
- package/dist/rename-prompt-tag-PA2BRIE6.js +18 -0
- package/dist/rename-test-suite-4J7UX5S2.js +21 -0
- package/dist/rename-test-suite-NNVLMLKY.js +20 -0
- package/dist/report-issue-AS34ZMJF.js +898 -0
- package/dist/report-issue-DCZFLGDO.js +899 -0
- package/dist/rerun-run-plan-TG2V4WM4.js +22 -0
- package/dist/rerun-run-plan-ZI5OY3VA.js +21 -0
- package/dist/revoke-api-key-3J3ZA4UB.js +15 -0
- package/dist/{revoke-api-key-FTRTZMOF.js → revoke-api-key-SFMEFWJC.js} +4 -4
- package/dist/run-agent-W4VJP72Z.js +75 -0
- package/dist/run-agent-YNV6ZHW4.js +74 -0
- package/dist/run-plan-6C77GWG4.js +38 -0
- package/dist/run-plan-PAARQSI4.js +39 -0
- package/dist/run-query-KJDH544C.js +47 -0
- package/dist/run-query-T4QW2Z5O.js +46 -0
- package/dist/run-test-suite-SQJELEZX.js +26 -0
- package/dist/run-test-suite-STB6NUJM.js +25 -0
- package/dist/{run-workflow-QPXC627O.js → run-workflow-D6PQNBI6.js} +4 -4
- package/dist/{run-agent-6SM4XNA7.js → run-workflow-SP32SO5M.js} +10 -11
- package/dist/search-traces-HCBGOG6R.js +170 -0
- package/dist/search-traces-HSTQ6WTQ.js +171 -0
- package/dist/{set-model-provider-3WKT63ZN.js → set-model-provider-GF7NXUJA.js} +4 -4
- package/dist/set-model-provider-KDQ7C4EZ.js +33 -0
- package/dist/{update-agent-SMAEHLXH.js → update-agent-DWG43T2P.js} +4 -4
- package/dist/update-agent-MXNOBS4H.js +20 -0
- package/dist/update-dashboard-widget-CJKJLCDY.js +71 -0
- package/dist/update-dashboard-widget-CYQDS2NR.js +70 -0
- package/dist/update-dataset-DQH3OHOU.js +22 -0
- package/dist/{update-dataset-BDUK7TUO.js → update-dataset-SQZ6T4WX.js} +6 -6
- package/dist/{update-dataset-record-4ZSDRBSW.js → update-dataset-record-3AT4IPBC.js} +4 -4
- package/dist/update-dataset-record-7PLDGTMR.js +19 -0
- package/dist/update-evaluator-4LFTKFPT.js +24 -0
- package/dist/{update-evaluator-LS6TIBY7.js → update-evaluator-IGTX6PX4.js} +4 -4
- package/dist/{update-project-LKVYXENH.js → update-project-PLJIOZS6.js} +4 -4
- package/dist/update-project-QVHSJRUP.js +24 -0
- package/dist/update-prompt-GDKRYJI3.js +140 -0
- package/dist/update-prompt-MY263DYF.js +141 -0
- package/dist/update-scenario-7KA3JDXA.js +34 -0
- package/dist/{update-scenario-NEXCAQI7.js → update-scenario-MOHRQKAQ.js} +11 -4
- package/package.json +39 -44
- package/pyproject.toml +8 -8
- package/src/config.d.ts +4 -0
- package/src/config.ts +20 -29
- package/src/create-mcp-server.ts +1021 -596
- 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 +202 -21
- package/src/langwatch-api-annotations.ts +11 -12
- package/src/langwatch-api-api-keys.ts +8 -9
- package/src/langwatch-api-boards.ts +46 -0
- package/src/langwatch-api-dashboard-widgets.ts +112 -0
- package/src/langwatch-api-dashboards.ts +13 -10
- 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 +27 -9
- package/src/langwatch-api-query.ts +114 -0
- package/src/langwatch-api-run-plans.ts +140 -0
- package/src/langwatch-api-scenarios.ts +17 -10
- package/src/langwatch-api-secrets.ts +31 -24
- package/src/langwatch-api-simulation-runs.ts +10 -7
- package/src/langwatch-api-test-suites.ts +116 -0
- package/src/langwatch-api-triggers.ts +96 -34
- package/src/langwatch-api-workflows.ts +9 -9
- package/src/langwatch-api.ts +143 -109
- 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 +76 -0
- package/src/schemas/suite-fields.ts +132 -0
- package/src/schemas/triggers.ts +365 -0
- package/src/tools/add-dashboard-widget.ts +63 -0
- package/src/tools/archive-project.ts +2 -4
- package/src/tools/archive-run-plan.ts +10 -0
- package/src/tools/archive-scenario.ts +2 -4
- package/src/tools/archive-test-suite.ts +10 -0
- package/src/tools/assign-prompt-tag.ts +6 -2
- package/src/tools/create-agent.ts +1 -1
- package/src/tools/create-annotation.ts +7 -2
- package/src/tools/create-api-key.ts +4 -6
- package/src/tools/create-dashboard.ts +1 -1
- 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 +11 -5
- package/src/tools/create-test-suite.ts +38 -0
- package/src/tools/create-trigger.ts +55 -0
- package/src/tools/dashboard-exists.ts +25 -0
- package/src/tools/dashboard-widget-queries.ts +32 -0
- package/src/tools/delete-agent.ts +1 -1
- package/src/tools/delete-annotation.ts +1 -1
- package/src/tools/delete-dashboard.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 +86 -12
- 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 +54 -0
- package/src/tools/format-scenario.ts +12 -0
- package/src/tools/format-suite-details.ts +90 -0
- package/src/tools/get-agent.ts +54 -3
- package/src/tools/get-analytics.ts +52 -46
- package/src/tools/get-dashboard.ts +1 -1
- 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 +100 -37
- package/src/tools/get-run-plan.ts +60 -0
- package/src/tools/get-scenario.ts +6 -5
- package/src/tools/get-simulation-run.ts +32 -20
- package/src/tools/get-test-suite.ts +46 -0
- package/src/tools/get-trace.ts +16 -17
- package/src/tools/get-workflow.ts +1 -1
- package/src/tools/list-agents.ts +20 -3
- package/src/tools/list-annotations.ts +8 -5
- package/src/tools/list-api-keys.ts +7 -2
- package/src/tools/list-dashboard-boards.ts +28 -0
- package/src/tools/list-dashboards.ts +1 -1
- 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 +47 -0
- package/src/tools/list-scenarios.ts +26 -17
- package/src/tools/list-simulation-runs.ts +13 -5
- package/src/tools/list-test-suites.ts +35 -0
- 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 +15 -0
- package/src/tools/report-issue.ts +5 -9
- package/src/tools/rerun-run-plan.ts +18 -0
- package/src/tools/revoke-api-key.ts +2 -4
- package/src/tools/run-agent.ts +65 -14
- package/src/tools/run-experiment.ts +36 -37
- package/src/tools/run-plan.ts +46 -0
- package/src/tools/run-query.ts +47 -0
- package/src/tools/run-test-suite.ts +27 -0
- 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 +18 -0
- package/src/tools/update-agent.ts +1 -1
- package/src/tools/update-dashboard-widget.ts +97 -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 +185 -15
- package/src/tools/update-scenario.ts +11 -5
- package/src/tools/update-test-suite.ts +40 -0
- 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 +19 -12
- package/uv.lock +416 -296
- package/vitest.integration.config.js +10 -0
- package/vitest.scenario.config.js +9 -0
- package/.eslintrc.cjs +0 -36
- package/dist/archive-suite-4T6BSRS7.js +0 -16
- package/dist/chunk-77BNWQ3U.js +0 -86
- package/dist/chunk-A2LEVYQ5.js +0 -217
- package/dist/chunk-TJCXFNDT.js +0 -24
- package/dist/chunk-YZLYHLLI.js +0 -48
- package/dist/config.d.ts +0 -17
- package/dist/create-mcp-server.d.ts +0 -10
- package/dist/create-suite-LZS6QIAF.js +0 -39
- package/dist/delete-evaluator-33SP2JFX.js +0 -16
- package/dist/discover-evaluator-schema-XTAD4X7D.js +0 -2191
- package/dist/discover-scenario-schema-FE64QK2D.js +0 -67
- package/dist/get-agent-Y7MWZ65F.js +0 -29
- package/dist/get-analytics-TETCSOK6.js +0 -73
- package/dist/get-dataset-RCMU5VAH.js +0 -49
- package/dist/get-prompt-OY5B7TRI.js +0 -46
- package/dist/get-suite-J7JVWO6O.js +0 -45
- package/dist/index.d.ts +0 -2
- package/dist/langwatch-api-secrets-BUBSNCNO.js +0 -41
- package/dist/langwatch-api-triggers-EDFUCJN6.js +0 -31
- package/dist/list-agents-KFHKGPXV.js +0 -33
- package/dist/list-scenarios-F2WYNRIE.js +0 -41
- package/dist/list-suites-CRY4VWW6.js +0 -43
- package/dist/report-issue-XYVAPAYJ.js +0 -412
- package/dist/run-suite-NKZCJ2IN.js +0 -30
- package/dist/search-traces-A6HFKPLJ.js +0 -79
- package/dist/update-prompt-ODCRQRN6.js +0 -25
- package/dist/update-suite-SNO3GS7T.js +0 -40
- package/src/__tests__/all-tools.integration.test.ts +0 -1626
- 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 -288
- 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__/public-http-request-security.integration.test.ts +0 -118
- package/src/__tests__/report-issue.integration.test.ts +0 -147
- package/src/__tests__/scenario-tools.integration.test.ts +0 -286
- package/src/__tests__/scenario-tools.unit.test.ts +0 -188
- package/src/__tests__/schemas.unit.test.ts +0 -85
- package/src/__tests__/support/http-server-harness.ts +0 -138
- package/src/__tests__/tools.unit.test.ts +0 -924
- package/src/langwatch-api-suites.ts +0 -118
- package/src/schemas/filter-fields.ts +0 -119
- package/src/schemas/index.ts +0 -4
- package/src/tools/archive-suite.ts +0 -12
- package/src/tools/create-suite.ts +0 -42
- package/src/tools/get-suite.ts +0 -47
- package/src/tools/list-suites.ts +0 -43
- package/src/tools/run-suite.ts +0 -28
- package/src/tools/update-suite.ts +0 -44
package/src/langwatch-api.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
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
|
+
};
|
|
7
15
|
|
|
8
16
|
// --- Response types ---
|
|
9
17
|
|
|
@@ -46,7 +54,7 @@ export interface TraceDetailResponse {
|
|
|
46
54
|
error?: Record<string, unknown>;
|
|
47
55
|
ascii_tree?: string;
|
|
48
56
|
evaluations?: EvaluationSummary[];
|
|
49
|
-
spans?:
|
|
57
|
+
spans?: {
|
|
50
58
|
span_id: string;
|
|
51
59
|
name?: string;
|
|
52
60
|
type?: string;
|
|
@@ -61,7 +69,7 @@ export interface TraceDetailResponse {
|
|
|
61
69
|
tokens_estimated?: boolean;
|
|
62
70
|
cost?: number;
|
|
63
71
|
};
|
|
64
|
-
}
|
|
72
|
+
}[];
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
export interface AnalyticsBucket {
|
|
@@ -82,25 +90,44 @@ export interface PromptSummary {
|
|
|
82
90
|
version?: number;
|
|
83
91
|
}
|
|
84
92
|
|
|
93
|
+
export interface PromptTag {
|
|
94
|
+
name: string;
|
|
95
|
+
versionId: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export type PromptFieldList = { identifier: string; type: string }[];
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* A single versioned prompt payload.
|
|
102
|
+
*/
|
|
85
103
|
export interface PromptVersion {
|
|
104
|
+
versionId?: string;
|
|
86
105
|
version?: number;
|
|
87
|
-
commitMessage?: string;
|
|
106
|
+
commitMessage?: string | null;
|
|
88
107
|
model?: string;
|
|
89
|
-
|
|
108
|
+
/** Legacy single-text prompt body. */
|
|
109
|
+
prompt?: string;
|
|
110
|
+
messages?: { role: string; content: string }[];
|
|
111
|
+
temperature?: number;
|
|
112
|
+
maxTokens?: number;
|
|
113
|
+
responseFormat?: Record<string, unknown> | null;
|
|
114
|
+
/** Runtime parameters: an object map of name -> JSON value, not an array. */
|
|
115
|
+
parameters?: Record<string, unknown>;
|
|
116
|
+
inputs?: PromptFieldList;
|
|
117
|
+
outputs?: PromptFieldList;
|
|
118
|
+
/** All tags on the prompt; each names the version it currently points to. */
|
|
119
|
+
tags?: PromptTag[];
|
|
90
120
|
}
|
|
91
121
|
|
|
92
|
-
export interface PromptDetailResponse extends PromptSummary {
|
|
93
|
-
versions?: PromptVersion[];
|
|
94
|
-
model?: string;
|
|
95
|
-
messages?: Array<{ role: string; content: string }>;
|
|
96
|
-
prompt?: Array<{ role: string; content: string }>;
|
|
97
|
-
}
|
|
122
|
+
export interface PromptDetailResponse extends PromptSummary, PromptVersion {}
|
|
98
123
|
|
|
99
124
|
export interface PromptMutationResponse {
|
|
100
125
|
id?: string;
|
|
101
126
|
handle?: string;
|
|
102
127
|
name?: string;
|
|
103
128
|
latestVersionNumber?: number;
|
|
129
|
+
versionId?: string;
|
|
130
|
+
tags?: string[];
|
|
104
131
|
}
|
|
105
132
|
|
|
106
133
|
// --- HTTP client ---
|
|
@@ -111,10 +138,9 @@ export class LangWatchApiError extends Error {
|
|
|
111
138
|
readonly docsUrl?: string;
|
|
112
139
|
readonly fault?: HandledErrorFault;
|
|
113
140
|
/**
|
|
114
|
-
* The per-field failures behind this error, verbatim from the envelope.
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* request and an agent guessing again.
|
|
141
|
+
* The per-field failures behind this error, verbatim from the envelope. A validation failure
|
|
142
|
+
* carries the offending field and the values it would have accepted here — the difference
|
|
143
|
+
* between an agent correcting its own request and an agent guessing again.
|
|
118
144
|
*/
|
|
119
145
|
readonly reasons?: SerializedReason[];
|
|
120
146
|
|
|
@@ -150,45 +176,42 @@ interface ParsedErrorBody {
|
|
|
150
176
|
reasons?: SerializedReason[];
|
|
151
177
|
}
|
|
152
178
|
|
|
153
|
-
const VALID_FAULTS: readonly HandledErrorFault[] = [
|
|
179
|
+
const VALID_FAULTS: readonly HandledErrorFault[] = [
|
|
180
|
+
"customer",
|
|
181
|
+
"platform",
|
|
182
|
+
"provider",
|
|
183
|
+
"presumed_platform",
|
|
184
|
+
];
|
|
154
185
|
|
|
155
186
|
/**
|
|
156
|
-
* Parses an error response body as a handled-error envelope.
|
|
157
|
-
* REST shape (`{ error: "<code>", message, tips?, docsUrl?, fault? }`) and the
|
|
158
|
-
* serialized tRPC shape (`{ code, message?, tips?, docsUrl?, fault?, ... }`).
|
|
159
|
-
* Returns an empty object when the body is not a recognizable error envelope.
|
|
187
|
+
* Parses an error response body as a handled-error envelope.
|
|
160
188
|
*/
|
|
161
189
|
function parseErrorBody(responseBody: string): ParsedErrorBody {
|
|
162
190
|
try {
|
|
163
191
|
const parsed: unknown = JSON.parse(responseBody);
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
: undefined;
|
|
192
|
+
if (!isRecord(parsed)) return {};
|
|
193
|
+
const envelope = parsed;
|
|
194
|
+
// The canonical v1 envelope nests everything under `error`. Read the
|
|
195
|
+
// nested object as the body so one parser serves both generations.
|
|
196
|
+
const nestedValue = envelope.error;
|
|
197
|
+
const nested = isRecord(nestedValue) ? nestedValue : null;
|
|
198
|
+
const body = nested ?? envelope;
|
|
199
|
+
// `code` is the domain discriminant. The `error` fallback reads the
|
|
200
|
+
// legacy envelope some non-framework families still send; the framework's
|
|
201
|
+
// own unversioned union envelope, which used `error` for the HTTP status
|
|
202
|
+
// text, is gone (packages/api/adrs/002).
|
|
203
|
+
const code = readErrorCode(body);
|
|
177
204
|
const message = typeof body.message === "string" ? body.message : undefined;
|
|
178
205
|
if (code === undefined && message === undefined) {
|
|
179
206
|
return {};
|
|
180
207
|
}
|
|
181
|
-
const tips =
|
|
182
|
-
Array.isArray(body.tips) && body.tips.every((t) => typeof t === "string")
|
|
183
|
-
? (body.tips as string[])
|
|
184
|
-
: undefined;
|
|
208
|
+
const tips = readStringArray(body.tips);
|
|
185
209
|
const docsUrl = typeof body.docsUrl === "string" ? body.docsUrl : undefined;
|
|
186
210
|
const fault = VALID_FAULTS.includes(body.fault as HandledErrorFault)
|
|
187
211
|
? (body.fault as HandledErrorFault)
|
|
188
212
|
: undefined;
|
|
189
213
|
const reasons =
|
|
190
|
-
Array.isArray(body.reasons) &&
|
|
191
|
-
body.reasons.every((r) => !!r && typeof r === "object")
|
|
214
|
+
Array.isArray(body.reasons) && body.reasons.every((r) => !!r && typeof r === "object")
|
|
192
215
|
? (body.reasons as SerializedReason[])
|
|
193
216
|
: undefined;
|
|
194
217
|
return { code, message, tips, docsUrl, fault, reasons };
|
|
@@ -197,14 +220,29 @@ function parseErrorBody(responseBody: string): ParsedErrorBody {
|
|
|
197
220
|
}
|
|
198
221
|
}
|
|
199
222
|
|
|
223
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
224
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function readErrorCode(body: Record<string, unknown>): string | undefined {
|
|
228
|
+
if (typeof body.code === "string") return body.code;
|
|
229
|
+
if (typeof body.error === "string") return body.error;
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function readStringArray(value: unknown): string[] | undefined {
|
|
234
|
+
if (!Array.isArray(value) || !value.every(isString)) return undefined;
|
|
235
|
+
return value;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function isString(value: unknown): value is string {
|
|
239
|
+
return typeof value === "string";
|
|
240
|
+
}
|
|
241
|
+
|
|
200
242
|
/**
|
|
201
|
-
* The human line for one per-field failure: the field, what it would have
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
* This exists because the MCP transport's only channel to the caller is the
|
|
206
|
-
* error MESSAGE — an agent never sees the `reasons` array itself, so a
|
|
207
|
-
* rejection whose remedy lives only there is unfollowable.
|
|
243
|
+
* The human line for one per-field failure: the field, what it would have accepted, and what it
|
|
244
|
+
* got. Returns null when a reason names no field, so a generic nested error adds no noise to
|
|
245
|
+
* the message.
|
|
208
246
|
*/
|
|
209
247
|
function describeReason(reason: SerializedReason): string | null {
|
|
210
248
|
const meta = reason.meta;
|
|
@@ -224,22 +262,19 @@ function describeReason(reason: SerializedReason): string | null {
|
|
|
224
262
|
}
|
|
225
263
|
|
|
226
264
|
/**
|
|
227
|
-
* Sends an HTTP request to the LangWatch API.
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
* and handles JSON serialization/deserialization.
|
|
231
|
-
*
|
|
232
|
-
* @throws LangWatchApiError with status code and response body when the
|
|
233
|
-
* response is not OK.
|
|
265
|
+
* Sends an HTTP request to the LangWatch API. Builds the full URL from the configured endpoint,
|
|
266
|
+
* adds authentication, and handles JSON serialization/deserialization. @throws
|
|
267
|
+
* LangWatchApiError with status code and response body when the response is not OK.
|
|
234
268
|
*/
|
|
235
269
|
export async function makeRequest(
|
|
236
270
|
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE",
|
|
237
271
|
path: string,
|
|
238
|
-
body?: unknown
|
|
272
|
+
body?: unknown,
|
|
239
273
|
): Promise<unknown> {
|
|
240
274
|
const config = getConfig();
|
|
241
275
|
const url = config.endpoint + path;
|
|
242
276
|
const headers: Record<string, string> = {
|
|
277
|
+
...MCP_IDENTITY_HEADERS,
|
|
243
278
|
"X-Auth-Token": requireApiKey(),
|
|
244
279
|
};
|
|
245
280
|
if (config.projectId) {
|
|
@@ -259,9 +294,7 @@ export async function makeRequest(
|
|
|
259
294
|
if (!response.ok) {
|
|
260
295
|
const responseBody = await response.text();
|
|
261
296
|
const parsed = parseErrorBody(responseBody);
|
|
262
|
-
const lines = [
|
|
263
|
-
`LangWatch API error ${response.status}: ${parsed.message ?? responseBody}`,
|
|
264
|
-
];
|
|
297
|
+
const lines = [`LangWatch API error ${response.status}: ${parsed.message ?? responseBody}`];
|
|
265
298
|
const reasonLines = (parsed.reasons ?? [])
|
|
266
299
|
.map(describeReason)
|
|
267
300
|
.filter((line): line is string => line !== null);
|
|
@@ -274,18 +307,13 @@ export async function makeRequest(
|
|
|
274
307
|
if (parsed.docsUrl) {
|
|
275
308
|
lines.push(`Docs: ${parsed.docsUrl}`);
|
|
276
309
|
}
|
|
277
|
-
throw new LangWatchApiError(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
docsUrl: parsed.docsUrl,
|
|
285
|
-
fault: parsed.fault,
|
|
286
|
-
reasons: parsed.reasons,
|
|
287
|
-
},
|
|
288
|
-
);
|
|
310
|
+
throw new LangWatchApiError(lines.join("\n"), response.status, responseBody, {
|
|
311
|
+
code: parsed.code,
|
|
312
|
+
tips: parsed.tips,
|
|
313
|
+
docsUrl: parsed.docsUrl,
|
|
314
|
+
fault: parsed.fault,
|
|
315
|
+
reasons: parsed.reasons,
|
|
316
|
+
});
|
|
289
317
|
}
|
|
290
318
|
|
|
291
319
|
if (response.status === 204 || response.headers?.get("content-length") === "0") {
|
|
@@ -294,19 +322,28 @@ export async function makeRequest(
|
|
|
294
322
|
return response.json();
|
|
295
323
|
}
|
|
296
324
|
|
|
297
|
-
/**
|
|
325
|
+
/**
|
|
326
|
+
* Searches traces with optional filters and pagination. Paging is by `scrollId` only: pass the
|
|
327
|
+
* one the previous response returned, and stop when a response carries none.
|
|
328
|
+
*/
|
|
298
329
|
export async function searchTraces(params: {
|
|
299
330
|
query?: string;
|
|
331
|
+
/** Exact trace ids: a primary-key seek on trace_summaries, not a scan (ADR-164). */
|
|
332
|
+
traceIds?: string[];
|
|
300
333
|
filters?: Record<string, string[]>;
|
|
334
|
+
/**
|
|
335
|
+
* The Trace Explorer's query language, as one string. Combined server-side
|
|
336
|
+
* with `filters`, `query` and `traceIds` rather than replacing any of them.
|
|
337
|
+
*/
|
|
338
|
+
filter?: string;
|
|
301
339
|
startDate: number;
|
|
302
340
|
endDate: number;
|
|
303
341
|
pageSize?: number;
|
|
304
|
-
pageOffset?: number;
|
|
305
342
|
scrollId?: string;
|
|
306
343
|
format?: "digest" | "json";
|
|
307
344
|
}): Promise<SearchTracesResponse> {
|
|
308
345
|
const { format = "digest", ...rest } = params;
|
|
309
|
-
return makeRequest("POST", "/api/traces/search", {
|
|
346
|
+
return makeRequest("POST", "/api/v1/traces/search", {
|
|
310
347
|
...rest,
|
|
311
348
|
format,
|
|
312
349
|
}) as Promise<SearchTracesResponse>;
|
|
@@ -315,22 +352,22 @@ export async function searchTraces(params: {
|
|
|
315
352
|
/** Retrieves a single trace by its ID. */
|
|
316
353
|
export async function getTraceById(
|
|
317
354
|
traceId: string,
|
|
318
|
-
format: "digest" | "json" = "digest"
|
|
355
|
+
format: "digest" | "json" = "digest",
|
|
319
356
|
): Promise<TraceDetailResponse> {
|
|
320
357
|
return makeRequest(
|
|
321
358
|
"GET",
|
|
322
|
-
`/api/traces/${encodeURIComponent(traceId)}?format=${format}
|
|
359
|
+
`/api/v1/traces/${encodeURIComponent(traceId)}?format=${format}`,
|
|
323
360
|
) as Promise<TraceDetailResponse>;
|
|
324
361
|
}
|
|
325
362
|
|
|
326
363
|
/** Fetches analytics timeseries data for the given metrics and date range. */
|
|
327
364
|
export async function getAnalyticsTimeseries(params: {
|
|
328
|
-
series:
|
|
365
|
+
series: {
|
|
329
366
|
metric: string;
|
|
330
367
|
aggregation: string;
|
|
331
368
|
key?: string;
|
|
332
369
|
subkey?: string;
|
|
333
|
-
}
|
|
370
|
+
}[];
|
|
334
371
|
startDate: number;
|
|
335
372
|
endDate: number;
|
|
336
373
|
timeZone?: string;
|
|
@@ -340,20 +377,20 @@ export async function getAnalyticsTimeseries(params: {
|
|
|
340
377
|
}): Promise<AnalyticsTimeseriesResponse> {
|
|
341
378
|
return makeRequest(
|
|
342
379
|
"POST",
|
|
343
|
-
"/api/analytics/timeseries",
|
|
344
|
-
params
|
|
380
|
+
"/api/v1/analytics/timeseries",
|
|
381
|
+
params,
|
|
345
382
|
) as Promise<AnalyticsTimeseriesResponse>;
|
|
346
383
|
}
|
|
347
384
|
|
|
348
385
|
/** Lists all prompts in the project. */
|
|
349
386
|
export async function listPrompts(): Promise<PromptSummary[]> {
|
|
350
|
-
return makeRequest("GET", "/api/prompts") as Promise<PromptSummary[]>;
|
|
387
|
+
return makeRequest("GET", "/api/v1/prompts") as Promise<PromptSummary[]>;
|
|
351
388
|
}
|
|
352
389
|
|
|
353
390
|
/** Retrieves a single prompt by ID or handle. */
|
|
354
391
|
export async function getPrompt(
|
|
355
392
|
idOrHandle: string,
|
|
356
|
-
options?: { version?: number; tag?: string }
|
|
393
|
+
options?: { version?: number; tag?: string },
|
|
357
394
|
): Promise<PromptDetailResponse> {
|
|
358
395
|
const params = new URLSearchParams();
|
|
359
396
|
if (options?.version != null) params.set("version", String(options.version));
|
|
@@ -361,38 +398,42 @@ export async function getPrompt(
|
|
|
361
398
|
const query = params.toString() ? `?${params}` : "";
|
|
362
399
|
return makeRequest(
|
|
363
400
|
"GET",
|
|
364
|
-
`/api/prompts/${encodeURIComponent(idOrHandle)}${query}
|
|
401
|
+
`/api/v1/prompts/${encodeURIComponent(idOrHandle)}${query}`,
|
|
365
402
|
) as Promise<PromptDetailResponse>;
|
|
366
403
|
}
|
|
367
404
|
|
|
405
|
+
/** Lists all versions of a prompt (versioned data only). */
|
|
406
|
+
export async function getPromptVersions(idOrHandle: string): Promise<PromptVersion[]> {
|
|
407
|
+
return makeRequest(
|
|
408
|
+
"GET",
|
|
409
|
+
`/api/v1/prompts/${encodeURIComponent(idOrHandle)}/versions`,
|
|
410
|
+
) as Promise<PromptVersion[]>;
|
|
411
|
+
}
|
|
412
|
+
|
|
368
413
|
/** Creates a new prompt. */
|
|
369
414
|
export async function createPrompt(data: {
|
|
370
415
|
handle: string;
|
|
371
|
-
messages:
|
|
416
|
+
messages: { role: string; content: string }[];
|
|
372
417
|
model: string;
|
|
373
418
|
tags?: string[];
|
|
374
419
|
}): Promise<PromptMutationResponse> {
|
|
375
|
-
return makeRequest(
|
|
376
|
-
"POST",
|
|
377
|
-
"/api/prompts",
|
|
378
|
-
data
|
|
379
|
-
) as Promise<PromptMutationResponse>;
|
|
420
|
+
return makeRequest("POST", "/api/v1/prompts", data) as Promise<PromptMutationResponse>;
|
|
380
421
|
}
|
|
381
422
|
|
|
382
423
|
/** Updates an existing prompt by ID or handle. */
|
|
383
424
|
export async function updatePrompt(
|
|
384
425
|
idOrHandle: string,
|
|
385
426
|
data: {
|
|
386
|
-
messages?:
|
|
427
|
+
messages?: { role: string; content: string }[];
|
|
387
428
|
model?: string;
|
|
388
429
|
commitMessage: string;
|
|
389
430
|
tags?: string[];
|
|
390
|
-
}
|
|
431
|
+
},
|
|
391
432
|
): Promise<PromptMutationResponse> {
|
|
392
433
|
return makeRequest(
|
|
393
434
|
"PUT",
|
|
394
|
-
`/api/prompts/${encodeURIComponent(idOrHandle)}`,
|
|
395
|
-
data
|
|
435
|
+
`/api/v1/prompts/${encodeURIComponent(idOrHandle)}`,
|
|
436
|
+
data,
|
|
396
437
|
) as Promise<PromptMutationResponse>;
|
|
397
438
|
}
|
|
398
439
|
|
|
@@ -408,19 +449,19 @@ export async function assignPromptTag({
|
|
|
408
449
|
}): Promise<unknown> {
|
|
409
450
|
return makeRequest(
|
|
410
451
|
"PUT",
|
|
411
|
-
`/api/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,
|
|
412
|
-
{ versionId }
|
|
452
|
+
`/api/v1/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,
|
|
453
|
+
{ versionId },
|
|
413
454
|
);
|
|
414
455
|
}
|
|
415
456
|
|
|
416
457
|
/** Lists all prompt tag definitions for the organization. */
|
|
417
458
|
export async function listPromptTags(): Promise<unknown> {
|
|
418
|
-
return makeRequest("GET", "/api/prompts/tags");
|
|
459
|
+
return makeRequest("GET", "/api/v1/prompts/tags");
|
|
419
460
|
}
|
|
420
461
|
|
|
421
462
|
/** Creates a custom prompt tag definition. */
|
|
422
463
|
export async function createPromptTag(name: string): Promise<unknown> {
|
|
423
|
-
return makeRequest("POST", "/api/prompts/tags", { name });
|
|
464
|
+
return makeRequest("POST", "/api/v1/prompts/tags", { name });
|
|
424
465
|
}
|
|
425
466
|
|
|
426
467
|
/** Renames an existing prompt tag. */
|
|
@@ -431,17 +472,10 @@ export async function renamePromptTag({
|
|
|
431
472
|
tag: string;
|
|
432
473
|
name: string;
|
|
433
474
|
}): Promise<unknown> {
|
|
434
|
-
return makeRequest(
|
|
435
|
-
"PUT",
|
|
436
|
-
`/api/prompts/tags/${encodeURIComponent(tag)}`,
|
|
437
|
-
{ name }
|
|
438
|
-
);
|
|
475
|
+
return makeRequest("PUT", `/api/v1/prompts/tags/${encodeURIComponent(tag)}`, { name });
|
|
439
476
|
}
|
|
440
477
|
|
|
441
478
|
/** Deletes a prompt tag and all its assignments. */
|
|
442
479
|
export async function deletePromptTag(tag: string): Promise<unknown> {
|
|
443
|
-
return makeRequest(
|
|
444
|
-
"DELETE",
|
|
445
|
-
`/api/prompts/tags/${encodeURIComponent(tag)}`
|
|
446
|
-
);
|
|
480
|
+
return makeRequest("DELETE", `/api/v1/prompts/tags/${encodeURIComponent(tag)}`);
|
|
447
481
|
}
|
|
@@ -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"),
|