ikoncomponents 1.7.0 → 1.7.2

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 (32) hide show
  1. package/dist/ikoncomponents/assistant-ui/Assistant.d.ts +28 -0
  2. package/dist/ikoncomponents/assistant-ui/Assistant.js +306 -0
  3. package/dist/ikoncomponents/assistant-ui/agent-dropdown.d.ts +24 -0
  4. package/dist/ikoncomponents/assistant-ui/agent-dropdown.js +16 -0
  5. package/dist/ikoncomponents/assistant-ui/agentTextChatTransport.d.ts +30 -0
  6. package/dist/ikoncomponents/assistant-ui/agentTextChatTransport.js +208 -0
  7. package/dist/ikoncomponents/assistant-ui/attachment.d.ts +4 -0
  8. package/dist/ikoncomponents/assistant-ui/attachment.js +93 -0
  9. package/dist/ikoncomponents/assistant-ui/markdown-text.d.ts +2 -0
  10. package/dist/ikoncomponents/assistant-ui/markdown-text.js +126 -0
  11. package/dist/ikoncomponents/assistant-ui/thread.d.ts +10 -0
  12. package/dist/ikoncomponents/assistant-ui/thread.js +115 -0
  13. package/dist/ikoncomponents/assistant-ui/tool-fallback.d.ts +2 -0
  14. package/dist/ikoncomponents/assistant-ui/tool-fallback.js +18 -0
  15. package/dist/ikoncomponents/assistant-ui/tooltip-icon-button.d.ts +7 -0
  16. package/dist/ikoncomponents/assistant-ui/tooltip-icon-button.js +23 -0
  17. package/dist/ikoncomponents/fileUpload/index.js +1 -1
  18. package/dist/ikoncomponents/fileUploadApi/index.js +1 -1
  19. package/dist/ikoncomponents/table/DataTable/index.d.ts +1 -1
  20. package/dist/ikoncomponents/table/DataTable/index.js +65 -6
  21. package/dist/ikoncomponents/table/index.d.ts +1 -1
  22. package/dist/ikoncomponents/table/index.js +153 -5
  23. package/dist/ikoncomponents/table/type.d.ts +21 -12
  24. package/dist/ikoncomponents/table/type.js +7 -0
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.js +1 -1
  27. package/dist/styles.css +309 -109
  28. package/dist/tsconfig.build.tsbuildinfo +1 -0
  29. package/dist/utils/api/file-upload copy/index.js +1 -1
  30. package/dist/utils/userType.d.ts +13 -0
  31. package/dist/utils/userType.js +1 -0
  32. package/package.json +4 -3
@@ -0,0 +1,28 @@
1
+ interface UserData {
2
+ userId: string;
3
+ userName: string;
4
+ userLogin: string;
5
+ password: string;
6
+ userPhone?: string;
7
+ userEmail: string;
8
+ userThumbnail?: string | null;
9
+ userType?: string;
10
+ active?: boolean;
11
+ accountId?: string;
12
+ userDeleted?: boolean;
13
+ }
14
+ interface AssistantComponentProps {
15
+ provider?: string;
16
+ model?: string;
17
+ agentId?: string;
18
+ agentName?: string;
19
+ temperature?: number;
20
+ maxTokens?: number;
21
+ className?: string;
22
+ baseUrl?: string;
23
+ additionalReferenceInfo?: object;
24
+ appId: string;
25
+ currentUserDetails: UserData;
26
+ }
27
+ export declare const AssistantComponent: ({ provider, model, agentId, agentName, temperature, maxTokens, className, baseUrl, additionalReferenceInfo, appId, currentUserDetails, }: AssistantComponentProps) => import("react/jsx-runtime").JSX.Element;
28
+ export {};
@@ -0,0 +1,306 @@
1
+ // "use client";
2
+ // import { Thread } from "./thread";
3
+ // import { AssistantRuntimeProvider } from "@assistant-ui/react";
4
+ // import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
5
+ // import { AgentTextChatTransport } from "./agentTextChatTransport";
6
+ // import { useEffect, useState } from "react";
7
+ // import { getValidAccessToken } from "@/utils/token-management";
8
+ // import { Agent } from "./agent-dropdown";
9
+ // interface UserData {
10
+ // userId: string;
11
+ // userName: string;
12
+ // userLogin: string;
13
+ // password: string;
14
+ // userPhone?: string;
15
+ // userEmail: string;
16
+ // userThumbnail?: string | null;
17
+ // userType?: string;
18
+ // active?: boolean;
19
+ // accountId?: string;
20
+ // userDeleted?: boolean;
21
+ // }
22
+ // interface AssistantComponentProps {
23
+ // provider?: string;
24
+ // model?: string;
25
+ // agentId?: string;
26
+ // agentName?: string;
27
+ // temperature?: number;
28
+ // maxTokens?: number;
29
+ // className?: string;
30
+ // baseUrl?: string;
31
+ // additionalReferenceInfo?: object;
32
+ // appId: string;
33
+ // currentUserDetails: UserData;
34
+ // }
35
+ // export const AssistantComponent = ({
36
+ // provider = "openai",
37
+ // model = "gpt-4o-mini",
38
+ // agentId = "default-agent",
39
+ // agentName = "Default Agent",
40
+ // temperature = 0.7,
41
+ // maxTokens = 2048,
42
+ // className,
43
+ // baseUrl = "http://localhost:3000",
44
+ // additionalReferenceInfo = {},
45
+ // appId = "",
46
+ // currentUserDetails,
47
+ // }: AssistantComponentProps) => {
48
+ // const runtime = useChatRuntime({
49
+ // transport: new AgentTextChatTransport({
50
+ // provider,
51
+ // model,
52
+ // agentId,
53
+ // agentName,
54
+ // temperature,
55
+ // maxTokens,
56
+ // baseUrl,
57
+ // additionalReferenceInfo,
58
+ // }),
59
+ // });
60
+ // const [agentList, setAgentList] = useState([]);
61
+ // const [selectedAgent, setSelectedAgent] = useState<Agent>();
62
+ // const getAgentsByAppId = async () => {
63
+ // try {
64
+ // const accessToken = await getValidAccessToken(
65
+ // "https://ikoncloud-dev.keross.com/ikon-api",
66
+ // );
67
+ // const response = await fetch(`${baseUrl}/api/agent/${appId}`, {
68
+ // method: "GET",
69
+ // headers: {
70
+ // "Content-Type": "application/json",
71
+ // Authorization: `Bearer ${accessToken}`,
72
+ // },
73
+ // });
74
+ // // 1. Check if the response is actually okay
75
+ // if (!response.ok) {
76
+ // throw new Error(`HTTP error! status: ${response.status}`);
77
+ // }
78
+ // // 2. Parse the body as JSON
79
+ // const data = await response.json();
80
+ // // 3. Now you can use it!
81
+ // console.log("Agent Data:", data);
82
+ // setAgentList(data);
83
+ // // setAgentList(response)
84
+ // } catch (error) {
85
+ // console.error(
86
+ // "Error while fetching agents with the specific appId",
87
+ // error,
88
+ // );
89
+ // }
90
+ // };
91
+ // useEffect(() => {
92
+ // getAgentsByAppId();
93
+ // }, [appId, baseUrl]);
94
+ // useEffect(() => {
95
+ // },[selectedAgent])
96
+ // return (
97
+ // <AssistantRuntimeProvider runtime={runtime}>
98
+ // <div className={className}>
99
+ // <div
100
+ // className={`flex flex-col h-full border rounded-lg overflow-hidden ${className}`}
101
+ // >
102
+ // <Thread
103
+ // currentUserDetails={currentUserDetails}
104
+ // agents={agentList}
105
+ // initialAgentId={agentId}
106
+ // initialAgentName={agentName}
107
+ // onAgentChange={(agent) => {
108
+ // // Handle agent change here
109
+ // console.log("Agent changed:", agent);
110
+ // setSelectedAgent(agent);
111
+ // }}
112
+ // />
113
+ // </div>
114
+ // </div>
115
+ // </AssistantRuntimeProvider>
116
+ // );
117
+ // };
118
+ //2nd imperfect change
119
+ // "use client";
120
+ // import { Thread } from "./thread";
121
+ // import { AssistantRuntimeProvider } from "@assistant-ui/react";
122
+ // import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
123
+ // import { AgentTextChatTransport } from "./agentTextChatTransport";
124
+ // import { useEffect, useRef, useState } from "react";
125
+ // import { getValidAccessToken } from "@/utils/token-management";
126
+ // import { Agent } from "./agent-dropdown";
127
+ // interface UserData {
128
+ // userId: string;
129
+ // userName: string;
130
+ // userLogin: string;
131
+ // password: string;
132
+ // userPhone?: string;
133
+ // userEmail: string;
134
+ // userThumbnail?: string | null;
135
+ // userType?: string;
136
+ // active?: boolean;
137
+ // accountId?: string;
138
+ // userDeleted?: boolean;
139
+ // }
140
+ // interface AssistantComponentProps {
141
+ // provider?: string;
142
+ // model?: string;
143
+ // agentId?: string;
144
+ // agentName?: string;
145
+ // temperature?: number;
146
+ // maxTokens?: number;
147
+ // className?: string;
148
+ // baseUrl?: string;
149
+ // additionalReferenceInfo?: object;
150
+ // appId: string;
151
+ // currentUserDetails: UserData;
152
+ // }
153
+ // export const AssistantComponent = ({
154
+ // provider = "openai",
155
+ // model = "gpt-4o-mini",
156
+ // agentId = "default-agent",
157
+ // agentName = "Default Agent",
158
+ // temperature = 0.7,
159
+ // maxTokens = 2048,
160
+ // className,
161
+ // baseUrl = "http://localhost:3000",
162
+ // additionalReferenceInfo = {},
163
+ // appId = "",
164
+ // currentUserDetails,
165
+ // }: AssistantComponentProps) => {
166
+ // const transportRef = useRef<AgentTextChatTransport | null>(null);
167
+ // const transport = new AgentTextChatTransport({
168
+ // provider,
169
+ // model,
170
+ // agentId,
171
+ // agentName,
172
+ // temperature,
173
+ // maxTokens,
174
+ // baseUrl,
175
+ // additionalReferenceInfo,
176
+ // });
177
+ // transportRef.current = transport;
178
+ // const runtime = useChatRuntime({
179
+ // transport,
180
+ // });
181
+ // const [agentList, setAgentList] = useState<Agent[]>([]);
182
+ // const [selectedAgent, setSelectedAgent] = useState<Agent>();
183
+ // const getAgentsByAppId = async () => {
184
+ // try {
185
+ // const accessToken = await getValidAccessToken(
186
+ // "https://ikoncloud-dev.keross.com/ikon-api",
187
+ // );
188
+ // const response = await fetch(`${baseUrl}/api/agent/${appId}`, {
189
+ // method: "GET",
190
+ // headers: {
191
+ // "Content-Type": "application/json",
192
+ // Authorization: `Bearer ${accessToken}`,
193
+ // },
194
+ // });
195
+ // if (!response.ok) {
196
+ // throw new Error(`HTTP error! status: ${response.status}`);
197
+ // }
198
+ // const data = await response.json();
199
+ // console.log("Agent Data:", data);
200
+ // setAgentList(data);
201
+ // } catch (error) {
202
+ // console.error(
203
+ // "Error while fetching agents with the specific appId",
204
+ // error,
205
+ // );
206
+ // }
207
+ // };
208
+ // useEffect(() => {
209
+ // getAgentsByAppId();
210
+ // }, [appId, baseUrl]);
211
+ // const handleAgentChange = (agent: Agent) => {
212
+ // setSelectedAgent(agent);
213
+ // // Update the transport with the new agent configuration
214
+ // if (transportRef.current) {
215
+ // transportRef.current.updateAgentConfig({
216
+ // agentId: agent.agentID,
217
+ // agentName: agent.agentName,
218
+ // });
219
+ // }
220
+ // console.log("Agent changed to:", agent.agentName);
221
+ // };
222
+ // return (
223
+ // <AssistantRuntimeProvider runtime={runtime}>
224
+ // <div className={className}>
225
+ // <div
226
+ // className={`flex flex-col h-full border rounded-lg overflow-hidden ${className}`}
227
+ // >
228
+ // <Thread
229
+ // currentUserDetails={currentUserDetails}
230
+ // agents={agentList}
231
+ // initialAgentId={agentId}
232
+ // initialAgentName={agentName}
233
+ // onAgentChange={handleAgentChange}
234
+ // />
235
+ // </div>
236
+ // </div>
237
+ // </AssistantRuntimeProvider>
238
+ // );
239
+ // };
240
+ //3rd change
241
+ "use client";
242
+ import { jsx as _jsx } from "react/jsx-runtime";
243
+ import { Thread } from "./thread";
244
+ import { AssistantRuntimeProvider } from "@assistant-ui/react";
245
+ import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
246
+ import { AgentTextChatTransport } from "./agentTextChatTransport";
247
+ import { useEffect, useMemo, useState } from "react";
248
+ import { getValidAccessToken } from "../../utils/token-management";
249
+ export const AssistantComponent = ({ provider = "openai", model = "gpt-4o-mini", agentId = "default-agent", agentName = "Default Agent", temperature = 0.7, maxTokens = 2048, className, baseUrl = "http://localhost:3000", additionalReferenceInfo = {}, appId = "", currentUserDetails, }) => {
250
+ const [agentList, setAgentList] = useState([]);
251
+ const [selectedAgent, setSelectedAgent] = useState();
252
+ // Create transport with current agent config - memoized to avoid recreating on every render
253
+ const transport = useMemo(() => new AgentTextChatTransport({
254
+ provider,
255
+ model,
256
+ agentId: selectedAgent ? selectedAgent.agentID : agentId,
257
+ agentName: selectedAgent ? selectedAgent.agentName : agentName,
258
+ temperature,
259
+ maxTokens,
260
+ baseUrl,
261
+ additionalReferenceInfo,
262
+ }), [
263
+ provider,
264
+ model,
265
+ selectedAgent,
266
+ agentId,
267
+ agentName,
268
+ temperature,
269
+ maxTokens,
270
+ baseUrl,
271
+ additionalReferenceInfo,
272
+ ]);
273
+ // Create runtime with the transport - will recreate when transport changes
274
+ const runtime = useChatRuntime({
275
+ transport,
276
+ });
277
+ const getAgentsByAppId = async () => {
278
+ try {
279
+ const accessToken = await getValidAccessToken("https://ikoncloud-dev.keross.com/ikon-api");
280
+ const response = await fetch(`${baseUrl}/api/agent/${appId}`, {
281
+ method: "GET",
282
+ headers: {
283
+ "Content-Type": "application/json",
284
+ Authorization: `Bearer ${accessToken}`,
285
+ },
286
+ });
287
+ if (!response.ok) {
288
+ throw new Error(`HTTP error! status: ${response.status}`);
289
+ }
290
+ const data = await response.json();
291
+ console.log("Agent Data:", data);
292
+ setAgentList(data);
293
+ }
294
+ catch (error) {
295
+ console.error("Error while fetching agents with the specific appId", error);
296
+ }
297
+ };
298
+ useEffect(() => {
299
+ getAgentsByAppId();
300
+ }, [appId, baseUrl]);
301
+ const handleAgentChange = (agent) => {
302
+ setSelectedAgent(agent);
303
+ console.log("Agent changed to:", agent.agentName);
304
+ };
305
+ return (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx("div", { className: className, children: _jsx("div", { className: `flex flex-col h-full border rounded-lg overflow-hidden ${className}`, children: _jsx(Thread, { currentUserDetails: currentUserDetails, agents: agentList, initialAgentId: agentId, initialAgentName: agentName, onAgentChange: handleAgentChange }) }) }) }));
306
+ };
@@ -0,0 +1,24 @@
1
+ export interface Agent {
2
+ agentDescription?: string;
3
+ agentID: string;
4
+ agentName: string;
5
+ agentRoles?: string[];
6
+ agentTasks?: object[];
7
+ appId: string;
8
+ createdAt: string;
9
+ createdBy: string;
10
+ mcpServerIds?: string[];
11
+ systemPrompt: string;
12
+ updatedAt: string;
13
+ updatedBy: string;
14
+ userName?: null | string;
15
+ [key: string]: any;
16
+ }
17
+ export interface AgentDropdownProps {
18
+ agents: Agent[];
19
+ selectedAgent?: Agent;
20
+ onSelectAgent: (agent: Agent) => void;
21
+ className?: string;
22
+ triggerClassName?: string;
23
+ }
24
+ export declare const AgentDropdown: ({ agents, selectedAgent, onSelectAgent, className, triggerClassName, }: AgentDropdownProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { ChevronDownIcon } from "lucide-react";
5
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "../../shadcn/dropdown-menu";
6
+ import { Button } from "../../shadcn/button";
7
+ import { cn } from "../../utils/cn";
8
+ export const AgentDropdown = ({ agents, selectedAgent, onSelectAgent, className, triggerClassName, }) => {
9
+ const [open, setOpen] = useState(false);
10
+ // const displayAgent = selectedAgent || (agents.length > 0 ? agents[0] : null);
11
+ const displayAgent = selectedAgent || null;
12
+ return (_jsxs(DropdownMenu, { open: open, onOpenChange: setOpen, children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", className: cn("gap-2 px-3 py-2 text-sm font-medium rounded-2xl", triggerClassName), children: [_jsx("span", { className: "truncate", children: (displayAgent === null || displayAgent === void 0 ? void 0 : displayAgent.agentName) || "Select Agent" }), _jsx(ChevronDownIcon, { className: "size-4 shrink-0 opacity-50" })] }) }), _jsx(DropdownMenuContent, { align: "end", className: cn("min-w-[200px]", className), children: agents.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(DropdownMenuLabel, { className: "px-2 py-1.5 text-xs font-semibold text-muted-foreground", children: "Agents" }), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuGroup, { children: agents.map((agent) => (_jsxs(DropdownMenuItem, { onClick: () => {
13
+ onSelectAgent(agent);
14
+ setOpen(false);
15
+ }, className: cn("cursor-pointer flex flex-col gap-1", (displayAgent === null || displayAgent === void 0 ? void 0 : displayAgent.agentID) === agent.agentID && "bg-accent"), children: [_jsx("div", { className: "font-medium text-sm", children: agent.agentName }), agent.agentDescription && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: agent.agentDescription }))] }, agent.agentID))) })] })) : (_jsx("div", { className: "px-2 py-1.5 text-sm text-muted-foreground text-center", children: "No agents available" })) })] }));
16
+ };
@@ -0,0 +1,30 @@
1
+ import { ChatTransport, UIMessage, UIMessageChunk, ChatRequestOptions } from "ai";
2
+ export interface AgentTextChatTransportOptions {
3
+ provider: string;
4
+ model: string;
5
+ agentId: string;
6
+ agentName?: string;
7
+ temperature?: number;
8
+ maxTokens?: number;
9
+ baseUrl?: string;
10
+ additionalReferenceInfo?: object;
11
+ }
12
+ export declare class AgentTextChatTransport<UI_MESSAGE extends UIMessage = UIMessage> implements ChatTransport<UI_MESSAGE> {
13
+ private agentConfig;
14
+ private baseUrl;
15
+ private chatIdMap;
16
+ constructor(options: AgentTextChatTransportOptions);
17
+ updateAgentConfig(options: Partial<AgentTextChatTransportOptions>): void;
18
+ private getChatId;
19
+ sendMessages(options: {
20
+ trigger: "submit-message" | "regenerate-message";
21
+ chatId: string;
22
+ messageId: string | undefined;
23
+ messages: UI_MESSAGE[];
24
+ abortSignal: AbortSignal | undefined;
25
+ } & ChatRequestOptions): Promise<ReadableStream<UIMessageChunk>>;
26
+ reconnectToStream(options: {
27
+ chatId: string;
28
+ } & ChatRequestOptions): Promise<ReadableStream<UIMessageChunk> | null>;
29
+ private processResponseStream;
30
+ }
@@ -0,0 +1,208 @@
1
+ import { getValidAccessToken } from "../../utils/token-management";
2
+ import { v4 as uuidv4 } from "uuid";
3
+ export class AgentTextChatTransport {
4
+ constructor(options) {
5
+ this.chatIdMap = new Map();
6
+ this.agentConfig = options;
7
+ this.baseUrl = options.baseUrl || "";
8
+ }
9
+ updateAgentConfig(options) {
10
+ this.agentConfig = Object.assign(Object.assign({}, this.agentConfig), options);
11
+ }
12
+ getChatId(chatId) {
13
+ if (this.chatIdMap.has(chatId)) {
14
+ return this.chatIdMap.get(chatId);
15
+ }
16
+ return uuidv4();
17
+ }
18
+ async sendMessages(options) {
19
+ var _a, _b;
20
+ const { messages, chatId, abortSignal, headers, body } = options;
21
+ console.log("sendMessages called with chatId:", chatId, "trigger:", options.trigger);
22
+ const serverChatId = this.getChatId(chatId);
23
+ console.log("Using server chatId:", serverChatId);
24
+ // Convert UIMessage[] to LangChain AIMessage format
25
+ const convertedMessages = messages.map((msg) => {
26
+ const content = msg.parts
27
+ .filter((part) => part.type === "text")
28
+ .map((part) => part.text)
29
+ .join("");
30
+ return {
31
+ role: msg.role,
32
+ content: msg.role === "user" &&
33
+ this.agentConfig.additionalReferenceInfo &&
34
+ Object.keys(this.agentConfig.additionalReferenceInfo).length > 0
35
+ ? content + JSON.stringify(this.agentConfig.additionalReferenceInfo)
36
+ : content,
37
+ };
38
+ });
39
+ const requestBody = Object.assign({ messages: convertedMessages, provider: this.agentConfig.provider, model: this.agentConfig.model, agentId: this.agentConfig.agentId, agentName: this.agentConfig.agentName, temperature: (_a = this.agentConfig.temperature) !== null && _a !== void 0 ? _a : 0.7, maxTokens: (_b = this.agentConfig.maxTokens) !== null && _b !== void 0 ? _b : 2048, stream: true, useVoice: false }, body);
40
+ //adding code to fetch the token and pass it
41
+ const accessToken = await getValidAccessToken(this.baseUrl);
42
+ const mergedHeaders = Object.assign({ "Content-Type": "application/json", "Authorization": `Bearer ${accessToken}` }, (headers instanceof Headers
43
+ ? Object.fromEntries(headers.entries())
44
+ : headers || {}));
45
+ try {
46
+ const response = await fetch(`${this.baseUrl}/api/chat/completions/${serverChatId}`, {
47
+ method: "POST",
48
+ headers: mergedHeaders,
49
+ body: JSON.stringify(requestBody),
50
+ signal: abortSignal,
51
+ cache: "no-store",
52
+ });
53
+ if (!response.ok) {
54
+ throw new Error(`HTTP error! status: ${response.status}`);
55
+ }
56
+ if (!response.body) {
57
+ throw new Error("Response body is null");
58
+ }
59
+ return this.processResponseStream(response.body);
60
+ }
61
+ catch (error) {
62
+ console.error("Error in sendMessages:", error);
63
+ throw error;
64
+ }
65
+ }
66
+ async reconnectToStream(options) {
67
+ return null;
68
+ }
69
+ processResponseStream(stream) {
70
+ const decoder = new TextDecoder();
71
+ let buffer = "";
72
+ let reader = null;
73
+ let isClosed = false;
74
+ let pendingChunks = [];
75
+ let hasStarted = false;
76
+ let messageId = "";
77
+ let textStarted = false;
78
+ let textPartId = "";
79
+ return new ReadableStream({
80
+ async start(controller) {
81
+ reader = stream.getReader();
82
+ },
83
+ async pull(controller) {
84
+ var _a;
85
+ if (!reader || isClosed) {
86
+ return;
87
+ }
88
+ // First, deliver any pending chunks one at a time
89
+ if (pendingChunks.length > 0) {
90
+ controller.enqueue(pendingChunks.shift());
91
+ return;
92
+ }
93
+ try {
94
+ const { done, value } = await reader.read();
95
+ if (done) {
96
+ // Send text-end and finish chunks before closing
97
+ if (hasStarted && messageId) {
98
+ if (textStarted && textPartId) {
99
+ pendingChunks.push({
100
+ type: "text-end",
101
+ id: textPartId,
102
+ });
103
+ }
104
+ pendingChunks.push({
105
+ type: "finish",
106
+ finishReason: "stop",
107
+ });
108
+ // Enqueue pending chunks before closing
109
+ while (pendingChunks.length > 0) {
110
+ controller.enqueue(pendingChunks.shift());
111
+ }
112
+ }
113
+ if (!isClosed) {
114
+ isClosed = true;
115
+ controller.close();
116
+ }
117
+ return;
118
+ }
119
+ buffer += decoder.decode(value, { stream: true });
120
+ const lines = buffer.split("\n");
121
+ buffer = lines.pop() || "";
122
+ for (const line of lines) {
123
+ const trimmedLine = line.trim();
124
+ if (!trimmedLine)
125
+ continue;
126
+ if (trimmedLine.startsWith("data:")) {
127
+ const data = trimmedLine.slice(5).trim();
128
+ if (!data)
129
+ continue;
130
+ try {
131
+ const parsed = JSON.parse(data);
132
+ if (isClosed) {
133
+ return;
134
+ }
135
+ // Track message ID and send start chunk once
136
+ if (parsed.id && !messageId) {
137
+ messageId = parsed.id;
138
+ hasStarted = true;
139
+ pendingChunks.push({
140
+ type: "start",
141
+ });
142
+ }
143
+ let chunk = null;
144
+ if (parsed.type === "ai") {
145
+ const message = (_a = parsed.messages) === null || _a === void 0 ? void 0 : _a[0];
146
+ if (message === null || message === void 0 ? void 0 : message.content) {
147
+ // Generate text part ID once
148
+ if (!textPartId) {
149
+ textPartId = uuidv4();
150
+ }
151
+ // Send text-start before first delta
152
+ if (!textStarted) {
153
+ textStarted = true;
154
+ pendingChunks.push({
155
+ type: "text-start",
156
+ id: textPartId,
157
+ });
158
+ }
159
+ chunk = {
160
+ type: "text-delta",
161
+ delta: message.content,
162
+ id: textPartId,
163
+ };
164
+ }
165
+ }
166
+ else if (parsed.type === "tool") {
167
+ const toolCall = parsed.toolCall;
168
+ if (toolCall) {
169
+ chunk = {
170
+ type: "tool-input-available",
171
+ toolCallId: toolCall.callId,
172
+ toolName: toolCall.name,
173
+ input: toolCall.result,
174
+ };
175
+ }
176
+ }
177
+ if (chunk) {
178
+ pendingChunks.push(chunk);
179
+ }
180
+ }
181
+ catch (e) {
182
+ // Ignore parse errors
183
+ }
184
+ }
185
+ }
186
+ // Enqueue the first chunk if we have any
187
+ if (pendingChunks.length > 0) {
188
+ controller.enqueue(pendingChunks.shift());
189
+ }
190
+ }
191
+ catch (error) {
192
+ if (!isClosed) {
193
+ isClosed = true;
194
+ controller.error(error);
195
+ }
196
+ }
197
+ },
198
+ cancel() {
199
+ isClosed = true;
200
+ pendingChunks = [];
201
+ if (reader) {
202
+ reader.releaseLock();
203
+ reader = null;
204
+ }
205
+ },
206
+ });
207
+ }
208
+ }
@@ -0,0 +1,4 @@
1
+ import { type FC } from "react";
2
+ export declare const UserMessageAttachments: FC;
3
+ export declare const ComposerAttachments: FC;
4
+ export declare const ComposerAddAttachment: FC;