@tanstack/ai-devtools-core 0.5.17 → 0.5.20
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/{production/Shell/EBEFU2GI.js → Shell/7YKZZJIO.js} +623 -173
- package/dist/Shell/{Y4V4YNYM.js → LR2PUWRS.js} +623 -173
- package/dist/Shell/{3BTXBRTQ.js → TTHBDBPP.js} +530 -141
- package/dist/dev.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{Shell/EBEFU2GI.js → production/Shell/7YKZZJIO.js} +623 -173
- package/dist/production/Shell/{Y4V4YNYM.js → LR2PUWRS.js} +623 -173
- package/dist/production/Shell/{3BTXBRTQ.js → TTHBDBPP.js} +530 -141
- package/dist/production/dev.js +1 -1
- package/dist/production/index.js +1 -1
- package/dist/production/server.js +1 -1
- package/dist/server.js +1 -1
- package/package.json +3 -3
- package/src/components/conversation/IterationTimeline.tsx +137 -45
- package/src/components/hooks/HookDetails.tsx +248 -86
- package/src/store/ai-context.tsx +3 -0
- package/src/store/subagent-steps.ts +387 -0
package/dist/production/dev.js
CHANGED
|
@@ -2,7 +2,7 @@ import { constructCoreClass } from '@tanstack/devtools-utils/solid/class';
|
|
|
2
2
|
|
|
3
3
|
// src/core.ts
|
|
4
4
|
var [AiDevtoolsCore, AiDevtoolsCoreNoOp] = constructCoreClass(
|
|
5
|
-
() => import('./Shell/
|
|
5
|
+
() => import('./Shell/7YKZZJIO.js')
|
|
6
6
|
);
|
|
7
7
|
|
|
8
8
|
export { AiDevtoolsCore };
|
package/dist/production/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { constructCoreClass } from '@tanstack/devtools-utils/solid/class';
|
|
|
2
2
|
|
|
3
3
|
// src/core.ts
|
|
4
4
|
var [AiDevtoolsCore, AiDevtoolsCoreNoOp] = constructCoreClass(
|
|
5
|
-
() => import('./Shell/
|
|
5
|
+
() => import('./Shell/LR2PUWRS.js')
|
|
6
6
|
);
|
|
7
7
|
|
|
8
8
|
export { AiDevtoolsCore };
|
|
@@ -2,7 +2,7 @@ import { constructCoreClass } from '@tanstack/devtools-utils/solid/class';
|
|
|
2
2
|
|
|
3
3
|
// src/core.ts
|
|
4
4
|
var [AiDevtoolsCore, AiDevtoolsCoreNoOp] = constructCoreClass(
|
|
5
|
-
() => import('./Shell/
|
|
5
|
+
() => import('./Shell/TTHBDBPP.js')
|
|
6
6
|
);
|
|
7
7
|
|
|
8
8
|
export { AiDevtoolsCore };
|
package/dist/server.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ai-devtools-core",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.20",
|
|
4
4
|
"description": "Core TanStack AI Devtools plugin for inspecting chat messages, tool calls, streams, and errors.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -84,8 +84,8 @@
|
|
|
84
84
|
"@tanstack/devtools-utils": "^0.7.0",
|
|
85
85
|
"goober": "^2.1.18",
|
|
86
86
|
"solid-js": "^1.9.10",
|
|
87
|
-
"@tanstack/ai": "^0.
|
|
88
|
-
"@tanstack/ai-event-client": "^0.
|
|
87
|
+
"@tanstack/ai": "^0.61.0",
|
|
88
|
+
"@tanstack/ai-event-client": "^0.13.0"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"@vitest/coverage-v8": "4.1.10",
|
|
@@ -7,20 +7,27 @@ import {
|
|
|
7
7
|
isMessageHighlighted,
|
|
8
8
|
} from '../hooks/preview-model'
|
|
9
9
|
import { formatDuration } from '../utils'
|
|
10
|
+
import { buildSubagentSteps, groupTimeline } from '../../store/subagent-steps'
|
|
10
11
|
import { IterationCard } from './IterationCard'
|
|
11
12
|
import type { HoverTarget } from '../hooks/preview-model'
|
|
12
13
|
import type { Iteration, Message } from '../../store/ai-store'
|
|
14
|
+
import type {
|
|
15
|
+
AgentStepGroup,
|
|
16
|
+
SubagentInfo,
|
|
17
|
+
TimelineGroup,
|
|
18
|
+
} from '../../store/subagent-steps'
|
|
13
19
|
import type { Component } from 'solid-js'
|
|
14
20
|
|
|
15
21
|
/** A group of iterations triggered by a single user message */
|
|
16
|
-
|
|
17
|
-
userMessage: Message | null
|
|
18
|
-
iterations: Array<Iteration>
|
|
19
|
-
}
|
|
22
|
+
type UserMessageGroup = TimelineGroup
|
|
20
23
|
|
|
21
24
|
interface IterationTimelineProps {
|
|
22
25
|
iterations: Array<Iteration>
|
|
23
26
|
messages: Array<Message>
|
|
27
|
+
/** Child agents from the hook snapshot. Their steps get their own cards. */
|
|
28
|
+
subagents?: Array<SubagentInfo>
|
|
29
|
+
/** The chat's user messages, from the snapshot. They mark the turns. */
|
|
30
|
+
turns?: Array<Message>
|
|
24
31
|
hoverTarget?: HoverTarget | null
|
|
25
32
|
onHoverTarget?: (target: HoverTarget | null) => void
|
|
26
33
|
}
|
|
@@ -33,47 +40,15 @@ export const IterationTimeline: Component<IterationTimelineProps> = (props) => {
|
|
|
33
40
|
* Group iterations by user messages.
|
|
34
41
|
* Memoized to avoid recomputing on unrelated store changes.
|
|
35
42
|
*/
|
|
36
|
-
const groups = createMemo(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const sortedUsers = [...userMessages].sort(
|
|
47
|
-
(a, b) => a.timestamp - b.timestamp,
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
for (const [u, currentUser] of sortedUsers.entries()) {
|
|
51
|
-
const nextUser = sortedUsers[u + 1]
|
|
52
|
-
|
|
53
|
-
const groupIters = iters.filter((it) => {
|
|
54
|
-
if (it.startedAt < currentUser.timestamp) return false
|
|
55
|
-
if (nextUser && it.startedAt >= nextUser.timestamp) return false
|
|
56
|
-
return true
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
if (groupIters.length > 0) {
|
|
60
|
-
result.push({ userMessage: currentUser, iterations: groupIters })
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Catch any iterations before the first user message
|
|
65
|
-
const firstUser = sortedUsers[0]
|
|
66
|
-
if (firstUser) {
|
|
67
|
-
const earlyIters = iters.filter(
|
|
68
|
-
(it) => it.startedAt < firstUser.timestamp,
|
|
69
|
-
)
|
|
70
|
-
if (earlyIters.length > 0) {
|
|
71
|
-
result.unshift({ userMessage: null, iterations: earlyIters })
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return result
|
|
76
|
-
})
|
|
43
|
+
const groups = createMemo(
|
|
44
|
+
(): Array<UserMessageGroup> =>
|
|
45
|
+
groupTimeline(
|
|
46
|
+
props.iterations,
|
|
47
|
+
props.messages,
|
|
48
|
+
props.subagents ?? [],
|
|
49
|
+
props.turns ?? [],
|
|
50
|
+
),
|
|
51
|
+
)
|
|
77
52
|
|
|
78
53
|
return (
|
|
79
54
|
<div class={s().container}>
|
|
@@ -468,9 +443,126 @@ const UserMessageGroupCard: Component<{
|
|
|
468
443
|
/>
|
|
469
444
|
)}
|
|
470
445
|
</For>
|
|
446
|
+
<For each={group().agents}>
|
|
447
|
+
{(agentGroup) => (
|
|
448
|
+
<SubagentStepsCard
|
|
449
|
+
group={agentGroup}
|
|
450
|
+
hoverTarget={props.hoverTarget}
|
|
451
|
+
onHoverTarget={props.onHoverTarget}
|
|
452
|
+
/>
|
|
453
|
+
)}
|
|
454
|
+
</For>
|
|
471
455
|
</div>
|
|
472
456
|
</div>
|
|
473
457
|
</div>
|
|
474
458
|
</div>
|
|
475
459
|
)
|
|
476
460
|
}
|
|
461
|
+
|
|
462
|
+
/** The steps of one child agent, drawn with the same cards as the root. */
|
|
463
|
+
export const SubagentStepsCard: Component<{
|
|
464
|
+
group?: AgentStepGroup
|
|
465
|
+
/** Build the steps from the snapshot when no group is given. */
|
|
466
|
+
agent?: SubagentInfo
|
|
467
|
+
hoverTarget: HoverTarget | null
|
|
468
|
+
onHoverTarget?: (target: HoverTarget | null) => void
|
|
469
|
+
}> = (props) => {
|
|
470
|
+
const styles = useStyles()
|
|
471
|
+
const s = () => styles().iterationTimeline
|
|
472
|
+
const [isOpen, setIsOpen] = createSignal(true)
|
|
473
|
+
|
|
474
|
+
const group = createMemo((): AgentStepGroup | undefined => {
|
|
475
|
+
if (props.group) return props.group
|
|
476
|
+
if (!props.agent) return undefined
|
|
477
|
+
return {
|
|
478
|
+
agent: props.agent,
|
|
479
|
+
...buildSubagentSteps(props.agent),
|
|
480
|
+
source: 'snapshot',
|
|
481
|
+
}
|
|
482
|
+
})
|
|
483
|
+
const agent = () => group()?.agent
|
|
484
|
+
const iterations = () => group()?.iterations ?? []
|
|
485
|
+
|
|
486
|
+
const accentClass = () => {
|
|
487
|
+
const status = agent()?.status
|
|
488
|
+
if (status === 'running') return s().cardActive
|
|
489
|
+
if (status === 'error') return s().cardError
|
|
490
|
+
if (status === 'finished') return s().cardCompleted
|
|
491
|
+
return ''
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
return (
|
|
495
|
+
<Show when={agent()}>
|
|
496
|
+
{(current) => (
|
|
497
|
+
<div
|
|
498
|
+
class={`${s().card} ${accentClass()}`}
|
|
499
|
+
style={{ 'margin-top': '8px' }}
|
|
500
|
+
data-testid="ai-devtools-subagent-steps"
|
|
501
|
+
data-agent={current().path}
|
|
502
|
+
data-source={group()?.source}
|
|
503
|
+
>
|
|
504
|
+
<div
|
|
505
|
+
class={s().cardHeader}
|
|
506
|
+
role="button"
|
|
507
|
+
tabIndex={0}
|
|
508
|
+
aria-expanded={isOpen()}
|
|
509
|
+
onClick={() => setIsOpen(!isOpen())}
|
|
510
|
+
onKeyDown={(event) => {
|
|
511
|
+
if (event.key !== 'Enter' && event.key !== ' ') return
|
|
512
|
+
event.preventDefault()
|
|
513
|
+
setIsOpen(!isOpen())
|
|
514
|
+
}}
|
|
515
|
+
>
|
|
516
|
+
<div class={s().userBubble}>
|
|
517
|
+
{current().name.charAt(0).toUpperCase()}
|
|
518
|
+
</div>
|
|
519
|
+
<div class={s().cardHeaderContent}>
|
|
520
|
+
<span class={s().cardHeaderLabel}>{current().path}</span>
|
|
521
|
+
<div class={s().cardSubtitle}>
|
|
522
|
+
<span class={s().subtitleText}>subagent</span>
|
|
523
|
+
<Show when={current().status}>
|
|
524
|
+
<span class={s().subtitleBadge}>{current().status}</span>
|
|
525
|
+
</Show>
|
|
526
|
+
<Show when={current().error}>
|
|
527
|
+
<span class={s().subtitleBadgeWarn}>{current().error}</span>
|
|
528
|
+
</Show>
|
|
529
|
+
</div>
|
|
530
|
+
</div>
|
|
531
|
+
<div class={s().cardHeaderBadges}>
|
|
532
|
+
<span
|
|
533
|
+
class={`${s().badge} ${s().badgeDuration}`}
|
|
534
|
+
title={`${iterations().length} ${iterations().length === 1 ? 'iteration' : 'iterations'}`}
|
|
535
|
+
>
|
|
536
|
+
🔄 {iterations().length}
|
|
537
|
+
</span>
|
|
538
|
+
</div>
|
|
539
|
+
<span class={`${s().chevron} ${isOpen() ? s().chevronOpen : ''}`}>
|
|
540
|
+
{'▶'}
|
|
541
|
+
</span>
|
|
542
|
+
</div>
|
|
543
|
+
<div class={`${s().cardBody} ${isOpen() ? s().cardBodyOpen : ''}`}>
|
|
544
|
+
<div class={s().cardBodyInner}>
|
|
545
|
+
<div class={s().iterList}>
|
|
546
|
+
<For each={iterations()}>
|
|
547
|
+
{(iteration, index) => (
|
|
548
|
+
<IterationCard
|
|
549
|
+
iteration={iteration}
|
|
550
|
+
previousIteration={
|
|
551
|
+
index() > 0 ? iterations()[index() - 1] : undefined
|
|
552
|
+
}
|
|
553
|
+
messages={group()?.messages ?? []}
|
|
554
|
+
index={index()}
|
|
555
|
+
isLast={index() === iterations().length - 1}
|
|
556
|
+
hoverTarget={props.hoverTarget}
|
|
557
|
+
onHoverTarget={props.onHoverTarget}
|
|
558
|
+
/>
|
|
559
|
+
)}
|
|
560
|
+
</For>
|
|
561
|
+
</div>
|
|
562
|
+
</div>
|
|
563
|
+
</div>
|
|
564
|
+
</div>
|
|
565
|
+
)}
|
|
566
|
+
</Show>
|
|
567
|
+
)
|
|
568
|
+
}
|