@langwatch/mcp-server 0.7.0 → 0.8.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/.release-please-shim +1 -0
- package/CHANGELOG.md +66 -0
- package/dist/{archive-scenario-WJ2A7ETN.js → archive-scenario-YKGLJ4MZ.js} +4 -4
- package/dist/{archive-suite-4JOM4SSL.js → archive-suite-QFNDO3Y3.js} +4 -4
- package/dist/{assign-prompt-tag-GL7EAAF3.js → assign-prompt-tag-Y2B4CBBT.js} +3 -3
- package/dist/{chunk-E5JYYU3J.js → chunk-B57MZ4WI.js} +89 -83
- package/dist/{chunk-CCWCIJJ3.js → chunk-CPUPGDNA.js} +2 -2
- package/dist/{chunk-LUMEZEHL.js → chunk-FBRKHHJV.js} +2 -2
- package/dist/{chunk-HYMIWO3U.js → chunk-HDJDFKZR.js} +2 -2
- package/dist/{chunk-BWWY5KEF.js → chunk-KOO5733S.js} +3 -2
- package/dist/{chunk-EUQDVOSU.js → chunk-KZNBCKWG.js} +2 -2
- package/dist/{chunk-IE4M5OGE.js → chunk-L6QENXYA.js} +2 -2
- package/dist/{chunk-2GT7IFWK.js → chunk-NACSR6B7.js} +2 -2
- package/dist/{chunk-WQG2DFHX.js → chunk-OVQF3D5R.js} +2 -2
- package/dist/{chunk-ZVS4UKN2.js → chunk-PO7FM7IX.js} +2 -2
- package/dist/{chunk-EGH5RPXM.js → chunk-PZUWCWOS.js} +2 -2
- package/dist/{chunk-2WPLXEKF.js → chunk-YH2IBTEL.js} +7 -3
- package/dist/{chunk-4AUB2BIA.js → chunk-YI3OG4PI.js} +3 -3
- package/dist/config.js +1 -1
- package/dist/{create-agent-MBOOT3XK.js → create-agent-YRSDH7P7.js} +4 -4
- package/dist/{create-annotation-XMV6A7ED.js → create-annotation-FYQNKMVJ.js} +4 -4
- package/dist/{create-dashboard-VRKLFVZJ.js → create-dashboard-CORBR4YQ.js} +4 -4
- package/dist/{create-dataset-7HQPZCRE.js → create-dataset-ZC63T6BB.js} +4 -4
- package/dist/{create-dataset-records-2NIVFYTV.js → create-dataset-records-ILVNVKVR.js} +4 -4
- package/dist/{create-evaluator-WYFRFLRC.js → create-evaluator-2AU3PXFB.js} +4 -4
- package/dist/create-mcp-server.js +2 -2
- package/dist/{create-prompt-IEN7O6JT.js → create-prompt-NKRJ47YY.js} +3 -3
- package/dist/{create-prompt-tag-CAEZ45VO.js → create-prompt-tag-S4JX3ULL.js} +3 -3
- package/dist/{create-scenario-6YHSMGLP.js → create-scenario-BPRF75KF.js} +4 -4
- package/dist/{create-suite-H5XOFDE5.js → create-suite-4YN7D6K2.js} +4 -4
- package/dist/{delete-agent-JKTNBWAA.js → delete-agent-Y72R2YQA.js} +4 -4
- package/dist/{delete-annotation-ACMDV6QO.js → delete-annotation-UHWDMHSH.js} +4 -4
- package/dist/{delete-dashboard-VJSR7CRU.js → delete-dashboard-LPWT36KN.js} +4 -4
- package/dist/{delete-dataset-RTTTWP4D.js → delete-dataset-GGPQRHKX.js} +4 -4
- package/dist/{delete-dataset-records-KNQTIPQK.js → delete-dataset-records-LTG5LT26.js} +4 -4
- package/dist/{delete-evaluator-7FVC5WM4.js → delete-evaluator-F7QLXDHU.js} +4 -4
- package/dist/{delete-prompt-tag-ZMZUAGFW.js → delete-prompt-tag-B5UKZL45.js} +3 -3
- package/dist/{delete-workflow-EYQ3T4RQ.js → delete-workflow-4DGUDIDE.js} +4 -4
- package/dist/{get-agent-E3QSTVKG.js → get-agent-YEVICUX4.js} +4 -4
- package/dist/{get-analytics-2OHV763I.js → get-analytics-3W5CMU3F.js} +3 -3
- package/dist/{get-dashboard-PC7JDHH6.js → get-dashboard-NCQHN6MW.js} +4 -4
- package/dist/{get-dataset-H5IK5FVU.js → get-dataset-KBK6PH36.js} +4 -4
- package/dist/{get-evaluator-UWVUPYTM.js → get-evaluator-QDUL5LXR.js} +4 -4
- package/dist/{get-prompt-WZUOLLQC.js → get-prompt-XCSSNRKR.js} +3 -3
- package/dist/{get-scenario-Q6LCNUYN.js → get-scenario-FNRKOY7E.js} +4 -4
- package/dist/{get-simulation-run-Z2XKO256.js → get-simulation-run-WOEKUF7K.js} +4 -4
- package/dist/{get-suite-BXK5TN7P.js → get-suite-U5AOD5TC.js} +4 -4
- package/dist/{get-trace-4EJAYVBG.js → get-trace-MUWEJM2Z.js} +3 -3
- package/dist/{get-workflow-O34QJLHD.js → get-workflow-SOA7MT7L.js} +4 -4
- package/dist/{http-server-ISHF7NJX.js → http-server-7DMOCB75.js} +3 -3
- package/dist/index.js +423 -241
- package/dist/{langwatch-api-annotations-ERBG27RF.js → langwatch-api-annotations-Q57NDUVR.js} +4 -4
- package/dist/{langwatch-api-dashboards-G6TR7VVO.js → langwatch-api-dashboards-VBWWXV3Y.js} +4 -4
- package/dist/{langwatch-api-monitors-WSXZLS2B.js → langwatch-api-monitors-L3IY7FDT.js} +3 -3
- package/dist/{langwatch-api-secrets-RR5DKG2X.js → langwatch-api-secrets-S5HHF3XR.js} +3 -3
- package/dist/{langwatch-api-triggers-2RTNSWQY.js → langwatch-api-triggers-ME33QE26.js} +3 -3
- package/dist/langwatch-api-workflows-4CJQAYP2.js +15 -0
- package/dist/{list-agents-AW3P6FJV.js → list-agents-3HGIBJFM.js} +4 -4
- package/dist/{list-annotations-QNCGWPQ3.js → list-annotations-KWXYVEPI.js} +4 -4
- package/dist/{list-dashboards-R7RK2IXL.js → list-dashboards-VQ2LH666.js} +4 -4
- package/dist/{list-dataset-records-WVCSQP7P.js → list-dataset-records-RNRGROJP.js} +4 -4
- package/dist/{list-datasets-KEXRLDEU.js → list-datasets-I4A2LT2S.js} +4 -4
- package/dist/{list-evaluators-7R2LB4JH.js → list-evaluators-AKKRJ5MX.js} +4 -4
- package/dist/{list-model-providers-OBYJCKBX.js → list-model-providers-DVFEHFHZ.js} +4 -4
- package/dist/{list-prompt-tags-6LY3ZPYI.js → list-prompt-tags-PL5OISUA.js} +3 -3
- package/dist/{list-prompts-VWEZ4CDE.js → list-prompts-7VTFWE2Z.js} +3 -3
- package/dist/{list-scenarios-TXD4W2ZJ.js → list-scenarios-5BZWZ6ZN.js} +4 -4
- package/dist/{list-simulation-runs-RHPOLMFI.js → list-simulation-runs-WCZ6RLPE.js} +4 -4
- package/dist/{list-suites-FSGBX27Z.js → list-suites-RRQ2JX5Y.js} +4 -4
- package/dist/{list-workflows-VRGEZ3EN.js → list-workflows-UQB5FCX5.js} +4 -4
- package/dist/{rename-prompt-tag-VOJJLX4M.js → rename-prompt-tag-TURD6KYU.js} +3 -3
- package/dist/{run-agent-KTCC7TB7.js → run-agent-BEJ4K4CM.js} +4 -4
- package/dist/{run-evaluation-2X3V3Q6L.js → run-evaluation-AJ7WZNQD.js} +3 -3
- package/dist/{run-suite-BTMHGI2D.js → run-suite-U7V432G2.js} +4 -4
- package/dist/{run-workflow-IGAYGKJL.js → run-workflow-5WX7DK5T.js} +4 -4
- package/dist/{search-traces-VYFUIMXH.js → search-traces-ZCHNOMTX.js} +3 -3
- package/dist/{set-model-provider-W5IUI326.js → set-model-provider-6CFHMCNE.js} +4 -4
- package/dist/{update-agent-4BB7EYLR.js → update-agent-UE6UWLZP.js} +4 -4
- package/dist/{update-dataset-CXBKZ4W3.js → update-dataset-4XQZZE4S.js} +4 -4
- package/dist/{update-dataset-record-HOHAMHXG.js → update-dataset-record-GNNM5TKM.js} +4 -4
- package/dist/{update-evaluator-IVOR6FTR.js → update-evaluator-LHVDXIZD.js} +4 -4
- package/dist/{update-prompt-OWQAKE7K.js → update-prompt-3XEHECJ7.js} +3 -3
- package/dist/{update-scenario-GDFVILPN.js → update-scenario-DFPREYCD.js} +4 -4
- package/dist/{update-suite-BXYUYSPT.js → update-suite-RATU5THO.js} +4 -4
- package/package.json +6 -6
- package/src/__tests__/all-tools.integration.test.ts +9 -0
- package/src/__tests__/datasets.integration.test.ts +17 -0
- package/src/__tests__/datasets.unit.test.ts +4 -0
- package/src/__tests__/scenario-tools.unit.test.ts +3 -0
- package/src/config.ts +2 -0
- package/src/langwatch-api.ts +5 -1
- package/uv.lock +188 -530
- package/Dockerfile +0 -22
- package/build.js +0 -12
- package/dist/archive-scenario-WJ2A7ETN.js.map +0 -1
- package/dist/archive-suite-4JOM4SSL.js.map +0 -1
- package/dist/assign-prompt-tag-GL7EAAF3.js.map +0 -1
- package/dist/chunk-2GT7IFWK.js.map +0 -1
- package/dist/chunk-2WPLXEKF.js.map +0 -1
- package/dist/chunk-4AUB2BIA.js.map +0 -1
- package/dist/chunk-BWWY5KEF.js.map +0 -1
- package/dist/chunk-CCWCIJJ3.js.map +0 -1
- package/dist/chunk-E5JYYU3J.js.map +0 -1
- package/dist/chunk-EGH5RPXM.js.map +0 -1
- package/dist/chunk-EUQDVOSU.js.map +0 -1
- package/dist/chunk-HYMIWO3U.js.map +0 -1
- package/dist/chunk-IE4M5OGE.js.map +0 -1
- package/dist/chunk-LUMEZEHL.js.map +0 -1
- package/dist/chunk-NUFPTHKU.js.map +0 -1
- package/dist/chunk-WQG2DFHX.js.map +0 -1
- package/dist/chunk-WVI5CJ6S.js.map +0 -1
- package/dist/chunk-ZVS4UKN2.js.map +0 -1
- package/dist/chunk-ZXKLPC2E.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/create-agent-MBOOT3XK.js.map +0 -1
- package/dist/create-annotation-XMV6A7ED.js.map +0 -1
- package/dist/create-dashboard-VRKLFVZJ.js.map +0 -1
- package/dist/create-dataset-7HQPZCRE.js.map +0 -1
- package/dist/create-dataset-records-2NIVFYTV.js.map +0 -1
- package/dist/create-evaluator-WYFRFLRC.js.map +0 -1
- package/dist/create-mcp-server.js.map +0 -1
- package/dist/create-prompt-IEN7O6JT.js.map +0 -1
- package/dist/create-prompt-tag-CAEZ45VO.js.map +0 -1
- package/dist/create-scenario-6YHSMGLP.js.map +0 -1
- package/dist/create-suite-H5XOFDE5.js.map +0 -1
- package/dist/delete-agent-JKTNBWAA.js.map +0 -1
- package/dist/delete-annotation-ACMDV6QO.js.map +0 -1
- package/dist/delete-dashboard-VJSR7CRU.js.map +0 -1
- package/dist/delete-dataset-RTTTWP4D.js.map +0 -1
- package/dist/delete-dataset-records-KNQTIPQK.js.map +0 -1
- package/dist/delete-evaluator-7FVC5WM4.js.map +0 -1
- package/dist/delete-prompt-tag-ZMZUAGFW.js.map +0 -1
- package/dist/delete-workflow-EYQ3T4RQ.js.map +0 -1
- package/dist/discover-evaluator-schema-H23XCLNE.js.map +0 -1
- package/dist/discover-scenario-schema-MEEEVND7.js.map +0 -1
- package/dist/discover-schema-3T52ORPB.js.map +0 -1
- package/dist/get-agent-E3QSTVKG.js.map +0 -1
- package/dist/get-analytics-2OHV763I.js.map +0 -1
- package/dist/get-dashboard-PC7JDHH6.js.map +0 -1
- package/dist/get-dataset-H5IK5FVU.js.map +0 -1
- package/dist/get-evaluator-UWVUPYTM.js.map +0 -1
- package/dist/get-prompt-WZUOLLQC.js.map +0 -1
- package/dist/get-scenario-Q6LCNUYN.js.map +0 -1
- package/dist/get-simulation-run-Z2XKO256.js.map +0 -1
- package/dist/get-suite-BXK5TN7P.js.map +0 -1
- package/dist/get-trace-4EJAYVBG.js.map +0 -1
- package/dist/get-workflow-O34QJLHD.js.map +0 -1
- package/dist/http-server-ISHF7NJX.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/langwatch-api-annotations-ERBG27RF.js.map +0 -1
- package/dist/langwatch-api-dashboards-G6TR7VVO.js.map +0 -1
- package/dist/langwatch-api-monitors-WSXZLS2B.js.map +0 -1
- package/dist/langwatch-api-secrets-RR5DKG2X.js.map +0 -1
- package/dist/langwatch-api-triggers-2RTNSWQY.js.map +0 -1
- package/dist/langwatch-api-workflows-VJRIIDZ7.js +0 -15
- package/dist/langwatch-api-workflows-VJRIIDZ7.js.map +0 -1
- package/dist/list-agents-AW3P6FJV.js.map +0 -1
- package/dist/list-annotations-QNCGWPQ3.js.map +0 -1
- package/dist/list-dashboards-R7RK2IXL.js.map +0 -1
- package/dist/list-dataset-records-WVCSQP7P.js.map +0 -1
- package/dist/list-datasets-KEXRLDEU.js.map +0 -1
- package/dist/list-evaluators-7R2LB4JH.js.map +0 -1
- package/dist/list-model-providers-OBYJCKBX.js.map +0 -1
- package/dist/list-prompt-tags-6LY3ZPYI.js.map +0 -1
- package/dist/list-prompts-VWEZ4CDE.js.map +0 -1
- package/dist/list-scenarios-TXD4W2ZJ.js.map +0 -1
- package/dist/list-simulation-runs-RHPOLMFI.js.map +0 -1
- package/dist/list-suites-FSGBX27Z.js.map +0 -1
- package/dist/list-workflows-VRGEZ3EN.js.map +0 -1
- package/dist/rename-prompt-tag-VOJJLX4M.js.map +0 -1
- package/dist/run-agent-KTCC7TB7.js.map +0 -1
- package/dist/run-evaluation-2X3V3Q6L.js.map +0 -1
- package/dist/run-suite-BTMHGI2D.js.map +0 -1
- package/dist/run-workflow-IGAYGKJL.js.map +0 -1
- package/dist/search-traces-VYFUIMXH.js.map +0 -1
- package/dist/set-model-provider-W5IUI326.js.map +0 -1
- package/dist/update-agent-4BB7EYLR.js.map +0 -1
- package/dist/update-dataset-CXBKZ4W3.js.map +0 -1
- package/dist/update-dataset-record-HOHAMHXG.js.map +0 -1
- package/dist/update-evaluator-IVOR6FTR.js.map +0 -1
- package/dist/update-prompt-OWQAKE7K.js.map +0 -1
- package/dist/update-scenario-GDFVILPN.js.map +0 -1
- package/dist/update-suite-BXYUYSPT.js.map +0 -1
- package/tests/evaluations.ipynb +0 -649
- package/tests/fixtures/azure/azure_openai_stream_bot_expected.py +0 -102
- package/tests/fixtures/azure/azure_openai_stream_bot_input.py +0 -78
- package/tests/fixtures/dspy/dspy_bot_expected.py +0 -61
- package/tests/fixtures/dspy/dspy_bot_input.py +0 -53
- package/tests/fixtures/fastapi/fastapi_app_expected.py +0 -68
- package/tests/fixtures/fastapi/fastapi_app_input.py +0 -60
- package/tests/fixtures/fastapi/prompt_management_fastapi_expected.py +0 -114
- package/tests/fixtures/fastapi/prompt_management_fastapi_input.py +0 -88
- package/tests/fixtures/haystack/haystack_bot_expected.py +0 -141
- package/tests/fixtures/haystack/haystack_bot_input.py +0 -69
- package/tests/fixtures/langchain/langchain_bot_expected.py +0 -53
- package/tests/fixtures/langchain/langchain_bot_input.py +0 -45
- package/tests/fixtures/langchain/langchain_bot_with_memory_expected.py +0 -69
- package/tests/fixtures/langchain/langchain_bot_with_memory_input.py +0 -61
- package/tests/fixtures/langchain/langchain_rag_bot_expected.py +0 -97
- package/tests/fixtures/langchain/langchain_rag_bot_input.py +0 -77
- package/tests/fixtures/langchain/langchain_rag_bot_vertex_ai_expected.py +0 -116
- package/tests/fixtures/langchain/langchain_rag_bot_vertex_ai_input.py +0 -81
- package/tests/fixtures/langchain/langgraph_rag_bot_with_threads_expected.py +0 -331
- package/tests/fixtures/langchain/langgraph_rag_bot_with_threads_input.py +0 -106
- package/tests/fixtures/litellm/litellm_bot_expected.py +0 -40
- package/tests/fixtures/litellm/litellm_bot_input.py +0 -35
- package/tests/fixtures/openai/openai_bot_expected.py +0 -43
- package/tests/fixtures/openai/openai_bot_function_call_expected.py +0 -91
- package/tests/fixtures/openai/openai_bot_function_call_input.py +0 -82
- package/tests/fixtures/openai/openai_bot_input.py +0 -36
- package/tests/fixtures/openai/openai_bot_rag_expected.py +0 -73
- package/tests/fixtures/openai/openai_bot_rag_input.py +0 -51
- package/tests/fixtures/opentelemetry/openinference_dspy_bot_expected.py +0 -63
- package/tests/fixtures/opentelemetry/openinference_dspy_bot_input.py +0 -58
- package/tests/fixtures/opentelemetry/openinference_langchain_bot_expected.py +0 -53
- package/tests/fixtures/opentelemetry/openinference_langchain_bot_input.py +0 -52
- package/tests/fixtures/opentelemetry/openinference_openai_bot_expected.py +0 -49
- package/tests/fixtures/opentelemetry/openinference_openai_bot_input.py +0 -41
- package/tests/fixtures/opentelemetry/openllmetry_openai_bot_expected.py +0 -44
- package/tests/fixtures/opentelemetry/openllmetry_openai_bot_input.py +0 -40
- package/tests/fixtures/strands/strands_bot_expected.py +0 -84
- package/tests/fixtures/strands/strands_bot_input.py +0 -52
- package/tests/scenario-openai.test.ts +0 -160
- package/tsup.config.ts +0 -14
- package/vitest.config.js +0 -7
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/delete-evaluator.ts"],"sourcesContent":["import { deleteEvaluator as apiDeleteEvaluator } from \"../langwatch-api-evaluators.js\";\n\n/**\n * Handles the platform_delete_evaluator MCP tool invocation.\n */\nexport async function handleDeleteEvaluator(params: {\n idOrSlug: string;\n}): Promise<string> {\n const result = await apiDeleteEvaluator(params.idOrSlug);\n\n return `Evaluator ${result.id} has been archived (soft-deleted).`;\n}\n"],"mappings":";;;;;;;AAKA,eAAsB,sBAAsB,QAExB;AAClB,QAAM,SAAS,MAAM,gBAAmB,OAAO,QAAQ;AAEvD,SAAO,aAAa,OAAO,EAAE;AAC/B;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/delete-prompt-tag.ts"],"sourcesContent":["import { deletePromptTag as apiDeletePromptTag } from \"../langwatch-api.js\";\n\nexport async function handleDeletePromptTag(params: {\n tag: string;\n}): Promise<string> {\n await apiDeletePromptTag(params.tag);\n\n const lines: string[] = [];\n lines.push(\"Tag deleted successfully!\\n\");\n lines.push(`**Tag**: ${params.tag}`);\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;AAEA,eAAsB,sBAAsB,QAExB;AAClB,QAAM,gBAAmB,OAAO,GAAG;AAEnC,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,6BAA6B;AACxC,QAAM,KAAK,YAAY,OAAO,GAAG,EAAE;AACnC,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/delete-workflow.ts"],"sourcesContent":["import { deleteWorkflow as apiDeleteWorkflow } from \"../langwatch-api-workflows.js\";\n\nexport async function handleDeleteWorkflow(params: { id: string }): Promise<string> {\n const result = await apiDeleteWorkflow(params.id);\n\n return `Workflow archived successfully!\\n\\n**ID**: ${result.id}`;\n}\n"],"mappings":";;;;;;;AAEA,eAAsB,qBAAqB,QAAyC;AAClF,QAAM,SAAS,MAAM,eAAkB,OAAO,EAAE;AAEhD,SAAO;AAAA;AAAA,UAA8C,OAAO,EAAE;AAChE;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../langevals/ts-integration/evaluators.generated.ts","../src/tools/discover-evaluator-schema.ts"],"sourcesContent":["export type EvaluatorDefinition<T extends EvaluatorTypes> = {\n name: string;\n description: string;\n category: \"quality\" | \"rag\" | \"safety\" | \"policy\" | \"other\" | \"custom\" | \"similarity\";\n docsUrl?: string;\n isGuardrail: boolean;\n requiredFields: (\"input\" | \"output\" | \"contexts\" | \"expected_output\" | \"expected_contexts\" | \"conversation\")[];\n optionalFields: (\"input\" | \"output\" | \"contexts\" | \"expected_output\" | \"expected_contexts\" | \"conversation\")[];\n settings: {\n [K in keyof Evaluators[T][\"settings\"]]: {\n description?: string;\n default: Evaluators[T][\"settings\"][K];\n };\n };\n envVars: string[];\n result: {\n score?: {\n description: string;\n };\n passed?: {\n description: string;\n };\n label?: {\n description: string;\n };\n };\n};\n\nexport type EvaluatorTypes = keyof Evaluators;\n\nexport type EvaluationResult = {\n status: 'processed';\n score?: number | undefined;\n passed?: boolean | undefined;\n label?: string | undefined;\n details?: string | undefined;\n cost?: Money | undefined;\n raw_response?: any;\n};\n\nexport type EvaluationResultSkipped = {\n status: 'skipped';\n details?: string | undefined;\n};\n\nexport type EvaluationResultError = {\n status: 'error';\n error_type: string;\n details: string;\n traceback: string[];\n};\n\nexport type SingleEvaluationResult = EvaluationResult | EvaluationResultSkipped | EvaluationResultError;\nexport type BatchEvaluationResult = SingleEvaluationResult[];\n\nexport type Money = {\n currency: string;\n amount: number;\n};\n\nexport type Evaluators = {\n \"legacy/ragas_answer_correctness\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The model to use for embeddings.\n * @default \"openai/text-embedding-ada-002\"\n */\n embeddings_model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n };\n };\n \"legacy/ragas_answer_relevancy\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The model to use for embeddings.\n * @default \"openai/text-embedding-ada-002\"\n */\n embeddings_model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n };\n };\n \"legacy/ragas_context_precision\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The model to use for embeddings.\n * @default \"openai/text-embedding-ada-002\"\n */\n embeddings_model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n };\n };\n \"legacy/ragas_context_recall\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The model to use for embeddings.\n * @default \"openai/text-embedding-ada-002\"\n */\n embeddings_model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n };\n };\n \"legacy/ragas_context_relevancy\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The model to use for embeddings.\n * @default \"openai/text-embedding-ada-002\"\n */\n embeddings_model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n };\n };\n \"legacy/ragas_context_utilization\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The model to use for embeddings.\n * @default \"openai/text-embedding-ada-002\"\n */\n embeddings_model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n };\n };\n \"legacy/ragas_faithfulness\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The model to use for embeddings.\n * @default \"openai/text-embedding-ada-002\"\n */\n embeddings_model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n };\n };\n \"presidio/pii_detection\": {\n settings: {\n /**\n * @description The types of PII to check for in the input.\n * @default {\"credit_card\": true, \"crypto\": true, \"email_address\": true, \"iban_code\": true, \"ip_address\": true, \"location\": false, \"person\": false, \"phone_number\": true, \"medical_license\": true, \"us_bank_number\": false, \"us_driver_license\": false, \"us_itin\": false, \"us_passport\": false, \"us_ssn\": false, \"uk_nhs\": false, \"sg_nric_fin\": false, \"au_abn\": false, \"au_acn\": false, \"au_tfn\": false, \"au_medicare\": false, \"in_pan\": false, \"in_aadhaar\": false, \"in_vehicle_registration\": false, \"in_voter\": false, \"in_passport\": false}\n */\n entities: {\n /**\n * @default true\n */\n credit_card: boolean;\n /**\n * @default true\n */\n crypto: boolean;\n /**\n * @default true\n */\n email_address: boolean;\n /**\n * @default true\n */\n iban_code: boolean;\n /**\n * @default true\n */\n ip_address: boolean;\n /**\n * @default false\n */\n location: boolean;\n /**\n * @default false\n */\n person: boolean;\n /**\n * @default true\n */\n phone_number: boolean;\n /**\n * @default true\n */\n medical_license: boolean;\n /**\n * @default false\n */\n us_bank_number: boolean;\n /**\n * @default false\n */\n us_driver_license: boolean;\n /**\n * @default false\n */\n us_itin: boolean;\n /**\n * @default false\n */\n us_passport: boolean;\n /**\n * @default false\n */\n us_ssn: boolean;\n /**\n * @default false\n */\n uk_nhs: boolean;\n /**\n * @default false\n */\n sg_nric_fin: boolean;\n /**\n * @default false\n */\n au_abn: boolean;\n /**\n * @default false\n */\n au_acn: boolean;\n /**\n * @default false\n */\n au_tfn: boolean;\n /**\n * @default false\n */\n au_medicare: boolean;\n /**\n * @default false\n */\n in_pan: boolean;\n /**\n * @default false\n */\n in_aadhaar: boolean;\n /**\n * @default false\n */\n in_vehicle_registration: boolean;\n /**\n * @default false\n */\n in_voter: boolean;\n /**\n * @default false\n */\n in_passport: boolean;\n };\n /**\n * @description The minimum confidence required for failing the evaluation on a PII match.\n * @default 0.5\n */\n min_threshold: number;\n };\n };\n \"lingua/language_detection\": {\n settings: {\n /**\n * @description What should be checked\n * @default \"input_matches_output\"\n */\n check_for: \"input_matches_output\" | \"output_matches_language\";\n /**\n * @description The specific language that the output is expected to be\n */\n expected_language?: \"AF\" | \"AR\" | \"AZ\" | \"BE\" | \"BG\" | \"BN\" | \"BS\" | \"CA\" | \"CS\" | \"CY\" | \"DA\" | \"DE\" | \"EL\" | \"EN\" | \"EO\" | \"ES\" | \"ET\" | \"EU\" | \"FA\" | \"FI\" | \"FR\" | \"GA\" | \"GU\" | \"HE\" | \"HI\" | \"HR\" | \"HU\" | \"HY\" | \"ID\" | \"IS\" | \"IT\" | \"JA\" | \"KA\" | \"KK\" | \"KO\" | \"LA\" | \"LG\" | \"LT\" | \"LV\" | \"MI\" | \"MK\" | \"MN\" | \"MR\" | \"MS\" | \"NB\" | \"NL\" | \"NN\" | \"PA\" | \"PL\" | \"PT\" | \"RO\" | \"RU\" | \"SK\" | \"SL\" | \"SN\" | \"SO\" | \"SQ\" | \"SR\" | \"ST\" | \"SV\" | \"SW\" | \"TA\" | \"TE\" | \"TH\" | \"TL\" | \"TN\" | \"TR\" | \"TS\" | \"UK\" | \"UR\" | \"VI\" | \"XH\" | \"YO\" | \"ZH\" | \"ZU\";\n /**\n * @description Minimum number of words to check, as the language detection can be unreliable for very short texts. Inputs shorter than the minimum will be skipped.\n * @default 7\n */\n min_words: number;\n /**\n * @description Minimum confidence threshold for the language detection. If the confidence is lower than this, the evaluation will be skipped.\n * @default 0.25\n */\n threshold: number;\n };\n };\n \"openai/moderation\": {\n settings: {\n /**\n * @description The model version to use, `text-moderation-latest` will be automatically upgraded over time, while `text-moderation-stable` will only be updated with advanced notice by OpenAI.\n * @default \"text-moderation-stable\"\n */\n model: \"text-moderation-stable\" | \"text-moderation-latest\";\n /**\n * @description The categories of content to check for moderation.\n * @default {\"harassment\": true, \"harassment_threatening\": true, \"hate\": true, \"hate_threatening\": true, \"self_harm\": true, \"self_harm_instructions\": true, \"self_harm_intent\": true, \"sexual\": true, \"sexual_minors\": true, \"violence\": true, \"violence_graphic\": true}\n */\n categories: {\n /**\n * @default true\n */\n harassment: boolean;\n /**\n * @default true\n */\n harassment_threatening: boolean;\n /**\n * @default true\n */\n hate: boolean;\n /**\n * @default true\n */\n hate_threatening: boolean;\n /**\n * @default true\n */\n self_harm: boolean;\n /**\n * @default true\n */\n self_harm_instructions: boolean;\n /**\n * @default true\n */\n self_harm_intent: boolean;\n /**\n * @default true\n */\n sexual: boolean;\n /**\n * @default true\n */\n sexual_minors: boolean;\n /**\n * @default true\n */\n violence: boolean;\n /**\n * @default true\n */\n violence_graphic: boolean;\n };\n };\n };\n \"ragas/bleu_score\": {\n settings: Record<string, never>;\n };\n \"ragas/context_f1\": {\n settings: {\n /**\n * @default \"levenshtein\"\n */\n distance_measure: \"levenshtein\" | \"hamming\" | \"jaro\" | \"jaro_winkler\";\n };\n };\n \"ragas/context_precision\": {\n settings: {\n /**\n * @default \"levenshtein\"\n */\n distance_measure: \"levenshtein\" | \"hamming\" | \"jaro\" | \"jaro_winkler\";\n };\n };\n \"ragas/context_recall\": {\n settings: {\n /**\n * @default \"levenshtein\"\n */\n distance_measure: \"levenshtein\" | \"hamming\" | \"jaro\" | \"jaro_winkler\";\n };\n };\n \"ragas/factual_correctness\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n /**\n * @description The mode to use for the factual correctness metric.\n * @default \"f1\"\n */\n mode: \"f1\" | \"precision\" | \"recall\";\n /**\n * @description The level of atomicity for claim decomposition.\n * @default \"low\"\n */\n atomicity: \"low\" | \"high\";\n /**\n * @description The level of coverage for claim decomposition.\n * @default \"low\"\n */\n coverage: \"low\" | \"high\";\n };\n };\n \"ragas/faithfulness\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n /**\n * @description Whether to autodetect 'I don't know' in the output to avoid failing the evaluation.\n * @default true\n */\n autodetect_dont_know: boolean;\n };\n };\n \"ragas/response_context_precision\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n };\n };\n \"ragas/response_context_recall\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n };\n };\n \"ragas/response_relevancy\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n /**\n * @description The model to use for embeddings.\n * @default \"openai/text-embedding-ada-002\"\n */\n embeddings_model: string;\n };\n };\n \"ragas/rouge_score\": {\n settings: {\n /**\n * @description ROUGE type\n * @default \"rouge1\"\n */\n rouge_type: \"rouge1\" | \"rougeL\";\n /**\n * @description ROUGE measure type\n * @default \"fmeasure\"\n */\n measure_type: \"fmeasure\" | \"precision\" | \"recall\";\n };\n };\n \"ragas/rubrics_based_scoring\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n /**\n * @default [{\"description\": \"The response is incorrect, irrelevant.\"}, {\"description\": \"The response partially answers the question but includes significant errors, omissions, or irrelevant information.\"}, {\"description\": \"The response partially answers the question but includes minor errors, omissions, or irrelevant information.\"}, {\"description\": \"The response fully answers the question and includes minor errors, omissions, or irrelevant information.\"}, {\"description\": \"The response fully answers the question and includes no errors, omissions, or irrelevant information.\"}]\n */\n rubrics: {\n description: string;\n }[];\n };\n };\n \"ragas/sql_query_equivalence\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n };\n };\n \"ragas/summarization_score\": {\n settings: {\n /**\n * @description The model to use for evaluation.\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\n * @default 2048\n */\n max_tokens: number;\n };\n };\n \"azure/content_safety\": {\n settings: {\n /**\n * @description The minimum severity level to consider content as unsafe, from 1 to 7.\n * @default 1\n */\n severity_threshold: 1 | 2 | 3 | 4 | 5 | 6 | 7;\n /**\n * @description The categories of moderation to check for.\n * @default {\"Hate\": true, \"SelfHarm\": true, \"Sexual\": true, \"Violence\": true}\n */\n categories: {\n /**\n * @default true\n */\n Hate: boolean;\n /**\n * @default true\n */\n SelfHarm: boolean;\n /**\n * @default true\n */\n Sexual: boolean;\n /**\n * @default true\n */\n Violence: boolean;\n };\n /**\n * @description The type of severity levels to return on the full 0-7 severity scale, it can be either the trimmed version with four values (0, 2, 4, 6 scores) or the whole range.\n * @default \"FourSeverityLevels\"\n */\n output_type: \"FourSeverityLevels\" | \"EightSeverityLevels\";\n };\n };\n \"azure/jailbreak\": {\n settings: Record<string, never>;\n };\n \"azure/prompt_injection\": {\n settings: Record<string, never>;\n };\n \"langevals/basic\": {\n settings: {\n /**\n * @description List of rules to check, the message must pass all of them\n * @default [{\"field\": \"output\", \"rule\": \"not_contains\", \"value\": \"artificial intelligence\"}]\n */\n rules: {\n /**\n * @default \"output\"\n */\n field: \"input\" | \"output\";\n rule: \"contains\" | \"not_contains\" | \"matches_regex\" | \"not_matches_regex\";\n value: string;\n }[];\n };\n };\n \"langevals/competitor_blocklist\": {\n settings: {\n /**\n * @description The competitors that must not be mentioned.\n * @default [\"OpenAI\", \"Google\", \"Microsoft\"]\n */\n competitors: string[];\n };\n };\n \"langevals/competitor_llm\": {\n settings: {\n /**\n * @description The model to use for evaluation\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description Max tokens allowed for evaluation\n * @default 128000\n */\n max_tokens: number;\n /**\n * @description The name of your company\n * @default \"LangWatch\"\n */\n name: string;\n /**\n * @description Description of what your company is specializing at\n * @default \"We are providing an LLM observability and evaluation platform\"\n */\n description: string;\n };\n };\n \"langevals/competitor_llm_function_call\": {\n settings: {\n /**\n * @description The model to use for evaluation\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description Max tokens allowed for evaluation\n * @default 128000\n */\n max_tokens: number;\n /**\n * @description The name of your company\n * @default \"LangWatch\"\n */\n name: string;\n /**\n * @description Description of what your company is specializing at\n * @default \"We are providing an LLM observability and evaluation platform\"\n */\n description: string;\n /**\n * @description The competitors that must not be mentioned.\n * @default [\"OpenAI\", \"Google\", \"Microsoft\"]\n */\n competitors: string[];\n };\n };\n \"langevals/exact_match\": {\n settings: {\n /**\n * @description True if the comparison should be case-sensitive, False otherwise\n * @default false\n */\n case_sensitive: boolean;\n /**\n * @description True if the comparison should trim whitespace, False otherwise\n * @default true\n */\n trim_whitespace: boolean;\n /**\n * @description True if the comparison should remove punctuation, False otherwise\n * @default true\n */\n remove_punctuation: boolean;\n };\n };\n \"langevals/llm_answer_match\": {\n settings: {\n /**\n * @description The model to use for evaluation\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description Max tokens allowed for evaluation\n * @default 128000\n */\n max_tokens: number;\n /**\n * @description Prompt for the comparison\n * @default \"Verify that the predicted answer matches the gold answer for the question. Style does not matter, for example the gold answer may be more direct while the predicted answer more verbose and still be correct.\"\n */\n prompt: string;\n };\n };\n \"langevals/llm_boolean\": {\n settings: {\n /**\n * @description The model to use for evaluation\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description Max tokens allowed for evaluation\n * @default 128000\n */\n max_tokens: number;\n /**\n * @description The system prompt to use for the LLM to run the evaluation\n * @default \"You are an LLM evaluator. We need the guarantee that the output answers what is being asked on the input, please evaluate as False if it doesn't\"\n */\n prompt: string;\n };\n };\n \"langevals/llm_category\": {\n settings: {\n /**\n * @description The model to use for evaluation\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description Max tokens allowed for evaluation\n * @default 128000\n */\n max_tokens: number;\n /**\n * @description The system prompt to use for the LLM to run the evaluation\n * @default \"You are an LLM category evaluator. Please categorize the message in one of the following categories\"\n */\n prompt: string;\n /**\n * @description The categories to use for the evaluation\n * @default [{\"name\": \"smalltalk\", \"description\": \"Smalltalk with the user\"}, {\"name\": \"company\", \"description\": \"Questions about the company, what we do, etc\"}]\n */\n categories: {\n name: string;\n description: string;\n }[];\n };\n };\n \"langevals/llm_score\": {\n settings: {\n /**\n * @description The model to use for evaluation\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description Max tokens allowed for evaluation\n * @default 128000\n */\n max_tokens: number;\n /**\n * @description The system prompt to use for the LLM to run the evaluation\n * @default \"You are an LLM evaluator. Please score from 0.0 to 1.0 how likely the user is to be satisfied with this answer, from 0.0 being not satisfied at all to 1.0 being completely satisfied\"\n */\n prompt: string;\n };\n };\n \"langevals/off_topic\": {\n settings: {\n /**\n * @description The model to use for evaluation\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description Max tokens allowed for evaluation\n * @default 128000\n */\n max_tokens: number;\n /**\n * @description The list of topics and their short descriptions that the chatbot is allowed to talk about\n * @default [{\"topic\": \"simple_chat\", \"description\": \"Smalltalk with the user\"}, {\"topic\": \"company\", \"description\": \"Questions about the company, what we do, etc\"}]\n */\n allowed_topics: {\n topic: string;\n description: string;\n }[];\n };\n };\n \"langevals/query_resolution\": {\n settings: {\n /**\n * @description The model to use for evaluation\n * @default \"openai/gpt-5\"\n */\n model: string;\n /**\n * @description Max tokens allowed for evaluation\n * @default 128000\n */\n max_tokens: number;\n };\n };\n \"langevals/sentiment\": {\n settings: {\n /**\n * @description The embeddings model to use for sentiment analysis\n * @default \"openai/text-embedding-3-small\"\n */\n embeddings_model: string;\n /**\n * @description Reference phrase representing the positive end of the sentiment scale\n * @default \"Comment of a very happy and satisfied user\"\n */\n positive_reference: string;\n /**\n * @description Reference phrase representing the negative end of the sentiment scale\n * @default \"Comment of a user who is extremely dissatisfied\"\n */\n negative_reference: string;\n /**\n * @description Controls sentiment sensitivity. Decrease to make scores more extreme (fewer neutrals), increase to make scores more moderate (more neutrals)\n * @default 0.1\n */\n normalization_factor: number;\n };\n };\n \"langevals/similarity\": {\n settings: {\n /**\n * @default \"output\"\n */\n field: \"input\" | \"output\";\n /**\n * @default \"is_not_similar_to\"\n */\n rule: \"is_not_similar_to\" | \"is_similar_to\";\n /**\n * @default \"example\"\n */\n value: string;\n /**\n * @default 0.3\n */\n threshold: number;\n /**\n * @default \"openai/text-embedding-3-small\"\n */\n embeddings_model: string;\n };\n };\n \"langevals/valid_format\": {\n settings: {\n /**\n * @default \"json\"\n */\n format: \"json\" | \"markdown\" | \"python\" | \"sql\";\n /**\n * @description JSON schema to validate against when format is 'json'\n */\n json_schema?: string;\n };\n };\n};\n\nexport const AVAILABLE_EVALUATORS: {\n [K in EvaluatorTypes]: EvaluatorDefinition<K>;\n} = {\n \"legacy/ragas_answer_correctness\": {\n name: `Ragas Answer Correctness`,\n description: `\nComputes with an LLM a weighted combination of factual as well as semantic similarity between the generated answer and the expected output.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/latest/concepts/metrics/answer_correctness.html\",\n isGuardrail: false,\n requiredFields: [\"output\", \"expected_output\"],\n optionalFields: [\"input\"],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"embeddings_model\": {\n \"description\": \"The model to use for embeddings.\",\n \"default\": \"openai/text-embedding-ada-002\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the correctness of the answer.\"\n }\n}\n },\n \"legacy/ragas_answer_relevancy\": {\n name: `Ragas Answer Relevancy`,\n description: `\nEvaluates how pertinent the generated answer is to the given prompt. Higher scores indicate better relevancy.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/latest/concepts/metrics/answer_relevance.html\",\n isGuardrail: false,\n requiredFields: [\"input\", \"output\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"embeddings_model\": {\n \"description\": \"The model to use for embeddings.\",\n \"default\": \"openai/text-embedding-ada-002\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the relevance of the answer.\"\n }\n}\n },\n \"legacy/ragas_context_precision\": {\n name: `Ragas Context Precision`,\n description: `\nThis metric evaluates whether all of the ground-truth relevant items present in the contexts are ranked higher or not. Higher scores indicate better precision.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/latest/concepts/metrics/context_precision.html\",\n isGuardrail: false,\n requiredFields: [\"input\", \"contexts\", \"expected_output\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"embeddings_model\": {\n \"description\": \"The model to use for embeddings.\",\n \"default\": \"openai/text-embedding-ada-002\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the precision of the context.\"\n }\n}\n },\n \"legacy/ragas_context_recall\": {\n name: `Ragas Context Recall`,\n description: `\nThis evaluator measures the extent to which the retrieved context aligns with the annotated answer, treated as the ground truth. Higher values indicate better performance.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/latest/concepts/metrics/context_recall.html\",\n isGuardrail: false,\n requiredFields: [\"input\", \"contexts\", \"expected_output\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"embeddings_model\": {\n \"description\": \"The model to use for embeddings.\",\n \"default\": \"openai/text-embedding-ada-002\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the recall of the context.\"\n }\n}\n },\n \"legacy/ragas_context_relevancy\": {\n name: `Ragas Context Relevancy`,\n description: `\nThis metric gauges the relevancy of the retrieved context, calculated based on both the question and contexts. The values fall within the range of (0, 1), with higher values indicating better relevancy.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/latest/concepts/metrics/context_relevancy.html\",\n isGuardrail: false,\n requiredFields: [\"output\", \"contexts\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"embeddings_model\": {\n \"description\": \"The model to use for embeddings.\",\n \"default\": \"openai/text-embedding-ada-002\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the relevancy of the context.\"\n }\n}\n },\n \"legacy/ragas_context_utilization\": {\n name: `Ragas Context Utilization`,\n description: `\nThis metric evaluates whether all of the output relevant items present in the contexts are ranked higher or not. Higher scores indicate better utilization.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/latest/concepts/metrics/context_precision.html\",\n isGuardrail: false,\n requiredFields: [\"input\", \"output\", \"contexts\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"embeddings_model\": {\n \"description\": \"The model to use for embeddings.\",\n \"default\": \"openai/text-embedding-ada-002\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the utilization of the context.\"\n }\n}\n },\n \"legacy/ragas_faithfulness\": {\n name: `Ragas Faithfulness`,\n description: `\nThis evaluator assesses the extent to which the generated answer is consistent with the provided context. Higher scores indicate better faithfulness to the context, useful for detecting hallucinations.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/latest/concepts/metrics/faithfulness.html\",\n isGuardrail: false,\n requiredFields: [\"output\", \"contexts\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"embeddings_model\": {\n \"description\": \"The model to use for embeddings.\",\n \"default\": \"openai/text-embedding-ada-002\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the faithfulness of the answer.\"\n }\n}\n },\n \"presidio/pii_detection\": {\n name: `Presidio PII Detection`,\n description: `\nDetects personally identifiable information in text, including phone numbers, email addresses, and\nsocial security numbers. It allows customization of the detection threshold and the specific types of PII to check.\n`,\n category: \"safety\",\n docsUrl: \"https://microsoft.github.io/presidio\",\n isGuardrail: true,\n requiredFields: [],\n optionalFields: [\"input\", \"output\"],\n settings: {\n \"entities\": {\n \"description\": \"The types of PII to check for in the input.\",\n \"default\": {\n \"credit_card\": true,\n \"crypto\": true,\n \"email_address\": true,\n \"iban_code\": true,\n \"ip_address\": true,\n \"location\": false,\n \"person\": false,\n \"phone_number\": true,\n \"medical_license\": true,\n \"us_bank_number\": false,\n \"us_driver_license\": false,\n \"us_itin\": false,\n \"us_passport\": false,\n \"us_ssn\": false,\n \"uk_nhs\": false,\n \"sg_nric_fin\": false,\n \"au_abn\": false,\n \"au_acn\": false,\n \"au_tfn\": false,\n \"au_medicare\": false,\n \"in_pan\": false,\n \"in_aadhaar\": false,\n \"in_vehicle_registration\": false,\n \"in_voter\": false,\n \"in_passport\": false\n }\n },\n \"min_threshold\": {\n \"description\": \"The minimum confidence required for failing the evaluation on a PII match.\",\n \"default\": 0.5\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"Amount of PII detected, 0 means no PII detected\"\n },\n \"passed\": {\n \"description\": \"If true then no PII was detected, if false then at least one PII was detected\"\n }\n}\n },\n \"lingua/language_detection\": {\n name: `Lingua Language Detection`,\n description: `\nThis evaluator detects the language of the input and output text to check for example if the generated answer is in the same language as the prompt,\nor if it's in a specific expected language.\n`,\n category: \"quality\",\n docsUrl: \"https://github.com/pemistahl/lingua-py\",\n isGuardrail: true,\n requiredFields: [\"output\"],\n optionalFields: [\"input\"],\n settings: {\n \"check_for\": {\n \"description\": \"What should be checked\",\n \"default\": \"input_matches_output\"\n },\n \"expected_language\": {\n \"description\": \"The specific language that the output is expected to be\",\n \"default\": undefined\n },\n \"min_words\": {\n \"description\": \"Minimum number of words to check, as the language detection can be unreliable for very short texts. Inputs shorter than the minimum will be skipped.\",\n \"default\": 7\n },\n \"threshold\": {\n \"description\": \"Minimum confidence threshold for the language detection. If the confidence is lower than this, the evaluation will be skipped.\",\n \"default\": 0.25\n }\n},\n envVars: [],\n result: {\n \"passed\": {\n \"description\": \"Passes if the detected language on the output matches the detected language on the input, or if the output matches the expected language\"\n },\n \"label\": {\n \"description\": \"Language detected on the input for input_matches_output, or language detected on the output for output_matches_language\"\n }\n}\n },\n \"openai/moderation\": {\n name: `OpenAI Moderation`,\n description: `\nThis evaluator uses OpenAI's moderation API to detect potentially harmful content in text,\nincluding harassment, hate speech, self-harm, sexual content, and violence.\n`,\n category: \"safety\",\n docsUrl: \"https://platform.openai.com/docs/guides/moderation/overview\",\n isGuardrail: true,\n requiredFields: [],\n optionalFields: [\"input\", \"output\"],\n settings: {\n \"model\": {\n \"description\": \"The model version to use, `text-moderation-latest` will be automatically upgraded over time, while `text-moderation-stable` will only be updated with advanced notice by OpenAI.\",\n \"default\": \"text-moderation-stable\"\n },\n \"categories\": {\n \"description\": \"The categories of content to check for moderation.\",\n \"default\": {\n \"harassment\": true,\n \"harassment_threatening\": true,\n \"hate\": true,\n \"hate_threatening\": true,\n \"self_harm\": true,\n \"self_harm_instructions\": true,\n \"self_harm_intent\": true,\n \"sexual\": true,\n \"sexual_minors\": true,\n \"violence\": true,\n \"violence_graphic\": true\n }\n }\n},\n envVars: [\"OPENAI_API_KEY\"],\n result: {\n \"score\": {\n \"description\": \"The model's confidence on primary category where the input violates the OpenAI's policy. The value is between 0 and 1, where higher values denote higher confidence.\"\n },\n \"passed\": {\n \"description\": \"Fails if any moderation category is flagged\"\n }\n}\n },\n \"ragas/bleu_score\": {\n name: `BLEU Score`,\n description: `\nTraditional NLP metric. BLEU score for evaluating the similarity between two strings.\n`,\n category: \"quality\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/traditional/#bleu-score\",\n isGuardrail: false,\n requiredFields: [\"output\", \"expected_output\"],\n optionalFields: [],\n settings: {},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"BLEU similarity score\"\n }\n}\n },\n \"ragas/context_f1\": {\n name: `Context F1`,\n description: `\nBalances between precision and recall for context retrieval, increasing it means a better signal-to-noise ratio. Uses traditional string distance metrics.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_F1/#non-llm-based-context-F1\",\n isGuardrail: false,\n requiredFields: [\"contexts\", \"expected_contexts\"],\n optionalFields: [],\n settings: {\n \"distance_measure\": {\n \"description\": undefined,\n \"default\": \"levenshtein\"\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the F1 score.\"\n }\n}\n },\n \"ragas/context_precision\": {\n name: `Context Precision`,\n description: `\nMeasures how accurate is the retrieval compared to expected contexts, increasing it means less noise in the retrieval. Uses traditional string distance metrics.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_precision/#non-llm-based-context-precision\",\n isGuardrail: false,\n requiredFields: [\"contexts\", \"expected_contexts\"],\n optionalFields: [],\n settings: {\n \"distance_measure\": {\n \"description\": undefined,\n \"default\": \"levenshtein\"\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the precision score.\"\n }\n}\n },\n \"ragas/context_recall\": {\n name: `Context Recall`,\n description: `\nMeasures how many relevant contexts were retrieved compared to expected contexts, increasing it means more signal in the retrieval. Uses traditional string distance metrics.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_recall/#non-llm-based-context-recall\",\n isGuardrail: false,\n requiredFields: [\"contexts\", \"expected_contexts\"],\n optionalFields: [],\n settings: {\n \"distance_measure\": {\n \"description\": undefined,\n \"default\": \"levenshtein\"\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the Recall score.\"\n }\n}\n },\n \"ragas/factual_correctness\": {\n name: `LLM Factual Match`,\n description: `\nComputes with an LLM how factually similar the generated answer is to the expected output.\n`,\n category: \"quality\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/factual_correctness/\",\n isGuardrail: false,\n requiredFields: [\"output\", \"expected_output\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n },\n \"mode\": {\n \"description\": \"The mode to use for the factual correctness metric.\",\n \"default\": \"f1\"\n },\n \"atomicity\": {\n \"description\": \"The level of atomicity for claim decomposition.\",\n \"default\": \"low\"\n },\n \"coverage\": {\n \"description\": \"The level of coverage for claim decomposition.\",\n \"default\": \"low\"\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating how factually similar the generated answer is to the expected output.\"\n }\n}\n },\n \"ragas/faithfulness\": {\n name: `Ragas Faithfulness`,\n description: `\nThis evaluator assesses the extent to which the generated answer is consistent with the provided context. Higher scores indicate better faithfulness to the context, useful for detecting hallucinations.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/faithfulness/\",\n isGuardrail: false,\n requiredFields: [\"output\", \"contexts\"],\n optionalFields: [\"input\"],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n },\n \"autodetect_dont_know\": {\n \"description\": \"Whether to autodetect 'I don't know' in the output to avoid failing the evaluation.\",\n \"default\": true\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the faithfulness of the answer.\"\n }\n}\n },\n \"ragas/response_context_precision\": {\n name: `Ragas Response Context Precision`,\n description: `\nUses an LLM to measure the proportion of chunks in the retrieved context that were relevant to generate the output or the expected output.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_precision/#context-precision-without-reference\",\n isGuardrail: false,\n requiredFields: [\"input\", \"contexts\"],\n optionalFields: [\"output\", \"expected_output\"],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the precision of the retrieved context.\"\n }\n}\n },\n \"ragas/response_context_recall\": {\n name: `Ragas Response Context Recall`,\n description: `\nUses an LLM to measure how many of relevant documents attributable the claims in the output were successfully retrieved in order to generate an expected output.\n`,\n category: \"rag\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_recall/#llm-based-context-recall\",\n isGuardrail: false,\n requiredFields: [\"input\", \"output\", \"contexts\", \"expected_output\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the recall of the retrieved context.\"\n }\n}\n },\n \"ragas/response_relevancy\": {\n name: `Ragas Response Relevancy`,\n description: `\nEvaluates how pertinent the generated answer is to the given prompt. Higher scores indicate better relevancy.\n`,\n category: \"quality\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/answer_relevance/\",\n isGuardrail: false,\n requiredFields: [\"input\", \"output\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n },\n \"embeddings_model\": {\n \"description\": \"The model to use for embeddings.\",\n \"default\": \"openai/text-embedding-ada-002\"\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the relevance of the answer.\"\n }\n}\n },\n \"ragas/rouge_score\": {\n name: `ROUGE Score`,\n description: `\nTraditional NLP metric. ROUGE score for evaluating the similarity between two strings.\n`,\n category: \"quality\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/traditional/#rouge-score\",\n isGuardrail: false,\n requiredFields: [\"output\", \"expected_output\"],\n optionalFields: [],\n settings: {\n \"rouge_type\": {\n \"description\": \"ROUGE type\",\n \"default\": \"rouge1\"\n },\n \"measure_type\": {\n \"description\": \"ROUGE measure type\",\n \"default\": \"fmeasure\"\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"ROUGE similarity score\"\n }\n}\n },\n \"ragas/rubrics_based_scoring\": {\n name: `Rubrics Based Scoring`,\n description: `\nRubric-based evaluation metric that is used to evaluate responses. The rubric consists of descriptions for each score, typically ranging from 1 to 5\n`,\n category: \"quality\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/general_purpose/#rubrics-based-criteria-scoring\",\n isGuardrail: false,\n requiredFields: [\"input\", \"output\"],\n optionalFields: [\"expected_output\"],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n },\n \"rubrics\": {\n \"description\": undefined,\n \"default\": [\n {\n \"description\": \"The response is incorrect, irrelevant.\"\n },\n {\n \"description\": \"The response partially answers the question but includes significant errors, omissions, or irrelevant information.\"\n },\n {\n \"description\": \"The response partially answers the question but includes minor errors, omissions, or irrelevant information.\"\n },\n {\n \"description\": \"The response fully answers the question and includes minor errors, omissions, or irrelevant information.\"\n },\n {\n \"description\": \"The response fully answers the question and includes no errors, omissions, or irrelevant information.\"\n }\n ]\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score according to the rubrics, typically between 1 and 5.\"\n }\n}\n },\n \"ragas/sql_query_equivalence\": {\n name: `SQL Query Equivalence`,\n description: `\nChecks if the SQL query is equivalent to a reference one by using an LLM to infer if it would generate the same results given the table schemas.\n`,\n category: \"quality\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/sql/#sql-query-semantic-equivalence\",\n isGuardrail: false,\n requiredFields: [\"output\", \"expected_output\", \"expected_contexts\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n }\n},\n envVars: [],\n result: {\n \"passed\": {\n \"description\": \"Whether the SQL query is equivalent to the expected one.\"\n }\n}\n },\n \"ragas/summarization_score\": {\n name: `Summarization Score`,\n description: `\nMeasures how well the summary captures important information from the retrieved contexts.\n`,\n category: \"quality\",\n docsUrl: \"https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/summarization_score/\",\n isGuardrail: false,\n requiredFields: [\"output\", \"contexts\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation.\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"The maximum number of tokens allowed for evaluation, a too high number can be costly. Entries above this amount will be skipped.\",\n \"default\": 2048\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"A score between 0.0 and 1.0 indicating the summarization quality.\"\n }\n}\n },\n \"azure/content_safety\": {\n name: `Azure Content Safety`,\n description: `\nThis evaluator detects potentially unsafe content in text, including hate speech,\nself-harm, sexual content, and violence. It allows customization of the severity\nthreshold and the specific categories to check.\n`,\n category: \"safety\",\n docsUrl: \"https://learn.microsoft.com/en-us/azure/ai-services/content-safety/quickstart-text\",\n isGuardrail: true,\n requiredFields: [],\n optionalFields: [\"input\", \"output\"],\n settings: {\n \"severity_threshold\": {\n \"description\": \"The minimum severity level to consider content as unsafe, from 1 to 7.\",\n \"default\": 1\n },\n \"categories\": {\n \"description\": \"The categories of moderation to check for.\",\n \"default\": {\n \"Hate\": true,\n \"SelfHarm\": true,\n \"Sexual\": true,\n \"Violence\": true\n }\n },\n \"output_type\": {\n \"description\": \"The type of severity levels to return on the full 0-7 severity scale, it can be either the trimmed version with four values (0, 2, 4, 6 scores) or the whole range.\",\n \"default\": \"FourSeverityLevels\"\n }\n},\n envVars: [\"AZURE_CONTENT_SAFETY_ENDPOINT\", \"AZURE_CONTENT_SAFETY_KEY\"],\n result: {\n \"score\": {\n \"description\": \"The severity level of the detected content from 0 to 7. A higher score indicates higher severity.\"\n }\n}\n },\n \"azure/jailbreak\": {\n name: `Azure Jailbreak Detection`,\n description: `\nThis evaluator checks for jailbreak-attempt in the input using Azure's Content Safety API.\n`,\n category: \"safety\",\n docsUrl: \"\",\n isGuardrail: true,\n requiredFields: [\"input\"],\n optionalFields: [],\n settings: {},\n envVars: [\"AZURE_CONTENT_SAFETY_ENDPOINT\", \"AZURE_CONTENT_SAFETY_KEY\"],\n result: {\n \"passed\": {\n \"description\": \"If true then no jailbreak was detected, if false then a jailbreak was detected\"\n }\n}\n },\n \"azure/prompt_injection\": {\n name: `Azure Prompt Shield`,\n description: `\nThis evaluator checks for prompt injection attempt in the input and the contexts using Azure's Content Safety API.\n`,\n category: \"safety\",\n docsUrl: \"https://learn.microsoft.com/en-us/azure/ai-services/content-safety/concepts/jailbreak-detection\",\n isGuardrail: true,\n requiredFields: [\"input\"],\n optionalFields: [\"contexts\"],\n settings: {},\n envVars: [\"AZURE_CONTENT_SAFETY_ENDPOINT\", \"AZURE_CONTENT_SAFETY_KEY\"],\n result: {\n \"passed\": {\n \"description\": \"If true then no prompt injection was detected, if false then a prompt injection was detected\"\n }\n}\n },\n \"langevals/basic\": {\n name: `Custom Basic Evaluator`,\n description: `\nAllows you to check for simple text matches or regex evaluation.\n`,\n category: \"custom\",\n docsUrl: \"\",\n isGuardrail: true,\n requiredFields: [],\n optionalFields: [\"input\", \"output\"],\n settings: {\n \"rules\": {\n \"description\": \"List of rules to check, the message must pass all of them\",\n \"default\": [\n {\n \"field\": \"output\",\n \"rule\": \"not_contains\",\n \"value\": \"artificial intelligence\"\n }\n ]\n }\n},\n envVars: [],\n result: {\n \"passed\": {\n \"description\": \"True if all rules pass, False if any rule fails\"\n }\n}\n },\n \"langevals/competitor_blocklist\": {\n name: `Competitor Blocklist`,\n description: `\nThis evaluator checks if any of the specified competitors was mentioned\n`,\n category: \"policy\",\n docsUrl: \"https://path/to/official/docs\",\n isGuardrail: true,\n requiredFields: [],\n optionalFields: [\"output\", \"input\"],\n settings: {\n \"competitors\": {\n \"description\": \"The competitors that must not be mentioned.\",\n \"default\": [\n \"OpenAI\",\n \"Google\",\n \"Microsoft\"\n ]\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"Number of competitors mentioned in the input and output\"\n },\n \"passed\": {\n \"description\": \"Is the message containing explicit mention of competitor\"\n }\n}\n },\n \"langevals/competitor_llm\": {\n name: `Competitor Allowlist Check`,\n description: `\nThis evaluator use an LLM-as-judge to check if the conversation is related to competitors, without having to name them explicitly\n`,\n category: \"policy\",\n docsUrl: \"\",\n isGuardrail: true,\n requiredFields: [],\n optionalFields: [\"output\", \"input\"],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"Max tokens allowed for evaluation\",\n \"default\": 128000\n },\n \"name\": {\n \"description\": \"The name of your company\",\n \"default\": \"LangWatch\"\n },\n \"description\": {\n \"description\": \"Description of what your company is specializing at\",\n \"default\": \"We are providing an LLM observability and evaluation platform\"\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"Confidence that the message is competitor free\"\n },\n \"passed\": {\n \"description\": \"Is the message related to the competitors\"\n }\n}\n },\n \"langevals/competitor_llm_function_call\": {\n name: `Competitor LLM Check`,\n description: `\nThis evaluator implements LLM-as-a-judge with a function call approach to check if the message contains a mention of a competitor.\n`,\n category: \"policy\",\n docsUrl: \"\",\n isGuardrail: true,\n requiredFields: [],\n optionalFields: [\"output\", \"input\"],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"Max tokens allowed for evaluation\",\n \"default\": 128000\n },\n \"name\": {\n \"description\": \"The name of your company\",\n \"default\": \"LangWatch\"\n },\n \"description\": {\n \"description\": \"Description of what your company is specializing at\",\n \"default\": \"We are providing an LLM observability and evaluation platform\"\n },\n \"competitors\": {\n \"description\": \"The competitors that must not be mentioned.\",\n \"default\": [\n \"OpenAI\",\n \"Google\",\n \"Microsoft\"\n ]\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"Number of unique competitors mentioned\"\n },\n \"passed\": {\n \"description\": \"Is the message related to the competitors\"\n }\n}\n },\n \"langevals/exact_match\": {\n name: `Exact Match Evaluator`,\n description: `\nA simple evaluator that checks if the output matches the expected_output exactly.\n`,\n category: \"quality\",\n docsUrl: \"\",\n isGuardrail: false,\n requiredFields: [\"output\", \"expected_output\"],\n optionalFields: [],\n settings: {\n \"case_sensitive\": {\n \"description\": \"True if the comparison should be case-sensitive, False otherwise\",\n \"default\": false\n },\n \"trim_whitespace\": {\n \"description\": \"True if the comparison should trim whitespace, False otherwise\",\n \"default\": true\n },\n \"remove_punctuation\": {\n \"description\": \"True if the comparison should remove punctuation, False otherwise\",\n \"default\": true\n }\n},\n envVars: [],\n result: {\n \"passed\": {\n \"description\": \"True if the output matched the expected_output exactly, False otherwise\"\n }\n}\n },\n \"langevals/llm_answer_match\": {\n name: `LLM Answer Match`,\n description: `\nUses an LLM to check if the generated output answers a question correctly the same way as the expected output, even if their style is different.\n`,\n category: \"quality\",\n docsUrl: \"\",\n isGuardrail: false,\n requiredFields: [\"output\", \"expected_output\"],\n optionalFields: [\"input\"],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"Max tokens allowed for evaluation\",\n \"default\": 128000\n },\n \"prompt\": {\n \"description\": \"Prompt for the comparison\",\n \"default\": \"Verify that the predicted answer matches the gold answer for the question. Style does not matter, for example the gold answer may be more direct while the predicted answer more verbose and still be correct.\"\n }\n},\n envVars: [],\n result: {\n \"passed\": {\n \"description\": \"Whether the predicted answer matches the gold answer\"\n }\n}\n },\n \"langevals/llm_boolean\": {\n name: `LLM-as-a-Judge Boolean Evaluator`,\n description: `\nUse an LLM as a judge with a custom prompt to do a true/false boolean evaluation of the message.\n`,\n category: \"custom\",\n docsUrl: \"\",\n isGuardrail: true,\n requiredFields: [],\n optionalFields: [\"input\", \"output\", \"contexts\"],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"Max tokens allowed for evaluation\",\n \"default\": 128000\n },\n \"prompt\": {\n \"description\": \"The system prompt to use for the LLM to run the evaluation\",\n \"default\": \"You are an LLM evaluator. We need the guarantee that the output answers what is being asked on the input, please evaluate as False if it doesn't\"\n }\n},\n envVars: [],\n result: {\n \"passed\": {\n \"description\": \"The veredict given by the LLM\"\n }\n}\n },\n \"langevals/llm_category\": {\n name: `LLM-as-a-Judge Category Evaluator`,\n description: `\nUse an LLM as a judge with a custom prompt to classify the message into custom defined categories.\n`,\n category: \"custom\",\n docsUrl: \"\",\n isGuardrail: false,\n requiredFields: [],\n optionalFields: [\"input\", \"output\", \"contexts\"],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"Max tokens allowed for evaluation\",\n \"default\": 128000\n },\n \"prompt\": {\n \"description\": \"The system prompt to use for the LLM to run the evaluation\",\n \"default\": \"You are an LLM category evaluator. Please categorize the message in one of the following categories\"\n },\n \"categories\": {\n \"description\": \"The categories to use for the evaluation\",\n \"default\": [\n {\n \"name\": \"smalltalk\",\n \"description\": \"Smalltalk with the user\"\n },\n {\n \"name\": \"company\",\n \"description\": \"Questions about the company, what we do, etc\"\n }\n ]\n }\n},\n envVars: [],\n result: {\n \"label\": {\n \"description\": \"The detected category of the message\"\n }\n}\n },\n \"langevals/llm_score\": {\n name: `LLM-as-a-Judge Score Evaluator`,\n description: `\nUse an LLM as a judge with custom prompt to do a numeric score evaluation of the message.\n`,\n category: \"custom\",\n docsUrl: \"\",\n isGuardrail: false,\n requiredFields: [],\n optionalFields: [\"input\", \"output\", \"contexts\"],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"Max tokens allowed for evaluation\",\n \"default\": 128000\n },\n \"prompt\": {\n \"description\": \"The system prompt to use for the LLM to run the evaluation\",\n \"default\": \"You are an LLM evaluator. Please score from 0.0 to 1.0 how likely the user is to be satisfied with this answer, from 0.0 being not satisfied at all to 1.0 being completely satisfied\"\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"The score given by the LLM, according to the prompt\"\n }\n}\n },\n \"langevals/off_topic\": {\n name: `Off Topic Evaluator`,\n description: `\nThis evaluator checks if the user message is concerning one of the allowed topics of the chatbot\n`,\n category: \"policy\",\n docsUrl: \"\",\n isGuardrail: true,\n requiredFields: [\"input\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"Max tokens allowed for evaluation\",\n \"default\": 128000\n },\n \"allowed_topics\": {\n \"description\": \"The list of topics and their short descriptions that the chatbot is allowed to talk about\",\n \"default\": [\n {\n \"topic\": \"simple_chat\",\n \"description\": \"Smalltalk with the user\"\n },\n {\n \"topic\": \"company\",\n \"description\": \"Questions about the company, what we do, etc\"\n }\n ]\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"Confidence level of the intent prediction\"\n },\n \"passed\": {\n \"description\": \"Is the message concerning allowed topic\"\n },\n \"label\": {\n \"description\": \"The detected intent or 'other' if the intent is not in the allowed topics\"\n }\n}\n },\n \"langevals/query_resolution\": {\n name: `Query Resolution`,\n description: `\nThis evaluator checks if all the user queries in the conversation were resolved. Useful to detect when the bot doesn't know how to answer or can't help the user.\n`,\n category: \"quality\",\n docsUrl: \"\",\n isGuardrail: false,\n requiredFields: [\"conversation\"],\n optionalFields: [],\n settings: {\n \"model\": {\n \"description\": \"The model to use for evaluation\",\n \"default\": \"openai/gpt-5\"\n },\n \"max_tokens\": {\n \"description\": \"Max tokens allowed for evaluation\",\n \"default\": 128000\n }\n},\n envVars: [],\n result: {}\n },\n \"langevals/sentiment\": {\n name: `Sentiment Evaluator`,\n description: `\nAnalyzes the sentiment of the input text by comparing its embedding similarity\nto positive and negative reference phrases. Returns a score from -1.0 (very negative)\nto 1.0 (very positive) and a corresponding label.\n`,\n category: \"quality\",\n docsUrl: \"\",\n isGuardrail: false,\n requiredFields: [\"input\"],\n optionalFields: [],\n settings: {\n \"embeddings_model\": {\n \"description\": \"The embeddings model to use for sentiment analysis\",\n \"default\": \"openai/text-embedding-3-small\"\n },\n \"positive_reference\": {\n \"description\": \"Reference phrase representing the positive end of the sentiment scale\",\n \"default\": \"Comment of a very happy and satisfied user\"\n },\n \"negative_reference\": {\n \"description\": \"Reference phrase representing the negative end of the sentiment scale\",\n \"default\": \"Comment of a user who is extremely dissatisfied\"\n },\n \"normalization_factor\": {\n \"description\": \"Controls sentiment sensitivity. Decrease to make scores more extreme (fewer neutrals), increase to make scores more moderate (more neutrals)\",\n \"default\": 0.1\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"Sentiment score from -1.0 (very negative) to 1.0 (very positive)\"\n },\n \"label\": {\n \"description\": \"Sentiment label: 'positive' or 'negative'\"\n }\n}\n },\n \"langevals/similarity\": {\n name: `Semantic Similarity Evaluator`,\n description: `\nAllows you to check for semantic similarity or dissimilarity between input and output and a\ntarget value, so you can avoid sentences that you don't want to be present without having to\nmatch on the exact text.\n`,\n category: \"custom\",\n docsUrl: \"\",\n isGuardrail: true,\n requiredFields: [],\n optionalFields: [\"input\", \"output\"],\n settings: {\n \"field\": {\n \"description\": undefined,\n \"default\": \"output\"\n },\n \"rule\": {\n \"description\": undefined,\n \"default\": \"is_not_similar_to\"\n },\n \"value\": {\n \"description\": undefined,\n \"default\": \"example\"\n },\n \"threshold\": {\n \"description\": undefined,\n \"default\": 0.3\n },\n \"embeddings_model\": {\n \"description\": undefined,\n \"default\": \"openai/text-embedding-3-small\"\n }\n},\n envVars: [],\n result: {\n \"score\": {\n \"description\": \"How similar the input and output semantically, from 0.0 to 1.0, with 1.0 meaning the sentences are identical\"\n },\n \"passed\": {\n \"description\": \"Passes if the cosine similarity crosses the threshold for the defined rule\"\n }\n}\n },\n \"langevals/valid_format\": {\n name: `Valid Format Evaluator`,\n description: `\nAllows you to check if the output is a valid json, markdown, python, sql, etc.\nFor JSON, can optionally validate against a provided schema.\n`,\n category: \"quality\",\n docsUrl: \"\",\n isGuardrail: true,\n requiredFields: [],\n optionalFields: [\"output\"],\n settings: {\n \"format\": {\n \"description\": undefined,\n \"default\": \"json\"\n },\n \"json_schema\": {\n \"description\": \"JSON schema to validate against when format is 'json'\",\n \"default\": undefined\n }\n},\n envVars: [],\n result: {\n \"passed\": {\n \"description\": \"True if the output is formatted correctly, False otherwise\"\n }\n}\n },\n};\n","import { AVAILABLE_EVALUATORS } from \"../../../langevals/ts-integration/evaluators.generated.js\";\nimport type { EvaluatorDefinition, EvaluatorTypes } from \"../../../langevals/ts-integration/evaluators.generated.js\";\n\n/**\n * Formats evaluator schema information for the discover_schema tool.\n *\n * Two levels of detail:\n * - Overview (no evaluatorType): compact list of all evaluator types\n * - Detail (with evaluatorType): full schema for one evaluator type\n */\nexport function formatEvaluatorSchema(evaluatorType?: string): string {\n if (evaluatorType) {\n return formatEvaluatorDetail(evaluatorType);\n }\n return formatEvaluatorOverview();\n}\n\n/**\n * Returns a compact overview of all available evaluator types.\n * Shows type, name, category, and a one-line description.\n */\nfunction formatEvaluatorOverview(): string {\n const lines: string[] = [];\n lines.push(\"# Available Evaluator Types\\n\");\n\n const byCategory = new Map<string, { type: string; name: string; description: string }[]>();\n\n for (const [type, def] of Object.entries(AVAILABLE_EVALUATORS)) {\n const evalDef = def as EvaluatorDefinition<EvaluatorTypes>;\n const oneLine = extractFirstLine(evalDef.description);\n const entry = { type, name: evalDef.name, description: oneLine };\n\n const list = byCategory.get(evalDef.category) ?? [];\n list.push(entry);\n byCategory.set(evalDef.category, list);\n }\n\n for (const [category, entries] of byCategory) {\n lines.push(`## ${category}\\n`);\n for (const entry of entries) {\n lines.push(`- **${entry.type}** (${entry.name}): ${entry.description}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\n \"> Use `discover_schema({ category: 'evaluators', evaluatorType: '<type>' })` for full details on a specific evaluator type.\",\n );\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Returns the full schema for a specific evaluator type.\n * Includes settings with descriptions and defaults, required/optional fields, env vars, and result fields.\n */\nfunction formatEvaluatorDetail(evaluatorType: string): string {\n const def = AVAILABLE_EVALUATORS[evaluatorType as EvaluatorTypes] as\n | EvaluatorDefinition<EvaluatorTypes>\n | undefined;\n\n if (!def) {\n return `Unknown evaluator type: \"${evaluatorType}\". Use \\`discover_schema({ category: 'evaluators' })\\` to see all available types.`;\n }\n\n const lines: string[] = [];\n lines.push(`# ${def.name} (\\`${evaluatorType}\\`)\\n`);\n lines.push(`**Category**: ${def.category}`);\n lines.push(`**Is Guardrail**: ${def.isGuardrail ? \"Yes\" : \"No\"}`);\n if (def.docsUrl) {\n lines.push(`**Docs**: ${def.docsUrl}`);\n }\n lines.push(\"\");\n lines.push(`## Description\\n`);\n lines.push(def.description.trim());\n\n // Required and optional fields\n lines.push(\"\\n## Fields\\n\");\n if (def.requiredFields.length > 0) {\n lines.push(`**Required**: ${def.requiredFields.join(\", \")}`);\n } else {\n lines.push(\"**Required**: none\");\n }\n if (def.optionalFields.length > 0) {\n lines.push(`**Optional**: ${def.optionalFields.join(\", \")}`);\n }\n\n // Settings\n const settingsEntries = Object.entries(def.settings);\n if (settingsEntries.length > 0) {\n lines.push(\"\\n## Settings\\n\");\n for (const [key, setting] of settingsEntries) {\n const s = setting as { description?: string; default: unknown };\n const defaultStr = JSON.stringify(s.default);\n const desc = s.description ? ` - ${s.description}` : \"\";\n lines.push(`- **${key}**${desc}`);\n lines.push(` Default: \\`${defaultStr}\\``);\n }\n }\n\n // Env vars\n if (def.envVars.length > 0) {\n lines.push(\"\\n## Required Environment Variables\\n\");\n for (const envVar of def.envVars) {\n lines.push(`- \\`${envVar}\\``);\n }\n }\n\n // Result fields\n const resultEntries = Object.entries(def.result);\n if (resultEntries.length > 0) {\n lines.push(\"\\n## Result Fields\\n\");\n for (const [key, value] of resultEntries) {\n const v = value as { description: string };\n lines.push(`- **${key}**: ${v.description}`);\n }\n }\n\n lines.push(\"\\n## Usage Example\\n\");\n lines.push(\"```json\");\n lines.push(JSON.stringify({\n evaluatorType: evaluatorType,\n settings: Object.fromEntries(\n settingsEntries.map(([key, setting]) => [key, (setting as { default: unknown }).default]),\n ),\n }, null, 2));\n lines.push(\"```\");\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Extracts the first meaningful line from a multi-line description.\n */\nfunction extractFirstLine(description: string): string {\n const trimmed = description.trim();\n const firstLine = trimmed.split(\"\\n\")[0]?.trim() ?? trimmed;\n // Limit to a reasonable length\n if (firstLine.length > 120) {\n return firstLine.slice(0, 117) + \"...\";\n }\n return firstLine;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/discover-scenario-schema.ts"],"sourcesContent":["/**\n * Returns a human-readable description of the scenario schema,\n * including field descriptions, authoring guidance, and examples.\n */\nexport function formatScenarioSchema(): string {\n const lines: string[] = [];\n\n lines.push(\"# Scenario Schema\\n\");\n\n lines.push(\"## Fields\\n\");\n lines.push(\n '- **name** (required): A short, descriptive name (e.g., \"billing dispute resolution\", \"password reset with 2FA unavailable\")',\n );\n lines.push(\n \"- **situation** (required): The context that guides the user simulator — who the user is, what they want, and any constraints (see Writing a Good Situation below)\",\n );\n lines.push(\n \"- **criteria** (array of strings): Pass/fail conditions a judge evaluates the agent against (see Writing Good Criteria below)\",\n );\n lines.push(\n '- **labels** (array of strings): Tags for organizing scenarios (e.g., \"auth\", \"happy-path\", \"edge-case\")',\n );\n\n lines.push(\"\\n## Writing a Good Situation\\n\");\n lines.push(\n \"The situation drives the user simulator. Include these elements:\",\n );\n lines.push(\"- **Persona**: Who is the user? (e.g., a stressed small business owner, a confused teenager)\");\n lines.push(\"- **Emotional state**: How are they feeling? (e.g., frustrated, anxious, impatient)\");\n lines.push(\"- **Background/Context**: What happened before this conversation?\");\n lines.push(\"- **Intent**: What do they want to accomplish?\");\n lines.push(\"- **Constraints**: What limitations do they have? (e.g., no phone for 2FA, unfamiliar with technical terms)\");\n lines.push(\"\\nExample:\");\n lines.push(\"```\");\n lines.push(\"User is a small business owner stressed about tax deadline.\");\n lines.push(\"They need help categorizing expenses but aren't familiar with\");\n lines.push(\"accounting terms. They appreciate patient explanations and examples.\");\n lines.push(\"They have a spreadsheet of transactions but aren't sure which\");\n lines.push(\"categories apply to their consulting business.\");\n lines.push(\"```\");\n\n lines.push(\"\\n## Writing Good Criteria\\n\");\n lines.push(\"Criteria are what the judge uses to pass or fail the agent. Each criterion should be:\");\n lines.push(\"- **Specific and testable** — not vague like \\\"responds helpfully\\\"\");\n lines.push(\"- **Behavioral** — describes what the agent should *do*, not how it works internally\");\n lines.push(\"- **Independent** — each criterion checks one thing\");\n lines.push(\"\\nGood criteria patterns:\");\n lines.push(\"- **Information gathering**: \\\"Agent asks for the user's account number before proceeding\\\"\");\n lines.push(\"- **Safety/guardrails**: \\\"Agent does not reveal internal system details or error stack traces\\\"\");\n lines.push(\"- **Clarification**: \\\"Agent asks clarifying questions before taking irreversible action\\\"\");\n lines.push(\"- **Tone**: \\\"Agent maintains a professional and empathetic tone throughout\\\"\");\n lines.push(\"- **Completeness**: \\\"Agent confirms the user understands the solution before ending\\\"\");\n lines.push(\"- **Domain-specific**: \\\"Agent recommends releasing a wild frog rather than keeping it as a pet\\\"\");\n lines.push(\"\\nAvoid vague criteria like:\");\n lines.push('- \"Responds correctly\" — correct how?');\n lines.push('- \"Is helpful\" — helpful in what way?');\n lines.push('- \"Works well\" — not testable');\n\n lines.push(\"\\n## Target Types\\n\");\n lines.push(\"Scenarios can target different execution backends:\");\n lines.push(\"- **prompt**: Test a prompt template with variable substitution\");\n lines.push(\"- **http**: Test an HTTP endpoint (e.g., a deployed agent API)\");\n lines.push(\"- **code**: Test a code function directly\");\n\n lines.push(\"\\n## Tips\\n\");\n lines.push(\"- Start simple, then layer complexity (add constraints, edge cases)\");\n lines.push(\"- Test edge cases: user changes their mind, gives ambiguous input, makes mistakes\");\n lines.push(\"- Use `fetch_scenario_docs` for the full authoring guide and advanced patterns\");\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";AAIO,SAAS,uBAA+B;AAC7C,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,qBAAqB;AAEhC,QAAM,KAAK,aAAa;AACxB,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,KAAK,iCAAiC;AAC5C,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,8FAA8F;AACzG,QAAM,KAAK,qFAAqF;AAChG,QAAM,KAAK,mEAAmE;AAC9E,QAAM,KAAK,gDAAgD;AAC3D,QAAM,KAAK,6GAA6G;AACxH,QAAM,KAAK,YAAY;AACvB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,6DAA6D;AACxE,QAAM,KAAK,+DAA+D;AAC1E,QAAM,KAAK,sEAAsE;AACjF,QAAM,KAAK,+DAA+D;AAC1E,QAAM,KAAK,gDAAgD;AAC3D,QAAM,KAAK,KAAK;AAEhB,QAAM,KAAK,8BAA8B;AACzC,QAAM,KAAK,uFAAuF;AAClG,QAAM,KAAK,wEAAqE;AAChF,QAAM,KAAK,2FAAsF;AACjG,QAAM,KAAK,0DAAqD;AAChE,QAAM,KAAK,2BAA2B;AACtC,QAAM,KAAK,2FAA6F;AACxG,QAAM,KAAK,gGAAkG;AAC7G,QAAM,KAAK,0FAA4F;AACvG,QAAM,KAAK,6EAA+E;AAC1F,QAAM,KAAK,sFAAwF;AACnG,QAAM,KAAK,iGAAmG;AAC9G,QAAM,KAAK,8BAA8B;AACzC,QAAM,KAAK,4CAAuC;AAClD,QAAM,KAAK,4CAAuC;AAClD,QAAM,KAAK,oCAA+B;AAE1C,QAAM,KAAK,qBAAqB;AAChC,QAAM,KAAK,oDAAoD;AAC/D,QAAM,KAAK,iEAAiE;AAC5E,QAAM,KAAK,gEAAgE;AAC3E,QAAM,KAAK,2CAA2C;AAEtD,QAAM,KAAK,aAAa;AACxB,QAAM,KAAK,qEAAqE;AAChF,QAAM,KAAK,mFAAmF;AAC9F,QAAM,KAAK,gFAAgF;AAE3F,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schemas/filter-fields.ts","../src/schemas/analytics-metrics.ts","../src/schemas/analytics-groups.ts","../src/tools/discover-schema.ts"],"sourcesContent":["export interface FilterFieldInfo {\n field: string;\n description: string;\n example?: string;\n}\n\nexport const filterFields: FilterFieldInfo[] = [\n {\n field: \"topics.topics\",\n description: \"Main topic classification of the trace\",\n example: \"billing\",\n },\n {\n field: \"topics.subtopics\",\n description: \"Subtopic classification\",\n example: \"refund-request\",\n },\n {\n field: \"metadata.user_id\",\n description: \"User ID from trace metadata\",\n example: \"user-123\",\n },\n {\n field: \"metadata.thread_id\",\n description: \"Conversation thread ID\",\n example: \"thread-456\",\n },\n {\n field: \"metadata.customer_id\",\n description: \"Customer/organization ID\",\n example: \"customer-789\",\n },\n {\n field: \"metadata.labels\",\n description: \"Custom labels attached to traces\",\n example: \"production\",\n },\n {\n field: \"metadata.key\",\n description: \"Custom metadata key\",\n example: \"environment\",\n },\n {\n field: \"metadata.value\",\n description: \"Custom metadata value (used with metadata.key)\",\n example: \"staging\",\n },\n {\n field: \"metadata.prompt_ids\",\n description: \"Prompt IDs used in the trace\",\n },\n {\n field: \"traces.error\",\n description: \"Whether the trace has errors\",\n example: \"true\",\n },\n {\n field: \"spans.type\",\n description: \"Span type (llm, tool, agent, chain, rag)\",\n example: \"llm\",\n },\n {\n field: \"spans.model\",\n description: \"LLM model name used in spans\",\n example: \"gpt-4o\",\n },\n {\n field: \"evaluations.evaluator_id\",\n description: \"Evaluator that ran on the trace\",\n },\n {\n field: \"evaluations.evaluator_id.guardrails_only\",\n description: \"Evaluator ID filtered to guardrails only\",\n },\n {\n field: \"evaluations.passed\",\n description: \"Whether evaluations passed\",\n example: \"true\",\n },\n {\n field: \"evaluations.score\",\n description: \"Evaluation score (numeric)\",\n },\n {\n field: \"evaluations.state\",\n description: \"Evaluation state (processed, error, skipped)\",\n },\n {\n field: \"evaluations.label\",\n description: \"Evaluation label result\",\n },\n {\n field: \"events.event_type\",\n description: \"Type of event (thumbs_up_down, custom)\",\n example: \"thumbs_up_down\",\n },\n {\n field: \"events.metrics.key\",\n description: \"Event metric key\",\n },\n {\n field: \"events.metrics.value\",\n description: \"Event metric value (numeric)\",\n },\n {\n field: \"events.event_details.key\",\n description: \"Event detail key\",\n },\n {\n field: \"annotations.hasAnnotation\",\n description: \"Whether trace has human annotations\",\n example: \"true\",\n },\n {\n field: \"sentiment.input_sentiment\",\n description: \"Detected sentiment of input\",\n example: \"positive\",\n },\n];\n","export interface MetricInfo {\n category: string;\n name: string;\n label: string;\n allowedAggregations: string[];\n description: string;\n}\n\nexport const analyticsMetrics: MetricInfo[] = [\n // metadata\n {\n category: \"metadata\",\n name: \"trace_id\",\n label: \"Traces\",\n allowedAggregations: [\"cardinality\"],\n description: \"Count of unique traces\",\n },\n {\n category: \"metadata\",\n name: \"user_id\",\n label: \"Users\",\n allowedAggregations: [\"cardinality\"],\n description: \"Count of unique users\",\n },\n {\n category: \"metadata\",\n name: \"thread_id\",\n label: \"Threads\",\n allowedAggregations: [\"cardinality\"],\n description: \"Count of unique conversation threads\",\n },\n {\n category: \"metadata\",\n name: \"span_type\",\n label: \"Span Type\",\n allowedAggregations: [\"cardinality\"],\n description: \"Count of spans, optionally filtered by span type\",\n },\n // sentiment\n {\n category: \"sentiment\",\n name: \"input_sentiment\",\n label: \"Input Sentiment Score\",\n allowedAggregations: [\"avg\", \"sum\", \"min\", \"max\", \"median\", \"p99\", \"p95\", \"p90\"],\n description: \"Sentiment analysis score of inputs\",\n },\n {\n category: \"sentiment\",\n name: \"thumbs_up_down\",\n label: \"Thumbs Up/Down Score\",\n allowedAggregations: [\n \"terms\",\n \"cardinality\",\n \"avg\",\n \"sum\",\n \"min\",\n \"max\",\n \"median\",\n \"p99\",\n \"p95\",\n \"p90\",\n ],\n description: \"User feedback score (-1 to 1)\",\n },\n // performance\n {\n category: \"performance\",\n name: \"completion_time\",\n label: \"Completion Time\",\n allowedAggregations: [\"avg\", \"sum\", \"min\", \"max\", \"median\", \"p99\", \"p95\", \"p90\"],\n description: \"Time to complete the trace (ms)\",\n },\n {\n category: \"performance\",\n name: \"first_token\",\n label: \"Time to First Token\",\n allowedAggregations: [\"avg\", \"sum\", \"min\", \"max\", \"median\", \"p99\", \"p95\", \"p90\"],\n description: \"Time to first token (ms)\",\n },\n {\n category: \"performance\",\n name: \"total_cost\",\n label: \"Total Cost\",\n allowedAggregations: [\"avg\", \"sum\", \"min\", \"max\", \"median\", \"p99\", \"p95\", \"p90\"],\n description: \"Cost per trace in USD\",\n },\n {\n category: \"performance\",\n name: \"prompt_tokens\",\n label: \"Prompt Tokens\",\n allowedAggregations: [\"avg\", \"sum\", \"min\", \"max\", \"median\", \"p99\", \"p95\", \"p90\"],\n description: \"Input token count\",\n },\n {\n category: \"performance\",\n name: \"completion_tokens\",\n label: \"Completion Tokens\",\n allowedAggregations: [\"avg\", \"sum\", \"min\", \"max\", \"median\", \"p99\", \"p95\", \"p90\"],\n description: \"Output token count\",\n },\n {\n category: \"performance\",\n name: \"total_tokens\",\n label: \"Total Tokens\",\n allowedAggregations: [\"avg\", \"sum\", \"min\", \"max\", \"median\", \"p99\", \"p95\", \"p90\"],\n description: \"Total token count (input + output)\",\n },\n {\n category: \"performance\",\n name: \"tokens_per_second\",\n label: \"Tokens per Second\",\n allowedAggregations: [\"avg\", \"sum\", \"min\", \"max\", \"median\", \"p99\", \"p95\", \"p90\"],\n description: \"Token generation speed\",\n },\n // events\n {\n category: \"events\",\n name: \"event_type\",\n label: \"Event Type\",\n allowedAggregations: [\"cardinality\"],\n description: \"Count of events, optionally filtered by event type\",\n },\n {\n category: \"events\",\n name: \"event_score\",\n label: \"Event Score\",\n allowedAggregations: [\n \"terms\",\n \"avg\",\n \"sum\",\n \"min\",\n \"max\",\n \"median\",\n \"p99\",\n \"p95\",\n \"p90\",\n ],\n description: \"Numeric score from events (requires event_type key and metrics key)\",\n },\n {\n category: \"events\",\n name: \"event_details\",\n label: \"Event Details\",\n allowedAggregations: [\"cardinality\"],\n description:\n \"Event detail key/value distribution (requires event_type key and details key)\",\n },\n // evaluations\n {\n category: \"evaluations\",\n name: \"evaluation_score\",\n label: \"Evaluation Score\",\n allowedAggregations: [\"avg\", \"sum\", \"min\", \"max\", \"median\", \"p99\", \"p95\", \"p90\"],\n description: \"Numeric evaluation score (requires evaluator_id key)\",\n },\n {\n category: \"evaluations\",\n name: \"evaluation_pass_rate\",\n label: \"Evaluation Pass Rate\",\n allowedAggregations: [\"avg\", \"sum\", \"min\", \"max\", \"median\", \"p99\", \"p95\", \"p90\"],\n description:\n \"Percentage of traces passing evaluation (requires evaluator_id key)\",\n },\n {\n category: \"evaluations\",\n name: \"evaluation_runs\",\n label: \"Evaluation Runs\",\n allowedAggregations: [\"cardinality\"],\n description: \"Count of evaluation executions\",\n },\n // threads\n {\n category: \"threads\",\n name: \"average_duration_per_thread\",\n label: \"Thread Duration\",\n allowedAggregations: [\"avg\"],\n description: \"Average duration of conversation threads (ms)\",\n },\n];\n","export interface GroupByInfo {\n name: string;\n label: string;\n description: string;\n}\n\nexport const analyticsGroups: GroupByInfo[] = [\n {\n name: \"topics.topics\",\n label: \"Topic\",\n description: \"Group by topic classification\",\n },\n {\n name: \"metadata.user_id\",\n label: \"User\",\n description: \"Group by user ID\",\n },\n {\n name: \"metadata.thread_id\",\n label: \"Thread\",\n description: \"Group by conversation thread\",\n },\n {\n name: \"metadata.customer_id\",\n label: \"Customer ID\",\n description: \"Group by customer/organization\",\n },\n {\n name: \"metadata.labels\",\n label: \"Label\",\n description: \"Group by custom labels\",\n },\n {\n name: \"metadata.model\",\n label: \"Model\",\n description: \"Group by LLM model name\",\n },\n {\n name: \"metadata.span_type\",\n label: \"Span Type\",\n description: \"Group by span type (llm, tool, agent, etc.)\",\n },\n {\n name: \"sentiment.input_sentiment\",\n label: \"Input Sentiment\",\n description: \"Group by detected input sentiment (positive, negative, neutral)\",\n },\n {\n name: \"sentiment.thumbs_up_down\",\n label: \"Thumbs Up/Down\",\n description: \"Group by user feedback (positive, negative, neutral)\",\n },\n {\n name: \"events.event_type\",\n label: \"Event Type\",\n description: \"Group by event type\",\n },\n {\n name: \"evaluations.evaluation_passed\",\n label: \"Evaluation Passed\",\n description: \"Group by evaluation pass/fail status\",\n },\n {\n name: \"evaluations.evaluation_label\",\n label: \"Evaluation Label\",\n description: \"Group by evaluation label result\",\n },\n {\n name: \"evaluations.evaluation_processing_state\",\n label: \"Evaluation Processing State\",\n description: \"Group by evaluation processing state\",\n },\n {\n name: \"error.has_error\",\n label: \"Contains Error\",\n description: \"Group by whether the trace contains an error\",\n },\n];\n","import { filterFields } from \"../schemas/filter-fields.js\";\nimport { analyticsMetrics } from \"../schemas/analytics-metrics.js\";\nimport { analyticsGroups } from \"../schemas/analytics-groups.js\";\n\nexport type Category =\n | \"filters\"\n | \"metrics\"\n | \"aggregations\"\n | \"groups\"\n | \"all\";\n\n/**\n * Formats the LangWatch analytics schema into human-readable markdown.\n *\n * Returns documentation for the requested category of schema elements\n * (filter fields, metrics, aggregation types, or group-by options).\n */\nexport function formatSchema(category: Category): string {\n const sections: string[] = [];\n\n if (category === \"filters\" || category === \"all\") {\n sections.push(formatFilters());\n }\n if (category === \"metrics\" || category === \"all\") {\n sections.push(formatMetrics());\n }\n if (category === \"aggregations\" || category === \"all\") {\n sections.push(formatAggregations());\n }\n if (category === \"groups\" || category === \"all\") {\n sections.push(formatGroups());\n }\n\n return sections.join(\"\\n\\n\");\n}\n\nfunction formatFilters(): string {\n const lines = [\"## Available Filter Fields\", \"\"];\n lines.push(\n \"Use these in the `filters` parameter of `search_traces` and `get_analytics`.\"\n );\n lines.push('Format: `{ \"field_name\": [\"value1\", \"value2\"] }`');\n lines.push(\"\");\n for (const f of filterFields) {\n lines.push(\n `- **${f.field}**: ${f.description}${f.example ? ` (e.g., \\`${f.example}\\`)` : \"\"}`\n );\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatMetrics(): string {\n const lines = [\"## Available Metrics\", \"\"];\n lines.push(\n \"Use these in `get_analytics` as `metric` parameter in `category.name` format.\"\n );\n lines.push(\"\");\n\n const byCategory = new Map<string, typeof analyticsMetrics>();\n for (const m of analyticsMetrics) {\n const list = byCategory.get(m.category) || [];\n list.push(m);\n byCategory.set(m.category, list);\n }\n\n for (const [cat, metrics] of byCategory) {\n lines.push(`### ${cat}`);\n for (const m of metrics) {\n lines.push(`- **${cat}.${m.name}** (${m.label}): ${m.description}`);\n lines.push(` Aggregations: ${m.allowedAggregations.join(\", \")}`);\n }\n lines.push(\"\");\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatAggregations(): string {\n return [\n \"## Available Aggregation Types\",\n \"\",\n \"- **cardinality**: Count unique values\",\n \"- **terms**: Distribution/breakdown of values\",\n \"- **avg**: Average\",\n \"- **sum**: Sum total\",\n \"- **min**: Minimum\",\n \"- **max**: Maximum\",\n \"- **median**: 50th percentile\",\n \"- **p90**: 90th percentile\",\n \"- **p95**: 95th percentile\",\n \"- **p99**: 99th percentile\",\n \"\",\n \"Note: Not all aggregations are available for all metrics. Check the metric's allowed aggregations.\",\n ].join(\"\\n\");\n}\n\nfunction formatGroups(): string {\n const lines = [\"## Available Group-By Options\", \"\"];\n lines.push(\n \"Use these in the `groupBy` parameter of `get_analytics`.\"\n );\n lines.push(\"\");\n for (const g of analyticsGroups) {\n lines.push(`- **${g.name}** (${g.label}): ${g.description}`);\n }\n return lines.join(\"\\n\");\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/get-agent.ts"],"sourcesContent":["import { getAgent as apiGetAgent } from \"../langwatch-api-agents.js\";\n\nexport async function handleGetAgent(params: { id: string }): Promise<string> {\n const agent = await apiGetAgent(params.id);\n\n const lines: string[] = [];\n lines.push(`# ${agent.name}\\n`);\n lines.push(`**ID**: ${agent.id}`);\n lines.push(`**Type**: ${agent.type}`);\n lines.push(`**Created**: ${agent.createdAt}`);\n lines.push(`**Updated**: ${agent.updatedAt}`);\n\n if (agent.config && Object.keys(agent.config).length > 0) {\n lines.push(\"\\n## Config\\n\");\n lines.push(\"```json\");\n lines.push(JSON.stringify(agent.config, null, 2));\n lines.push(\"```\");\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAEA,eAAsB,eAAe,QAAyC;AAC5E,QAAM,QAAQ,MAAM,SAAY,OAAO,EAAE;AAEzC,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,KAAK,MAAM,IAAI;AAAA,CAAI;AAC9B,QAAM,KAAK,WAAW,MAAM,EAAE,EAAE;AAChC,QAAM,KAAK,aAAa,MAAM,IAAI,EAAE;AACpC,QAAM,KAAK,gBAAgB,MAAM,SAAS,EAAE;AAC5C,QAAM,KAAK,gBAAgB,MAAM,SAAS,EAAE;AAE5C,MAAI,MAAM,UAAU,OAAO,KAAK,MAAM,MAAM,EAAE,SAAS,GAAG;AACxD,UAAM,KAAK,eAAe;AAC1B,UAAM,KAAK,SAAS;AACpB,UAAM,KAAK,KAAK,UAAU,MAAM,QAAQ,MAAM,CAAC,CAAC;AAChD,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/get-analytics.ts"],"sourcesContent":["import type { AnalyticsBucket } from \"../langwatch-api.js\";\nimport { getAnalyticsTimeseries as apiGetAnalytics } from \"../langwatch-api.js\";\nimport { parseRelativeDate } from \"../utils/date-parsing.js\";\n\ntype GroupedData = Record<string, Record<string, number>>;\n\nfunction getGroupedData(\n bucket: AnalyticsBucket,\n groupBy: string,\n): GroupedData | undefined {\n const data = bucket[groupBy];\n if (typeof data === \"object\" && data !== null && !Array.isArray(data)) {\n return data as GroupedData;\n }\n return undefined;\n}\n\n/**\n * Handles the get_analytics MCP tool invocation.\n *\n * Queries analytics timeseries from LangWatch and formats the results\n * as an AI-readable markdown table.\n */\nexport async function handleGetAnalytics(params: {\n metric: string;\n aggregation?: string;\n startDate?: string;\n endDate?: string;\n timeZone?: string;\n groupBy?: string;\n filters?: Record<string, string[]>;\n}): Promise<string> {\n const now = Date.now();\n const startDate = params.startDate\n ? parseRelativeDate(params.startDate)\n : now - 7 * 86400000;\n const endDate = params.endDate ? parseRelativeDate(params.endDate) : now;\n\n // Parse metric format \"category.name\"\n const [category, name] = params.metric.includes(\".\")\n ? params.metric.split(\".\", 2)\n : [\"metadata\", params.metric];\n const metricKey = `${category}.${name}`;\n const aggregation = params.aggregation ?? \"avg\";\n\n const result = await apiGetAnalytics({\n series: [{ metric: metricKey, aggregation }],\n startDate,\n endDate,\n timeZone: params.timeZone ?? \"UTC\",\n groupBy: params.groupBy,\n filters: params.filters,\n });\n\n const lines: string[] = [];\n lines.push(`# Analytics: ${metricKey} (${aggregation})\\n`);\n lines.push(\n `Period: ${new Date(startDate).toISOString().split(\"T\")[0]} to ${new Date(endDate).toISOString().split(\"T\")[0]}`\n );\n if (params.groupBy) lines.push(`Grouped by: ${params.groupBy}`);\n lines.push(\"\");\n\n const currentPeriod = result.currentPeriod ?? [];\n if (currentPeriod.length === 0) {\n lines.push(\"No data available for this period.\");\n } else if (\n params.groupBy &&\n currentPeriod.some((b) => getGroupedData(b, params.groupBy!) !== undefined)\n ) {\n lines.push(\"| Date | Group | Value |\");\n lines.push(\"|------|-------|-------|\");\n for (const bucket of currentPeriod) {\n const groups = getGroupedData(bucket, params.groupBy);\n if (!groups) continue;\n for (const [groupKey, metrics] of Object.entries(groups)) {\n const value =\n Object.values(metrics).find((v) => typeof v === \"number\") ?? \"N/A\";\n lines.push(`| ${bucket.date} | ${groupKey} | ${value} |`);\n }\n }\n } else {\n lines.push(\"| Date | Value |\");\n lines.push(\"|------|-------|\");\n for (const bucket of currentPeriod) {\n const value =\n Object.entries(bucket).find(\n ([k]) => k !== \"date\" && typeof bucket[k] === \"number\"\n )?.[1] ?? \"N/A\";\n lines.push(`| ${bucket.date} | ${value} |`);\n }\n }\n\n lines.push(\n \"\\n> Tip: Use `discover_schema` to see all available metrics and aggregation types.\"\n );\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;;AAMA,SAAS,eACP,QACA,SACyB;AACzB,QAAM,OAAO,OAAO,OAAO;AAC3B,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,CAAC,MAAM,QAAQ,IAAI,GAAG;AACrE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAQA,eAAsB,mBAAmB,QAQrB;AAClB,QAAM,MAAM,KAAK,IAAI;AACrB,QAAM,YAAY,OAAO,YACrB,kBAAkB,OAAO,SAAS,IAClC,MAAM,IAAI;AACd,QAAM,UAAU,OAAO,UAAU,kBAAkB,OAAO,OAAO,IAAI;AAGrE,QAAM,CAAC,UAAU,IAAI,IAAI,OAAO,OAAO,SAAS,GAAG,IAC/C,OAAO,OAAO,MAAM,KAAK,CAAC,IAC1B,CAAC,YAAY,OAAO,MAAM;AAC9B,QAAM,YAAY,GAAG,QAAQ,IAAI,IAAI;AACrC,QAAM,cAAc,OAAO,eAAe;AAE1C,QAAM,SAAS,MAAM,uBAAgB;AAAA,IACnC,QAAQ,CAAC,EAAE,QAAQ,WAAW,YAAY,CAAC;AAAA,IAC3C;AAAA,IACA;AAAA,IACA,UAAU,OAAO,YAAY;AAAA,IAC7B,SAAS,OAAO;AAAA,IAChB,SAAS,OAAO;AAAA,EAClB,CAAC;AAED,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,gBAAgB,SAAS,KAAK,WAAW;AAAA,CAAK;AACzD,QAAM;AAAA,IACJ,WAAW,IAAI,KAAK,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,EAChH;AACA,MAAI,OAAO,QAAS,OAAM,KAAK,eAAe,OAAO,OAAO,EAAE;AAC9D,QAAM,KAAK,EAAE;AAEb,QAAM,gBAAgB,OAAO,iBAAiB,CAAC;AAC/C,MAAI,cAAc,WAAW,GAAG;AAC9B,UAAM,KAAK,oCAAoC;AAAA,EACjD,WACE,OAAO,WACP,cAAc,KAAK,CAAC,MAAM,eAAe,GAAG,OAAO,OAAQ,MAAM,MAAS,GAC1E;AACA,UAAM,KAAK,0BAA0B;AACrC,UAAM,KAAK,0BAA0B;AACrC,eAAW,UAAU,eAAe;AAClC,YAAM,SAAS,eAAe,QAAQ,OAAO,OAAO;AACpD,UAAI,CAAC,OAAQ;AACb,iBAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,MAAM,GAAG;AACxD,cAAM,QACJ,OAAO,OAAO,OAAO,EAAE,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,KAAK;AAC/D,cAAM,KAAK,KAAK,OAAO,IAAI,MAAM,QAAQ,MAAM,KAAK,IAAI;AAAA,MAC1D;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM,KAAK,kBAAkB;AAC7B,UAAM,KAAK,kBAAkB;AAC7B,eAAW,UAAU,eAAe;AAClC,YAAM,QACJ,OAAO,QAAQ,MAAM,EAAE;AAAA,QACrB,CAAC,CAAC,CAAC,MAAM,MAAM,UAAU,OAAO,OAAO,CAAC,MAAM;AAAA,MAChD,IAAI,CAAC,KAAK;AACZ,YAAM,KAAK,KAAK,OAAO,IAAI,MAAM,KAAK,IAAI;AAAA,IAC5C;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/get-dashboard.ts"],"sourcesContent":["import { getDashboard as apiGetDashboard } from \"../langwatch-api-dashboards.js\";\n\nexport async function handleGetDashboard(params: { id: string }): Promise<string> {\n const dashboard = await apiGetDashboard(params.id);\n\n const lines: string[] = [];\n lines.push(`# ${dashboard.name}\\n`);\n lines.push(`**ID**: ${dashboard.id}`);\n lines.push(`**Order**: ${dashboard.order}`);\n lines.push(`**Graphs**: ${Array.isArray(dashboard.graphs) ? dashboard.graphs.length : 0}`);\n lines.push(`**Created**: ${dashboard.createdAt}`);\n lines.push(`**Updated**: ${dashboard.updatedAt}`);\n\n if (Array.isArray(dashboard.graphs) && dashboard.graphs.length > 0) {\n lines.push(\"\\n## Graphs\\n\");\n lines.push(\"```json\");\n lines.push(JSON.stringify(dashboard.graphs, null, 2));\n lines.push(\"```\");\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAEA,eAAsB,mBAAmB,QAAyC;AAChF,QAAM,YAAY,MAAM,aAAgB,OAAO,EAAE;AAEjD,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,KAAK,UAAU,IAAI;AAAA,CAAI;AAClC,QAAM,KAAK,WAAW,UAAU,EAAE,EAAE;AACpC,QAAM,KAAK,cAAc,UAAU,KAAK,EAAE;AAC1C,QAAM,KAAK,eAAe,MAAM,QAAQ,UAAU,MAAM,IAAI,UAAU,OAAO,SAAS,CAAC,EAAE;AACzF,QAAM,KAAK,gBAAgB,UAAU,SAAS,EAAE;AAChD,QAAM,KAAK,gBAAgB,UAAU,SAAS,EAAE;AAEhD,MAAI,MAAM,QAAQ,UAAU,MAAM,KAAK,UAAU,OAAO,SAAS,GAAG;AAClE,UAAM,KAAK,eAAe;AAC1B,UAAM,KAAK,SAAS;AACpB,UAAM,KAAK,KAAK,UAAU,UAAU,QAAQ,MAAM,CAAC,CAAC;AACpD,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/get-dataset.ts"],"sourcesContent":["import {\n getDataset as apiGetDataset,\n type DatasetDetailResponse,\n} from \"../langwatch-api-datasets.js\";\nimport { escapeMarkdown } from \"../utils/escape-markdown.js\";\n\n/**\n * Formats a dataset detail response into AI-readable markdown.\n *\n * Exported for unit testing.\n */\nexport function formatDatasetResponse(\n dataset: DatasetDetailResponse,\n): string {\n const lines: string[] = [];\n lines.push(`# Dataset: ${escapeMarkdown(dataset.name)}\\n`);\n lines.push(`**Slug**: ${escapeMarkdown(dataset.slug)}`);\n lines.push(`**ID**: ${escapeMarkdown(dataset.id)}`);\n\n // Column table\n if (\n Array.isArray(dataset.columnTypes) &&\n dataset.columnTypes.length > 0\n ) {\n lines.push(\"\\n## Columns\\n\");\n lines.push(\"| Name | Type |\");\n lines.push(\"|------|------|\");\n for (const col of dataset.columnTypes) {\n lines.push(`| ${escapeMarkdown(col.name)} | ${escapeMarkdown(col.type)} |`);\n }\n }\n\n // Record preview\n if (Array.isArray(dataset.data) && dataset.data.length > 0) {\n lines.push(`\\n## Records (${dataset.data.length} shown)\\n`);\n for (const record of dataset.data) {\n lines.push(`**${escapeMarkdown(record.id)}**: ${escapeMarkdown(JSON.stringify(record.entry))}`);\n }\n } else {\n lines.push(\"\\nNo records in this dataset.\");\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Handles the platform_get_dataset MCP tool invocation.\n *\n * Retrieves a specific dataset by slug or ID and formats it as\n * AI-readable markdown or raw JSON.\n */\nexport async function handleGetDataset(params: {\n slugOrId: string;\n format?: \"digest\" | \"json\";\n}): Promise<string> {\n const dataset = await apiGetDataset(params.slugOrId);\n\n if (params.format === \"json\") {\n return JSON.stringify(dataset, null, 2);\n }\n\n return formatDatasetResponse(dataset);\n}\n"],"mappings":";;;;;;;;;;AAWO,SAAS,sBACd,SACQ;AACR,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,cAAc,eAAe,QAAQ,IAAI,CAAC;AAAA,CAAI;AACzD,QAAM,KAAK,aAAa,eAAe,QAAQ,IAAI,CAAC,EAAE;AACtD,QAAM,KAAK,WAAW,eAAe,QAAQ,EAAE,CAAC,EAAE;AAGlD,MACE,MAAM,QAAQ,QAAQ,WAAW,KACjC,QAAQ,YAAY,SAAS,GAC7B;AACA,UAAM,KAAK,gBAAgB;AAC3B,UAAM,KAAK,iBAAiB;AAC5B,UAAM,KAAK,iBAAiB;AAC5B,eAAW,OAAO,QAAQ,aAAa;AACrC,YAAM,KAAK,KAAK,eAAe,IAAI,IAAI,CAAC,MAAM,eAAe,IAAI,IAAI,CAAC,IAAI;AAAA,IAC5E;AAAA,EACF;AAGA,MAAI,MAAM,QAAQ,QAAQ,IAAI,KAAK,QAAQ,KAAK,SAAS,GAAG;AAC1D,UAAM,KAAK;AAAA,cAAiB,QAAQ,KAAK,MAAM;AAAA,CAAW;AAC1D,eAAW,UAAU,QAAQ,MAAM;AACjC,YAAM,KAAK,KAAK,eAAe,OAAO,EAAE,CAAC,OAAO,eAAe,KAAK,UAAU,OAAO,KAAK,CAAC,CAAC,EAAE;AAAA,IAChG;AAAA,EACF,OAAO;AACL,UAAM,KAAK,+BAA+B;AAAA,EAC5C;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAQA,eAAsB,iBAAiB,QAGnB;AAClB,QAAM,UAAU,MAAM,WAAc,OAAO,QAAQ;AAEnD,MAAI,OAAO,WAAW,QAAQ;AAC5B,WAAO,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,EACxC;AAEA,SAAO,sBAAsB,OAAO;AACtC;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/get-evaluator.ts"],"sourcesContent":["import {\n getEvaluator as apiGetEvaluator,\n getEvaluatorType,\n} from \"../langwatch-api-evaluators.js\";\n\n/**\n * Handles the platform_get_evaluator MCP tool invocation.\n *\n * Retrieves a specific evaluator by ID or slug and formats it as\n * AI-readable markdown.\n */\nexport async function handleGetEvaluator(params: {\n idOrSlug: string;\n}): Promise<string> {\n const evaluator = await apiGetEvaluator(params.idOrSlug);\n\n const evaluatorType = getEvaluatorType(evaluator);\n\n const lines: string[] = [];\n lines.push(`# Evaluator: ${evaluator.name}\\n`);\n lines.push(`**ID**: ${evaluator.id}`);\n if (evaluator.slug) lines.push(`**Slug**: ${evaluator.slug}`);\n lines.push(`**Kind**: ${evaluator.type}`);\n if (evaluatorType) lines.push(`**Evaluator Type**: ${evaluatorType}`);\n\n if (evaluator.config) {\n lines.push(\"\\n## Config\");\n lines.push(\"```json\");\n lines.push(JSON.stringify(evaluator.config, null, 2));\n lines.push(\"```\");\n }\n\n if (Array.isArray(evaluator.fields) && evaluator.fields.length > 0) {\n lines.push(\"\\n## Input Fields\");\n for (const field of evaluator.fields) {\n const opt = field.optional ? \" (optional)\" : \"\";\n lines.push(`- **${field.identifier}** (${field.type})${opt}`);\n }\n }\n\n if (Array.isArray(evaluator.outputFields) && evaluator.outputFields.length > 0) {\n lines.push(\"\\n## Output Fields\");\n for (const field of evaluator.outputFields) {\n lines.push(`- **${field.identifier}** (${field.type})`);\n }\n }\n\n if (evaluator.workflowName) {\n lines.push(`\\n**Workflow**: ${evaluator.workflowName}`);\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;AAWA,eAAsB,mBAAmB,QAErB;AAClB,QAAM,YAAY,MAAM,aAAgB,OAAO,QAAQ;AAEvD,QAAM,gBAAgB,iBAAiB,SAAS;AAEhD,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,gBAAgB,UAAU,IAAI;AAAA,CAAI;AAC7C,QAAM,KAAK,WAAW,UAAU,EAAE,EAAE;AACpC,MAAI,UAAU,KAAM,OAAM,KAAK,aAAa,UAAU,IAAI,EAAE;AAC5D,QAAM,KAAK,aAAa,UAAU,IAAI,EAAE;AACxC,MAAI,cAAe,OAAM,KAAK,uBAAuB,aAAa,EAAE;AAEpE,MAAI,UAAU,QAAQ;AACpB,UAAM,KAAK,aAAa;AACxB,UAAM,KAAK,SAAS;AACpB,UAAM,KAAK,KAAK,UAAU,UAAU,QAAQ,MAAM,CAAC,CAAC;AACpD,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,MAAI,MAAM,QAAQ,UAAU,MAAM,KAAK,UAAU,OAAO,SAAS,GAAG;AAClE,UAAM,KAAK,mBAAmB;AAC9B,eAAW,SAAS,UAAU,QAAQ;AACpC,YAAM,MAAM,MAAM,WAAW,gBAAgB;AAC7C,YAAM,KAAK,OAAO,MAAM,UAAU,OAAO,MAAM,IAAI,IAAI,GAAG,EAAE;AAAA,IAC9D;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ,UAAU,YAAY,KAAK,UAAU,aAAa,SAAS,GAAG;AAC9E,UAAM,KAAK,oBAAoB;AAC/B,eAAW,SAAS,UAAU,cAAc;AAC1C,YAAM,KAAK,OAAO,MAAM,UAAU,OAAO,MAAM,IAAI,GAAG;AAAA,IACxD;AAAA,EACF;AAEA,MAAI,UAAU,cAAc;AAC1B,UAAM,KAAK;AAAA,gBAAmB,UAAU,YAAY,EAAE;AAAA,EACxD;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/get-prompt.ts"],"sourcesContent":["import { getPrompt as apiGetPrompt } from \"../langwatch-api.js\";\n\n/**\n * Handles the platform_get_prompt MCP tool invocation.\n *\n * Retrieves a specific prompt by ID or handle and formats it as\n * AI-readable markdown, including messages, model config, and version history.\n */\nexport async function handleGetPrompt(params: {\n idOrHandle: string;\n version?: number;\n tag?: string;\n}): Promise<string> {\n const prompt = await apiGetPrompt(params.idOrHandle, { version: params.version, tag: params.tag });\n\n const lines: string[] = [];\n lines.push(\n `# Prompt: ${prompt.name || prompt.handle || prompt.id}\\n`\n );\n\n if (prompt.handle) lines.push(`**Handle**: ${prompt.handle}`);\n if (prompt.id) lines.push(`**ID**: ${prompt.id}`);\n if (prompt.latestVersionNumber != null)\n lines.push(`**Latest Version**: v${prompt.latestVersionNumber}`);\n\n // Show model config\n const version = prompt.versions?.[0] ?? prompt;\n if (version.model) lines.push(`**Model**: ${version.model}`);\n\n // Show messages\n const messages = version.messages || prompt.prompt || [];\n if (Array.isArray(messages) && messages.length > 0) {\n lines.push(\"\\n## Messages\");\n for (const msg of messages) {\n lines.push(`\\n### ${msg.role}`);\n lines.push(msg.content);\n }\n }\n\n // Show version history\n if (prompt.versions && prompt.versions.length > 0) {\n lines.push(\"\\n## Version History\");\n for (const v of prompt.versions.slice(0, 10)) {\n const versionNum = v.version ?? \"?\";\n const commitMsg = v.commitMessage || \"No message\";\n lines.push(`- **v${versionNum}**: ${commitMsg}`);\n }\n if (prompt.versions.length > 10) {\n lines.push(`... and ${prompt.versions.length - 10} more versions`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;AAQA,eAAsB,gBAAgB,QAIlB;AAClB,QAAM,SAAS,MAAM,UAAa,OAAO,YAAY,EAAE,SAAS,OAAO,SAAS,KAAK,OAAO,IAAI,CAAC;AAEjG,QAAM,QAAkB,CAAC;AACzB,QAAM;AAAA,IACJ,aAAa,OAAO,QAAQ,OAAO,UAAU,OAAO,EAAE;AAAA;AAAA,EACxD;AAEA,MAAI,OAAO,OAAQ,OAAM,KAAK,eAAe,OAAO,MAAM,EAAE;AAC5D,MAAI,OAAO,GAAI,OAAM,KAAK,WAAW,OAAO,EAAE,EAAE;AAChD,MAAI,OAAO,uBAAuB;AAChC,UAAM,KAAK,wBAAwB,OAAO,mBAAmB,EAAE;AAGjE,QAAM,UAAU,OAAO,WAAW,CAAC,KAAK;AACxC,MAAI,QAAQ,MAAO,OAAM,KAAK,cAAc,QAAQ,KAAK,EAAE;AAG3D,QAAM,WAAW,QAAQ,YAAY,OAAO,UAAU,CAAC;AACvD,MAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,GAAG;AAClD,UAAM,KAAK,eAAe;AAC1B,eAAW,OAAO,UAAU;AAC1B,YAAM,KAAK;AAAA,MAAS,IAAI,IAAI,EAAE;AAC9B,YAAM,KAAK,IAAI,OAAO;AAAA,IACxB;AAAA,EACF;AAGA,MAAI,OAAO,YAAY,OAAO,SAAS,SAAS,GAAG;AACjD,UAAM,KAAK,sBAAsB;AACjC,eAAW,KAAK,OAAO,SAAS,MAAM,GAAG,EAAE,GAAG;AAC5C,YAAM,aAAa,EAAE,WAAW;AAChC,YAAM,YAAY,EAAE,iBAAiB;AACrC,YAAM,KAAK,QAAQ,UAAU,OAAO,SAAS,EAAE;AAAA,IACjD;AACA,QAAI,OAAO,SAAS,SAAS,IAAI;AAC/B,YAAM,KAAK,WAAW,OAAO,SAAS,SAAS,EAAE,gBAAgB;AAAA,IACnE;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/get-scenario.ts"],"sourcesContent":["import { getScenario as apiGetScenario } from \"../langwatch-api-scenarios.js\";\n\n/**\n * Handles the get_scenario MCP tool invocation.\n *\n * Retrieves a specific scenario by ID and formats it as\n * AI-readable markdown or raw JSON.\n */\nexport async function handleGetScenario(params: {\n scenarioId: string;\n format?: \"digest\" | \"json\";\n}): Promise<string> {\n const scenario = await apiGetScenario(params.scenarioId);\n\n if (params.format === \"json\") {\n return JSON.stringify(scenario, null, 2);\n }\n\n const lines: string[] = [];\n lines.push(`# Scenario: ${scenario.name}\\n`);\n lines.push(`**ID**: ${scenario.id}`);\n lines.push(`**Situation**: ${scenario.situation}`);\n\n if (Array.isArray(scenario.criteria) && scenario.criteria.length > 0) {\n lines.push(\"\\n## Criteria\");\n for (const criterion of scenario.criteria) {\n lines.push(`- ${criterion}`);\n }\n }\n\n if (Array.isArray(scenario.labels) && scenario.labels.length > 0) {\n lines.push(`\\n**Labels**: ${scenario.labels.join(\", \")}`);\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAQA,eAAsB,kBAAkB,QAGpB;AAClB,QAAM,WAAW,MAAM,YAAe,OAAO,UAAU;AAEvD,MAAI,OAAO,WAAW,QAAQ;AAC5B,WAAO,KAAK,UAAU,UAAU,MAAM,CAAC;AAAA,EACzC;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,eAAe,SAAS,IAAI;AAAA,CAAI;AAC3C,QAAM,KAAK,WAAW,SAAS,EAAE,EAAE;AACnC,QAAM,KAAK,kBAAkB,SAAS,SAAS,EAAE;AAEjD,MAAI,MAAM,QAAQ,SAAS,QAAQ,KAAK,SAAS,SAAS,SAAS,GAAG;AACpE,UAAM,KAAK,eAAe;AAC1B,eAAW,aAAa,SAAS,UAAU;AACzC,YAAM,KAAK,KAAK,SAAS,EAAE;AAAA,IAC7B;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,OAAO,SAAS,GAAG;AAChE,UAAM,KAAK;AAAA,cAAiB,SAAS,OAAO,KAAK,IAAI,CAAC,EAAE;AAAA,EAC1D;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/get-simulation-run.ts"],"sourcesContent":["import { getSimulationRun as apiGetSimulationRun } from \"../langwatch-api-simulation-runs.js\";\n\n/**\n * Handles the platform_get_simulation_run MCP tool invocation.\n */\nexport async function handleGetSimulationRun(params: {\n scenarioRunId: string;\n format?: \"digest\" | \"json\";\n}): Promise<string> {\n const run = await apiGetSimulationRun(params.scenarioRunId);\n\n if (params.format === \"json\") {\n return JSON.stringify(run, null, 2);\n }\n\n const lines: string[] = [];\n lines.push(`# Simulation Run: ${run.name ?? run.scenarioRunId}\\n`);\n lines.push(`**Run ID**: ${run.scenarioRunId}`);\n lines.push(`**Scenario ID**: ${run.scenarioId}`);\n lines.push(`**Batch ID**: ${run.batchRunId}`);\n lines.push(`**Status**: ${run.status}`);\n\n const duration = run.durationInMs > 0 ? `${(run.durationInMs / 1000).toFixed(1)}s` : \"—\";\n lines.push(`**Duration**: ${duration}`);\n if (run.totalCost) {\n lines.push(`**Cost**: $${run.totalCost.toFixed(4)}`);\n }\n lines.push(`**Started**: ${new Date(run.timestamp).toISOString()}`);\n\n if (run.results) {\n lines.push(\"\\n## Results\");\n if (run.results.verdict) {\n lines.push(`**Verdict**: ${run.results.verdict}`);\n }\n if (run.results.reasoning) {\n lines.push(`**Reasoning**: ${run.results.reasoning}`);\n }\n if (run.results.metCriteria && run.results.metCriteria.length > 0) {\n lines.push(`**Met Criteria**: ${run.results.metCriteria.join(\", \")}`);\n }\n if (run.results.unmetCriteria && run.results.unmetCriteria.length > 0) {\n lines.push(`**Unmet Criteria**: ${run.results.unmetCriteria.join(\", \")}`);\n }\n if (run.results.error) {\n lines.push(`**Error**: ${run.results.error}`);\n }\n }\n\n if (run.messages && run.messages.length > 0) {\n lines.push(\"\\n## Conversation\");\n for (const msg of run.messages) {\n const content = msg.content.length > 300\n ? msg.content.slice(0, 300) + \"...\"\n : msg.content;\n lines.push(`**[${msg.role}]**: ${content}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAKA,eAAsB,uBAAuB,QAGzB;AAClB,QAAM,MAAM,MAAM,iBAAoB,OAAO,aAAa;AAE1D,MAAI,OAAO,WAAW,QAAQ;AAC5B,WAAO,KAAK,UAAU,KAAK,MAAM,CAAC;AAAA,EACpC;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,qBAAqB,IAAI,QAAQ,IAAI,aAAa;AAAA,CAAI;AACjE,QAAM,KAAK,eAAe,IAAI,aAAa,EAAE;AAC7C,QAAM,KAAK,oBAAoB,IAAI,UAAU,EAAE;AAC/C,QAAM,KAAK,iBAAiB,IAAI,UAAU,EAAE;AAC5C,QAAM,KAAK,eAAe,IAAI,MAAM,EAAE;AAEtC,QAAM,WAAW,IAAI,eAAe,IAAI,IAAI,IAAI,eAAe,KAAM,QAAQ,CAAC,CAAC,MAAM;AACrF,QAAM,KAAK,iBAAiB,QAAQ,EAAE;AACtC,MAAI,IAAI,WAAW;AACjB,UAAM,KAAK,cAAc,IAAI,UAAU,QAAQ,CAAC,CAAC,EAAE;AAAA,EACrD;AACA,QAAM,KAAK,gBAAgB,IAAI,KAAK,IAAI,SAAS,EAAE,YAAY,CAAC,EAAE;AAElE,MAAI,IAAI,SAAS;AACf,UAAM,KAAK,cAAc;AACzB,QAAI,IAAI,QAAQ,SAAS;AACvB,YAAM,KAAK,gBAAgB,IAAI,QAAQ,OAAO,EAAE;AAAA,IAClD;AACA,QAAI,IAAI,QAAQ,WAAW;AACzB,YAAM,KAAK,kBAAkB,IAAI,QAAQ,SAAS,EAAE;AAAA,IACtD;AACA,QAAI,IAAI,QAAQ,eAAe,IAAI,QAAQ,YAAY,SAAS,GAAG;AACjE,YAAM,KAAK,qBAAqB,IAAI,QAAQ,YAAY,KAAK,IAAI,CAAC,EAAE;AAAA,IACtE;AACA,QAAI,IAAI,QAAQ,iBAAiB,IAAI,QAAQ,cAAc,SAAS,GAAG;AACrE,YAAM,KAAK,uBAAuB,IAAI,QAAQ,cAAc,KAAK,IAAI,CAAC,EAAE;AAAA,IAC1E;AACA,QAAI,IAAI,QAAQ,OAAO;AACrB,YAAM,KAAK,cAAc,IAAI,QAAQ,KAAK,EAAE;AAAA,IAC9C;AAAA,EACF;AAEA,MAAI,IAAI,YAAY,IAAI,SAAS,SAAS,GAAG;AAC3C,UAAM,KAAK,mBAAmB;AAC9B,eAAW,OAAO,IAAI,UAAU;AAC9B,YAAM,UAAU,IAAI,QAAQ,SAAS,MACjC,IAAI,QAAQ,MAAM,GAAG,GAAG,IAAI,QAC5B,IAAI;AACR,YAAM,KAAK,MAAM,IAAI,IAAI,QAAQ,OAAO,EAAE;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/get-suite.ts"],"sourcesContent":["import { getSuite as apiGetSuite } from \"../langwatch-api-suites.js\";\n\n/**\n * Handles the platform_get_suite MCP tool invocation.\n */\nexport async function handleGetSuite(params: {\n id: string;\n format?: \"digest\" | \"json\";\n}): Promise<string> {\n const suite = await apiGetSuite(params.id);\n\n if (params.format === \"json\") {\n return JSON.stringify(suite, null, 2);\n }\n\n const lines: string[] = [];\n lines.push(`# Suite: ${suite.name}\\n`);\n lines.push(`**ID**: ${suite.id}`);\n lines.push(`**Slug**: ${suite.slug}`);\n lines.push(`**Description**: ${suite.description ?? \"—\"}`);\n lines.push(`**Repeat Count**: ${suite.repeatCount}`);\n lines.push(`**Created**: ${suite.createdAt}`);\n lines.push(`**Updated**: ${suite.updatedAt}`);\n\n if (suite.labels.length > 0) {\n lines.push(`**Labels**: ${suite.labels.join(\", \")}`);\n }\n\n lines.push(\"\\n## Scenarios\");\n for (const id of suite.scenarioIds) {\n lines.push(`- ${id}`);\n }\n\n lines.push(\"\\n## Targets\");\n for (const t of suite.targets) {\n lines.push(`- ${t.type}:${t.referenceId}`);\n }\n\n const totalJobs = suite.scenarioIds.length * suite.targets.length * suite.repeatCount;\n lines.push(`\\n**Total jobs per run**: ${totalJobs}`);\n\n lines.push(\n \"\\n> Use `platform_run_suite` to trigger a run, or `platform_update_suite` to modify.\"\n );\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAKA,eAAsB,eAAe,QAGjB;AAClB,QAAM,QAAQ,MAAM,SAAY,OAAO,EAAE;AAEzC,MAAI,OAAO,WAAW,QAAQ;AAC5B,WAAO,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,EACtC;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,YAAY,MAAM,IAAI;AAAA,CAAI;AACrC,QAAM,KAAK,WAAW,MAAM,EAAE,EAAE;AAChC,QAAM,KAAK,aAAa,MAAM,IAAI,EAAE;AACpC,QAAM,KAAK,oBAAoB,MAAM,eAAe,QAAG,EAAE;AACzD,QAAM,KAAK,qBAAqB,MAAM,WAAW,EAAE;AACnD,QAAM,KAAK,gBAAgB,MAAM,SAAS,EAAE;AAC5C,QAAM,KAAK,gBAAgB,MAAM,SAAS,EAAE;AAE5C,MAAI,MAAM,OAAO,SAAS,GAAG;AAC3B,UAAM,KAAK,eAAe,MAAM,OAAO,KAAK,IAAI,CAAC,EAAE;AAAA,EACrD;AAEA,QAAM,KAAK,gBAAgB;AAC3B,aAAW,MAAM,MAAM,aAAa;AAClC,UAAM,KAAK,KAAK,EAAE,EAAE;AAAA,EACtB;AAEA,QAAM,KAAK,cAAc;AACzB,aAAW,KAAK,MAAM,SAAS;AAC7B,UAAM,KAAK,KAAK,EAAE,IAAI,IAAI,EAAE,WAAW,EAAE;AAAA,EAC3C;AAEA,QAAM,YAAY,MAAM,YAAY,SAAS,MAAM,QAAQ,SAAS,MAAM;AAC1E,QAAM,KAAK;AAAA,0BAA6B,SAAS,EAAE;AAEnD,QAAM;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/get-trace.ts"],"sourcesContent":["import { getTraceById as apiGetTraceById } from \"../langwatch-api.js\";\n\n/**\n * Handles the get_trace MCP tool invocation.\n *\n * Retrieves a single trace by ID. In digest mode (default), returns the\n * AI-readable formatted digest. In json mode, returns the full raw JSON.\n */\nexport async function handleGetTrace(params: {\n traceId: string;\n format?: \"digest\" | \"json\";\n}): Promise<string> {\n const format = params.format ?? \"digest\";\n const result = await apiGetTraceById(params.traceId, format);\n\n if (format === \"json\") {\n return JSON.stringify(result, null, 2);\n }\n\n const lines: string[] = [];\n lines.push(`# Trace: ${params.traceId}\\n`);\n\n if (result.timestamps) {\n lines.push(`**Started**: ${result.timestamps.started_at}`);\n if (result.timestamps.updated_at)\n lines.push(`**Updated**: ${result.timestamps.updated_at}`);\n }\n\n if (result.metadata) {\n const meta = result.metadata;\n if (meta.user_id) lines.push(`**User**: ${meta.user_id}`);\n if (meta.thread_id) lines.push(`**Thread**: ${meta.thread_id}`);\n if (meta.customer_id) lines.push(`**Customer**: ${meta.customer_id}`);\n if (meta.labels?.length) lines.push(`**Labels**: ${meta.labels.join(\", \")}`);\n }\n\n if (result.evaluations && result.evaluations.length > 0) {\n lines.push(\"\\n## Evaluations\");\n for (const evaluation of result.evaluations) {\n const status =\n evaluation.passed === true\n ? \"PASSED\"\n : evaluation.passed === false\n ? \"FAILED\"\n : \"N/A\";\n lines.push(\n `- **${evaluation.name || evaluation.evaluator_id}**: ${status}${evaluation.score != null ? ` (score: ${evaluation.score})` : \"\"}${evaluation.label ? ` [${evaluation.label}]` : \"\"}`\n );\n }\n }\n\n if (result.formatted_trace) {\n lines.push(`\\n## Trace Details\\n${result.formatted_trace}`);\n }\n\n lines.push(\n '\\n> Tip: Use `get_trace` with `format: \"json\"` to get the full raw trace data.'\n );\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;AAQA,eAAsB,eAAe,QAGjB;AAClB,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,SAAS,MAAM,aAAgB,OAAO,SAAS,MAAM;AAE3D,MAAI,WAAW,QAAQ;AACrB,WAAO,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,EACvC;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,YAAY,OAAO,OAAO;AAAA,CAAI;AAEzC,MAAI,OAAO,YAAY;AACrB,UAAM,KAAK,gBAAgB,OAAO,WAAW,UAAU,EAAE;AACzD,QAAI,OAAO,WAAW;AACpB,YAAM,KAAK,gBAAgB,OAAO,WAAW,UAAU,EAAE;AAAA,EAC7D;AAEA,MAAI,OAAO,UAAU;AACnB,UAAM,OAAO,OAAO;AACpB,QAAI,KAAK,QAAS,OAAM,KAAK,aAAa,KAAK,OAAO,EAAE;AACxD,QAAI,KAAK,UAAW,OAAM,KAAK,eAAe,KAAK,SAAS,EAAE;AAC9D,QAAI,KAAK,YAAa,OAAM,KAAK,iBAAiB,KAAK,WAAW,EAAE;AACpE,QAAI,KAAK,QAAQ,OAAQ,OAAM,KAAK,eAAe,KAAK,OAAO,KAAK,IAAI,CAAC,EAAE;AAAA,EAC7E;AAEA,MAAI,OAAO,eAAe,OAAO,YAAY,SAAS,GAAG;AACvD,UAAM,KAAK,kBAAkB;AAC7B,eAAW,cAAc,OAAO,aAAa;AAC3C,YAAM,SACJ,WAAW,WAAW,OAClB,WACA,WAAW,WAAW,QACpB,WACA;AACR,YAAM;AAAA,QACJ,OAAO,WAAW,QAAQ,WAAW,YAAY,OAAO,MAAM,GAAG,WAAW,SAAS,OAAO,YAAY,WAAW,KAAK,MAAM,EAAE,GAAG,WAAW,QAAQ,KAAK,WAAW,KAAK,MAAM,EAAE;AAAA,MACrL;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,iBAAiB;AAC1B,UAAM,KAAK;AAAA;AAAA,EAAuB,OAAO,eAAe,EAAE;AAAA,EAC5D;AAEA,QAAM;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/get-workflow.ts"],"sourcesContent":["import { getWorkflow as apiGetWorkflow } from \"../langwatch-api-workflows.js\";\n\nexport async function handleGetWorkflow(params: { id: string }): Promise<string> {\n const workflow = await apiGetWorkflow(params.id);\n\n const lines: string[] = [];\n lines.push(`# ${workflow.name}\\n`);\n lines.push(`**ID**: ${workflow.id}`);\n if (workflow.description) lines.push(`**Description**: ${workflow.description}`);\n if (workflow.icon) lines.push(`**Icon**: ${workflow.icon}`);\n lines.push(`**Evaluator**: ${workflow.isEvaluator ? \"yes\" : \"no\"}`);\n lines.push(`**Component**: ${workflow.isComponent ? \"yes\" : \"no\"}`);\n lines.push(`**Created**: ${workflow.createdAt}`);\n lines.push(`**Updated**: ${workflow.updatedAt}`);\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAEA,eAAsB,kBAAkB,QAAyC;AAC/E,QAAM,WAAW,MAAM,YAAe,OAAO,EAAE;AAE/C,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,KAAK,SAAS,IAAI;AAAA,CAAI;AACjC,QAAM,KAAK,WAAW,SAAS,EAAE,EAAE;AACnC,MAAI,SAAS,YAAa,OAAM,KAAK,oBAAoB,SAAS,WAAW,EAAE;AAC/E,MAAI,SAAS,KAAM,OAAM,KAAK,aAAa,SAAS,IAAI,EAAE;AAC1D,QAAM,KAAK,kBAAkB,SAAS,cAAc,QAAQ,IAAI,EAAE;AAClE,QAAM,KAAK,kBAAkB,SAAS,cAAc,QAAQ,IAAI,EAAE;AAClE,QAAM,KAAK,gBAAgB,SAAS,SAAS,EAAE;AAC/C,QAAM,KAAK,gBAAgB,SAAS,SAAS,EAAE;AAE/C,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/http-server.ts"],"sourcesContent":["import express from \"express\";\nimport type { Request, Response, NextFunction } from \"express\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { SSEServerTransport } from \"@modelcontextprotocol/sdk/server/sse.js\";\nimport { isInitializeRequest } from \"@modelcontextprotocol/sdk/types.js\";\nimport { randomUUID, createHash } from \"node:crypto\";\nimport type { Server } from \"node:http\";\n\nimport { getConfig, runWithConfig } from \"./config.js\";\nimport { createMcpServer } from \"./create-mcp-server.js\";\n\n/**\n * In-memory store for OAuth access tokens.\n * Maps token → API key so we can resolve Bearer tokens from either\n * direct API keys or OAuth-issued access tokens.\n */\nconst oauthTokens = new Map<string, { apiKey: string; expiresAt: number }>();\n\n/**\n * Extracts the API key from the request's Authorization header.\n * Accepts both direct API keys and OAuth-issued access tokens.\n * Expects the format: `Bearer <key>`.\n */\nfunction extractBearerToken(req: Request): string | null {\n const authHeader = req.headers.authorization;\n if (!authHeader?.startsWith(\"Bearer \")) return null;\n const token = authHeader.slice(7) || null;\n if (!token) return null;\n\n // Check if this is an OAuth-issued access token\n const oauthEntry = oauthTokens.get(token);\n if (oauthEntry) {\n if (Date.now() < oauthEntry.expiresAt) {\n return oauthEntry.apiKey;\n }\n // Token expired, clean up\n oauthTokens.delete(token);\n return null;\n }\n\n // Otherwise treat it as a direct API key\n return token;\n}\n\n/**\n * Generates a deterministic but opaque access token from client credentials.\n */\nfunction generateAccessToken(): string {\n return createHash(\"sha256\").update(randomUUID()).digest(\"hex\");\n}\n\n/**\n * Per-session state: the transport and the API key provided at session creation.\n */\ninterface SessionState {\n transport: StreamableHTTPServerTransport;\n apiKey: string;\n}\n\n/**\n * Wraps the request handling inside `runWithConfig()` so that all downstream\n * tool calls (which read config via `getConfig()`/`requireApiKey()`) see the\n * per-session API key instead of the global one.\n */\nasync function handleWithSessionConfig<T>(\n apiKey: string,\n fn: () => Promise<T>\n): Promise<T> {\n const baseConfig = getConfig();\n return runWithConfig({ ...baseConfig, apiKey }, fn);\n}\n\n/**\n * Starts an Express HTTP server with Streamable HTTP and legacy SSE transports\n * for the LangWatch MCP server.\n *\n * Each client session provides its own API key via `Authorization: Bearer <key>`.\n * The key is captured on the initialize request and stored per-session. All\n * subsequent requests in that session use the captured key.\n *\n * Endpoints:\n * - GET /health - Health check for Kubernetes probes (no auth)\n * - POST/GET/DELETE /mcp - Streamable HTTP transport (modern)\n * - GET /sse - Legacy SSE transport (backwards compatibility)\n * - POST /messages - Legacy SSE message endpoint\n */\nexport async function startHttpServer({\n port,\n}: {\n port: number;\n}): Promise<{ server: Server; port: number }> {\n const app = express();\n app.set(\"trust proxy\", true);\n app.use(express.json());\n\n // CORS middleware for cross-origin requests (ChatGPT/Claude Chat)\n app.use((_req: Request, res: Response, next: NextFunction) => {\n res.header(\"Access-Control-Allow-Origin\", \"*\");\n res.header(\n \"Access-Control-Allow-Methods\",\n \"GET, POST, DELETE, OPTIONS\"\n );\n res.header(\n \"Access-Control-Allow-Headers\",\n \"Content-Type, Authorization, mcp-session-id, MCP-Protocol-Version\"\n );\n if (_req.method === \"OPTIONS\") {\n res.sendStatus(200);\n return;\n }\n next();\n });\n\n // Health check endpoint for Kubernetes probes\n app.get(\"/health\", (_req: Request, res: Response) => {\n res.json({ status: \"ok\" });\n });\n\n // --- OAuth 2.0 endpoints (for Claude Desktop and other OAuth-only clients) ---\n\n app.get(\n \"/.well-known/oauth-authorization-server\",\n (_req: Request, res: Response) => {\n const baseUrl = `${_req.protocol}://${_req.get(\"host\")}`;\n res.json({\n issuer: baseUrl,\n token_endpoint: `${baseUrl}/oauth/token`,\n token_endpoint_auth_methods_supported: [\"client_secret_post\"],\n grant_types_supported: [\"client_credentials\"],\n response_types_supported: [],\n scopes_supported: [\"mcp:tools\"],\n });\n }\n );\n\n // URL-encoded body parser for OAuth token endpoint (RFC 6749 requires\n // application/x-www-form-urlencoded)\n app.post(\n \"/oauth/token\",\n express.urlencoded({ extended: false }),\n (req: Request, res: Response) => {\n const grantType = req.body.grant_type;\n\n if (grantType !== \"client_credentials\") {\n res.status(400).json({\n error: \"unsupported_grant_type\",\n error_description:\n \"Only client_credentials grant type is supported\",\n });\n return;\n }\n\n // Accept client_secret as the LangWatch API key.\n // client_id is ignored — the API key identifies the project.\n const clientSecret = req.body.client_secret;\n\n if (!clientSecret || typeof clientSecret !== \"string\") {\n res.status(400).json({\n error: \"invalid_request\",\n error_description:\n \"client_secret is required (use your LangWatch API key)\",\n });\n return;\n }\n\n const expiresIn = 3600; // 1 hour\n const accessToken = generateAccessToken();\n\n oauthTokens.set(accessToken, {\n apiKey: clientSecret,\n expiresAt: Date.now() + expiresIn * 1000,\n });\n\n res.json({\n access_token: accessToken,\n token_type: \"Bearer\",\n expires_in: expiresIn,\n scope: \"mcp:tools\",\n });\n }\n );\n\n // --- Streamable HTTP transport (modern) ---\n\n const sessions: Record<string, SessionState> = {};\n\n app.post(\"/mcp\", async (req: Request, res: Response) => {\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n\n if (sessionId && sessions[sessionId]) {\n const session = sessions[sessionId];\n await handleWithSessionConfig(session.apiKey, () =>\n session.transport.handleRequest(req, res, req.body)\n );\n return;\n }\n\n if (!sessionId && isInitializeRequest(req.body)) {\n const apiKey = extractBearerToken(req);\n\n if (!apiKey) {\n res.status(401).json({\n error:\n \"Authorization: Bearer <LANGWATCH_API_KEY> header required\",\n });\n return;\n }\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n onsessioninitialized: (id) => {\n sessions[id] = { transport, apiKey };\n },\n });\n transport.onclose = () => {\n if (transport.sessionId) {\n delete sessions[transport.sessionId];\n }\n };\n\n const sessionServer = createMcpServer();\n await handleWithSessionConfig(apiKey, () =>\n sessionServer.connect(transport)\n );\n\n await handleWithSessionConfig(apiKey, () =>\n transport.handleRequest(req, res, req.body)\n );\n return;\n }\n\n res.status(400).json({\n error: \"Invalid request — no session ID or not an initialize request\",\n });\n });\n\n app.get(\"/mcp\", async (req: Request, res: Response) => {\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n\n if (sessionId && sessions[sessionId]) {\n const session = sessions[sessionId];\n await handleWithSessionConfig(session.apiKey, () =>\n session.transport.handleRequest(req, res)\n );\n } else {\n res\n .status(400)\n .json({ error: \"Invalid request — no valid session ID\" });\n }\n });\n\n app.delete(\"/mcp\", async (req: Request, res: Response) => {\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n if (sessionId && sessions[sessionId]) {\n const session = sessions[sessionId];\n await session.transport.close();\n delete sessions[sessionId];\n res.status(200).json({ status: \"session closed\" });\n } else {\n res.status(404).json({ error: \"Session not found\" });\n }\n });\n\n // --- Legacy SSE transport (backwards compatibility) ---\n\n interface SseSessionState {\n transport: SSEServerTransport;\n apiKey: string;\n }\n\n const sseSessions: Record<string, SseSessionState> = {};\n\n app.get(\"/sse\", async (req: Request, res: Response) => {\n const apiKey =\n extractBearerToken(req) ||\n (req.query[\"apiKey\"] as string | undefined) ||\n null;\n\n if (!apiKey) {\n res.status(401).json({\n error:\n \"Authorization: Bearer <LANGWATCH_API_KEY> header or ?apiKey= query parameter required\",\n });\n return;\n }\n\n const transport = new SSEServerTransport(\"/messages\", res);\n sseSessions[transport.sessionId] = { transport, apiKey };\n\n const sessionServer = createMcpServer();\n\n // Clean up when the SSE connection closes\n res.on(\"close\", () => {\n delete sseSessions[transport.sessionId];\n });\n\n await handleWithSessionConfig(apiKey, () =>\n sessionServer.connect(transport)\n );\n });\n\n // Handle POST messages — mount at both /messages and /sse/messages\n // because some clients resolve the relative /messages URL differently\n const handleSseMessage = async (req: Request, res: Response) => {\n const sessionId = req.query[\"sessionId\"] as string | undefined;\n if (!sessionId || !sseSessions[sessionId]) {\n res.status(400).json({ error: \"Invalid or missing session ID\" });\n return;\n }\n\n const session = sseSessions[sessionId];\n await handleWithSessionConfig(session.apiKey, () =>\n session.transport.handlePostMessage(req, res, req.body)\n );\n };\n\n app.post(\"/messages\", handleSseMessage);\n app.post(\"/sse/messages\", handleSseMessage);\n\n // Start the server\n return new Promise((resolve) => {\n const server = app.listen(port, \"0.0.0.0\", () => {\n const addr = server.address();\n const resolvedPort =\n typeof addr === \"object\" && addr ? addr.port : port;\n resolve({ server, port: resolvedPort });\n });\n });\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\n\nimport { initConfig } from \"./config.js\";\nimport { createMcpServer } from \"./create-mcp-server.js\";\n\nconst argv = await yargs(hideBin(process.argv))\n .option(\"apiKey\", {\n type: \"string\",\n description: \"LangWatch API key\",\n })\n .option(\"endpoint\", {\n type: \"string\",\n description: \"LangWatch API endpoint\",\n })\n .option(\"http\", {\n type: \"boolean\",\n description: \"Start HTTP/SSE server instead of stdio\",\n default: false,\n })\n .option(\"port\", {\n type: \"number\",\n description: \"HTTP server port (only used with --http)\",\n default: 3000,\n })\n .help()\n .parseAsync();\n\ninitConfig({\n apiKey: argv.apiKey,\n endpoint: argv.endpoint,\n});\n\nif (argv.http) {\n const { startHttpServer } = await import(\"./http-server.js\");\n const { port } = await startHttpServer({ port: argv.port });\n console.log(`LangWatch MCP server listening on http://0.0.0.0:${port}/mcp`);\n console.log(\n \"Clients must provide their API key via Authorization: Bearer <key> header\"\n );\n} else {\n const transport = new StdioServerTransport();\n const server = createMcpServer();\n await server.connect(transport);\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,4BAA4B;AACrC,OAAO,WAAW;AAClB,SAAS,eAAe;AAKxB,IAAM,OAAO,MAAM,MAAM,QAAQ,QAAQ,IAAI,CAAC,EAC3C,OAAO,UAAU;AAAA,EAChB,MAAM;AAAA,EACN,aAAa;AACf,CAAC,EACA,OAAO,YAAY;AAAA,EAClB,MAAM;AAAA,EACN,aAAa;AACf,CAAC,EACA,OAAO,QAAQ;AAAA,EACd,MAAM;AAAA,EACN,aAAa;AAAA,EACb,SAAS;AACX,CAAC,EACA,OAAO,QAAQ;AAAA,EACd,MAAM;AAAA,EACN,aAAa;AAAA,EACb,SAAS;AACX,CAAC,EACA,KAAK,EACL,WAAW;AAEd,WAAW;AAAA,EACT,QAAQ,KAAK;AAAA,EACb,UAAU,KAAK;AACjB,CAAC;AAED,IAAI,KAAK,MAAM;AACb,QAAM,EAAE,gBAAgB,IAAI,MAAM,OAAO,2BAAkB;AAC3D,QAAM,EAAE,KAAK,IAAI,MAAM,gBAAgB,EAAE,MAAM,KAAK,KAAK,CAAC;AAC1D,UAAQ,IAAI,oDAAoD,IAAI,MAAM;AAC1E,UAAQ;AAAA,IACN;AAAA,EACF;AACF,OAAO;AACL,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,SAAS,gBAAgB;AAC/B,QAAM,OAAO,QAAQ,SAAS;AAChC;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/langwatch-api-monitors.ts"],"sourcesContent":["import { makeRequest } from \"./langwatch-api.js\";\n\nexport interface MonitorSummary {\n id: string;\n name: string;\n slug: string;\n checkType: string;\n enabled: boolean;\n executionMode: string;\n sample: number;\n level: string;\n evaluatorId: string | null;\n preconditions: unknown;\n parameters: unknown;\n mappings: unknown;\n threadIdleTimeout: number | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport async function listMonitors(): Promise<MonitorSummary[]> {\n return makeRequest(\"GET\", \"/api/monitors\") as Promise<MonitorSummary[]>;\n}\n\nexport async function getMonitor(id: string): Promise<MonitorSummary> {\n return makeRequest(\n \"GET\",\n `/api/monitors/${encodeURIComponent(id)}`\n ) as Promise<MonitorSummary>;\n}\n\nexport async function createMonitor(data: {\n name: string;\n checkType: string;\n executionMode?: string;\n sample?: number;\n evaluatorId?: string;\n level?: string;\n parameters?: Record<string, unknown>;\n}): Promise<MonitorSummary> {\n return makeRequest(\"POST\", \"/api/monitors\", {\n ...data,\n preconditions: [],\n parameters: data.parameters ?? {},\n }) as Promise<MonitorSummary>;\n}\n\nexport async function updateMonitor(params: {\n id: string;\n name?: string;\n enabled?: boolean;\n executionMode?: string;\n sample?: number;\n parameters?: Record<string, unknown>;\n}): Promise<MonitorSummary> {\n const { id, ...data } = params;\n return makeRequest(\n \"PATCH\",\n `/api/monitors/${encodeURIComponent(id)}`,\n data\n ) as Promise<MonitorSummary>;\n}\n\nexport async function toggleMonitor(params: {\n id: string;\n enabled: boolean;\n}): Promise<{ id: string; enabled: boolean }> {\n return makeRequest(\n \"POST\",\n `/api/monitors/${encodeURIComponent(params.id)}/toggle`,\n { enabled: params.enabled }\n ) as Promise<{ id: string; enabled: boolean }>;\n}\n\nexport async function deleteMonitor(\n id: string\n): Promise<{ id: string; deleted: boolean }> {\n return makeRequest(\n \"DELETE\",\n `/api/monitors/${encodeURIComponent(id)}`\n ) as Promise<{ id: string; deleted: boolean }>;\n}\n"],"mappings":";;;;;;AAoBA,eAAsB,eAA0C;AAC9D,SAAO,YAAY,OAAO,eAAe;AAC3C;AAEA,eAAsB,WAAW,IAAqC;AACpE,SAAO;AAAA,IACL;AAAA,IACA,iBAAiB,mBAAmB,EAAE,CAAC;AAAA,EACzC;AACF;AAEA,eAAsB,cAAc,MAQR;AAC1B,SAAO,YAAY,QAAQ,iBAAiB;AAAA,IAC1C,GAAG;AAAA,IACH,eAAe,CAAC;AAAA,IAChB,YAAY,KAAK,cAAc,CAAC;AAAA,EAClC,CAAC;AACH;AAEA,eAAsB,cAAc,QAOR;AAC1B,QAAM,EAAE,IAAI,GAAG,KAAK,IAAI;AACxB,SAAO;AAAA,IACL;AAAA,IACA,iBAAiB,mBAAmB,EAAE,CAAC;AAAA,IACvC;AAAA,EACF;AACF;AAEA,eAAsB,cAAc,QAGU;AAC5C,SAAO;AAAA,IACL;AAAA,IACA,iBAAiB,mBAAmB,OAAO,EAAE,CAAC;AAAA,IAC9C,EAAE,SAAS,OAAO,QAAQ;AAAA,EAC5B;AACF;AAEA,eAAsB,cACpB,IAC2C;AAC3C,SAAO;AAAA,IACL;AAAA,IACA,iBAAiB,mBAAmB,EAAE,CAAC;AAAA,EACzC;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/langwatch-api-secrets.ts"],"sourcesContent":["import { makeRequest } from \"./langwatch-api.js\";\n\nexport interface SecretSummary {\n id: string;\n projectId: string;\n name: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport async function listSecrets(): Promise<SecretSummary[]> {\n return makeRequest(\"GET\", \"/api/secrets\") as Promise<SecretSummary[]>;\n}\n\nexport async function getSecret(id: string): Promise<SecretSummary> {\n return makeRequest(\n \"GET\",\n `/api/secrets/${encodeURIComponent(id)}`\n ) as Promise<SecretSummary>;\n}\n\nexport async function createSecret(data: {\n name: string;\n value: string;\n}): Promise<SecretSummary> {\n return makeRequest(\"POST\", \"/api/secrets\", data) as Promise<SecretSummary>;\n}\n\nexport async function updateSecret(params: {\n id: string;\n value: string;\n}): Promise<SecretSummary> {\n const { id, value } = params;\n return makeRequest(\n \"PUT\",\n `/api/secrets/${encodeURIComponent(id)}`,\n { value }\n ) as Promise<SecretSummary>;\n}\n\nexport async function deleteSecret(\n id: string\n): Promise<{ id: string; deleted: boolean }> {\n return makeRequest(\n \"DELETE\",\n `/api/secrets/${encodeURIComponent(id)}`\n ) as Promise<{ id: string; deleted: boolean }>;\n}\n"],"mappings":";;;;;;AAUA,eAAsB,cAAwC;AAC5D,SAAO,YAAY,OAAO,cAAc;AAC1C;AAEA,eAAsB,UAAU,IAAoC;AAClE,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,mBAAmB,EAAE,CAAC;AAAA,EACxC;AACF;AAEA,eAAsB,aAAa,MAGR;AACzB,SAAO,YAAY,QAAQ,gBAAgB,IAAI;AACjD;AAEA,eAAsB,aAAa,QAGR;AACzB,QAAM,EAAE,IAAI,MAAM,IAAI;AACtB,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,mBAAmB,EAAE,CAAC;AAAA,IACtC,EAAE,MAAM;AAAA,EACV;AACF;AAEA,eAAsB,aACpB,IAC2C;AAC3C,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,mBAAmB,EAAE,CAAC;AAAA,EACxC;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/langwatch-api-triggers.ts"],"sourcesContent":["import { makeRequest } from \"./langwatch-api.js\";\n\nexport interface TriggerSummary {\n id: string;\n name: string;\n action: string;\n actionParams: Record<string, unknown>;\n filters: Record<string, unknown>;\n active: boolean;\n message: string | null;\n alertType: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport async function listTriggers(): Promise<TriggerSummary[]> {\n return makeRequest(\"GET\", \"/api/triggers\") as Promise<TriggerSummary[]>;\n}\n\nexport async function getTrigger(id: string): Promise<TriggerSummary> {\n return makeRequest(\"GET\", `/api/triggers/${encodeURIComponent(id)}`) as Promise<TriggerSummary>;\n}\n\nexport async function createTrigger(data: {\n name: string;\n action: string;\n actionParams?: Record<string, unknown>;\n filters?: Record<string, unknown>;\n message?: string;\n alertType?: string;\n}): Promise<TriggerSummary> {\n return makeRequest(\"POST\", \"/api/triggers\", data) as Promise<TriggerSummary>;\n}\n\nexport async function updateTrigger(params: {\n id: string;\n name?: string;\n active?: boolean;\n message?: string | null;\n alertType?: string | null;\n}): Promise<TriggerSummary> {\n const { id, ...data } = params;\n return makeRequest(\"PATCH\", `/api/triggers/${encodeURIComponent(id)}`, data) as Promise<TriggerSummary>;\n}\n\nexport async function deleteTrigger(id: string): Promise<{ id: string; deleted: boolean }> {\n return makeRequest(\"DELETE\", `/api/triggers/${encodeURIComponent(id)}`) as Promise<{ id: string; deleted: boolean }>;\n}\n"],"mappings":";;;;;;AAeA,eAAsB,eAA0C;AAC9D,SAAO,YAAY,OAAO,eAAe;AAC3C;AAEA,eAAsB,WAAW,IAAqC;AACpE,SAAO,YAAY,OAAO,iBAAiB,mBAAmB,EAAE,CAAC,EAAE;AACrE;AAEA,eAAsB,cAAc,MAOR;AAC1B,SAAO,YAAY,QAAQ,iBAAiB,IAAI;AAClD;AAEA,eAAsB,cAAc,QAMR;AAC1B,QAAM,EAAE,IAAI,GAAG,KAAK,IAAI;AACxB,SAAO,YAAY,SAAS,iBAAiB,mBAAmB,EAAE,CAAC,IAAI,IAAI;AAC7E;AAEA,eAAsB,cAAc,IAAuD;AACzF,SAAO,YAAY,UAAU,iBAAiB,mBAAmB,EAAE,CAAC,EAAE;AACxE;","names":[]}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
deleteWorkflow,
|
|
3
|
-
getWorkflow,
|
|
4
|
-
listWorkflows,
|
|
5
|
-
runWorkflow
|
|
6
|
-
} from "./chunk-ZVS4UKN2.js";
|
|
7
|
-
import "./chunk-2WPLXEKF.js";
|
|
8
|
-
import "./chunk-BWWY5KEF.js";
|
|
9
|
-
export {
|
|
10
|
-
deleteWorkflow,
|
|
11
|
-
getWorkflow,
|
|
12
|
-
listWorkflows,
|
|
13
|
-
runWorkflow
|
|
14
|
-
};
|
|
15
|
-
//# sourceMappingURL=langwatch-api-workflows-VJRIIDZ7.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/list-agents.ts"],"sourcesContent":["import { listAgents as apiListAgents } from \"../langwatch-api-agents.js\";\n\nexport async function handleListAgents(): Promise<string> {\n const result = await apiListAgents({ limit: 100 });\n const agents = result.data;\n\n if (!Array.isArray(agents) || agents.length === 0) {\n return \"No agents found in this project.\\n\\n> Tip: Use `platform_create_agent` to create your first agent.\";\n }\n\n const lines: string[] = [];\n lines.push(`# Agents (${result.pagination.total} total)\\n`);\n\n for (const a of agents) {\n lines.push(`## ${a.name}`);\n lines.push(`**ID**: ${a.id}`);\n lines.push(`**Type**: ${a.type}`);\n lines.push(`**Updated**: ${a.updatedAt}`);\n lines.push(\"\");\n }\n\n lines.push(\n \"> Use `platform_get_agent` with the ID to see full agent details including config.\",\n );\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAEA,eAAsB,mBAAoC;AACxD,QAAM,SAAS,MAAM,WAAc,EAAE,OAAO,IAAI,CAAC;AACjD,QAAM,SAAS,OAAO;AAEtB,MAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,GAAG;AACjD,WAAO;AAAA,EACT;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,aAAa,OAAO,WAAW,KAAK;AAAA,CAAW;AAE1D,aAAW,KAAK,QAAQ;AACtB,UAAM,KAAK,MAAM,EAAE,IAAI,EAAE;AACzB,UAAM,KAAK,WAAW,EAAE,EAAE,EAAE;AAC5B,UAAM,KAAK,aAAa,EAAE,IAAI,EAAE;AAChC,UAAM,KAAK,gBAAgB,EAAE,SAAS,EAAE;AACxC,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/list-annotations.ts"],"sourcesContent":["import {\n listAnnotations as apiListAnnotations,\n getAnnotationsByTrace as apiGetByTrace,\n} from \"../langwatch-api-annotations.js\";\n\nexport async function handleListAnnotations(params: {\n traceId?: string;\n}): Promise<string> {\n const annotations = params.traceId\n ? await apiGetByTrace(params.traceId)\n : await apiListAnnotations();\n\n if (!Array.isArray(annotations) || annotations.length === 0) {\n return params.traceId\n ? `No annotations found for trace \"${params.traceId}\".\\n\\n> Tip: Use \\`platform_create_annotation\\` to annotate a trace.`\n : \"No annotations found in this project.\\n\\n> Tip: Use `platform_create_annotation` to annotate a trace.\";\n }\n\n const lines: string[] = [];\n lines.push(`# Annotations (${annotations.length} total)\\n`);\n\n for (const a of annotations) {\n const rating = a.isThumbsUp === true ? \"👍\" : a.isThumbsUp === false ? \"👎\" : \"—\";\n lines.push(`## Annotation ${a.id ?? \"—\"}`);\n lines.push(`**Trace ID**: ${a.traceId ?? \"—\"}`);\n lines.push(`**Rating**: ${rating}`);\n if (a.comment) lines.push(`**Comment**: ${a.comment}`);\n if (a.email) lines.push(`**By**: ${a.email}`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;AAKA,eAAsB,sBAAsB,QAExB;AAClB,QAAM,cAAc,OAAO,UACvB,MAAM,sBAAc,OAAO,OAAO,IAClC,MAAM,gBAAmB;AAE7B,MAAI,CAAC,MAAM,QAAQ,WAAW,KAAK,YAAY,WAAW,GAAG;AAC3D,WAAO,OAAO,UACV,mCAAmC,OAAO,OAAO;AAAA;AAAA,kEACjD;AAAA,EACN;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,kBAAkB,YAAY,MAAM;AAAA,CAAW;AAE1D,aAAW,KAAK,aAAa;AAC3B,UAAM,SAAS,EAAE,eAAe,OAAO,cAAO,EAAE,eAAe,QAAQ,cAAO;AAC9E,UAAM,KAAK,iBAAiB,EAAE,MAAM,QAAG,EAAE;AACzC,UAAM,KAAK,iBAAiB,EAAE,WAAW,QAAG,EAAE;AAC9C,UAAM,KAAK,eAAe,MAAM,EAAE;AAClC,QAAI,EAAE,QAAS,OAAM,KAAK,gBAAgB,EAAE,OAAO,EAAE;AACrD,QAAI,EAAE,MAAO,OAAM,KAAK,WAAW,EAAE,KAAK,EAAE;AAC5C,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|