@townco/ui 0.1.16 → 0.1.18
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-input.d.ts +17 -17
- package/dist/core/hooks/use-chat-input.js +55 -64
- package/dist/core/hooks/use-chat-messages.js +114 -121
- package/dist/core/hooks/use-chat-session.d.ts +1 -1
- package/dist/core/hooks/use-chat-session.js +80 -78
- package/dist/gui/components/Button.d.ts +7 -23
- package/dist/gui/components/Button.js +27 -40
- package/dist/gui/components/Card.d.ts +7 -26
- package/dist/gui/components/Card.js +8 -54
- package/dist/gui/components/ChatSecondaryPanel.d.ts +25 -14
- package/dist/gui/components/ChatSecondaryPanel.js +60 -115
- package/dist/gui/components/ChatStatus.d.ts +2 -4
- package/dist/gui/components/ChatStatus.js +34 -45
- package/dist/gui/components/Conversation.d.ts +14 -17
- package/dist/gui/components/Conversation.js +83 -143
- package/dist/gui/components/Dialog.d.ts +11 -57
- package/dist/gui/components/Dialog.js +8 -84
- package/dist/gui/components/HeightTransition.d.ts +7 -12
- package/dist/gui/components/HeightTransition.js +77 -88
- package/dist/gui/components/Input.d.ts +6 -13
- package/dist/gui/components/Input.js +16 -27
- package/dist/gui/components/Label.d.ts +1 -7
- package/dist/gui/components/Label.js +2 -12
- package/dist/gui/components/MarkdownRenderer.d.ts +4 -6
- package/dist/gui/components/MarkdownRenderer.js +81 -178
- package/dist/gui/components/MessageContent.d.ts +22 -29
- package/dist/gui/components/PanelTabsHeader.d.ts +17 -0
- package/dist/gui/components/PanelTabsHeader.js +31 -0
- package/dist/gui/components/Reasoning.d.ts +24 -30
- package/dist/gui/components/Reasoning.js +60 -187
- package/dist/gui/components/Response.d.ts +9 -11
- package/dist/gui/components/Response.js +90 -229
- package/dist/gui/components/Select.d.ts +10 -69
- package/dist/gui/components/Select.js +12 -118
- package/dist/gui/components/Tabs.d.ts +4 -24
- package/dist/gui/components/Tabs.js +4 -32
- package/dist/gui/components/Task.d.ts +24 -28
- package/dist/gui/components/Task.js +31 -164
- package/dist/gui/components/Textarea.d.ts +7 -15
- package/dist/gui/components/Textarea.js +46 -63
- package/dist/gui/components/ThinkingBlock.d.ts +10 -20
- package/dist/gui/components/ThinkingBlock.js +35 -134
- package/dist/gui/components/TodoList.d.ts +10 -12
- package/dist/gui/components/TodoList.js +7 -22
- package/dist/gui/components/TodoListItem.d.ts +6 -9
- package/dist/gui/components/TodoListItem.js +4 -18
- package/dist/gui/components/ToolCall.js +5 -5
- package/dist/gui/components/index.d.ts +1 -0
- package/dist/gui/components/index.js +1 -0
- package/dist/gui/lib/utils.js +1 -1
- package/dist/index.test.js +1 -0
- package/dist/sdk/client/acp-client.d.ts +76 -88
- package/dist/sdk/client/acp-client.js +217 -215
- package/dist/sdk/schemas/agent.d.ts +64 -111
- package/dist/sdk/schemas/agent.js +24 -24
- package/dist/sdk/schemas/message.d.ts +147 -245
- package/dist/sdk/schemas/message.js +40 -40
- package/dist/sdk/schemas/session.d.ts +6 -6
- package/dist/sdk/transports/http.d.ts +55 -55
- package/dist/sdk/transports/stdio.d.ts +20 -20
- package/dist/sdk/transports/types.d.ts +42 -42
- package/dist/sdk/transports/websocket.d.ts +12 -12
- package/dist/sdk/transports/websocket.js +46 -52
- package/dist/tui/components/ChatView.d.ts +2 -4
- package/dist/tui/components/GameOfLife.js +35 -64
- package/dist/tui/components/InputBox.d.ts +11 -18
- package/dist/tui/components/InputBox.js +10 -70
- package/dist/tui/components/ReadlineInput.d.ts +6 -12
- package/dist/tui/components/ReadlineInput.js +237 -252
- package/dist/tui/components/SingleSelect.d.ts +9 -15
- package/dist/tui/components/SingleSelect.js +43 -84
- package/dist/tui/components/StatusBar.d.ts +6 -11
- package/dist/tui/components/StatusBar.js +67 -102
- package/package.json +3 -3
- package/dist/core/hooks/index.d.ts.map +0 -1
- package/dist/core/hooks/index.js.map +0 -1
- package/dist/core/hooks/use-chat-input.d.ts.map +0 -1
- package/dist/core/hooks/use-chat-input.js.map +0 -1
- package/dist/core/hooks/use-chat-messages.d.ts.map +0 -1
- package/dist/core/hooks/use-chat-messages.js.map +0 -1
- package/dist/core/hooks/use-chat-session.d.ts.map +0 -1
- package/dist/core/hooks/use-chat-session.js.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/core/schemas/chat.d.ts.map +0 -1
- package/dist/core/schemas/chat.js.map +0 -1
- package/dist/core/schemas/index.d.ts.map +0 -1
- package/dist/core/schemas/index.js.map +0 -1
- package/dist/core/store/chat-store.d.ts.map +0 -1
- package/dist/core/store/chat-store.js.map +0 -1
- package/dist/gui/components/Button.d.ts.map +0 -1
- package/dist/gui/components/Button.js.map +0 -1
- package/dist/gui/components/Card.d.ts.map +0 -1
- package/dist/gui/components/Card.js.map +0 -1
- package/dist/gui/components/ChatInput.d.ts.map +0 -1
- package/dist/gui/components/ChatInput.js.map +0 -1
- package/dist/gui/components/ChatInterface.d.ts +0 -12
- package/dist/gui/components/ChatInterface.d.ts.map +0 -1
- package/dist/gui/components/ChatInterface.js +0 -204
- package/dist/gui/components/ChatInterface.js.map +0 -1
- package/dist/gui/components/ChatPreview.d.ts +0 -12
- package/dist/gui/components/ChatPreview.d.ts.map +0 -1
- package/dist/gui/components/ChatPreview.js +0 -214
- package/dist/gui/components/ChatPreview.js.map +0 -1
- package/dist/gui/components/ChatSecondaryPanel.d.ts.map +0 -1
- package/dist/gui/components/ChatSecondaryPanel.js.map +0 -1
- package/dist/gui/components/ChatStatus.d.ts.map +0 -1
- package/dist/gui/components/ChatStatus.js.map +0 -1
- package/dist/gui/components/ChatView.d.ts +0 -8
- package/dist/gui/components/ChatView.d.ts.map +0 -1
- package/dist/gui/components/ChatView.js +0 -42
- package/dist/gui/components/ChatView.js.map +0 -1
- package/dist/gui/components/ConfigPanel.d.ts +0 -20
- package/dist/gui/components/ConfigPanel.d.ts.map +0 -1
- package/dist/gui/components/ConfigPanel.js +0 -225
- package/dist/gui/components/ConfigPanel.js.map +0 -1
- package/dist/gui/components/Conversation.d.ts.map +0 -1
- package/dist/gui/components/Conversation.js.map +0 -1
- package/dist/gui/components/Dialog.d.ts.map +0 -1
- package/dist/gui/components/Dialog.js.map +0 -1
- package/dist/gui/components/HeightTransition.d.ts.map +0 -1
- package/dist/gui/components/HeightTransition.js.map +0 -1
- package/dist/gui/components/Input.d.ts.map +0 -1
- package/dist/gui/components/Input.js.map +0 -1
- package/dist/gui/components/InputBox.d.ts +0 -21
- package/dist/gui/components/InputBox.d.ts.map +0 -1
- package/dist/gui/components/InputBox.js +0 -90
- package/dist/gui/components/InputBox.js.map +0 -1
- package/dist/gui/components/Label.d.ts.map +0 -1
- package/dist/gui/components/Label.js.map +0 -1
- package/dist/gui/components/MarkdownRenderer.d.ts.map +0 -1
- package/dist/gui/components/MarkdownRenderer.js.map +0 -1
- package/dist/gui/components/Message.d.ts.map +0 -1
- package/dist/gui/components/Message.js.map +0 -1
- package/dist/gui/components/MessageContent.d.ts.map +0 -1
- package/dist/gui/components/MessageContent.js.map +0 -1
- package/dist/gui/components/MessageList.d.ts.map +0 -1
- package/dist/gui/components/MessageList.js.map +0 -1
- package/dist/gui/components/PlaygroundLayout.d.ts +0 -14
- package/dist/gui/components/PlaygroundLayout.d.ts.map +0 -1
- package/dist/gui/components/PlaygroundLayout.js +0 -49
- package/dist/gui/components/PlaygroundLayout.js.map +0 -1
- package/dist/gui/components/Reasoning.d.ts.map +0 -1
- package/dist/gui/components/Reasoning.js.map +0 -1
- package/dist/gui/components/Response.d.ts.map +0 -1
- package/dist/gui/components/Response.js.map +0 -1
- package/dist/gui/components/Select.d.ts.map +0 -1
- package/dist/gui/components/Select.js.map +0 -1
- package/dist/gui/components/StatusBar.d.ts +0 -12
- package/dist/gui/components/StatusBar.d.ts.map +0 -1
- package/dist/gui/components/StatusBar.js +0 -58
- package/dist/gui/components/StatusBar.js.map +0 -1
- package/dist/gui/components/Tabs.d.ts.map +0 -1
- package/dist/gui/components/Tabs.js.map +0 -1
- package/dist/gui/components/Task.d.ts.map +0 -1
- package/dist/gui/components/Task.js.map +0 -1
- package/dist/gui/components/Textarea.d.ts.map +0 -1
- package/dist/gui/components/Textarea.js.map +0 -1
- package/dist/gui/components/ThinkingBlock.d.ts.map +0 -1
- package/dist/gui/components/ThinkingBlock.js.map +0 -1
- package/dist/gui/components/TodoList.d.ts.map +0 -1
- package/dist/gui/components/TodoList.js.map +0 -1
- package/dist/gui/components/TodoListItem.d.ts.map +0 -1
- package/dist/gui/components/TodoListItem.js.map +0 -1
- package/dist/gui/components/index.d.ts.map +0 -1
- package/dist/gui/components/index.js.map +0 -1
- package/dist/gui/index.d.ts.map +0 -1
- package/dist/gui/index.js.map +0 -1
- package/dist/gui/lib/utils.d.ts.map +0 -1
- package/dist/gui/lib/utils.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/sdk/client/acp-client.d.ts.map +0 -1
- package/dist/sdk/client/acp-client.js.map +0 -1
- package/dist/sdk/client/index.d.ts.map +0 -1
- package/dist/sdk/client/index.js.map +0 -1
- package/dist/sdk/index.d.ts.map +0 -1
- package/dist/sdk/index.js.map +0 -1
- package/dist/sdk/schemas/agent.d.ts.map +0 -1
- package/dist/sdk/schemas/agent.js.map +0 -1
- package/dist/sdk/schemas/index.d.ts.map +0 -1
- package/dist/sdk/schemas/index.js.map +0 -1
- package/dist/sdk/schemas/message.d.ts.map +0 -1
- package/dist/sdk/schemas/message.js.map +0 -1
- package/dist/sdk/schemas/session.d.ts.map +0 -1
- package/dist/sdk/schemas/session.js.map +0 -1
- package/dist/sdk/transports/http.d.ts.map +0 -1
- package/dist/sdk/transports/http.js.map +0 -1
- package/dist/sdk/transports/index.d.ts.map +0 -1
- package/dist/sdk/transports/index.js.map +0 -1
- package/dist/sdk/transports/stdio.d.ts.map +0 -1
- package/dist/sdk/transports/stdio.js.map +0 -1
- package/dist/sdk/transports/types.d.ts.map +0 -1
- package/dist/sdk/transports/types.js.map +0 -1
- package/dist/sdk/transports/websocket.d.ts.map +0 -1
- package/dist/sdk/transports/websocket.js.map +0 -1
- package/dist/tui/components/ChatView.d.ts.map +0 -1
- package/dist/tui/components/ChatView.js.map +0 -1
- package/dist/tui/components/GameOfLife.d.ts.map +0 -1
- package/dist/tui/components/GameOfLife.js.map +0 -1
- package/dist/tui/components/InputBox.d.ts.map +0 -1
- package/dist/tui/components/InputBox.js.map +0 -1
- package/dist/tui/components/MessageList.d.ts.map +0 -1
- package/dist/tui/components/MessageList.js.map +0 -1
- package/dist/tui/components/ReadlineInput.d.ts.map +0 -1
- package/dist/tui/components/ReadlineInput.js.map +0 -1
- package/dist/tui/components/StatusBar.d.ts.map +0 -1
- package/dist/tui/components/StatusBar.js.map +0 -1
- package/dist/tui/components/index.d.ts.map +0 -1
- package/dist/tui/components/index.js.map +0 -1
- package/dist/tui/index.d.ts.map +0 -1
- package/dist/tui/index.js.map +0 -1
|
@@ -3,21 +3,21 @@ import type { AcpClient } from "../../sdk/client/index.js";
|
|
|
3
3
|
* Hook for managing chat input
|
|
4
4
|
*/
|
|
5
5
|
export declare function useChatInput(client: AcpClient | null): {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
6
|
+
value: string;
|
|
7
|
+
isSubmitting: boolean;
|
|
8
|
+
attachedFiles: {
|
|
9
|
+
name: string;
|
|
10
|
+
path: string;
|
|
11
|
+
size: number;
|
|
12
|
+
mimeType: string;
|
|
13
|
+
}[];
|
|
14
|
+
onChange: (value: string) => void;
|
|
15
|
+
onSubmit: () => Promise<void>;
|
|
16
|
+
onAttachFile: (file: {
|
|
17
|
+
name: string;
|
|
18
|
+
path: string;
|
|
19
|
+
size: number;
|
|
20
|
+
mimeType: string;
|
|
21
|
+
}) => void;
|
|
22
|
+
onRemoveFile: (index: number) => void;
|
|
23
23
|
};
|
|
@@ -5,68 +5,59 @@ import { useChatMessages } from "./use-chat-messages.js";
|
|
|
5
5
|
* Hook for managing chat input
|
|
6
6
|
*/
|
|
7
7
|
export function useChatInput(client) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return {
|
|
64
|
-
value: input.value,
|
|
65
|
-
isSubmitting: input.isSubmitting,
|
|
66
|
-
attachedFiles: input.attachedFiles,
|
|
67
|
-
onChange: handleInputChange,
|
|
68
|
-
onSubmit: handleSubmit,
|
|
69
|
-
onAttachFile: handleAttachFile,
|
|
70
|
-
onRemoveFile: handleRemoveFile,
|
|
71
|
-
};
|
|
8
|
+
const input = useChatStore((state) => state.input);
|
|
9
|
+
const setInputValue = useChatStore((state) => state.setInputValue);
|
|
10
|
+
const setInputSubmitting = useChatStore((state) => state.setInputSubmitting);
|
|
11
|
+
const addFileAttachment = useChatStore((state) => state.addFileAttachment);
|
|
12
|
+
const removeFileAttachment = useChatStore((state) => state.removeFileAttachment);
|
|
13
|
+
const { sendMessage } = useChatMessages(client);
|
|
14
|
+
/**
|
|
15
|
+
* Handle input value change
|
|
16
|
+
*/
|
|
17
|
+
const handleInputChange = useCallback((value) => {
|
|
18
|
+
setInputValue(value);
|
|
19
|
+
}, [setInputValue]);
|
|
20
|
+
/**
|
|
21
|
+
* Handle input submission
|
|
22
|
+
*/
|
|
23
|
+
const handleSubmit = useCallback(async () => {
|
|
24
|
+
if (!input.value.trim() || input.isSubmitting) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const message = input.value;
|
|
28
|
+
// Clear input immediately for better UX
|
|
29
|
+
setInputValue("");
|
|
30
|
+
setInputSubmitting(true);
|
|
31
|
+
try {
|
|
32
|
+
await sendMessage(message);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
// Error is handled in useChatMessages
|
|
36
|
+
console.error("Failed to send message:", error);
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
setInputSubmitting(false);
|
|
40
|
+
}
|
|
41
|
+
}, [input, setInputValue, setInputSubmitting, sendMessage]);
|
|
42
|
+
/**
|
|
43
|
+
* Handle file attachment
|
|
44
|
+
*/
|
|
45
|
+
const handleAttachFile = useCallback((file) => {
|
|
46
|
+
addFileAttachment(file);
|
|
47
|
+
}, [addFileAttachment]);
|
|
48
|
+
/**
|
|
49
|
+
* Handle file removal
|
|
50
|
+
*/
|
|
51
|
+
const handleRemoveFile = useCallback((index) => {
|
|
52
|
+
removeFileAttachment(index);
|
|
53
|
+
}, [removeFileAttachment]);
|
|
54
|
+
return {
|
|
55
|
+
value: input.value,
|
|
56
|
+
isSubmitting: input.isSubmitting,
|
|
57
|
+
attachedFiles: input.attachedFiles,
|
|
58
|
+
onChange: handleInputChange,
|
|
59
|
+
onSubmit: handleSubmit,
|
|
60
|
+
onAttachFile: handleAttachFile,
|
|
61
|
+
onRemoveFile: handleRemoveFile,
|
|
62
|
+
};
|
|
72
63
|
}
|
|
@@ -4,125 +4,118 @@ import { useChatStore } from "../store/chat-store.js";
|
|
|
4
4
|
* Hook for managing chat messages
|
|
5
5
|
*/
|
|
6
6
|
export function useChatMessages(client) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
],
|
|
122
|
-
);
|
|
123
|
-
return {
|
|
124
|
-
messages,
|
|
125
|
-
isStreaming,
|
|
126
|
-
sendMessage,
|
|
127
|
-
};
|
|
7
|
+
const messages = useChatStore((state) => state.messages);
|
|
8
|
+
const isStreaming = useChatStore((state) => state.isStreaming);
|
|
9
|
+
const sessionId = useChatStore((state) => state.sessionId);
|
|
10
|
+
const setIsStreaming = useChatStore((state) => state.setIsStreaming);
|
|
11
|
+
const setStreamingStartTime = useChatStore((state) => state.setStreamingStartTime);
|
|
12
|
+
const addMessage = useChatStore((state) => state.addMessage);
|
|
13
|
+
const updateMessage = useChatStore((state) => state.updateMessage);
|
|
14
|
+
const setError = useChatStore((state) => state.setError);
|
|
15
|
+
/**
|
|
16
|
+
* Send a message to the agent
|
|
17
|
+
*/
|
|
18
|
+
const sendMessage = useCallback(async (content) => {
|
|
19
|
+
if (!client) {
|
|
20
|
+
console.error("❌ No client available");
|
|
21
|
+
setError("No client available");
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (!sessionId) {
|
|
25
|
+
console.error("❌ No active session");
|
|
26
|
+
setError("No active session");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
// Start streaming and track time immediately
|
|
31
|
+
const startTime = Date.now();
|
|
32
|
+
setIsStreaming(true);
|
|
33
|
+
setStreamingStartTime(startTime);
|
|
34
|
+
// Add user message to UI
|
|
35
|
+
const userMessage = {
|
|
36
|
+
id: `msg_${Date.now()}_user`,
|
|
37
|
+
role: "user",
|
|
38
|
+
content,
|
|
39
|
+
timestamp: new Date().toISOString(),
|
|
40
|
+
isStreaming: false,
|
|
41
|
+
};
|
|
42
|
+
addMessage(userMessage);
|
|
43
|
+
// Create placeholder for assistant message BEFORE sending
|
|
44
|
+
const assistantMessageId = `msg_${Date.now()}_assistant`;
|
|
45
|
+
const assistantMessage = {
|
|
46
|
+
id: assistantMessageId,
|
|
47
|
+
role: "assistant",
|
|
48
|
+
content: "",
|
|
49
|
+
timestamp: new Date().toISOString(),
|
|
50
|
+
isStreaming: true,
|
|
51
|
+
streamingStartTime: startTime, // Use the same start time from when user sent message
|
|
52
|
+
};
|
|
53
|
+
addMessage(assistantMessage);
|
|
54
|
+
// Build full conversation history (excluding system messages)
|
|
55
|
+
const conversationHistory = messages
|
|
56
|
+
.filter((msg) => msg.role !== "system")
|
|
57
|
+
.map((msg) => `${msg.role === "user" ? "Human" : "Assistant"}: ${msg.content}`)
|
|
58
|
+
.join("\n\n");
|
|
59
|
+
// Combine history with new message
|
|
60
|
+
const fullPrompt = conversationHistory
|
|
61
|
+
? `${conversationHistory}\n\nHuman: ${content}`
|
|
62
|
+
: content;
|
|
63
|
+
// Start receiving chunks (async iterator)
|
|
64
|
+
const messageStream = client.receiveMessages();
|
|
65
|
+
// Send full conversation without awaiting (fire and forget)
|
|
66
|
+
// This allows chunks to start arriving while we're listening
|
|
67
|
+
client.sendMessage(fullPrompt, sessionId).catch((error) => {
|
|
68
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
69
|
+
setError(message);
|
|
70
|
+
setIsStreaming(false);
|
|
71
|
+
setStreamingStartTime(null);
|
|
72
|
+
});
|
|
73
|
+
// Listen for streaming chunks
|
|
74
|
+
let accumulatedContent = "";
|
|
75
|
+
for await (const chunk of messageStream) {
|
|
76
|
+
if (chunk.isComplete) {
|
|
77
|
+
// Update final message
|
|
78
|
+
updateMessage(assistantMessageId, {
|
|
79
|
+
content: accumulatedContent,
|
|
80
|
+
isStreaming: false,
|
|
81
|
+
streamingStartTime: undefined, // Clear streaming start time
|
|
82
|
+
});
|
|
83
|
+
setIsStreaming(false);
|
|
84
|
+
setStreamingStartTime(null); // Clear global streaming start time
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Update streaming content
|
|
89
|
+
if (chunk.contentDelta.type === "text") {
|
|
90
|
+
accumulatedContent += chunk.contentDelta.text;
|
|
91
|
+
updateMessage(assistantMessageId, {
|
|
92
|
+
content: accumulatedContent,
|
|
93
|
+
});
|
|
94
|
+
// Small delay to allow Ink to render between chunks (~60fps)
|
|
95
|
+
await new Promise((resolve) => setTimeout(resolve, 16));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
102
|
+
setError(message);
|
|
103
|
+
setIsStreaming(false);
|
|
104
|
+
setStreamingStartTime(null); // Clear streaming start time on error
|
|
105
|
+
}
|
|
106
|
+
}, [
|
|
107
|
+
client,
|
|
108
|
+
sessionId,
|
|
109
|
+
messages,
|
|
110
|
+
addMessage,
|
|
111
|
+
updateMessage,
|
|
112
|
+
setIsStreaming,
|
|
113
|
+
setStreamingStartTime,
|
|
114
|
+
setError,
|
|
115
|
+
]);
|
|
116
|
+
return {
|
|
117
|
+
messages,
|
|
118
|
+
isStreaming,
|
|
119
|
+
sendMessage,
|
|
120
|
+
};
|
|
128
121
|
}
|
|
@@ -3,7 +3,7 @@ import type { AcpClient } from "../../sdk/client/index.js";
|
|
|
3
3
|
* Hook for managing chat session lifecycle
|
|
4
4
|
*/
|
|
5
5
|
export declare function useChatSession(client: AcpClient | null): {
|
|
6
|
-
connectionStatus: "
|
|
6
|
+
connectionStatus: "error" | "connecting" | "connected" | "disconnected";
|
|
7
7
|
sessionId: string | null;
|
|
8
8
|
connect: () => Promise<void>;
|
|
9
9
|
startSession: () => Promise<void>;
|
|
@@ -4,82 +4,84 @@ import { useChatStore } from "../store/chat-store.js";
|
|
|
4
4
|
* Hook for managing chat session lifecycle
|
|
5
5
|
*/
|
|
6
6
|
export function useChatSession(client) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
7
|
+
const connectionStatus = useChatStore((state) => state.connectionStatus);
|
|
8
|
+
const sessionId = useChatStore((state) => state.sessionId);
|
|
9
|
+
const setConnectionStatus = useChatStore((state) => state.setConnectionStatus);
|
|
10
|
+
const setSessionId = useChatStore((state) => state.setSessionId);
|
|
11
|
+
const setError = useChatStore((state) => state.setError);
|
|
12
|
+
const clearMessages = useChatStore((state) => state.clearMessages);
|
|
13
|
+
/**
|
|
14
|
+
* Connect to the agent
|
|
15
|
+
*/
|
|
16
|
+
const connect = useCallback(async () => {
|
|
17
|
+
if (!client) {
|
|
18
|
+
setError("No client available");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
setConnectionStatus("connecting");
|
|
23
|
+
setError(null);
|
|
24
|
+
await client.connect();
|
|
25
|
+
setConnectionStatus("connected");
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
console.log(error);
|
|
29
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
30
|
+
setError(message);
|
|
31
|
+
setConnectionStatus("error");
|
|
32
|
+
}
|
|
33
|
+
}, [client, setConnectionStatus, setError]);
|
|
34
|
+
/**
|
|
35
|
+
* Start a new session
|
|
36
|
+
*/
|
|
37
|
+
const startSession = useCallback(async () => {
|
|
38
|
+
if (!client) {
|
|
39
|
+
setError("No client available");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const id = await client.startSession();
|
|
44
|
+
setSessionId(id);
|
|
45
|
+
clearMessages();
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
49
|
+
setError(message);
|
|
50
|
+
}
|
|
51
|
+
}, [client, setSessionId, setError, clearMessages]);
|
|
52
|
+
/**
|
|
53
|
+
* Disconnect from the agent
|
|
54
|
+
*/
|
|
55
|
+
const disconnect = useCallback(async () => {
|
|
56
|
+
if (!client)
|
|
57
|
+
return;
|
|
58
|
+
try {
|
|
59
|
+
await client.disconnect();
|
|
60
|
+
setConnectionStatus("disconnected");
|
|
61
|
+
setSessionId(null);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
65
|
+
setError(message);
|
|
66
|
+
}
|
|
67
|
+
}, [client, setConnectionStatus, setSessionId, setError]);
|
|
68
|
+
// Auto-connect on mount if client is available
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (client && connectionStatus === "disconnected") {
|
|
71
|
+
connect();
|
|
72
|
+
}
|
|
73
|
+
}, [client, connectionStatus, connect]);
|
|
74
|
+
// Auto-start session after connecting
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (connectionStatus === "connected" && !sessionId) {
|
|
77
|
+
startSession();
|
|
78
|
+
}
|
|
79
|
+
}, [connectionStatus, sessionId, startSession]);
|
|
80
|
+
return {
|
|
81
|
+
connectionStatus,
|
|
82
|
+
sessionId,
|
|
83
|
+
connect,
|
|
84
|
+
startSession,
|
|
85
|
+
disconnect,
|
|
86
|
+
};
|
|
85
87
|
}
|
|
@@ -1,27 +1,11 @@
|
|
|
1
1
|
import { type VariantProps } from "class-variance-authority";
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
declare const buttonVariants: (
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
| "outline"
|
|
10
|
-
| "secondary"
|
|
11
|
-
| "ghost"
|
|
12
|
-
| "link"
|
|
13
|
-
| null
|
|
14
|
-
| undefined;
|
|
15
|
-
size?: "default" | "sm" | "lg" | "icon" | null | undefined;
|
|
16
|
-
} & import("class-variance-authority/types").ClassProp)
|
|
17
|
-
| undefined,
|
|
18
|
-
) => string;
|
|
19
|
-
export interface ButtonProps
|
|
20
|
-
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
21
|
-
VariantProps<typeof buttonVariants> {
|
|
22
|
-
asChild?: boolean;
|
|
3
|
+
declare const buttonVariants: (props?: ({
|
|
4
|
+
variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
|
|
5
|
+
size?: "default" | "sm" | "lg" | "icon" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
8
|
+
asChild?: boolean;
|
|
23
9
|
}
|
|
24
|
-
declare const Button: React.ForwardRefExoticComponent<
|
|
25
|
-
ButtonProps & React.RefAttributes<HTMLButtonElement>
|
|
26
|
-
>;
|
|
10
|
+
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
27
11
|
export { Button, buttonVariants };
|