@langwatch/mcp-server 1.0.0 → 2.1.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/.python-version +1 -0
- package/CHANGELOG.md +110 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +86 -4
- package/dist/{archive-project-MK3673A7.js → archive-project-W3IKI7UL.js} +5 -5
- package/dist/archive-run-plan-474OKHHU.js +16 -0
- package/dist/{archive-scenario-KATSXRIN.js → archive-scenario-V5UNYK26.js} +5 -5
- package/dist/archive-test-suite-O7FLDMXK.js +16 -0
- package/dist/{assign-prompt-tag-E3C5W6PI.js → assign-prompt-tag-Q46WRB6P.js} +4 -4
- package/dist/chunk-56OGTS24.js +44 -0
- package/dist/chunk-6DJDEXET.js +63 -0
- package/dist/chunk-7E4FZIYJ.js +15 -0
- package/dist/{chunk-J45SVWPR.js → chunk-AN4OUA4D.js} +2 -2
- package/dist/chunk-CKNAH5TG.js +74 -0
- package/dist/{chunk-CE6QMZOP.js → chunk-EYXMLE5X.js} +86 -11
- package/dist/{chunk-XY4STOBE.js → chunk-G4ZAZTZW.js} +2 -2
- package/dist/{chunk-5UWY24RP.js → chunk-GELJ2MQR.js} +12 -3
- package/dist/chunk-HV4DWKBI.js +46 -0
- package/dist/chunk-JR6DJZOU.js +49 -0
- package/dist/{chunk-DAIQKS27.js → chunk-JTQJRNFJ.js} +2 -2
- package/dist/{chunk-WWMDHZZV.js → chunk-K37ZNPXK.js} +2 -2
- package/dist/{chunk-EU22L52K.js → chunk-OJLYYJWI.js} +2 -2
- package/dist/{chunk-Y3HDZ6OW.js → chunk-QAMP3CGR.js} +2 -2
- package/dist/{chunk-VYPSKRPN.js → chunk-QRO35SOM.js} +347 -146
- package/dist/{chunk-O3LWVN67.js → chunk-RVAE2MEA.js} +2 -2
- package/dist/{chunk-UXXA4D6K.js → chunk-S4GVX36W.js} +2 -2
- package/dist/{chunk-BJ7B4R26.js → chunk-SAS5OB7F.js} +18 -2
- package/dist/{chunk-RYRB2YVJ.js → chunk-SR6QPRIE.js} +2 -2
- package/dist/chunk-UF6XIGYR.js +58 -0
- package/dist/{chunk-T7WJVS2N.js → chunk-UFOYFYI7.js} +2 -2
- package/dist/chunk-UJPXFA26.js +267 -0
- package/dist/{chunk-KOO5733S.js → chunk-WT4PO4A3.js} +8 -2
- package/dist/config.js +2 -2
- package/dist/{create-agent-7W57J7MT.js → create-agent-JFJ2K6X3.js} +5 -5
- package/dist/{create-annotation-W2XELBCQ.js → create-annotation-EUXXQ6NS.js} +5 -5
- package/dist/{create-api-key-MKRXKFJM.js → create-api-key-BGBB76JX.js} +5 -5
- package/dist/{create-dashboard-QGL7IODC.js → create-dashboard-Z76AIPLS.js} +5 -5
- package/dist/{create-dataset-3PH7A4HG.js → create-dataset-FD5VAXU4.js} +5 -5
- package/dist/{create-dataset-records-4DZS3VRL.js → create-dataset-records-WQUXXOHI.js} +5 -5
- package/dist/{create-evaluator-YWH6NC4M.js → create-evaluator-6NV33Z52.js} +5 -5
- package/dist/create-mcp-server.js +9 -4
- package/dist/{create-project-BOBQ32C5.js → create-project-ZQ7TFIO2.js} +5 -5
- package/dist/{create-prompt-FLCFGITE.js → create-prompt-BS6QRCUU.js} +4 -4
- package/dist/{create-prompt-tag-EMPNIKEA.js → create-prompt-tag-FCQ5ELSQ.js} +4 -4
- package/dist/{create-scenario-BSBIHUL6.js → create-scenario-DRPTPXU3.js} +12 -5
- package/dist/create-test-suite-ZIZCCFJ4.js +37 -0
- package/dist/{delete-agent-7MSYNY5E.js → delete-agent-SA4JMUZF.js} +5 -5
- package/dist/{delete-annotation-ZT5IGN24.js → delete-annotation-X3KKK7QY.js} +5 -5
- package/dist/{delete-dashboard-BTIY5S3L.js → delete-dashboard-LYMRPF27.js} +5 -5
- package/dist/{delete-dataset-U45HQHPR.js → delete-dataset-W6EZ44HY.js} +5 -5
- package/dist/{delete-dataset-records-R43IMAWB.js → delete-dataset-records-7CNOTALB.js} +5 -5
- package/dist/{delete-evaluator-U6JMQ6C7.js → delete-evaluator-RKYC4TNB.js} +5 -5
- package/dist/{delete-prompt-tag-4EV4TDHB.js → delete-prompt-tag-QB3OCZUV.js} +4 -4
- package/dist/{delete-workflow-5QYALXEL.js → delete-workflow-NG2VXYYM.js} +5 -5
- package/dist/{discover-evaluator-schema-MRGHVNTT.js → discover-evaluator-schema-ESSHQGPY.js} +58 -321
- package/dist/{discover-scenario-schema-UPBTCWPG.js → discover-scenario-schema-W7KBXA4J.js} +54 -2
- package/dist/{discover-schema-ICGXPHUW.js → discover-schema-L6QDPON3.js} +2 -2
- package/dist/get-agent-7THF7HCU.js +66 -0
- package/dist/{get-analytics-PVERWOA5.js → get-analytics-R6AZD3AW.js} +4 -4
- package/dist/{get-dashboard-ZZPC3WMD.js → get-dashboard-P4WWVHFU.js} +5 -5
- package/dist/{get-dataset-25TB2LQH.js → get-dataset-AKTYSQDI.js} +5 -5
- package/dist/{get-evaluator-3FTRQKEC.js → get-evaluator-RZ44UIN6.js} +5 -5
- package/dist/{get-project-5OAXYC57.js → get-project-QSQEAB33.js} +5 -5
- package/dist/get-prompt-GVKXF5NL.js +100 -0
- package/dist/get-run-plan-NY7J5GRE.js +61 -0
- package/dist/{get-scenario-DSSTR6FI.js → get-scenario-Q3LLQE4T.js} +9 -5
- package/dist/{get-simulation-run-RQPMS2MC.js → get-simulation-run-WINEYDMK.js} +14 -5
- package/dist/get-test-suite-4HKA7OKS.js +49 -0
- package/dist/{get-trace-O5VT3NAC.js → get-trace-RCUV7N4O.js} +4 -4
- package/dist/{get-workflow-3EZDOEIF.js → get-workflow-EEOC7Y45.js} +5 -5
- package/dist/http-security-EU3CHTY7.js +26 -0
- package/dist/{http-server-2ACJ3CXW.js → http-server-WCDUARTH.js} +1038 -693
- package/dist/index.js +6437 -4020
- package/dist/{langwatch-api-annotations-E65MI3WZ.js → langwatch-api-annotations-6DHVZWUK.js} +5 -5
- package/dist/{langwatch-api-dashboards-QCDECRCY.js → langwatch-api-dashboards-2KJL2M42.js} +5 -5
- package/dist/{langwatch-api-monitors-UIO2KTDV.js → langwatch-api-monitors-6ISFJ7WX.js} +4 -4
- package/dist/{langwatch-api-secrets-4T2EKSJ7.js → langwatch-api-secrets-OEBD6GBU.js} +4 -4
- package/dist/{langwatch-api-triggers-MPOEKPUY.js → langwatch-api-triggers-5E6DDGX6.js} +4 -4
- package/dist/langwatch-api-workflows-6UJL5U4Z.js +16 -0
- package/dist/list-agents-AMVDQPQL.js +43 -0
- package/dist/{list-annotations-CGX5BT7E.js → list-annotations-6PR5NLIC.js} +5 -5
- package/dist/{list-api-keys-JLWJPFRX.js → list-api-keys-GVPNBIHQ.js} +5 -5
- package/dist/{list-dashboards-RNIWX3TX.js → list-dashboards-Z3BZKDGF.js} +5 -5
- package/dist/{list-dataset-records-B5MHZR66.js → list-dataset-records-O67HZ35Y.js} +5 -5
- package/dist/{list-datasets-BVCAMQCP.js → list-datasets-WXZL6UMP.js} +5 -5
- package/dist/{list-evaluators-65FBTL2U.js → list-evaluators-PAX72WCN.js} +5 -5
- package/dist/{list-model-providers-GRK3I3VV.js → list-model-providers-VVLZMLCX.js} +5 -5
- package/dist/{list-projects-JLMBFMW3.js → list-projects-AQVI6SUK.js} +5 -5
- package/dist/{list-prompt-tags-UHNWDGQI.js → list-prompt-tags-WZFBJOHG.js} +4 -4
- package/dist/{list-prompts-7254B3U7.js → list-prompts-BQOHRHYT.js} +4 -4
- package/dist/list-run-plans-UBAU2DGH.js +46 -0
- package/dist/{list-scenarios-46YNICKM.js → list-scenarios-MS4IUIVM.js} +10 -7
- package/dist/{list-simulation-runs-LGNEFNPN.js → list-simulation-runs-D6YF4ZOU.js} +13 -7
- package/dist/list-test-suites-L7R2O6DR.js +35 -0
- package/dist/{list-workflows-MLQDM6CP.js → list-workflows-6MV4XJHF.js} +5 -5
- package/dist/{rename-prompt-tag-RHQMNEQL.js → rename-prompt-tag-K5LQ4CY6.js} +4 -4
- package/dist/rename-test-suite-NTYHAO5X.js +21 -0
- package/dist/report-issue-RHZZ33IS.js +885 -0
- package/dist/rerun-run-plan-MUDWJBE4.js +22 -0
- package/dist/{revoke-api-key-3Y35EMBT.js → revoke-api-key-6LAZ3QZZ.js} +5 -5
- package/dist/run-agent-CAGWGTYT.js +72 -0
- package/dist/run-plan-T4ZYOZGA.js +39 -0
- package/dist/run-test-suite-L4MZ7G4D.js +26 -0
- package/dist/{run-workflow-5LVBZYLS.js → run-workflow-DFIS23AP.js} +5 -5
- package/dist/{search-traces-U4HLOCZ2.js → search-traces-4XTJYXIK.js} +4 -4
- package/dist/{set-model-provider-V3M5CDIY.js → set-model-provider-XRNMFOVR.js} +5 -5
- package/dist/{update-agent-47RZIHS7.js → update-agent-DUWNYBNA.js} +5 -5
- package/dist/{update-dataset-G6QJJGS5.js → update-dataset-YSOMDCOB.js} +5 -5
- package/dist/{update-dataset-record-RMWLSWCS.js → update-dataset-record-DEA2ITYR.js} +5 -5
- package/dist/{update-evaluator-SFRRI5Q3.js → update-evaluator-NH7Q5GWV.js} +5 -5
- package/dist/{update-project-PI5DWBVK.js → update-project-Q26FBSYH.js} +5 -5
- package/dist/update-prompt-ZQQ2C3KU.js +143 -0
- package/dist/{update-scenario-G3IU2UIB.js → update-scenario-WUX34JAR.js} +12 -5
- package/package.json +8 -9
- package/pyproject.toml +5 -5
- package/src/__tests__/agent-tools.unit.test.ts +257 -0
- package/src/__tests__/all-tools.integration.test.ts +321 -75
- package/src/__tests__/config.unit.test.ts +33 -0
- package/src/__tests__/docker.integration.test.ts +91 -7
- package/src/__tests__/documentation-fetch-security.integration.test.ts +8 -2
- package/src/__tests__/feature-map-tool-drift.unit.test.ts +93 -0
- package/src/__tests__/http-security-origin.unit.test.ts +97 -0
- package/src/__tests__/http-security-sessions.unit.test.ts +209 -0
- package/src/__tests__/http-security-verifier.unit.test.ts +248 -0
- package/src/__tests__/http-server-allocation.integration.test.ts +279 -0
- package/src/__tests__/http-server-origin.integration.test.ts +169 -0
- package/src/__tests__/http-server-session-auth.integration.test.ts +341 -0
- package/src/__tests__/http-transport.integration.test.ts +85 -87
- package/src/__tests__/integration.integration.test.ts +7 -11
- package/src/__tests__/prompt-response-types.unit.test.ts +51 -0
- package/src/__tests__/prompts.integration.test.ts +736 -0
- package/src/__tests__/run-plan-tools.unit.test.ts +565 -0
- package/src/__tests__/scenario-tools.unit.test.ts +19 -0
- package/src/__tests__/simulation-run-tools.unit.test.ts +116 -0
- package/src/__tests__/support/http-server-harness.ts +138 -0
- package/src/__tests__/test-suite-tools.unit.test.ts +615 -0
- package/src/__tests__/{tools.unit.test.ts → tools.integration.test.ts} +31 -59
- package/src/config.ts +17 -2
- package/src/create-mcp-server.ts +334 -55
- package/src/http-security.ts +492 -0
- package/src/http-server.ts +536 -152
- package/src/index.ts +49 -2
- package/src/langwatch-api-agents.ts +196 -12
- package/src/langwatch-api-run-plans.ts +157 -0
- package/src/langwatch-api-scenarios.ts +9 -0
- package/src/langwatch-api-simulation-runs.ts +5 -0
- package/src/langwatch-api-test-suites.ts +135 -0
- package/src/langwatch-api.ts +62 -12
- package/src/schemas/index.ts +5 -0
- package/src/schemas/run-plan.ts +92 -0
- package/src/schemas/suite-fields.ts +149 -0
- package/src/tools/archive-run-plan.ts +12 -0
- package/src/tools/archive-test-suite.ts +12 -0
- package/src/tools/create-scenario.ts +8 -0
- package/src/tools/create-test-suite.ts +43 -0
- package/src/tools/discover-evaluator-schema.ts +2 -2
- package/src/tools/discover-scenario-schema.ts +54 -0
- package/src/tools/format-run-plan.ts +68 -0
- package/src/tools/format-scenario.ts +14 -0
- package/src/tools/format-suite-details.ts +96 -0
- package/src/tools/get-agent.ts +45 -3
- package/src/tools/get-prompt.ts +108 -24
- package/src/tools/get-run-plan.ts +62 -0
- package/src/tools/get-scenario.ts +3 -0
- package/src/tools/get-simulation-run.ts +9 -0
- package/src/tools/get-test-suite.ts +49 -0
- package/src/tools/list-agents.ts +20 -3
- package/src/tools/list-run-plans.ts +47 -0
- package/src/tools/list-scenarios.ts +12 -2
- package/src/tools/list-simulation-runs.ts +6 -2
- package/src/tools/list-test-suites.ts +35 -0
- package/src/tools/rename-test-suite.ts +18 -0
- package/src/tools/rerun-run-plan.ts +21 -0
- package/src/tools/run-agent.ts +54 -6
- package/src/tools/run-plan.ts +49 -0
- package/src/tools/run-test-suite.ts +30 -0
- package/src/tools/test-agent.ts +18 -0
- package/src/tools/update-prompt.ts +195 -10
- package/src/tools/update-scenario.ts +8 -0
- package/src/tools/update-test-suite.ts +45 -0
- package/tsconfig.json +7 -2
- package/uv.lock +418 -298
- package/dist/archive-suite-C3KX6IIZ.js +0 -16
- package/dist/chunk-WDH5P5RF.js +0 -48
- package/dist/create-suite-TWF6BBR4.js +0 -39
- package/dist/get-agent-7QJVPH72.js +0 -29
- package/dist/get-prompt-I753LZKZ.js +0 -46
- package/dist/get-suite-GTOCY5PL.js +0 -45
- package/dist/langwatch-api-workflows-5HRZ7HR4.js +0 -16
- package/dist/list-agents-TIJTP566.js +0 -33
- package/dist/list-suites-5VK4HXEK.js +0 -43
- package/dist/report-issue-DXJ6TPTC.js +0 -412
- package/dist/run-agent-RBSIFKRT.js +0 -37
- package/dist/run-suite-K3DNQ3SE.js +0 -30
- package/dist/update-prompt-RQFTEO7Y.js +0 -25
- package/dist/update-suite-TRGGLNR7.js +0 -40
- package/pnpm-workspace.yaml +0 -34
- package/src/langwatch-api-suites.ts +0 -118
- 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
|
@@ -6,6 +6,7 @@ vi.mock("../langwatch-api.js", () => ({
|
|
|
6
6
|
getAnalyticsTimeseries: vi.fn(),
|
|
7
7
|
listPrompts: vi.fn(),
|
|
8
8
|
getPrompt: vi.fn(),
|
|
9
|
+
getPromptVersions: vi.fn(),
|
|
9
10
|
createPrompt: vi.fn(),
|
|
10
11
|
updatePrompt: vi.fn(),
|
|
11
12
|
assignPromptTag: vi.fn(),
|
|
@@ -570,22 +571,14 @@ describe("handleGetPrompt()", () => {
|
|
|
570
571
|
id: "p1",
|
|
571
572
|
handle: "greeting",
|
|
572
573
|
name: "Greeting Prompt",
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
{ role: "system", content: "You are a greeter." },
|
|
580
|
-
{ role: "user", content: "Hello!" },
|
|
581
|
-
],
|
|
582
|
-
commitMessage: "Updated greeting",
|
|
583
|
-
},
|
|
584
|
-
{
|
|
585
|
-
version: 1,
|
|
586
|
-
commitMessage: "Initial version",
|
|
587
|
-
},
|
|
574
|
+
version: 2,
|
|
575
|
+
versionId: "ver_002",
|
|
576
|
+
model: "openai/gpt-4o",
|
|
577
|
+
messages: [
|
|
578
|
+
{ role: "system", content: "You are a greeter." },
|
|
579
|
+
{ role: "user", content: "Hello!" },
|
|
588
580
|
],
|
|
581
|
+
commitMessage: "Updated greeting",
|
|
589
582
|
});
|
|
590
583
|
|
|
591
584
|
const result = await handleGetPrompt({ idOrHandle: "greeting" });
|
|
@@ -593,7 +586,7 @@ describe("handleGetPrompt()", () => {
|
|
|
593
586
|
expect(result).toContain("# Prompt: Greeting Prompt");
|
|
594
587
|
expect(result).toContain("**Handle**: greeting");
|
|
595
588
|
expect(result).toContain("**ID**: p1");
|
|
596
|
-
expect(result).toContain("**
|
|
589
|
+
expect(result).toContain("**Version**: v2");
|
|
597
590
|
expect(result).toContain("**Model**: openai/gpt-4o");
|
|
598
591
|
expect(result).not.toContain("**Provider**");
|
|
599
592
|
});
|
|
@@ -601,13 +594,9 @@ describe("handleGetPrompt()", () => {
|
|
|
601
594
|
it("formats messages", async () => {
|
|
602
595
|
mockGetPrompt.mockResolvedValue({
|
|
603
596
|
name: "Test",
|
|
604
|
-
|
|
605
|
-
{
|
|
606
|
-
|
|
607
|
-
{ role: "system", content: "You are helpful." },
|
|
608
|
-
{ role: "user", content: "Hi there" },
|
|
609
|
-
],
|
|
610
|
-
},
|
|
597
|
+
messages: [
|
|
598
|
+
{ role: "system", content: "You are helpful." },
|
|
599
|
+
{ role: "user", content: "Hi there" },
|
|
611
600
|
],
|
|
612
601
|
});
|
|
613
602
|
|
|
@@ -618,41 +607,6 @@ describe("handleGetPrompt()", () => {
|
|
|
618
607
|
expect(result).toContain("### user\nHi there");
|
|
619
608
|
});
|
|
620
609
|
|
|
621
|
-
it("formats version history", async () => {
|
|
622
|
-
mockGetPrompt.mockResolvedValue({
|
|
623
|
-
name: "Test",
|
|
624
|
-
versions: [
|
|
625
|
-
{ version: 3, commitMessage: "Third update" },
|
|
626
|
-
{ version: 2, commitMessage: "Second update" },
|
|
627
|
-
{ version: 1, commitMessage: "Initial" },
|
|
628
|
-
],
|
|
629
|
-
});
|
|
630
|
-
|
|
631
|
-
const result = await handleGetPrompt({ idOrHandle: "test" });
|
|
632
|
-
|
|
633
|
-
expect(result).toContain("## Version History");
|
|
634
|
-
expect(result).toContain("- **v3**: Third update");
|
|
635
|
-
expect(result).toContain("- **v2**: Second update");
|
|
636
|
-
expect(result).toContain("- **v1**: Initial");
|
|
637
|
-
});
|
|
638
|
-
});
|
|
639
|
-
|
|
640
|
-
describe("when prompt has more than 10 versions", () => {
|
|
641
|
-
it("truncates version history with a count", async () => {
|
|
642
|
-
const versions = Array.from({ length: 12 }, (_, i) => ({
|
|
643
|
-
version: 12 - i,
|
|
644
|
-
commitMessage: `Version ${12 - i}`,
|
|
645
|
-
}));
|
|
646
|
-
|
|
647
|
-
mockGetPrompt.mockResolvedValue({
|
|
648
|
-
name: "Test",
|
|
649
|
-
versions,
|
|
650
|
-
});
|
|
651
|
-
|
|
652
|
-
const result = await handleGetPrompt({ idOrHandle: "test" });
|
|
653
|
-
|
|
654
|
-
expect(result).toContain("... and 2 more versions");
|
|
655
|
-
});
|
|
656
610
|
});
|
|
657
611
|
|
|
658
612
|
describe("when prompt has no versions", () => {
|
|
@@ -760,6 +714,13 @@ describe("handleUpdatePrompt()", () => {
|
|
|
760
714
|
handle: "greeting",
|
|
761
715
|
latestVersionNumber: 2,
|
|
762
716
|
});
|
|
717
|
+
mockGetPrompt.mockResolvedValue({
|
|
718
|
+
id: "p1",
|
|
719
|
+
handle: "greeting",
|
|
720
|
+
version: 2,
|
|
721
|
+
versionId: "ver_002",
|
|
722
|
+
commitMessage: "Update system prompt",
|
|
723
|
+
});
|
|
763
724
|
|
|
764
725
|
const result = await handleUpdatePrompt({
|
|
765
726
|
idOrHandle: "greeting",
|
|
@@ -824,6 +785,17 @@ describe("handleUpdatePrompt() with tags", () => {
|
|
|
824
785
|
describe("when called with tags", () => {
|
|
825
786
|
it("includes tags in the output", async () => {
|
|
826
787
|
mockUpdatePrompt.mockResolvedValue({ id: "p1", handle: "test", latestVersionNumber: 2 });
|
|
788
|
+
mockGetPrompt.mockResolvedValue({
|
|
789
|
+
id: "p1",
|
|
790
|
+
handle: "test",
|
|
791
|
+
version: 2,
|
|
792
|
+
versionId: "ver_002",
|
|
793
|
+
commitMessage: "add tags",
|
|
794
|
+
tags: [
|
|
795
|
+
{ name: "staging", versionId: "ver_002" },
|
|
796
|
+
{ name: "latest", versionId: "ver_002" },
|
|
797
|
+
],
|
|
798
|
+
});
|
|
827
799
|
|
|
828
800
|
const result = await handleUpdatePrompt({
|
|
829
801
|
idOrHandle: "test",
|
|
@@ -831,7 +803,7 @@ describe("handleUpdatePrompt() with tags", () => {
|
|
|
831
803
|
tags: ["staging"],
|
|
832
804
|
});
|
|
833
805
|
|
|
834
|
-
expect(result).toContain("**
|
|
806
|
+
expect(result).toContain("**Deployed to**: staging");
|
|
835
807
|
});
|
|
836
808
|
});
|
|
837
809
|
});
|
package/src/config.ts
CHANGED
|
@@ -49,13 +49,28 @@ function getGlobalState(): McpGlobalState {
|
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Trim surrounding whitespace and drop any trailing slashes.
|
|
54
|
+
*
|
|
55
|
+
* Request URLs are built as `${endpoint}/api/...`, so an endpoint written as
|
|
56
|
+
* `https://app.langwatch.ai/` would produce a double slash the router does not
|
|
57
|
+
* match, and the caller gets an opaque 404 with nothing pointing at the
|
|
58
|
+
* endpoint as the cause.
|
|
59
|
+
*/
|
|
60
|
+
function normalizeEndpoint(endpoint: string): string {
|
|
61
|
+
const trimmed = endpoint.trim();
|
|
62
|
+
let end = trimmed.length;
|
|
63
|
+
while (end > 0 && trimmed[end - 1] === "/") end--;
|
|
64
|
+
return trimmed.slice(0, end);
|
|
65
|
+
}
|
|
66
|
+
|
|
52
67
|
export function initConfig(args: { apiKey?: string; endpoint?: string }): void {
|
|
53
68
|
const state = getGlobalState();
|
|
54
69
|
state.globalConfig = {
|
|
55
70
|
apiKey: args.apiKey || process.env.LANGWATCH_API_KEY,
|
|
56
71
|
endpoint:
|
|
57
|
-
args.endpoint ||
|
|
58
|
-
process.env.LANGWATCH_ENDPOINT ||
|
|
72
|
+
normalizeEndpoint(args.endpoint ?? "") ||
|
|
73
|
+
normalizeEndpoint(process.env.LANGWATCH_ENDPOINT ?? "") ||
|
|
59
74
|
"https://app.langwatch.ai",
|
|
60
75
|
projectId: process.env.LANGWATCH_PROJECT_ID,
|
|
61
76
|
};
|