@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
package/src/create-mcp-server.ts
CHANGED
|
@@ -8,10 +8,22 @@ import {
|
|
|
8
8
|
createDatasetSchema,
|
|
9
9
|
datasetColumnDefinitionSchema,
|
|
10
10
|
} from "./schemas/create-dataset.js";
|
|
11
|
+
import {
|
|
12
|
+
runParametersSchema,
|
|
13
|
+
runPlanScopeSchema,
|
|
14
|
+
runPlanTargetSchema,
|
|
15
|
+
} from "./schemas/run-plan.js";
|
|
16
|
+
import {
|
|
17
|
+
evaluatorAttachmentsSchema,
|
|
18
|
+
scenarioFieldValuesSchema,
|
|
19
|
+
suiteFieldsSchema,
|
|
20
|
+
} from "./schemas/suite-fields.js";
|
|
11
21
|
import { handleExperimentResults } from "./tools/get-experiment-results.js";
|
|
12
22
|
import { handleExperimentListRuns } from "./tools/list-experiment-runs.js";
|
|
13
23
|
import { handleExperimentList } from "./tools/list-experiments.js";
|
|
14
24
|
import { handleRunExperiment, handleExperimentStatus } from "./tools/run-experiment.js";
|
|
25
|
+
import { handleTestAgent } from "./tools/test-agent.js";
|
|
26
|
+
import { handleUpdateTestSuite } from "./tools/update-test-suite.js";
|
|
15
27
|
|
|
16
28
|
const modelSchema = z
|
|
17
29
|
.string()
|
|
@@ -360,7 +372,7 @@ NOTE: Prompts can be managed two ways. Determine which approach the user needs:
|
|
|
360
372
|
|
|
361
373
|
server.tool(
|
|
362
374
|
"platform_get_prompt",
|
|
363
|
-
"Get a specific prompt from the LangWatch platform by ID or handle, including messages, model config, and version history.",
|
|
375
|
+
"Get a specific prompt from the LangWatch platform by ID or handle, including messages, model config, and version history. Use format: 'json' for the full raw API payload, or 'digest' (default) for a formatted summary.",
|
|
364
376
|
{
|
|
365
377
|
idOrHandle: z.string().describe("Prompt ID or handle"),
|
|
366
378
|
version: z
|
|
@@ -371,6 +383,12 @@ NOTE: Prompts can be managed two ways. Determine which approach the user needs:
|
|
|
371
383
|
'Fetch the version pointed to by this tag (e.g., "production", "staging"). ' +
|
|
372
384
|
'Alternatively, use shorthand in idOrHandle: "pizza-prompt:production"'
|
|
373
385
|
),
|
|
386
|
+
format: z
|
|
387
|
+
.enum(["digest", "json"])
|
|
388
|
+
.optional()
|
|
389
|
+
.describe(
|
|
390
|
+
"Output format: 'digest' (default, AI-readable) or 'json' (full raw data)"
|
|
391
|
+
),
|
|
374
392
|
},
|
|
375
393
|
withToolLogging("platform_get_prompt", async (params) => {
|
|
376
394
|
if (params.version != null && params.tag) {
|
|
@@ -528,6 +546,13 @@ NOTE: Scenarios can be created two ways. Determine which approach the user needs
|
|
|
528
546
|
.array(z.string())
|
|
529
547
|
.optional()
|
|
530
548
|
.describe("Tags for organizing and filtering scenarios"),
|
|
549
|
+
testSuiteId: z
|
|
550
|
+
.string()
|
|
551
|
+
.nullish()
|
|
552
|
+
.describe(
|
|
553
|
+
"The test suite to file this scenario in. Pass a test suite ID, or null to unfile it."
|
|
554
|
+
),
|
|
555
|
+
fields: scenarioFieldValuesSchema.optional(),
|
|
531
556
|
},
|
|
532
557
|
withToolLogging("platform_create_scenario", async (params) => {
|
|
533
558
|
requireApiKey();
|
|
@@ -546,6 +571,10 @@ NOTE: Scenarios can be created two ways. Determine which approach the user needs
|
|
|
546
571
|
"platform_list_scenarios",
|
|
547
572
|
"List all scenarios on the LangWatch platform. Returns AI-readable digest by default.",
|
|
548
573
|
{
|
|
574
|
+
testSuiteId: z
|
|
575
|
+
.string()
|
|
576
|
+
.optional()
|
|
577
|
+
.describe("Only the scenarios filed in this test suite"),
|
|
549
578
|
format: z
|
|
550
579
|
.enum(["digest", "json"])
|
|
551
580
|
.optional()
|
|
@@ -602,6 +631,13 @@ NOTE: Scenarios can be created two ways. Determine which approach the user needs
|
|
|
602
631
|
.array(z.string())
|
|
603
632
|
.optional()
|
|
604
633
|
.describe("Updated labels"),
|
|
634
|
+
testSuiteId: z
|
|
635
|
+
.string()
|
|
636
|
+
.nullish()
|
|
637
|
+
.describe(
|
|
638
|
+
"The test suite to file this scenario in. Pass a test suite ID, or null to unfile it."
|
|
639
|
+
),
|
|
640
|
+
fields: scenarioFieldValuesSchema.optional(),
|
|
605
641
|
},
|
|
606
642
|
withToolLogging("platform_update_scenario", async (params) => {
|
|
607
643
|
requireApiKey();
|
|
@@ -635,113 +671,325 @@ NOTE: Scenarios can be created two ways. Determine which approach the user needs
|
|
|
635
671
|
})
|
|
636
672
|
);
|
|
637
673
|
|
|
638
|
-
// --- Platform
|
|
639
|
-
//
|
|
674
|
+
// --- Platform Run Plan Tools (require API key) ---
|
|
675
|
+
// A run plan is what you run, and its NAME identifies it: running a name
|
|
676
|
+
// that exists replaces that plan's configuration, running a new name
|
|
677
|
+
// creates the plan. A test suite groups scenarios; running one is
|
|
678
|
+
// sugar that creates or joins the plan "<suite name> <target name>".
|
|
679
|
+
|
|
680
|
+
server.tool(
|
|
681
|
+
"platform_run_plan",
|
|
682
|
+
"Run scenarios against targets. The plan name identifies the run plan: an existing name is re-run with the configuration you send here, a new name creates the plan. Configuration is the scope, the targets, the repeat count and the models; parameters, the note and the idempotency key belong to this run alone. Send more than one target to compare them in the same run, and give a target its own parameters to compare one agent on two models.",
|
|
683
|
+
{
|
|
684
|
+
name: z
|
|
685
|
+
.string()
|
|
686
|
+
.optional()
|
|
687
|
+
.describe(
|
|
688
|
+
"The run plan to run. An existing name is replaced with this configuration, a new name creates the plan. Omit to let the server name it after the suite and the target.",
|
|
689
|
+
),
|
|
690
|
+
scope: runPlanScopeSchema.describe(
|
|
691
|
+
"What the plan covers: every scenario in the project, the scenarios filed in given test suites, the scenarios carrying given labels, or the hand-picked list in scenarioIds.",
|
|
692
|
+
),
|
|
693
|
+
scenarioIds: z
|
|
694
|
+
.array(z.string())
|
|
695
|
+
.optional()
|
|
696
|
+
.describe(
|
|
697
|
+
"The scenarios to run. Read only when scope.mode is 'scenarios'.",
|
|
698
|
+
),
|
|
699
|
+
targets: z
|
|
700
|
+
.array(runPlanTargetSchema)
|
|
701
|
+
.describe(
|
|
702
|
+
"What to run the scenarios against. Every target runs every scenario, and the results show one column for each, so this is how one run compares two agents or one agent on two models.",
|
|
703
|
+
),
|
|
704
|
+
repeatCount: z
|
|
705
|
+
.number()
|
|
706
|
+
.int()
|
|
707
|
+
.min(1)
|
|
708
|
+
.max(5)
|
|
709
|
+
.optional()
|
|
710
|
+
.describe("How many times to run each scenario against each target (1 to 5, default 1)"),
|
|
711
|
+
simulatorModel: z
|
|
712
|
+
.string()
|
|
713
|
+
.optional()
|
|
714
|
+
.describe("Model that plays the user. Omit for the project default."),
|
|
715
|
+
judgeModel: z
|
|
716
|
+
.string()
|
|
717
|
+
.optional()
|
|
718
|
+
.describe("Model that judges the criteria. Omit for the project default."),
|
|
719
|
+
evaluators: evaluatorAttachmentsSchema
|
|
720
|
+
.optional()
|
|
721
|
+
.describe(
|
|
722
|
+
"The plan's own evaluators, run beside the ones attached to the test suites its scenarios belong to. A plan evaluator reads the conversation and the trace, never a scenario field. Omit to keep what the plan already holds. See discover_schema({ category: 'scenarios' }) for the mapping paths.",
|
|
723
|
+
),
|
|
724
|
+
parameters: runParametersSchema
|
|
725
|
+
.optional()
|
|
726
|
+
.describe(
|
|
727
|
+
"Values for the parameters the scenarios declare, by name. They apply to every target; a target that names the same parameter overrides them for itself.",
|
|
728
|
+
),
|
|
729
|
+
note: z
|
|
730
|
+
.string()
|
|
731
|
+
.max(200)
|
|
732
|
+
.optional()
|
|
733
|
+
.describe("One short line saying why this run was started (max 200 characters)"),
|
|
734
|
+
idempotencyKey: z
|
|
735
|
+
.string()
|
|
736
|
+
.optional()
|
|
737
|
+
.describe("Send the same key to make a retry join the run it already started instead of starting a second one."),
|
|
738
|
+
},
|
|
739
|
+
withToolLogging("platform_run_plan", async (params) => {
|
|
740
|
+
requireApiKey();
|
|
741
|
+
const { handleRunPlan } = await import("./tools/run-plan.js");
|
|
742
|
+
return {
|
|
743
|
+
content: [{ type: "text", text: await handleRunPlan(params) }],
|
|
744
|
+
};
|
|
745
|
+
})
|
|
746
|
+
);
|
|
747
|
+
|
|
748
|
+
server.tool(
|
|
749
|
+
"platform_list_run_plans",
|
|
750
|
+
"List the run plans of the project. A run plan holds the configuration a run used, keyed by its name.",
|
|
751
|
+
{
|
|
752
|
+
includeArchived: z
|
|
753
|
+
.boolean()
|
|
754
|
+
.optional()
|
|
755
|
+
.describe("Include archived plans (default false)"),
|
|
756
|
+
format: z
|
|
757
|
+
.enum(["digest", "json"])
|
|
758
|
+
.optional()
|
|
759
|
+
.describe("Output format: 'digest' (default) or 'json' (raw data)"),
|
|
760
|
+
},
|
|
761
|
+
withToolLogging("platform_list_run_plans", async (params) => {
|
|
762
|
+
requireApiKey();
|
|
763
|
+
const { handleListRunPlans } = await import("./tools/list-run-plans.js");
|
|
764
|
+
return {
|
|
765
|
+
content: [{ type: "text", text: await handleListRunPlans(params) }],
|
|
766
|
+
};
|
|
767
|
+
})
|
|
768
|
+
);
|
|
769
|
+
|
|
770
|
+
server.tool(
|
|
771
|
+
"platform_get_run_plan",
|
|
772
|
+
"Get the full configuration of a run plan: what it covers, its targets, its repeat count and its models.",
|
|
773
|
+
{
|
|
774
|
+
id: z.string().describe("The run plan ID"),
|
|
775
|
+
format: z
|
|
776
|
+
.enum(["digest", "json"])
|
|
777
|
+
.optional()
|
|
778
|
+
.describe("Output format: 'digest' (default) or 'json'"),
|
|
779
|
+
},
|
|
780
|
+
withToolLogging("platform_get_run_plan", async (params) => {
|
|
781
|
+
requireApiKey();
|
|
782
|
+
const { handleGetRunPlan } = await import("./tools/get-run-plan.js");
|
|
783
|
+
return {
|
|
784
|
+
content: [{ type: "text", text: await handleGetRunPlan(params) }],
|
|
785
|
+
};
|
|
786
|
+
})
|
|
787
|
+
);
|
|
788
|
+
|
|
789
|
+
server.tool(
|
|
790
|
+
"platform_rerun_run_plan",
|
|
791
|
+
"Run a plan again with the configuration it already holds. Only the parameters and the note belong to the new run.",
|
|
792
|
+
{
|
|
793
|
+
id: z.string().describe("The run plan ID to run again"),
|
|
794
|
+
parameters: runParametersSchema
|
|
795
|
+
.optional()
|
|
796
|
+
.describe("Values for the parameters the scenarios declare, by name."),
|
|
797
|
+
note: z
|
|
798
|
+
.string()
|
|
799
|
+
.max(200)
|
|
800
|
+
.optional()
|
|
801
|
+
.describe("One short line saying why this run was started (max 200 characters)"),
|
|
802
|
+
},
|
|
803
|
+
withToolLogging("platform_rerun_run_plan", async (params) => {
|
|
804
|
+
requireApiKey();
|
|
805
|
+
const { handleRerunRunPlan } = await import("./tools/rerun-run-plan.js");
|
|
806
|
+
return {
|
|
807
|
+
content: [{ type: "text", text: await handleRerunRunPlan(params) }],
|
|
808
|
+
};
|
|
809
|
+
})
|
|
810
|
+
);
|
|
811
|
+
|
|
812
|
+
server.tool(
|
|
813
|
+
"platform_archive_run_plan",
|
|
814
|
+
"Archive a run plan. Its past runs stay readable and the name is free for a new plan.",
|
|
815
|
+
{
|
|
816
|
+
id: z.string().describe("The run plan ID to archive"),
|
|
817
|
+
},
|
|
818
|
+
withToolLogging("platform_archive_run_plan", async (params) => {
|
|
819
|
+
requireApiKey();
|
|
820
|
+
const { handleArchiveRunPlan } = await import(
|
|
821
|
+
"./tools/archive-run-plan.js"
|
|
822
|
+
);
|
|
823
|
+
return {
|
|
824
|
+
content: [{ type: "text", text: await handleArchiveRunPlan(params) }],
|
|
825
|
+
};
|
|
826
|
+
})
|
|
827
|
+
);
|
|
828
|
+
|
|
829
|
+
// --- Platform Test Suite Tools (require API key) ---
|
|
830
|
+
// A test suite groups scenarios: a name and the scenarios filed in it.
|
|
640
831
|
|
|
641
832
|
server.tool(
|
|
642
|
-
"
|
|
643
|
-
"List
|
|
833
|
+
"platform_list_test_suites",
|
|
834
|
+
"List the test suites of the project. A test suite groups scenarios.",
|
|
644
835
|
{
|
|
645
836
|
format: z
|
|
646
837
|
.enum(["digest", "json"])
|
|
647
838
|
.optional()
|
|
648
839
|
.describe("Output format: 'digest' (default) or 'json' (raw data)"),
|
|
649
840
|
},
|
|
650
|
-
withToolLogging("
|
|
841
|
+
withToolLogging("platform_list_test_suites", async (params) => {
|
|
842
|
+
requireApiKey();
|
|
843
|
+
const { handleListTestSuites } = await import(
|
|
844
|
+
"./tools/list-test-suites.js"
|
|
845
|
+
);
|
|
846
|
+
return {
|
|
847
|
+
content: [{ type: "text", text: await handleListTestSuites(params) }],
|
|
848
|
+
};
|
|
849
|
+
})
|
|
850
|
+
);
|
|
851
|
+
|
|
852
|
+
server.tool(
|
|
853
|
+
"platform_create_test_suite",
|
|
854
|
+
"Create a test suite. A test suite groups scenarios: file a scenario in it by passing the suite ID as testSuiteId on platform_create_scenario or platform_update_scenario. A suite can declare typed fields every scenario carries a value for, and attach saved evaluators that run after every scenario run with mappings from their inputs to the conversation, the scenario's fields or the trace. Call discover_schema({ category: 'scenarios' }) first for the field rules and the mapping paths.",
|
|
855
|
+
{
|
|
856
|
+
name: z.string().describe("Test suite name"),
|
|
857
|
+
fields: suiteFieldsSchema.optional(),
|
|
858
|
+
evaluators: evaluatorAttachmentsSchema.optional(),
|
|
859
|
+
},
|
|
860
|
+
withToolLogging("platform_create_test_suite", async (params) => {
|
|
651
861
|
requireApiKey();
|
|
652
|
-
const {
|
|
862
|
+
const { handleCreateTestSuite } = await import(
|
|
863
|
+
"./tools/create-test-suite.js"
|
|
864
|
+
);
|
|
653
865
|
return {
|
|
654
|
-
content: [{ type: "text", text: await
|
|
866
|
+
content: [{ type: "text", text: await handleCreateTestSuite(params) }],
|
|
655
867
|
};
|
|
656
868
|
})
|
|
657
869
|
);
|
|
658
870
|
|
|
659
871
|
server.tool(
|
|
660
|
-
"
|
|
661
|
-
"Get
|
|
872
|
+
"platform_get_test_suite",
|
|
873
|
+
"Get a test suite and the scenarios filed in it.",
|
|
662
874
|
{
|
|
663
|
-
id: z.string().describe("The suite ID"),
|
|
875
|
+
id: z.string().describe("The test suite ID"),
|
|
664
876
|
format: z
|
|
665
877
|
.enum(["digest", "json"])
|
|
666
878
|
.optional()
|
|
667
879
|
.describe("Output format: 'digest' (default) or 'json'"),
|
|
668
880
|
},
|
|
669
|
-
withToolLogging("
|
|
881
|
+
withToolLogging("platform_get_test_suite", async (params) => {
|
|
670
882
|
requireApiKey();
|
|
671
|
-
const {
|
|
883
|
+
const { handleGetTestSuite } = await import("./tools/get-test-suite.js");
|
|
672
884
|
return {
|
|
673
|
-
content: [{ type: "text", text: await
|
|
885
|
+
content: [{ type: "text", text: await handleGetTestSuite(params) }],
|
|
674
886
|
};
|
|
675
887
|
})
|
|
676
888
|
);
|
|
677
889
|
|
|
678
890
|
server.tool(
|
|
679
|
-
"
|
|
680
|
-
"
|
|
891
|
+
"platform_update_test_suite",
|
|
892
|
+
"Edit a test suite: any of its name, its fields and its evaluators. A field list or an evaluator list replaces the one the suite holds; a key left out keeps what the suite has. A field an attached evaluator still reads cannot be removed. Call discover_schema({ category: 'scenarios' }) first for the field rules and the mapping paths.",
|
|
681
893
|
{
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
894
|
+
id: z.string().describe("The test suite ID"),
|
|
895
|
+
name: z.string().optional().describe("The new name. The slug is kept."),
|
|
896
|
+
fields: suiteFieldsSchema
|
|
897
|
+
.optional()
|
|
898
|
+
.describe("The full list of fields the suite declares. It replaces the list the suite holds."),
|
|
899
|
+
evaluators: evaluatorAttachmentsSchema
|
|
900
|
+
.optional()
|
|
901
|
+
.describe("The full list of evaluators attached to the suite. It replaces the list the suite holds."),
|
|
688
902
|
},
|
|
689
|
-
withToolLogging("
|
|
903
|
+
withToolLogging("platform_update_test_suite", async (params) => {
|
|
690
904
|
requireApiKey();
|
|
691
|
-
const { handleCreateSuite } = await import("./tools/create-suite.js");
|
|
692
905
|
return {
|
|
693
|
-
content: [{ type: "text", text: await
|
|
906
|
+
content: [{ type: "text", text: await handleUpdateTestSuite(params) }],
|
|
694
907
|
};
|
|
695
908
|
})
|
|
696
909
|
);
|
|
697
910
|
|
|
698
911
|
server.tool(
|
|
699
|
-
"
|
|
700
|
-
"
|
|
912
|
+
"platform_rename_test_suite",
|
|
913
|
+
"Rename a test suite.",
|
|
701
914
|
{
|
|
702
|
-
id: z.string().describe("The suite ID
|
|
703
|
-
name: z.string().
|
|
704
|
-
description: z.string().optional().describe("New description"),
|
|
705
|
-
scenarioIds: z.array(z.string()).optional().describe("New array of scenario IDs"),
|
|
706
|
-
targets: z.string().optional().describe("New JSON array of targets"),
|
|
707
|
-
repeatCount: z.number().optional().describe("New repeat count"),
|
|
708
|
-
labels: z.array(z.string()).optional().describe("New labels"),
|
|
915
|
+
id: z.string().describe("The test suite ID"),
|
|
916
|
+
name: z.string().describe("The new name"),
|
|
709
917
|
},
|
|
710
|
-
withToolLogging("
|
|
918
|
+
withToolLogging("platform_rename_test_suite", async (params) => {
|
|
711
919
|
requireApiKey();
|
|
712
|
-
const {
|
|
920
|
+
const { handleRenameTestSuite } = await import(
|
|
921
|
+
"./tools/rename-test-suite.js"
|
|
922
|
+
);
|
|
713
923
|
return {
|
|
714
|
-
content: [{ type: "text", text: await
|
|
924
|
+
content: [{ type: "text", text: await handleRenameTestSuite(params) }],
|
|
715
925
|
};
|
|
716
926
|
})
|
|
717
927
|
);
|
|
718
928
|
|
|
719
929
|
server.tool(
|
|
720
|
-
"
|
|
721
|
-
"
|
|
930
|
+
"platform_archive_test_suite",
|
|
931
|
+
"Archive a test suite. The scenarios filed in it are archived with it.",
|
|
722
932
|
{
|
|
723
|
-
id: z.string().describe("The suite ID to
|
|
933
|
+
id: z.string().describe("The test suite ID to archive"),
|
|
724
934
|
},
|
|
725
|
-
withToolLogging("
|
|
935
|
+
withToolLogging("platform_archive_test_suite", async (params) => {
|
|
726
936
|
requireApiKey();
|
|
727
|
-
const {
|
|
937
|
+
const { handleArchiveTestSuite } = await import(
|
|
938
|
+
"./tools/archive-test-suite.js"
|
|
939
|
+
);
|
|
728
940
|
return {
|
|
729
|
-
content: [{ type: "text", text: await
|
|
941
|
+
content: [{ type: "text", text: await handleArchiveTestSuite(params) }],
|
|
730
942
|
};
|
|
731
943
|
})
|
|
732
944
|
);
|
|
733
945
|
|
|
734
946
|
server.tool(
|
|
735
|
-
"
|
|
736
|
-
"
|
|
947
|
+
"platform_run_test_suite",
|
|
948
|
+
"Run every scenario of a test suite against targets. This creates or joins the run plan named '<suite name> <target name>' unless you send a name of your own. Send more than one target to compare them in the same run, and give a target its own parameters to compare one agent on two models.",
|
|
737
949
|
{
|
|
738
|
-
id: z.string().describe("The suite ID to
|
|
950
|
+
id: z.string().describe("The test suite ID to run"),
|
|
951
|
+
targets: z
|
|
952
|
+
.array(runPlanTargetSchema)
|
|
953
|
+
.describe(
|
|
954
|
+
"What to run the scenarios against. Every target runs every scenario, and the results show one column for each.",
|
|
955
|
+
),
|
|
956
|
+
name: z
|
|
957
|
+
.string()
|
|
958
|
+
.optional()
|
|
959
|
+
.describe(
|
|
960
|
+
"The run plan to run. Omit to let the server name it after the suite and the target.",
|
|
961
|
+
),
|
|
962
|
+
repeatCount: z
|
|
963
|
+
.number()
|
|
964
|
+
.int()
|
|
965
|
+
.min(1)
|
|
966
|
+
.max(5)
|
|
967
|
+
.optional()
|
|
968
|
+
.describe("How many times to run each scenario against each target (1 to 5, default 1)"),
|
|
969
|
+
simulatorModel: z
|
|
970
|
+
.string()
|
|
971
|
+
.optional()
|
|
972
|
+
.describe("Model that plays the user. Omit for the project default."),
|
|
973
|
+
judgeModel: z
|
|
974
|
+
.string()
|
|
975
|
+
.optional()
|
|
976
|
+
.describe("Model that judges the criteria. Omit for the project default."),
|
|
977
|
+
parameters: runParametersSchema
|
|
978
|
+
.optional()
|
|
979
|
+
.describe(
|
|
980
|
+
"Values for the parameters the scenarios declare, by name. They apply to every target; a target that names the same parameter overrides them for itself.",
|
|
981
|
+
),
|
|
982
|
+
note: z
|
|
983
|
+
.string()
|
|
984
|
+
.max(200)
|
|
985
|
+
.optional()
|
|
986
|
+
.describe("One short line saying why this run was started (max 200 characters)"),
|
|
739
987
|
},
|
|
740
|
-
withToolLogging("
|
|
988
|
+
withToolLogging("platform_run_test_suite", async (params) => {
|
|
741
989
|
requireApiKey();
|
|
742
|
-
const {
|
|
990
|
+
const { handleRunTestSuite } = await import("./tools/run-test-suite.js");
|
|
743
991
|
return {
|
|
744
|
-
content: [{ type: "text", text: await
|
|
992
|
+
content: [{ type: "text", text: await handleRunTestSuite(params) }],
|
|
745
993
|
};
|
|
746
994
|
})
|
|
747
995
|
);
|
|
@@ -769,7 +1017,7 @@ NOTE: Scenarios can be created two ways. Determine which approach the user needs
|
|
|
769
1017
|
|
|
770
1018
|
server.tool(
|
|
771
1019
|
"platform_get_simulation_run",
|
|
772
|
-
"Get full details of a simulation run including conversation messages, results, costs, and
|
|
1020
|
+
"Get full details of a simulation run including conversation messages, results, costs, the verdict and the result of every evaluator attached to its test suite or run plan.",
|
|
773
1021
|
{
|
|
774
1022
|
scenarioRunId: z.string().describe("The simulation run ID"),
|
|
775
1023
|
format: z.enum(["digest", "json"]).optional().describe("Output format"),
|
|
@@ -941,7 +1189,7 @@ NOTE: Scenarios can be created two ways. Determine which approach the user needs
|
|
|
941
1189
|
|
|
942
1190
|
server.tool(
|
|
943
1191
|
"platform_list_agents",
|
|
944
|
-
"List all agents in the LangWatch project with their names, types
|
|
1192
|
+
"List all agents in the LangWatch project with their names, types and IDs. A connected agent (one that registered itself from code with connectAgent or connect_agent) also shows its environment, whether it is online, how many instances are connected, and its owner.",
|
|
945
1193
|
{},
|
|
946
1194
|
withToolLogging("platform_list_agents", async () => {
|
|
947
1195
|
requireApiKey();
|
|
@@ -954,7 +1202,7 @@ NOTE: Scenarios can be created two ways. Determine which approach the user needs
|
|
|
954
1202
|
|
|
955
1203
|
server.tool(
|
|
956
1204
|
"platform_get_agent",
|
|
957
|
-
"Get detailed information about a specific agent by its ID, including its configuration.",
|
|
1205
|
+
"Get detailed information about a specific agent by its ID, including its configuration. A connected agent also shows its environment, status, the run parameters it declared (with options and defaults) and the instances connected right now.",
|
|
958
1206
|
{
|
|
959
1207
|
id: z.string().describe("The agent ID"),
|
|
960
1208
|
},
|
|
@@ -969,7 +1217,7 @@ NOTE: Scenarios can be created two ways. Determine which approach the user needs
|
|
|
969
1217
|
|
|
970
1218
|
server.tool(
|
|
971
1219
|
"platform_create_agent",
|
|
972
|
-
"Create a new agent. Supported types: 'signature' (LLM prompt), 'code' (Python), 'workflow' (sub-workflow), 'http' (external API).",
|
|
1220
|
+
"Create a new agent. Supported types: 'signature' (LLM prompt), 'code' (Python), 'workflow' (sub-workflow), 'http' (external API). A 'connected' agent is not created here: it registers itself from code, with connectAgent from langwatch/agent in TypeScript or langwatch.connect_agent in Python, and appears in the list once that process runs.",
|
|
973
1221
|
{
|
|
974
1222
|
name: z.string().describe("Agent name"),
|
|
975
1223
|
type: z.enum(["signature", "code", "workflow", "http"]).describe("Agent type"),
|
|
@@ -1021,10 +1269,27 @@ NOTE: Scenarios can be created two ways. Determine which approach the user needs
|
|
|
1021
1269
|
|
|
1022
1270
|
server.tool(
|
|
1023
1271
|
"platform_run_agent",
|
|
1024
|
-
"
|
|
1272
|
+
"Run one turn of an agent. A connected agent runs through the platform relay on a live instance: give `message` (one user turn) or `input` with a `messages` list, plus `parameters` and `threadId` to continue a conversation. HTTP agents call their configured URL directly; workflow-linked agents execute via the workflow engine.",
|
|
1025
1273
|
{
|
|
1026
1274
|
id: z.string().describe("The agent ID to run"),
|
|
1027
|
-
input: z
|
|
1275
|
+
input: z
|
|
1276
|
+
.string()
|
|
1277
|
+
.optional()
|
|
1278
|
+
.describe(
|
|
1279
|
+
"Input data as a JSON object string. For a connected agent it is the relay body: messages (OpenAI style), and optionally threadId, session and params.",
|
|
1280
|
+
),
|
|
1281
|
+
message: z
|
|
1282
|
+
.string()
|
|
1283
|
+
.optional()
|
|
1284
|
+
.describe("One user message to send to a connected agent, instead of input"),
|
|
1285
|
+
parameters: z
|
|
1286
|
+
.record(z.string(), z.union([z.string(), z.number(), z.boolean()]))
|
|
1287
|
+
.optional()
|
|
1288
|
+
.describe("Run parameter values for a connected agent, by name"),
|
|
1289
|
+
threadId: z
|
|
1290
|
+
.string()
|
|
1291
|
+
.optional()
|
|
1292
|
+
.describe("Continue a conversation on a connected agent"),
|
|
1028
1293
|
},
|
|
1029
1294
|
withToolLogging("platform_run_agent", async (params) => {
|
|
1030
1295
|
requireApiKey();
|
|
@@ -1035,6 +1300,20 @@ NOTE: Scenarios can be created two ways. Determine which approach the user needs
|
|
|
1035
1300
|
})
|
|
1036
1301
|
);
|
|
1037
1302
|
|
|
1303
|
+
server.tool(
|
|
1304
|
+
"platform_test_agent",
|
|
1305
|
+
"Test an agent with one scripted scenario run: the user sends \"ping\", the agent answers, and the run succeeds when the answer arrives. No model is used, and no scenario, run plan or test suite is added to the project. Answers at once with the scenario run id to follow with platform_get_simulation_run; the run itself is asynchronous.",
|
|
1306
|
+
{
|
|
1307
|
+
id: z.string().describe("The agent ID to test"),
|
|
1308
|
+
},
|
|
1309
|
+
withToolLogging("platform_test_agent", async (params) => {
|
|
1310
|
+
requireApiKey();
|
|
1311
|
+
return {
|
|
1312
|
+
content: [{ type: "text", text: await handleTestAgent(params) }],
|
|
1313
|
+
};
|
|
1314
|
+
})
|
|
1315
|
+
);
|
|
1316
|
+
|
|
1038
1317
|
// --- Platform Dashboard Tools (require API key) ---
|
|
1039
1318
|
|
|
1040
1319
|
server.tool(
|