@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.
Files changed (72) hide show
  1. package/.env.example +2 -2
  2. package/.turbo/turbo-build.log +30 -30
  3. package/.turbo/turbo-test.log +10 -43
  4. package/.turbo/turbo-typecheck.log +1 -1
  5. package/README.md +3 -3
  6. package/biome.json +3 -0
  7. package/package.json +8 -7
  8. package/src/app/api/signoz/conversations/[conversationId]/route.ts +56 -34
  9. package/src/components/artifact-components/form/artifact-component-form.tsx +16 -7
  10. package/src/components/data-components/form/data-component-form.tsx +16 -7
  11. package/src/components/graph/configuration/node-types.tsx +2 -4
  12. package/src/components/graph/graph.tsx +4 -26
  13. package/src/components/graph/nodes/agent-node.tsx +1 -1
  14. package/src/components/graph/nodes/external-agent-node.tsx +1 -1
  15. package/src/components/graph/playground/chat-widget.tsx +2 -2
  16. package/src/components/graph/playground/ikp-message.tsx +16 -16
  17. package/src/components/graph/playground/playground.tsx +5 -5
  18. package/src/components/graph/sidepane/metadata/metadata-editor.tsx +34 -17
  19. package/src/components/graph/sidepane/nodes/agent-node-editor.tsx +34 -19
  20. package/src/components/graph/sidepane/nodes/external-agent-node-editor.tsx +31 -11
  21. package/src/components/graph/sidepane/nodes/mcp-node-editor.tsx +4 -9
  22. package/src/components/graph/sidepane/nodes/model-section.tsx +1 -1
  23. package/src/components/graph/toolbar/toolbar.tsx +1 -1
  24. package/src/components/mcp-servers/form/active-tools-selector.tsx +4 -2
  25. package/src/components/projects/form/project-form.tsx +18 -9
  26. package/src/components/projects/form/project-models-section.tsx +51 -23
  27. package/src/components/projects/form/project-stopwhen-section.tsx +25 -11
  28. package/src/components/traces/ai-calls-breakdown.tsx +1 -1
  29. package/src/components/traces/charts/area-chart-card.tsx +2 -2
  30. package/src/components/traces/charts/area-chart.tsx +2 -2
  31. package/src/components/traces/charts/chart-card.tsx +4 -4
  32. package/src/components/traces/conversation-detail.tsx +10 -8
  33. package/src/components/traces/conversation-stats/conversation-list-item.tsx +48 -37
  34. package/src/components/traces/conversation-stats/conversation-stats-card.tsx +1 -1
  35. package/src/components/traces/filters/date-picker.tsx +6 -6
  36. package/src/components/traces/filters/filter-trigger.tsx +1 -1
  37. package/src/components/traces/filters/graph-filter.tsx +3 -3
  38. package/src/components/traces/timeline/activity-details-sidepane.tsx +1 -1
  39. package/src/components/traces/timeline/activity-timeline.tsx +1 -1
  40. package/src/components/traces/timeline/blocks.tsx +2 -2
  41. package/src/components/traces/timeline/render-panel-content.tsx +11 -11
  42. package/src/components/traces/timeline/timeline-item.tsx +36 -22
  43. package/src/components/traces/timeline/timeline-wrapper.tsx +11 -12
  44. package/src/components/traces/traces-overview.tsx +3 -3
  45. package/src/components/ui/alert.tsx +17 -23
  46. package/src/components/ui/calendar.tsx +3 -4
  47. package/src/components/ui/external-link.tsx +2 -2
  48. package/src/components/ui/inheritance-indicator.tsx +20 -17
  49. package/src/components/ui/resizable.tsx +13 -18
  50. package/src/constants/page-descriptions.tsx +2 -5
  51. package/src/constants/signoz.ts +15 -18
  52. package/src/features/graph/domain/__tests__/roundtrip.test.ts +5 -5
  53. package/src/features/graph/domain/serialize.ts +8 -9
  54. package/src/hooks/use-auto-prefill-id-zustand.ts +68 -0
  55. package/src/hooks/use-auto-prefill-id.ts +36 -0
  56. package/src/hooks/use-chat-activities-polling.ts +1 -1
  57. package/src/hooks/use-graph-errors.ts +2 -1
  58. package/src/hooks/use-project-data.ts +2 -2
  59. package/src/lib/actions/graph-full.ts +6 -2
  60. package/src/lib/actions/projects.ts +1 -1
  61. package/src/lib/api/api-config.ts +6 -6
  62. package/src/lib/api/api-keys.ts +4 -1
  63. package/src/lib/api/credentials.ts +1 -1
  64. package/src/lib/api/data-components.ts +1 -1
  65. package/src/lib/api/graph-full-client.ts +6 -3
  66. package/src/lib/api/projects.ts +1 -1
  67. package/src/lib/api/signoz-sql.ts +1 -1
  68. package/src/lib/index.ts +1 -1
  69. package/src/lib/logger.ts +1 -2
  70. package/src/lib/utils/generate-id.ts +14 -0
  71. package/tsconfig.json +2 -2
  72. 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 { Control, useController, useWatch } from 'react-hook-form';
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({ control, name: 'models.base.providerOptions' });
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={providerOptionsField.value ? JSON.stringify(providerOptionsField.value, null, 2) : ''}
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({ control, name: 'models.structuredOutput.providerOptions' });
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={providerOptionsField.value ? JSON.stringify(providerOptionsField.value, null, 2) : ''}
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({ control, name: 'models.summarizer.providerOptions' });
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={providerOptionsField.value ? JSON.stringify(providerOptionsField.value, null, 2) : ''}
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 className={`h-4 w-4 transition-transform duration-200 ${isOpen ? 'rotate-90' : ''}`} />
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">How model inheritance works:</p>
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>• <strong>Models</strong>: Project → Graph → Agent (partial inheritance - missing models only)</li>
166
- <li>• <strong>Individual model types</strong> inherit independently (base, structuredOutput, summarizer)</li>
167
- <li>• <strong>Explicit settings</strong> always take precedence over inherited values</li>
168
- <li>• <strong>Provider options</strong> are inherited along with the model if not explicitly set</li>
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 { Control } from 'react-hook-form';
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 className={`h-4 w-4 transition-transform duration-200 ${isOpen ? 'rotate-90' : ''}`} />
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">How inheritance works:</p>
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>• <strong>transferCountIs</strong>: Project → Graph only (graph-level limit)</li>
79
- <li>• <strong>stepCountIs</strong>: Project → Agent only (agent-level limit)</li>
80
- <li>• <strong>Explicit settings</strong> always take precedence over inherited values</li>
81
- <li>• <strong>Default fallback</strong>: transferCountIs = 10 if no value is set</li>
82
- <li>• <strong>Error limit</strong> is hardcoded to 3 errors across all levels</li>
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 { Skeleton } from '@/components/ui/skeleton';
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 { AreaChart, type AreaChartProps } from '@/components/traces/charts/area-chart';
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 { Badge } from '@/components/ui/badge';
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 { formatDateTime } from '@/app/utils/format-date';
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: {conversation.graphName ? `${conversation.graphName} (${conversation.graphId})` : conversation.graphId}
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 { conversationId, firstUserMessage, tenantId, graphId, graphName, hasErrors, totalErrors, toolsUsed, startTime } =
14
- conversation;
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
- {conversationId}
31
- </code>
32
- {startTime && (() => {
33
- try {
34
- const date = new Date(startTime);
35
- // Check if the date is valid
36
- if (isNaN(date.getTime())) return null;
37
-
38
- const isoString = date.toISOString();
39
- return (
40
- <>
41
- <span className="text-gray-400 dark:text-white/40">•</span>
42
- <Tooltip>
43
- <TooltipTrigger asChild>
44
- <span className="text-gray-400 dark:text-white/40 cursor-help">
45
- {formatDateAgo(isoString)}
46
- </span>
47
- </TooltipTrigger>
48
- <TooltipContent>
49
- <p className="text-xs">
50
- Started: {formatDateTime(isoString)}
51
- </p>
52
- </TooltipContent>
53
- </Tooltip>
54
- </>
55
- );
56
- } catch (error) {
57
- console.warn('Invalid startTime for conversation:', conversationId, startTime, error);
58
- return null;
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 { getAllGraphsAction } from '@/lib/actions/graph-full';
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 { Button } from '@/components/ui/button';
2
1
  import { X } from 'lucide-react';
2
+ import { Button } from '@/components/ui/button';
3
3
 
4
4
  export function ActivityDetailsSidePane({
5
5
  title,
@@ -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
- ACTIVITY_TYPES,
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 activity.type === ACTIVITY_TYPES.AI_ASSISTANT_MESSAGE ||
25
- activity.type === ACTIVITY_TYPES.AI_MODEL_STREAMED_TEXT;
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 ? "Expand AI response" : "Collapse AI response"}
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={isAiMessageCollapsed ? "Expand AI streaming response" : "Collapse AI streaming response"}
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
  )}