@townco/ui 0.1.68 → 0.1.69
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/core/hooks/use-chat-messages.d.ts +6 -1
- package/dist/core/hooks/use-chat-session.d.ts +1 -1
- package/dist/core/hooks/use-tool-calls.d.ts +6 -1
- package/dist/core/schemas/chat.d.ts +10 -0
- package/dist/core/schemas/tool-call.d.ts +5 -0
- package/dist/core/schemas/tool-call.js +8 -0
- package/dist/core/utils/tool-call-state.d.ts +30 -0
- package/dist/core/utils/tool-call-state.js +73 -0
- package/dist/core/utils/tool-summary.d.ts +13 -0
- package/dist/core/utils/tool-summary.js +172 -0
- package/dist/core/utils/tool-verbiage.d.ts +28 -0
- package/dist/core/utils/tool-verbiage.js +185 -0
- package/dist/gui/components/AppSidebar.d.ts +22 -0
- package/dist/gui/components/AppSidebar.js +22 -0
- package/dist/gui/components/Button.d.ts +1 -1
- package/dist/gui/components/ChatLayout.d.ts +5 -0
- package/dist/gui/components/ChatLayout.js +239 -132
- package/dist/gui/components/ChatView.js +42 -118
- package/dist/gui/components/MessageContent.js +151 -39
- package/dist/gui/components/SessionHistory.d.ts +10 -0
- package/dist/gui/components/SessionHistory.js +101 -0
- package/dist/gui/components/SessionHistoryItem.d.ts +11 -0
- package/dist/gui/components/SessionHistoryItem.js +24 -0
- package/dist/gui/components/Sheet.d.ts +25 -0
- package/dist/gui/components/Sheet.js +36 -0
- package/dist/gui/components/Sidebar.d.ts +65 -0
- package/dist/gui/components/Sidebar.js +231 -0
- package/dist/gui/components/SidebarToggle.d.ts +3 -0
- package/dist/gui/components/SidebarToggle.js +9 -0
- package/dist/gui/components/ToolCallList.js +3 -3
- package/dist/gui/components/ToolOperation.d.ts +11 -0
- package/dist/gui/components/ToolOperation.js +289 -0
- package/dist/gui/components/WorkProgress.d.ts +20 -0
- package/dist/gui/components/WorkProgress.js +79 -0
- package/dist/gui/components/index.d.ts +8 -1
- package/dist/gui/components/index.js +9 -1
- package/dist/gui/hooks/index.d.ts +1 -0
- package/dist/gui/hooks/index.js +1 -0
- package/dist/gui/hooks/use-mobile.d.ts +1 -0
- package/dist/gui/hooks/use-mobile.js +15 -0
- package/dist/gui/index.d.ts +1 -0
- package/dist/gui/index.js +2 -0
- package/dist/gui/lib/motion.d.ts +55 -0
- package/dist/gui/lib/motion.js +217 -0
- package/dist/sdk/schemas/session.d.ts +11 -6
- package/dist/sdk/transports/types.d.ts +5 -0
- package/package.json +8 -7
- package/src/styles/global.css +128 -1
- package/dist/gui/components/InvokingGroup.d.ts +0 -9
- package/dist/gui/components/InvokingGroup.js +0 -16
- package/dist/gui/components/SubagentStream.d.ts +0 -23
- package/dist/gui/components/SubagentStream.js +0 -98
- package/dist/gui/components/ToolCall.d.ts +0 -8
- package/dist/gui/components/ToolCall.js +0 -234
- package/dist/gui/components/ToolCallGroup.d.ts +0 -8
- package/dist/gui/components/ToolCallGroup.js +0 -29
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Motion utilities and reusable animation variants for the UI package
|
|
3
|
+
* Provides consistent animation behavior across components
|
|
4
|
+
*/
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// Standard Durations
|
|
7
|
+
// ============================================================================
|
|
8
|
+
export const motionDuration = {
|
|
9
|
+
fast: 0.15,
|
|
10
|
+
normal: 0.25,
|
|
11
|
+
slow: 0.4,
|
|
12
|
+
};
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Standard Easings
|
|
15
|
+
// ============================================================================
|
|
16
|
+
export const motionEasing = {
|
|
17
|
+
// Smooth, natural easing
|
|
18
|
+
smooth: [0.25, 0.1, 0.25, 1],
|
|
19
|
+
// Bouncy, playful easing
|
|
20
|
+
bounce: [0.68, -0.55, 0.265, 1.55],
|
|
21
|
+
// Sharp, snappy easing
|
|
22
|
+
sharp: [0.4, 0, 0.2, 1],
|
|
23
|
+
// Gentle, subtle easing
|
|
24
|
+
gentle: [0.25, 0.46, 0.45, 0.94],
|
|
25
|
+
};
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Fade Variants
|
|
28
|
+
// ============================================================================
|
|
29
|
+
export const fadeInVariants = {
|
|
30
|
+
hidden: {
|
|
31
|
+
opacity: 0,
|
|
32
|
+
},
|
|
33
|
+
visible: {
|
|
34
|
+
opacity: 1,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
export const fadeInUpVariants = {
|
|
38
|
+
hidden: {
|
|
39
|
+
opacity: 0,
|
|
40
|
+
y: 8,
|
|
41
|
+
},
|
|
42
|
+
visible: {
|
|
43
|
+
opacity: 1,
|
|
44
|
+
y: 0,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// Expand/Collapse Variants
|
|
49
|
+
// ============================================================================
|
|
50
|
+
export const expandCollapseVariants = {
|
|
51
|
+
collapsed: {
|
|
52
|
+
height: 0,
|
|
53
|
+
opacity: 0,
|
|
54
|
+
overflow: "hidden",
|
|
55
|
+
},
|
|
56
|
+
expanded: {
|
|
57
|
+
height: "auto",
|
|
58
|
+
opacity: 1,
|
|
59
|
+
overflow: "visible",
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
export const slideDownVariants = {
|
|
63
|
+
hidden: {
|
|
64
|
+
opacity: 0,
|
|
65
|
+
height: 0,
|
|
66
|
+
y: -4,
|
|
67
|
+
},
|
|
68
|
+
visible: {
|
|
69
|
+
opacity: 1,
|
|
70
|
+
height: "auto",
|
|
71
|
+
y: 0,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
// ============================================================================
|
|
75
|
+
// Shimmer Effect
|
|
76
|
+
// ============================================================================
|
|
77
|
+
export const shimmerTransition = {
|
|
78
|
+
duration: 2,
|
|
79
|
+
ease: "linear",
|
|
80
|
+
repeat: Infinity,
|
|
81
|
+
repeatType: "loop",
|
|
82
|
+
};
|
|
83
|
+
// For shimmer, we'll use a background gradient that shifts
|
|
84
|
+
export const shimmerVariants = {
|
|
85
|
+
idle: {
|
|
86
|
+
backgroundPosition: "200% 0",
|
|
87
|
+
},
|
|
88
|
+
active: {
|
|
89
|
+
backgroundPosition: "-200% 0",
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// Scale Variants
|
|
94
|
+
// ============================================================================
|
|
95
|
+
export const scaleInVariants = {
|
|
96
|
+
hidden: {
|
|
97
|
+
scale: 0.95,
|
|
98
|
+
opacity: 0,
|
|
99
|
+
},
|
|
100
|
+
visible: {
|
|
101
|
+
scale: 1,
|
|
102
|
+
opacity: 1,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
export const pulseVariants = {
|
|
106
|
+
idle: {
|
|
107
|
+
scale: 1,
|
|
108
|
+
},
|
|
109
|
+
pulse: {
|
|
110
|
+
scale: [1, 1.05, 1],
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
// ============================================================================
|
|
114
|
+
// Rotation Variants
|
|
115
|
+
// ============================================================================
|
|
116
|
+
export const rotateVariants = {
|
|
117
|
+
collapsed: {
|
|
118
|
+
rotate: 0,
|
|
119
|
+
},
|
|
120
|
+
expanded: {
|
|
121
|
+
rotate: 180,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
// ============================================================================
|
|
125
|
+
// Standard Transitions
|
|
126
|
+
// ============================================================================
|
|
127
|
+
export const standardTransition = {
|
|
128
|
+
duration: motionDuration.normal,
|
|
129
|
+
ease: motionEasing.smooth,
|
|
130
|
+
};
|
|
131
|
+
export const fastTransition = {
|
|
132
|
+
duration: motionDuration.fast,
|
|
133
|
+
ease: motionEasing.sharp,
|
|
134
|
+
};
|
|
135
|
+
export const slowTransition = {
|
|
136
|
+
duration: motionDuration.slow,
|
|
137
|
+
ease: motionEasing.gentle,
|
|
138
|
+
};
|
|
139
|
+
export const springTransition = {
|
|
140
|
+
type: "spring",
|
|
141
|
+
stiffness: 300,
|
|
142
|
+
damping: 30,
|
|
143
|
+
};
|
|
144
|
+
export const gentleSpringTransition = {
|
|
145
|
+
type: "spring",
|
|
146
|
+
stiffness: 200,
|
|
147
|
+
damping: 25,
|
|
148
|
+
};
|
|
149
|
+
// ============================================================================
|
|
150
|
+
// Layout Transition (for shared layout animations)
|
|
151
|
+
// ============================================================================
|
|
152
|
+
export const layoutTransition = {
|
|
153
|
+
layout: {
|
|
154
|
+
duration: motionDuration.normal,
|
|
155
|
+
ease: motionEasing.smooth,
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
// ============================================================================
|
|
159
|
+
// Stagger Configurations
|
|
160
|
+
// ============================================================================
|
|
161
|
+
export const staggerChildren = {
|
|
162
|
+
visible: {
|
|
163
|
+
transition: {
|
|
164
|
+
staggerChildren: 0.05,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
export const staggerChildrenFast = {
|
|
169
|
+
visible: {
|
|
170
|
+
transition: {
|
|
171
|
+
staggerChildren: 0.03,
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
// ============================================================================
|
|
176
|
+
// Slide Variants (for panels and drawers)
|
|
177
|
+
// ============================================================================
|
|
178
|
+
export const slideInFromRightVariants = {
|
|
179
|
+
hidden: {
|
|
180
|
+
x: "100%",
|
|
181
|
+
opacity: 0,
|
|
182
|
+
},
|
|
183
|
+
visible: {
|
|
184
|
+
x: 0,
|
|
185
|
+
opacity: 1,
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
export const slideOutToRightVariants = {
|
|
189
|
+
visible: {
|
|
190
|
+
x: 0,
|
|
191
|
+
opacity: 1,
|
|
192
|
+
},
|
|
193
|
+
hidden: {
|
|
194
|
+
x: "100%",
|
|
195
|
+
opacity: 0,
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
// ============================================================================
|
|
199
|
+
// Helper Functions
|
|
200
|
+
// ============================================================================
|
|
201
|
+
/**
|
|
202
|
+
* Get transition with reduced motion consideration
|
|
203
|
+
*/
|
|
204
|
+
export function getTransition(shouldReduceMotion, transition = standardTransition) {
|
|
205
|
+
if (shouldReduceMotion) {
|
|
206
|
+
return {
|
|
207
|
+
duration: 0.01,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return transition;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Get duration with reduced motion consideration
|
|
214
|
+
*/
|
|
215
|
+
export function getDuration(shouldReduceMotion, duration = motionDuration.normal) {
|
|
216
|
+
return shouldReduceMotion ? 0.01 : duration;
|
|
217
|
+
}
|
|
@@ -4,10 +4,10 @@ import { z } from "zod";
|
|
|
4
4
|
*/
|
|
5
5
|
export declare const SessionStatus: z.ZodEnum<{
|
|
6
6
|
error: "error";
|
|
7
|
+
active: "active";
|
|
7
8
|
idle: "idle";
|
|
8
9
|
connecting: "connecting";
|
|
9
10
|
connected: "connected";
|
|
10
|
-
active: "active";
|
|
11
11
|
streaming: "streaming";
|
|
12
12
|
disconnected: "disconnected";
|
|
13
13
|
}>;
|
|
@@ -41,10 +41,10 @@ export declare const Session: z.ZodObject<{
|
|
|
41
41
|
id: z.ZodString;
|
|
42
42
|
status: z.ZodEnum<{
|
|
43
43
|
error: "error";
|
|
44
|
+
active: "active";
|
|
44
45
|
idle: "idle";
|
|
45
46
|
connecting: "connecting";
|
|
46
47
|
connected: "connected";
|
|
47
|
-
active: "active";
|
|
48
48
|
streaming: "streaming";
|
|
49
49
|
disconnected: "disconnected";
|
|
50
50
|
}>;
|
|
@@ -117,10 +117,10 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
117
117
|
sessionId: z.ZodString;
|
|
118
118
|
status: z.ZodOptional<z.ZodEnum<{
|
|
119
119
|
error: "error";
|
|
120
|
+
active: "active";
|
|
120
121
|
idle: "idle";
|
|
121
122
|
connecting: "connecting";
|
|
122
123
|
connected: "connected";
|
|
123
|
-
active: "active";
|
|
124
124
|
streaming: "streaming";
|
|
125
125
|
disconnected: "disconnected";
|
|
126
126
|
}>>;
|
|
@@ -178,6 +178,11 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
178
178
|
title: z.ZodString;
|
|
179
179
|
prettyName: z.ZodOptional<z.ZodString>;
|
|
180
180
|
icon: z.ZodOptional<z.ZodString>;
|
|
181
|
+
verbiage: z.ZodOptional<z.ZodObject<{
|
|
182
|
+
active: z.ZodString;
|
|
183
|
+
past: z.ZodString;
|
|
184
|
+
paramKey: z.ZodOptional<z.ZodString>;
|
|
185
|
+
}, z.core.$strip>>;
|
|
181
186
|
subline: z.ZodOptional<z.ZodString>;
|
|
182
187
|
kind: z.ZodEnum<{
|
|
183
188
|
read: "read";
|
|
@@ -349,10 +354,10 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
349
354
|
sessionId: z.ZodString;
|
|
350
355
|
status: z.ZodOptional<z.ZodEnum<{
|
|
351
356
|
error: "error";
|
|
357
|
+
active: "active";
|
|
352
358
|
idle: "idle";
|
|
353
359
|
connecting: "connecting";
|
|
354
360
|
connected: "connected";
|
|
355
|
-
active: "active";
|
|
356
361
|
streaming: "streaming";
|
|
357
362
|
disconnected: "disconnected";
|
|
358
363
|
}>>;
|
|
@@ -556,10 +561,10 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
556
561
|
sessionId: z.ZodString;
|
|
557
562
|
status: z.ZodOptional<z.ZodEnum<{
|
|
558
563
|
error: "error";
|
|
564
|
+
active: "active";
|
|
559
565
|
idle: "idle";
|
|
560
566
|
connecting: "connecting";
|
|
561
567
|
connected: "connected";
|
|
562
|
-
active: "active";
|
|
563
568
|
streaming: "streaming";
|
|
564
569
|
disconnected: "disconnected";
|
|
565
570
|
}>>;
|
|
@@ -621,10 +626,10 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
621
626
|
sessionId: z.ZodString;
|
|
622
627
|
status: z.ZodOptional<z.ZodEnum<{
|
|
623
628
|
error: "error";
|
|
629
|
+
active: "active";
|
|
624
630
|
idle: "idle";
|
|
625
631
|
connecting: "connecting";
|
|
626
632
|
connected: "connected";
|
|
627
|
-
active: "active";
|
|
628
633
|
streaming: "streaming";
|
|
629
634
|
disconnected: "disconnected";
|
|
630
635
|
}>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@townco/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.69",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -49,11 +49,12 @@
|
|
|
49
49
|
"@radix-ui/react-slot": "^1.2.4",
|
|
50
50
|
"@radix-ui/react-tabs": "^1.1.13",
|
|
51
51
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
52
|
-
"@townco/core": "0.0.
|
|
52
|
+
"@townco/core": "0.0.47",
|
|
53
53
|
"@uiw/react-json-view": "^2.0.0-alpha.39",
|
|
54
54
|
"bun": "^1.3.1",
|
|
55
55
|
"class-variance-authority": "^0.7.1",
|
|
56
56
|
"clsx": "^2.1.1",
|
|
57
|
+
"framer-motion": "^12.23.25",
|
|
57
58
|
"lucide-react": "^0.552.0",
|
|
58
59
|
"react-markdown": "^10.1.0",
|
|
59
60
|
"react-resizable-panels": "^3.0.6",
|
|
@@ -66,18 +67,18 @@
|
|
|
66
67
|
},
|
|
67
68
|
"devDependencies": {
|
|
68
69
|
"@tailwindcss/postcss": "^4.1.17",
|
|
69
|
-
"@townco/tsconfig": "0.1.
|
|
70
|
+
"@townco/tsconfig": "0.1.66",
|
|
70
71
|
"@types/node": "^24.10.0",
|
|
71
72
|
"@types/react": "^19.2.2",
|
|
72
73
|
"ink": "^6.4.0",
|
|
73
|
-
"react": "
|
|
74
|
+
"react": "19.2.1",
|
|
74
75
|
"tailwindcss": "^4.1.17",
|
|
75
76
|
"typescript": "^5.9.3"
|
|
76
77
|
},
|
|
77
78
|
"peerDependencies": {
|
|
78
|
-
"ink": "^
|
|
79
|
-
"react": "^19.2.
|
|
80
|
-
"react-dom": "^19.2.
|
|
79
|
+
"ink": "^6.4.0",
|
|
80
|
+
"react": "^19.2.1",
|
|
81
|
+
"react-dom": "^19.2.1"
|
|
81
82
|
},
|
|
82
83
|
"peerDependenciesMeta": {
|
|
83
84
|
"react": {
|
package/src/styles/global.css
CHANGED
|
@@ -47,6 +47,14 @@
|
|
|
47
47
|
--color-text-primary: var(--text-primary);
|
|
48
48
|
--color-text-secondary: var(--text-secondary);
|
|
49
49
|
--color-text-tertiary: var(--text-tertiary);
|
|
50
|
+
|
|
51
|
+
/* Sidebar colors */
|
|
52
|
+
--color-sidebar: var(--sidebar);
|
|
53
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
54
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
55
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
56
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
57
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
50
58
|
|
|
51
59
|
/* Layout widths - max-width utilities */
|
|
52
60
|
--max-width-chat: 720px;
|
|
@@ -149,8 +157,16 @@
|
|
|
149
157
|
|
|
150
158
|
/* Text colors from design system */
|
|
151
159
|
--text-primary: var(--color-neutral-900);
|
|
152
|
-
--text-secondary: var(--color-neutral-
|
|
160
|
+
--text-secondary: var(--color-neutral-700);
|
|
153
161
|
--text-tertiary: var(--color-neutral-500);
|
|
162
|
+
|
|
163
|
+
/* Sidebar colors */
|
|
164
|
+
--sidebar: var(--color-neutral-50);
|
|
165
|
+
--sidebar-foreground: var(--color-neutral-950);
|
|
166
|
+
--sidebar-accent: var(--color-neutral-100);
|
|
167
|
+
--sidebar-accent-foreground: var(--color-neutral-900);
|
|
168
|
+
--sidebar-border: var(--color-neutral-200);
|
|
169
|
+
--sidebar-ring: var(--color-neutral-900);
|
|
154
170
|
}
|
|
155
171
|
|
|
156
172
|
.dark {
|
|
@@ -194,6 +210,14 @@
|
|
|
194
210
|
--text-primary: var(--color-neutral-50);
|
|
195
211
|
--text-secondary: var(--color-neutral-400);
|
|
196
212
|
--text-tertiary: var(--color-neutral-500);
|
|
213
|
+
|
|
214
|
+
/* Sidebar colors (dark mode) */
|
|
215
|
+
--sidebar: var(--color-neutral-900);
|
|
216
|
+
--sidebar-foreground: var(--color-neutral-50);
|
|
217
|
+
--sidebar-accent: var(--color-neutral-800);
|
|
218
|
+
--sidebar-accent-foreground: var(--color-neutral-50);
|
|
219
|
+
--sidebar-border: var(--color-neutral-800);
|
|
220
|
+
--sidebar-ring: var(--color-neutral-300);
|
|
197
221
|
}
|
|
198
222
|
|
|
199
223
|
@layer base {
|
|
@@ -417,3 +441,106 @@
|
|
|
417
441
|
.animate-pulse-scale {
|
|
418
442
|
animation: pulse-scale 1s ease-in-out infinite;
|
|
419
443
|
}
|
|
444
|
+
|
|
445
|
+
@keyframes fadeIn {
|
|
446
|
+
from {
|
|
447
|
+
opacity: 0;
|
|
448
|
+
}
|
|
449
|
+
to {
|
|
450
|
+
opacity: 1;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.animate-fadeIn {
|
|
455
|
+
animation: fadeIn 200ms ease-out;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
@keyframes slideDown {
|
|
459
|
+
from {
|
|
460
|
+
opacity: 0;
|
|
461
|
+
max-height: 0;
|
|
462
|
+
transform: translateY(-4px);
|
|
463
|
+
}
|
|
464
|
+
to {
|
|
465
|
+
opacity: 1;
|
|
466
|
+
max-height: 500px;
|
|
467
|
+
transform: translateY(0);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.animate-slideDown {
|
|
472
|
+
animation: slideDown 250ms ease-out;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
@keyframes collapseUp {
|
|
476
|
+
from {
|
|
477
|
+
opacity: 1;
|
|
478
|
+
max-height: 500px;
|
|
479
|
+
transform: translateY(0);
|
|
480
|
+
}
|
|
481
|
+
to {
|
|
482
|
+
opacity: 0;
|
|
483
|
+
max-height: 0;
|
|
484
|
+
transform: translateY(-4px);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.animate-collapseUp {
|
|
489
|
+
animation: collapseUp 200ms ease-in;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
@keyframes pulse-subtle {
|
|
493
|
+
0%, 100% {
|
|
494
|
+
opacity: 1;
|
|
495
|
+
}
|
|
496
|
+
50% {
|
|
497
|
+
opacity: 0.8;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
.animate-pulse-subtle {
|
|
502
|
+
animation: pulse-subtle 2s ease-in-out infinite;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
@keyframes typing {
|
|
506
|
+
0%, 100% {
|
|
507
|
+
opacity: 0;
|
|
508
|
+
}
|
|
509
|
+
50% {
|
|
510
|
+
opacity: 1;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.animate-typing {
|
|
515
|
+
animation: typing 1.4s ease-in-out infinite;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
@keyframes shimmer {
|
|
519
|
+
0% {
|
|
520
|
+
background-position: -200% 0;
|
|
521
|
+
}
|
|
522
|
+
100% {
|
|
523
|
+
background-position: 200% 0;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
.animate-shimmer {
|
|
528
|
+
background: linear-gradient(
|
|
529
|
+
90deg,
|
|
530
|
+
transparent 0%,
|
|
531
|
+
rgba(255, 255, 255, 0.5) 50%,
|
|
532
|
+
transparent 100%
|
|
533
|
+
);
|
|
534
|
+
background-size: 200% 100%;
|
|
535
|
+
animation: shimmer 2s ease-in-out infinite;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
.dark .animate-shimmer {
|
|
539
|
+
background: linear-gradient(
|
|
540
|
+
90deg,
|
|
541
|
+
transparent 0%,
|
|
542
|
+
rgba(255, 255, 255, 0.05) 50%,
|
|
543
|
+
transparent 100%
|
|
544
|
+
);
|
|
545
|
+
background-size: 200% 100%;
|
|
546
|
+
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { ToolCall as ToolCallType } from "../../core/schemas/tool-call.js";
|
|
2
|
-
export interface InvokingGroupProps {
|
|
3
|
-
toolCalls: ToolCallType[];
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* InvokingGroup component - displays a group of preliminary (invoking) tool calls
|
|
7
|
-
* Shows as "Invoking parallel operation (N)" with a summary of unique tool names
|
|
8
|
-
*/
|
|
9
|
-
export declare function InvokingGroup({ toolCalls }: InvokingGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { ListVideo } from "lucide-react";
|
|
3
|
-
import React from "react";
|
|
4
|
-
/**
|
|
5
|
-
* InvokingGroup component - displays a group of preliminary (invoking) tool calls
|
|
6
|
-
* Shows as "Invoking parallel operation (N)" with a summary of unique tool names
|
|
7
|
-
*/
|
|
8
|
-
export function InvokingGroup({ toolCalls }) {
|
|
9
|
-
// Get unique display names for the summary
|
|
10
|
-
const displayNames = toolCalls.map((tc) => tc.prettyName || tc.title);
|
|
11
|
-
const uniqueNames = [...new Set(displayNames)];
|
|
12
|
-
const summary = uniqueNames.length <= 2
|
|
13
|
-
? uniqueNames.join(", ")
|
|
14
|
-
: `${uniqueNames.slice(0, 2).join(", ")} +${uniqueNames.length - 2} more`;
|
|
15
|
-
return (_jsxs("div", { className: "flex flex-col my-4", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-paragraph-sm text-muted-foreground/50", children: [_jsx(ListVideo, { className: "h-3 w-3" }), _jsx("span", { children: "Invoking parallel operation" }), _jsx("span", { className: "text-[10px] bg-muted px-1.5 py-0.5 rounded text-muted-foreground/50", children: toolCalls.length })] }), _jsx("span", { className: "text-paragraph-sm text-muted-foreground/50 pl-4.5", children: summary })] }));
|
|
16
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export interface SubagentStreamProps {
|
|
2
|
-
/** Sub-agent HTTP port */
|
|
3
|
-
port: number;
|
|
4
|
-
/** Sub-agent session ID */
|
|
5
|
-
sessionId: string;
|
|
6
|
-
/** Optional host (defaults to localhost) */
|
|
7
|
-
host?: string;
|
|
8
|
-
/** Parent tool call status - use this to determine if sub-agent is running */
|
|
9
|
-
parentStatus?: "pending" | "in_progress" | "completed" | "failed";
|
|
10
|
-
/** Sub-agent name (for display) */
|
|
11
|
-
agentName?: string | undefined;
|
|
12
|
-
/** Query sent to the sub-agent */
|
|
13
|
-
query?: string | undefined;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* SubagentStream component - displays streaming content from a sub-agent.
|
|
17
|
-
*
|
|
18
|
-
* This component:
|
|
19
|
-
* - Connects directly to the sub-agent's SSE endpoint
|
|
20
|
-
* - Displays streaming text and tool calls
|
|
21
|
-
* - Renders in a collapsible section (collapsed by default)
|
|
22
|
-
*/
|
|
23
|
-
export declare function SubagentStream({ port, sessionId, host, parentStatus, agentName, query, }: SubagentStreamProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { ChevronDown, CircleDot, Loader2 } from "lucide-react";
|
|
3
|
-
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
-
import { useSubagentStream } from "../../core/hooks/use-subagent-stream.js";
|
|
5
|
-
const SCROLL_THRESHOLD = 50; // px from bottom to consider "at bottom"
|
|
6
|
-
/**
|
|
7
|
-
* SubagentStream component - displays streaming content from a sub-agent.
|
|
8
|
-
*
|
|
9
|
-
* This component:
|
|
10
|
-
* - Connects directly to the sub-agent's SSE endpoint
|
|
11
|
-
* - Displays streaming text and tool calls
|
|
12
|
-
* - Renders in a collapsible section (collapsed by default)
|
|
13
|
-
*/
|
|
14
|
-
export function SubagentStream({ port, sessionId, host, parentStatus, agentName, query, }) {
|
|
15
|
-
const [isExpanded, setIsExpanded] = useState(false); // Start collapsed for parallel ops
|
|
16
|
-
const [isThinkingExpanded, setIsThinkingExpanded] = useState(true);
|
|
17
|
-
const [isNearBottom, setIsNearBottom] = useState(true);
|
|
18
|
-
const thinkingContainerRef = useRef(null);
|
|
19
|
-
const { messages, isStreaming: hookIsStreaming, error } = useSubagentStream({
|
|
20
|
-
port,
|
|
21
|
-
sessionId,
|
|
22
|
-
...(host !== undefined ? { host } : {}),
|
|
23
|
-
});
|
|
24
|
-
// Use parent status as primary indicator, fall back to hook's streaming state
|
|
25
|
-
// Parent is "in_progress" means sub-agent is definitely still running
|
|
26
|
-
const isRunning = parentStatus === "in_progress" || parentStatus === "pending" || hookIsStreaming;
|
|
27
|
-
// Get the current/latest message
|
|
28
|
-
const currentMessage = messages[messages.length - 1];
|
|
29
|
-
const hasContent = currentMessage &&
|
|
30
|
-
(currentMessage.content ||
|
|
31
|
-
(currentMessage.toolCalls && currentMessage.toolCalls.length > 0));
|
|
32
|
-
// Auto-collapse Thinking when completed (so Output is the primary view)
|
|
33
|
-
const prevIsRunningRef = useRef(isRunning);
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
if (prevIsRunningRef.current && !isRunning) {
|
|
36
|
-
// Just completed - collapse thinking to show output
|
|
37
|
-
setIsThinkingExpanded(false);
|
|
38
|
-
}
|
|
39
|
-
prevIsRunningRef.current = isRunning;
|
|
40
|
-
}, [isRunning]);
|
|
41
|
-
// Check if user is near bottom of scroll area
|
|
42
|
-
const checkScrollPosition = useCallback(() => {
|
|
43
|
-
const container = thinkingContainerRef.current;
|
|
44
|
-
if (!container)
|
|
45
|
-
return;
|
|
46
|
-
const { scrollTop, scrollHeight, clientHeight } = container;
|
|
47
|
-
const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
|
|
48
|
-
setIsNearBottom(distanceFromBottom < SCROLL_THRESHOLD);
|
|
49
|
-
}, []);
|
|
50
|
-
// Scroll to bottom
|
|
51
|
-
const scrollToBottom = useCallback(() => {
|
|
52
|
-
const container = thinkingContainerRef.current;
|
|
53
|
-
if (!container)
|
|
54
|
-
return;
|
|
55
|
-
container.scrollTop = container.scrollHeight;
|
|
56
|
-
}, []);
|
|
57
|
-
// Auto-scroll when content changes and user is near bottom
|
|
58
|
-
useEffect(() => {
|
|
59
|
-
if (isNearBottom && (isRunning || hasContent)) {
|
|
60
|
-
scrollToBottom();
|
|
61
|
-
}
|
|
62
|
-
}, [currentMessage?.content, currentMessage?.toolCalls, isNearBottom, isRunning, hasContent, scrollToBottom]);
|
|
63
|
-
// Set up scroll listener
|
|
64
|
-
useEffect(() => {
|
|
65
|
-
const container = thinkingContainerRef.current;
|
|
66
|
-
if (!container)
|
|
67
|
-
return;
|
|
68
|
-
const handleScroll = () => checkScrollPosition();
|
|
69
|
-
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
70
|
-
checkScrollPosition(); // Check initial position
|
|
71
|
-
return () => container.removeEventListener("scroll", handleScroll);
|
|
72
|
-
}, [checkScrollPosition, isThinkingExpanded, isExpanded]);
|
|
73
|
-
// Get last line of streaming content for preview
|
|
74
|
-
const lastLine = currentMessage?.content
|
|
75
|
-
? currentMessage.content.split("\n").filter(Boolean).pop() || ""
|
|
76
|
-
: "";
|
|
77
|
-
const previewText = lastLine.length > 100 ? `${lastLine.slice(0, 100)}...` : lastLine;
|
|
78
|
-
return (_jsxs("div", { children: [!isExpanded && (_jsx("button", { type: "button", onClick: () => setIsExpanded(true), className: "w-full max-w-md text-left cursor-pointer bg-transparent border-none p-0", children: previewText ? (_jsx("p", { className: `text-paragraph-sm text-muted-foreground truncate ${isRunning ? "animate-pulse" : ""}`, children: previewText })) : isRunning ? (_jsx("p", { className: "text-paragraph-sm text-muted-foreground/50 italic animate-pulse", children: "Waiting for response..." })) : null })), isExpanded && (_jsxs("div", { className: "space-y-3", children: [(agentName || query) && (_jsxs("div", { children: [_jsx("div", { className: "text-[10px] font-bold text-muted-foreground uppercase tracking-wider mb-1.5 font-sans", children: "Input" }), _jsxs("div", { className: "text-[11px] font-mono space-y-1", children: [agentName && (_jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "agentName: " }), _jsx("span", { className: "text-foreground", children: agentName })] })), query && (_jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "query: " }), _jsx("span", { className: "text-foreground", children: query })] }))] })] })), _jsxs("div", { children: [_jsxs("button", { type: "button", onClick: () => setIsThinkingExpanded(!isThinkingExpanded), className: "flex items-center gap-2 cursor-pointer bg-transparent border-none p-0 text-left group", children: [_jsx("div", { className: "text-[10px] font-bold text-muted-foreground uppercase tracking-wider font-sans", children: "Thinking" }), _jsx(ChevronDown, { className: `h-3 w-3 text-muted-foreground/70 transition-transform duration-200 ${isThinkingExpanded ? "rotate-180" : ""}` })] }), isThinkingExpanded && (_jsxs("div", { ref: thinkingContainerRef, className: "mt-2 rounded-md overflow-hidden bg-muted/30 border border-border/50 max-h-[200px] overflow-y-auto", children: [error && (_jsxs("div", { className: "px-2 py-2 text-[11px] text-destructive", children: ["Error: ", error] })), !error && !hasContent && isRunning && (_jsx("div", { className: "px-2 py-2 text-[11px] text-muted-foreground", children: "Waiting for sub-agent response..." })), currentMessage && (_jsxs("div", { className: "px-2 py-2 space-y-2", children: [currentMessage.toolCalls &&
|
|
79
|
-
currentMessage.toolCalls.length > 0 && (_jsx("div", { className: "space-y-1", children: currentMessage.toolCalls.map((tc) => (_jsx(SubagentToolCallItem, { toolCall: tc }, tc.id))) })), currentMessage.content && (_jsxs("div", { className: "text-[11px] text-foreground whitespace-pre-wrap font-mono", children: [currentMessage.content, currentMessage.isStreaming && (_jsx("span", { className: "inline-block w-1.5 h-3 bg-primary/70 ml-0.5 animate-pulse" }))] }))] }))] }))] }), !isRunning && currentMessage?.content && (_jsxs("div", { children: [_jsx("div", { className: "text-[10px] font-bold text-muted-foreground uppercase tracking-wider mb-1.5 font-sans", children: "Output" }), _jsx("div", { className: "text-[11px] text-foreground whitespace-pre-wrap font-mono max-h-[200px] overflow-y-auto rounded-md bg-muted/30 border border-border/50 px-2 py-2", children: currentMessage.content })] }))] }))] }));
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Simple tool call display for sub-agent tool calls
|
|
83
|
-
*/
|
|
84
|
-
function SubagentToolCallItem({ toolCall }) {
|
|
85
|
-
const statusIcon = {
|
|
86
|
-
pending: "...",
|
|
87
|
-
in_progress: "",
|
|
88
|
-
completed: "",
|
|
89
|
-
failed: "",
|
|
90
|
-
}[toolCall.status];
|
|
91
|
-
const statusColor = {
|
|
92
|
-
pending: "text-muted-foreground",
|
|
93
|
-
in_progress: "text-blue-500",
|
|
94
|
-
completed: "text-green-500",
|
|
95
|
-
failed: "text-destructive",
|
|
96
|
-
}[toolCall.status];
|
|
97
|
-
return (_jsxs("div", { className: "flex items-center gap-2 text-[10px] text-muted-foreground", children: [_jsx("span", { className: statusColor, children: statusIcon }), _jsx("span", { className: "font-medium", children: toolCall.prettyName || toolCall.title }), toolCall.status === "in_progress" && (_jsx(Loader2, { className: "h-2.5 w-2.5 animate-spin" }))] }));
|
|
98
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ToolCall as ToolCallType } from "../../core/schemas/tool-call.js";
|
|
2
|
-
export interface ToolCallProps {
|
|
3
|
-
toolCall: ToolCallType;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* ToolCall component - displays a single tool call with collapsible details
|
|
7
|
-
*/
|
|
8
|
-
export declare function ToolCall({ toolCall }: ToolCallProps): import("react/jsx-runtime").JSX.Element;
|