diff --git a/.changeset/five-pens-dance.md b/.changeset/five-pens-dance.md new file mode 100644 index 000000000..f7d37675c --- /dev/null +++ b/.changeset/five-pens-dance.md @@ -0,0 +1,5 @@ +--- +"braintrust": patch +--- + +feat(auto-instrumentation): add Mastra auto-instrumentation coverage diff --git a/e2e/config/pr-comment-scenarios.json b/e2e/config/pr-comment-scenarios.json index bee0040c5..ccf52b34e 100644 --- a/e2e/config/pr-comment-scenarios.json +++ b/e2e/config/pr-comment-scenarios.json @@ -42,6 +42,12 @@ { "variantKey": "google-genai-v1460", "label": "v1.46.0" } ] }, + { + "scenarioDirName": "mastra-instrumentation", + "label": "Mastra Instrumentation", + "metadataScenario": "mastra-instrumentation", + "variants": [{ "variantKey": "mastra-v1260", "label": "v1.26.0" }] + }, { "scenarioDirName": "groq-instrumentation", "label": "Groq Instrumentation", diff --git a/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1260.log-payloads.json b/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1260.log-payloads.json new file mode 100644 index 000000000..97a43fe9e --- /dev/null +++ b/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1260.log-payloads.json @@ -0,0 +1,461 @@ +[ + { + "has_input": false, + "has_output": false, + "metadata": { + "scenario": "mastra-instrumentation" + }, + "metric_keys": [], + "name": "mastra-instrumentation-root", + "type": "task" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "generate" + }, + "metric_keys": [], + "name": "mastra-agent-generate-operation", + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "agent_name": "Weather Agent", + "method": "generate" + }, + "metric_keys": [], + "name": "Mastra Agent Weather Agent generate", + "type": "task" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "execution-workflow" + }, + "metric_keys": [], + "name": "Mastra Workflow execution-workflow start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-tools-step", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-memory-step", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.mapping_", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.stream-text-step", + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "agentic-loop" + }, + "metric_keys": [], + "name": "Mastra Workflow agentic-loop start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "agentic-loop", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.agentic-loop.step.executionWorkflow", + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "executionWorkflow" + }, + "metric_keys": [], + "name": "Mastra Workflow executionWorkflow start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.capture-response-count", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llm-execution", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.add-response-to-messagelist", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.map-tool-calls", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llmExecutionMappingStep", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.backgroundTaskCheckStep", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.isTaskCompleteStep", + "type": "function" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "stream" + }, + "metric_keys": [], + "name": "mastra-agent-stream-operation", + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "agent_name": "Weather Agent", + "method": "stream" + }, + "metric_keys": [], + "name": "Mastra Agent Weather Agent stream", + "type": "task" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "execution-workflow" + }, + "metric_keys": [], + "name": "Mastra Workflow execution-workflow start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-tools-step", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-memory-step", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.mapping_", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.stream-text-step", + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "agentic-loop" + }, + "metric_keys": [], + "name": "Mastra Workflow agentic-loop start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "agentic-loop", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.agentic-loop.step.executionWorkflow", + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "executionWorkflow" + }, + "metric_keys": [], + "name": "Mastra Workflow executionWorkflow start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.capture-response-count", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llm-execution", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.add-response-to-messagelist", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.map-tool-calls", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llmExecutionMappingStep", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.backgroundTaskCheckStep", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.isTaskCompleteStep", + "type": "function" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "tool" + }, + "metric_keys": [], + "name": "mastra-tool-operation", + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "tool_id": "lookup_weather" + }, + "metric_keys": [], + "name": "Mastra Tool lookup_weather", + "type": "tool" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "workflow" + }, + "metric_keys": [], + "name": "mastra-workflow-operation", + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "travel-flow" + }, + "metric_keys": [], + "name": "Mastra Workflow travel-flow start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "travel-flow", + "workflow_run_id": "workflow-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.travel-flow.step.lookup-step", + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "tool_id": "lookup_weather", + "workflow_id": "travel-flow", + "workflow_run_id": "workflow-run-context" + }, + "metric_keys": [], + "name": "Mastra Tool lookup_weather", + "type": "tool" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "scenario": "mastra-instrumentation" + }, + "metric_keys": [], + "name": "mastra-instrumentation-root", + "type": "task" + } +] diff --git a/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1260.span-events.json b/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1260.span-events.json new file mode 100644 index 000000000..e696cc367 --- /dev/null +++ b/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1260.span-events.json @@ -0,0 +1,667 @@ +[ + { + "has_input": false, + "has_output": false, + "metadata": { + "scenario": "mastra-instrumentation" + }, + "metric_keys": [], + "name": "mastra-instrumentation-root", + "root_span_id": "", + "span_id": "", + "span_parents": [], + "type": "task" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "generate" + }, + "metric_keys": [], + "name": "mastra-agent-generate-operation", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "agent_name": "Weather Agent", + "method": "generate" + }, + "metric_keys": [], + "name": "Mastra Agent Weather Agent generate", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "execution-workflow" + }, + "metric_keys": [], + "name": "Mastra Workflow execution-workflow start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-tools-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-memory-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.mapping_", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.stream-text-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "agentic-loop" + }, + "metric_keys": [], + "name": "Mastra Workflow agentic-loop start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "agentic-loop", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.agentic-loop.step.executionWorkflow", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "executionWorkflow" + }, + "metric_keys": [], + "name": "Mastra Workflow executionWorkflow start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.capture-response-count", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llm-execution", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.add-response-to-messagelist", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.map-tool-calls", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llmExecutionMappingStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.backgroundTaskCheckStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.isTaskCompleteStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "stream" + }, + "metric_keys": [], + "name": "mastra-agent-stream-operation", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "agent_name": "Weather Agent", + "method": "stream" + }, + "metric_keys": [], + "name": "Mastra Agent Weather Agent stream", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "execution-workflow" + }, + "metric_keys": [], + "name": "Mastra Workflow execution-workflow start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-tools-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-memory-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.mapping_", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.stream-text-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "agentic-loop" + }, + "metric_keys": [], + "name": "Mastra Workflow agentic-loop start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "agentic-loop", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.agentic-loop.step.executionWorkflow", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "executionWorkflow" + }, + "metric_keys": [], + "name": "Mastra Workflow executionWorkflow start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.capture-response-count", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llm-execution", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.add-response-to-messagelist", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.map-tool-calls", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llmExecutionMappingStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.backgroundTaskCheckStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.isTaskCompleteStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "tool" + }, + "metric_keys": [], + "name": "mastra-tool-operation", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "tool_id": "lookup_weather" + }, + "metric_keys": [], + "name": "Mastra Tool lookup_weather", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "tool" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "workflow" + }, + "metric_keys": [], + "name": "mastra-workflow-operation", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "travel-flow" + }, + "metric_keys": [], + "name": "Mastra Workflow travel-flow start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "travel-flow", + "workflow_run_id": "workflow-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.travel-flow.step.lookup-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "tool_id": "lookup_weather", + "workflow_id": "travel-flow", + "workflow_run_id": "workflow-run-context" + }, + "metric_keys": [], + "name": "Mastra Tool lookup_weather", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "tool" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "scenario": "mastra-instrumentation" + }, + "metric_keys": [], + "name": "mastra-instrumentation-root", + "root_span_id": "", + "span_id": "", + "span_parents": [], + "type": "task" + } +] diff --git a/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1261-alpha0.log-payloads.json b/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1261-alpha0.log-payloads.json new file mode 100644 index 000000000..97a43fe9e --- /dev/null +++ b/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1261-alpha0.log-payloads.json @@ -0,0 +1,461 @@ +[ + { + "has_input": false, + "has_output": false, + "metadata": { + "scenario": "mastra-instrumentation" + }, + "metric_keys": [], + "name": "mastra-instrumentation-root", + "type": "task" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "generate" + }, + "metric_keys": [], + "name": "mastra-agent-generate-operation", + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "agent_name": "Weather Agent", + "method": "generate" + }, + "metric_keys": [], + "name": "Mastra Agent Weather Agent generate", + "type": "task" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "execution-workflow" + }, + "metric_keys": [], + "name": "Mastra Workflow execution-workflow start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-tools-step", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-memory-step", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.mapping_", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.stream-text-step", + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "agentic-loop" + }, + "metric_keys": [], + "name": "Mastra Workflow agentic-loop start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "agentic-loop", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.agentic-loop.step.executionWorkflow", + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "executionWorkflow" + }, + "metric_keys": [], + "name": "Mastra Workflow executionWorkflow start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.capture-response-count", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llm-execution", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.add-response-to-messagelist", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.map-tool-calls", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llmExecutionMappingStep", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.backgroundTaskCheckStep", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.isTaskCompleteStep", + "type": "function" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "stream" + }, + "metric_keys": [], + "name": "mastra-agent-stream-operation", + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "agent_name": "Weather Agent", + "method": "stream" + }, + "metric_keys": [], + "name": "Mastra Agent Weather Agent stream", + "type": "task" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "execution-workflow" + }, + "metric_keys": [], + "name": "Mastra Workflow execution-workflow start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-tools-step", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-memory-step", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.mapping_", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.stream-text-step", + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "agentic-loop" + }, + "metric_keys": [], + "name": "Mastra Workflow agentic-loop start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "agentic-loop", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.agentic-loop.step.executionWorkflow", + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "executionWorkflow" + }, + "metric_keys": [], + "name": "Mastra Workflow executionWorkflow start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.capture-response-count", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llm-execution", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.add-response-to-messagelist", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.map-tool-calls", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llmExecutionMappingStep", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.backgroundTaskCheckStep", + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.isTaskCompleteStep", + "type": "function" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "tool" + }, + "metric_keys": [], + "name": "mastra-tool-operation", + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "tool_id": "lookup_weather" + }, + "metric_keys": [], + "name": "Mastra Tool lookup_weather", + "type": "tool" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "workflow" + }, + "metric_keys": [], + "name": "mastra-workflow-operation", + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "travel-flow" + }, + "metric_keys": [], + "name": "Mastra Workflow travel-flow start", + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "travel-flow", + "workflow_run_id": "workflow-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.travel-flow.step.lookup-step", + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "tool_id": "lookup_weather", + "workflow_id": "travel-flow", + "workflow_run_id": "workflow-run-context" + }, + "metric_keys": [], + "name": "Mastra Tool lookup_weather", + "type": "tool" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "scenario": "mastra-instrumentation" + }, + "metric_keys": [], + "name": "mastra-instrumentation-root", + "type": "task" + } +] diff --git a/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1261-alpha0.span-events.json b/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1261-alpha0.span-events.json new file mode 100644 index 000000000..e696cc367 --- /dev/null +++ b/e2e/scenarios/mastra-instrumentation/__snapshots__/mastra-v1261-alpha0.span-events.json @@ -0,0 +1,667 @@ +[ + { + "has_input": false, + "has_output": false, + "metadata": { + "scenario": "mastra-instrumentation" + }, + "metric_keys": [], + "name": "mastra-instrumentation-root", + "root_span_id": "", + "span_id": "", + "span_parents": [], + "type": "task" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "generate" + }, + "metric_keys": [], + "name": "mastra-agent-generate-operation", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "agent_name": "Weather Agent", + "method": "generate" + }, + "metric_keys": [], + "name": "Mastra Agent Weather Agent generate", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "execution-workflow" + }, + "metric_keys": [], + "name": "Mastra Workflow execution-workflow start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-tools-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-memory-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.mapping_", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.stream-text-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "agentic-loop" + }, + "metric_keys": [], + "name": "Mastra Workflow agentic-loop start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "agentic-loop", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.agentic-loop.step.executionWorkflow", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "executionWorkflow" + }, + "metric_keys": [], + "name": "Mastra Workflow executionWorkflow start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.capture-response-count", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llm-execution", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.add-response-to-messagelist", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.map-tool-calls", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llmExecutionMappingStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.backgroundTaskCheckStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-generate-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.isTaskCompleteStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "stream" + }, + "metric_keys": [], + "name": "mastra-agent-stream-operation", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "agent_name": "Weather Agent", + "method": "stream" + }, + "metric_keys": [], + "name": "Mastra Agent Weather Agent stream", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "execution-workflow" + }, + "metric_keys": [], + "name": "Mastra Workflow execution-workflow start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-tools-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.prepare-memory-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.mapping_", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "execution-workflow", + "workflow_run_id": "" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.execution-workflow.step.stream-text-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "agentic-loop" + }, + "metric_keys": [], + "name": "Mastra Workflow agentic-loop start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "agentic-loop", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.agentic-loop.step.executionWorkflow", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "executionWorkflow" + }, + "metric_keys": [], + "name": "Mastra Workflow executionWorkflow start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.capture-response-count", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llm-execution", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.add-response-to-messagelist", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.map-tool-calls", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.llmExecutionMappingStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.backgroundTaskCheckStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "executionWorkflow", + "workflow_run_id": "agent-stream-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.executionWorkflow.step.isTaskCompleteStep", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "tool" + }, + "metric_keys": [], + "name": "mastra-tool-operation", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "agent_id": "weather-agent", + "tool_id": "lookup_weather" + }, + "metric_keys": [], + "name": "Mastra Tool lookup_weather", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "tool" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "operation": "workflow" + }, + "metric_keys": [], + "name": "mastra-workflow-operation", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": null + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "method": "start", + "workflow_id": "travel-flow" + }, + "metric_keys": [], + "name": "Mastra Workflow travel-flow start", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "task" + }, + { + "has_input": false, + "has_output": true, + "metadata": { + "workflow_id": "travel-flow", + "workflow_run_id": "workflow-run" + }, + "metric_keys": [], + "name": "Mastra Workflow Step workflow.travel-flow.step.lookup-step", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "function" + }, + { + "has_input": true, + "has_output": true, + "metadata": { + "tool_id": "lookup_weather", + "workflow_id": "travel-flow", + "workflow_run_id": "workflow-run-context" + }, + "metric_keys": [], + "name": "Mastra Tool lookup_weather", + "root_span_id": "", + "span_id": "", + "span_parents": [ + "" + ], + "type": "tool" + }, + { + "has_input": false, + "has_output": false, + "metadata": { + "scenario": "mastra-instrumentation" + }, + "metric_keys": [], + "name": "mastra-instrumentation-root", + "root_span_id": "", + "span_id": "", + "span_parents": [], + "type": "task" + } +] diff --git a/e2e/scenarios/mastra-instrumentation/package.json b/e2e/scenarios/mastra-instrumentation/package.json new file mode 100644 index 000000000..ffffa9758 --- /dev/null +++ b/e2e/scenarios/mastra-instrumentation/package.json @@ -0,0 +1,15 @@ +{ + "name": "@braintrust/e2e-mastra-instrumentation", + "private": true, + "braintrustScenario": { + "canary": { + "dependencies": { + "@mastra/core": "@mastra/core@1.26.1-alpha.0" + } + } + }, + "dependencies": { + "@mastra/core": "1.26.0", + "zod": "4.3.6" + } +} diff --git a/e2e/scenarios/mastra-instrumentation/pnpm-lock.yaml b/e2e/scenarios/mastra-instrumentation/pnpm-lock.yaml new file mode 100644 index 000000000..e5c2000ac --- /dev/null +++ b/e2e/scenarios/mastra-instrumentation/pnpm-lock.yaml @@ -0,0 +1,2405 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@mastra/core': + specifier: 1.26.0 + version: 1.26.0(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6))(@types/json-schema@7.0.15)(openapi-types@12.1.3)(zod@4.3.6) + zod: + specifier: 4.3.6 + version: 4.3.6 + +packages: + + '@a2a-js/sdk@0.2.5': + resolution: {integrity: sha512-VTDuRS5V0ATbJ/LkaQlisMnTAeYKXAK6scMguVBstf+KIBQ7HIuKhiXLv+G/hvejkV+THoXzoNifInAkU81P1g==} + engines: {node: '>=18'} + + '@ai-sdk/provider-utils@2.2.8': + resolution: {integrity: sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.23.8 + + '@ai-sdk/provider-utils@3.0.23': + resolution: {integrity: sha512-60GYsRj5wIJQRcq5YwYJq4KhwLeStceXEJiZdecP1miiH+6FMmrnc7lZDOJoQ6m9lrudEb+uI4LEwddLz5+rPQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@4.0.23': + resolution: {integrity: sha512-z8GlDaCmRSDlqkMF2f4/RFgWxdarvIbyuk+m6WXT1LYgsnGiXRJGTD2Z1+SDl3LqtFuRtGX1aghYvQLoHL/9pg==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider@1.1.3': + resolution: {integrity: sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==} + engines: {node: '>=18'} + + '@ai-sdk/provider@2.0.1': + resolution: {integrity: sha512-KCUwswvsC5VsW2PWFqF8eJgSCu5Ysj7m1TxiHTVA6g7k360bk0RNQENT8KTMAYEs+8fWPD3Uu4dEmzGHc+jGng==} + engines: {node: '>=18'} + + '@ai-sdk/provider@3.0.8': + resolution: {integrity: sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==} + engines: {node: '>=18'} + + '@ai-sdk/ui-utils@1.2.11': + resolution: {integrity: sha512-3zcwCc8ezzFlwp3ZD15wAPjf2Au4s3vAbKsXQVyhxODHcmu0iyPO2Eua6D/vicq/AUm/BAo60r97O6HU+EI0+w==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.23.8 + + '@hono/node-server@1.19.14': + resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + + '@isaacs/ttlcache@2.1.4': + resolution: {integrity: sha512-7kMz0BJpMvgAMkyglums7B2vtrn5g0a0am77JY0GjkZZNetOBCFn7AG7gKCwT0QPiXyxW7YIQSgtARknUEOcxQ==} + engines: {node: '>=12'} + + '@lukeed/csprng@1.1.0': + resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} + engines: {node: '>=8'} + + '@lukeed/uuid@2.0.1': + resolution: {integrity: sha512-qC72D4+CDdjGqJvkFMMEAtancHUQ7/d/tAiHf64z8MopFDmcrtbcJuerDtFceuAfQJ2pDSfCKCtbqoGBNnwg0w==} + engines: {node: '>=8'} + + '@mastra/core@1.26.0': + resolution: {integrity: sha512-LHedxFSSpM+yEdTq7l5XeM6ZaBlHjlaSoDIDkFTnM15lcvjWNajkV8sFtEn+Gq5TB0sghyw2n8IObYlHtr0wBA==} + engines: {node: '>=22.13.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + '@mastra/schema-compat@1.2.9': + resolution: {integrity: sha512-1/RgazXqi1Wdyx8aR81CVS+sRyzlTGUL1YhhHkSULoEY8aXs58bvWkH/6iixlYsY0xGvn+0OPLCeSRkBCtDx4Q==} + engines: {node: '>=22.13.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + '@modelcontextprotocol/sdk@1.29.0': + resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@sindresorhus/slugify@2.2.1': + resolution: {integrity: sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==} + engines: {node: '>=12'} + + '@sindresorhus/transliterate@1.6.0': + resolution: {integrity: sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==} + engines: {node: '>=12'} + + '@standard-community/standard-json@0.3.5': + resolution: {integrity: sha512-4+ZPorwDRt47i+O7RjyuaxHRK/37QY/LmgxlGrRrSTLYoFatEOzvqIc85GTlM18SFZ5E91C+v0o/M37wZPpUHA==} + peerDependencies: + '@standard-schema/spec': ^1.0.0 + '@types/json-schema': ^7.0.15 + '@valibot/to-json-schema': ^1.3.0 + arktype: ^2.1.20 + effect: ^3.16.8 + quansync: ^0.2.11 + sury: ^10.0.0 + typebox: ^1.0.17 + valibot: ^1.1.0 + zod: ^3.25.0 || ^4.0.0 + zod-to-json-schema: ^3.24.5 + peerDependenciesMeta: + '@valibot/to-json-schema': + optional: true + arktype: + optional: true + effect: + optional: true + sury: + optional: true + typebox: + optional: true + valibot: + optional: true + zod: + optional: true + zod-to-json-schema: + optional: true + + '@standard-community/standard-openapi@0.2.9': + resolution: {integrity: sha512-htj+yldvN1XncyZi4rehbf9kLbu8os2Ke/rfqoZHCMHuw34kiF3LP/yQPdA0tQ940y8nDq3Iou8R3wG+AGGyvg==} + peerDependencies: + '@standard-community/standard-json': ^0.3.5 + '@standard-schema/spec': ^1.0.0 + arktype: ^2.1.20 + effect: ^3.17.14 + openapi-types: ^12.1.3 + sury: ^10.0.0 + typebox: ^1.0.0 + valibot: ^1.1.0 + zod: ^3.25.0 || ^4.0.0 + zod-openapi: ^4 + peerDependenciesMeta: + arktype: + optional: true + effect: + optional: true + sury: + optional: true + typebox: + optional: true + valibot: + optional: true + zod: + optional: true + zod-openapi: + optional: true + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/cors@2.8.19': + resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/express-serve-static-core@4.19.8': + resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} + + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} + + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@25.6.0': + resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} + + '@types/qs@6.15.0': + resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@workflow/serde@4.1.0-beta.2': + resolution: {integrity: sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + engines: {node: '>=18'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + chat@4.26.0: + resolution: {integrity: sha512-QToDnIEGpyb8yQA6YLMHOSRK30YVk4RtsyFyuWFYyB2c4jQlyIrSWtwVK7qyvmvqzQp9uDwCdJRAhS8GtCHAGQ==} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-disposition@1.1.0: + resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventsource-parser@3.0.8: + resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} + engines: {node: ^18.19.0 || >=20.5.0} + + express-rate-limit@8.4.0: + resolution: {integrity: sha512-gDK8yiqKxrGta+3WtON59arrrw6GLmadA1qoFgYXzdcch8fmKDID2XqO8itsi3f1wufXYPT51387dN6cvVBS3Q==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + engines: {node: '>= 0.10.0'} + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} + + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + engines: {node: '>= 0.4'} + + hono-openapi@1.3.0: + resolution: {integrity: sha512-xDvCWpWEIv0weEmnl3EjRQzqbHIO8LnfzMuYOCmbuyE5aes6aXxLg4vM3ybnoZD5TiTUkA6PuRQPJs3R7WRBig==} + peerDependencies: + '@hono/standard-validator': ^0.2.0 + '@standard-community/standard-json': ^0.3.5 + '@standard-community/standard-openapi': ^0.2.9 + '@types/json-schema': ^7.0.15 + hono: ^4.8.3 + openapi-types: ^12.1.3 + peerDependenciesMeta: + '@hono/standard-validator': + optional: true + hono: + optional: true + + hono@4.12.14: + resolution: {integrity: sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==} + engines: {node: '>=16.9.0'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-network-error@1.3.1: + resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} + engines: {node: '>=16'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jose@6.2.2: + resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} + + js-tiktoken@1.0.21: + resolution: {integrity: sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + json-schema-to-zod@2.8.1: + resolution: {integrity: sha512-fRr1mHgZ7hboLKBUdR428gd9dIHUFGivUqOeiDcSmyXkNZCtB1uGaZLvsjZ4GaN5pwBIs+TGIOf6s+Rp5/R/zA==} + hasBin: true + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + lru-cache@11.3.5: + resolution: {integrity: sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==} + engines: {node: 20 || >=22} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} + engines: {node: '>=18'} + + p-retry@7.1.1: + resolution: {integrity: sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w==} + engines: {node: '>=20'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-to-regexp@0.1.13: + resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} + + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + + pretty-ms@9.3.0: + resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} + engines: {node: '>=18'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + qs@6.14.2: + resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} + engines: {node: '>=0.6'} + + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} + engines: {node: '>=0.6'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + radash@12.1.1: + resolution: {integrity: sha512-h36JMxKRqrAxVD8201FrCpyeNuUY9Y5zZwujr20fFO77tpUtGa6EZzfKw/3WaiBX95fq7+MpsuMLNdSnORAwSA==} + engines: {node: '>=14.18.0'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remend@1.3.0: + resolution: {integrity: sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw==} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tokenx@1.3.0: + resolution: {integrity: sha512-NLdXTEZkKiO0gZuLtMoZKjCXTREXeZZt8nnnNeyoXtNZAfG/GKGSbQtLU5STspc0rMSwcA+UJfWZkbNU01iKmQ==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + + undici-types@7.19.2: + resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xxhash-wasm@1.1.0: + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + + zod-from-json-schema@0.0.5: + resolution: {integrity: sha512-zYEoo86M1qpA1Pq6329oSyHLS785z/mTwfr9V1Xf/ZLhuuBGaMlDGu/pDVGVUe4H4oa1EFgWZT53DP0U3oT9CQ==} + + zod-from-json-schema@0.5.2: + resolution: {integrity: sha512-/dNaicfdhJTOuUd4RImbLUE2g5yrSzzDjI/S6C2vO2ecAGZzn9UcRVgtyLSnENSmAOBRiSpUdzDS6fDWX3Z35g==} + + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: ^3.25.28 || ^4 + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@a2a-js/sdk@0.2.5': + dependencies: + '@types/cors': 2.8.19 + '@types/express': 4.17.25 + body-parser: 2.2.2 + cors: 2.8.6 + express: 4.22.1 + uuid: 11.1.0 + transitivePeerDependencies: + - supports-color + + '@ai-sdk/provider-utils@2.2.8(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 1.1.3 + nanoid: 3.3.11 + secure-json-parse: 2.7.0 + zod: 4.3.6 + + '@ai-sdk/provider-utils@3.0.23(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 2.0.1 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.0.8 + zod: 4.3.6 + + '@ai-sdk/provider-utils@4.0.23(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.0.8 + zod: 4.3.6 + + '@ai-sdk/provider@1.1.3': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/provider@2.0.1': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/provider@3.0.8': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/ui-utils@1.2.11(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 1.1.3 + '@ai-sdk/provider-utils': 2.2.8(zod@4.3.6) + zod: 4.3.6 + zod-to-json-schema: 3.25.2(zod@4.3.6) + + '@hono/node-server@1.19.14(hono@4.12.14)': + dependencies: + hono: 4.12.14 + + '@isaacs/ttlcache@2.1.4': {} + + '@lukeed/csprng@1.1.0': {} + + '@lukeed/uuid@2.0.1': + dependencies: + '@lukeed/csprng': 1.1.0 + + '@mastra/core@1.26.0(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6))(@types/json-schema@7.0.15)(openapi-types@12.1.3)(zod@4.3.6)': + dependencies: + '@a2a-js/sdk': 0.2.5 + '@ai-sdk/provider-utils-v5': '@ai-sdk/provider-utils@3.0.23(zod@4.3.6)' + '@ai-sdk/provider-utils-v6': '@ai-sdk/provider-utils@4.0.23(zod@4.3.6)' + '@ai-sdk/provider-v5': '@ai-sdk/provider@2.0.1' + '@ai-sdk/provider-v6': '@ai-sdk/provider@3.0.8' + '@ai-sdk/ui-utils-v5': '@ai-sdk/ui-utils@1.2.11(zod@4.3.6)' + '@isaacs/ttlcache': 2.1.4 + '@lukeed/uuid': 2.0.1 + '@mastra/schema-compat': 1.2.9(zod@4.3.6) + '@modelcontextprotocol/sdk': 1.29.0(zod@4.3.6) + '@sindresorhus/slugify': 2.2.1 + '@standard-schema/spec': 1.1.0 + ajv: 8.18.0 + chat: 4.26.0 + dotenv: 17.4.2 + execa: 9.6.1 + gray-matter: 4.0.3 + hono: 4.12.14 + hono-openapi: 1.3.0(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6))(@types/json-schema@7.0.15)(hono@4.12.14)(openapi-types@12.1.3) + ignore: 7.0.5 + js-tiktoken: 1.0.21 + json-schema: 0.4.0 + lru-cache: 11.3.5 + p-map: 7.0.4 + p-retry: 7.1.1 + picomatch: 4.0.4 + radash: 12.1.1 + tokenx: 1.3.0 + ws: 8.20.0 + xxhash-wasm: 1.1.0 + zod: 4.3.6 + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@hono/standard-validator' + - '@standard-community/standard-json' + - '@standard-community/standard-openapi' + - '@types/json-schema' + - bufferutil + - openapi-types + - supports-color + - utf-8-validate + + '@mastra/schema-compat@1.2.9(zod@4.3.6)': + dependencies: + json-schema-to-zod: 2.8.1 + zod: 4.3.6 + zod-from-json-schema: 0.5.2 + zod-from-json-schema-v3: zod-from-json-schema@0.0.5 + zod-to-json-schema: 3.25.2(zod@4.3.6) + + '@modelcontextprotocol/sdk@1.29.0(zod@4.3.6)': + dependencies: + '@hono/node-server': 1.19.14(hono@4.12.14) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.8 + express: 5.2.1 + express-rate-limit: 8.4.0(express@5.2.1) + hono: 4.12.14 + jose: 6.2.2 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.3.6 + zod-to-json-schema: 3.25.2(zod@4.3.6) + transitivePeerDependencies: + - supports-color + + '@sec-ant/readable-stream@0.4.1': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@sindresorhus/slugify@2.2.1': + dependencies: + '@sindresorhus/transliterate': 1.6.0 + escape-string-regexp: 5.0.0 + + '@sindresorhus/transliterate@1.6.0': + dependencies: + escape-string-regexp: 5.0.0 + + '@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6)': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/json-schema': 7.0.15 + quansync: 0.2.11 + optionalDependencies: + zod: 4.3.6 + zod-to-json-schema: 3.25.2(zod@4.3.6) + + '@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6)': + dependencies: + '@standard-community/standard-json': 0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6) + '@standard-schema/spec': 1.1.0 + openapi-types: 12.1.3 + optionalDependencies: + zod: 4.3.6 + + '@standard-schema/spec@1.1.0': {} + + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 25.6.0 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 25.6.0 + + '@types/cors@2.8.19': + dependencies: + '@types/node': 25.6.0 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/express-serve-static-core@4.19.8': + dependencies: + '@types/node': 25.6.0 + '@types/qs': 6.15.0 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@4.17.25': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.8 + '@types/qs': 6.15.0 + '@types/serve-static': 1.15.10 + + '@types/http-errors@2.0.5': {} + + '@types/json-schema@7.0.15': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mime@1.3.5': {} + + '@types/ms@2.1.0': {} + + '@types/node@25.6.0': + dependencies: + undici-types: 7.19.2 + + '@types/qs@6.15.0': {} + + '@types/range-parser@1.2.7': {} + + '@types/send@0.17.6': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 25.6.0 + + '@types/send@1.2.1': + dependencies: + '@types/node': 25.6.0 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 25.6.0 + '@types/send': 0.17.6 + + '@types/unist@3.0.3': {} + + '@workflow/serde@4.1.0-beta.2': {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + array-flatten@1.1.1: {} + + bail@2.0.2: {} + + base64-js@1.5.1: {} + + body-parser@1.20.4: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.14.2 + raw-body: 2.5.3 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + body-parser@2.2.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + on-finished: 2.4.1 + qs: 6.15.1 + raw-body: 3.0.2 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + + bytes@3.1.2: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + ccount@2.0.1: {} + + character-entities@2.0.2: {} + + chat@4.26.0: + dependencies: + '@workflow/serde': 4.1.0-beta.2 + mdast-util-to-string: 4.0.0 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + remend: 1.3.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-disposition@1.1.0: {} + + content-type@1.0.5: {} + + cookie-signature@1.0.7: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + depd@2.0.0: {} + + dequal@2.0.3: {} + + destroy@1.2.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dotenv@17.4.2: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ee-first@1.1.1: {} + + encodeurl@2.0.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + escape-html@1.0.3: {} + + escape-string-regexp@5.0.0: {} + + esprima@4.0.1: {} + + etag@1.8.1: {} + + eventsource-parser@3.0.8: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.8 + + execa@9.6.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.3.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.2 + + express-rate-limit@8.4.0(express@5.2.1): + dependencies: + express: 5.2.1 + ip-address: 10.1.0 + + express@4.22.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.4 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2 + fresh: 0.5.2 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.13 + proxy-addr: 2.0.7 + qs: 6.14.2 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2 + serve-static: 1.16.3 + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.2 + content-disposition: 1.1.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.15.1 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-uri@3.1.0: {} + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + + finalhandler@1.3.2: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + fresh@2.0.0: {} + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + gopd@1.2.0: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.2 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + has-symbols@1.1.0: {} + + hasown@2.0.3: + dependencies: + function-bind: 1.1.2 + + hono-openapi@1.3.0(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6))(@types/json-schema@7.0.15)(hono@4.12.14)(openapi-types@12.1.3): + dependencies: + '@standard-community/standard-json': 0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6) + '@standard-community/standard-openapi': 0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6) + '@types/json-schema': 7.0.15 + openapi-types: 12.1.3 + optionalDependencies: + hono: 4.12.14 + + hono@4.12.14: {} + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + human-signals@8.0.1: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ignore@7.0.5: {} + + inherits@2.0.4: {} + + ip-address@10.1.0: {} + + ipaddr.js@1.9.1: {} + + is-extendable@0.1.1: {} + + is-network-error@1.3.1: {} + + is-plain-obj@4.1.0: {} + + is-promise@4.0.0: {} + + is-stream@4.0.1: {} + + is-unicode-supported@2.1.0: {} + + isexe@2.0.0: {} + + jose@6.2.2: {} + + js-tiktoken@1.0.21: + dependencies: + base64-js: 1.5.1 + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + json-schema-to-zod@2.8.1: {} + + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + + json-schema@0.4.0: {} + + kind-of@6.0.3: {} + + longest-streak@3.1.0: {} + + lru-cache@11.3.5: {} + + markdown-table@3.0.4: {} + + math-intrinsics@1.1.0: {} + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + media-typer@0.3.0: {} + + media-typer@1.1.0: {} + + merge-descriptors@1.0.3: {} + + merge-descriptors@2.0.0: {} + + methods@1.1.2: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mime@1.6.0: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + negotiator@0.6.3: {} + + negotiator@1.0.0: {} + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + openapi-types@12.1.3: {} + + p-map@7.0.4: {} + + p-retry@7.1.1: + dependencies: + is-network-error: 1.3.1 + + parse-ms@4.0.0: {} + + parseurl@1.3.3: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-to-regexp@0.1.13: {} + + path-to-regexp@8.4.2: {} + + picomatch@4.0.4: {} + + pkce-challenge@5.0.1: {} + + pretty-ms@9.3.0: + dependencies: + parse-ms: 4.0.0 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + qs@6.14.2: + dependencies: + side-channel: 1.1.0 + + qs@6.15.1: + dependencies: + side-channel: 1.1.0 + + quansync@0.2.11: {} + + radash@12.1.1: {} + + range-parser@1.2.1: {} + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + unpipe: 1.0.0 + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + remend@1.3.0: {} + + require-from-string@2.0.2: {} + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.4.2 + transitivePeerDependencies: + - supports-color + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + secure-json-parse@2.7.0: {} + + send@0.19.2: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.3: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@4.1.0: {} + + sprintf-js@1.0.3: {} + + statuses@2.0.2: {} + + strip-bom-string@1.0.0: {} + + strip-final-newline@4.0.0: {} + + toidentifier@1.0.1: {} + + tokenx@1.3.0: {} + + trough@2.2.0: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2 + + undici-types@7.19.2: {} + + unicorn-magic@0.3.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + unpipe@1.0.0: {} + + utils-merge@1.0.1: {} + + uuid@11.1.0: {} + + vary@1.1.2: {} + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrappy@1.0.2: {} + + ws@8.20.0: {} + + xxhash-wasm@1.1.0: {} + + yoctocolors@2.1.2: {} + + zod-from-json-schema@0.0.5: + dependencies: + zod: 3.25.76 + + zod-from-json-schema@0.5.2: + dependencies: + zod: 4.3.6 + + zod-to-json-schema@3.25.2(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@3.25.76: {} + + zod@4.3.6: {} + + zwitch@2.0.4: {} diff --git a/e2e/scenarios/mastra-instrumentation/scenario.mjs b/e2e/scenarios/mastra-instrumentation/scenario.mjs new file mode 100644 index 000000000..6964b9ee7 --- /dev/null +++ b/e2e/scenarios/mastra-instrumentation/scenario.mjs @@ -0,0 +1,125 @@ +import { Agent } from "@mastra/core/agent"; +import { createMockModel } from "@mastra/core/test-utils/llm-mock"; +import { createTool } from "@mastra/core/tools"; +import { createStep, createWorkflow } from "@mastra/core/workflows"; +import { z } from "zod"; +import { + runMain, + runOperation, + runTracedScenario, +} from "../../helpers/provider-runtime.mjs"; + +export const ROOT_NAME = "mastra-instrumentation-root"; +export const SCENARIO_NAME = "mastra-instrumentation"; + +const weatherTool = createTool({ + id: "lookup_weather", + description: "Look up a deterministic weather forecast.", + inputSchema: z.object({ + city: z.string(), + }), + outputSchema: z.object({ + forecast: z.string(), + }), + execute: async ({ city }) => ({ + forecast: `Sunny in ${city}`, + }), +}); + +const weatherAgent = new Agent({ + id: "weather-agent", + name: "Weather Agent", + instructions: "Answer weather questions with the provided mock forecast.", + model: createMockModel({ + mockText: "The forecast is sunny.", + }), +}); + +const lookupStep = createStep({ + id: "lookup-step", + inputSchema: z.object({ + city: z.string(), + }), + outputSchema: z.object({ + forecast: z.string(), + }), + execute: async ({ inputData }) => + weatherTool.execute(inputData, { + workflow: { + workflowId: "travel-flow", + runId: "workflow-run-context", + }, + }), +}); + +const travelWorkflow = createWorkflow({ + id: "travel-flow", + inputSchema: z.object({ + city: z.string(), + }), + outputSchema: z.object({ + forecast: z.string(), + }), +}) + .then(lookupStep) + .commit(); + +async function runMastraInstrumentationScenario() { + await runTracedScenario({ + callback: async () => { + await runOperation("mastra-agent-generate-operation", "generate", () => + weatherAgent.generate("What is the weather in Paris?", { + runId: "agent-generate-run", + resourceId: "weather-user", + }), + ); + + await runOperation( + "mastra-agent-stream-operation", + "stream", + async () => { + const result = await weatherAgent.stream( + "Stream the Paris forecast.", + { + runId: "agent-stream-run", + resourceId: "weather-user", + }, + ); + for await (const _chunk of result.textStream) { + } + }, + ); + + await runOperation("mastra-tool-operation", "tool", () => + weatherTool.execute( + { city: "Paris" }, + { + agent: { + agentId: "weather-agent", + resourceId: "weather-user", + toolCallId: "manual-tool-call", + }, + }, + ), + ); + + await runOperation("mastra-workflow-operation", "workflow", async () => { + const run = await travelWorkflow.createRun({ + runId: "workflow-run", + }); + await run.start({ + inputData: { + city: "Berlin", + }, + }); + }); + }, + metadata: { + scenario: SCENARIO_NAME, + }, + projectNameBase: "e2e-mastra-instrumentation", + rootName: ROOT_NAME, + }); +} + +runMain(runMastraInstrumentationScenario); diff --git a/e2e/scenarios/mastra-instrumentation/scenario.test.ts b/e2e/scenarios/mastra-instrumentation/scenario.test.ts new file mode 100644 index 000000000..d42bf940e --- /dev/null +++ b/e2e/scenarios/mastra-instrumentation/scenario.test.ts @@ -0,0 +1,207 @@ +import { beforeAll, describe, expect, test } from "vitest"; +import { + formatJsonFileSnapshot, + resolveFileSnapshotPath, +} from "../../helpers/file-snapshot"; +import { normalizeForSnapshot, type Json } from "../../helpers/normalize"; +import type { CapturedLogEvent } from "../../helpers/mock-braintrust-server"; +import { + prepareScenarioDir, + readInstalledPackageVersion, + resolveScenarioDir, + withScenarioHarness, +} from "../../helpers/scenario-harness"; +import { findLatestSpan } from "../../helpers/trace-selectors"; +import { summarizeWrapperContract } from "../../helpers/wrapper-contract"; + +const scenarioDir = await prepareScenarioDir({ + scenarioDir: resolveScenarioDir(import.meta.url), +}); +const mastraVersion = await readInstalledPackageVersion( + scenarioDir, + "@mastra/core", +); +const snapshotName = resolveSnapshotName(mastraVersion); +const TIMEOUT_MS = 90_000; +const ROOT_NAME = "mastra-instrumentation-root"; +const SCENARIO_NAME = "mastra-instrumentation"; + +const SNAPSHOT_METADATA_KEYS = [ + "agent_id", + "agent_name", + "method", + "operation", + "scenario", + "tool_id", + "workflow_id", + "workflow_run_id", +]; + +function relevantMastraEvents(events: CapturedLogEvent[]): CapturedLogEvent[] { + return events.filter( + (event) => + event.span.name === ROOT_NAME || + event.span.name?.startsWith("mastra-") || + event.span.name?.startsWith("Mastra ") || + event.span.type === "llm", + ); +} + +function summarizeMastraPayload(event: CapturedLogEvent): Json { + const metadata = event.row.metadata as Record | undefined; + const pickedMetadata = Object.fromEntries( + SNAPSHOT_METADATA_KEYS.flatMap((key) => + metadata && key in metadata ? [[key, metadata[key] as Json]] : [], + ), + ); + + return { + has_input: event.input !== undefined && event.input !== null, + has_output: event.output !== undefined && event.output !== null, + metadata: + Object.keys(pickedMetadata).length > 0 ? (pickedMetadata as Json) : null, + metric_keys: Object.keys(event.metrics ?? {}) + .filter((key) => key !== "start" && key !== "end") + .sort(), + name: event.span.name ?? null, + type: event.span.type ?? null, + } satisfies Json; +} + +function resolveSnapshotName(version: string): string { + switch (version) { + case "1.26.0": + return "mastra-v1260"; + case "1.26.1-alpha.0": + return "mastra-v1261-alpha0"; + default: + throw new Error( + `Unsupported @mastra/core version for e2e snapshots: ${version}`, + ); + } +} + +describe(`mastra sdk ${mastraVersion} auto-hook instrumentation`, () => { + let events: CapturedLogEvent[] = []; + + beforeAll(async () => { + await withScenarioHarness(async (harness) => { + await harness.runNodeScenarioDir({ + entry: "scenario.mjs", + nodeArgs: ["--import", "braintrust/hook.mjs"], + runContext: { variantKey: snapshotName }, + scenarioDir, + timeoutMs: TIMEOUT_MS, + }); + events = harness.events(); + }); + }, TIMEOUT_MS); + + test("captures the root trace for the scenario", () => { + const root = findLatestSpan(events, ROOT_NAME); + + expect(root).toBeDefined(); + expect(root?.row.metadata).toMatchObject({ + scenario: SCENARIO_NAME, + }); + }); + + test("captures agent generate and stream spans", () => { + expect( + findLatestSpan(events, "Mastra Agent Weather Agent generate"), + ).toBeDefined(); + expect( + findLatestSpan(events, "Mastra Agent Weather Agent stream"), + ).toBeDefined(); + }); + + test("captures direct and workflow-nested tool spans", () => { + const toolSpans = events.filter( + (event) => + event.span.name === "Mastra Tool lookup_weather" && + event.output !== undefined, + ); + + expect(toolSpans.length).toBeGreaterThanOrEqual(2); + expect( + toolSpans.some( + (event) => + event.row.metadata?.workflow_id === "travel-flow" && + event.row.metadata?.workflow_run_id === "workflow-run-context", + ), + ).toBe(true); + }); + + test("captures workflow run and step spans", () => { + expect( + findLatestSpan(events, "Mastra Workflow travel-flow start"), + ).toBeDefined(); + expect( + findLatestSpan( + events, + "Mastra Workflow Step workflow.travel-flow.step.lookup-step", + ), + ).toBeDefined(); + }); + + test("nests the workflow tool under the workflow step", () => { + const stepSpan = findLatestSpan( + events, + "Mastra Workflow Step workflow.travel-flow.step.lookup-step", + ); + const nestedTool = events.find( + (event) => + event.span.name === "Mastra Tool lookup_weather" && + event.row.metadata?.workflow_run_id === "workflow-run-context" && + event.span.parentIds.includes(stepSpan?.span.id ?? ""), + ); + + expect(stepSpan).toBeDefined(); + expect(nestedTool).toBeDefined(); + }); + + test("captures nested Mastra execution workflow spans during agent execution", () => { + const generateSpan = findLatestSpan( + events, + "Mastra Agent Weather Agent generate", + ); + const nestedExecutionWorkflow = events.find( + (event) => + event.span.name === "Mastra Workflow execution-workflow start" && + event.span.parentIds.includes(generateSpan?.span.id ?? ""), + ); + + expect(generateSpan).toBeDefined(); + expect(nestedExecutionWorkflow).toBeDefined(); + }); + + test("matches the shared span snapshot", async () => { + const spanSummary = normalizeForSnapshot( + relevantMastraEvents(events).map((event) => + summarizeWrapperContract(event, SNAPSHOT_METADATA_KEYS), + ) as Json, + ); + + await expect(formatJsonFileSnapshot(spanSummary)).toMatchFileSnapshot( + resolveFileSnapshotPath( + import.meta.url, + `${snapshotName}.span-events.json`, + ), + ); + }); + + test("matches the shared payload snapshot", async () => { + const payloadSummary = normalizeForSnapshot( + relevantMastraEvents(events).map((event) => + summarizeMastraPayload(event), + ) as Json, + ); + + await expect(formatJsonFileSnapshot(payloadSummary)).toMatchFileSnapshot( + resolveFileSnapshotPath( + import.meta.url, + `${snapshotName}.log-payloads.json`, + ), + ); + }); +}); diff --git a/js/src/auto-instrumentations/bundler/plugin.ts b/js/src/auto-instrumentations/bundler/plugin.ts index 3202d3dbc..506c65847 100644 --- a/js/src/auto-instrumentations/bundler/plugin.ts +++ b/js/src/auto-instrumentations/bundler/plugin.ts @@ -12,14 +12,12 @@ */ import { createUnplugin } from "unplugin"; -import { - create, - type InstrumentationConfig, -} from "@apm-js-collab/code-transformer"; +import { type InstrumentationConfig } from "@apm-js-collab/code-transformer"; import { extname, join, sep } from "path"; import { readFileSync } from "fs"; import { fileURLToPath } from "url"; import moduleDetailsFromPath from "module-details-from-path"; +import { createInstrumentationMatcher } from "../custom-transforms"; import { openaiConfigs } from "../configs/openai"; import { anthropicConfigs } from "../configs/anthropic"; import { aiSDKConfigs } from "../configs/ai-sdk"; @@ -31,6 +29,7 @@ import { openRouterConfigs } from "../configs/openrouter"; import { mistralConfigs } from "../configs/mistral"; import { cohereConfigs } from "../configs/cohere"; import { groqConfigs } from "../configs/groq"; +import { mastraConfigs } from "../configs/mastra"; export interface BundlerPluginOptions { /** @@ -83,6 +82,7 @@ export const unplugin = createUnplugin((options = {}) => { ...mistralConfigs, ...cohereConfigs, ...groqConfigs, + ...mastraConfigs, ...(options.instrumentations || []), ]; @@ -90,7 +90,10 @@ export const unplugin = createUnplugin((options = {}) => { const dcModule = options.browser === false ? undefined : "dc-browser"; // Create the code transformer instrumentor - const instrumentationMatcher = create(allInstrumentations, dcModule); + const instrumentationMatcher = createInstrumentationMatcher( + allInstrumentations, + dcModule, + ); return { name: "code-transformer", diff --git a/js/src/auto-instrumentations/bundler/webpack-loader.ts b/js/src/auto-instrumentations/bundler/webpack-loader.ts index 5d6c7e20b..b762aa2e7 100644 --- a/js/src/auto-instrumentations/bundler/webpack-loader.ts +++ b/js/src/auto-instrumentations/bundler/webpack-loader.ts @@ -22,13 +22,13 @@ */ import { - create, type InstrumentationMatcher, type ModuleType, } from "@apm-js-collab/code-transformer"; import { extname, join, sep } from "path"; import { readFileSync } from "fs"; import moduleDetailsFromPath from "module-details-from-path"; +import { createInstrumentationMatcher } from "../custom-transforms"; import { openaiConfigs } from "../configs/openai"; import { anthropicConfigs } from "../configs/anthropic"; import { aiSDKConfigs } from "../configs/ai-sdk"; @@ -40,6 +40,7 @@ import { openRouterConfigs } from "../configs/openrouter"; import { mistralConfigs } from "../configs/mistral"; import { cohereConfigs } from "../configs/cohere"; import { groqConfigs } from "../configs/groq"; +import { mastraConfigs } from "../configs/mastra"; import { type BundlerPluginOptions } from "./plugin"; /** @@ -78,6 +79,7 @@ function getMatcher(options: BundlerPluginOptions): InstrumentationMatcher { ...mistralConfigs, ...cohereConfigs, ...groqConfigs, + ...mastraConfigs, ...(options.instrumentations ?? []), ]; const dcModule = options.browser ? "dc-browser" : undefined; @@ -95,7 +97,7 @@ function getMatcher(options: BundlerPluginOptions): InstrumentationMatcher { } } - const matcher = create(allInstrumentations, dcModule ?? null); + const matcher = createInstrumentationMatcher(allInstrumentations, dcModule); matcherCache.set(configHash, matcher); return matcher; } diff --git a/js/src/auto-instrumentations/configs/mastra.test.ts b/js/src/auto-instrumentations/configs/mastra.test.ts new file mode 100644 index 000000000..bf9ae4cac --- /dev/null +++ b/js/src/auto-instrumentations/configs/mastra.test.ts @@ -0,0 +1,186 @@ +import { createRequire } from "node:module"; +import { describe, expect, it } from "vitest"; +import { mastraChannels } from "../../instrumentation/plugins/mastra-channels"; +import { + createEventCollector, + runAndCollectEvents, +} from "../../../tests/auto-instrumentations/test-helpers"; +import { createInstrumentationMatcher } from "../custom-transforms"; +import { mastraConfigs } from "./mastra"; + +const require = createRequire(import.meta.url); + +function configsForChannel(channelName: string) { + return mastraConfigs.filter((config) => config.channelName === channelName); +} + +function transformWithConfig(options: { + channelName: string; + code: string; + filePath: string; + moduleType: "esm" | "cjs"; + version?: string; +}) { + const config = mastraConfigs.find( + (candidate) => + candidate.channelName === options.channelName && + candidate.module.filePath === options.filePath, + ); + expect(config).toBeDefined(); + + const matcher = createInstrumentationMatcher([config!]); + const transformer = matcher.getTransformer( + "@mastra/core", + options.version ?? "1.26.0", + options.filePath, + ); + expect(transformer).toBeDefined(); + + return transformer!.transform(options.code, options.moduleType).code; +} + +describe("mastraConfigs", () => { + it("defines expected Mastra channels", () => { + expect(mastraChannels.agentExecute.channelName).toBe("agent.execute"); + expect(mastraChannels.agentNetwork.channelName).toBe("agent.network"); + expect(mastraChannels.agentGenerateLegacy.channelName).toBe( + "agent.generateLegacy", + ); + expect(mastraChannels.agentStreamLegacy.channelName).toBe( + "agent.streamLegacy", + ); + expect(mastraChannels.toolExecute.channelName).toBe("tool.execute"); + expect(mastraChannels.workflowRunStart.channelName).toBe( + "workflow.run.start", + ); + expect(mastraChannels.workflowRunResume.channelName).toBe( + "workflow.run.resume", + ); + expect(mastraChannels.workflowRunRestart.channelName).toBe( + "workflow.run.restart", + ); + expect(mastraChannels.workflowStepExecute.channelName).toBe( + "workflow.step.execute", + ); + }); + + it("instruments current stable and alpha Mastra chunks", () => { + expect( + configsForChannel(mastraChannels.agentExecute.channelName).map( + (config) => config.module.filePath, + ), + ).toEqual( + expect.arrayContaining([ + "dist/chunk-CXW3Z2OL.js", + "dist/chunk-PBGNXXU5.cjs", + "dist/chunk-4QTY73BW.js", + "dist/chunk-7432OHPH.cjs", + ]), + ); + + expect( + configsForChannel(mastraChannels.toolExecute.channelName).map( + (config) => config.module.filePath, + ), + ).toEqual( + expect.arrayContaining([ + "dist/chunk-O3JJ5ZPY.js", + "dist/chunk-U7Z7GCXY.cjs", + ]), + ); + }); + + it("transforms constructor-assigned Tool.execute", async () => { + const output = transformWithConfig({ + channelName: mastraChannels.toolExecute.channelName, + filePath: "dist/chunk-O3JJ5ZPY.js", + moduleType: "cjs", + code: ` + var Tool = class { + execute; + constructor(opts) { + if (opts.execute) { + this.execute = async (inputData, context) => { + return await opts.execute(inputData, context); + }; + } + } + }; + `, + }); + + expect(output).toContain("orchestrion:@mastra/core:tool.execute"); + expect(output).toContain("tr_ch_apm$tool_execute.asyncEnd.publish"); + expect(output).toContain("this.execute = function (inputData, context)"); + + const collector = createEventCollector(); + collector.subscribe("orchestrion:@mastra/core:tool.execute"); + + const Tool = new Function("require", `${output}; return Tool;`)( + require, + ) as new (opts: { + execute: ( + inputData: unknown, + context: unknown, + ) => Promise<{ forecast: string }>; + }) => { + execute: (inputData: unknown, context: unknown) => Promise; + }; + + const tool = new Tool({ + execute: async (_inputData, context) => { + expect(context).toEqual({ + workflow: { + workflowId: "travel-flow", + runId: "workflow-run", + }, + }); + return { forecast: "Sunny" }; + }, + }); + + await runAndCollectEvents( + () => + tool.execute( + { city: "Paris" }, + { + workflow: { + workflowId: "travel-flow", + runId: "workflow-run", + }, + }, + ), + collector, + ); + + expect(collector.start[0]?.arguments).toEqual([ + { city: "Paris" }, + { + workflow: { + workflowId: "travel-flow", + runId: "workflow-run", + }, + }, + ]); + }); + + it("transforms Agent.#execute", () => { + const output = transformWithConfig({ + channelName: mastraChannels.agentExecute.channelName, + filePath: "dist/chunk-CXW3Z2OL.js", + moduleType: "esm", + code: ` + var Agent = class _Agent { + async #execute(options) { + return { status: "success", result: options }; + } + async generate(messages, options) { + return this.#execute({ ...options, messages, methodType: "generate" }); + } + }; + `, + }); + + expect(output).toContain("orchestrion:@mastra/core:agent.execute"); + }); +}); diff --git a/js/src/auto-instrumentations/configs/mastra.ts b/js/src/auto-instrumentations/configs/mastra.ts new file mode 100644 index 000000000..c0f7a3992 --- /dev/null +++ b/js/src/auto-instrumentations/configs/mastra.ts @@ -0,0 +1,152 @@ +import type { InstrumentationConfig } from "@apm-js-collab/code-transformer"; +import { mastraChannels } from "../../instrumentation/plugins/mastra-channels"; +import { mastraAssignedAsyncTransformName } from "../custom-transforms"; + +const mastraPackageName = "@mastra/core"; + +const stableVersionRange = "1.26.0"; +const alphaVersionRange = "1.26.1-alpha.0"; + +const stableAgentWorkflowChunks = [ + { filePath: "dist/chunk-CXW3Z2OL.js", moduleType: "esm" }, + { filePath: "dist/chunk-PBGNXXU5.cjs", moduleType: "cjs" }, +] as const; + +const alphaAgentWorkflowChunks = [ + { filePath: "dist/chunk-4QTY73BW.js", moduleType: "esm" }, + { filePath: "dist/chunk-7432OHPH.cjs", moduleType: "cjs" }, +] as const; + +const toolChunks = [ + { filePath: "dist/chunk-O3JJ5ZPY.js", moduleType: "esm" }, + { filePath: "dist/chunk-U7Z7GCXY.cjs", moduleType: "cjs" }, +] as const; + +function config( + channelName: string, + versionRange: string, + filePath: string, + functionQuery: InstrumentationConfig["functionQuery"], + transform?: string, +): InstrumentationConfig { + return { + channelName, + module: { + name: mastraPackageName, + versionRange, + filePath, + }, + functionQuery, + ...(transform ? { transform } : {}), + }; +} + +function agentWorkflowConfigs( + versionRange: string, + chunks: readonly { filePath: string }[], +): InstrumentationConfig[] { + return chunks.flatMap(({ filePath }) => [ + config(mastraChannels.agentExecute.channelName, versionRange, filePath, { + className: "Agent", + privateMethodName: "execute", + kind: "Async", + }), + config(mastraChannels.agentNetwork.channelName, versionRange, filePath, { + className: "Agent", + methodName: "network", + kind: "Async", + }), + config( + mastraChannels.agentResumeNetwork.channelName, + versionRange, + filePath, + { + className: "Agent", + methodName: "resumeNetwork", + kind: "Async", + }, + ), + config( + mastraChannels.agentGenerateLegacy.channelName, + versionRange, + filePath, + { + className: "Agent", + methodName: "generateLegacy", + kind: "Async", + }, + ), + config( + mastraChannels.agentStreamLegacy.channelName, + versionRange, + filePath, + { + className: "Agent", + methodName: "streamLegacy", + kind: "Async", + }, + ), + config( + mastraChannels.workflowRunStart.channelName, + versionRange, + filePath, + { + className: "Run", + methodName: "_start", + kind: "Async", + }, + ), + config( + mastraChannels.workflowRunResume.channelName, + versionRange, + filePath, + { + className: "Run", + methodName: "_resume", + kind: "Async", + }, + ), + config( + mastraChannels.workflowRunRestart.channelName, + versionRange, + filePath, + { + className: "Run", + methodName: "_restart", + kind: "Async", + }, + ), + config( + mastraChannels.workflowStepExecute.channelName, + versionRange, + filePath, + { + className: "DefaultExecutionEngine", + methodName: "executeStepWithRetry", + kind: "Async", + }, + ), + ]); +} + +function toolConfigs(versionRange: string): InstrumentationConfig[] { + return toolChunks.map(({ filePath }) => + config( + mastraChannels.toolExecute.channelName, + versionRange, + filePath, + { + expressionName: "execute", + kind: "Async", + }, + mastraAssignedAsyncTransformName, + ), + ); +} + +export const mastraConfigs: InstrumentationConfig[] = [ + ...agentWorkflowConfigs(stableVersionRange, stableAgentWorkflowChunks), + ...agentWorkflowConfigs(alphaVersionRange, alphaAgentWorkflowChunks), + ...toolConfigs(stableVersionRange), + ...toolConfigs(alphaVersionRange), +]; diff --git a/js/src/auto-instrumentations/custom-transforms.ts b/js/src/auto-instrumentations/custom-transforms.ts new file mode 100644 index 000000000..1ce626ed5 --- /dev/null +++ b/js/src/auto-instrumentations/custom-transforms.ts @@ -0,0 +1,80 @@ +import type { + CustomTransform, + InstrumentationConfig, + InstrumentationMatcher, +} from "@apm-js-collab/code-transformer"; +import { create } from "@apm-js-collab/code-transformer"; + +// @ts-expect-error Internal code-transformer helpers are not part of the public API. +import * as codeTransformerTransforms from "@apm-js-collab/code-transformer/lib/transforms.js"; + +export const mastraAssignedAsyncTransformName = "braintrustMastraAssignedAsync"; + +const tracePromiseTransform = + ( + codeTransformerTransforms as { + default?: { + tracePromise?: CustomTransform; + }; + tracePromise?: CustomTransform; + } + ).tracePromise ?? + ( + codeTransformerTransforms as { + default?: { + tracePromise?: CustomTransform; + }; + } + ).default?.tracePromise; + +if (!tracePromiseTransform) { + throw new Error( + "Failed to resolve code-transformer tracePromise helper for Mastra instrumentation.", + ); +} + +/** + * Mastra assigns `Tool.execute` in the constructor with an async arrow function. + * + * The generic expression wrapper preserves arrow semantics, which means + * diagnostics context sees the constructor's lexical `arguments` instead of the + * runtime `(inputData, context)` passed to `Tool.execute`. Convert that assigned + * arrow into a function expression before delegating to the standard async + * wrapper so channel events capture the real call arguments. + */ +const traceMastraAssignedAsync: CustomTransform = ( + state, + node, + parent, + ancestry, +) => { + if (node.type === "ArrowFunctionExpression") { + Object.assign(node, { + type: "FunctionExpression", + id: null, + expression: false, + }); + } + + return tracePromiseTransform( + { + ...(state as Record), + operator: "tracePromise", + }, + node, + parent, + ancestry, + ); +}; + +export function createInstrumentationMatcher( + instrumentations: InstrumentationConfig[], + dcModule?: string | null, +): InstrumentationMatcher { + const matcher = create(instrumentations, dcModule ?? null); + matcher.addTransform( + mastraAssignedAsyncTransformName, + traceMastraAssignedAsync, + ); + return matcher; +} diff --git a/js/src/auto-instrumentations/hook.mts b/js/src/auto-instrumentations/hook.mts index 2c3622600..5a0f57f4b 100644 --- a/js/src/auto-instrumentations/hook.mts +++ b/js/src/auto-instrumentations/hook.mts @@ -26,6 +26,7 @@ import { mistralConfigs } from "./configs/mistral.js"; import { googleADKConfigs } from "./configs/google-adk.js"; import { cohereConfigs } from "./configs/cohere.js"; import { groqConfigs } from "./configs/groq.js"; +import { mastraConfigs } from "./configs/mastra.js"; import { ModulePatch } from "./loader/cjs-patch.js"; import { patchTracingChannel } from "./patch-tracing-channel.js"; @@ -84,6 +85,9 @@ const allConfigs = [ : googleADKConfigs), ...(isDisabled(disabledIntegrations, "cohere") ? [] : cohereConfigs), ...(isDisabled(disabledIntegrations, "groq", "groq-sdk") ? [] : groqConfigs), + ...(isDisabled(disabledIntegrations, "mastra", "mastra-core", "@mastra/core") + ? [] + : mastraConfigs), ]; // 1. Register ESM loader for ESM modules diff --git a/js/src/auto-instrumentations/index.ts b/js/src/auto-instrumentations/index.ts index 03fda75a1..c063217a5 100644 --- a/js/src/auto-instrumentations/index.ts +++ b/js/src/auto-instrumentations/index.ts @@ -40,6 +40,7 @@ export { mistralConfigs } from "./configs/mistral"; export { googleADKConfigs } from "./configs/google-adk"; export { cohereConfigs } from "./configs/cohere"; export { groqConfigs } from "./configs/groq"; +export { mastraConfigs } from "./configs/mastra"; // Re-export orchestrion configuration types // Note: ModuleMetadata and FunctionQuery are properties of InstrumentationConfig, diff --git a/js/src/auto-instrumentations/loader/cjs-patch.ts b/js/src/auto-instrumentations/loader/cjs-patch.ts index 127b5ef5b..63a7821c5 100644 --- a/js/src/auto-instrumentations/loader/cjs-patch.ts +++ b/js/src/auto-instrumentations/loader/cjs-patch.ts @@ -3,13 +3,11 @@ * Patches Module.prototype._compile to transform CommonJS modules at load time. */ -import { - create, - type InstrumentationConfig, -} from "@apm-js-collab/code-transformer"; +import { type InstrumentationConfig } from "@apm-js-collab/code-transformer"; import * as NodeModule from "node:module"; import { sep } from "node:path"; import moduleDetailsFromPath from "module-details-from-path"; +import { createInstrumentationMatcher } from "../custom-transforms"; import { getPackageName, getPackageVersion } from "./get-package-version.js"; export class ModulePatch { @@ -24,7 +22,7 @@ export class ModulePatch { const modulePrototype = resolveModulePrototype() as any; this.packages = new Set(instrumentations.map((i) => i.module.name)); - this.instrumentator = create(instrumentations); + this.instrumentator = createInstrumentationMatcher(instrumentations); this.modulePrototype = modulePrototype; this.originalCompile = modulePrototype._compile; } diff --git a/js/src/auto-instrumentations/loader/esm-hook.mts b/js/src/auto-instrumentations/loader/esm-hook.mts index c5af87183..217232307 100644 --- a/js/src/auto-instrumentations/loader/esm-hook.mts +++ b/js/src/auto-instrumentations/loader/esm-hook.mts @@ -6,11 +6,9 @@ import { readFile } from "node:fs/promises"; import { fileURLToPath } from "node:url"; import { sep } from "node:path"; -import { - create, - type InstrumentationConfig, -} from "@apm-js-collab/code-transformer"; +import { type InstrumentationConfig } from "@apm-js-collab/code-transformer"; import moduleDetailsFromPath from "module-details-from-path"; +import { createInstrumentationMatcher } from "../custom-transforms.js"; import { getPackageName, getPackageVersion } from "./get-package-version.js"; let instrumentator: any; @@ -22,7 +20,7 @@ export async function initialize( ) { // Use the instrumentations passed from the parent via register() const configs = data.instrumentations || []; - instrumentator = create(configs); + instrumentator = createInstrumentationMatcher(configs); packages = new Set(configs.map((i) => i.module.name)); } diff --git a/js/src/instrumentation/braintrust-plugin.test.ts b/js/src/instrumentation/braintrust-plugin.test.ts index aec836b66..ee62b03d3 100644 --- a/js/src/instrumentation/braintrust-plugin.test.ts +++ b/js/src/instrumentation/braintrust-plugin.test.ts @@ -390,7 +390,7 @@ describe("BraintrustPlugin", () => { it("should not create Groq plugin when groq: false", () => { const plugin = new BraintrustPlugin({ integrations: { groq: false }, - }); + } as any); plugin.enable(); expect(GroqPlugin).not.toHaveBeenCalled(); @@ -428,7 +428,7 @@ describe("BraintrustPlugin", () => { cohere: false, groq: false, }, - }); + } as any); plugin.enable(); expect(OpenAIPlugin).not.toHaveBeenCalled(); diff --git a/js/src/instrumentation/braintrust-plugin.ts b/js/src/instrumentation/braintrust-plugin.ts index 485d2d9bc..a98cdd29c 100644 --- a/js/src/instrumentation/braintrust-plugin.ts +++ b/js/src/instrumentation/braintrust-plugin.ts @@ -11,6 +11,7 @@ import { MistralPlugin } from "./plugins/mistral-plugin"; import { GoogleADKPlugin } from "./plugins/google-adk-plugin"; import { CoherePlugin } from "./plugins/cohere-plugin"; import { GroqPlugin } from "./plugins/groq-plugin"; +import { MastraPlugin } from "./plugins/mastra-plugin"; export interface BraintrustPluginConfig { integrations?: { @@ -27,10 +28,16 @@ export interface BraintrustPluginConfig { mistral?: boolean; googleADK?: boolean; cohere?: boolean; - groq?: boolean; }; } +type RuntimeBraintrustPluginConfig = BraintrustPluginConfig & { + integrations?: NonNullable & { + groq?: boolean; + mastra?: boolean; + }; +}; + /** * Default Braintrust plugin that manages all AI provider instrumentation plugins. * @@ -48,7 +55,7 @@ export interface BraintrustPluginConfig { * Individual integrations can be disabled via configuration. */ export class BraintrustPlugin extends BasePlugin { - private config: BraintrustPluginConfig; + private config: RuntimeBraintrustPluginConfig; private openaiPlugin: OpenAIPlugin | null = null; private anthropicPlugin: AnthropicPlugin | null = null; private aiSDKPlugin: AISDKPlugin | null = null; @@ -61,14 +68,17 @@ export class BraintrustPlugin extends BasePlugin { private googleADKPlugin: GoogleADKPlugin | null = null; private coherePlugin: CoherePlugin | null = null; private groqPlugin: GroqPlugin | null = null; + private mastraPlugin: MastraPlugin | null = null; constructor(config: BraintrustPluginConfig = {}) { super(); - this.config = config; + this.config = config as RuntimeBraintrustPluginConfig; } protected onEnable(): void { - const integrations = this.config.integrations || {}; + const integrations = (this.config.integrations || {}) as NonNullable< + RuntimeBraintrustPluginConfig["integrations"] + >; // Enable OpenAI integration (default: true) if (integrations.openai !== false) { @@ -137,6 +147,11 @@ export class BraintrustPlugin extends BasePlugin { this.groqPlugin = new GroqPlugin(); this.groqPlugin.enable(); } + + if (integrations.mastra !== false) { + this.mastraPlugin = new MastraPlugin(); + this.mastraPlugin.enable(); + } } protected onDisable(): void { @@ -199,6 +214,11 @@ export class BraintrustPlugin extends BasePlugin { this.groqPlugin.disable(); this.groqPlugin = null; } + + if (this.mastraPlugin) { + this.mastraPlugin.disable(); + this.mastraPlugin = null; + } } } diff --git a/js/src/instrumentation/plugins/mastra-channels.ts b/js/src/instrumentation/plugins/mastra-channels.ts new file mode 100644 index 000000000..471f7d287 --- /dev/null +++ b/js/src/instrumentation/plugins/mastra-channels.ts @@ -0,0 +1,65 @@ +import { channel, defineChannels } from "../core/channel-definitions"; +import type { + MastraAgentExecuteOptions, + MastraAgentNetworkOptions, + MastraToolContext, + MastraWorkflowRestartArgs, + MastraWorkflowResumeArgs, + MastraWorkflowStartArgs, + MastraWorkflowStepParams, +} from "../../vendor-sdk-types/mastra"; + +export const mastraChannels = defineChannels("@mastra/core", { + agentExecute: channel<[MastraAgentExecuteOptions], unknown>({ + channelName: "agent.execute", + kind: "async", + }), + + agentNetwork: channel<[unknown, MastraAgentNetworkOptions?], unknown>({ + channelName: "agent.network", + kind: "async", + }), + + agentResumeNetwork: channel<[unknown, MastraAgentNetworkOptions?], unknown>({ + channelName: "agent.resumeNetwork", + kind: "async", + }), + + agentGenerateLegacy: channel<[unknown, Record?], unknown>({ + channelName: "agent.generateLegacy", + kind: "async", + }), + + agentStreamLegacy: channel<[unknown, Record?], unknown>({ + channelName: "agent.streamLegacy", + kind: "async", + }), + + toolExecute: channel<[unknown, MastraToolContext?], unknown>({ + channelName: "tool.execute", + kind: "async", + }), + + workflowRunStart: channel<[MastraWorkflowStartArgs?], unknown>({ + channelName: "workflow.run.start", + kind: "async", + }), + + workflowRunResume: channel<[MastraWorkflowResumeArgs?], unknown>({ + channelName: "workflow.run.resume", + kind: "async", + }), + + workflowRunRestart: channel<[MastraWorkflowRestartArgs?], unknown>({ + channelName: "workflow.run.restart", + kind: "async", + }), + + workflowStepExecute: channel< + [string, unknown, MastraWorkflowStepParams?], + unknown + >({ + channelName: "workflow.step.execute", + kind: "async", + }), +}); diff --git a/js/src/instrumentation/plugins/mastra-plugin.test.ts b/js/src/instrumentation/plugins/mastra-plugin.test.ts new file mode 100644 index 000000000..7057ad536 --- /dev/null +++ b/js/src/instrumentation/plugins/mastra-plugin.test.ts @@ -0,0 +1,241 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +const { + mockCurrentSpanStoreSymbol: MOCK_CURRENT_SPAN_STORE_SYMBOL, + mockInternalGetGlobalState, +} = vi.hoisted(() => ({ + mockCurrentSpanStoreSymbol: Symbol.for("braintrust.currentSpanStore"), + mockInternalGetGlobalState: vi.fn(() => undefined), +})); + +vi.mock("../../isomorph", () => ({ + default: { + newTracingChannel: vi.fn(), + }, +})); + +const mockStartSpan = vi.fn(() => ({ + log: vi.fn(), + end: vi.fn(), + spanId: "span-id", + rootSpanId: "root-span-id", + export: vi.fn(() => Promise.resolve("span-id")), +})); + +vi.mock("../../logger", () => ({ + startSpan: (...args: any[]) => mockStartSpan(...args), + _internalGetGlobalState: (...args: any[]) => + mockInternalGetGlobalState(...args), + BRAINTRUST_CURRENT_SPAN_STORE: MOCK_CURRENT_SPAN_STORE_SYMBOL, +})); + +import iso from "../../isomorph"; +import { MastraPlugin } from "./mastra-plugin"; + +const mockNewTracingChannel = iso.newTracingChannel as ReturnType; + +describe("MastraPlugin", () => { + let channels: Map; + + beforeEach(() => { + channels = new Map(); + mockNewTracingChannel.mockImplementation((name: string) => { + const channel = { + name, + subscribe: vi.fn(), + unsubscribe: vi.fn(), + start: { + bindStore: vi.fn(), + unbindStore: vi.fn(), + }, + }; + channels.set(name, channel); + return channel; + }); + mockStartSpan.mockClear(); + mockInternalGetGlobalState.mockReset(); + mockInternalGetGlobalState.mockReturnValue(undefined); + }); + + function subscribedHandlers(channelName: string) { + const channel = channels.get(`orchestrion:@mastra/core:${channelName}`); + expect(channel).toBeDefined(); + expect(channel.subscribe).toHaveBeenCalledTimes(1); + return channel.subscribe.mock.calls[0][0]; + } + + it("subscribes to all Mastra channels", () => { + const plugin = new MastraPlugin(); + + plugin.enable(); + + expect(mockNewTracingChannel).toHaveBeenCalledWith( + "orchestrion:@mastra/core:agent.execute", + ); + expect(mockNewTracingChannel).toHaveBeenCalledWith( + "orchestrion:@mastra/core:tool.execute", + ); + expect(mockNewTracingChannel).toHaveBeenCalledWith( + "orchestrion:@mastra/core:workflow.run.start", + ); + expect(mockNewTracingChannel).toHaveBeenCalledWith( + "orchestrion:@mastra/core:workflow.step.execute", + ); + }); + + it("creates an agent task span with method metadata", () => { + const plugin = new MastraPlugin(); + plugin.enable(); + const handlers = subscribedHandlers("agent.execute"); + const event: any = { + self: { name: "Weather Agent", id: "weather-agent" }, + arguments: [ + { + methodType: "generate", + messages: "What is the weather?", + runId: "run-1", + resourceId: "resource-1", + }, + ], + }; + + handlers.start(event); + handlers.asyncEnd({ ...event, result: { text: "Sunny" } }); + + const span = mockStartSpan.mock.results[0].value; + expect(mockStartSpan).toHaveBeenCalledWith({ + name: "Mastra Agent Weather Agent generate", + spanAttributes: { type: "task" }, + }); + expect(span.log).toHaveBeenCalledWith({ + input: "What is the weather?", + metadata: { + agent_id: "weather-agent", + agent_name: "Weather Agent", + method: "generate", + resource_id: "resource-1", + run_id: "run-1", + }, + }); + expect(span.log).toHaveBeenCalledWith({ + output: { text: "Sunny" }, + metadata: {}, + metrics: {}, + }); + expect(span.end).toHaveBeenCalled(); + }); + + it("creates a tool span with workflow context", () => { + const plugin = new MastraPlugin(); + plugin.enable(); + const handlers = subscribedHandlers("tool.execute"); + const event: any = { + self: { id: "lookup_weather" }, + arguments: [ + { city: "Paris" }, + { + workflow: { + workflowId: "travel-flow", + runId: "workflow-run", + }, + }, + ], + }; + + handlers.start(event); + handlers.asyncEnd({ ...event, result: { forecast: "Sunny" } }); + + const span = mockStartSpan.mock.results[0].value; + expect(mockStartSpan).toHaveBeenCalledWith({ + name: "Mastra Tool lookup_weather", + spanAttributes: { type: "tool" }, + }); + expect(span.log).toHaveBeenCalledWith({ + input: { city: "Paris" }, + metadata: { + tool_id: "lookup_weather", + workflow_id: "travel-flow", + workflow_run_id: "workflow-run", + }, + }); + expect(span.log).toHaveBeenCalledWith({ + output: { forecast: "Sunny" }, + metadata: {}, + metrics: {}, + }); + }); + + it("creates workflow run and step spans", () => { + const plugin = new MastraPlugin(); + plugin.enable(); + + subscribedHandlers("workflow.run.start").start({ + self: { workflowId: "travel-flow", runId: "run-1" }, + arguments: [{ inputData: { city: "Paris" } }], + }); + subscribedHandlers("workflow.step.execute").start({ + arguments: [ + "lookup-step", + () => undefined, + { workflowId: "travel-flow", runId: "run-1" }, + ], + }); + + expect(mockStartSpan).toHaveBeenCalledWith({ + name: "Mastra Workflow travel-flow start", + spanAttributes: { type: "task" }, + }); + expect(mockStartSpan).toHaveBeenCalledWith({ + name: "Mastra Workflow Step lookup-step", + spanAttributes: { type: "function" }, + }); + }); + + it("logs errors and unsubscribes on disable", () => { + const plugin = new MastraPlugin(); + plugin.enable(); + const handlers = subscribedHandlers("workflow.step.execute"); + const event: any = { + arguments: [ + "lookup-step", + () => undefined, + { workflowId: "travel-flow", runId: "run-1" }, + ], + }; + + handlers.start(event); + handlers.error({ ...event, error: new Error("step failed") }); + plugin.disable(); + + const span = mockStartSpan.mock.results[0].value; + expect(span.log).toHaveBeenCalledWith({ error: "step failed" }); + expect(span.end).toHaveBeenCalled(); + for (const channel of channels.values()) { + expect(channel.unsubscribe).toHaveBeenCalledTimes(1); + } + }); + + it("binds current span context on channel start", () => { + const contextManager = { + wrapSpanForStore: vi.fn((span) => ({ span })), + [MOCK_CURRENT_SPAN_STORE_SYMBOL]: { store: "current-span" }, + }; + mockInternalGetGlobalState.mockReturnValue({ contextManager }); + + const plugin = new MastraPlugin(); + plugin.enable(); + const channel = channels.get("orchestrion:@mastra/core:agent.execute"); + const event: any = { + self: { name: "Weather Agent" }, + arguments: [{ methodType: "generate", messages: "Hello" }], + }; + const bindCallback = channel.start.bindStore.mock.calls[0][1]; + + const storeValue = bindCallback(event); + + expect(storeValue).toEqual({ span: mockStartSpan.mock.results[0].value }); + expect(contextManager.wrapSpanForStore).toHaveBeenCalledWith( + mockStartSpan.mock.results[0].value, + ); + }); +}); diff --git a/js/src/instrumentation/plugins/mastra-plugin.ts b/js/src/instrumentation/plugins/mastra-plugin.ts new file mode 100644 index 000000000..285aa5218 --- /dev/null +++ b/js/src/instrumentation/plugins/mastra-plugin.ts @@ -0,0 +1,528 @@ +import type { IsoChannelHandlers, IsoTracingChannel } from "../../isomorph"; +import { + BRAINTRUST_CURRENT_SPAN_STORE, + _internalGetGlobalState, + startSpan, +} from "../../logger"; +import type { CurrentSpanStore, Span } from "../../logger"; +import { SpanTypeAttribute, isObject } from "../../../util/index"; +import type { + AnyAsyncChannel, + AsyncEndOf, + ChannelMessage, + StartOf, +} from "../core/channel-definitions"; +import { BasePlugin } from "../core"; +import { mastraChannels } from "./mastra-channels"; +import type { + MastraAgentExecuteOptions, + MastraAgentLike, + MastraAgentNetworkOptions, + MastraToolContext, + MastraToolLike, + MastraWorkflowRestartArgs, + MastraWorkflowResumeArgs, + MastraWorkflowRunLike, + MastraWorkflowStartArgs, + MastraWorkflowStepParams, +} from "../../vendor-sdk-types/mastra"; + +type MastraChannel = + | typeof mastraChannels.agentExecute + | typeof mastraChannels.agentNetwork + | typeof mastraChannels.agentResumeNetwork + | typeof mastraChannels.agentGenerateLegacy + | typeof mastraChannels.agentStreamLegacy + | typeof mastraChannels.toolExecute + | typeof mastraChannels.workflowRunStart + | typeof mastraChannels.workflowRunResume + | typeof mastraChannels.workflowRunRestart + | typeof mastraChannels.workflowStepExecute; + +type SpanState = { + span: Span; +}; + +type MastraChannelEvent = + ChannelMessage; + +type MastraSpanConfig = { + createSpan: (event: StartOf) => { + input: unknown; + metadata: Record; + name: string; + type: SpanTypeAttribute; + }; + extractOutput: ( + result: AsyncEndOf["result"], + event: AsyncEndOf, + ) => { + metadata?: Record; + output: unknown; + }; +}; + +export class MastraPlugin extends BasePlugin { + protected onEnable(): void { + this.subscribeToMastraChannel(mastraChannels.agentExecute, { + createSpan: (event) => createAgentExecuteSpan(event), + extractOutput: (result) => ({ output: extractAgentOutput(result) }), + }); + this.subscribeToMastraChannel(mastraChannels.agentNetwork, { + createSpan: (event) => createAgentMethodSpan(event, "network"), + extractOutput: (result) => ({ output: extractAgentOutput(result) }), + }); + this.subscribeToMastraChannel(mastraChannels.agentResumeNetwork, { + createSpan: (event) => createAgentMethodSpan(event, "resumeNetwork"), + extractOutput: (result) => ({ output: extractAgentOutput(result) }), + }); + this.subscribeToMastraChannel(mastraChannels.agentGenerateLegacy, { + createSpan: (event) => createAgentMethodSpan(event, "generateLegacy"), + extractOutput: (result) => ({ output: extractAgentOutput(result) }), + }); + this.subscribeToMastraChannel(mastraChannels.agentStreamLegacy, { + createSpan: (event) => createAgentMethodSpan(event, "streamLegacy"), + extractOutput: (result) => ({ output: extractAgentOutput(result) }), + }); + this.subscribeToMastraChannel(mastraChannels.toolExecute, { + createSpan: (event) => createToolSpan(event), + extractOutput: (result) => ({ output: result }), + }); + this.subscribeToMastraChannel(mastraChannels.workflowRunStart, { + createSpan: (event) => createWorkflowRunSpan(event, "start"), + extractOutput: (result) => ({ + output: extractWorkflowRunOutput(result), + metadata: extractWorkflowRunOutputMetadata(result), + }), + }); + this.subscribeToMastraChannel(mastraChannels.workflowRunResume, { + createSpan: (event) => createWorkflowRunSpan(event, "resume"), + extractOutput: (result) => ({ + output: extractWorkflowRunOutput(result), + metadata: extractWorkflowRunOutputMetadata(result), + }), + }); + this.subscribeToMastraChannel(mastraChannels.workflowRunRestart, { + createSpan: (event) => createWorkflowRunSpan(event, "restart"), + extractOutput: (result) => ({ + output: extractWorkflowRunOutput(result), + metadata: extractWorkflowRunOutputMetadata(result), + }), + }); + this.subscribeToMastraChannel(mastraChannels.workflowStepExecute, { + createSpan: (event) => createWorkflowStepSpan(event), + extractOutput: (result) => ({ + output: extractWorkflowStepOutput(result), + }), + }); + } + + protected onDisable(): void { + for (const unsubscribe of this.unsubscribers) { + unsubscribe(); + } + this.unsubscribers = []; + } + + private subscribeToMastraChannel( + channel: TChannel, + config: MastraSpanConfig, + ): void { + const tracingChannel = + channel.tracingChannel() as unknown as IsoTracingChannel< + MastraChannelEvent + >; + const states = new WeakMap(); + const pendingStates: SpanState[] = []; + const unbindCurrentSpanStore = bindCurrentSpanStoreToStart( + tracingChannel, + states, + config, + ); + + const handlers: IsoChannelHandlers> = { + start: (event) => { + const key = event; + const existing = states.get(key); + if (existing) { + return; + } + const created = startSpanForEvent(config, event); + states.set(key, created); + pendingStates.push(created); + }, + asyncEnd: (event) => { + const state = states.get(event) ?? pendingStates.shift(); + if (!state) { + return; + } + + try { + const { output, metadata = {} } = config.extractOutput( + event.result as AsyncEndOf["result"], + event as AsyncEndOf, + ); + state.span.log({ + output, + metadata, + metrics: {}, + }); + } finally { + state.span.end(); + states.delete(event); + const pendingIndex = pendingStates.indexOf(state); + if (pendingIndex >= 0) { + pendingStates.splice(pendingIndex, 1); + } + } + }, + error: (event) => { + const state = states.get(event) ?? pendingStates.shift(); + if (!state || !event.error) { + return; + } + state.span.log({ error: event.error.message }); + state.span.end(); + states.delete(event); + const pendingIndex = pendingStates.indexOf(state); + if (pendingIndex >= 0) { + pendingStates.splice(pendingIndex, 1); + } + }, + }; + + tracingChannel.subscribe(handlers); + this.unsubscribers.push(() => { + unbindCurrentSpanStore?.(); + tracingChannel.unsubscribe(handlers); + }); + } +} + +function ensureState( + states: WeakMap, + event: object, + create: () => TState, +): TState { + const existing = states.get(event); + if (existing) { + return existing; + } + + const created = create(); + states.set(event, created); + return created; +} + +function startSpanForEvent( + config: MastraSpanConfig, + event: StartOf, +): SpanState { + const { name, type, input, metadata } = config.createSpan(event); + const span = startSpan({ + name, + spanAttributes: { + type, + }, + }); + + span.log({ + input, + metadata, + }); + + return { span }; +} + +function bindCurrentSpanStoreToStart( + tracingChannel: IsoTracingChannel>, + states: WeakMap, + config: MastraSpanConfig, +): (() => void) | undefined { + const state = _internalGetGlobalState(); + const contextManager = state?.contextManager; + const startChannel = tracingChannel.start as + | ({ + bindStore?: ( + store: CurrentSpanStore, + callback: (event: MastraChannelEvent) => unknown, + ) => void; + unbindStore?: (store: CurrentSpanStore) => void; + } & object) + | undefined; + const currentSpanStore = contextManager + ? ( + contextManager as { + [BRAINTRUST_CURRENT_SPAN_STORE]?: CurrentSpanStore; + } + )[BRAINTRUST_CURRENT_SPAN_STORE] + : undefined; + + if (!startChannel?.bindStore || !currentSpanStore) { + return undefined; + } + + startChannel.bindStore(currentSpanStore, (event) => { + const span = ensureState(states, event, () => + startSpanForEvent(config, event), + ).span; + return contextManager.wrapSpanForStore(span); + }); + + return () => { + startChannel.unbindStore?.(currentSpanStore); + }; +} + +function createAgentExecuteSpan( + event: StartOf, +): ReturnType< + MastraSpanConfig["createSpan"] +> { + const self = event.self as MastraAgentLike | undefined; + const options = event.arguments[0] ?? {}; + const method = stringValue(options.methodType) ?? "execute"; + const metadata = agentMetadata(self, options, method); + + return { + name: `Mastra Agent ${agentDisplayName(self)} ${method}`, + type: SpanTypeAttribute.TASK, + input: options.messages ?? options.input ?? options, + metadata, + }; +} + +function createAgentMethodSpan( + event: + | StartOf + | StartOf + | StartOf + | StartOf, + method: string, +): { + input: unknown; + metadata: Record; + name: string; + type: SpanTypeAttribute; +} { + const self = event.self as MastraAgentLike | undefined; + const options = (event.arguments[1] ?? {}) as MastraAgentNetworkOptions; + const metadata = agentMetadata(self, options, method); + + return { + name: `Mastra Agent ${agentDisplayName(self)} ${method}`, + type: SpanTypeAttribute.TASK, + input: event.arguments[0], + metadata, + }; +} + +function createToolSpan( + event: StartOf, +): ReturnType< + MastraSpanConfig["createSpan"] +> { + const self = event.self as MastraToolLike | undefined; + const context = event.arguments[1] as MastraToolContext | undefined; + const toolId = toolDisplayName(self); + + return { + name: `Mastra Tool ${toolId}`, + type: SpanTypeAttribute.TOOL, + input: event.arguments[0], + metadata: cleanMetadata({ + tool_id: toolId, + agent_id: context?.agent?.agentId, + tool_call_id: context?.agent?.toolCallId, + thread_id: context?.agent?.threadId, + resource_id: context?.agent?.resourceId, + workflow_id: context?.workflow?.workflowId, + workflow_run_id: context?.workflow?.runId, + }), + }; +} + +function createWorkflowRunSpan( + event: + | StartOf + | StartOf + | StartOf, + method: "start" | "resume" | "restart", +): { + input: unknown; + metadata: Record; + name: string; + type: SpanTypeAttribute; +} { + const self = event.self as MastraWorkflowRunLike | undefined; + const args = event.arguments[0]; + const workflowId = stringValue(self?.workflowId) ?? "workflow"; + + return { + name: `Mastra Workflow ${workflowId} ${method}`, + type: SpanTypeAttribute.TASK, + input: extractWorkflowRunInput(args, method), + metadata: cleanMetadata({ + workflow_id: workflowId, + run_id: self?.runId, + resource_id: self?.resourceId, + method, + }), + }; +} + +function createWorkflowStepSpan( + event: StartOf, +): ReturnType< + MastraSpanConfig["createSpan"] +> { + const stepId = event.arguments[0]; + const params = event.arguments[2] as MastraWorkflowStepParams | undefined; + + return { + name: `Mastra Workflow Step ${stepId}`, + type: SpanTypeAttribute.FUNCTION, + input: undefined, + metadata: cleanMetadata({ + step_id: stepId, + workflow_id: params?.workflowId, + workflow_run_id: params?.runId, + resource_id: params?.resourceId, + }), + }; +} + +function agentDisplayName(agent: MastraAgentLike | undefined): string { + return stringValue(agent?.name) ?? stringValue(agent?.id) ?? "Agent"; +} + +function agentMetadata( + agent: MastraAgentLike | undefined, + options: MastraAgentExecuteOptions | MastraAgentNetworkOptions, + method: string, +): Record { + const memory = readAgentMemory(options); + + return cleanMetadata({ + agent_id: agent?.id, + agent_name: agent?.name, + method, + run_id: options.runId, + resource_id: options.resourceId ?? memory?.resource, + thread_id: options.threadId ?? extractThreadId(options), + }); +} + +function toolDisplayName(tool: MastraToolLike | undefined): string { + return ( + stringValue(tool?.id) ?? + stringValue(tool?.toolName) ?? + stringValue(tool?.name) ?? + "tool" + ); +} + +function extractThreadId( + options: MastraAgentExecuteOptions | MastraAgentNetworkOptions, +): string | undefined { + const memoryThread = readAgentMemory(options)?.thread; + if (typeof memoryThread === "string") { + return memoryThread; + } + return stringValue(memoryThread?.id); +} + +function readAgentMemory( + options: MastraAgentExecuteOptions | MastraAgentNetworkOptions, +): MastraAgentNetworkOptions["memory"] | undefined { + if (!("memory" in options) || !isObject(options.memory)) { + return undefined; + } + + return options.memory; +} + +function extractAgentOutput(result: unknown): unknown { + if (!isObject(result)) { + return result; + } + + const output: Record = {}; + for (const key of ["text", "object", "files", "result", "status"]) { + if (key in result) { + output[key] = result[key]; + } + } + + return Object.keys(output).length > 0 ? output : result; +} + +function extractWorkflowRunInput( + args: + | MastraWorkflowStartArgs + | MastraWorkflowResumeArgs + | MastraWorkflowRestartArgs + | undefined, + method: "start" | "resume" | "restart", +): unknown { + if (!args) { + return undefined; + } + if (method === "resume") { + return args.resumeData ?? args; + } + return args.inputData ?? args; +} + +function extractWorkflowRunOutput(result: unknown): unknown { + if (!isObject(result)) { + return result; + } + + if ("status" in result || "result" in result) { + return cleanMetadata({ + status: result.status, + result: result.result, + }); + } + + return result; +} + +function extractWorkflowRunOutputMetadata( + result: unknown, +): Record { + if (!isObject(result)) { + return {}; + } + return cleanMetadata({ + run_id: result.runId, + resource_id: result.resourceId, + }); +} + +function extractWorkflowStepOutput(result: unknown): unknown { + if (!isObject(result)) { + return result; + } + if ("status" in result) { + return cleanMetadata({ + status: result.status, + output: result.output, + error: result.error, + }); + } + return result; +} + +function cleanMetadata( + metadata: Record, +): Record { + return Object.fromEntries( + Object.entries(metadata).filter(([, value]) => value !== undefined), + ); +} + +function stringValue(value: unknown): string | undefined { + return typeof value === "string" && value.length > 0 ? value : undefined; +} diff --git a/js/src/instrumentation/registry.test.ts b/js/src/instrumentation/registry.test.ts index 9e8c6a889..71a75c35d 100644 --- a/js/src/instrumentation/registry.test.ts +++ b/js/src/instrumentation/registry.test.ts @@ -124,6 +124,12 @@ describe("configureInstrumentation API", () => { cohere: false, }, }); + + configureInstrumentation({ + integrations: { + mastra: false, + }, + } as any); }); }); @@ -223,4 +229,24 @@ describe("Environment Variable Configuration", () => { expect(testRegistry.isEnabled()).toBe(true); testRegistry.disable(); }); + + it("should treat Mastra aliases as mastra instrumentation", async () => { + const iso = (await import("../isomorph")).default; + mockNewTracingChannel.mockClear(); + iso.getEnv = (name: string) => { + if (name === "BRAINTRUST_DISABLE_INSTRUMENTATION") { + return "mastra-core,@mastra/core"; + } + return originalGetEnv(name); + }; + + const testRegistry = new (registry.constructor as any)(); + testRegistry.enable(); + + expect(testRegistry.isEnabled()).toBe(true); + expect(mockNewTracingChannel).not.toHaveBeenCalledWith( + "orchestrion:@mastra/core:agent.execute", + ); + testRegistry.disable(); + }); }); diff --git a/js/src/instrumentation/registry.ts b/js/src/instrumentation/registry.ts index 0d3111db4..b588c4e9a 100644 --- a/js/src/instrumentation/registry.ts +++ b/js/src/instrumentation/registry.ts @@ -28,9 +28,21 @@ export interface InstrumentationConfig { }; } +type RuntimeInstrumentationConfig = InstrumentationConfig & { + integrations?: NonNullable & { + groq?: boolean; + mastra?: boolean; + }; +}; + +type RuntimeIntegrationName = keyof NonNullable< + RuntimeInstrumentationConfig["integrations"] +>; +type RuntimeIntegrationMap = Partial>; + class PluginRegistry { private braintrustPlugin: BraintrustPlugin | null = null; - private config: InstrumentationConfig = {}; + private config: RuntimeInstrumentationConfig = {}; private enabled = false; /** @@ -102,7 +114,7 @@ class PluginRegistry { /** * Get default configuration (all integrations enabled). */ - private getDefaultConfig(): Record { + private getDefaultConfig(): RuntimeIntegrationMap { return { openai: true, anthropic: true, @@ -115,6 +127,8 @@ class PluginRegistry { openrouterAgent: true, mistral: true, cohere: true, + groq: true, + mastra: true, }; } @@ -122,8 +136,8 @@ class PluginRegistry { * Read configuration from environment variables. * Supports: BRAINTRUST_DISABLE_INSTRUMENTATION=openai,anthropic,... */ - private readEnvConfig(): InstrumentationConfig { - const integrations: Record = {}; + private readEnvConfig(): RuntimeInstrumentationConfig { + const integrations: RuntimeIntegrationMap = {}; const disabledList = iso.getEnv("BRAINTRUST_DISABLE_INSTRUMENTATION"); if (disabledList) { @@ -133,7 +147,7 @@ class PluginRegistry { .filter((s) => s.length > 0); for (const sdk of disabled) { - integrations[sdk] = false; + integrations[normalizeIntegrationName(sdk)] = false; } } @@ -141,6 +155,16 @@ class PluginRegistry { } } +function normalizeIntegrationName(name: string): RuntimeIntegrationName { + switch (name) { + case "@mastra/core": + case "mastra-core": + return "mastra"; + default: + return name as RuntimeIntegrationName; + } +} + /** * Global plugin registry instance. */ diff --git a/js/src/vendor-sdk-types/mastra.ts b/js/src/vendor-sdk-types/mastra.ts new file mode 100644 index 000000000..c3830ca34 --- /dev/null +++ b/js/src/vendor-sdk-types/mastra.ts @@ -0,0 +1,85 @@ +/** + * Minimal vendored types for @mastra/core auto-instrumentation. + * + * These types describe only the runtime shapes consumed by instrumentation and + * should never be exposed to users of the SDK. + */ + +export interface MastraAgentLike { + id?: string; + name?: string; +} + +export interface MastraAgentExecuteOptions { + methodType?: string; + messages?: unknown; + input?: unknown; + runId?: string; + resourceId?: string; + threadId?: string; + [key: string]: unknown; +} + +export interface MastraAgentNetworkOptions { + runId?: string; + resourceId?: string; + threadId?: string; + memory?: { + thread?: string | { id?: string }; + resource?: string; + }; + [key: string]: unknown; +} + +export interface MastraToolLike { + id?: string; + name?: string; + toolName?: string; +} + +export interface MastraToolContext { + agent?: { + agentId?: string; + toolCallId?: string; + threadId?: string; + resourceId?: string; + }; + workflow?: { + workflowId?: string; + runId?: string; + }; + [key: string]: unknown; +} + +export interface MastraWorkflowRunLike { + workflowId?: string; + runId?: string; + resourceId?: string; + [key: string]: unknown; +} + +export interface MastraWorkflowStartArgs { + inputData?: unknown; + initialState?: unknown; + [key: string]: unknown; +} + +export interface MastraWorkflowResumeArgs { + resumeData?: unknown; + step?: unknown; + label?: string; + [key: string]: unknown; +} + +export interface MastraWorkflowRestartArgs { + inputData?: unknown; + step?: unknown; + [key: string]: unknown; +} + +export interface MastraWorkflowStepParams { + workflowId?: string; + runId?: string; + resourceId?: string; + [key: string]: unknown; +}