@tanstack/ai-devtools-core 0.3.37 → 0.4.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.
Files changed (52) hide show
  1. package/dist/Shell/DKCFIT6H.js +12142 -0
  2. package/dist/Shell/SLOX2TPU.js +12119 -0
  3. package/dist/Shell/Z6HLJOVZ.js +10170 -0
  4. package/dist/dev.js +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/production/Shell/DKCFIT6H.js +12142 -0
  7. package/dist/production/Shell/SLOX2TPU.js +12119 -0
  8. package/dist/production/Shell/Z6HLJOVZ.js +10170 -0
  9. package/dist/production/dev.js +1 -1
  10. package/dist/production/index.js +1 -1
  11. package/dist/production/server.js +1 -1
  12. package/dist/server.js +1 -1
  13. package/package.json +4 -4
  14. package/src/components/Shell.tsx +74 -30
  15. package/src/components/conversation/IterationCard.tsx +261 -12
  16. package/src/components/conversation/IterationTimeline.tsx +66 -16
  17. package/src/components/conversation/index.ts +0 -9
  18. package/src/components/hooks/FixtureNamePopover.tsx +69 -0
  19. package/src/components/hooks/GenerationPanel.tsx +847 -0
  20. package/src/components/hooks/HookDashboard.tsx +292 -0
  21. package/src/components/hooks/HookDetails.tsx +1757 -0
  22. package/src/components/hooks/ToolFixtureForm.tsx +347 -0
  23. package/src/components/hooks/hook-dashboard-model.ts +134 -0
  24. package/src/components/hooks/index.ts +4 -0
  25. package/src/components/hooks/preview-messages.ts +117 -0
  26. package/src/components/hooks/preview-model.ts +195 -0
  27. package/src/components/utils/format.ts +0 -58
  28. package/src/store/ai-context.tsx +1165 -159
  29. package/src/store/ai-store.ts +0 -1
  30. package/src/store/hook-registry.ts +815 -0
  31. package/src/store/message-event-utils.ts +60 -0
  32. package/src/styles/use-styles.ts +1558 -99
  33. package/dist/Shell/MRWZEHAJ.js +0 -6225
  34. package/dist/Shell/RRRNZJ5E.js +0 -7560
  35. package/dist/production/Shell/MRWZEHAJ.js +0 -6225
  36. package/dist/production/Shell/RRRNZJ5E.js +0 -7560
  37. package/src/components/ConversationDetails.tsx +0 -216
  38. package/src/components/ConversationsList.tsx +0 -21
  39. package/src/components/conversation/ActivityEventsTab.tsx +0 -57
  40. package/src/components/conversation/ChunkBadges.tsx +0 -51
  41. package/src/components/conversation/ChunkItem.tsx +0 -273
  42. package/src/components/conversation/ChunksCollapsible.tsx +0 -56
  43. package/src/components/conversation/ChunksTab.tsx +0 -87
  44. package/src/components/conversation/ConversationHeader.tsx +0 -106
  45. package/src/components/conversation/ConversationTabs.tsx +0 -205
  46. package/src/components/conversation/MessageCard.tsx +0 -174
  47. package/src/components/conversation/MessageGroup.tsx +0 -101
  48. package/src/components/conversation/MessagesTab.tsx +0 -30
  49. package/src/components/conversation/SummariesTab.tsx +0 -91
  50. package/src/components/conversation/ToolCallDisplay.tsx +0 -99
  51. package/src/components/list/ConversationRow.tsx +0 -85
  52. package/src/components/list/index.ts +0 -1
@@ -0,0 +1,195 @@
1
+ export type HoverOrigin = 'timeline' | 'preview'
2
+
3
+ export interface HoverTarget {
4
+ messageIds: Array<string>
5
+ partIds: Array<string>
6
+ origin: HoverOrigin
7
+ }
8
+
9
+ export interface PreviewJsonItem {
10
+ label: string
11
+ value: unknown
12
+ }
13
+
14
+ export interface StructuredOutputJsonSource {
15
+ data?: unknown
16
+ partial?: unknown
17
+ raw?: unknown
18
+ reasoning?: unknown
19
+ errorMessage?: unknown
20
+ }
21
+
22
+ export function createHoverTarget(input: {
23
+ messageIds?: Array<string | null | undefined>
24
+ partIds?: Array<string | null | undefined>
25
+ origin?: HoverOrigin
26
+ }): HoverTarget {
27
+ return {
28
+ messageIds: uniqueStrings(input.messageIds ?? []),
29
+ partIds: uniqueStrings(input.partIds ?? []),
30
+ origin: input.origin ?? 'timeline',
31
+ }
32
+ }
33
+
34
+ export function createHoverTargetFromDataAttributes(input: {
35
+ messageIds?: string | null
36
+ partIds?: string | null
37
+ origin?: HoverOrigin
38
+ }): HoverTarget | null {
39
+ const target = createHoverTarget({
40
+ messageIds: splitDataIds(input.messageIds),
41
+ partIds: splitDataIds(input.partIds),
42
+ origin: input.origin,
43
+ })
44
+
45
+ if (target.messageIds.length === 0 && target.partIds.length === 0) {
46
+ return null
47
+ }
48
+
49
+ return target
50
+ }
51
+
52
+ export function isMessageHighlighted(
53
+ messageId: string,
54
+ target: HoverTarget | null,
55
+ ): boolean {
56
+ return target?.messageIds.includes(messageId) ?? false
57
+ }
58
+
59
+ export function isPartHighlighted(
60
+ messageId: string,
61
+ partId: string,
62
+ target: HoverTarget | null,
63
+ ): boolean {
64
+ if (!target) return false
65
+ return (
66
+ target.partIds.includes(partId) || target.messageIds.includes(messageId)
67
+ )
68
+ }
69
+
70
+ export function isMessageOrPartHighlighted(
71
+ messageId: string,
72
+ partIds: Array<string>,
73
+ target: HoverTarget | null,
74
+ ): boolean {
75
+ if (!target) return false
76
+ return (
77
+ target.messageIds.includes(messageId) ||
78
+ partIds.some((partId) => target.partIds.includes(partId))
79
+ )
80
+ }
81
+
82
+ export function getHoverDataAttributes(target: {
83
+ messageIds?: Array<string>
84
+ partIds?: Array<string>
85
+ }): Record<string, string> {
86
+ return {
87
+ 'data-ai-devtools-hover-message-ids': (target.messageIds ?? []).join(','),
88
+ 'data-ai-devtools-hover-part-ids': (target.partIds ?? []).join(','),
89
+ }
90
+ }
91
+
92
+ export function hoverTargetMatchesElement(
93
+ target: HoverTarget,
94
+ elementTarget: {
95
+ messageIds?: string | null
96
+ partIds?: string | null
97
+ },
98
+ ): boolean {
99
+ const messageIds = splitDataIds(elementTarget.messageIds)
100
+ const partIds = splitDataIds(elementTarget.partIds)
101
+
102
+ return (
103
+ target.messageIds.some((id) => messageIds.includes(id)) ||
104
+ target.partIds.some((id) => partIds.includes(id))
105
+ )
106
+ }
107
+
108
+ export function toolCallPartId(toolCallId: string): string {
109
+ return `tool-call:${toolCallId}`
110
+ }
111
+
112
+ export function toolResultPartId(toolCallId: string): string {
113
+ return `tool-result:${toolCallId}`
114
+ }
115
+
116
+ export function structuredOutputPartId(messageId: string): string {
117
+ return `structured-output:${messageId}`
118
+ }
119
+
120
+ export function parseJsonishValue(value: unknown): unknown {
121
+ if (typeof value !== 'string') return value
122
+
123
+ const trimmed = value.trim()
124
+ if (!trimmed) return value
125
+ if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return value
126
+
127
+ try {
128
+ return JSON.parse(trimmed)
129
+ } catch {
130
+ return value
131
+ }
132
+ }
133
+
134
+ export function structuredOutputJsonItems(
135
+ source: StructuredOutputJsonSource,
136
+ ): Array<PreviewJsonItem> {
137
+ const raw = typeof source.raw === 'string' ? source.raw : undefined
138
+ const items: Array<PreviewJsonItem> = []
139
+ const partialValue =
140
+ source.partial !== undefined
141
+ ? source.partial
142
+ : source.data !== undefined
143
+ ? source.data
144
+ : parseJsonishValue(raw)
145
+
146
+ if (raw !== undefined) {
147
+ items.push({
148
+ label: 'Raw',
149
+ value: raw,
150
+ })
151
+ }
152
+
153
+ if (partialValue !== undefined) {
154
+ items.push({
155
+ label: 'Partial',
156
+ value: partialValue,
157
+ })
158
+ }
159
+
160
+ if (source.reasoning !== undefined) {
161
+ items.push({
162
+ label: 'Reasoning',
163
+ value: source.reasoning,
164
+ })
165
+ }
166
+
167
+ if (source.errorMessage !== undefined) {
168
+ items.push({
169
+ label: 'Error',
170
+ value: source.errorMessage,
171
+ })
172
+ }
173
+
174
+ return items
175
+ }
176
+
177
+ function uniqueStrings(
178
+ values: Array<string | null | undefined>,
179
+ ): Array<string> {
180
+ const result: Array<string> = []
181
+ const seen = new Set<string>()
182
+
183
+ for (const value of values) {
184
+ if (!value || seen.has(value)) continue
185
+ seen.add(value)
186
+ result.push(value)
187
+ }
188
+
189
+ return result
190
+ }
191
+
192
+ function splitDataIds(value: string | null | undefined): Array<string> {
193
+ if (!value) return []
194
+ return value.split(',').filter(Boolean)
195
+ }
@@ -1,63 +1,5 @@
1
- import type { Chunk } from '../../store/ai-store'
2
-
3
- export const formatTimestamp = (timestamp: number): string => {
4
- const date = new Date(timestamp)
5
- return (
6
- date.toLocaleTimeString() +
7
- '.' +
8
- date.getMilliseconds().toString().padStart(3, '0')
9
- )
10
- }
11
-
12
1
  export const formatDuration = (ms?: number): string => {
13
2
  if (!ms) return '-'
14
3
  if (ms < 1000) return `${ms}ms`
15
4
  return `${(ms / 1000).toFixed(2)}s`
16
5
  }
17
-
18
- export const getChunkTypeColor = (type: Chunk['type']): string => {
19
- switch (type) {
20
- case 'content':
21
- return '#10b981' // green
22
- case 'tool_call':
23
- return '#8b5cf6' // purple
24
- case 'tool_result':
25
- return '#3b82f6' // blue
26
- case 'done':
27
- return '#6b7280' // gray
28
- case 'error':
29
- return '#ef4444' // red
30
- case 'approval':
31
- return '#f59e0b' // orange/amber
32
- case 'thinking':
33
- return '#a855f7' // violet
34
- default:
35
- return '#6b7280' // gray
36
- }
37
- }
38
-
39
- export const getStatusColor = (
40
- status: 'active' | 'completed' | 'error',
41
- ): string => {
42
- switch (status) {
43
- case 'active':
44
- return 'oklch(0.7 0.17 142)' // green
45
- case 'completed':
46
- return 'oklch(0.65 0.1 260)' // blue
47
- case 'error':
48
- return 'oklch(0.65 0.2 25)' // red
49
- default:
50
- return 'oklch(0.6 0.05 200)'
51
- }
52
- }
53
-
54
- export const getTypeColor = (type: 'client' | 'server'): string => {
55
- switch (type) {
56
- case 'client':
57
- return 'oklch(0.68 0.16 330)' // pink
58
- case 'server':
59
- return 'oklch(0.68 0.15 280)' // purple
60
- default:
61
- return 'oklch(0.6 0.05 200)'
62
- }
63
- }