@inkeep/agents-manage-ui 0.1.2 → 0.1.3
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/.env.example +2 -2
- package/.turbo/turbo-build.log +30 -30
- package/.turbo/turbo-test.log +10 -43
- package/.turbo/turbo-typecheck.log +1 -1
- package/README.md +3 -3
- package/biome.json +3 -0
- package/package.json +8 -7
- package/src/app/api/signoz/conversations/[conversationId]/route.ts +56 -34
- package/src/components/artifact-components/form/artifact-component-form.tsx +16 -7
- package/src/components/data-components/form/data-component-form.tsx +16 -7
- package/src/components/graph/configuration/node-types.tsx +2 -4
- package/src/components/graph/graph.tsx +4 -26
- package/src/components/graph/nodes/agent-node.tsx +1 -1
- package/src/components/graph/nodes/external-agent-node.tsx +1 -1
- package/src/components/graph/playground/chat-widget.tsx +2 -2
- package/src/components/graph/playground/ikp-message.tsx +16 -16
- package/src/components/graph/playground/playground.tsx +5 -5
- package/src/components/graph/sidepane/metadata/metadata-editor.tsx +34 -17
- package/src/components/graph/sidepane/nodes/agent-node-editor.tsx +34 -19
- package/src/components/graph/sidepane/nodes/external-agent-node-editor.tsx +31 -11
- package/src/components/graph/sidepane/nodes/mcp-node-editor.tsx +4 -9
- package/src/components/graph/sidepane/nodes/model-section.tsx +1 -1
- package/src/components/graph/toolbar/toolbar.tsx +1 -1
- package/src/components/mcp-servers/form/active-tools-selector.tsx +4 -2
- package/src/components/projects/form/project-form.tsx +18 -9
- package/src/components/projects/form/project-models-section.tsx +51 -23
- package/src/components/projects/form/project-stopwhen-section.tsx +25 -11
- package/src/components/traces/ai-calls-breakdown.tsx +1 -1
- package/src/components/traces/charts/area-chart-card.tsx +2 -2
- package/src/components/traces/charts/area-chart.tsx +2 -2
- package/src/components/traces/charts/chart-card.tsx +4 -4
- package/src/components/traces/conversation-detail.tsx +10 -8
- package/src/components/traces/conversation-stats/conversation-list-item.tsx +48 -37
- package/src/components/traces/conversation-stats/conversation-stats-card.tsx +1 -1
- package/src/components/traces/filters/date-picker.tsx +6 -6
- package/src/components/traces/filters/filter-trigger.tsx +1 -1
- package/src/components/traces/filters/graph-filter.tsx +3 -3
- package/src/components/traces/timeline/activity-details-sidepane.tsx +1 -1
- package/src/components/traces/timeline/activity-timeline.tsx +1 -1
- package/src/components/traces/timeline/blocks.tsx +2 -2
- package/src/components/traces/timeline/render-panel-content.tsx +11 -11
- package/src/components/traces/timeline/timeline-item.tsx +36 -22
- package/src/components/traces/timeline/timeline-wrapper.tsx +11 -12
- package/src/components/traces/traces-overview.tsx +3 -3
- package/src/components/ui/alert.tsx +17 -23
- package/src/components/ui/calendar.tsx +3 -4
- package/src/components/ui/external-link.tsx +2 -2
- package/src/components/ui/inheritance-indicator.tsx +20 -17
- package/src/components/ui/resizable.tsx +13 -18
- package/src/constants/page-descriptions.tsx +2 -5
- package/src/constants/signoz.ts +15 -18
- package/src/features/graph/domain/__tests__/roundtrip.test.ts +5 -5
- package/src/features/graph/domain/serialize.ts +8 -9
- package/src/hooks/use-auto-prefill-id-zustand.ts +68 -0
- package/src/hooks/use-auto-prefill-id.ts +36 -0
- package/src/hooks/use-chat-activities-polling.ts +1 -1
- package/src/hooks/use-graph-errors.ts +2 -1
- package/src/hooks/use-project-data.ts +2 -2
- package/src/lib/actions/graph-full.ts +6 -2
- package/src/lib/actions/projects.ts +1 -1
- package/src/lib/api/api-config.ts +6 -6
- package/src/lib/api/api-keys.ts +4 -1
- package/src/lib/api/credentials.ts +1 -1
- package/src/lib/api/data-components.ts +1 -1
- package/src/lib/api/graph-full-client.ts +6 -3
- package/src/lib/api/projects.ts +1 -1
- package/src/lib/api/signoz-sql.ts +1 -1
- package/src/lib/index.ts +1 -1
- package/src/lib/logger.ts +1 -2
- package/src/lib/utils/generate-id.ts +14 -0
- package/tsconfig.json +2 -2
- package/eslint.config.mjs +0 -14
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useState } from 'react';
|
|
4
3
|
import { ChevronRight } from 'lucide-react';
|
|
5
|
-
import {
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import { type Control, useController, useWatch } from 'react-hook-form';
|
|
6
|
+
import { ExpandableJsonEditor } from '@/components/form/expandable-json-editor';
|
|
7
|
+
import { ModelSelector } from '@/components/graph/sidepane/nodes/model-selector';
|
|
6
8
|
import { Button } from '@/components/ui/button';
|
|
7
9
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
|
|
8
|
-
import { ExpandableJsonEditor } from '@/components/form/expandable-json-editor';
|
|
9
10
|
import { Label } from '@/components/ui/label';
|
|
10
|
-
import { ModelSelector } from '@/components/graph/sidepane/nodes/model-selector';
|
|
11
11
|
import type { ProjectFormData } from './validation';
|
|
12
12
|
|
|
13
13
|
interface ProjectModelsSectionProps {
|
|
@@ -16,8 +16,11 @@ interface ProjectModelsSectionProps {
|
|
|
16
16
|
|
|
17
17
|
function BaseModelSection({ control }: { control: Control<ProjectFormData> }) {
|
|
18
18
|
const { field: modelField } = useController({ control, name: 'models.base.model' });
|
|
19
|
-
const { field: providerOptionsField } = useController({
|
|
20
|
-
|
|
19
|
+
const { field: providerOptionsField } = useController({
|
|
20
|
+
control,
|
|
21
|
+
name: 'models.base.providerOptions',
|
|
22
|
+
});
|
|
23
|
+
|
|
21
24
|
return (
|
|
22
25
|
<div className="space-y-2">
|
|
23
26
|
<ModelSelector
|
|
@@ -26,13 +29,13 @@ function BaseModelSection({ control }: { control: Control<ProjectFormData> }) {
|
|
|
26
29
|
value={modelField.value || ''}
|
|
27
30
|
onValueChange={modelField.onChange}
|
|
28
31
|
/>
|
|
29
|
-
<p className="text-xs text-muted-foreground">
|
|
30
|
-
Primary model for general agent responses
|
|
31
|
-
</p>
|
|
32
|
+
<p className="text-xs text-muted-foreground">Primary model for general agent responses</p>
|
|
32
33
|
<ExpandableJsonEditor
|
|
33
34
|
name="models.base.providerOptions"
|
|
34
35
|
label="Provider Options"
|
|
35
|
-
value={
|
|
36
|
+
value={
|
|
37
|
+
providerOptionsField.value ? JSON.stringify(providerOptionsField.value, null, 2) : ''
|
|
38
|
+
}
|
|
36
39
|
onChange={(value) => {
|
|
37
40
|
let parsedOptions;
|
|
38
41
|
try {
|
|
@@ -53,8 +56,11 @@ function BaseModelSection({ control }: { control: Control<ProjectFormData> }) {
|
|
|
53
56
|
|
|
54
57
|
function StructuredOutputModelSection({ control }: { control: Control<ProjectFormData> }) {
|
|
55
58
|
const { field: modelField } = useController({ control, name: 'models.structuredOutput.model' });
|
|
56
|
-
const { field: providerOptionsField } = useController({
|
|
57
|
-
|
|
59
|
+
const { field: providerOptionsField } = useController({
|
|
60
|
+
control,
|
|
61
|
+
name: 'models.structuredOutput.providerOptions',
|
|
62
|
+
});
|
|
63
|
+
|
|
58
64
|
return (
|
|
59
65
|
<div className="space-y-2">
|
|
60
66
|
<ModelSelector
|
|
@@ -69,7 +75,9 @@ function StructuredOutputModelSection({ control }: { control: Control<ProjectFor
|
|
|
69
75
|
<ExpandableJsonEditor
|
|
70
76
|
name="models.structuredOutput.providerOptions"
|
|
71
77
|
label="Provider Options"
|
|
72
|
-
value={
|
|
78
|
+
value={
|
|
79
|
+
providerOptionsField.value ? JSON.stringify(providerOptionsField.value, null, 2) : ''
|
|
80
|
+
}
|
|
73
81
|
onChange={(value) => {
|
|
74
82
|
let parsedOptions;
|
|
75
83
|
try {
|
|
@@ -90,8 +98,11 @@ function StructuredOutputModelSection({ control }: { control: Control<ProjectFor
|
|
|
90
98
|
|
|
91
99
|
function SummarizerModelSection({ control }: { control: Control<ProjectFormData> }) {
|
|
92
100
|
const { field: modelField } = useController({ control, name: 'models.summarizer.model' });
|
|
93
|
-
const { field: providerOptionsField } = useController({
|
|
94
|
-
|
|
101
|
+
const { field: providerOptionsField } = useController({
|
|
102
|
+
control,
|
|
103
|
+
name: 'models.summarizer.providerOptions',
|
|
104
|
+
});
|
|
105
|
+
|
|
95
106
|
return (
|
|
96
107
|
<div className="space-y-2">
|
|
97
108
|
<ModelSelector
|
|
@@ -106,7 +117,9 @@ function SummarizerModelSection({ control }: { control: Control<ProjectFormData>
|
|
|
106
117
|
<ExpandableJsonEditor
|
|
107
118
|
name="models.summarizer.providerOptions"
|
|
108
119
|
label="Provider Options"
|
|
109
|
-
value={
|
|
120
|
+
value={
|
|
121
|
+
providerOptionsField.value ? JSON.stringify(providerOptionsField.value, null, 2) : ''
|
|
122
|
+
}
|
|
110
123
|
onChange={(value) => {
|
|
111
124
|
let parsedOptions;
|
|
112
125
|
try {
|
|
@@ -145,7 +158,9 @@ export function ProjectModelsSection({ control }: ProjectModelsSectionProps) {
|
|
|
145
158
|
size="sm"
|
|
146
159
|
className="flex items-center justify-start gap-2 w-full"
|
|
147
160
|
>
|
|
148
|
-
<ChevronRight
|
|
161
|
+
<ChevronRight
|
|
162
|
+
className={`h-4 w-4 transition-transform duration-200 ${isOpen ? 'rotate-90' : ''}`}
|
|
163
|
+
/>
|
|
149
164
|
Configure Default Models
|
|
150
165
|
</Button>
|
|
151
166
|
</CollapsibleTrigger>
|
|
@@ -160,16 +175,29 @@ export function ProjectModelsSection({ control }: ProjectModelsSectionProps) {
|
|
|
160
175
|
<SummarizerModelSection control={control} />
|
|
161
176
|
|
|
162
177
|
<div className="text-xs text-muted-foreground p-3 bg-blue-50 dark:bg-blue-950/20 rounded-md border border-blue-200 dark:border-blue-800">
|
|
163
|
-
<p className="font-medium text-blue-900 dark:text-blue-100 mb-2">
|
|
178
|
+
<p className="font-medium text-blue-900 dark:text-blue-100 mb-2">
|
|
179
|
+
How model inheritance works:
|
|
180
|
+
</p>
|
|
164
181
|
<ul className="space-y-1 text-blue-800 dark:text-blue-200">
|
|
165
|
-
<li
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
182
|
+
<li>
|
|
183
|
+
• <strong>Models</strong>: Project → Graph → Agent (partial inheritance - missing
|
|
184
|
+
models only)
|
|
185
|
+
</li>
|
|
186
|
+
<li>
|
|
187
|
+
• <strong>Individual model types</strong> inherit independently (base,
|
|
188
|
+
structuredOutput, summarizer)
|
|
189
|
+
</li>
|
|
190
|
+
<li>
|
|
191
|
+
• <strong>Explicit settings</strong> always take precedence over inherited values
|
|
192
|
+
</li>
|
|
193
|
+
<li>
|
|
194
|
+
• <strong>Provider options</strong> are inherited along with the model if not
|
|
195
|
+
explicitly set
|
|
196
|
+
</li>
|
|
169
197
|
</ul>
|
|
170
198
|
</div>
|
|
171
199
|
</CollapsibleContent>
|
|
172
200
|
</Collapsible>
|
|
173
201
|
</div>
|
|
174
202
|
);
|
|
175
|
-
}
|
|
203
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useState } from 'react';
|
|
4
3
|
import { ChevronRight } from 'lucide-react';
|
|
5
|
-
import {
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import type { Control } from 'react-hook-form';
|
|
6
|
+
import { GenericInput } from '@/components/form/generic-input';
|
|
6
7
|
import { Button } from '@/components/ui/button';
|
|
7
8
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
|
|
8
|
-
import { GenericInput } from '@/components/form/generic-input';
|
|
9
9
|
import { Label } from '@/components/ui/label';
|
|
10
10
|
import type { ProjectFormData } from './validation';
|
|
11
11
|
|
|
@@ -33,7 +33,9 @@ export function ProjectStopWhenSection({ control }: ProjectStopWhenSectionProps)
|
|
|
33
33
|
size="sm"
|
|
34
34
|
className="flex items-center justify-start gap-2 w-full"
|
|
35
35
|
>
|
|
36
|
-
<ChevronRight
|
|
36
|
+
<ChevronRight
|
|
37
|
+
className={`h-4 w-4 transition-transform duration-200 ${isOpen ? 'rotate-90' : ''}`}
|
|
38
|
+
/>
|
|
37
39
|
Configure Execution Limits
|
|
38
40
|
</Button>
|
|
39
41
|
</CollapsibleTrigger>
|
|
@@ -73,17 +75,29 @@ export function ProjectStopWhenSection({ control }: ProjectStopWhenSectionProps)
|
|
|
73
75
|
</div>
|
|
74
76
|
|
|
75
77
|
<div className="text-xs text-muted-foreground p-3 bg-blue-50 dark:bg-blue-950/20 rounded-md border border-blue-200 dark:border-blue-800">
|
|
76
|
-
<p className="font-medium text-blue-900 dark:text-blue-100 mb-2">
|
|
78
|
+
<p className="font-medium text-blue-900 dark:text-blue-100 mb-2">
|
|
79
|
+
How inheritance works:
|
|
80
|
+
</p>
|
|
77
81
|
<ul className="space-y-1 text-blue-800 dark:text-blue-200">
|
|
78
|
-
<li
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
<li
|
|
82
|
-
|
|
82
|
+
<li>
|
|
83
|
+
• <strong>transferCountIs</strong>: Project → Graph only (graph-level limit)
|
|
84
|
+
</li>
|
|
85
|
+
<li>
|
|
86
|
+
• <strong>stepCountIs</strong>: Project → Agent only (agent-level limit)
|
|
87
|
+
</li>
|
|
88
|
+
<li>
|
|
89
|
+
• <strong>Explicit settings</strong> always take precedence over inherited values
|
|
90
|
+
</li>
|
|
91
|
+
<li>
|
|
92
|
+
• <strong>Default fallback</strong>: transferCountIs = 10 if no value is set
|
|
93
|
+
</li>
|
|
94
|
+
<li>
|
|
95
|
+
• <strong>Error limit</strong> is hardcoded to 3 errors across all levels
|
|
96
|
+
</li>
|
|
83
97
|
</ul>
|
|
84
98
|
</div>
|
|
85
99
|
</CollapsibleContent>
|
|
86
100
|
</Collapsible>
|
|
87
101
|
</div>
|
|
88
102
|
);
|
|
89
|
-
}
|
|
103
|
+
}
|
|
@@ -15,9 +15,9 @@ import {
|
|
|
15
15
|
SelectValue,
|
|
16
16
|
} from '@/components/ui/select';
|
|
17
17
|
import { Skeleton } from '@/components/ui/skeleton';
|
|
18
|
+
import { UNKNOWN_VALUE } from '@/constants/signoz';
|
|
18
19
|
import { type TimeRange, useAICallsQueryState } from '@/hooks/use-ai-calls-query-state';
|
|
19
20
|
import { getSigNozStatsClient } from '@/lib/api/signoz-stats';
|
|
20
|
-
import { UNKNOWN_VALUE } from '@/constants/signoz';
|
|
21
21
|
|
|
22
22
|
// Time range options
|
|
23
23
|
const TIME_RANGES = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AreaChart, type AreaChartProps } from '@/components/traces/charts/area-chart';
|
|
2
2
|
import { ChartCard, type ChartCardProps } from '@/components/traces/charts/chart-card';
|
|
3
3
|
import { ChartNoResults } from '@/components/traces/charts/chart-no-results';
|
|
4
|
-
import {
|
|
4
|
+
import { Skeleton } from '@/components/ui/skeleton';
|
|
5
5
|
|
|
6
6
|
type AreaChartCardProps<TData> = AreaChartProps<TData> &
|
|
7
7
|
Pick<
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { Area, CartesianGrid, AreaChart as RechartsAreaChart, XAxis, YAxis } from 'recharts';
|
|
1
2
|
import {
|
|
3
|
+
type ChartConfig,
|
|
2
4
|
ChartContainer,
|
|
3
5
|
ChartTooltip,
|
|
4
6
|
ChartTooltipContent,
|
|
5
|
-
type ChartConfig,
|
|
6
7
|
} from '@/components/ui/chart';
|
|
7
|
-
import { AreaChart as RechartsAreaChart, Area, XAxis, YAxis, CartesianGrid } from 'recharts';
|
|
8
8
|
|
|
9
9
|
export interface AreaChartProps<TData> {
|
|
10
10
|
data?: TData[];
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import type { LucideIcon } from 'lucide-react';
|
|
2
|
+
import { ArrowUpRight, Info } from 'lucide-react';
|
|
3
|
+
import { ErrorBoundary } from 'react-error-boundary';
|
|
4
|
+
import { Button } from '@/components/ui/button';
|
|
1
5
|
import {
|
|
2
6
|
Card,
|
|
3
7
|
CardContent,
|
|
@@ -8,11 +12,7 @@ import {
|
|
|
8
12
|
} from '@/components/ui/card';
|
|
9
13
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
|
|
10
14
|
import { cn } from '@/lib/utils';
|
|
11
|
-
import type { LucideIcon } from 'lucide-react';
|
|
12
|
-
import { ArrowUpRight, Info } from 'lucide-react';
|
|
13
15
|
import { ChartError } from './chart-error';
|
|
14
|
-
import { Button } from '@/components/ui/button';
|
|
15
|
-
import { ErrorBoundary } from 'react-error-boundary';
|
|
16
16
|
|
|
17
17
|
export interface ChartCardProps {
|
|
18
18
|
className?: string;
|
|
@@ -2,21 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
import { Activity, ArrowLeft, MessageSquare, TriangleAlert } from 'lucide-react';
|
|
4
4
|
import { useEffect, useState } from 'react';
|
|
5
|
-
import {
|
|
6
|
-
import { Button } from '@/components/ui/button';
|
|
7
|
-
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
8
|
-
import { Skeleton } from '@/components/ui/skeleton';
|
|
5
|
+
import { formatDateTime, formatDuration } from '@/app/utils/format-date';
|
|
9
6
|
import type {
|
|
10
7
|
ActivityItem,
|
|
11
8
|
ConversationDetail as ConversationDetailType,
|
|
12
9
|
} from '@/components/traces/timeline/types';
|
|
13
|
-
import {
|
|
10
|
+
import { Badge } from '@/components/ui/badge';
|
|
11
|
+
import { Button } from '@/components/ui/button';
|
|
12
|
+
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
13
|
+
import { ResizablePanelGroup } from '@/components/ui/resizable';
|
|
14
|
+
import { Skeleton } from '@/components/ui/skeleton';
|
|
14
15
|
import { ConversationErrors } from './conversation-errors';
|
|
15
16
|
import { SignozLink } from './signoz-link';
|
|
16
|
-
import { formatDuration } from '@/app/utils/format-date';
|
|
17
17
|
import { InfoRow } from './timeline/blocks';
|
|
18
18
|
import { TimelineWrapper } from './timeline/timeline-wrapper';
|
|
19
|
-
import { ResizablePanelGroup } from '@/components/ui/resizable';
|
|
20
19
|
|
|
21
20
|
interface ConversationDetailProps {
|
|
22
21
|
conversationId: string;
|
|
@@ -109,7 +108,10 @@ export function ConversationDetail({ conversationId, onBack }: ConversationDetai
|
|
|
109
108
|
</Badge>
|
|
110
109
|
{(conversation.graphId || conversation.graphName) && (
|
|
111
110
|
<Badge variant="code" className="text-xs">
|
|
112
|
-
Graph:
|
|
111
|
+
Graph:{' '}
|
|
112
|
+
{conversation.graphName
|
|
113
|
+
? `${conversation.graphName} (${conversation.graphId})`
|
|
114
|
+
: conversation.graphId}
|
|
113
115
|
</Badge>
|
|
114
116
|
)}
|
|
115
117
|
</div>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ConversationStats } from '@/lib/api/signoz-stats';
|
|
2
|
-
import { Badge } from '@/components/ui/badge';
|
|
3
1
|
import Link from 'next/link';
|
|
4
|
-
import { TooltipContent, Tooltip, TooltipTrigger } from '@/components/ui/tooltip';
|
|
5
2
|
import { formatDateAgo, formatDateTime } from '@/app/utils/format-date';
|
|
3
|
+
import { Badge } from '@/components/ui/badge';
|
|
4
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
|
5
|
+
import type { ConversationStats } from '@/lib/api/signoz-stats';
|
|
6
6
|
|
|
7
7
|
interface ConversationListItemProps {
|
|
8
8
|
conversation: ConversationStats;
|
|
@@ -10,8 +10,17 @@ interface ConversationListItemProps {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export function ConversationListItem({ conversation, projectId }: ConversationListItemProps) {
|
|
13
|
-
const {
|
|
14
|
-
|
|
13
|
+
const {
|
|
14
|
+
conversationId,
|
|
15
|
+
firstUserMessage,
|
|
16
|
+
tenantId,
|
|
17
|
+
graphId,
|
|
18
|
+
graphName,
|
|
19
|
+
hasErrors,
|
|
20
|
+
totalErrors,
|
|
21
|
+
toolsUsed,
|
|
22
|
+
startTime,
|
|
23
|
+
} = conversation;
|
|
15
24
|
|
|
16
25
|
return (
|
|
17
26
|
<Link
|
|
@@ -26,38 +35,40 @@ export function ConversationListItem({ conversation, projectId }: ConversationLi
|
|
|
26
35
|
</div>
|
|
27
36
|
|
|
28
37
|
<div className="flex items-center gap-2 text-xs">
|
|
29
|
-
<code className="font-mono text-gray-500 dark:text-white/50">
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
</
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
38
|
+
<code className="font-mono text-gray-500 dark:text-white/50">{conversationId}</code>
|
|
39
|
+
{startTime &&
|
|
40
|
+
(() => {
|
|
41
|
+
try {
|
|
42
|
+
const date = new Date(startTime);
|
|
43
|
+
// Check if the date is valid
|
|
44
|
+
if (isNaN(date.getTime())) return null;
|
|
45
|
+
|
|
46
|
+
const isoString = date.toISOString();
|
|
47
|
+
return (
|
|
48
|
+
<>
|
|
49
|
+
<span className="text-gray-400 dark:text-white/40">•</span>
|
|
50
|
+
<Tooltip>
|
|
51
|
+
<TooltipTrigger asChild>
|
|
52
|
+
<span className="text-gray-400 dark:text-white/40 cursor-help">
|
|
53
|
+
{formatDateAgo(isoString)}
|
|
54
|
+
</span>
|
|
55
|
+
</TooltipTrigger>
|
|
56
|
+
<TooltipContent>
|
|
57
|
+
<p className="text-xs">Started: {formatDateTime(isoString)}</p>
|
|
58
|
+
</TooltipContent>
|
|
59
|
+
</Tooltip>
|
|
60
|
+
</>
|
|
61
|
+
);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.warn(
|
|
64
|
+
'Invalid startTime for conversation:',
|
|
65
|
+
conversationId,
|
|
66
|
+
startTime,
|
|
67
|
+
error
|
|
68
|
+
);
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
})()}
|
|
61
72
|
</div>
|
|
62
73
|
</div>
|
|
63
74
|
<div className="flex items-center gap-2">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import React from 'react';
|
|
4
3
|
import { ChevronLeft, ChevronRight, MessageSquare, Search, X } from 'lucide-react';
|
|
4
|
+
import React from 'react';
|
|
5
5
|
import { Badge } from '@/components/ui/badge';
|
|
6
6
|
import { Button } from '@/components/ui/button';
|
|
7
7
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { format } from 'date-fns';
|
|
4
|
+
import { Check } from 'lucide-react';
|
|
5
|
+
import { useMemo, useRef, useState } from 'react';
|
|
6
|
+
import type { DateRange } from 'react-day-picker';
|
|
3
7
|
import type { SelectOption } from '@/components/form/generic-select';
|
|
4
|
-
import { FilterTriggerComponent } from './filter-trigger';
|
|
5
8
|
import { Button } from '@/components/ui/button';
|
|
6
9
|
import { Calendar } from '@/components/ui/calendar';
|
|
7
10
|
import { Command, CommandGroup, CommandItem, CommandList } from '@/components/ui/command';
|
|
8
11
|
import { Popover, PopoverContent } from '@/components/ui/popover';
|
|
9
12
|
import { useDisclosure } from '@/hooks/use-disclosure';
|
|
10
|
-
import { cn } from '@/lib/utils';
|
|
11
|
-
import { format } from 'date-fns';
|
|
12
|
-
import { Check } from 'lucide-react';
|
|
13
|
-
import { useMemo, useRef, useState } from 'react';
|
|
14
|
-
import type { DateRange } from 'react-day-picker';
|
|
15
13
|
import type { TimeRange } from '@/hooks/use-traces-query-state';
|
|
14
|
+
import { cn } from '@/lib/utils';
|
|
15
|
+
import { FilterTriggerComponent } from './filter-trigger';
|
|
16
16
|
|
|
17
17
|
interface DatePickerWithPresetsProps {
|
|
18
18
|
label: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ChevronDown, type LucideIcon, X } from 'lucide-react';
|
|
2
2
|
import { Button } from '@/components/ui/button';
|
|
3
|
-
import { PopoverTrigger } from '@/components/ui/popover';
|
|
4
3
|
import type { OptionType } from '@/components/ui/combobox';
|
|
4
|
+
import { PopoverTrigger } from '@/components/ui/popover';
|
|
5
5
|
|
|
6
6
|
interface FilterTriggerComponentProps {
|
|
7
7
|
Icon?: LucideIcon;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useState, useEffect } from 'react';
|
|
4
3
|
import { useParams } from 'next/navigation';
|
|
5
|
-
import {
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
import type { OptionType } from '@/components/ui/combobox';
|
|
6
6
|
import { Combobox } from '@/components/ui/combobox';
|
|
7
|
+
import { getAllGraphsAction } from '@/lib/actions/graph-full';
|
|
7
8
|
import { FilterTriggerComponent } from './filter-trigger';
|
|
8
|
-
import type { OptionType } from '@/components/ui/combobox';
|
|
9
9
|
|
|
10
10
|
interface GraphFilterProps {
|
|
11
11
|
onSelect: (value: string | undefined) => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ActivityItem } from '@/components/traces/timeline/types';
|
|
2
1
|
import { TimelineItem } from '@/components/traces/timeline/timeline-item';
|
|
2
|
+
import type { ActivityItem } from '@/components/traces/timeline/types';
|
|
3
3
|
|
|
4
4
|
export function ActivityTimeline({
|
|
5
5
|
activities,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Badge } from '@/components/ui/badge';
|
|
2
|
-
import type { ActivityItem } from './types';
|
|
3
1
|
import { AnthropicIcon } from '@/components/icons/anthropic';
|
|
4
2
|
import { OpenAIIcon } from '@/components/icons/openai';
|
|
3
|
+
import { Badge } from '@/components/ui/badge';
|
|
4
|
+
import type { ActivityItem } from './types';
|
|
5
5
|
|
|
6
6
|
export function LabeledBlock({ label, children }: { label: string; children: React.ReactNode }) {
|
|
7
7
|
return (
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { SelectedPanel } from '@/components/traces/timeline/types';
|
|
2
|
-
import { Section } from '@/components/traces/timeline/blocks';
|
|
3
|
-
import { Info } from '@/components/traces/timeline/blocks';
|
|
4
1
|
import { Streamdown } from 'streamdown';
|
|
5
|
-
import { LabeledBlock } from '@/components/traces/timeline/blocks';
|
|
6
|
-
import { Bubble } from '@/components/traces/timeline/bubble';
|
|
7
|
-
import { StatusBadge } from '@/components/traces/timeline/blocks';
|
|
8
2
|
import { formatDateTime } from '@/app/utils/format-date';
|
|
9
|
-
import { Divider } from '@/components/traces/timeline/blocks';
|
|
10
|
-
import { Badge } from '@/components/ui/badge';
|
|
11
|
-
import type { ConversationDetail } from '@/components/traces/timeline/types';
|
|
12
|
-
import { ModelBadge } from '@/components/traces/timeline/blocks';
|
|
13
|
-
import { CodeBubble } from '@/components/traces/timeline/bubble';
|
|
14
3
|
import { SignozSpanLink } from '@/components/traces/signoz-link';
|
|
4
|
+
import {
|
|
5
|
+
Divider,
|
|
6
|
+
Info,
|
|
7
|
+
LabeledBlock,
|
|
8
|
+
ModelBadge,
|
|
9
|
+
Section,
|
|
10
|
+
StatusBadge,
|
|
11
|
+
} from '@/components/traces/timeline/blocks';
|
|
12
|
+
import { Bubble, CodeBubble } from '@/components/traces/timeline/bubble';
|
|
13
|
+
import type { ConversationDetail, SelectedPanel } from '@/components/traces/timeline/types';
|
|
14
|
+
import { Badge } from '@/components/ui/badge';
|
|
15
15
|
|
|
16
16
|
export function renderPanelContent({
|
|
17
17
|
selected,
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ArrowRight,
|
|
3
|
+
ArrowUpRight,
|
|
4
|
+
CheckCircle,
|
|
5
|
+
ChevronDown,
|
|
6
|
+
ChevronRight,
|
|
7
|
+
Database,
|
|
8
|
+
Hammer,
|
|
9
|
+
Settings,
|
|
10
|
+
Sparkles,
|
|
11
|
+
User,
|
|
12
|
+
} from 'lucide-react';
|
|
13
|
+
import { Streamdown } from 'streamdown';
|
|
14
|
+
import { formatDateTime } from '@/app/utils/format-date';
|
|
15
|
+
import { Bubble, CodeBubble } from '@/components/traces/timeline/bubble';
|
|
16
|
+
import { Flow } from '@/components/traces/timeline/flow';
|
|
17
|
+
import { TagRow } from '@/components/traces/timeline/tag-row';
|
|
18
|
+
import {
|
|
19
|
+
ACTIVITY_TYPES,
|
|
2
20
|
type ActivityItem,
|
|
3
21
|
type ActivityKind,
|
|
4
|
-
|
|
22
|
+
TOOL_TYPES,
|
|
5
23
|
} from '@/components/traces/timeline/types';
|
|
6
|
-
import { User, Settings, Database, Hammer, Sparkles, ArrowRight, ArrowUpRight, ChevronDown, ChevronRight } from 'lucide-react';
|
|
7
|
-
import { Bubble, CodeBubble } from '@/components/traces/timeline/bubble';
|
|
8
|
-
import { TagRow } from '@/components/traces/timeline/tag-row';
|
|
9
|
-
import { TOOL_TYPES } from '@/components/traces/timeline/types';
|
|
10
|
-
import { CheckCircle } from 'lucide-react';
|
|
11
|
-
import { Flow } from '@/components/traces/timeline/flow';
|
|
12
|
-
import { Streamdown } from 'streamdown';
|
|
13
|
-
import { formatDateTime } from '@/app/utils/format-date';
|
|
14
24
|
|
|
15
25
|
function truncateWords(s: string, nWords: number) {
|
|
16
26
|
const words = s.split(/\s+/);
|
|
@@ -21,8 +31,10 @@ function truncateChars(s: string, n: number) {
|
|
|
21
31
|
}
|
|
22
32
|
|
|
23
33
|
function isAiMessage(activity: ActivityItem): boolean {
|
|
24
|
-
return
|
|
25
|
-
|
|
34
|
+
return (
|
|
35
|
+
activity.type === ACTIVITY_TYPES.AI_ASSISTANT_MESSAGE ||
|
|
36
|
+
activity.type === ACTIVITY_TYPES.AI_MODEL_STREAMED_TEXT
|
|
37
|
+
);
|
|
26
38
|
}
|
|
27
39
|
|
|
28
40
|
function statusIcon(
|
|
@@ -64,12 +76,12 @@ interface TimelineItemProps {
|
|
|
64
76
|
onToggleAiMessageCollapse?: (activityId: string) => void;
|
|
65
77
|
}
|
|
66
78
|
|
|
67
|
-
export function TimelineItem({
|
|
68
|
-
activity,
|
|
69
|
-
isLast,
|
|
70
|
-
onSelect,
|
|
71
|
-
isAiMessageCollapsed = false,
|
|
72
|
-
onToggleAiMessageCollapse
|
|
79
|
+
export function TimelineItem({
|
|
80
|
+
activity,
|
|
81
|
+
isLast,
|
|
82
|
+
onSelect,
|
|
83
|
+
isAiMessageCollapsed = false,
|
|
84
|
+
onToggleAiMessageCollapse,
|
|
73
85
|
}: TimelineItemProps) {
|
|
74
86
|
const typeForIcon =
|
|
75
87
|
activity.type === ACTIVITY_TYPES.TOOL_CALL && activity.toolType === TOOL_TYPES.TRANSFER
|
|
@@ -128,7 +140,7 @@ export function TimelineItem({
|
|
|
128
140
|
type="button"
|
|
129
141
|
onClick={() => onToggleAiMessageCollapse(activity.id)}
|
|
130
142
|
className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors"
|
|
131
|
-
title={isAiMessageCollapsed ?
|
|
143
|
+
title={isAiMessageCollapsed ? 'Expand AI response' : 'Collapse AI response'}
|
|
132
144
|
>
|
|
133
145
|
{isAiMessageCollapsed ? (
|
|
134
146
|
<ChevronRight className="h-3 w-3" />
|
|
@@ -154,7 +166,11 @@ export function TimelineItem({
|
|
|
154
166
|
type="button"
|
|
155
167
|
onClick={() => onToggleAiMessageCollapse(activity.id)}
|
|
156
168
|
className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors"
|
|
157
|
-
title={
|
|
169
|
+
title={
|
|
170
|
+
isAiMessageCollapsed
|
|
171
|
+
? 'Expand AI streaming response'
|
|
172
|
+
: 'Collapse AI streaming response'
|
|
173
|
+
}
|
|
158
174
|
>
|
|
159
175
|
{isAiMessageCollapsed ? (
|
|
160
176
|
<ChevronRight className="h-3 w-3" />
|
|
@@ -165,9 +181,7 @@ export function TimelineItem({
|
|
|
165
181
|
</button>
|
|
166
182
|
)}
|
|
167
183
|
{!isAiMessageCollapsed && (
|
|
168
|
-
<Bubble>
|
|
169
|
-
{truncateWords(activity.aiStreamTextContent, 100)}
|
|
170
|
-
</Bubble>
|
|
184
|
+
<Bubble>{truncateWords(activity.aiStreamTextContent, 100)}</Bubble>
|
|
171
185
|
)}
|
|
172
186
|
</div>
|
|
173
187
|
)}
|