@mastra/playground-ui 60.1.0-alpha.0 → 60.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{code-editor-IR5UX112.js → code-editor-28chVxHw.js} +6 -4
- package/dist/code-editor-28chVxHw.js.map +1 -0
- package/dist/{code-editor-DzQEzQJh.cjs → code-editor-B_wPmKPf.cjs} +6 -4
- package/dist/code-editor-B_wPmKPf.cjs.map +1 -0
- package/dist/components/CodeEditor.cjs.js +1 -1
- package/dist/components/CodeEditor.es.js +1 -1
- package/dist/components/EnvironmentVariablesEditor.cjs.js +4 -4
- package/dist/components/EnvironmentVariablesEditor.cjs.js.map +1 -1
- package/dist/components/EnvironmentVariablesEditor.es.js +4 -4
- package/dist/components/EnvironmentVariablesEditor.es.js.map +1 -1
- package/dist/components/Workflow.cjs.js +3 -3
- package/dist/components/Workflow.es.js +3 -3
- package/dist/domains/chat/components/network-choice-metadata-dialog.cjs.js +1 -1
- package/dist/domains/chat/components/network-choice-metadata-dialog.es.js +1 -1
- package/dist/domains/chat/messages/dataset-save-action.cjs.js +1 -1
- package/dist/domains/chat/messages/dataset-save-action.es.js +1 -1
- package/dist/domains/chat/messages/message-row.cjs.js +1 -1
- package/dist/domains/chat/messages/message-row.es.js +1 -1
- package/dist/domains/chat/tools/badges/agent-badge-wrapper.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/agent-badge-wrapper.es.js +1 -1
- package/dist/domains/chat/tools/badges/agent-badge.cjs.js +2 -2
- package/dist/domains/chat/tools/badges/agent-badge.es.js +2 -2
- package/dist/domains/chat/tools/badges/background-task-metadata-dialog.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/background-task-metadata-dialog.es.js +1 -1
- package/dist/domains/chat/tools/badges/code-mode-badge.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/code-mode-badge.es.js +1 -1
- package/dist/domains/chat/tools/badges/tool-badge.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/tool-badge.es.js +1 -1
- package/dist/domains/chat/tools/badges/workflow-badge.cjs.js +2 -1
- package/dist/domains/chat/tools/badges/workflow-badge.cjs.js.map +1 -1
- package/dist/domains/chat/tools/badges/workflow-badge.es.js +2 -1
- package/dist/domains/chat/tools/badges/workflow-badge.es.js.map +1 -1
- package/dist/domains/chat/tools/tool-card.cjs.js +1 -1
- package/dist/domains/chat/tools/tool-card.es.js +1 -1
- package/dist/domains/datasets/components/save-as-dataset-item-dialog.cjs.js +1 -1
- package/dist/domains/datasets/components/save-as-dataset-item-dialog.es.js +1 -1
- package/dist/domains/metrics/drilldown.cjs.js +0 -1
- package/dist/domains/metrics/drilldown.cjs.js.map +1 -1
- package/dist/domains/metrics/drilldown.es.js +0 -1
- package/dist/domains/metrics/drilldown.es.js.map +1 -1
- package/dist/domains/metrics/metrics-filters.cjs.js +0 -2
- package/dist/domains/metrics/metrics-filters.cjs.js.map +1 -1
- package/dist/domains/metrics/metrics-filters.es.js +0 -2
- package/dist/domains/metrics/metrics-filters.es.js.map +1 -1
- package/dist/domains/observability/components/add-trace-mocks-to-item-dialog.cjs.js +1 -1
- package/dist/domains/observability/components/add-trace-mocks-to-item-dialog.es.js +1 -1
- package/dist/domains/workflows/components/workflow-step-detail.cjs.js +1 -1
- package/dist/domains/workflows/components/workflow-step-detail.es.js +1 -1
- package/dist/domains/workflows/workflow/data/workflow-data-button.cjs.js +1 -1
- package/dist/domains/workflows/workflow/data/workflow-data-button.es.js +1 -1
- package/dist/domains/workflows/workflow/data/workflow-data-inspector.cjs.js +1 -1
- package/dist/domains/workflows/workflow/data/workflow-data-inspector.es.js +1 -1
- package/dist/domains/workflows/workflow/input/workflow-json-input.cjs.js +1 -1
- package/dist/domains/workflows/workflow/input/workflow-json-input.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-data-edge.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-data-edge.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-map-config-dialog.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-map-config-dialog.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-run-data.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-run-data.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-status.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-status.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-step-action-bar.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-step-action-bar.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-suspended-steps.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-suspended-steps.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-time-travel-form.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-time-travel-form.es.js +1 -1
- package/dist/hooks/use-environment-variables-editor.cjs.js +6 -1
- package/dist/hooks/use-environment-variables-editor.cjs.js.map +1 -1
- package/dist/hooks/use-environment-variables-editor.es.js +6 -1
- package/dist/hooks/use-environment-variables-editor.es.js.map +1 -1
- package/dist/src/domains/metrics/hooks/use-metrics-filters.d.ts +0 -1
- package/dist/src/domains/metrics/metrics-filters.d.ts +0 -2
- package/dist/src/ds/components/CodeEditor/variable-autocomplete-extension.d.ts +6 -0
- package/dist/src/hooks/use-environment-variables-editor.d.ts +1 -1
- package/dist/{tool-card-DPrShK-9.js → tool-card-C_K5PwrK.js} +2 -2
- package/dist/{tool-card-DPrShK-9.js.map → tool-card-C_K5PwrK.js.map} +1 -1
- package/dist/{tool-card-BfMA9tub.cjs → tool-card-rxo27sve.cjs} +2 -2
- package/dist/{tool-card-BfMA9tub.cjs.map → tool-card-rxo27sve.cjs.map} +1 -1
- package/dist/{workflow-code-dialog-content-COlaHWtW.cjs → workflow-code-dialog-content-BFm2IWDl.cjs} +2 -2
- package/dist/{workflow-code-dialog-content-COlaHWtW.cjs.map → workflow-code-dialog-content-BFm2IWDl.cjs.map} +1 -1
- package/dist/{workflow-code-dialog-content-BQBHzRfZ.js → workflow-code-dialog-content-BM4ZnrUr.js} +2 -2
- package/dist/{workflow-code-dialog-content-BQBHzRfZ.js.map → workflow-code-dialog-content-BM4ZnrUr.js.map} +1 -1
- package/dist/{workflow-data-edge-view-BvhW_gux.cjs → workflow-data-edge-view-7f8O6pVW.cjs} +2 -2
- package/dist/{workflow-data-edge-view-BvhW_gux.cjs.map → workflow-data-edge-view-7f8O6pVW.cjs.map} +1 -1
- package/dist/{workflow-data-edge-view-BjfKYysc.js → workflow-data-edge-view-BpGLV-at.js} +2 -2
- package/dist/{workflow-data-edge-view-BjfKYysc.js.map → workflow-data-edge-view-BpGLV-at.js.map} +1 -1
- package/dist/{workflow-edge-data-button-BTsPGDpk.cjs → workflow-edge-data-button-BOVRo4xO.cjs} +2 -2
- package/dist/{workflow-edge-data-button-BTsPGDpk.cjs.map → workflow-edge-data-button-BOVRo4xO.cjs.map} +1 -1
- package/dist/{workflow-edge-data-button-CIP46GJE.js → workflow-edge-data-button-C6eyWbcG.js} +2 -2
- package/dist/{workflow-edge-data-button-CIP46GJE.js.map → workflow-edge-data-button-C6eyWbcG.js.map} +1 -1
- package/package.json +11 -11
- package/dist/code-editor-DzQEzQJh.cjs.map +0 -1
- package/dist/code-editor-IR5UX112.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-badge.es.js","sources":["../../../../../src/domains/chat/tools/badges/workflow-badge.tsx"],"sourcesContent":["import type { GetWorkflowResponse } from '@mastra/client-js';\nimport { Eye } from 'lucide-react';\nimport { useContext, useEffect } from 'react';\nimport { BackgroundTaskMetadataDialogTrigger } from './background-task-metadata-dialog';\nimport type { MessageMetadata } from '@/domains/chat';\n\nimport { BadgeWrapper } from '@/domains/chat/components/badge-wrapper';\nimport { LoadingBadge } from '@/domains/chat/components/loading-badge';\nimport { NetworkChoiceMetadataDialogTrigger } from '@/domains/chat/components/network-choice-metadata-dialog';\nimport { SectionLabel } from '@/domains/chat/components/section-label';\nimport { awaitsToolApproval } from '@/domains/chat/tools/badges/awaits-tool-approval';\nimport type { ToolApprovalButtonsProps } from '@/domains/chat/tools/badges/tool-approval-buttons';\nimport { ToolApprovalButtons } from '@/domains/chat/tools/badges/tool-approval-buttons';\nimport { useEntityRequestContext } from '@/domains/request-context/hooks/use-entity-request-context';\nimport {\n WorkflowGraph,\n WorkflowRunContext,\n WorkflowSelectedStepProvider,\n WorkflowStepDetailProvider,\n useWorkflowStepDetail,\n} from '@/domains/workflows';\nimport { WorkflowStepDetailContent } from '@/domains/workflows/components/workflow-step-detail';\nimport { PlaygroundWorkflowRunProvider } from '@/domains/workflows/context/playground-workflow-run-provider';\nimport type { WorkflowRunStreamResult } from '@/domains/workflows/context/workflow-run-context';\nimport { useWorkflow } from '@/domains/workflows/hooks/use-workflow';\nimport { ToolCallMono } from '@/ds/components/ai/tool-call';\nimport { Button } from '@/ds/components/Button';\nimport { CodeEditor } from '@/ds/components/CodeEditor';\nimport { WorkflowIcon } from '@/ds/icons/WorkflowIcon';\nimport { useLinkComponent } from '@/lib/framework';\n\nexport interface WorkflowBadgeProps extends Omit<ToolApprovalButtonsProps, 'toolCalled'> {\n workflowId: string;\n result?: any;\n isStreaming?: boolean;\n metadata?: MessageMetadata;\n suspendPayload?: any;\n toolCalled?: boolean;\n}\n\nexport const WorkflowBadge = ({\n result,\n workflowId,\n isStreaming,\n metadata,\n toolCallId,\n toolApprovalMetadata,\n suspendPayload,\n toolName,\n isNetwork,\n toolCalled,\n}: WorkflowBadgeProps) => {\n const { runId, status } = result || {};\n const { data: workflow, isLoading: isWorkflowLoading } = useWorkflow(\n workflowId,\n useEntityRequestContext('workflow', workflowId)[0],\n );\n const routingDecision = metadata?.mode === 'network' ? metadata.routingDecision : undefined;\n const selectionReason =\n metadata?.mode === 'network' ? (routingDecision?.selectionReason ?? metadata.selectionReason) : undefined;\n const agentNetworkInput = metadata?.mode === 'network' ? (routingDecision ?? metadata.agentInput) : undefined;\n\n const bgEntry =\n (metadata?.mode === 'stream' || metadata?.mode === 'generate') && metadata?.backgroundTasks\n ? metadata.backgroundTasks[toolCallId]\n : undefined;\n\n let suspendPayloadSlot =\n typeof suspendPayload === 'string' ? (\n <ToolCallMono copyText={suspendPayload} className=\"text-muted-foreground\">\n {suspendPayload}\n </ToolCallMono>\n ) : (\n <CodeEditor data={suspendPayload} data-testid=\"tool-suspend-payload\" />\n );\n\n if (isWorkflowLoading || !workflow) return <LoadingBadge />;\n\n const toolCalledOrFinished = toolCalled ?? !!status;\n const showsRun = isStreaming || Boolean(runId);\n const hasBody =\n showsRun ||\n Boolean(suspendPayload) ||\n awaitsToolApproval({ toolApprovalMetadata, toolCalled: toolCalledOrFinished });\n\n return (\n <BadgeWrapper\n data-testid=\"workflow-badge\"\n icon={<WorkflowIcon className=\"text-span-workflow\" />}\n title={workflow.name}\n initialCollapsed={false}\n extraInfo={\n metadata?.mode === 'network' ? (\n <NetworkChoiceMetadataDialogTrigger\n selectionReason={selectionReason ?? ''}\n input={agentNetworkInput as string | Record<string, unknown> | undefined}\n />\n ) : bgEntry?.taskId && bgEntry?.startedAt ? (\n <BackgroundTaskMetadataDialogTrigger backgroundTask={bgEntry} />\n ) : null\n }\n >\n {hasBody && (\n <>\n {!isStreaming && runId && (\n <PlaygroundWorkflowRunProvider workflowId={workflowId} initialRunId={runId} withoutTimeTravel>\n <WorkflowBadgeExtended workflowId={workflowId} workflow={workflow} runId={runId} />\n </PlaygroundWorkflowRunProvider>\n )}\n\n {isStreaming && <WorkflowBadgeExtended workflowId={workflowId} workflow={workflow} runId={runId} />}\n\n {suspendPayloadSlot !== undefined && suspendPayload && (\n <div>\n <SectionLabel>Workflow suspend payload</SectionLabel>\n {suspendPayloadSlot}\n </div>\n )}\n\n <ToolApprovalButtons\n toolCalled={toolCalledOrFinished}\n toolCallId={toolCallId}\n toolApprovalMetadata={toolApprovalMetadata}\n toolName={toolName}\n isNetwork={isNetwork}\n isGenerateMode={metadata?.mode === 'generate'}\n />\n </>\n )}\n </BadgeWrapper>\n );\n};\n\ninterface WorkflowBadgeExtendedProps {\n workflowId: string;\n runId?: string;\n workflow: GetWorkflowResponse;\n}\n\nconst WorkflowBadgeExtended = ({ workflowId, workflow, runId }: WorkflowBadgeExtendedProps) => {\n const requestContext = useEntityRequestContext('workflow', workflowId)[0];\n const { Link } = useLinkComponent();\n const { isLoadingRunExecutionResult } = useContext(WorkflowRunContext);\n\n return (\n <>\n <div className=\"flex items-center gap-2 pb-2\">\n <Button icon={<WorkflowIcon />} render={<Link href={`/workflows/${workflowId}/graph`} />}>\n Go to workflow\n </Button>\n {runId && (\n <Button icon={<Eye />} render={<Link href={`/workflows/${workflowId}/graph/${runId}`} />}>\n See run\n </Button>\n )}\n </div>\n\n <WorkflowSelectedStepProvider>\n <WorkflowStepDetailProvider>\n <div className=\"h-[60vh] w-full overflow-hidden rounded-md\">\n <WorkflowGraph\n workflowId={workflowId}\n workflow={workflow}\n isLoading={isLoadingRunExecutionResult}\n requestContext={requestContext}\n />\n </div>\n <WorkflowBadgeStepDetail requestContext={requestContext} />\n </WorkflowStepDetailProvider>\n </WorkflowSelectedStepProvider>\n </>\n );\n};\n\nconst WorkflowBadgeStepDetail = ({ requestContext }: { requestContext: Record<string, any> }) => {\n const { stepDetail } = useWorkflowStepDetail();\n if (!stepDetail) return null;\n return (\n <div className=\"mt-2 flex max-h-[60vh] flex-col overflow-hidden rounded-md border border-border bg-background\">\n <WorkflowStepDetailContent requestContext={requestContext} />\n </div>\n );\n};\n\n// eslint-disable-next-line react-refresh/only-export-components\nexport const useWorkflowStream = (workflowFullState?: WorkflowRunStreamResult) => {\n const { setResult } = useContext(WorkflowRunContext);\n\n useEffect(() => {\n if (!workflowFullState) return;\n setResult(workflowFullState);\n }, [workflowFullState, setResult]);\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"workflow-badge.es.js","sources":["../../../../../src/domains/chat/tools/badges/workflow-badge.tsx"],"sourcesContent":["import type { GetWorkflowResponse } from '@mastra/client-js';\nimport { Eye } from 'lucide-react';\nimport { useContext, useEffect } from 'react';\nimport { BackgroundTaskMetadataDialogTrigger } from './background-task-metadata-dialog';\nimport type { MessageMetadata } from '@/domains/chat';\n\nimport { BadgeWrapper } from '@/domains/chat/components/badge-wrapper';\nimport { LoadingBadge } from '@/domains/chat/components/loading-badge';\nimport { NetworkChoiceMetadataDialogTrigger } from '@/domains/chat/components/network-choice-metadata-dialog';\nimport { SectionLabel } from '@/domains/chat/components/section-label';\nimport { awaitsToolApproval } from '@/domains/chat/tools/badges/awaits-tool-approval';\nimport type { ToolApprovalButtonsProps } from '@/domains/chat/tools/badges/tool-approval-buttons';\nimport { ToolApprovalButtons } from '@/domains/chat/tools/badges/tool-approval-buttons';\nimport { useEntityRequestContext } from '@/domains/request-context/hooks/use-entity-request-context';\nimport {\n WorkflowGraph,\n WorkflowRunContext,\n WorkflowSelectedStepProvider,\n WorkflowStepDetailProvider,\n useWorkflowStepDetail,\n} from '@/domains/workflows';\nimport { WorkflowStepDetailContent } from '@/domains/workflows/components/workflow-step-detail';\nimport { PlaygroundWorkflowRunProvider } from '@/domains/workflows/context/playground-workflow-run-provider';\nimport type { WorkflowRunStreamResult } from '@/domains/workflows/context/workflow-run-context';\nimport { useWorkflow } from '@/domains/workflows/hooks/use-workflow';\nimport { ToolCallMono } from '@/ds/components/ai/tool-call';\nimport { Button } from '@/ds/components/Button';\nimport { CodeEditor } from '@/ds/components/CodeEditor';\nimport { WorkflowIcon } from '@/ds/icons/WorkflowIcon';\nimport { useLinkComponent } from '@/lib/framework';\n\nexport interface WorkflowBadgeProps extends Omit<ToolApprovalButtonsProps, 'toolCalled'> {\n workflowId: string;\n result?: any;\n isStreaming?: boolean;\n metadata?: MessageMetadata;\n suspendPayload?: any;\n toolCalled?: boolean;\n}\n\nexport const WorkflowBadge = ({\n result,\n workflowId,\n isStreaming,\n metadata,\n toolCallId,\n toolApprovalMetadata,\n suspendPayload,\n toolName,\n isNetwork,\n toolCalled,\n}: WorkflowBadgeProps) => {\n const { runId, status } = result || {};\n const { data: workflow, isLoading: isWorkflowLoading } = useWorkflow(\n workflowId,\n useEntityRequestContext('workflow', workflowId)[0],\n );\n const routingDecision = metadata?.mode === 'network' ? metadata.routingDecision : undefined;\n const selectionReason =\n metadata?.mode === 'network' ? (routingDecision?.selectionReason ?? metadata.selectionReason) : undefined;\n const agentNetworkInput = metadata?.mode === 'network' ? (routingDecision ?? metadata.agentInput) : undefined;\n\n const bgEntry =\n (metadata?.mode === 'stream' || metadata?.mode === 'generate') && metadata?.backgroundTasks\n ? metadata.backgroundTasks[toolCallId]\n : undefined;\n\n let suspendPayloadSlot =\n typeof suspendPayload === 'string' ? (\n <ToolCallMono copyText={suspendPayload} className=\"text-muted-foreground\">\n {suspendPayload}\n </ToolCallMono>\n ) : (\n <CodeEditor data={suspendPayload} data-testid=\"tool-suspend-payload\" />\n );\n\n if (isWorkflowLoading || !workflow) return <LoadingBadge />;\n\n const toolCalledOrFinished = toolCalled ?? !!status;\n const showsRun = isStreaming || Boolean(runId);\n const hasBody =\n showsRun ||\n Boolean(suspendPayload) ||\n awaitsToolApproval({ toolApprovalMetadata, toolCalled: toolCalledOrFinished });\n\n return (\n <BadgeWrapper\n data-testid=\"workflow-badge\"\n icon={<WorkflowIcon className=\"text-span-workflow\" />}\n title={workflow.name}\n initialCollapsed={false}\n extraInfo={\n metadata?.mode === 'network' ? (\n <NetworkChoiceMetadataDialogTrigger\n selectionReason={selectionReason ?? ''}\n input={agentNetworkInput as string | Record<string, unknown> | undefined}\n />\n ) : bgEntry?.taskId && bgEntry?.startedAt ? (\n <BackgroundTaskMetadataDialogTrigger backgroundTask={bgEntry} />\n ) : null\n }\n >\n {hasBody && (\n <>\n {!isStreaming && runId && (\n <PlaygroundWorkflowRunProvider workflowId={workflowId} initialRunId={runId} withoutTimeTravel>\n <WorkflowBadgeExtended workflowId={workflowId} workflow={workflow} runId={runId} />\n </PlaygroundWorkflowRunProvider>\n )}\n\n {isStreaming && <WorkflowBadgeExtended workflowId={workflowId} workflow={workflow} runId={runId} />}\n\n {suspendPayloadSlot !== undefined && suspendPayload && (\n <div>\n <SectionLabel>Workflow suspend payload</SectionLabel>\n {suspendPayloadSlot}\n </div>\n )}\n\n <ToolApprovalButtons\n toolCalled={toolCalledOrFinished}\n toolCallId={toolCallId}\n toolApprovalMetadata={toolApprovalMetadata}\n toolName={toolName}\n isNetwork={isNetwork}\n isGenerateMode={metadata?.mode === 'generate'}\n />\n </>\n )}\n </BadgeWrapper>\n );\n};\n\ninterface WorkflowBadgeExtendedProps {\n workflowId: string;\n runId?: string;\n workflow: GetWorkflowResponse;\n}\n\nconst WorkflowBadgeExtended = ({ workflowId, workflow, runId }: WorkflowBadgeExtendedProps) => {\n const requestContext = useEntityRequestContext('workflow', workflowId)[0];\n const { Link } = useLinkComponent();\n const { isLoadingRunExecutionResult } = useContext(WorkflowRunContext);\n\n return (\n <>\n <div className=\"flex items-center gap-2 pb-2\">\n <Button icon={<WorkflowIcon />} render={<Link href={`/workflows/${workflowId}/graph`} />}>\n Go to workflow\n </Button>\n {runId && (\n <Button icon={<Eye />} render={<Link href={`/workflows/${workflowId}/graph/${runId}`} />}>\n See run\n </Button>\n )}\n </div>\n\n <WorkflowSelectedStepProvider>\n <WorkflowStepDetailProvider>\n <div className=\"h-[60vh] w-full overflow-hidden rounded-md\">\n <WorkflowGraph\n workflowId={workflowId}\n workflow={workflow}\n isLoading={isLoadingRunExecutionResult}\n requestContext={requestContext}\n />\n </div>\n <WorkflowBadgeStepDetail requestContext={requestContext} />\n </WorkflowStepDetailProvider>\n </WorkflowSelectedStepProvider>\n </>\n );\n};\n\nconst WorkflowBadgeStepDetail = ({ requestContext }: { requestContext: Record<string, any> }) => {\n const { stepDetail } = useWorkflowStepDetail();\n if (!stepDetail) return null;\n return (\n <div className=\"mt-2 flex max-h-[60vh] flex-col overflow-hidden rounded-md border border-border bg-background\">\n <WorkflowStepDetailContent requestContext={requestContext} />\n </div>\n );\n};\n\n// eslint-disable-next-line react-refresh/only-export-components\nexport const useWorkflowStream = (workflowFullState?: WorkflowRunStreamResult) => {\n const { setResult } = useContext(WorkflowRunContext);\n\n useEffect(() => {\n if (!workflowFullState) return;\n setResult(workflowFullState);\n }, [workflowFullState, setResult]);\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,MAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,oBAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,KAA0B;AACxB,EAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,UAAU,EAAC;AACrC,EAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,SAAA,EAAW,mBAAkB,GAAI,WAAA;AAAA,IACvD,UAAA;AAAA,IACA,uBAAA,CAAwB,UAAA,EAAY,UAAU,CAAA,CAAE,CAAC;AAAA,GACnD;AACA,EAAA,MAAM,eAAA,GAAkB,QAAA,EAAU,IAAA,KAAS,SAAA,GAAY,SAAS,eAAA,GAAkB,MAAA;AAClF,EAAA,MAAM,kBACJ,QAAA,EAAU,IAAA,KAAS,YAAa,eAAA,EAAiB,eAAA,IAAmB,SAAS,eAAA,GAAmB,MAAA;AAClG,EAAA,MAAM,oBAAoB,QAAA,EAAU,IAAA,KAAS,SAAA,GAAa,eAAA,IAAmB,SAAS,UAAA,GAAc,MAAA;AAEpG,EAAA,MAAM,OAAA,GAAA,CACH,QAAA,EAAU,IAAA,KAAS,QAAA,IAAY,QAAA,EAAU,IAAA,KAAS,UAAA,KAAe,QAAA,EAAU,eAAA,GACxE,QAAA,CAAS,eAAA,CAAgB,UAAU,CAAA,GACnC,MAAA;AAEN,EAAA,IAAI,qBACF,OAAO,cAAA,KAAmB,QAAA,mBACxB,GAAA,CAAC,gBAAa,QAAA,EAAU,cAAA,EAAgB,SAAA,EAAU,uBAAA,EAC/C,0BACH,CAAA,mBAEA,GAAA,CAAC,cAAW,IAAA,EAAM,cAAA,EAAgB,eAAY,sBAAA,EAAuB,CAAA;AAGzE,EAAA,IAAI,iBAAA,IAAqB,CAAC,QAAA,EAAU,2BAAQ,YAAA,EAAA,EAAa,CAAA;AAEzD,EAAA,MAAM,oBAAA,GAAuB,UAAA,IAAc,CAAC,CAAC,MAAA;AAC7C,EAAA,MAAM,QAAA,GAAW,WAAA,IAAe,OAAA,CAAQ,KAAK,CAAA;AAC7C,EAAA,MAAM,OAAA,GACJ,QAAA,IACA,OAAA,CAAQ,cAAc,CAAA,IACtB,mBAAmB,EAAE,oBAAA,EAAsB,UAAA,EAAY,oBAAA,EAAsB,CAAA;AAE/E,EAAA,uBACE,GAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,aAAA,EAAY,gBAAA;AAAA,MACZ,IAAA,kBAAM,GAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAU,oBAAA,EAAqB,CAAA;AAAA,MACnD,OAAO,QAAA,CAAS,IAAA;AAAA,MAChB,gBAAA,EAAkB,KAAA;AAAA,MAClB,SAAA,EACE,QAAA,EAAU,IAAA,KAAS,SAAA,mBACjB,GAAA;AAAA,QAAC,kCAAA;AAAA,QAAA;AAAA,UACC,iBAAiB,eAAA,IAAmB,EAAA;AAAA,UACpC,KAAA,EAAO;AAAA;AAAA,OACT,GACE,SAAS,MAAA,IAAU,OAAA,EAAS,4BAC9B,GAAA,CAAC,mCAAA,EAAA,EAAoC,cAAA,EAAgB,OAAA,EAAS,CAAA,GAC5D,IAAA;AAAA,MAGL,qCACC,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,QAAA,CAAC,WAAA,IAAe,KAAA,oBACf,GAAA,CAAC,6BAAA,EAAA,EAA8B,YAAwB,YAAA,EAAc,KAAA,EAAO,iBAAA,EAAiB,IAAA,EAC3F,QAAA,kBAAA,GAAA,CAAC,qBAAA,EAAA,EAAsB,UAAA,EAAwB,QAAA,EAAoB,OAAc,CAAA,EACnF,CAAA;AAAA,QAGD,WAAA,oBAAe,GAAA,CAAC,qBAAA,EAAA,EAAsB,UAAA,EAAwB,UAAoB,KAAA,EAAc,CAAA;AAAA,QAEhG,kBAAA,KAAuB,MAAA,IAAa,cAAA,oBACnC,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,gBAAa,QAAA,EAAA,0BAAA,EAAwB,CAAA;AAAA,UACrC;AAAA,SAAA,EACH,CAAA;AAAA,wBAGF,GAAA;AAAA,UAAC,mBAAA;AAAA,UAAA;AAAA,YACC,UAAA,EAAY,oBAAA;AAAA,YACZ,UAAA;AAAA,YACA,oBAAA;AAAA,YACA,QAAA;AAAA,YACA,SAAA;AAAA,YACA,cAAA,EAAgB,UAAU,IAAA,KAAS;AAAA;AAAA;AACrC,OAAA,EACF;AAAA;AAAA,GAEJ;AAEJ;AAQA,MAAM,wBAAwB,CAAC,EAAE,UAAA,EAAY,QAAA,EAAU,OAAM,KAAkC;AAC7F,EAAA,MAAM,cAAA,GAAiB,uBAAA,CAAwB,UAAA,EAAY,UAAU,EAAE,CAAC,CAAA;AACxE,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,gBAAA,EAAiB;AAClC,EAAA,MAAM,EAAE,2BAAA,EAA4B,GAAI,UAAA,CAAW,kBAAkB,CAAA;AAErE,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,8BAAA,EACb,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,IAAA,kBAAM,GAAA,CAAC,YAAA,EAAA,EAAa,CAAA,EAAI,MAAA,kBAAQ,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAM,CAAA,WAAA,EAAc,UAAU,CAAA,MAAA,CAAA,EAAU,GAAI,QAAA,EAAA,gBAAA,EAE1F,CAAA;AAAA,MACC,yBACC,GAAA,CAAC,MAAA,EAAA,EAAO,IAAA,kBAAM,GAAA,CAAC,OAAI,CAAA,EAAI,MAAA,kBAAQ,GAAA,CAAC,IAAA,EAAA,EAAK,MAAM,CAAA,WAAA,EAAc,UAAU,UAAU,KAAK,CAAA,CAAA,EAAI,GAAI,QAAA,EAAA,SAAA,EAE1F;AAAA,KAAA,EAEJ,CAAA;AAAA,oBAEA,GAAA,CAAC,4BAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,0BAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,4CAAA,EACb,QAAA,kBAAA,GAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACC,UAAA;AAAA,UACA,QAAA;AAAA,UACA,SAAA,EAAW,2BAAA;AAAA,UACX;AAAA;AAAA,OACF,EACF,CAAA;AAAA,sBACA,GAAA,CAAC,2BAAwB,cAAA,EAAgC;AAAA,KAAA,EAC3D,CAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ,CAAA;AAEA,MAAM,uBAAA,GAA0B,CAAC,EAAE,cAAA,EAAe,KAA+C;AAC/F,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,qBAAA,EAAsB;AAC7C,EAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AACxB,EAAA,2BACG,KAAA,EAAA,EAAI,SAAA,EAAU,iGACb,QAAA,kBAAA,GAAA,CAAC,yBAAA,EAAA,EAA0B,gBAAgC,CAAA,EAC7D,CAAA;AAEJ,CAAA;AAGO,MAAM,iBAAA,GAAoB,CAAC,iBAAA,KAAgD;AAChF,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,UAAA,CAAW,kBAAkB,CAAA;AAEnD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,iBAAA,EAAmB;AACxB,IAAA,SAAA,CAAU,iBAAiB,CAAA;AAAA,EAC7B,CAAA,EAAG,CAAC,iBAAA,EAAmB,SAAS,CAAC,CAAA;AACnC;;;;"}
|
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
4
4
|
|
|
5
5
|
require('react/jsx-runtime');
|
|
6
6
|
require('react');
|
|
7
|
-
const domains_chat_tools_badges_agentBadge = require('../../../tool-card-
|
|
7
|
+
const domains_chat_tools_badges_agentBadge = require('../../../tool-card-rxo27sve.cjs');
|
|
8
8
|
require('./badges/file-tree-badge.cjs.js');
|
|
9
9
|
require('./badges/sandbox-execution-badge.cjs.js');
|
|
10
10
|
require('./badges/tool-badge.cjs.js');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import 'react/jsx-runtime';
|
|
2
2
|
import 'react';
|
|
3
|
-
export { T as ToolCard, b as ToolCardInner } from '../../../tool-card-
|
|
3
|
+
export { T as ToolCard, b as ToolCardInner } from '../../../tool-card-C_K5PwrK.js';
|
|
4
4
|
import './badges/file-tree-badge.es.js';
|
|
5
5
|
import './badges/sandbox-execution-badge.es.js';
|
|
6
6
|
import './badges/tool-badge.es.js';
|
|
@@ -8,7 +8,7 @@ const React = require('react');
|
|
|
8
8
|
const domains_datasets_hooks_useDatasetMutations = require('../hooks/use-dataset-mutations.cjs.js');
|
|
9
9
|
const domains_datasets_hooks_useDatasets = require('../hooks/use-datasets.cjs.js');
|
|
10
10
|
const Button = require('../../../Button-CXhSUBxN.cjs');
|
|
11
|
-
const codeEditor = require('../../../code-editor-
|
|
11
|
+
const codeEditor = require('../../../code-editor-B_wPmKPf.cjs');
|
|
12
12
|
const label = require('../../../label-DfAhywj_.cjs');
|
|
13
13
|
const select = require('../../../select-DBY9LQFQ.cjs');
|
|
14
14
|
const sideDialog = require('../../../side-dialog-DFnD1498.cjs');
|
|
@@ -4,7 +4,7 @@ import { useState, useRef, useEffect } from 'react';
|
|
|
4
4
|
import { useDatasetMutations } from '../hooks/use-dataset-mutations.es.js';
|
|
5
5
|
import { useDatasets } from '../hooks/use-datasets.es.js';
|
|
6
6
|
import { B as Button } from '../../../Button-D43ghVKt.js';
|
|
7
|
-
import { C as CodeEditor } from '../../../code-editor-
|
|
7
|
+
import { C as CodeEditor } from '../../../code-editor-28chVxHw.js';
|
|
8
8
|
import { L as Label } from '../../../label-Dxsz0dFs.js';
|
|
9
9
|
import { S as Select, d as SelectTrigger, e as SelectValue, a as SelectContent, c as SelectItem } from '../../../select-DZeNf-kI.js';
|
|
10
10
|
import { S as SideDialog } from '../../../side-dialog-DCzCcZs6.js';
|
|
@@ -84,7 +84,6 @@ function buildTracesDrilldownUrl({
|
|
|
84
84
|
setIfDefined(params, domains_traces_traceFilters.TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.entityName, scope.entityName ?? dashboardFilter.entityName);
|
|
85
85
|
setIfDefined(params, domains_traces_traceFilters.TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.threadId, scope.threadId ?? dashboardFilter.threadId);
|
|
86
86
|
setIfDefined(params, domains_traces_traceFilters.TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.resourceId, scope.resourceId ?? dashboardFilter.resourceId);
|
|
87
|
-
setIfDefined(params, domains_traces_traceFilters.TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.entityId, dashboardFilter.entityId);
|
|
88
87
|
setIfDefined(params, domains_traces_traceFilters.TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.runId, dashboardFilter.runId);
|
|
89
88
|
setIfDefined(params, domains_traces_traceFilters.TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.sessionId, dashboardFilter.sessionId);
|
|
90
89
|
setIfDefined(params, domains_traces_traceFilters.TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.requestId, dashboardFilter.requestId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drilldown.cjs.js","sources":["../../../src/domains/metrics/drilldown.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport {\n LOGS_DATE_FROM_PARAM,\n LOGS_DATE_PRESET_PARAM,\n LOGS_DATE_TO_PARAM,\n LOGS_PROPERTY_FILTER_PARAM_BY_FIELD,\n LOGS_ROOT_ENTITY_TYPE_PARAM,\n} from '../logs/log-filters';\nimport type { LogsDatePreset } from '../logs/log-filters';\nimport {\n TRACE_DATE_FROM_PARAM,\n TRACE_DATE_PRESET_PARAM,\n TRACE_DATE_TO_PARAM,\n TRACE_LIST_MODE_PARAM,\n TRACE_PROPERTY_FILTER_PARAM_BY_FIELD,\n TRACE_ROOT_ENTITY_TYPE_PARAM,\n TRACE_STATUS_PARAM,\n} from '../traces/trace-filters';\nimport type { TraceDatePreset } from '../traces/types';\nimport type { DatePreset, DateRange } from './hooks/use-metrics';\nimport type { MetricsDimensionalFilter } from './metrics-filters';\n\n/** Map the metrics date preset (`24h`, `3d`, …) to the equivalent traces /\n * logs preset (`last-24h`, `last-3d`, …). `'custom'` is passed through and\n * explicit from/to dates are serialized separately. Returns `undefined` for\n * presets we can't translate — in that case we omit the date preset and rely\n * on concrete `from`/`to` timestamps. */\nfunction mapPreset(preset: DatePreset): TraceDatePreset | LogsDatePreset | undefined {\n switch (preset) {\n case '24h':\n return 'last-24h';\n case '3d':\n return 'last-3d';\n case '7d':\n return 'last-7d';\n case '14d':\n return 'last-14d';\n case '30d':\n return 'last-30d';\n case 'custom':\n return 'custom';\n default:\n return undefined;\n }\n}\n\n/** Narrow time window for a single chart node. Callers pass concrete start/end\n * Dates (typically bucket boundaries); these bypass the preset. */\nexport type DrilldownWindow = {\n from: Date;\n to: Date;\n};\n\n/** Narrow a raw timestamp into the time-series bucket window that surrounds\n * it. For a chart with `interval = 1h`, clicking a node at 14:37Z drills into\n * 14:00Z → 15:00Z. For `1d`, the corresponding UTC day. */\nexport function narrowWindowToBucket(tsMs: number, interval: '1h' | '1d'): DrilldownWindow {\n if (interval === '1h') {\n const from = new Date(tsMs);\n from.setUTCMinutes(0, 0, 0);\n const to = new Date(from.getTime() + 60 * 60 * 1000);\n return { from, to };\n }\n const from = new Date(tsMs);\n from.setUTCHours(0, 0, 0, 0);\n const to = new Date(from.getTime() + 24 * 60 * 60 * 1000);\n return { from, to };\n}\n\n/** Fields a card may use to scope the drilldown. Only the pieces the caller\n * knows are attached; everything else falls through to the current dashboard\n * filters. `status` is only valid for traces. */\nexport type DrilldownScope = {\n rootEntityType?: EntityType;\n entityName?: string;\n threadId?: string;\n resourceId?: string;\n model?: string;\n provider?: string;\n /** Trace-only. Valid for drill-downs from \"errors\" segments. */\n status?: 'running' | 'success' | 'error';\n /** Overrides date preset with explicit window bounds. */\n window?: DrilldownWindow;\n};\n\ntype BuildArgs = {\n /** Current metrics dashboard preset. */\n preset: DatePreset;\n /** Current metrics dashboard custom range (only honoured when preset === 'custom'). */\n customRange?: DateRange;\n /** Dashboard-level dimensional filters (environment, serviceName, tags, etc.). */\n dashboardFilter: MetricsDimensionalFilter;\n /** Per-card scoping applied on top of dashboard filters. */\n scope: DrilldownScope;\n /** Override the Traces page base path. Defaults to `/traces` (mastra Studio). */\n tracesBasePath?: string;\n /** Override the Logs page base path. Defaults to `/logs` (mastra Studio). */\n logsBasePath?: string;\n};\n\nfunction applyDate(\n params: URLSearchParams,\n presetKey: string,\n fromKey: string,\n toKey: string,\n preset: DatePreset,\n customRange: DateRange | undefined,\n window: DrilldownWindow | undefined,\n): void {\n // A concrete window always wins — it's a precise node-level drilldown.\n if (window) {\n params.set(presetKey, 'custom');\n params.set(fromKey, window.from.toISOString());\n params.set(toKey, window.to.toISOString());\n return;\n }\n if (preset === 'custom') {\n params.set(presetKey, 'custom');\n if (customRange?.from) params.set(fromKey, customRange.from.toISOString());\n if (customRange?.to) params.set(toKey, customRange.to.toISOString());\n return;\n }\n const mapped = mapPreset(preset);\n if (mapped) params.set(presetKey, mapped);\n}\n\nfunction setIfDefined(params: URLSearchParams, key: string, value: string | undefined | null): void {\n if (typeof value === 'string' && value.length > 0) {\n params.set(key, value);\n }\n}\n\nfunction appendArray(params: URLSearchParams, key: string, values: string[] | undefined): void {\n if (!Array.isArray(values) || values.length === 0) return;\n for (const v of values) if (v) params.append(key, v);\n}\n\n/** Build a relative URL to the Traces page pre-filtered by the dashboard\n * filters + per-card scope. */\nexport function buildTracesDrilldownUrl({\n preset,\n customRange,\n dashboardFilter,\n scope,\n tracesBasePath = '/traces',\n}: BuildArgs): string {\n const params = new URLSearchParams();\n params.set(TRACE_LIST_MODE_PARAM, 'branches');\n\n applyDate(\n params,\n TRACE_DATE_PRESET_PARAM,\n TRACE_DATE_FROM_PARAM,\n TRACE_DATE_TO_PARAM,\n preset,\n customRange,\n scope.window,\n );\n\n // Scope overrides dashboard filter when both are present.\n const rootEntityType = scope.rootEntityType ?? dashboardFilter.rootEntityType;\n if (rootEntityType) params.set(TRACE_ROOT_ENTITY_TYPE_PARAM, rootEntityType);\n\n if (scope.status) params.set(TRACE_STATUS_PARAM, scope.status);\n\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.entityName, scope.entityName ?? dashboardFilter.entityName);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.threadId, scope.threadId ?? dashboardFilter.threadId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.resourceId, scope.resourceId ?? dashboardFilter.resourceId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.entityId, dashboardFilter.entityId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.runId, dashboardFilter.runId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.sessionId, dashboardFilter.sessionId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.requestId, dashboardFilter.requestId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.userId, dashboardFilter.userId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.organizationId, dashboardFilter.organizationId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.experimentId, dashboardFilter.experimentId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.serviceName, dashboardFilter.serviceName);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.environment, dashboardFilter.environment);\n appendArray(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.tags, dashboardFilter.tags);\n\n const query = params.toString();\n return query ? `${tracesBasePath}?${query}` : tracesBasePath;\n}\n\n/** Build a relative URL to the Logs page pre-filtered by the dashboard filters\n * + per-card scope. Useful for \"View errors in logs\" affordances. */\nexport function buildLogsDrilldownUrl({\n preset,\n customRange,\n dashboardFilter,\n scope,\n logsBasePath = '/logs',\n}: BuildArgs): string {\n const params = new URLSearchParams();\n\n applyDate(\n params,\n LOGS_DATE_PRESET_PARAM,\n LOGS_DATE_FROM_PARAM,\n LOGS_DATE_TO_PARAM,\n preset,\n customRange,\n scope.window,\n );\n\n const rootEntityType = scope.rootEntityType ?? dashboardFilter.rootEntityType;\n if (rootEntityType) params.set(LOGS_ROOT_ENTITY_TYPE_PARAM, rootEntityType);\n\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.entityName, scope.entityName ?? dashboardFilter.entityName);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.threadId, scope.threadId ?? dashboardFilter.threadId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.resourceId, scope.resourceId ?? dashboardFilter.resourceId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.runId, dashboardFilter.runId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.sessionId, dashboardFilter.sessionId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.requestId, dashboardFilter.requestId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.userId, dashboardFilter.userId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.organizationId, dashboardFilter.organizationId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.experimentId, dashboardFilter.experimentId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.serviceName, dashboardFilter.serviceName);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.environment, dashboardFilter.environment);\n appendArray(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.tags, dashboardFilter.tags);\n\n // Error drill-ins always target log level=error. Status filter isn't valid\n // for logs, so we translate `status: 'error'` to `filterLevel=error`.\n if (scope.status === 'error') {\n params.append(LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.level, 'error');\n }\n\n const query = params.toString();\n return query ? `${logsBasePath}?${query}` : logsBasePath;\n}\n"],"names":["from","to","TRACE_LIST_MODE_PARAM","TRACE_DATE_PRESET_PARAM","TRACE_DATE_FROM_PARAM","TRACE_DATE_TO_PARAM","TRACE_ROOT_ENTITY_TYPE_PARAM","TRACE_STATUS_PARAM","TRACE_PROPERTY_FILTER_PARAM_BY_FIELD","LOGS_DATE_PRESET_PARAM","LOGS_DATE_FROM_PARAM","LOGS_DATE_TO_PARAM","LOGS_ROOT_ENTITY_TYPE_PARAM","LOGS_PROPERTY_FILTER_PARAM_BY_FIELD"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"drilldown.cjs.js","sources":["../../../src/domains/metrics/drilldown.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport {\n LOGS_DATE_FROM_PARAM,\n LOGS_DATE_PRESET_PARAM,\n LOGS_DATE_TO_PARAM,\n LOGS_PROPERTY_FILTER_PARAM_BY_FIELD,\n LOGS_ROOT_ENTITY_TYPE_PARAM,\n} from '../logs/log-filters';\nimport type { LogsDatePreset } from '../logs/log-filters';\nimport {\n TRACE_DATE_FROM_PARAM,\n TRACE_DATE_PRESET_PARAM,\n TRACE_DATE_TO_PARAM,\n TRACE_LIST_MODE_PARAM,\n TRACE_PROPERTY_FILTER_PARAM_BY_FIELD,\n TRACE_ROOT_ENTITY_TYPE_PARAM,\n TRACE_STATUS_PARAM,\n} from '../traces/trace-filters';\nimport type { TraceDatePreset } from '../traces/types';\nimport type { DatePreset, DateRange } from './hooks/use-metrics';\nimport type { MetricsDimensionalFilter } from './metrics-filters';\n\n/** Map the metrics date preset (`24h`, `3d`, …) to the equivalent traces /\n * logs preset (`last-24h`, `last-3d`, …). `'custom'` is passed through and\n * explicit from/to dates are serialized separately. Returns `undefined` for\n * presets we can't translate — in that case we omit the date preset and rely\n * on concrete `from`/`to` timestamps. */\nfunction mapPreset(preset: DatePreset): TraceDatePreset | LogsDatePreset | undefined {\n switch (preset) {\n case '24h':\n return 'last-24h';\n case '3d':\n return 'last-3d';\n case '7d':\n return 'last-7d';\n case '14d':\n return 'last-14d';\n case '30d':\n return 'last-30d';\n case 'custom':\n return 'custom';\n default:\n return undefined;\n }\n}\n\n/** Narrow time window for a single chart node. Callers pass concrete start/end\n * Dates (typically bucket boundaries); these bypass the preset. */\nexport type DrilldownWindow = {\n from: Date;\n to: Date;\n};\n\n/** Narrow a raw timestamp into the time-series bucket window that surrounds\n * it. For a chart with `interval = 1h`, clicking a node at 14:37Z drills into\n * 14:00Z → 15:00Z. For `1d`, the corresponding UTC day. */\nexport function narrowWindowToBucket(tsMs: number, interval: '1h' | '1d'): DrilldownWindow {\n if (interval === '1h') {\n const from = new Date(tsMs);\n from.setUTCMinutes(0, 0, 0);\n const to = new Date(from.getTime() + 60 * 60 * 1000);\n return { from, to };\n }\n const from = new Date(tsMs);\n from.setUTCHours(0, 0, 0, 0);\n const to = new Date(from.getTime() + 24 * 60 * 60 * 1000);\n return { from, to };\n}\n\n/** Fields a card may use to scope the drilldown. Only the pieces the caller\n * knows are attached; everything else falls through to the current dashboard\n * filters. `status` is only valid for traces. */\nexport type DrilldownScope = {\n rootEntityType?: EntityType;\n entityName?: string;\n threadId?: string;\n resourceId?: string;\n model?: string;\n provider?: string;\n /** Trace-only. Valid for drill-downs from \"errors\" segments. */\n status?: 'running' | 'success' | 'error';\n /** Overrides date preset with explicit window bounds. */\n window?: DrilldownWindow;\n};\n\ntype BuildArgs = {\n /** Current metrics dashboard preset. */\n preset: DatePreset;\n /** Current metrics dashboard custom range (only honoured when preset === 'custom'). */\n customRange?: DateRange;\n /** Dashboard-level dimensional filters (environment, serviceName, tags, etc.). */\n dashboardFilter: MetricsDimensionalFilter;\n /** Per-card scoping applied on top of dashboard filters. */\n scope: DrilldownScope;\n /** Override the Traces page base path. Defaults to `/traces` (mastra Studio). */\n tracesBasePath?: string;\n /** Override the Logs page base path. Defaults to `/logs` (mastra Studio). */\n logsBasePath?: string;\n};\n\nfunction applyDate(\n params: URLSearchParams,\n presetKey: string,\n fromKey: string,\n toKey: string,\n preset: DatePreset,\n customRange: DateRange | undefined,\n window: DrilldownWindow | undefined,\n): void {\n // A concrete window always wins — it's a precise node-level drilldown.\n if (window) {\n params.set(presetKey, 'custom');\n params.set(fromKey, window.from.toISOString());\n params.set(toKey, window.to.toISOString());\n return;\n }\n if (preset === 'custom') {\n params.set(presetKey, 'custom');\n if (customRange?.from) params.set(fromKey, customRange.from.toISOString());\n if (customRange?.to) params.set(toKey, customRange.to.toISOString());\n return;\n }\n const mapped = mapPreset(preset);\n if (mapped) params.set(presetKey, mapped);\n}\n\nfunction setIfDefined(params: URLSearchParams, key: string, value: string | undefined | null): void {\n if (typeof value === 'string' && value.length > 0) {\n params.set(key, value);\n }\n}\n\nfunction appendArray(params: URLSearchParams, key: string, values: string[] | undefined): void {\n if (!Array.isArray(values) || values.length === 0) return;\n for (const v of values) if (v) params.append(key, v);\n}\n\n/** Build a relative URL to the Traces page pre-filtered by the dashboard\n * filters + per-card scope. */\nexport function buildTracesDrilldownUrl({\n preset,\n customRange,\n dashboardFilter,\n scope,\n tracesBasePath = '/traces',\n}: BuildArgs): string {\n const params = new URLSearchParams();\n params.set(TRACE_LIST_MODE_PARAM, 'branches');\n\n applyDate(\n params,\n TRACE_DATE_PRESET_PARAM,\n TRACE_DATE_FROM_PARAM,\n TRACE_DATE_TO_PARAM,\n preset,\n customRange,\n scope.window,\n );\n\n // Scope overrides dashboard filter when both are present.\n const rootEntityType = scope.rootEntityType ?? dashboardFilter.rootEntityType;\n if (rootEntityType) params.set(TRACE_ROOT_ENTITY_TYPE_PARAM, rootEntityType);\n\n if (scope.status) params.set(TRACE_STATUS_PARAM, scope.status);\n\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.entityName, scope.entityName ?? dashboardFilter.entityName);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.threadId, scope.threadId ?? dashboardFilter.threadId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.resourceId, scope.resourceId ?? dashboardFilter.resourceId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.runId, dashboardFilter.runId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.sessionId, dashboardFilter.sessionId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.requestId, dashboardFilter.requestId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.userId, dashboardFilter.userId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.organizationId, dashboardFilter.organizationId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.experimentId, dashboardFilter.experimentId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.serviceName, dashboardFilter.serviceName);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.environment, dashboardFilter.environment);\n appendArray(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.tags, dashboardFilter.tags);\n\n const query = params.toString();\n return query ? `${tracesBasePath}?${query}` : tracesBasePath;\n}\n\n/** Build a relative URL to the Logs page pre-filtered by the dashboard filters\n * + per-card scope. Useful for \"View errors in logs\" affordances. */\nexport function buildLogsDrilldownUrl({\n preset,\n customRange,\n dashboardFilter,\n scope,\n logsBasePath = '/logs',\n}: BuildArgs): string {\n const params = new URLSearchParams();\n\n applyDate(\n params,\n LOGS_DATE_PRESET_PARAM,\n LOGS_DATE_FROM_PARAM,\n LOGS_DATE_TO_PARAM,\n preset,\n customRange,\n scope.window,\n );\n\n const rootEntityType = scope.rootEntityType ?? dashboardFilter.rootEntityType;\n if (rootEntityType) params.set(LOGS_ROOT_ENTITY_TYPE_PARAM, rootEntityType);\n\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.entityName, scope.entityName ?? dashboardFilter.entityName);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.threadId, scope.threadId ?? dashboardFilter.threadId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.resourceId, scope.resourceId ?? dashboardFilter.resourceId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.runId, dashboardFilter.runId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.sessionId, dashboardFilter.sessionId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.requestId, dashboardFilter.requestId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.userId, dashboardFilter.userId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.organizationId, dashboardFilter.organizationId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.experimentId, dashboardFilter.experimentId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.serviceName, dashboardFilter.serviceName);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.environment, dashboardFilter.environment);\n appendArray(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.tags, dashboardFilter.tags);\n\n // Error drill-ins always target log level=error. Status filter isn't valid\n // for logs, so we translate `status: 'error'` to `filterLevel=error`.\n if (scope.status === 'error') {\n params.append(LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.level, 'error');\n }\n\n const query = params.toString();\n return query ? `${logsBasePath}?${query}` : logsBasePath;\n}\n"],"names":["from","to","TRACE_LIST_MODE_PARAM","TRACE_DATE_PRESET_PARAM","TRACE_DATE_FROM_PARAM","TRACE_DATE_TO_PARAM","TRACE_ROOT_ENTITY_TYPE_PARAM","TRACE_STATUS_PARAM","TRACE_PROPERTY_FILTER_PARAM_BY_FIELD","LOGS_DATE_PRESET_PARAM","LOGS_DATE_FROM_PARAM","LOGS_DATE_TO_PARAM","LOGS_ROOT_ENTITY_TYPE_PARAM","LOGS_PROPERTY_FILTER_PARAM_BY_FIELD"],"mappings":"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"}
|
|
@@ -80,7 +80,6 @@ function buildTracesDrilldownUrl({
|
|
|
80
80
|
setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.entityName, scope.entityName ?? dashboardFilter.entityName);
|
|
81
81
|
setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.threadId, scope.threadId ?? dashboardFilter.threadId);
|
|
82
82
|
setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.resourceId, scope.resourceId ?? dashboardFilter.resourceId);
|
|
83
|
-
setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.entityId, dashboardFilter.entityId);
|
|
84
83
|
setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.runId, dashboardFilter.runId);
|
|
85
84
|
setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.sessionId, dashboardFilter.sessionId);
|
|
86
85
|
setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.requestId, dashboardFilter.requestId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drilldown.es.js","sources":["../../../src/domains/metrics/drilldown.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport {\n LOGS_DATE_FROM_PARAM,\n LOGS_DATE_PRESET_PARAM,\n LOGS_DATE_TO_PARAM,\n LOGS_PROPERTY_FILTER_PARAM_BY_FIELD,\n LOGS_ROOT_ENTITY_TYPE_PARAM,\n} from '../logs/log-filters';\nimport type { LogsDatePreset } from '../logs/log-filters';\nimport {\n TRACE_DATE_FROM_PARAM,\n TRACE_DATE_PRESET_PARAM,\n TRACE_DATE_TO_PARAM,\n TRACE_LIST_MODE_PARAM,\n TRACE_PROPERTY_FILTER_PARAM_BY_FIELD,\n TRACE_ROOT_ENTITY_TYPE_PARAM,\n TRACE_STATUS_PARAM,\n} from '../traces/trace-filters';\nimport type { TraceDatePreset } from '../traces/types';\nimport type { DatePreset, DateRange } from './hooks/use-metrics';\nimport type { MetricsDimensionalFilter } from './metrics-filters';\n\n/** Map the metrics date preset (`24h`, `3d`, …) to the equivalent traces /\n * logs preset (`last-24h`, `last-3d`, …). `'custom'` is passed through and\n * explicit from/to dates are serialized separately. Returns `undefined` for\n * presets we can't translate — in that case we omit the date preset and rely\n * on concrete `from`/`to` timestamps. */\nfunction mapPreset(preset: DatePreset): TraceDatePreset | LogsDatePreset | undefined {\n switch (preset) {\n case '24h':\n return 'last-24h';\n case '3d':\n return 'last-3d';\n case '7d':\n return 'last-7d';\n case '14d':\n return 'last-14d';\n case '30d':\n return 'last-30d';\n case 'custom':\n return 'custom';\n default:\n return undefined;\n }\n}\n\n/** Narrow time window for a single chart node. Callers pass concrete start/end\n * Dates (typically bucket boundaries); these bypass the preset. */\nexport type DrilldownWindow = {\n from: Date;\n to: Date;\n};\n\n/** Narrow a raw timestamp into the time-series bucket window that surrounds\n * it. For a chart with `interval = 1h`, clicking a node at 14:37Z drills into\n * 14:00Z → 15:00Z. For `1d`, the corresponding UTC day. */\nexport function narrowWindowToBucket(tsMs: number, interval: '1h' | '1d'): DrilldownWindow {\n if (interval === '1h') {\n const from = new Date(tsMs);\n from.setUTCMinutes(0, 0, 0);\n const to = new Date(from.getTime() + 60 * 60 * 1000);\n return { from, to };\n }\n const from = new Date(tsMs);\n from.setUTCHours(0, 0, 0, 0);\n const to = new Date(from.getTime() + 24 * 60 * 60 * 1000);\n return { from, to };\n}\n\n/** Fields a card may use to scope the drilldown. Only the pieces the caller\n * knows are attached; everything else falls through to the current dashboard\n * filters. `status` is only valid for traces. */\nexport type DrilldownScope = {\n rootEntityType?: EntityType;\n entityName?: string;\n threadId?: string;\n resourceId?: string;\n model?: string;\n provider?: string;\n /** Trace-only. Valid for drill-downs from \"errors\" segments. */\n status?: 'running' | 'success' | 'error';\n /** Overrides date preset with explicit window bounds. */\n window?: DrilldownWindow;\n};\n\ntype BuildArgs = {\n /** Current metrics dashboard preset. */\n preset: DatePreset;\n /** Current metrics dashboard custom range (only honoured when preset === 'custom'). */\n customRange?: DateRange;\n /** Dashboard-level dimensional filters (environment, serviceName, tags, etc.). */\n dashboardFilter: MetricsDimensionalFilter;\n /** Per-card scoping applied on top of dashboard filters. */\n scope: DrilldownScope;\n /** Override the Traces page base path. Defaults to `/traces` (mastra Studio). */\n tracesBasePath?: string;\n /** Override the Logs page base path. Defaults to `/logs` (mastra Studio). */\n logsBasePath?: string;\n};\n\nfunction applyDate(\n params: URLSearchParams,\n presetKey: string,\n fromKey: string,\n toKey: string,\n preset: DatePreset,\n customRange: DateRange | undefined,\n window: DrilldownWindow | undefined,\n): void {\n // A concrete window always wins — it's a precise node-level drilldown.\n if (window) {\n params.set(presetKey, 'custom');\n params.set(fromKey, window.from.toISOString());\n params.set(toKey, window.to.toISOString());\n return;\n }\n if (preset === 'custom') {\n params.set(presetKey, 'custom');\n if (customRange?.from) params.set(fromKey, customRange.from.toISOString());\n if (customRange?.to) params.set(toKey, customRange.to.toISOString());\n return;\n }\n const mapped = mapPreset(preset);\n if (mapped) params.set(presetKey, mapped);\n}\n\nfunction setIfDefined(params: URLSearchParams, key: string, value: string | undefined | null): void {\n if (typeof value === 'string' && value.length > 0) {\n params.set(key, value);\n }\n}\n\nfunction appendArray(params: URLSearchParams, key: string, values: string[] | undefined): void {\n if (!Array.isArray(values) || values.length === 0) return;\n for (const v of values) if (v) params.append(key, v);\n}\n\n/** Build a relative URL to the Traces page pre-filtered by the dashboard\n * filters + per-card scope. */\nexport function buildTracesDrilldownUrl({\n preset,\n customRange,\n dashboardFilter,\n scope,\n tracesBasePath = '/traces',\n}: BuildArgs): string {\n const params = new URLSearchParams();\n params.set(TRACE_LIST_MODE_PARAM, 'branches');\n\n applyDate(\n params,\n TRACE_DATE_PRESET_PARAM,\n TRACE_DATE_FROM_PARAM,\n TRACE_DATE_TO_PARAM,\n preset,\n customRange,\n scope.window,\n );\n\n // Scope overrides dashboard filter when both are present.\n const rootEntityType = scope.rootEntityType ?? dashboardFilter.rootEntityType;\n if (rootEntityType) params.set(TRACE_ROOT_ENTITY_TYPE_PARAM, rootEntityType);\n\n if (scope.status) params.set(TRACE_STATUS_PARAM, scope.status);\n\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.entityName, scope.entityName ?? dashboardFilter.entityName);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.threadId, scope.threadId ?? dashboardFilter.threadId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.resourceId, scope.resourceId ?? dashboardFilter.resourceId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.entityId, dashboardFilter.entityId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.runId, dashboardFilter.runId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.sessionId, dashboardFilter.sessionId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.requestId, dashboardFilter.requestId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.userId, dashboardFilter.userId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.organizationId, dashboardFilter.organizationId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.experimentId, dashboardFilter.experimentId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.serviceName, dashboardFilter.serviceName);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.environment, dashboardFilter.environment);\n appendArray(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.tags, dashboardFilter.tags);\n\n const query = params.toString();\n return query ? `${tracesBasePath}?${query}` : tracesBasePath;\n}\n\n/** Build a relative URL to the Logs page pre-filtered by the dashboard filters\n * + per-card scope. Useful for \"View errors in logs\" affordances. */\nexport function buildLogsDrilldownUrl({\n preset,\n customRange,\n dashboardFilter,\n scope,\n logsBasePath = '/logs',\n}: BuildArgs): string {\n const params = new URLSearchParams();\n\n applyDate(\n params,\n LOGS_DATE_PRESET_PARAM,\n LOGS_DATE_FROM_PARAM,\n LOGS_DATE_TO_PARAM,\n preset,\n customRange,\n scope.window,\n );\n\n const rootEntityType = scope.rootEntityType ?? dashboardFilter.rootEntityType;\n if (rootEntityType) params.set(LOGS_ROOT_ENTITY_TYPE_PARAM, rootEntityType);\n\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.entityName, scope.entityName ?? dashboardFilter.entityName);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.threadId, scope.threadId ?? dashboardFilter.threadId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.resourceId, scope.resourceId ?? dashboardFilter.resourceId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.runId, dashboardFilter.runId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.sessionId, dashboardFilter.sessionId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.requestId, dashboardFilter.requestId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.userId, dashboardFilter.userId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.organizationId, dashboardFilter.organizationId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.experimentId, dashboardFilter.experimentId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.serviceName, dashboardFilter.serviceName);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.environment, dashboardFilter.environment);\n appendArray(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.tags, dashboardFilter.tags);\n\n // Error drill-ins always target log level=error. Status filter isn't valid\n // for logs, so we translate `status: 'error'` to `filterLevel=error`.\n if (scope.status === 'error') {\n params.append(LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.level, 'error');\n }\n\n const query = params.toString();\n return query ? `${logsBasePath}?${query}` : logsBasePath;\n}\n"],"names":["from","to"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"drilldown.es.js","sources":["../../../src/domains/metrics/drilldown.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport {\n LOGS_DATE_FROM_PARAM,\n LOGS_DATE_PRESET_PARAM,\n LOGS_DATE_TO_PARAM,\n LOGS_PROPERTY_FILTER_PARAM_BY_FIELD,\n LOGS_ROOT_ENTITY_TYPE_PARAM,\n} from '../logs/log-filters';\nimport type { LogsDatePreset } from '../logs/log-filters';\nimport {\n TRACE_DATE_FROM_PARAM,\n TRACE_DATE_PRESET_PARAM,\n TRACE_DATE_TO_PARAM,\n TRACE_LIST_MODE_PARAM,\n TRACE_PROPERTY_FILTER_PARAM_BY_FIELD,\n TRACE_ROOT_ENTITY_TYPE_PARAM,\n TRACE_STATUS_PARAM,\n} from '../traces/trace-filters';\nimport type { TraceDatePreset } from '../traces/types';\nimport type { DatePreset, DateRange } from './hooks/use-metrics';\nimport type { MetricsDimensionalFilter } from './metrics-filters';\n\n/** Map the metrics date preset (`24h`, `3d`, …) to the equivalent traces /\n * logs preset (`last-24h`, `last-3d`, …). `'custom'` is passed through and\n * explicit from/to dates are serialized separately. Returns `undefined` for\n * presets we can't translate — in that case we omit the date preset and rely\n * on concrete `from`/`to` timestamps. */\nfunction mapPreset(preset: DatePreset): TraceDatePreset | LogsDatePreset | undefined {\n switch (preset) {\n case '24h':\n return 'last-24h';\n case '3d':\n return 'last-3d';\n case '7d':\n return 'last-7d';\n case '14d':\n return 'last-14d';\n case '30d':\n return 'last-30d';\n case 'custom':\n return 'custom';\n default:\n return undefined;\n }\n}\n\n/** Narrow time window for a single chart node. Callers pass concrete start/end\n * Dates (typically bucket boundaries); these bypass the preset. */\nexport type DrilldownWindow = {\n from: Date;\n to: Date;\n};\n\n/** Narrow a raw timestamp into the time-series bucket window that surrounds\n * it. For a chart with `interval = 1h`, clicking a node at 14:37Z drills into\n * 14:00Z → 15:00Z. For `1d`, the corresponding UTC day. */\nexport function narrowWindowToBucket(tsMs: number, interval: '1h' | '1d'): DrilldownWindow {\n if (interval === '1h') {\n const from = new Date(tsMs);\n from.setUTCMinutes(0, 0, 0);\n const to = new Date(from.getTime() + 60 * 60 * 1000);\n return { from, to };\n }\n const from = new Date(tsMs);\n from.setUTCHours(0, 0, 0, 0);\n const to = new Date(from.getTime() + 24 * 60 * 60 * 1000);\n return { from, to };\n}\n\n/** Fields a card may use to scope the drilldown. Only the pieces the caller\n * knows are attached; everything else falls through to the current dashboard\n * filters. `status` is only valid for traces. */\nexport type DrilldownScope = {\n rootEntityType?: EntityType;\n entityName?: string;\n threadId?: string;\n resourceId?: string;\n model?: string;\n provider?: string;\n /** Trace-only. Valid for drill-downs from \"errors\" segments. */\n status?: 'running' | 'success' | 'error';\n /** Overrides date preset with explicit window bounds. */\n window?: DrilldownWindow;\n};\n\ntype BuildArgs = {\n /** Current metrics dashboard preset. */\n preset: DatePreset;\n /** Current metrics dashboard custom range (only honoured when preset === 'custom'). */\n customRange?: DateRange;\n /** Dashboard-level dimensional filters (environment, serviceName, tags, etc.). */\n dashboardFilter: MetricsDimensionalFilter;\n /** Per-card scoping applied on top of dashboard filters. */\n scope: DrilldownScope;\n /** Override the Traces page base path. Defaults to `/traces` (mastra Studio). */\n tracesBasePath?: string;\n /** Override the Logs page base path. Defaults to `/logs` (mastra Studio). */\n logsBasePath?: string;\n};\n\nfunction applyDate(\n params: URLSearchParams,\n presetKey: string,\n fromKey: string,\n toKey: string,\n preset: DatePreset,\n customRange: DateRange | undefined,\n window: DrilldownWindow | undefined,\n): void {\n // A concrete window always wins — it's a precise node-level drilldown.\n if (window) {\n params.set(presetKey, 'custom');\n params.set(fromKey, window.from.toISOString());\n params.set(toKey, window.to.toISOString());\n return;\n }\n if (preset === 'custom') {\n params.set(presetKey, 'custom');\n if (customRange?.from) params.set(fromKey, customRange.from.toISOString());\n if (customRange?.to) params.set(toKey, customRange.to.toISOString());\n return;\n }\n const mapped = mapPreset(preset);\n if (mapped) params.set(presetKey, mapped);\n}\n\nfunction setIfDefined(params: URLSearchParams, key: string, value: string | undefined | null): void {\n if (typeof value === 'string' && value.length > 0) {\n params.set(key, value);\n }\n}\n\nfunction appendArray(params: URLSearchParams, key: string, values: string[] | undefined): void {\n if (!Array.isArray(values) || values.length === 0) return;\n for (const v of values) if (v) params.append(key, v);\n}\n\n/** Build a relative URL to the Traces page pre-filtered by the dashboard\n * filters + per-card scope. */\nexport function buildTracesDrilldownUrl({\n preset,\n customRange,\n dashboardFilter,\n scope,\n tracesBasePath = '/traces',\n}: BuildArgs): string {\n const params = new URLSearchParams();\n params.set(TRACE_LIST_MODE_PARAM, 'branches');\n\n applyDate(\n params,\n TRACE_DATE_PRESET_PARAM,\n TRACE_DATE_FROM_PARAM,\n TRACE_DATE_TO_PARAM,\n preset,\n customRange,\n scope.window,\n );\n\n // Scope overrides dashboard filter when both are present.\n const rootEntityType = scope.rootEntityType ?? dashboardFilter.rootEntityType;\n if (rootEntityType) params.set(TRACE_ROOT_ENTITY_TYPE_PARAM, rootEntityType);\n\n if (scope.status) params.set(TRACE_STATUS_PARAM, scope.status);\n\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.entityName, scope.entityName ?? dashboardFilter.entityName);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.threadId, scope.threadId ?? dashboardFilter.threadId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.resourceId, scope.resourceId ?? dashboardFilter.resourceId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.runId, dashboardFilter.runId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.sessionId, dashboardFilter.sessionId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.requestId, dashboardFilter.requestId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.userId, dashboardFilter.userId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.organizationId, dashboardFilter.organizationId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.experimentId, dashboardFilter.experimentId);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.serviceName, dashboardFilter.serviceName);\n setIfDefined(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.environment, dashboardFilter.environment);\n appendArray(params, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD.tags, dashboardFilter.tags);\n\n const query = params.toString();\n return query ? `${tracesBasePath}?${query}` : tracesBasePath;\n}\n\n/** Build a relative URL to the Logs page pre-filtered by the dashboard filters\n * + per-card scope. Useful for \"View errors in logs\" affordances. */\nexport function buildLogsDrilldownUrl({\n preset,\n customRange,\n dashboardFilter,\n scope,\n logsBasePath = '/logs',\n}: BuildArgs): string {\n const params = new URLSearchParams();\n\n applyDate(\n params,\n LOGS_DATE_PRESET_PARAM,\n LOGS_DATE_FROM_PARAM,\n LOGS_DATE_TO_PARAM,\n preset,\n customRange,\n scope.window,\n );\n\n const rootEntityType = scope.rootEntityType ?? dashboardFilter.rootEntityType;\n if (rootEntityType) params.set(LOGS_ROOT_ENTITY_TYPE_PARAM, rootEntityType);\n\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.entityName, scope.entityName ?? dashboardFilter.entityName);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.threadId, scope.threadId ?? dashboardFilter.threadId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.resourceId, scope.resourceId ?? dashboardFilter.resourceId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.runId, dashboardFilter.runId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.sessionId, dashboardFilter.sessionId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.requestId, dashboardFilter.requestId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.userId, dashboardFilter.userId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.organizationId, dashboardFilter.organizationId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.experimentId, dashboardFilter.experimentId);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.serviceName, dashboardFilter.serviceName);\n setIfDefined(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.environment, dashboardFilter.environment);\n appendArray(params, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.tags, dashboardFilter.tags);\n\n // Error drill-ins always target log level=error. Status filter isn't valid\n // for logs, so we translate `status: 'error'` to `filterLevel=error`.\n if (scope.status === 'error') {\n params.append(LOGS_PROPERTY_FILTER_PARAM_BY_FIELD.level, 'error');\n }\n\n const query = params.toString();\n return query ? `${logsBasePath}?${query}` : logsBasePath;\n}\n"],"names":["from","to"],"mappings":"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"}
|
|
@@ -12,7 +12,6 @@ const METRICS_SYNTHETIC_FILTER_FIELD_IDS = ["rootEntityType"];
|
|
|
12
12
|
const METRICS_ROOT_ENTITY_TYPE_PARAM = "rootEntityType";
|
|
13
13
|
const METRICS_PROPERTY_FILTER_PARAM_BY_FIELD = {
|
|
14
14
|
tags: "filterTags",
|
|
15
|
-
entityId: "filterEntityId",
|
|
16
15
|
entityName: "filterEntityName",
|
|
17
16
|
runId: "filterRunId",
|
|
18
17
|
threadId: "filterThreadId",
|
|
@@ -87,7 +86,6 @@ function createMetricsPropertyFilterFields({
|
|
|
87
86
|
emptyText: "No entity names found.",
|
|
88
87
|
isLoading: loading?.entityNames
|
|
89
88
|
},
|
|
90
|
-
{ id: "entityId", label: "Primitive ID", kind: "text" },
|
|
91
89
|
{
|
|
92
90
|
id: "tags",
|
|
93
91
|
label: "Tags",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics-filters.cjs.js","sources":["../../../src/domains/metrics/metrics-filters.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport type { PropertyFilterField, PropertyFilterToken } from '@/ds/components/PropertyFilter/types';\n\ntype EntityTypeValue = `${EntityType}`;\n\n/** Primitive type options — matches the traces filter vocabulary. */\nexport const METRICS_ROOT_ENTITY_TYPE_OPTIONS = [\n { label: 'Agent', entityType: 'agent' },\n { label: 'Workflow', entityType: 'workflow_run' },\n { label: 'Scorer', entityType: 'scorer' },\n { label: 'Ingest', entityType: 'rag_ingestion' },\n] as const satisfies readonly { label: string; entityType: EntityTypeValue }[];\n\n/** Field IDs that live in dedicated URL params (not the generic `filterX` set). */\nexport const METRICS_SYNTHETIC_FILTER_FIELD_IDS = ['rootEntityType'] as const;\n\nexport const METRICS_ROOT_ENTITY_TYPE_PARAM = 'rootEntityType';\n\n/** URL param name for each generic property filter field. Mirrors traces for\n * cross-page URL consistency (user can copy a trace's filter URL and paste\n * equivalent dimensions into metrics). */\nexport const METRICS_PROPERTY_FILTER_PARAM_BY_FIELD = {\n tags: 'filterTags',\n entityId: 'filterEntityId',\n entityName: 'filterEntityName',\n runId: 'filterRunId',\n threadId: 'filterThreadId',\n sessionId: 'filterSessionId',\n requestId: 'filterRequestId',\n resourceId: 'filterResourceId',\n userId: 'filterUserId',\n organizationId: 'filterOrganizationId',\n serviceName: 'filterServiceName',\n environment: 'filterEnvironment',\n experimentId: 'filterExperimentId',\n provider: 'filterProvider',\n model: 'filterModel',\n} as const;\n\nexport type MetricsPropertyFilterFieldId = keyof typeof METRICS_PROPERTY_FILTER_PARAM_BY_FIELD;\n\nexport const METRICS_PROPERTY_FILTER_FIELD_IDS = Object.keys(\n METRICS_PROPERTY_FILTER_PARAM_BY_FIELD,\n) as Array<MetricsPropertyFilterFieldId>;\n\nconst METRICS_FILTERS_STORAGE_KEY = 'mastra:metrics:saved-filters';\n\n/** Save the current metrics filter URL params so the metrics page can restore\n * them on next visit (same pattern as traces/logs). */\nexport function saveMetricsFiltersToStorage(params: URLSearchParams): void {\n const serialized = getPreservedMetricsFilterParams(params);\n try {\n localStorage.setItem(METRICS_FILTERS_STORAGE_KEY, serialized.toString());\n } catch {\n // localStorage may be unavailable — silently skip.\n }\n}\n\nexport function clearSavedMetricsFilters(): void {\n try {\n localStorage.removeItem(METRICS_FILTERS_STORAGE_KEY);\n } catch {\n // ignore\n }\n}\n\nexport function loadMetricsFiltersFromStorage(): URLSearchParams | null {\n try {\n const raw = localStorage.getItem(METRICS_FILTERS_STORAGE_KEY);\n if (!raw) return null;\n const parsed = new URLSearchParams(raw);\n return parsed.toString() ? parsed : null;\n } catch {\n return null;\n }\n}\n\nexport function hasAnyMetricsFilterParams(params: URLSearchParams): boolean {\n if (params.has(METRICS_ROOT_ENTITY_TYPE_PARAM)) return true;\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n if (params.has(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId])) return true;\n }\n return false;\n}\n\n/** Build the PropertyFilterField list shown in the metrics filter popover.\n *\n * The field order is curated for OLAP efficiency: columnar/LowCardinality\n * dimensions first, then bloom_filter-indexed high-cardinality IDs as\n * free-text. Fields that are expensive to filter without an index are\n * intentionally omitted from this dashboard surface. */\nexport function createMetricsPropertyFilterFields({\n availableTags,\n availableEntityNames,\n availableServiceNames,\n availableEnvironments,\n loading,\n}: {\n availableTags: string[];\n availableEntityNames: string[];\n availableServiceNames: string[];\n availableEnvironments: string[];\n loading?: {\n tags?: boolean;\n entityNames?: boolean;\n serviceNames?: boolean;\n environments?: boolean;\n };\n}): PropertyFilterField[] {\n const fields: PropertyFilterField[] = [\n {\n id: 'rootEntityType',\n label: 'Primitive type',\n kind: 'pick-multi',\n searchable: false,\n options: METRICS_ROOT_ENTITY_TYPE_OPTIONS.map(o => ({ label: o.label, value: o.entityType })),\n placeholder: 'Choose entity type',\n emptyText: 'No entity types.',\n },\n {\n id: 'entityName',\n label: 'Primitive name',\n kind: 'pick-multi',\n options: availableEntityNames.map(name => ({ label: name, value: name })),\n placeholder: 'Choose entity names',\n emptyText: 'No entity names found.',\n isLoading: loading?.entityNames,\n },\n { id: 'entityId', label: 'Primitive ID', kind: 'text' },\n {\n id: 'tags',\n label: 'Tags',\n kind: 'pick-multi',\n multi: true,\n options: availableTags.map(tag => ({ label: tag, value: tag })),\n placeholder: 'Choose tags',\n emptyText: 'No tags found.',\n isLoading: loading?.tags,\n },\n {\n id: 'serviceName',\n label: 'Service Name',\n kind: 'pick-multi',\n options: availableServiceNames.map(name => ({ label: name, value: name })),\n placeholder: 'Choose service names',\n emptyText: 'No service names found.',\n isLoading: loading?.serviceNames,\n },\n {\n id: 'environment',\n label: 'Environment',\n kind: 'pick-multi',\n options: availableEnvironments.map(env => ({ label: env, value: env })),\n placeholder: 'Choose environments',\n emptyText: 'No environments found.',\n isLoading: loading?.environments,\n },\n // Provider / model are filterable by URL (filterProvider / filterModel) but\n // are omitted from the popover until we expose a discovery endpoint.\n // High-cardinality IDs — free-text. Backed by bloom_filter skip indexes on\n // ClickHouse, narrow timestamp range pruning on DuckDB.\n { id: 'threadId', label: 'Thread ID', kind: 'text' },\n { id: 'resourceId', label: 'Resource ID', kind: 'text' },\n { id: 'userId', label: 'User ID', kind: 'text' },\n { id: 'organizationId', label: 'Organization ID', kind: 'text' },\n { id: 'runId', label: 'Run ID', kind: 'text' },\n { id: 'sessionId', label: 'Session ID', kind: 'text' },\n { id: 'requestId', label: 'Request ID', kind: 'text' },\n { id: 'experimentId', label: 'Experiment ID', kind: 'text' },\n ];\n const byLabel = (a: PropertyFilterField, b: PropertyFilterField) => a.label.localeCompare(b.label);\n const pickMulti = fields.filter(f => f.kind === 'pick-multi').sort(byLabel);\n const text = fields.filter(f => f.kind === 'text').sort(byLabel);\n return [...pickMulti, ...text];\n}\n\n/** Parse filter tokens from URL params, preserving insertion order. */\nexport function getMetricsPropertyFilterTokens(searchParams: URLSearchParams): PropertyFilterToken[] {\n const tokens: PropertyFilterToken[] = [];\n\n const paramToFieldId = new Map<string, string>([[METRICS_ROOT_ENTITY_TYPE_PARAM, 'rootEntityType']]);\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n paramToFieldId.set(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId], fieldId);\n }\n\n const seen = new Set<string>();\n for (const [paramName] of searchParams.entries()) {\n const fieldId = paramToFieldId.get(paramName);\n if (!fieldId || seen.has(fieldId)) continue;\n seen.add(fieldId);\n\n if (fieldId === 'tags') {\n const raw = searchParams.getAll(paramName);\n if (raw.length === 0) continue;\n tokens.push({ fieldId, value: raw.filter(Boolean) });\n continue;\n }\n\n // Multi-value pick-multi fields: collect all occurrences.\n if (\n fieldId === 'rootEntityType' ||\n fieldId === 'entityName' ||\n fieldId === 'serviceName' ||\n fieldId === 'environment' ||\n fieldId === 'provider' ||\n fieldId === 'model'\n ) {\n const raw = searchParams.getAll(paramName);\n if (raw.length > 1) {\n tokens.push({ fieldId, value: raw });\n continue;\n }\n }\n\n const value = searchParams.get(paramName);\n if (value !== null) tokens.push({ fieldId, value });\n }\n\n return tokens;\n}\n\n/** Return a fresh URLSearchParams containing only metrics filter params. */\nexport function getPreservedMetricsFilterParams(searchParams: URLSearchParams): URLSearchParams {\n const next = new URLSearchParams();\n const rootEntityValues = searchParams.getAll(METRICS_ROOT_ENTITY_TYPE_PARAM);\n for (const v of rootEntityValues) next.append(METRICS_ROOT_ENTITY_TYPE_PARAM, v);\n\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n const param = METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId];\n const values = searchParams.getAll(param);\n for (const v of values) next.append(param, v);\n }\n return next;\n}\n\n/** Mutate `params` in place: strip every metrics filter param, then re-write\n * them from `tokens` in order. Token insertion order drives URL order so\n * filter pill order is stable across reloads. */\nexport function applyMetricsPropertyFilterTokens(params: URLSearchParams, tokens: PropertyFilterToken[]): void {\n params.delete(METRICS_ROOT_ENTITY_TYPE_PARAM);\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n params.delete(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId]);\n }\n\n for (const token of tokens) {\n const paramName =\n token.fieldId === 'rootEntityType'\n ? METRICS_ROOT_ENTITY_TYPE_PARAM\n : METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[token.fieldId as MetricsPropertyFilterFieldId];\n if (!paramName) continue;\n\n if (Array.isArray(token.value)) {\n const values = token.value.filter(v => typeof v === 'string' && v !== '');\n if (values.length === 0) {\n // Keep an empty sentinel for `tags` so the pill survives a Reset.\n if (token.fieldId === 'tags') params.append(paramName, '');\n continue;\n }\n for (const v of values) params.append(paramName, v);\n } else if (typeof token.value === 'string') {\n // Persist even empty / 'Any' strings so newly-created pills (and\n // neutralized-but-still-visible pills after a Reset) survive URL\n // round-trips. `buildMetricsDimensionalFilter` drops these on the API\n // query side so neutrals never reach the backend.\n params.set(paramName, token.value.trim());\n }\n }\n}\n\n/** Shape of the dimensional filter object fed into `MetricsFilter` on client\n * calls. Kept compatible with `metricsFilterSchema` in @internal/core — every\n * scalar field maps to a single-string column filter, and `tags` is the only\n * array field (matched via `has()` / equivalent on backends). */\nexport type MetricsDimensionalFilter = {\n rootEntityType?: EntityType;\n entityName?: string;\n entityId?: string;\n tags?: string[];\n serviceName?: string;\n environment?: string;\n provider?: string;\n model?: string;\n threadId?: string;\n resourceId?: string;\n userId?: string;\n organizationId?: string;\n runId?: string;\n sessionId?: string;\n requestId?: string;\n experimentId?: string;\n};\n\n/** Convert the active token list into a `MetricsFilter`-compatible object.\n *\n * Single-value text fields are assigned as strings; `pick-multi` fields are\n * assigned as string arrays. Empty/neutral values are dropped. */\n/** \"Neutral\" sentinel for single-select pick-multi fields. Emitted by the\n * toolbar's Clear action so pills stay visible after reset; must be stripped\n * before the filter object is sent to the backend (it is not a valid enum\n * option for fields like `rootEntityType`). */\nconst NEUTRAL_PICK_VALUE = 'Any';\n\nfunction isNeutralValue(v: string): boolean {\n const trimmed = v.trim();\n return trimmed === '' || trimmed === NEUTRAL_PICK_VALUE;\n}\n\n/** `rootEntityType` is enum-valued at the backend; URL-supplied or stale stored\n * values can be arbitrary strings, so we validate against the allowed set\n * before letting them reach the filter object. Returns `undefined` if the\n * value isn't a known enum option. */\nconst VALID_ROOT_ENTITY_TYPES: ReadonlySet<EntityTypeValue> = new Set(\n METRICS_ROOT_ENTITY_TYPE_OPTIONS.map(o => o.entityType),\n);\nfunction toValidRootEntityType(v: string): EntityType | undefined {\n const trimmed = v.trim();\n return VALID_ROOT_ENTITY_TYPES.has(trimmed as EntityTypeValue) ? (trimmed as EntityType) : undefined;\n}\n\nexport function buildMetricsDimensionalFilter(tokens: PropertyFilterToken[]): MetricsDimensionalFilter {\n const result: MetricsDimensionalFilter = {};\n for (const token of tokens) {\n const fieldId = token.fieldId as keyof MetricsDimensionalFilter;\n if (Array.isArray(token.value)) {\n const values = token.value\n .filter((v): v is string => typeof v === 'string')\n .map(v => v.trim())\n .filter(v => !isNeutralValue(v));\n if (values.length === 0) continue;\n if (fieldId === 'tags') {\n result.tags = values;\n } else if (fieldId === 'rootEntityType') {\n const firstValue = values[0];\n const validated = firstValue !== undefined ? toValidRootEntityType(firstValue) : undefined;\n if (validated) result.rootEntityType = validated;\n } else {\n // Backend accepts a single string per dimension; take the first selection.\n (result as Record<string, unknown>)[fieldId] = values[0];\n }\n } else if (typeof token.value === 'string') {\n if (isNeutralValue(token.value)) continue;\n const trimmed = token.value.trim();\n if (fieldId === 'rootEntityType') {\n const validated = toValidRootEntityType(trimmed);\n if (validated) result.rootEntityType = validated;\n } else {\n (result as Record<string, unknown>)[fieldId] = trimmed;\n }\n }\n }\n return result;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"metrics-filters.cjs.js","sources":["../../../src/domains/metrics/metrics-filters.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport type { PropertyFilterField, PropertyFilterToken } from '@/ds/components/PropertyFilter/types';\n\ntype EntityTypeValue = `${EntityType}`;\n\n/** Primitive type options — matches the traces filter vocabulary. */\nexport const METRICS_ROOT_ENTITY_TYPE_OPTIONS = [\n { label: 'Agent', entityType: 'agent' },\n { label: 'Workflow', entityType: 'workflow_run' },\n { label: 'Scorer', entityType: 'scorer' },\n { label: 'Ingest', entityType: 'rag_ingestion' },\n] as const satisfies readonly { label: string; entityType: EntityTypeValue }[];\n\n/** Field IDs that live in dedicated URL params (not the generic `filterX` set). */\nexport const METRICS_SYNTHETIC_FILTER_FIELD_IDS = ['rootEntityType'] as const;\n\nexport const METRICS_ROOT_ENTITY_TYPE_PARAM = 'rootEntityType';\n\n/** URL param name for each generic property filter field. Mirrors traces for\n * cross-page URL consistency (user can copy a trace's filter URL and paste\n * equivalent dimensions into metrics). */\nexport const METRICS_PROPERTY_FILTER_PARAM_BY_FIELD = {\n tags: 'filterTags',\n entityName: 'filterEntityName',\n runId: 'filterRunId',\n threadId: 'filterThreadId',\n sessionId: 'filterSessionId',\n requestId: 'filterRequestId',\n resourceId: 'filterResourceId',\n userId: 'filterUserId',\n organizationId: 'filterOrganizationId',\n serviceName: 'filterServiceName',\n environment: 'filterEnvironment',\n experimentId: 'filterExperimentId',\n provider: 'filterProvider',\n model: 'filterModel',\n} as const;\n\nexport type MetricsPropertyFilterFieldId = keyof typeof METRICS_PROPERTY_FILTER_PARAM_BY_FIELD;\n\nexport const METRICS_PROPERTY_FILTER_FIELD_IDS = Object.keys(\n METRICS_PROPERTY_FILTER_PARAM_BY_FIELD,\n) as Array<MetricsPropertyFilterFieldId>;\n\nconst METRICS_FILTERS_STORAGE_KEY = 'mastra:metrics:saved-filters';\n\n/** Save the current metrics filter URL params so the metrics page can restore\n * them on next visit (same pattern as traces/logs). */\nexport function saveMetricsFiltersToStorage(params: URLSearchParams): void {\n const serialized = getPreservedMetricsFilterParams(params);\n try {\n localStorage.setItem(METRICS_FILTERS_STORAGE_KEY, serialized.toString());\n } catch {\n // localStorage may be unavailable — silently skip.\n }\n}\n\nexport function clearSavedMetricsFilters(): void {\n try {\n localStorage.removeItem(METRICS_FILTERS_STORAGE_KEY);\n } catch {\n // ignore\n }\n}\n\nexport function loadMetricsFiltersFromStorage(): URLSearchParams | null {\n try {\n const raw = localStorage.getItem(METRICS_FILTERS_STORAGE_KEY);\n if (!raw) return null;\n const parsed = new URLSearchParams(raw);\n return parsed.toString() ? parsed : null;\n } catch {\n return null;\n }\n}\n\nexport function hasAnyMetricsFilterParams(params: URLSearchParams): boolean {\n if (params.has(METRICS_ROOT_ENTITY_TYPE_PARAM)) return true;\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n if (params.has(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId])) return true;\n }\n return false;\n}\n\n/** Build the PropertyFilterField list shown in the metrics filter popover.\n *\n * The field order is curated for OLAP efficiency: columnar/LowCardinality\n * dimensions first, then bloom_filter-indexed high-cardinality IDs as\n * free-text. Fields that are expensive to filter without an index are\n * intentionally omitted from this dashboard surface. */\nexport function createMetricsPropertyFilterFields({\n availableTags,\n availableEntityNames,\n availableServiceNames,\n availableEnvironments,\n loading,\n}: {\n availableTags: string[];\n availableEntityNames: string[];\n availableServiceNames: string[];\n availableEnvironments: string[];\n loading?: {\n tags?: boolean;\n entityNames?: boolean;\n serviceNames?: boolean;\n environments?: boolean;\n };\n}): PropertyFilterField[] {\n const fields: PropertyFilterField[] = [\n {\n id: 'rootEntityType',\n label: 'Primitive type',\n kind: 'pick-multi',\n searchable: false,\n options: METRICS_ROOT_ENTITY_TYPE_OPTIONS.map(o => ({ label: o.label, value: o.entityType })),\n placeholder: 'Choose entity type',\n emptyText: 'No entity types.',\n },\n {\n id: 'entityName',\n label: 'Primitive name',\n kind: 'pick-multi',\n options: availableEntityNames.map(name => ({ label: name, value: name })),\n placeholder: 'Choose entity names',\n emptyText: 'No entity names found.',\n isLoading: loading?.entityNames,\n },\n {\n id: 'tags',\n label: 'Tags',\n kind: 'pick-multi',\n multi: true,\n options: availableTags.map(tag => ({ label: tag, value: tag })),\n placeholder: 'Choose tags',\n emptyText: 'No tags found.',\n isLoading: loading?.tags,\n },\n {\n id: 'serviceName',\n label: 'Service Name',\n kind: 'pick-multi',\n options: availableServiceNames.map(name => ({ label: name, value: name })),\n placeholder: 'Choose service names',\n emptyText: 'No service names found.',\n isLoading: loading?.serviceNames,\n },\n {\n id: 'environment',\n label: 'Environment',\n kind: 'pick-multi',\n options: availableEnvironments.map(env => ({ label: env, value: env })),\n placeholder: 'Choose environments',\n emptyText: 'No environments found.',\n isLoading: loading?.environments,\n },\n // Provider / model are filterable by URL (filterProvider / filterModel) but\n // are omitted from the popover until we expose a discovery endpoint.\n // High-cardinality IDs — free-text. Backed by bloom_filter skip indexes on\n // ClickHouse, narrow timestamp range pruning on DuckDB.\n { id: 'threadId', label: 'Thread ID', kind: 'text' },\n { id: 'resourceId', label: 'Resource ID', kind: 'text' },\n { id: 'userId', label: 'User ID', kind: 'text' },\n { id: 'organizationId', label: 'Organization ID', kind: 'text' },\n { id: 'runId', label: 'Run ID', kind: 'text' },\n { id: 'sessionId', label: 'Session ID', kind: 'text' },\n { id: 'requestId', label: 'Request ID', kind: 'text' },\n { id: 'experimentId', label: 'Experiment ID', kind: 'text' },\n ];\n const byLabel = (a: PropertyFilterField, b: PropertyFilterField) => a.label.localeCompare(b.label);\n const pickMulti = fields.filter(f => f.kind === 'pick-multi').sort(byLabel);\n const text = fields.filter(f => f.kind === 'text').sort(byLabel);\n return [...pickMulti, ...text];\n}\n\n/** Parse filter tokens from URL params, preserving insertion order. */\nexport function getMetricsPropertyFilterTokens(searchParams: URLSearchParams): PropertyFilterToken[] {\n const tokens: PropertyFilterToken[] = [];\n\n const paramToFieldId = new Map<string, string>([[METRICS_ROOT_ENTITY_TYPE_PARAM, 'rootEntityType']]);\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n paramToFieldId.set(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId], fieldId);\n }\n\n const seen = new Set<string>();\n for (const [paramName] of searchParams.entries()) {\n const fieldId = paramToFieldId.get(paramName);\n if (!fieldId || seen.has(fieldId)) continue;\n seen.add(fieldId);\n\n if (fieldId === 'tags') {\n const raw = searchParams.getAll(paramName);\n if (raw.length === 0) continue;\n tokens.push({ fieldId, value: raw.filter(Boolean) });\n continue;\n }\n\n // Multi-value pick-multi fields: collect all occurrences.\n if (\n fieldId === 'rootEntityType' ||\n fieldId === 'entityName' ||\n fieldId === 'serviceName' ||\n fieldId === 'environment' ||\n fieldId === 'provider' ||\n fieldId === 'model'\n ) {\n const raw = searchParams.getAll(paramName);\n if (raw.length > 1) {\n tokens.push({ fieldId, value: raw });\n continue;\n }\n }\n\n const value = searchParams.get(paramName);\n if (value !== null) tokens.push({ fieldId, value });\n }\n\n return tokens;\n}\n\n/** Return a fresh URLSearchParams containing only metrics filter params. */\nexport function getPreservedMetricsFilterParams(searchParams: URLSearchParams): URLSearchParams {\n const next = new URLSearchParams();\n const rootEntityValues = searchParams.getAll(METRICS_ROOT_ENTITY_TYPE_PARAM);\n for (const v of rootEntityValues) next.append(METRICS_ROOT_ENTITY_TYPE_PARAM, v);\n\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n const param = METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId];\n const values = searchParams.getAll(param);\n for (const v of values) next.append(param, v);\n }\n return next;\n}\n\n/** Mutate `params` in place: strip every metrics filter param, then re-write\n * them from `tokens` in order. Token insertion order drives URL order so\n * filter pill order is stable across reloads. */\nexport function applyMetricsPropertyFilterTokens(params: URLSearchParams, tokens: PropertyFilterToken[]): void {\n params.delete(METRICS_ROOT_ENTITY_TYPE_PARAM);\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n params.delete(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId]);\n }\n\n for (const token of tokens) {\n const paramName =\n token.fieldId === 'rootEntityType'\n ? METRICS_ROOT_ENTITY_TYPE_PARAM\n : METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[token.fieldId as MetricsPropertyFilterFieldId];\n if (!paramName) continue;\n\n if (Array.isArray(token.value)) {\n const values = token.value.filter(v => typeof v === 'string' && v !== '');\n if (values.length === 0) {\n // Keep an empty sentinel for `tags` so the pill survives a Reset.\n if (token.fieldId === 'tags') params.append(paramName, '');\n continue;\n }\n for (const v of values) params.append(paramName, v);\n } else if (typeof token.value === 'string') {\n // Persist even empty / 'Any' strings so newly-created pills (and\n // neutralized-but-still-visible pills after a Reset) survive URL\n // round-trips. `buildMetricsDimensionalFilter` drops these on the API\n // query side so neutrals never reach the backend.\n params.set(paramName, token.value.trim());\n }\n }\n}\n\n/** Shape of the dimensional filter object fed into `MetricsFilter` on client\n * calls. Kept compatible with `metricsFilterSchema` in @internal/core — every\n * scalar field maps to a single-string column filter, and `tags` is the only\n * array field (matched via `has()` / equivalent on backends). */\nexport type MetricsDimensionalFilter = {\n rootEntityType?: EntityType;\n entityName?: string;\n tags?: string[];\n serviceName?: string;\n environment?: string;\n provider?: string;\n model?: string;\n threadId?: string;\n resourceId?: string;\n userId?: string;\n organizationId?: string;\n runId?: string;\n sessionId?: string;\n requestId?: string;\n experimentId?: string;\n};\n\n/** Convert the active token list into a `MetricsFilter`-compatible object.\n *\n * Single-value text fields are assigned as strings; `pick-multi` fields are\n * assigned as string arrays. Empty/neutral values are dropped. */\n/** \"Neutral\" sentinel for single-select pick-multi fields. Emitted by the\n * toolbar's Clear action so pills stay visible after reset; must be stripped\n * before the filter object is sent to the backend (it is not a valid enum\n * option for fields like `rootEntityType`). */\nconst NEUTRAL_PICK_VALUE = 'Any';\n\nfunction isNeutralValue(v: string): boolean {\n const trimmed = v.trim();\n return trimmed === '' || trimmed === NEUTRAL_PICK_VALUE;\n}\n\n/** `rootEntityType` is enum-valued at the backend; URL-supplied or stale stored\n * values can be arbitrary strings, so we validate against the allowed set\n * before letting them reach the filter object. Returns `undefined` if the\n * value isn't a known enum option. */\nconst VALID_ROOT_ENTITY_TYPES: ReadonlySet<EntityTypeValue> = new Set(\n METRICS_ROOT_ENTITY_TYPE_OPTIONS.map(o => o.entityType),\n);\nfunction toValidRootEntityType(v: string): EntityType | undefined {\n const trimmed = v.trim();\n return VALID_ROOT_ENTITY_TYPES.has(trimmed as EntityTypeValue) ? (trimmed as EntityType) : undefined;\n}\n\nexport function buildMetricsDimensionalFilter(tokens: PropertyFilterToken[]): MetricsDimensionalFilter {\n const result: MetricsDimensionalFilter = {};\n for (const token of tokens) {\n const fieldId = token.fieldId as keyof MetricsDimensionalFilter;\n if (Array.isArray(token.value)) {\n const values = token.value\n .filter((v): v is string => typeof v === 'string')\n .map(v => v.trim())\n .filter(v => !isNeutralValue(v));\n if (values.length === 0) continue;\n if (fieldId === 'tags') {\n result.tags = values;\n } else if (fieldId === 'rootEntityType') {\n const firstValue = values[0];\n const validated = firstValue !== undefined ? toValidRootEntityType(firstValue) : undefined;\n if (validated) result.rootEntityType = validated;\n } else {\n // Backend accepts a single string per dimension; take the first selection.\n (result as Record<string, unknown>)[fieldId] = values[0];\n }\n } else if (typeof token.value === 'string') {\n if (isNeutralValue(token.value)) continue;\n const trimmed = token.value.trim();\n if (fieldId === 'rootEntityType') {\n const validated = toValidRootEntityType(trimmed);\n if (validated) result.rootEntityType = validated;\n } else {\n (result as Record<string, unknown>)[fieldId] = trimmed;\n }\n }\n }\n return result;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,6 @@ const METRICS_SYNTHETIC_FILTER_FIELD_IDS = ["rootEntityType"];
|
|
|
8
8
|
const METRICS_ROOT_ENTITY_TYPE_PARAM = "rootEntityType";
|
|
9
9
|
const METRICS_PROPERTY_FILTER_PARAM_BY_FIELD = {
|
|
10
10
|
tags: "filterTags",
|
|
11
|
-
entityId: "filterEntityId",
|
|
12
11
|
entityName: "filterEntityName",
|
|
13
12
|
runId: "filterRunId",
|
|
14
13
|
threadId: "filterThreadId",
|
|
@@ -83,7 +82,6 @@ function createMetricsPropertyFilterFields({
|
|
|
83
82
|
emptyText: "No entity names found.",
|
|
84
83
|
isLoading: loading?.entityNames
|
|
85
84
|
},
|
|
86
|
-
{ id: "entityId", label: "Primitive ID", kind: "text" },
|
|
87
85
|
{
|
|
88
86
|
id: "tags",
|
|
89
87
|
label: "Tags",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics-filters.es.js","sources":["../../../src/domains/metrics/metrics-filters.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport type { PropertyFilterField, PropertyFilterToken } from '@/ds/components/PropertyFilter/types';\n\ntype EntityTypeValue = `${EntityType}`;\n\n/** Primitive type options — matches the traces filter vocabulary. */\nexport const METRICS_ROOT_ENTITY_TYPE_OPTIONS = [\n { label: 'Agent', entityType: 'agent' },\n { label: 'Workflow', entityType: 'workflow_run' },\n { label: 'Scorer', entityType: 'scorer' },\n { label: 'Ingest', entityType: 'rag_ingestion' },\n] as const satisfies readonly { label: string; entityType: EntityTypeValue }[];\n\n/** Field IDs that live in dedicated URL params (not the generic `filterX` set). */\nexport const METRICS_SYNTHETIC_FILTER_FIELD_IDS = ['rootEntityType'] as const;\n\nexport const METRICS_ROOT_ENTITY_TYPE_PARAM = 'rootEntityType';\n\n/** URL param name for each generic property filter field. Mirrors traces for\n * cross-page URL consistency (user can copy a trace's filter URL and paste\n * equivalent dimensions into metrics). */\nexport const METRICS_PROPERTY_FILTER_PARAM_BY_FIELD = {\n tags: 'filterTags',\n entityId: 'filterEntityId',\n entityName: 'filterEntityName',\n runId: 'filterRunId',\n threadId: 'filterThreadId',\n sessionId: 'filterSessionId',\n requestId: 'filterRequestId',\n resourceId: 'filterResourceId',\n userId: 'filterUserId',\n organizationId: 'filterOrganizationId',\n serviceName: 'filterServiceName',\n environment: 'filterEnvironment',\n experimentId: 'filterExperimentId',\n provider: 'filterProvider',\n model: 'filterModel',\n} as const;\n\nexport type MetricsPropertyFilterFieldId = keyof typeof METRICS_PROPERTY_FILTER_PARAM_BY_FIELD;\n\nexport const METRICS_PROPERTY_FILTER_FIELD_IDS = Object.keys(\n METRICS_PROPERTY_FILTER_PARAM_BY_FIELD,\n) as Array<MetricsPropertyFilterFieldId>;\n\nconst METRICS_FILTERS_STORAGE_KEY = 'mastra:metrics:saved-filters';\n\n/** Save the current metrics filter URL params so the metrics page can restore\n * them on next visit (same pattern as traces/logs). */\nexport function saveMetricsFiltersToStorage(params: URLSearchParams): void {\n const serialized = getPreservedMetricsFilterParams(params);\n try {\n localStorage.setItem(METRICS_FILTERS_STORAGE_KEY, serialized.toString());\n } catch {\n // localStorage may be unavailable — silently skip.\n }\n}\n\nexport function clearSavedMetricsFilters(): void {\n try {\n localStorage.removeItem(METRICS_FILTERS_STORAGE_KEY);\n } catch {\n // ignore\n }\n}\n\nexport function loadMetricsFiltersFromStorage(): URLSearchParams | null {\n try {\n const raw = localStorage.getItem(METRICS_FILTERS_STORAGE_KEY);\n if (!raw) return null;\n const parsed = new URLSearchParams(raw);\n return parsed.toString() ? parsed : null;\n } catch {\n return null;\n }\n}\n\nexport function hasAnyMetricsFilterParams(params: URLSearchParams): boolean {\n if (params.has(METRICS_ROOT_ENTITY_TYPE_PARAM)) return true;\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n if (params.has(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId])) return true;\n }\n return false;\n}\n\n/** Build the PropertyFilterField list shown in the metrics filter popover.\n *\n * The field order is curated for OLAP efficiency: columnar/LowCardinality\n * dimensions first, then bloom_filter-indexed high-cardinality IDs as\n * free-text. Fields that are expensive to filter without an index are\n * intentionally omitted from this dashboard surface. */\nexport function createMetricsPropertyFilterFields({\n availableTags,\n availableEntityNames,\n availableServiceNames,\n availableEnvironments,\n loading,\n}: {\n availableTags: string[];\n availableEntityNames: string[];\n availableServiceNames: string[];\n availableEnvironments: string[];\n loading?: {\n tags?: boolean;\n entityNames?: boolean;\n serviceNames?: boolean;\n environments?: boolean;\n };\n}): PropertyFilterField[] {\n const fields: PropertyFilterField[] = [\n {\n id: 'rootEntityType',\n label: 'Primitive type',\n kind: 'pick-multi',\n searchable: false,\n options: METRICS_ROOT_ENTITY_TYPE_OPTIONS.map(o => ({ label: o.label, value: o.entityType })),\n placeholder: 'Choose entity type',\n emptyText: 'No entity types.',\n },\n {\n id: 'entityName',\n label: 'Primitive name',\n kind: 'pick-multi',\n options: availableEntityNames.map(name => ({ label: name, value: name })),\n placeholder: 'Choose entity names',\n emptyText: 'No entity names found.',\n isLoading: loading?.entityNames,\n },\n { id: 'entityId', label: 'Primitive ID', kind: 'text' },\n {\n id: 'tags',\n label: 'Tags',\n kind: 'pick-multi',\n multi: true,\n options: availableTags.map(tag => ({ label: tag, value: tag })),\n placeholder: 'Choose tags',\n emptyText: 'No tags found.',\n isLoading: loading?.tags,\n },\n {\n id: 'serviceName',\n label: 'Service Name',\n kind: 'pick-multi',\n options: availableServiceNames.map(name => ({ label: name, value: name })),\n placeholder: 'Choose service names',\n emptyText: 'No service names found.',\n isLoading: loading?.serviceNames,\n },\n {\n id: 'environment',\n label: 'Environment',\n kind: 'pick-multi',\n options: availableEnvironments.map(env => ({ label: env, value: env })),\n placeholder: 'Choose environments',\n emptyText: 'No environments found.',\n isLoading: loading?.environments,\n },\n // Provider / model are filterable by URL (filterProvider / filterModel) but\n // are omitted from the popover until we expose a discovery endpoint.\n // High-cardinality IDs — free-text. Backed by bloom_filter skip indexes on\n // ClickHouse, narrow timestamp range pruning on DuckDB.\n { id: 'threadId', label: 'Thread ID', kind: 'text' },\n { id: 'resourceId', label: 'Resource ID', kind: 'text' },\n { id: 'userId', label: 'User ID', kind: 'text' },\n { id: 'organizationId', label: 'Organization ID', kind: 'text' },\n { id: 'runId', label: 'Run ID', kind: 'text' },\n { id: 'sessionId', label: 'Session ID', kind: 'text' },\n { id: 'requestId', label: 'Request ID', kind: 'text' },\n { id: 'experimentId', label: 'Experiment ID', kind: 'text' },\n ];\n const byLabel = (a: PropertyFilterField, b: PropertyFilterField) => a.label.localeCompare(b.label);\n const pickMulti = fields.filter(f => f.kind === 'pick-multi').sort(byLabel);\n const text = fields.filter(f => f.kind === 'text').sort(byLabel);\n return [...pickMulti, ...text];\n}\n\n/** Parse filter tokens from URL params, preserving insertion order. */\nexport function getMetricsPropertyFilterTokens(searchParams: URLSearchParams): PropertyFilterToken[] {\n const tokens: PropertyFilterToken[] = [];\n\n const paramToFieldId = new Map<string, string>([[METRICS_ROOT_ENTITY_TYPE_PARAM, 'rootEntityType']]);\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n paramToFieldId.set(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId], fieldId);\n }\n\n const seen = new Set<string>();\n for (const [paramName] of searchParams.entries()) {\n const fieldId = paramToFieldId.get(paramName);\n if (!fieldId || seen.has(fieldId)) continue;\n seen.add(fieldId);\n\n if (fieldId === 'tags') {\n const raw = searchParams.getAll(paramName);\n if (raw.length === 0) continue;\n tokens.push({ fieldId, value: raw.filter(Boolean) });\n continue;\n }\n\n // Multi-value pick-multi fields: collect all occurrences.\n if (\n fieldId === 'rootEntityType' ||\n fieldId === 'entityName' ||\n fieldId === 'serviceName' ||\n fieldId === 'environment' ||\n fieldId === 'provider' ||\n fieldId === 'model'\n ) {\n const raw = searchParams.getAll(paramName);\n if (raw.length > 1) {\n tokens.push({ fieldId, value: raw });\n continue;\n }\n }\n\n const value = searchParams.get(paramName);\n if (value !== null) tokens.push({ fieldId, value });\n }\n\n return tokens;\n}\n\n/** Return a fresh URLSearchParams containing only metrics filter params. */\nexport function getPreservedMetricsFilterParams(searchParams: URLSearchParams): URLSearchParams {\n const next = new URLSearchParams();\n const rootEntityValues = searchParams.getAll(METRICS_ROOT_ENTITY_TYPE_PARAM);\n for (const v of rootEntityValues) next.append(METRICS_ROOT_ENTITY_TYPE_PARAM, v);\n\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n const param = METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId];\n const values = searchParams.getAll(param);\n for (const v of values) next.append(param, v);\n }\n return next;\n}\n\n/** Mutate `params` in place: strip every metrics filter param, then re-write\n * them from `tokens` in order. Token insertion order drives URL order so\n * filter pill order is stable across reloads. */\nexport function applyMetricsPropertyFilterTokens(params: URLSearchParams, tokens: PropertyFilterToken[]): void {\n params.delete(METRICS_ROOT_ENTITY_TYPE_PARAM);\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n params.delete(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId]);\n }\n\n for (const token of tokens) {\n const paramName =\n token.fieldId === 'rootEntityType'\n ? METRICS_ROOT_ENTITY_TYPE_PARAM\n : METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[token.fieldId as MetricsPropertyFilterFieldId];\n if (!paramName) continue;\n\n if (Array.isArray(token.value)) {\n const values = token.value.filter(v => typeof v === 'string' && v !== '');\n if (values.length === 0) {\n // Keep an empty sentinel for `tags` so the pill survives a Reset.\n if (token.fieldId === 'tags') params.append(paramName, '');\n continue;\n }\n for (const v of values) params.append(paramName, v);\n } else if (typeof token.value === 'string') {\n // Persist even empty / 'Any' strings so newly-created pills (and\n // neutralized-but-still-visible pills after a Reset) survive URL\n // round-trips. `buildMetricsDimensionalFilter` drops these on the API\n // query side so neutrals never reach the backend.\n params.set(paramName, token.value.trim());\n }\n }\n}\n\n/** Shape of the dimensional filter object fed into `MetricsFilter` on client\n * calls. Kept compatible with `metricsFilterSchema` in @internal/core — every\n * scalar field maps to a single-string column filter, and `tags` is the only\n * array field (matched via `has()` / equivalent on backends). */\nexport type MetricsDimensionalFilter = {\n rootEntityType?: EntityType;\n entityName?: string;\n entityId?: string;\n tags?: string[];\n serviceName?: string;\n environment?: string;\n provider?: string;\n model?: string;\n threadId?: string;\n resourceId?: string;\n userId?: string;\n organizationId?: string;\n runId?: string;\n sessionId?: string;\n requestId?: string;\n experimentId?: string;\n};\n\n/** Convert the active token list into a `MetricsFilter`-compatible object.\n *\n * Single-value text fields are assigned as strings; `pick-multi` fields are\n * assigned as string arrays. Empty/neutral values are dropped. */\n/** \"Neutral\" sentinel for single-select pick-multi fields. Emitted by the\n * toolbar's Clear action so pills stay visible after reset; must be stripped\n * before the filter object is sent to the backend (it is not a valid enum\n * option for fields like `rootEntityType`). */\nconst NEUTRAL_PICK_VALUE = 'Any';\n\nfunction isNeutralValue(v: string): boolean {\n const trimmed = v.trim();\n return trimmed === '' || trimmed === NEUTRAL_PICK_VALUE;\n}\n\n/** `rootEntityType` is enum-valued at the backend; URL-supplied or stale stored\n * values can be arbitrary strings, so we validate against the allowed set\n * before letting them reach the filter object. Returns `undefined` if the\n * value isn't a known enum option. */\nconst VALID_ROOT_ENTITY_TYPES: ReadonlySet<EntityTypeValue> = new Set(\n METRICS_ROOT_ENTITY_TYPE_OPTIONS.map(o => o.entityType),\n);\nfunction toValidRootEntityType(v: string): EntityType | undefined {\n const trimmed = v.trim();\n return VALID_ROOT_ENTITY_TYPES.has(trimmed as EntityTypeValue) ? (trimmed as EntityType) : undefined;\n}\n\nexport function buildMetricsDimensionalFilter(tokens: PropertyFilterToken[]): MetricsDimensionalFilter {\n const result: MetricsDimensionalFilter = {};\n for (const token of tokens) {\n const fieldId = token.fieldId as keyof MetricsDimensionalFilter;\n if (Array.isArray(token.value)) {\n const values = token.value\n .filter((v): v is string => typeof v === 'string')\n .map(v => v.trim())\n .filter(v => !isNeutralValue(v));\n if (values.length === 0) continue;\n if (fieldId === 'tags') {\n result.tags = values;\n } else if (fieldId === 'rootEntityType') {\n const firstValue = values[0];\n const validated = firstValue !== undefined ? toValidRootEntityType(firstValue) : undefined;\n if (validated) result.rootEntityType = validated;\n } else {\n // Backend accepts a single string per dimension; take the first selection.\n (result as Record<string, unknown>)[fieldId] = values[0];\n }\n } else if (typeof token.value === 'string') {\n if (isNeutralValue(token.value)) continue;\n const trimmed = token.value.trim();\n if (fieldId === 'rootEntityType') {\n const validated = toValidRootEntityType(trimmed);\n if (validated) result.rootEntityType = validated;\n } else {\n (result as Record<string, unknown>)[fieldId] = trimmed;\n }\n }\n }\n return result;\n}\n"],"names":[],"mappings":"AAMO,MAAM,gCAAA,GAAmC;AAAA,EAC9C,EAAE,KAAA,EAAO,OAAA,EAAS,UAAA,EAAY,OAAA,EAAQ;AAAA,EACtC,EAAE,KAAA,EAAO,UAAA,EAAY,UAAA,EAAY,cAAA,EAAe;AAAA,EAChD,EAAE,KAAA,EAAO,QAAA,EAAU,UAAA,EAAY,QAAA,EAAS;AAAA,EACxC,EAAE,KAAA,EAAO,QAAA,EAAU,UAAA,EAAY,eAAA;AACjC;AAGO,MAAM,kCAAA,GAAqC,CAAC,gBAAgB;AAE5D,MAAM,8BAAA,GAAiC;AAKvC,MAAM,sCAAA,GAAyC;AAAA,EACpD,IAAA,EAAM,YAAA;AAAA,EACN,QAAA,EAAU,gBAAA;AAAA,EACV,UAAA,EAAY,kBAAA;AAAA,EACZ,KAAA,EAAO,aAAA;AAAA,EACP,QAAA,EAAU,gBAAA;AAAA,EACV,SAAA,EAAW,iBAAA;AAAA,EACX,SAAA,EAAW,iBAAA;AAAA,EACX,UAAA,EAAY,kBAAA;AAAA,EACZ,MAAA,EAAQ,cAAA;AAAA,EACR,cAAA,EAAgB,sBAAA;AAAA,EAChB,WAAA,EAAa,mBAAA;AAAA,EACb,WAAA,EAAa,mBAAA;AAAA,EACb,YAAA,EAAc,oBAAA;AAAA,EACd,QAAA,EAAU,gBAAA;AAAA,EACV,KAAA,EAAO;AACT;AAIO,MAAM,oCAAoC,MAAA,CAAO,IAAA;AAAA,EACtD;AACF;AAEA,MAAM,2BAAA,GAA8B,8BAAA;AAI7B,SAAS,4BAA4B,MAAA,EAA+B;AACzE,EAAA,MAAM,UAAA,GAAa,gCAAgC,MAAM,CAAA;AACzD,EAAA,IAAI;AACF,IAAA,YAAA,CAAa,OAAA,CAAQ,2BAAA,EAA6B,UAAA,CAAW,QAAA,EAAU,CAAA;AAAA,EACzE,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEO,SAAS,wBAAA,GAAiC;AAC/C,EAAA,IAAI;AACF,IAAA,YAAA,CAAa,WAAW,2BAA2B,CAAA;AAAA,EACrD,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEO,SAAS,6BAAA,GAAwD;AACtE,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,OAAA,CAAQ,2BAA2B,CAAA;AAC5D,IAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,IAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB,GAAG,CAAA;AACtC,IAAA,OAAO,MAAA,CAAO,QAAA,EAAS,GAAI,MAAA,GAAS,IAAA;AAAA,EACtC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEO,SAAS,0BAA0B,MAAA,EAAkC;AAC1E,EAAA,IAAI,MAAA,CAAO,GAAA,CAAI,8BAA8B,CAAA,EAAG,OAAO,IAAA;AACvD,EAAA,KAAA,MAAW,WAAW,iCAAA,EAAmC;AACvD,IAAA,IAAI,OAAO,GAAA,CAAI,sCAAA,CAAuC,OAAO,CAAC,GAAG,OAAO,IAAA;AAAA,EAC1E;AACA,EAAA,OAAO,KAAA;AACT;AAQO,SAAS,iCAAA,CAAkC;AAAA,EAChD,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,qBAAA;AAAA,EACA,qBAAA;AAAA,EACA;AACF,CAAA,EAW0B;AACxB,EAAA,MAAM,MAAA,GAAgC;AAAA,IACpC;AAAA,MACE,EAAA,EAAI,gBAAA;AAAA,MACJ,KAAA,EAAO,gBAAA;AAAA,MACP,IAAA,EAAM,YAAA;AAAA,MACN,UAAA,EAAY,KAAA;AAAA,MACZ,OAAA,EAAS,gCAAA,CAAiC,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAO,KAAA,EAAO,CAAA,CAAE,UAAA,EAAW,CAAE,CAAA;AAAA,MAC5F,WAAA,EAAa,oBAAA;AAAA,MACb,SAAA,EAAW;AAAA,KACb;AAAA,IACA;AAAA,MACE,EAAA,EAAI,YAAA;AAAA,MACJ,KAAA,EAAO,gBAAA;AAAA,MACP,IAAA,EAAM,YAAA;AAAA,MACN,OAAA,EAAS,qBAAqB,GAAA,CAAI,CAAA,IAAA,MAAS,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK,CAAE,CAAA;AAAA,MACxE,WAAA,EAAa,qBAAA;AAAA,MACb,SAAA,EAAW,wBAAA;AAAA,MACX,WAAW,OAAA,EAAS;AAAA,KACtB;AAAA,IACA,EAAE,EAAA,EAAI,UAAA,EAAY,KAAA,EAAO,cAAA,EAAgB,MAAM,MAAA,EAAO;AAAA,IACtD;AAAA,MACE,EAAA,EAAI,MAAA;AAAA,MACJ,KAAA,EAAO,MAAA;AAAA,MACP,IAAA,EAAM,YAAA;AAAA,MACN,KAAA,EAAO,IAAA;AAAA,MACP,OAAA,EAAS,cAAc,GAAA,CAAI,CAAA,GAAA,MAAQ,EAAE,KAAA,EAAO,GAAA,EAAK,KAAA,EAAO,GAAA,EAAI,CAAE,CAAA;AAAA,MAC9D,WAAA,EAAa,aAAA;AAAA,MACb,SAAA,EAAW,gBAAA;AAAA,MACX,WAAW,OAAA,EAAS;AAAA,KACtB;AAAA,IACA;AAAA,MACE,EAAA,EAAI,aAAA;AAAA,MACJ,KAAA,EAAO,cAAA;AAAA,MACP,IAAA,EAAM,YAAA;AAAA,MACN,OAAA,EAAS,sBAAsB,GAAA,CAAI,CAAA,IAAA,MAAS,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK,CAAE,CAAA;AAAA,MACzE,WAAA,EAAa,sBAAA;AAAA,MACb,SAAA,EAAW,yBAAA;AAAA,MACX,WAAW,OAAA,EAAS;AAAA,KACtB;AAAA,IACA;AAAA,MACE,EAAA,EAAI,aAAA;AAAA,MACJ,KAAA,EAAO,aAAA;AAAA,MACP,IAAA,EAAM,YAAA;AAAA,MACN,OAAA,EAAS,sBAAsB,GAAA,CAAI,CAAA,GAAA,MAAQ,EAAE,KAAA,EAAO,GAAA,EAAK,KAAA,EAAO,GAAA,EAAI,CAAE,CAAA;AAAA,MACtE,WAAA,EAAa,qBAAA;AAAA,MACb,SAAA,EAAW,wBAAA;AAAA,MACX,WAAW,OAAA,EAAS;AAAA,KACtB;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,EAAE,EAAA,EAAI,UAAA,EAAY,KAAA,EAAO,WAAA,EAAa,MAAM,MAAA,EAAO;AAAA,IACnD,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,aAAA,EAAe,MAAM,MAAA,EAAO;AAAA,IACvD,EAAE,EAAA,EAAI,QAAA,EAAU,KAAA,EAAO,SAAA,EAAW,MAAM,MAAA,EAAO;AAAA,IAC/C,EAAE,EAAA,EAAI,gBAAA,EAAkB,KAAA,EAAO,iBAAA,EAAmB,MAAM,MAAA,EAAO;AAAA,IAC/D,EAAE,EAAA,EAAI,OAAA,EAAS,KAAA,EAAO,QAAA,EAAU,MAAM,MAAA,EAAO;AAAA,IAC7C,EAAE,EAAA,EAAI,WAAA,EAAa,KAAA,EAAO,YAAA,EAAc,MAAM,MAAA,EAAO;AAAA,IACrD,EAAE,EAAA,EAAI,WAAA,EAAa,KAAA,EAAO,YAAA,EAAc,MAAM,MAAA,EAAO;AAAA,IACrD,EAAE,EAAA,EAAI,cAAA,EAAgB,KAAA,EAAO,eAAA,EAAiB,MAAM,MAAA;AAAO,GAC7D;AACA,EAAA,MAAM,OAAA,GAAU,CAAC,CAAA,EAAwB,CAAA,KAA2B,EAAE,KAAA,CAAM,aAAA,CAAc,EAAE,KAAK,CAAA;AACjG,EAAA,MAAM,SAAA,GAAY,OAAO,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,YAAY,CAAA,CAAE,IAAA,CAAK,OAAO,CAAA;AAC1E,EAAA,MAAM,IAAA,GAAO,OAAO,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,MAAM,CAAA,CAAE,IAAA,CAAK,OAAO,CAAA;AAC/D,EAAA,OAAO,CAAC,GAAG,SAAA,EAAW,GAAG,IAAI,CAAA;AAC/B;AAGO,SAAS,+BAA+B,YAAA,EAAsD;AACnG,EAAA,MAAM,SAAgC,EAAC;AAEvC,EAAA,MAAM,cAAA,uBAAqB,GAAA,CAAoB,CAAC,CAAC,8BAAA,EAAgC,gBAAgB,CAAC,CAAC,CAAA;AACnG,EAAA,KAAA,MAAW,WAAW,iCAAA,EAAmC;AACvD,IAAA,cAAA,CAAe,GAAA,CAAI,sCAAA,CAAuC,OAAO,CAAA,EAAG,OAAO,CAAA;AAAA,EAC7E;AAEA,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,CAAC,SAAS,CAAA,IAAK,YAAA,CAAa,SAAQ,EAAG;AAChD,IAAA,MAAM,OAAA,GAAU,cAAA,CAAe,GAAA,CAAI,SAAS,CAAA;AAC5C,IAAA,IAAI,CAAC,OAAA,IAAW,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA,EAAG;AACnC,IAAA,IAAA,CAAK,IAAI,OAAO,CAAA;AAEhB,IAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,MAAA,MAAM,GAAA,GAAM,YAAA,CAAa,MAAA,CAAO,SAAS,CAAA;AACzC,MAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACtB,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,OAAA,EAAS,KAAA,EAAO,IAAI,MAAA,CAAO,OAAO,GAAG,CAAA;AACnD,MAAA;AAAA,IACF;AAGA,IAAA,IACE,OAAA,KAAY,gBAAA,IACZ,OAAA,KAAY,YAAA,IACZ,OAAA,KAAY,aAAA,IACZ,OAAA,KAAY,aAAA,IACZ,OAAA,KAAY,UAAA,IACZ,OAAA,KAAY,OAAA,EACZ;AACA,MAAA,MAAM,GAAA,GAAM,YAAA,CAAa,MAAA,CAAO,SAAS,CAAA;AACzC,MAAA,IAAI,GAAA,CAAI,SAAS,CAAA,EAAG;AAClB,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,OAAA,EAAS,KAAA,EAAO,KAAK,CAAA;AACnC,QAAA;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,GAAA,CAAI,SAAS,CAAA;AACxC,IAAA,IAAI,UAAU,IAAA,EAAM,MAAA,CAAO,KAAK,EAAE,OAAA,EAAS,OAAO,CAAA;AAAA,EACpD;AAEA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,gCAAgC,YAAA,EAAgD;AAC9F,EAAA,MAAM,IAAA,GAAO,IAAI,eAAA,EAAgB;AACjC,EAAA,MAAM,gBAAA,GAAmB,YAAA,CAAa,MAAA,CAAO,8BAA8B,CAAA;AAC3E,EAAA,KAAA,MAAW,CAAA,IAAK,gBAAA,EAAkB,IAAA,CAAK,MAAA,CAAO,gCAAgC,CAAC,CAAA;AAE/E,EAAA,KAAA,MAAW,WAAW,iCAAA,EAAmC;AACvD,IAAA,MAAM,KAAA,GAAQ,uCAAuC,OAAO,CAAA;AAC5D,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,MAAA,CAAO,KAAK,CAAA;AACxC,IAAA,KAAA,MAAW,CAAA,IAAK,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,OAAO,CAAC,CAAA;AAAA,EAC9C;AACA,EAAA,OAAO,IAAA;AACT;AAKO,SAAS,gCAAA,CAAiC,QAAyB,MAAA,EAAqC;AAC7G,EAAA,MAAA,CAAO,OAAO,8BAA8B,CAAA;AAC5C,EAAA,KAAA,MAAW,WAAW,iCAAA,EAAmC;AACvD,IAAA,MAAA,CAAO,MAAA,CAAO,sCAAA,CAAuC,OAAO,CAAC,CAAA;AAAA,EAC/D;AAEA,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,YACJ,KAAA,CAAM,OAAA,KAAY,mBACd,8BAAA,GACA,sCAAA,CAAuC,MAAM,OAAuC,CAAA;AAC1F,IAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAG;AAC9B,MAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAAM,MAAA,CAAO,OAAK,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,KAAM,EAAE,CAAA;AACxE,MAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AAEvB,QAAA,IAAI,MAAM,OAAA,KAAY,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,WAAW,EAAE,CAAA;AACzD,QAAA;AAAA,MACF;AACA,MAAA,KAAA,MAAW,CAAA,IAAK,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,IACpD,CAAA,MAAA,IAAW,OAAO,KAAA,CAAM,KAAA,KAAU,QAAA,EAAU;AAK1C,MAAA,MAAA,CAAO,GAAA,CAAI,SAAA,EAAW,KAAA,CAAM,KAAA,CAAM,MAAM,CAAA;AAAA,IAC1C;AAAA,EACF;AACF;AAiCA,MAAM,kBAAA,GAAqB,KAAA;AAE3B,SAAS,eAAe,CAAA,EAAoB;AAC1C,EAAA,MAAM,OAAA,GAAU,EAAE,IAAA,EAAK;AACvB,EAAA,OAAO,OAAA,KAAY,MAAM,OAAA,KAAY,kBAAA;AACvC;AAMA,MAAM,0BAAwD,IAAI,GAAA;AAAA,EAChE,gCAAA,CAAiC,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU;AACxD,CAAA;AACA,SAAS,sBAAsB,CAAA,EAAmC;AAChE,EAAA,MAAM,OAAA,GAAU,EAAE,IAAA,EAAK;AACvB,EAAA,OAAO,uBAAA,CAAwB,GAAA,CAAI,OAA0B,CAAA,GAAK,OAAA,GAAyB,MAAA;AAC7F;AAEO,SAAS,8BAA8B,MAAA,EAAyD;AACrG,EAAA,MAAM,SAAmC,EAAC;AAC1C,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,UAAU,KAAA,CAAM,OAAA;AACtB,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAG;AAC9B,MAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAClB,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,MAAM,QAAQ,CAAA,CAChD,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,MAAM,CAAA,CACjB,OAAO,CAAA,CAAA,KAAK,CAAC,cAAA,CAAe,CAAC,CAAC,CAAA;AACjC,MAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACzB,MAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,QAAA,MAAA,CAAO,IAAA,GAAO,MAAA;AAAA,MAChB,CAAA,MAAA,IAAW,YAAY,gBAAA,EAAkB;AACvC,QAAA,MAAM,UAAA,GAAa,OAAO,CAAC,CAAA;AAC3B,QAAA,MAAM,SAAA,GAAY,UAAA,KAAe,MAAA,GAAY,qBAAA,CAAsB,UAAU,CAAA,GAAI,MAAA;AACjF,QAAA,IAAI,SAAA,SAAkB,cAAA,GAAiB,SAAA;AAAA,MACzC,CAAA,MAAO;AAEL,QAAC,MAAA,CAAmC,OAAO,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA;AAAA,MACzD;AAAA,IACF,CAAA,MAAA,IAAW,OAAO,KAAA,CAAM,KAAA,KAAU,QAAA,EAAU;AAC1C,MAAA,IAAI,cAAA,CAAe,KAAA,CAAM,KAAK,CAAA,EAAG;AACjC,MAAA,MAAM,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,IAAA,EAAK;AACjC,MAAA,IAAI,YAAY,gBAAA,EAAkB;AAChC,QAAA,MAAM,SAAA,GAAY,sBAAsB,OAAO,CAAA;AAC/C,QAAA,IAAI,SAAA,SAAkB,cAAA,GAAiB,SAAA;AAAA,MACzC,CAAA,MAAO;AACL,QAAC,MAAA,CAAmC,OAAO,CAAA,GAAI,OAAA;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;;;;"}
|
|
1
|
+
{"version":3,"file":"metrics-filters.es.js","sources":["../../../src/domains/metrics/metrics-filters.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport type { PropertyFilterField, PropertyFilterToken } from '@/ds/components/PropertyFilter/types';\n\ntype EntityTypeValue = `${EntityType}`;\n\n/** Primitive type options — matches the traces filter vocabulary. */\nexport const METRICS_ROOT_ENTITY_TYPE_OPTIONS = [\n { label: 'Agent', entityType: 'agent' },\n { label: 'Workflow', entityType: 'workflow_run' },\n { label: 'Scorer', entityType: 'scorer' },\n { label: 'Ingest', entityType: 'rag_ingestion' },\n] as const satisfies readonly { label: string; entityType: EntityTypeValue }[];\n\n/** Field IDs that live in dedicated URL params (not the generic `filterX` set). */\nexport const METRICS_SYNTHETIC_FILTER_FIELD_IDS = ['rootEntityType'] as const;\n\nexport const METRICS_ROOT_ENTITY_TYPE_PARAM = 'rootEntityType';\n\n/** URL param name for each generic property filter field. Mirrors traces for\n * cross-page URL consistency (user can copy a trace's filter URL and paste\n * equivalent dimensions into metrics). */\nexport const METRICS_PROPERTY_FILTER_PARAM_BY_FIELD = {\n tags: 'filterTags',\n entityName: 'filterEntityName',\n runId: 'filterRunId',\n threadId: 'filterThreadId',\n sessionId: 'filterSessionId',\n requestId: 'filterRequestId',\n resourceId: 'filterResourceId',\n userId: 'filterUserId',\n organizationId: 'filterOrganizationId',\n serviceName: 'filterServiceName',\n environment: 'filterEnvironment',\n experimentId: 'filterExperimentId',\n provider: 'filterProvider',\n model: 'filterModel',\n} as const;\n\nexport type MetricsPropertyFilterFieldId = keyof typeof METRICS_PROPERTY_FILTER_PARAM_BY_FIELD;\n\nexport const METRICS_PROPERTY_FILTER_FIELD_IDS = Object.keys(\n METRICS_PROPERTY_FILTER_PARAM_BY_FIELD,\n) as Array<MetricsPropertyFilterFieldId>;\n\nconst METRICS_FILTERS_STORAGE_KEY = 'mastra:metrics:saved-filters';\n\n/** Save the current metrics filter URL params so the metrics page can restore\n * them on next visit (same pattern as traces/logs). */\nexport function saveMetricsFiltersToStorage(params: URLSearchParams): void {\n const serialized = getPreservedMetricsFilterParams(params);\n try {\n localStorage.setItem(METRICS_FILTERS_STORAGE_KEY, serialized.toString());\n } catch {\n // localStorage may be unavailable — silently skip.\n }\n}\n\nexport function clearSavedMetricsFilters(): void {\n try {\n localStorage.removeItem(METRICS_FILTERS_STORAGE_KEY);\n } catch {\n // ignore\n }\n}\n\nexport function loadMetricsFiltersFromStorage(): URLSearchParams | null {\n try {\n const raw = localStorage.getItem(METRICS_FILTERS_STORAGE_KEY);\n if (!raw) return null;\n const parsed = new URLSearchParams(raw);\n return parsed.toString() ? parsed : null;\n } catch {\n return null;\n }\n}\n\nexport function hasAnyMetricsFilterParams(params: URLSearchParams): boolean {\n if (params.has(METRICS_ROOT_ENTITY_TYPE_PARAM)) return true;\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n if (params.has(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId])) return true;\n }\n return false;\n}\n\n/** Build the PropertyFilterField list shown in the metrics filter popover.\n *\n * The field order is curated for OLAP efficiency: columnar/LowCardinality\n * dimensions first, then bloom_filter-indexed high-cardinality IDs as\n * free-text. Fields that are expensive to filter without an index are\n * intentionally omitted from this dashboard surface. */\nexport function createMetricsPropertyFilterFields({\n availableTags,\n availableEntityNames,\n availableServiceNames,\n availableEnvironments,\n loading,\n}: {\n availableTags: string[];\n availableEntityNames: string[];\n availableServiceNames: string[];\n availableEnvironments: string[];\n loading?: {\n tags?: boolean;\n entityNames?: boolean;\n serviceNames?: boolean;\n environments?: boolean;\n };\n}): PropertyFilterField[] {\n const fields: PropertyFilterField[] = [\n {\n id: 'rootEntityType',\n label: 'Primitive type',\n kind: 'pick-multi',\n searchable: false,\n options: METRICS_ROOT_ENTITY_TYPE_OPTIONS.map(o => ({ label: o.label, value: o.entityType })),\n placeholder: 'Choose entity type',\n emptyText: 'No entity types.',\n },\n {\n id: 'entityName',\n label: 'Primitive name',\n kind: 'pick-multi',\n options: availableEntityNames.map(name => ({ label: name, value: name })),\n placeholder: 'Choose entity names',\n emptyText: 'No entity names found.',\n isLoading: loading?.entityNames,\n },\n {\n id: 'tags',\n label: 'Tags',\n kind: 'pick-multi',\n multi: true,\n options: availableTags.map(tag => ({ label: tag, value: tag })),\n placeholder: 'Choose tags',\n emptyText: 'No tags found.',\n isLoading: loading?.tags,\n },\n {\n id: 'serviceName',\n label: 'Service Name',\n kind: 'pick-multi',\n options: availableServiceNames.map(name => ({ label: name, value: name })),\n placeholder: 'Choose service names',\n emptyText: 'No service names found.',\n isLoading: loading?.serviceNames,\n },\n {\n id: 'environment',\n label: 'Environment',\n kind: 'pick-multi',\n options: availableEnvironments.map(env => ({ label: env, value: env })),\n placeholder: 'Choose environments',\n emptyText: 'No environments found.',\n isLoading: loading?.environments,\n },\n // Provider / model are filterable by URL (filterProvider / filterModel) but\n // are omitted from the popover until we expose a discovery endpoint.\n // High-cardinality IDs — free-text. Backed by bloom_filter skip indexes on\n // ClickHouse, narrow timestamp range pruning on DuckDB.\n { id: 'threadId', label: 'Thread ID', kind: 'text' },\n { id: 'resourceId', label: 'Resource ID', kind: 'text' },\n { id: 'userId', label: 'User ID', kind: 'text' },\n { id: 'organizationId', label: 'Organization ID', kind: 'text' },\n { id: 'runId', label: 'Run ID', kind: 'text' },\n { id: 'sessionId', label: 'Session ID', kind: 'text' },\n { id: 'requestId', label: 'Request ID', kind: 'text' },\n { id: 'experimentId', label: 'Experiment ID', kind: 'text' },\n ];\n const byLabel = (a: PropertyFilterField, b: PropertyFilterField) => a.label.localeCompare(b.label);\n const pickMulti = fields.filter(f => f.kind === 'pick-multi').sort(byLabel);\n const text = fields.filter(f => f.kind === 'text').sort(byLabel);\n return [...pickMulti, ...text];\n}\n\n/** Parse filter tokens from URL params, preserving insertion order. */\nexport function getMetricsPropertyFilterTokens(searchParams: URLSearchParams): PropertyFilterToken[] {\n const tokens: PropertyFilterToken[] = [];\n\n const paramToFieldId = new Map<string, string>([[METRICS_ROOT_ENTITY_TYPE_PARAM, 'rootEntityType']]);\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n paramToFieldId.set(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId], fieldId);\n }\n\n const seen = new Set<string>();\n for (const [paramName] of searchParams.entries()) {\n const fieldId = paramToFieldId.get(paramName);\n if (!fieldId || seen.has(fieldId)) continue;\n seen.add(fieldId);\n\n if (fieldId === 'tags') {\n const raw = searchParams.getAll(paramName);\n if (raw.length === 0) continue;\n tokens.push({ fieldId, value: raw.filter(Boolean) });\n continue;\n }\n\n // Multi-value pick-multi fields: collect all occurrences.\n if (\n fieldId === 'rootEntityType' ||\n fieldId === 'entityName' ||\n fieldId === 'serviceName' ||\n fieldId === 'environment' ||\n fieldId === 'provider' ||\n fieldId === 'model'\n ) {\n const raw = searchParams.getAll(paramName);\n if (raw.length > 1) {\n tokens.push({ fieldId, value: raw });\n continue;\n }\n }\n\n const value = searchParams.get(paramName);\n if (value !== null) tokens.push({ fieldId, value });\n }\n\n return tokens;\n}\n\n/** Return a fresh URLSearchParams containing only metrics filter params. */\nexport function getPreservedMetricsFilterParams(searchParams: URLSearchParams): URLSearchParams {\n const next = new URLSearchParams();\n const rootEntityValues = searchParams.getAll(METRICS_ROOT_ENTITY_TYPE_PARAM);\n for (const v of rootEntityValues) next.append(METRICS_ROOT_ENTITY_TYPE_PARAM, v);\n\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n const param = METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId];\n const values = searchParams.getAll(param);\n for (const v of values) next.append(param, v);\n }\n return next;\n}\n\n/** Mutate `params` in place: strip every metrics filter param, then re-write\n * them from `tokens` in order. Token insertion order drives URL order so\n * filter pill order is stable across reloads. */\nexport function applyMetricsPropertyFilterTokens(params: URLSearchParams, tokens: PropertyFilterToken[]): void {\n params.delete(METRICS_ROOT_ENTITY_TYPE_PARAM);\n for (const fieldId of METRICS_PROPERTY_FILTER_FIELD_IDS) {\n params.delete(METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[fieldId]);\n }\n\n for (const token of tokens) {\n const paramName =\n token.fieldId === 'rootEntityType'\n ? METRICS_ROOT_ENTITY_TYPE_PARAM\n : METRICS_PROPERTY_FILTER_PARAM_BY_FIELD[token.fieldId as MetricsPropertyFilterFieldId];\n if (!paramName) continue;\n\n if (Array.isArray(token.value)) {\n const values = token.value.filter(v => typeof v === 'string' && v !== '');\n if (values.length === 0) {\n // Keep an empty sentinel for `tags` so the pill survives a Reset.\n if (token.fieldId === 'tags') params.append(paramName, '');\n continue;\n }\n for (const v of values) params.append(paramName, v);\n } else if (typeof token.value === 'string') {\n // Persist even empty / 'Any' strings so newly-created pills (and\n // neutralized-but-still-visible pills after a Reset) survive URL\n // round-trips. `buildMetricsDimensionalFilter` drops these on the API\n // query side so neutrals never reach the backend.\n params.set(paramName, token.value.trim());\n }\n }\n}\n\n/** Shape of the dimensional filter object fed into `MetricsFilter` on client\n * calls. Kept compatible with `metricsFilterSchema` in @internal/core — every\n * scalar field maps to a single-string column filter, and `tags` is the only\n * array field (matched via `has()` / equivalent on backends). */\nexport type MetricsDimensionalFilter = {\n rootEntityType?: EntityType;\n entityName?: string;\n tags?: string[];\n serviceName?: string;\n environment?: string;\n provider?: string;\n model?: string;\n threadId?: string;\n resourceId?: string;\n userId?: string;\n organizationId?: string;\n runId?: string;\n sessionId?: string;\n requestId?: string;\n experimentId?: string;\n};\n\n/** Convert the active token list into a `MetricsFilter`-compatible object.\n *\n * Single-value text fields are assigned as strings; `pick-multi` fields are\n * assigned as string arrays. Empty/neutral values are dropped. */\n/** \"Neutral\" sentinel for single-select pick-multi fields. Emitted by the\n * toolbar's Clear action so pills stay visible after reset; must be stripped\n * before the filter object is sent to the backend (it is not a valid enum\n * option for fields like `rootEntityType`). */\nconst NEUTRAL_PICK_VALUE = 'Any';\n\nfunction isNeutralValue(v: string): boolean {\n const trimmed = v.trim();\n return trimmed === '' || trimmed === NEUTRAL_PICK_VALUE;\n}\n\n/** `rootEntityType` is enum-valued at the backend; URL-supplied or stale stored\n * values can be arbitrary strings, so we validate against the allowed set\n * before letting them reach the filter object. Returns `undefined` if the\n * value isn't a known enum option. */\nconst VALID_ROOT_ENTITY_TYPES: ReadonlySet<EntityTypeValue> = new Set(\n METRICS_ROOT_ENTITY_TYPE_OPTIONS.map(o => o.entityType),\n);\nfunction toValidRootEntityType(v: string): EntityType | undefined {\n const trimmed = v.trim();\n return VALID_ROOT_ENTITY_TYPES.has(trimmed as EntityTypeValue) ? (trimmed as EntityType) : undefined;\n}\n\nexport function buildMetricsDimensionalFilter(tokens: PropertyFilterToken[]): MetricsDimensionalFilter {\n const result: MetricsDimensionalFilter = {};\n for (const token of tokens) {\n const fieldId = token.fieldId as keyof MetricsDimensionalFilter;\n if (Array.isArray(token.value)) {\n const values = token.value\n .filter((v): v is string => typeof v === 'string')\n .map(v => v.trim())\n .filter(v => !isNeutralValue(v));\n if (values.length === 0) continue;\n if (fieldId === 'tags') {\n result.tags = values;\n } else if (fieldId === 'rootEntityType') {\n const firstValue = values[0];\n const validated = firstValue !== undefined ? toValidRootEntityType(firstValue) : undefined;\n if (validated) result.rootEntityType = validated;\n } else {\n // Backend accepts a single string per dimension; take the first selection.\n (result as Record<string, unknown>)[fieldId] = values[0];\n }\n } else if (typeof token.value === 'string') {\n if (isNeutralValue(token.value)) continue;\n const trimmed = token.value.trim();\n if (fieldId === 'rootEntityType') {\n const validated = toValidRootEntityType(trimmed);\n if (validated) result.rootEntityType = validated;\n } else {\n (result as Record<string, unknown>)[fieldId] = trimmed;\n }\n }\n }\n return result;\n}\n"],"names":[],"mappings":"AAMO,MAAM,gCAAA,GAAmC;AAAA,EAC9C,EAAE,KAAA,EAAO,OAAA,EAAS,UAAA,EAAY,OAAA,EAAQ;AAAA,EACtC,EAAE,KAAA,EAAO,UAAA,EAAY,UAAA,EAAY,cAAA,EAAe;AAAA,EAChD,EAAE,KAAA,EAAO,QAAA,EAAU,UAAA,EAAY,QAAA,EAAS;AAAA,EACxC,EAAE,KAAA,EAAO,QAAA,EAAU,UAAA,EAAY,eAAA;AACjC;AAGO,MAAM,kCAAA,GAAqC,CAAC,gBAAgB;AAE5D,MAAM,8BAAA,GAAiC;AAKvC,MAAM,sCAAA,GAAyC;AAAA,EACpD,IAAA,EAAM,YAAA;AAAA,EACN,UAAA,EAAY,kBAAA;AAAA,EACZ,KAAA,EAAO,aAAA;AAAA,EACP,QAAA,EAAU,gBAAA;AAAA,EACV,SAAA,EAAW,iBAAA;AAAA,EACX,SAAA,EAAW,iBAAA;AAAA,EACX,UAAA,EAAY,kBAAA;AAAA,EACZ,MAAA,EAAQ,cAAA;AAAA,EACR,cAAA,EAAgB,sBAAA;AAAA,EAChB,WAAA,EAAa,mBAAA;AAAA,EACb,WAAA,EAAa,mBAAA;AAAA,EACb,YAAA,EAAc,oBAAA;AAAA,EACd,QAAA,EAAU,gBAAA;AAAA,EACV,KAAA,EAAO;AACT;AAIO,MAAM,oCAAoC,MAAA,CAAO,IAAA;AAAA,EACtD;AACF;AAEA,MAAM,2BAAA,GAA8B,8BAAA;AAI7B,SAAS,4BAA4B,MAAA,EAA+B;AACzE,EAAA,MAAM,UAAA,GAAa,gCAAgC,MAAM,CAAA;AACzD,EAAA,IAAI;AACF,IAAA,YAAA,CAAa,OAAA,CAAQ,2BAAA,EAA6B,UAAA,CAAW,QAAA,EAAU,CAAA;AAAA,EACzE,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEO,SAAS,wBAAA,GAAiC;AAC/C,EAAA,IAAI;AACF,IAAA,YAAA,CAAa,WAAW,2BAA2B,CAAA;AAAA,EACrD,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEO,SAAS,6BAAA,GAAwD;AACtE,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,OAAA,CAAQ,2BAA2B,CAAA;AAC5D,IAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,IAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB,GAAG,CAAA;AACtC,IAAA,OAAO,MAAA,CAAO,QAAA,EAAS,GAAI,MAAA,GAAS,IAAA;AAAA,EACtC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEO,SAAS,0BAA0B,MAAA,EAAkC;AAC1E,EAAA,IAAI,MAAA,CAAO,GAAA,CAAI,8BAA8B,CAAA,EAAG,OAAO,IAAA;AACvD,EAAA,KAAA,MAAW,WAAW,iCAAA,EAAmC;AACvD,IAAA,IAAI,OAAO,GAAA,CAAI,sCAAA,CAAuC,OAAO,CAAC,GAAG,OAAO,IAAA;AAAA,EAC1E;AACA,EAAA,OAAO,KAAA;AACT;AAQO,SAAS,iCAAA,CAAkC;AAAA,EAChD,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,qBAAA;AAAA,EACA,qBAAA;AAAA,EACA;AACF,CAAA,EAW0B;AACxB,EAAA,MAAM,MAAA,GAAgC;AAAA,IACpC;AAAA,MACE,EAAA,EAAI,gBAAA;AAAA,MACJ,KAAA,EAAO,gBAAA;AAAA,MACP,IAAA,EAAM,YAAA;AAAA,MACN,UAAA,EAAY,KAAA;AAAA,MACZ,OAAA,EAAS,gCAAA,CAAiC,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAO,KAAA,EAAO,CAAA,CAAE,UAAA,EAAW,CAAE,CAAA;AAAA,MAC5F,WAAA,EAAa,oBAAA;AAAA,MACb,SAAA,EAAW;AAAA,KACb;AAAA,IACA;AAAA,MACE,EAAA,EAAI,YAAA;AAAA,MACJ,KAAA,EAAO,gBAAA;AAAA,MACP,IAAA,EAAM,YAAA;AAAA,MACN,OAAA,EAAS,qBAAqB,GAAA,CAAI,CAAA,IAAA,MAAS,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK,CAAE,CAAA;AAAA,MACxE,WAAA,EAAa,qBAAA;AAAA,MACb,SAAA,EAAW,wBAAA;AAAA,MACX,WAAW,OAAA,EAAS;AAAA,KACtB;AAAA,IACA;AAAA,MACE,EAAA,EAAI,MAAA;AAAA,MACJ,KAAA,EAAO,MAAA;AAAA,MACP,IAAA,EAAM,YAAA;AAAA,MACN,KAAA,EAAO,IAAA;AAAA,MACP,OAAA,EAAS,cAAc,GAAA,CAAI,CAAA,GAAA,MAAQ,EAAE,KAAA,EAAO,GAAA,EAAK,KAAA,EAAO,GAAA,EAAI,CAAE,CAAA;AAAA,MAC9D,WAAA,EAAa,aAAA;AAAA,MACb,SAAA,EAAW,gBAAA;AAAA,MACX,WAAW,OAAA,EAAS;AAAA,KACtB;AAAA,IACA;AAAA,MACE,EAAA,EAAI,aAAA;AAAA,MACJ,KAAA,EAAO,cAAA;AAAA,MACP,IAAA,EAAM,YAAA;AAAA,MACN,OAAA,EAAS,sBAAsB,GAAA,CAAI,CAAA,IAAA,MAAS,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK,CAAE,CAAA;AAAA,MACzE,WAAA,EAAa,sBAAA;AAAA,MACb,SAAA,EAAW,yBAAA;AAAA,MACX,WAAW,OAAA,EAAS;AAAA,KACtB;AAAA,IACA;AAAA,MACE,EAAA,EAAI,aAAA;AAAA,MACJ,KAAA,EAAO,aAAA;AAAA,MACP,IAAA,EAAM,YAAA;AAAA,MACN,OAAA,EAAS,sBAAsB,GAAA,CAAI,CAAA,GAAA,MAAQ,EAAE,KAAA,EAAO,GAAA,EAAK,KAAA,EAAO,GAAA,EAAI,CAAE,CAAA;AAAA,MACtE,WAAA,EAAa,qBAAA;AAAA,MACb,SAAA,EAAW,wBAAA;AAAA,MACX,WAAW,OAAA,EAAS;AAAA,KACtB;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,EAAE,EAAA,EAAI,UAAA,EAAY,KAAA,EAAO,WAAA,EAAa,MAAM,MAAA,EAAO;AAAA,IACnD,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,aAAA,EAAe,MAAM,MAAA,EAAO;AAAA,IACvD,EAAE,EAAA,EAAI,QAAA,EAAU,KAAA,EAAO,SAAA,EAAW,MAAM,MAAA,EAAO;AAAA,IAC/C,EAAE,EAAA,EAAI,gBAAA,EAAkB,KAAA,EAAO,iBAAA,EAAmB,MAAM,MAAA,EAAO;AAAA,IAC/D,EAAE,EAAA,EAAI,OAAA,EAAS,KAAA,EAAO,QAAA,EAAU,MAAM,MAAA,EAAO;AAAA,IAC7C,EAAE,EAAA,EAAI,WAAA,EAAa,KAAA,EAAO,YAAA,EAAc,MAAM,MAAA,EAAO;AAAA,IACrD,EAAE,EAAA,EAAI,WAAA,EAAa,KAAA,EAAO,YAAA,EAAc,MAAM,MAAA,EAAO;AAAA,IACrD,EAAE,EAAA,EAAI,cAAA,EAAgB,KAAA,EAAO,eAAA,EAAiB,MAAM,MAAA;AAAO,GAC7D;AACA,EAAA,MAAM,OAAA,GAAU,CAAC,CAAA,EAAwB,CAAA,KAA2B,EAAE,KAAA,CAAM,aAAA,CAAc,EAAE,KAAK,CAAA;AACjG,EAAA,MAAM,SAAA,GAAY,OAAO,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,YAAY,CAAA,CAAE,IAAA,CAAK,OAAO,CAAA;AAC1E,EAAA,MAAM,IAAA,GAAO,OAAO,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,MAAM,CAAA,CAAE,IAAA,CAAK,OAAO,CAAA;AAC/D,EAAA,OAAO,CAAC,GAAG,SAAA,EAAW,GAAG,IAAI,CAAA;AAC/B;AAGO,SAAS,+BAA+B,YAAA,EAAsD;AACnG,EAAA,MAAM,SAAgC,EAAC;AAEvC,EAAA,MAAM,cAAA,uBAAqB,GAAA,CAAoB,CAAC,CAAC,8BAAA,EAAgC,gBAAgB,CAAC,CAAC,CAAA;AACnG,EAAA,KAAA,MAAW,WAAW,iCAAA,EAAmC;AACvD,IAAA,cAAA,CAAe,GAAA,CAAI,sCAAA,CAAuC,OAAO,CAAA,EAAG,OAAO,CAAA;AAAA,EAC7E;AAEA,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,CAAC,SAAS,CAAA,IAAK,YAAA,CAAa,SAAQ,EAAG;AAChD,IAAA,MAAM,OAAA,GAAU,cAAA,CAAe,GAAA,CAAI,SAAS,CAAA;AAC5C,IAAA,IAAI,CAAC,OAAA,IAAW,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA,EAAG;AACnC,IAAA,IAAA,CAAK,IAAI,OAAO,CAAA;AAEhB,IAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,MAAA,MAAM,GAAA,GAAM,YAAA,CAAa,MAAA,CAAO,SAAS,CAAA;AACzC,MAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACtB,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,OAAA,EAAS,KAAA,EAAO,IAAI,MAAA,CAAO,OAAO,GAAG,CAAA;AACnD,MAAA;AAAA,IACF;AAGA,IAAA,IACE,OAAA,KAAY,gBAAA,IACZ,OAAA,KAAY,YAAA,IACZ,OAAA,KAAY,aAAA,IACZ,OAAA,KAAY,aAAA,IACZ,OAAA,KAAY,UAAA,IACZ,OAAA,KAAY,OAAA,EACZ;AACA,MAAA,MAAM,GAAA,GAAM,YAAA,CAAa,MAAA,CAAO,SAAS,CAAA;AACzC,MAAA,IAAI,GAAA,CAAI,SAAS,CAAA,EAAG;AAClB,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,OAAA,EAAS,KAAA,EAAO,KAAK,CAAA;AACnC,QAAA;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,GAAA,CAAI,SAAS,CAAA;AACxC,IAAA,IAAI,UAAU,IAAA,EAAM,MAAA,CAAO,KAAK,EAAE,OAAA,EAAS,OAAO,CAAA;AAAA,EACpD;AAEA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,gCAAgC,YAAA,EAAgD;AAC9F,EAAA,MAAM,IAAA,GAAO,IAAI,eAAA,EAAgB;AACjC,EAAA,MAAM,gBAAA,GAAmB,YAAA,CAAa,MAAA,CAAO,8BAA8B,CAAA;AAC3E,EAAA,KAAA,MAAW,CAAA,IAAK,gBAAA,EAAkB,IAAA,CAAK,MAAA,CAAO,gCAAgC,CAAC,CAAA;AAE/E,EAAA,KAAA,MAAW,WAAW,iCAAA,EAAmC;AACvD,IAAA,MAAM,KAAA,GAAQ,uCAAuC,OAAO,CAAA;AAC5D,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,MAAA,CAAO,KAAK,CAAA;AACxC,IAAA,KAAA,MAAW,CAAA,IAAK,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,OAAO,CAAC,CAAA;AAAA,EAC9C;AACA,EAAA,OAAO,IAAA;AACT;AAKO,SAAS,gCAAA,CAAiC,QAAyB,MAAA,EAAqC;AAC7G,EAAA,MAAA,CAAO,OAAO,8BAA8B,CAAA;AAC5C,EAAA,KAAA,MAAW,WAAW,iCAAA,EAAmC;AACvD,IAAA,MAAA,CAAO,MAAA,CAAO,sCAAA,CAAuC,OAAO,CAAC,CAAA;AAAA,EAC/D;AAEA,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,YACJ,KAAA,CAAM,OAAA,KAAY,mBACd,8BAAA,GACA,sCAAA,CAAuC,MAAM,OAAuC,CAAA;AAC1F,IAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAG;AAC9B,MAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAAM,MAAA,CAAO,OAAK,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,KAAM,EAAE,CAAA;AACxE,MAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AAEvB,QAAA,IAAI,MAAM,OAAA,KAAY,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,WAAW,EAAE,CAAA;AACzD,QAAA;AAAA,MACF;AACA,MAAA,KAAA,MAAW,CAAA,IAAK,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,IACpD,CAAA,MAAA,IAAW,OAAO,KAAA,CAAM,KAAA,KAAU,QAAA,EAAU;AAK1C,MAAA,MAAA,CAAO,GAAA,CAAI,SAAA,EAAW,KAAA,CAAM,KAAA,CAAM,MAAM,CAAA;AAAA,IAC1C;AAAA,EACF;AACF;AAgCA,MAAM,kBAAA,GAAqB,KAAA;AAE3B,SAAS,eAAe,CAAA,EAAoB;AAC1C,EAAA,MAAM,OAAA,GAAU,EAAE,IAAA,EAAK;AACvB,EAAA,OAAO,OAAA,KAAY,MAAM,OAAA,KAAY,kBAAA;AACvC;AAMA,MAAM,0BAAwD,IAAI,GAAA;AAAA,EAChE,gCAAA,CAAiC,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU;AACxD,CAAA;AACA,SAAS,sBAAsB,CAAA,EAAmC;AAChE,EAAA,MAAM,OAAA,GAAU,EAAE,IAAA,EAAK;AACvB,EAAA,OAAO,uBAAA,CAAwB,GAAA,CAAI,OAA0B,CAAA,GAAK,OAAA,GAAyB,MAAA;AAC7F;AAEO,SAAS,8BAA8B,MAAA,EAAyD;AACrG,EAAA,MAAM,SAAmC,EAAC;AAC1C,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,UAAU,KAAA,CAAM,OAAA;AACtB,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAG;AAC9B,MAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAClB,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,MAAM,QAAQ,CAAA,CAChD,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,MAAM,CAAA,CACjB,OAAO,CAAA,CAAA,KAAK,CAAC,cAAA,CAAe,CAAC,CAAC,CAAA;AACjC,MAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACzB,MAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,QAAA,MAAA,CAAO,IAAA,GAAO,MAAA;AAAA,MAChB,CAAA,MAAA,IAAW,YAAY,gBAAA,EAAkB;AACvC,QAAA,MAAM,UAAA,GAAa,OAAO,CAAC,CAAA;AAC3B,QAAA,MAAM,SAAA,GAAY,UAAA,KAAe,MAAA,GAAY,qBAAA,CAAsB,UAAU,CAAA,GAAI,MAAA;AACjF,QAAA,IAAI,SAAA,SAAkB,cAAA,GAAiB,SAAA;AAAA,MACzC,CAAA,MAAO;AAEL,QAAC,MAAA,CAAmC,OAAO,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA;AAAA,MACzD;AAAA,IACF,CAAA,MAAA,IAAW,OAAO,KAAA,CAAM,KAAA,KAAU,QAAA,EAAU;AAC1C,MAAA,IAAI,cAAA,CAAe,KAAA,CAAM,KAAK,CAAA,EAAG;AACjC,MAAA,MAAM,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,IAAA,EAAK;AACjC,MAAA,IAAI,YAAY,gBAAA,EAAkB;AAChC,QAAA,MAAM,SAAA,GAAY,sBAAsB,OAAO,CAAA;AAC/C,QAAA,IAAI,SAAA,SAAkB,cAAA,GAAiB,SAAA;AAAA,MACzC,CAAA,MAAO;AACL,QAAC,MAAA,CAAmC,OAAO,CAAA,GAAI,OAAA;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;;;;"}
|
|
@@ -12,7 +12,7 @@ const React = require('react');
|
|
|
12
12
|
const domains_datasets_hooks_useDatasetMutations = require('../../datasets/hooks/use-dataset-mutations.cjs.js');
|
|
13
13
|
const domains_datasets_hooks_useDatasets = require('../../datasets/hooks/use-datasets.cjs.js');
|
|
14
14
|
const Button = require('../../../Button-CXhSUBxN.cjs');
|
|
15
|
-
const codeEditor = require('../../../code-editor-
|
|
15
|
+
const codeEditor = require('../../../code-editor-B_wPmKPf.cjs');
|
|
16
16
|
const label = require('../../../label-DfAhywj_.cjs');
|
|
17
17
|
const select = require('../../../select-DBY9LQFQ.cjs');
|
|
18
18
|
const sideDialog = require('../../../side-dialog-DFnD1498.cjs');
|
|
@@ -8,7 +8,7 @@ import { useState } from 'react';
|
|
|
8
8
|
import { useDatasetMutations } from '../../datasets/hooks/use-dataset-mutations.es.js';
|
|
9
9
|
import { useDatasets } from '../../datasets/hooks/use-datasets.es.js';
|
|
10
10
|
import { B as Button } from '../../../Button-D43ghVKt.js';
|
|
11
|
-
import { C as CodeEditor } from '../../../code-editor-
|
|
11
|
+
import { C as CodeEditor } from '../../../code-editor-28chVxHw.js';
|
|
12
12
|
import { L as Label } from '../../../label-Dxsz0dFs.js';
|
|
13
13
|
import { S as Select, d as SelectTrigger, e as SelectValue, a as SelectContent, c as SelectItem } from '../../../select-DZeNf-kI.js';
|
|
14
14
|
import { S as SideDialog } from '../../../side-dialog-DCzCcZs6.js';
|
|
@@ -10,7 +10,7 @@ const domains_workflows_workflow_data_workflowDataInspector = require('../workfl
|
|
|
10
10
|
const domains_workflows_workflow_workflowNestedGraph = require('../../../use-workflow-graph-runtime-CIs2HzoP.cjs');
|
|
11
11
|
const Txt = require('../../../Txt-DPmEpNbp.cjs');
|
|
12
12
|
const workflowConditionCard = require('../../../workflow-condition-card-BjEAp0t6.cjs');
|
|
13
|
-
const workflowCodeDialogContent = require('../../../workflow-code-dialog-content-
|
|
13
|
+
const workflowCodeDialogContent = require('../../../workflow-code-dialog-content-BFm2IWDl.cjs');
|
|
14
14
|
const icons_WorkflowIcon = require('../../../icons/WorkflowIcon.cjs.js');
|
|
15
15
|
|
|
16
16
|
function WorkflowStepDetailContent({ requestContext }) {
|
|
@@ -6,7 +6,7 @@ import { WorkflowDataInspector } from '../workflow/data/workflow-data-inspector.
|
|
|
6
6
|
import { W as WorkflowNestedGraph } from '../../../use-workflow-graph-runtime-CexS1ECI.js';
|
|
7
7
|
import { T as Txt } from '../../../Txt-BP1SRHmL.js';
|
|
8
8
|
import { B as BADGE_COLORS } from '../../../workflow-condition-card-3J-As62x.js';
|
|
9
|
-
import { W as WorkflowCodeContent } from '../../../workflow-code-dialog-content-
|
|
9
|
+
import { W as WorkflowCodeContent } from '../../../workflow-code-dialog-content-BM4ZnrUr.js';
|
|
10
10
|
import { WorkflowIcon } from '../../../icons/WorkflowIcon.es.js';
|
|
11
11
|
|
|
12
12
|
function WorkflowStepDetailContent({ requestContext }) {
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
5
5
|
const jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
const domains_workflows_context_workflowStepDetailContext = require('../../context/workflow-step-detail-context.cjs.js');
|
|
7
7
|
const domains_workflows_workflow_data_useWorkflowData = require('./use-workflow-data.cjs.js');
|
|
8
|
-
const workflowEdgeDataButton = require('../../../../workflow-edge-data-button-
|
|
8
|
+
const workflowEdgeDataButton = require('../../../../workflow-edge-data-button-BOVRo4xO.cjs');
|
|
9
9
|
|
|
10
10
|
function WorkflowDataButton({ selection }) {
|
|
11
11
|
const { stepDetail, showData } = domains_workflows_context_workflowStepDetailContext.useWorkflowStepDetail();
|