Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ export const DetailsViewJsonOutput: FC<JsonViewerProps> = ({
className={`overflow-x-hidden rounded-xl p-4 text-left ${className}`}
data={content}
id={`json-pretty-${id}`}
keyStyle={`color: oklch(var(--${agentPrismPrefix}-code-key));`}
mainStyle={`color: oklch(var(--${agentPrismPrefix}-code-base)); font-size: 12px; white-space: pre-wrap; word-wrap: break-word; overflow-wrap: break-word;`}
stringStyle={`color: oklch(var(--${agentPrismPrefix}-code-string));`}
valueStyle={`color: oklch(var(--${agentPrismPrefix}-code-number));`}
keyStyle={`color: hsl(var(--${agentPrismPrefix}-code-key));`}
mainStyle={`color: hsl(var(--${agentPrismPrefix}-code-base)); font-size: 12px; white-space: pre-wrap; word-wrap: break-word; overflow-wrap: break-word;`}
stringStyle={`color: hsl(var(--${agentPrismPrefix}-code-string));`}
valueStyle={`color: hsl(var(--${agentPrismPrefix}-code-number));`}
/>
);
};
2 changes: 1 addition & 1 deletion frontend/app/src/components/v1/agent-prism/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,5 @@ export const agentPrismTailwindColors = Object.fromEntries(
) as AgentPrismColors;

function token(name: string) {
return `oklch(var(--${agentPrismPrefix}-${name}) / <alpha-value>)`;
return `hsl(var(--${agentPrismPrefix}-${name}) / <alpha-value>)`;
}
475 changes: 232 additions & 243 deletions frontend/app/src/components/v1/agent-prism/theme/theme.css

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Waterfall } from '../../waterfall';
import { TabOption } from '../step-run-detail';
import { TaskRunTrace } from './task-run-trace';
import { Loading } from '@/components/v1/ui/loading';
import { useSidePanel } from '@/hooks/use-side-panel';
import api from '@/lib/api/api';
import { useQuery } from '@tanstack/react-query';
import { useCallback } from 'react';

export const Observability = ({
taskRunId,
isRunning,
}: {
taskRunId: string;
isRunning: boolean;
}) => {
const { open } = useSidePanel();

const handleTaskRunExpand = useCallback(
(taskRunId: string) => {
open({
type: 'task-run-details',
content: {
taskRunId,
defaultOpenTab: TabOption.Output,
showViewTaskRunButton: true,
},
});
},
[open],
);

const tracesQuery = useQuery({
queryKey: ['task:trace', taskRunId],
queryFn: async () => {
const res = await api.v1TaskGetTrace(taskRunId);
return res.data.rows || [];
},
refetchInterval: isRunning ? 1000 : false,
});

if (!tracesQuery.isFetched) {
return <Loading />;
}

if (!tracesQuery.data || tracesQuery.data.length === 0) {
return (
<Waterfall
workflowRunId={taskRunId}
selectedTaskId={undefined}
handleTaskSelect={handleTaskRunExpand}
/>
);
}

return <TaskRunTrace spans={tracesQuery.data} taskRunId={taskRunId} />;
};
Original file line number Diff line number Diff line change
@@ -1,37 +1,21 @@
import { convertOtelSpans } from './otel-span-adapter';
import { TreeView } from '@/components/v1/agent-prism/TreeView';
import { Loading } from '@/components/v1/ui/loading';
import api from '@/lib/api/api';
import { OtelSpan } from '@/lib/api/generated/data-contracts';
import { openTelemetrySpanAdapter } from '@evilmartians/agent-prism-data';
import { flattenSpans } from '@evilmartians/agent-prism-data';
import { useQuery } from '@tanstack/react-query';
import { useEffect, useMemo, useState } from 'react';

export function TaskRunTrace({
taskExternalId,
isRunning,
spans,
taskRunId,
}: {
taskExternalId: string;
isRunning: boolean;
spans: OtelSpan[];
taskRunId: string;
}) {
const tracesQuery = useQuery({
queryKey: ['task:trace', taskExternalId],
queryFn: async () => {
const res = await api.v1TaskGetTrace(taskExternalId);
return res.data;
},
refetchInterval: isRunning ? 100 : false,
});

const traceSpans = useMemo(() => {
const rows = tracesQuery.data?.rows;
if (!rows || rows.length === 0) {
return [];
}

const otlpSpans = convertOtelSpans(rows, taskExternalId);
const otlpSpans = convertOtelSpans(spans, taskRunId);
return openTelemetrySpanAdapter.convertRawSpansToSpanTree(otlpSpans);
}, [tracesQuery.data, taskExternalId]);
}, [spans, taskRunId]);

const allIds = useMemo(
() => flattenSpans(traceSpans).map((s) => s.id),
Expand All @@ -47,18 +31,6 @@ export function TaskRunTrace({
}
}, [allIds]);

if (tracesQuery.isLoading) {
return <Loading />;
}

if (tracesQuery.isError) {
return (
<div className="py-4 text-sm text-muted-foreground">
Failed to load traces.
</div>
);
}

if (traceSpans.length === 0) {
return (
<div className="py-4 text-sm text-muted-foreground">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import { useIsTaskRunSkipped } from '../../../hooks/use-is-task-run-skipped';
import { isTerminalState } from '../../../hooks/use-workflow-details';
import { TaskRunMiniMap } from '../mini-map';
import { StepRunEvents } from '../step-run-events-for-workflow-run';
import { Waterfall } from '../waterfall';
import { Observability } from './observability/observability';
import { V1StepRunOutput } from './step-run-output';
import { TaskRunLogs } from './task-run-logs';
import { TaskRunTrace } from './task-run-trace';
import RelativeDate from '@/components/v1/molecules/relative-date';
import { CopyWorkflowConfigButton } from '@/components/v1/shared/copy-workflow-config';
import { Button } from '@/components/v1/ui/button';
Expand All @@ -20,7 +19,6 @@ import {
TabsList,
TabsTrigger,
} from '@/components/v1/ui/tabs';
import { useSidePanel } from '@/hooks/use-side-panel';
import { V1TaskStatus, V1TaskSummary, queries } from '@/lib/api';
import { emptyGolangUUID, formatDuration } from '@/lib/utils';
import { TaskRunActionButton } from '@/pages/main/v1/task-runs-v1/actions';
Expand All @@ -29,15 +27,14 @@ import { appRoutes } from '@/router';
import { useQuery } from '@tanstack/react-query';
import { Link, useParams } from '@tanstack/react-router';
import { FullscreenIcon } from 'lucide-react';
import { useCallback, useState } from 'react';
import { useState } from 'react';

export enum TabOption {
Output = 'output',
ChildWorkflowRuns = 'child-workflow-runs',
Input = 'input',
Logs = 'logs',
Trace = 'trace',
Waterfall = 'waterfall',
Observability = 'observability',
AdditionalMetadata = 'additional-metadata',
Activity = 'activity',
}
Expand Down Expand Up @@ -107,21 +104,7 @@ export const TaskRunDetail = ({
defaultOpenTab = TabOption.Output,
showViewTaskRunButton,
}: TaskRunDetailProps) => {
const { open } = useSidePanel();
const [logsResetKey, setLogsResetKey] = useState(0);
const handleTaskRunExpand = useCallback(
(taskRunId: string) => {
open({
type: 'task-run-details',
content: {
taskRunId,
defaultOpenTab: TabOption.Output,
showViewTaskRunButton: true,
},
});
},
[open],
);
const taskRunQuery = useQuery({
...queries.v1Tasks.get(taskRunId),
refetchInterval: (query) => {
Expand Down Expand Up @@ -210,8 +193,8 @@ export const TaskRunDetail = ({
Overview
</TabsTrigger>
{isStandaloneTaskRun && (
<TabsTrigger variant="underlined" value="waterfall">
Waterfall
<TabsTrigger variant="underlined" value="observability">
Observability
</TabsTrigger>
)}
</TabsList>
Expand Down Expand Up @@ -250,9 +233,6 @@ export const TaskRunDetail = ({
<TabsTrigger variant="underlined" value={TabOption.Logs}>
Logs
</TabsTrigger>
<TabsTrigger variant="underlined" value={TabOption.Trace}>
Trace
</TabsTrigger>
<TabsTrigger
variant="underlined"
value={TabOption.AdditionalMetadata}
Expand Down Expand Up @@ -309,12 +289,6 @@ export const TaskRunDetail = ({
<TabsContent value={TabOption.Logs}>
<TaskRunLogs resetTrigger={logsResetKey} taskRun={taskRun} />
</TabsContent>
<TabsContent value={TabOption.Trace}>
<TaskRunTrace
taskExternalId={taskRun.metadata.id}
isRunning={!TASK_RUN_TERMINAL_STATUSES.includes(taskRun.status)}
/>
</TabsContent>
<TabsContent value={TabOption.AdditionalMetadata}>
<CodeHighlighter
className="my-4 h-[400px] max-h-[400px] overflow-y-auto"
Expand All @@ -327,11 +301,10 @@ export const TaskRunDetail = ({
</Tabs>
</TabsContent>
{isStandaloneTaskRun && (
<TabsContent value="waterfall" className="min-h-0 flex-1">
<Waterfall
workflowRunId={taskRunId}
selectedTaskId={undefined}
handleTaskSelect={handleTaskRunExpand}
<TabsContent value="observability" className="min-h-0 flex-1">
<Observability
taskRunId={taskRunId}
isRunning={!TASK_RUN_TERMINAL_STATUSES.includes(taskRun.status)}
/>
</TabsContent>
)}
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const agentPrismTokens = [
const agentPrismColors = Object.fromEntries(
agentPrismTokens.map((name) => [
`agentprism-${name}`,
`oklch(var(--agentprism-${name}) / <alpha-value>)`,
`hsl(var(--agentprism-${name}) / <alpha-value>)`,
])
);

Expand Down
Loading