@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
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
|
|
3
|
-
vi.mock("../langwatch-api-scenarios.js", () => ({
|
|
4
|
-
listScenarios: vi.fn(),
|
|
5
|
-
getScenario: vi.fn(),
|
|
6
|
-
}));
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
listScenarios,
|
|
10
|
-
getScenario,
|
|
11
|
-
} from "../langwatch-api-scenarios.js";
|
|
12
|
-
|
|
13
|
-
import { handleListScenarios } from "../tools/list-scenarios.js";
|
|
14
|
-
import { handleGetScenario } from "../tools/get-scenario.js";
|
|
15
|
-
import { formatScenarioSchema } from "../tools/discover-scenario-schema.js";
|
|
16
|
-
|
|
17
|
-
const mockListScenarios = vi.mocked(listScenarios);
|
|
18
|
-
const mockGetScenario = vi.mocked(getScenario);
|
|
19
|
-
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
vi.clearAllMocks();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
describe("handleListScenarios()", () => {
|
|
25
|
-
const sampleScenarios = [
|
|
26
|
-
{
|
|
27
|
-
id: "scen_abc123",
|
|
28
|
-
name: "Login Flow Happy Path",
|
|
29
|
-
situation:
|
|
30
|
-
"User attempts to log in with valid credentials and expects a welcome message back from the system",
|
|
31
|
-
criteria: [
|
|
32
|
-
"Responds with a welcome message",
|
|
33
|
-
"Includes user name in greeting",
|
|
34
|
-
"Sets session cookie",
|
|
35
|
-
],
|
|
36
|
-
labels: ["auth", "happy-path"],
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
id: "scen_def456",
|
|
40
|
-
name: "Error Handling",
|
|
41
|
-
situation: "User sends malformed input",
|
|
42
|
-
criteria: ["Returns 400 status"],
|
|
43
|
-
labels: ["error"],
|
|
44
|
-
},
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
describe("when scenarios exist (digest mode)", () => {
|
|
48
|
-
let result: string;
|
|
49
|
-
|
|
50
|
-
beforeEach(async () => {
|
|
51
|
-
mockListScenarios.mockResolvedValue(sampleScenarios);
|
|
52
|
-
result = await handleListScenarios({});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("includes scenario id", () => {
|
|
56
|
-
expect(result).toContain("scen_abc123");
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("includes scenario name", () => {
|
|
60
|
-
expect(result).toContain("Login Flow Happy Path");
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("includes truncated situation preview", () => {
|
|
64
|
-
expect(result).toContain("User attempts to log in");
|
|
65
|
-
expect(result).not.toContain(
|
|
66
|
-
"User attempts to log in with valid credentials and expects a welcome message back from the system"
|
|
67
|
-
);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("shows criteria count per scenario", () => {
|
|
71
|
-
expect(result).toContain("3 criteria");
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("includes labels", () => {
|
|
75
|
-
expect(result).toContain("auth");
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("includes all scenarios in the list", () => {
|
|
79
|
-
expect(result).toContain("scen_def456");
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
/** @scenario Agent lists all scenarios in a project */
|
|
83
|
-
it("includes the total count header", () => {
|
|
84
|
-
expect(result).toContain("# Scenarios (2 total)");
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
describe("when no scenarios exist", () => {
|
|
89
|
-
let result: string;
|
|
90
|
-
|
|
91
|
-
beforeEach(async () => {
|
|
92
|
-
mockListScenarios.mockResolvedValue([]);
|
|
93
|
-
result = await handleListScenarios({});
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
/** @scenario Agent lists scenarios when none exist */
|
|
97
|
-
it("returns a no-scenarios message", () => {
|
|
98
|
-
expect(result).toContain("No scenarios found");
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it("includes a tip to use platform_create_scenario", () => {
|
|
102
|
-
expect(result).toContain("platform_create_scenario");
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
describe("when format is json", () => {
|
|
107
|
-
it("returns valid parseable JSON matching the scenario structure", async () => {
|
|
108
|
-
mockListScenarios.mockResolvedValue(sampleScenarios);
|
|
109
|
-
const result = await handleListScenarios({ format: "json" });
|
|
110
|
-
expect(JSON.parse(result)).toEqual(sampleScenarios);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
describe("handleGetScenario()", () => {
|
|
116
|
-
const sampleScenario = {
|
|
117
|
-
id: "scen_abc123",
|
|
118
|
-
name: "Login Flow Happy Path",
|
|
119
|
-
situation: "User attempts to log in with valid credentials",
|
|
120
|
-
criteria: [
|
|
121
|
-
"Responds with a welcome message",
|
|
122
|
-
"Includes user name in greeting",
|
|
123
|
-
],
|
|
124
|
-
labels: ["auth", "happy-path"],
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
describe("when format is digest", () => {
|
|
128
|
-
let result: string;
|
|
129
|
-
|
|
130
|
-
beforeEach(async () => {
|
|
131
|
-
mockGetScenario.mockResolvedValue(sampleScenario);
|
|
132
|
-
result = await handleGetScenario({ scenarioId: "scen_abc123" });
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
/** @scenario Agent gets full details of a scenario */
|
|
136
|
-
it("includes the scenario name in the heading", () => {
|
|
137
|
-
expect(result).toContain("# Scenario: Login Flow Happy Path");
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it("includes the situation", () => {
|
|
141
|
-
expect(result).toContain("User attempts to log in with valid credentials");
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it("includes each criteria item", () => {
|
|
145
|
-
expect(result).toContain("- Responds with a welcome message");
|
|
146
|
-
expect(result).toContain("- Includes user name in greeting");
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it("includes labels", () => {
|
|
150
|
-
expect(result).toContain("auth, happy-path");
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
describe("when format is json", () => {
|
|
155
|
-
it("returns valid parseable JSON matching the scenario structure", async () => {
|
|
156
|
-
mockGetScenario.mockResolvedValue(sampleScenario);
|
|
157
|
-
const result = await handleGetScenario({
|
|
158
|
-
scenarioId: "scen_abc123",
|
|
159
|
-
format: "json",
|
|
160
|
-
});
|
|
161
|
-
expect(JSON.parse(result)).toEqual(sampleScenario);
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
describe("formatScenarioSchema()", () => {
|
|
167
|
-
it("includes field descriptions with required/optional annotations", () => {
|
|
168
|
-
const result = formatScenarioSchema();
|
|
169
|
-
expect(result).toContain("**name** (required)");
|
|
170
|
-
expect(result).toContain("**situation** (required)");
|
|
171
|
-
expect(result).toContain("**criteria** (array of strings)");
|
|
172
|
-
expect(result).toContain("**labels** (array of strings)");
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it("includes all target types with descriptions", () => {
|
|
176
|
-
const result = formatScenarioSchema();
|
|
177
|
-
expect(result).toContain("**prompt**: Test a prompt template");
|
|
178
|
-
expect(result).toContain("**http**: Test an HTTP endpoint");
|
|
179
|
-
expect(result).toContain("**code**: Test a code function");
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it("includes authoring guidance for situations and criteria", () => {
|
|
183
|
-
const result = formatScenarioSchema();
|
|
184
|
-
expect(result).toContain("## Writing a Good Situation");
|
|
185
|
-
expect(result).toContain("## Writing Good Criteria");
|
|
186
|
-
expect(result).toContain("Specific and testable");
|
|
187
|
-
});
|
|
188
|
-
});
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { filterFields } from "../schemas/filter-fields.js";
|
|
3
|
-
import { analyticsMetrics } from "../schemas/analytics-metrics.js";
|
|
4
|
-
import { analyticsGroups } from "../schemas/analytics-groups.js";
|
|
5
|
-
|
|
6
|
-
describe("schemas", () => {
|
|
7
|
-
describe("filterFields", () => {
|
|
8
|
-
it("has at least 22 entries", () => {
|
|
9
|
-
expect(filterFields.length).toBeGreaterThanOrEqual(22);
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it("has non-empty field and description for every entry", () => {
|
|
13
|
-
for (const entry of filterFields) {
|
|
14
|
-
expect(entry.field).toBeTruthy();
|
|
15
|
-
expect(entry.description).toBeTruthy();
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("contains expected filter fields", () => {
|
|
20
|
-
const fieldNames = filterFields.map((f) => f.field);
|
|
21
|
-
expect(fieldNames).toContain("topics.topics");
|
|
22
|
-
expect(fieldNames).toContain("metadata.user_id");
|
|
23
|
-
expect(fieldNames).toContain("spans.model");
|
|
24
|
-
expect(fieldNames).toContain("evaluations.passed");
|
|
25
|
-
expect(fieldNames).toContain("events.event_type");
|
|
26
|
-
expect(fieldNames).toContain("annotations.hasAnnotation");
|
|
27
|
-
expect(fieldNames).toContain("sentiment.input_sentiment");
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
describe("analyticsMetrics", () => {
|
|
32
|
-
it("covers expected categories", () => {
|
|
33
|
-
const categories = new Set(analyticsMetrics.map((m) => m.category));
|
|
34
|
-
expect(categories).toContain("metadata");
|
|
35
|
-
expect(categories).toContain("performance");
|
|
36
|
-
expect(categories).toContain("evaluations");
|
|
37
|
-
expect(categories).toContain("sentiment");
|
|
38
|
-
expect(categories).toContain("events");
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("has non-empty allowedAggregations for every metric", () => {
|
|
42
|
-
for (const metric of analyticsMetrics) {
|
|
43
|
-
expect(metric.allowedAggregations.length).toBeGreaterThan(0);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("has non-empty name, label, and description for every metric", () => {
|
|
48
|
-
for (const metric of analyticsMetrics) {
|
|
49
|
-
expect(metric.name).toBeTruthy();
|
|
50
|
-
expect(metric.label).toBeTruthy();
|
|
51
|
-
expect(metric.description).toBeTruthy();
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("contains expected metrics", () => {
|
|
56
|
-
const names = analyticsMetrics.map((m) => `${m.category}.${m.name}`);
|
|
57
|
-
expect(names).toContain("metadata.trace_id");
|
|
58
|
-
expect(names).toContain("performance.completion_time");
|
|
59
|
-
expect(names).toContain("performance.total_cost");
|
|
60
|
-
expect(names).toContain("evaluations.evaluation_score");
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
describe("analyticsGroups", () => {
|
|
65
|
-
it("has at least 10 entries", () => {
|
|
66
|
-
expect(analyticsGroups.length).toBeGreaterThanOrEqual(10);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it("has non-empty name, label, and description for every group", () => {
|
|
70
|
-
for (const group of analyticsGroups) {
|
|
71
|
-
expect(group.name).toBeTruthy();
|
|
72
|
-
expect(group.label).toBeTruthy();
|
|
73
|
-
expect(group.description).toBeTruthy();
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it("contains expected group-by options", () => {
|
|
78
|
-
const names = analyticsGroups.map((g) => g.name);
|
|
79
|
-
expect(names).toContain("topics.topics");
|
|
80
|
-
expect(names).toContain("metadata.user_id");
|
|
81
|
-
expect(names).toContain("metadata.model");
|
|
82
|
-
expect(names).toContain("events.event_type");
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
});
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared fixtures for the standalone MCP HTTP server tests.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { expect, vi } from "vitest";
|
|
6
|
-
|
|
7
|
-
import type { ApiKeyVerifier } from "../../http-security.js";
|
|
8
|
-
import { startHttpServer } from "../../http-server.js";
|
|
9
|
-
|
|
10
|
-
/** Standard headers the MCP Streamable HTTP protocol requires on POST. */
|
|
11
|
-
export const MCP_POST_HEADERS = {
|
|
12
|
-
"Content-Type": "application/json",
|
|
13
|
-
Accept: "application/json, text/event-stream",
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const VALID_KEY = "sk-lw-valid-key";
|
|
17
|
-
export const OTHER_VALID_KEY = "sk-lw-other-valid-key";
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Stands in for the LangWatch API. The standalone server has no database, so
|
|
21
|
-
* it asks the API whether a key is real; here a fixed list is.
|
|
22
|
-
*/
|
|
23
|
-
export function countingVerifier(validKeys: string[]) {
|
|
24
|
-
const verify = vi.fn(async (apiKey: string) => validKeys.includes(apiKey));
|
|
25
|
-
const verifier: ApiKeyVerifier = {
|
|
26
|
-
verify,
|
|
27
|
-
sweep: () => undefined,
|
|
28
|
-
clear: () => undefined,
|
|
29
|
-
};
|
|
30
|
-
return { verifier, verify };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** A verifier whose accepted keys can change mid-test, to model revocation. */
|
|
34
|
-
export function revocableVerifier(initialKeys: string[]) {
|
|
35
|
-
const live = new Set(initialKeys);
|
|
36
|
-
const verifier: ApiKeyVerifier = {
|
|
37
|
-
verify: async (apiKey: string) => live.has(apiKey),
|
|
38
|
-
sweep: () => undefined,
|
|
39
|
-
clear: () => undefined,
|
|
40
|
-
};
|
|
41
|
-
return { verifier, revoke: (apiKey: string) => live.delete(apiKey) };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface Harness {
|
|
45
|
-
baseUrl: string;
|
|
46
|
-
close: () => Promise<void>;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export async function startHarness(
|
|
50
|
-
options: Parameters<typeof startHttpServer>[0]
|
|
51
|
-
): Promise<Harness> {
|
|
52
|
-
const { server, port, host } = await startHttpServer(options);
|
|
53
|
-
return {
|
|
54
|
-
baseUrl: `http://${host === "0.0.0.0" ? "127.0.0.1" : host}:${port}`,
|
|
55
|
-
close: () =>
|
|
56
|
-
new Promise<void>((resolve) => {
|
|
57
|
-
server.close(() => resolve());
|
|
58
|
-
}),
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function initializeBody(): string {
|
|
63
|
-
return JSON.stringify({
|
|
64
|
-
jsonrpc: "2.0",
|
|
65
|
-
method: "initialize",
|
|
66
|
-
params: {
|
|
67
|
-
protocolVersion: "2025-03-26",
|
|
68
|
-
capabilities: {},
|
|
69
|
-
clientInfo: { name: "test-client", version: "1.0.0" },
|
|
70
|
-
},
|
|
71
|
-
id: 1,
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function toolsListBody(): string {
|
|
76
|
-
return JSON.stringify({ jsonrpc: "2.0", method: "tools/list", id: 2 });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/** Opens a Streamable HTTP session and returns its id. */
|
|
80
|
-
export async function openSession({
|
|
81
|
-
baseUrl,
|
|
82
|
-
apiKey = VALID_KEY,
|
|
83
|
-
}: {
|
|
84
|
-
baseUrl: string;
|
|
85
|
-
apiKey?: string;
|
|
86
|
-
}): Promise<string> {
|
|
87
|
-
const response = await fetch(`${baseUrl}/mcp`, {
|
|
88
|
-
method: "POST",
|
|
89
|
-
headers: { ...MCP_POST_HEADERS, Authorization: `Bearer ${apiKey}` },
|
|
90
|
-
body: initializeBody(),
|
|
91
|
-
});
|
|
92
|
-
expect(response.status).toBe(200);
|
|
93
|
-
await response.text();
|
|
94
|
-
return response.headers.get("mcp-session-id")!;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Reads an SSE stream until the endpoint event carrying the session id has
|
|
99
|
-
* arrived. A single read can return a partial frame, so waiting for the
|
|
100
|
-
* pattern rather than the first chunk keeps this from failing intermittently.
|
|
101
|
-
*/
|
|
102
|
-
export async function readSessionId(response: Response): Promise<string> {
|
|
103
|
-
const reader = response.body!.getReader();
|
|
104
|
-
const decoder = new TextDecoder();
|
|
105
|
-
let buffered = "";
|
|
106
|
-
|
|
107
|
-
for (let reads = 0; reads < 20; reads++) {
|
|
108
|
-
const { value, done } = await reader.read();
|
|
109
|
-
if (done) break;
|
|
110
|
-
buffered += decoder.decode(value, { stream: true });
|
|
111
|
-
const match = /sessionId=([\w-]+)/.exec(buffered);
|
|
112
|
-
if (match?.[1]) return match[1];
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
throw new Error(`No session id in SSE stream. Received: ${buffered}`);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Sends `request` repeatedly until it answers 429, and returns that response
|
|
120
|
-
* along with how many attempts it took. Returns `rejected: undefined` when the
|
|
121
|
-
* limit never triggered within `maxAttempts`.
|
|
122
|
-
*/
|
|
123
|
-
export async function requestUntilThrottled({
|
|
124
|
-
request,
|
|
125
|
-
maxAttempts = 30,
|
|
126
|
-
}: {
|
|
127
|
-
request: (attempt: number) => Promise<Response>;
|
|
128
|
-
maxAttempts?: number;
|
|
129
|
-
}): Promise<{ attempts: number; rejected: Response | undefined }> {
|
|
130
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
131
|
-
const response = await request(attempt);
|
|
132
|
-
if (response.status === 429) {
|
|
133
|
-
return { attempts: attempt + 1, rejected: response };
|
|
134
|
-
}
|
|
135
|
-
await response.text();
|
|
136
|
-
}
|
|
137
|
-
return { attempts: maxAttempts, rejected: undefined };
|
|
138
|
-
}
|