@libreapps/react 1.1.1

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/index.mjs ADDED
@@ -0,0 +1,539 @@
1
+ import { createContext, useState, useEffect, useCallback, useMemo, useContext, useRef } from 'react';
2
+ import { nanoid } from 'nanoid';
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { clsx } from 'clsx';
5
+ import { twMerge } from 'tailwind-merge';
6
+
7
+ // src/components/LibreAppsProvider.tsx
8
+ var LibreAppsContext = createContext(void 0);
9
+ function LibreAppsProvider({
10
+ children,
11
+ apiKey,
12
+ apiUrl = "https://api.libreapps.com/v1",
13
+ model = "gpt-4-turbo-preview",
14
+ components: initialComponents = [],
15
+ tools: initialTools = [],
16
+ initialMessages = [],
17
+ onMessage,
18
+ onError,
19
+ enableStreaming = true,
20
+ // @ts-expect-error - MCP integration coming soon
21
+ enableMCP = false,
22
+ // eslint-disable-line @typescript-eslint/no-unused-vars
23
+ // @ts-expect-error - MCP server support coming soon
24
+ mcpServers = []
25
+ // eslint-disable-line @typescript-eslint/no-unused-vars
26
+ }) {
27
+ const [components] = useState(() => new Map(initialComponents.map((c) => [c.name, c])));
28
+ const [tools] = useState(() => new Map(initialTools.map((t) => [t.name, t])));
29
+ const [threads, setThreads] = useState(/* @__PURE__ */ new Map());
30
+ const [activeThreadId, setActiveThreadId] = useState();
31
+ const [isStreaming, setIsStreaming] = useState(false);
32
+ const [responseStage, setResponseStage] = useState();
33
+ const [error, setError] = useState();
34
+ useEffect(() => {
35
+ const defaultThread = createThread({ name: "default" });
36
+ if (initialMessages.length > 0) {
37
+ defaultThread.messages = initialMessages;
38
+ }
39
+ setActiveThreadId(defaultThread.id);
40
+ }, []);
41
+ const createThread = useCallback((metadata) => {
42
+ const thread = {
43
+ id: nanoid(),
44
+ messages: [],
45
+ createdAt: /* @__PURE__ */ new Date(),
46
+ updatedAt: /* @__PURE__ */ new Date(),
47
+ metadata
48
+ };
49
+ setThreads((prev) => new Map(prev).set(thread.id, thread));
50
+ return thread;
51
+ }, []);
52
+ const switchThread = useCallback((threadId) => {
53
+ if (threads.has(threadId)) {
54
+ setActiveThreadId(threadId);
55
+ } else {
56
+ throw new Error(`Thread ${threadId} not found`);
57
+ }
58
+ }, [threads]);
59
+ const deleteThread = useCallback((threadId) => {
60
+ setThreads((prev) => {
61
+ const next = new Map(prev);
62
+ next.delete(threadId);
63
+ return next;
64
+ });
65
+ if (activeThreadId === threadId) {
66
+ const remainingThreads = Array.from(threads.keys()).filter((id) => id !== threadId);
67
+ setActiveThreadId(remainingThreads[0]);
68
+ }
69
+ }, [activeThreadId, threads]);
70
+ const sendMessage = useCallback(async (content, threadId) => {
71
+ const targetThreadId = threadId || activeThreadId;
72
+ if (!targetThreadId) {
73
+ throw new Error("No active thread");
74
+ }
75
+ const thread = threads.get(targetThreadId);
76
+ if (!thread) {
77
+ throw new Error(`Thread ${targetThreadId} not found`);
78
+ }
79
+ const userMessage = {
80
+ id: nanoid(),
81
+ role: "user",
82
+ content,
83
+ timestamp: /* @__PURE__ */ new Date(),
84
+ threadId: targetThreadId
85
+ };
86
+ thread.messages.push(userMessage);
87
+ thread.updatedAt = /* @__PURE__ */ new Date();
88
+ setThreads(new Map(threads));
89
+ onMessage?.(userMessage);
90
+ setIsStreaming(true);
91
+ setResponseStage("thinking");
92
+ try {
93
+ const response = await fetch(`${apiUrl}/chat/completions`, {
94
+ method: "POST",
95
+ headers: {
96
+ "Content-Type": "application/json",
97
+ "Authorization": `Bearer ${apiKey}`
98
+ },
99
+ body: JSON.stringify({
100
+ model,
101
+ messages: thread.messages.map((m) => ({
102
+ role: m.role,
103
+ content: typeof m.content === "string" ? m.content : "Component rendered"
104
+ })),
105
+ tools: Array.from(tools.values()).map((t) => ({
106
+ type: "function",
107
+ function: {
108
+ name: t.name,
109
+ description: t.description,
110
+ parameters: t.parameters
111
+ }
112
+ })),
113
+ stream: enableStreaming
114
+ })
115
+ });
116
+ if (!response.ok) {
117
+ throw new Error(`API error: ${response.statusText}`);
118
+ }
119
+ setResponseStage("generating");
120
+ const data = await response.json();
121
+ const assistantMessage = {
122
+ id: nanoid(),
123
+ role: "assistant",
124
+ content: data.choices[0].message.content,
125
+ timestamp: /* @__PURE__ */ new Date(),
126
+ threadId: targetThreadId
127
+ };
128
+ if (data.choices[0].message.tool_calls) {
129
+ setResponseStage("tool-calling");
130
+ assistantMessage.toolCalls = await Promise.all(
131
+ data.choices[0].message.tool_calls.map(async (call) => {
132
+ const tool = tools.get(call.function.name);
133
+ if (!tool) {
134
+ return {
135
+ id: call.id,
136
+ name: call.function.name,
137
+ arguments: call.function.arguments,
138
+ status: "failed",
139
+ result: `Tool ${call.function.name} not found`
140
+ };
141
+ }
142
+ try {
143
+ const result = await tool.execute(JSON.parse(call.function.arguments));
144
+ return {
145
+ id: call.id,
146
+ name: call.function.name,
147
+ arguments: call.function.arguments,
148
+ status: "completed",
149
+ result
150
+ };
151
+ } catch (error2) {
152
+ return {
153
+ id: call.id,
154
+ name: call.function.name,
155
+ arguments: call.function.arguments,
156
+ status: "failed",
157
+ result: error2 instanceof Error ? error2.message : "Unknown error"
158
+ };
159
+ }
160
+ })
161
+ );
162
+ }
163
+ thread.messages.push(assistantMessage);
164
+ thread.updatedAt = /* @__PURE__ */ new Date();
165
+ setThreads(new Map(threads));
166
+ onMessage?.(assistantMessage);
167
+ setResponseStage("completed");
168
+ return assistantMessage;
169
+ } catch (err) {
170
+ const error2 = err instanceof Error ? err : new Error("Unknown error");
171
+ setError(error2);
172
+ onError?.(error2);
173
+ throw error2;
174
+ } finally {
175
+ setIsStreaming(false);
176
+ setResponseStage(void 0);
177
+ }
178
+ }, [apiKey, apiUrl, model, activeThreadId, threads, tools, onMessage, onError, enableStreaming]);
179
+ const streamMessage = useCallback(async function* (content, threadId) {
180
+ const targetThreadId = threadId || activeThreadId;
181
+ if (!targetThreadId) {
182
+ throw new Error("No active thread");
183
+ }
184
+ const thread = threads.get(targetThreadId);
185
+ if (!thread) {
186
+ throw new Error(`Thread ${targetThreadId} not found`);
187
+ }
188
+ const userMessage = {
189
+ id: nanoid(),
190
+ role: "user",
191
+ content,
192
+ timestamp: /* @__PURE__ */ new Date(),
193
+ threadId: targetThreadId
194
+ };
195
+ thread.messages.push(userMessage);
196
+ yield userMessage;
197
+ setIsStreaming(true);
198
+ setResponseStage("thinking");
199
+ try {
200
+ const response = await fetch(`${apiUrl}/chat/completions`, {
201
+ method: "POST",
202
+ headers: {
203
+ "Content-Type": "application/json",
204
+ "Authorization": `Bearer ${apiKey}`
205
+ },
206
+ body: JSON.stringify({
207
+ model,
208
+ messages: thread.messages.map((m) => ({
209
+ role: m.role,
210
+ content: typeof m.content === "string" ? m.content : "Component rendered"
211
+ })),
212
+ stream: true
213
+ })
214
+ });
215
+ if (!response.ok) {
216
+ throw new Error(`API error: ${response.statusText}`);
217
+ }
218
+ setResponseStage("generating");
219
+ const reader = response.body?.getReader();
220
+ if (!reader) {
221
+ throw new Error("No response body");
222
+ }
223
+ const decoder = new TextDecoder();
224
+ let assistantMessage = {
225
+ id: nanoid(),
226
+ role: "assistant",
227
+ content: "",
228
+ timestamp: /* @__PURE__ */ new Date(),
229
+ threadId: targetThreadId
230
+ };
231
+ while (true) {
232
+ const { done, value } = await reader.read();
233
+ if (done) break;
234
+ const chunk = decoder.decode(value);
235
+ const lines = chunk.split("\n").filter((line) => line.trim() !== "");
236
+ for (const line of lines) {
237
+ if (line.startsWith("data: ")) {
238
+ const data = line.slice(6);
239
+ if (data === "[DONE]") continue;
240
+ try {
241
+ const parsed = JSON.parse(data);
242
+ if (parsed.choices?.[0]?.delta?.content) {
243
+ assistantMessage.content += parsed.choices[0].delta.content;
244
+ yield { ...assistantMessage };
245
+ }
246
+ } catch (e) {
247
+ console.error("Error parsing SSE data:", e);
248
+ }
249
+ }
250
+ }
251
+ }
252
+ thread.messages.push(assistantMessage);
253
+ thread.updatedAt = /* @__PURE__ */ new Date();
254
+ setThreads(new Map(threads));
255
+ setResponseStage("completed");
256
+ } finally {
257
+ setIsStreaming(false);
258
+ setResponseStage(void 0);
259
+ }
260
+ }, [apiKey, apiUrl, model, activeThreadId, threads]);
261
+ const registerComponent = useCallback((component) => {
262
+ components.set(component.name, component);
263
+ }, [components]);
264
+ const unregisterComponent = useCallback((name) => {
265
+ components.delete(name);
266
+ }, [components]);
267
+ const renderComponent = useCallback((name, props) => {
268
+ const component = components.get(name);
269
+ if (!component) return null;
270
+ if (component.generateUI) {
271
+ return component.generateUI(props);
272
+ }
273
+ const Component = component.component;
274
+ return /* @__PURE__ */ jsx(Component, { ...props });
275
+ }, [components]);
276
+ const registerTool = useCallback((tool) => {
277
+ tools.set(tool.name, tool);
278
+ }, [tools]);
279
+ const unregisterTool = useCallback((name) => {
280
+ tools.delete(name);
281
+ }, [tools]);
282
+ const executeTool = useCallback(async (name, params) => {
283
+ const tool = tools.get(name);
284
+ if (!tool) {
285
+ throw new Error(`Tool ${name} not found`);
286
+ }
287
+ return tool.execute(params);
288
+ }, [tools]);
289
+ const contextValue = useMemo(() => ({
290
+ apiKey,
291
+ apiUrl,
292
+ model,
293
+ components,
294
+ tools,
295
+ threads,
296
+ activeThreadId,
297
+ sendMessage,
298
+ streamMessage,
299
+ createThread,
300
+ switchThread,
301
+ deleteThread,
302
+ registerComponent,
303
+ unregisterComponent,
304
+ renderComponent,
305
+ registerTool,
306
+ unregisterTool,
307
+ executeTool,
308
+ isStreaming,
309
+ responseStage,
310
+ error
311
+ }), [
312
+ apiKey,
313
+ apiUrl,
314
+ model,
315
+ components,
316
+ tools,
317
+ threads,
318
+ activeThreadId,
319
+ sendMessage,
320
+ streamMessage,
321
+ createThread,
322
+ switchThread,
323
+ deleteThread,
324
+ registerComponent,
325
+ unregisterComponent,
326
+ renderComponent,
327
+ registerTool,
328
+ unregisterTool,
329
+ executeTool,
330
+ isStreaming,
331
+ responseStage,
332
+ error
333
+ ]);
334
+ return /* @__PURE__ */ jsx(LibreAppsContext.Provider, { value: contextValue, children });
335
+ }
336
+ function useLibreApps() {
337
+ const context = useContext(LibreAppsContext);
338
+ if (!context) {
339
+ throw new Error("useLibreApps must be used within LibreAppsProvider");
340
+ }
341
+ return context;
342
+ }
343
+ function useMessage(options = {}) {
344
+ const {
345
+ threadId,
346
+ onSuccess,
347
+ onError,
348
+ autoRetry = false,
349
+ maxRetries = 3,
350
+ retryDelay = 1e3
351
+ } = options;
352
+ const { sendMessage: sendToAPI, activeThreadId } = useLibreApps();
353
+ const [isLoading, setIsLoading] = useState(false);
354
+ const [error, setError] = useState(null);
355
+ const [lastMessage, setLastMessage] = useState(null);
356
+ const lastContentRef = useRef("");
357
+ const retryCountRef = useRef(0);
358
+ const sendMessage = useCallback(async (content) => {
359
+ setIsLoading(true);
360
+ setError(null);
361
+ lastContentRef.current = content;
362
+ retryCountRef.current = 0;
363
+ try {
364
+ const targetThread = threadId || activeThreadId;
365
+ if (!targetThread) {
366
+ throw new Error("No thread available");
367
+ }
368
+ const message = await sendToAPI(content, targetThread);
369
+ setLastMessage(message);
370
+ onSuccess?.(message);
371
+ return message;
372
+ } catch (err) {
373
+ const error2 = err instanceof Error ? err : new Error("Failed to send message");
374
+ setError(error2);
375
+ onError?.(error2);
376
+ if (autoRetry && retryCountRef.current < maxRetries) {
377
+ retryCountRef.current++;
378
+ setTimeout(() => retry(), retryDelay * retryCountRef.current);
379
+ }
380
+ throw error2;
381
+ } finally {
382
+ setIsLoading(false);
383
+ }
384
+ }, [sendToAPI, threadId, activeThreadId, onSuccess, onError, autoRetry, maxRetries, retryDelay]);
385
+ const sendMessageWithAttachments = useCallback(async (content, attachments) => {
386
+ const attachmentInfo = attachments.map((f) => `[Attached: ${f.name}]`).join(" ");
387
+ const enrichedContent = `${content}
388
+ ${attachmentInfo}`;
389
+ return sendMessage(enrichedContent);
390
+ }, [sendMessage]);
391
+ const clearError = useCallback(() => {
392
+ setError(null);
393
+ }, []);
394
+ const retry = useCallback(async () => {
395
+ if (lastContentRef.current) {
396
+ await sendMessage(lastContentRef.current);
397
+ }
398
+ }, [sendMessage]);
399
+ return {
400
+ sendMessage,
401
+ sendMessageWithAttachments,
402
+ isLoading,
403
+ error,
404
+ lastMessage,
405
+ clearError,
406
+ retry
407
+ };
408
+ }
409
+ function useStreaming(options = {}) {
410
+ const {
411
+ threadId,
412
+ onChunk,
413
+ onComplete,
414
+ onError,
415
+ bufferSize = 1,
416
+ throttleMs = 0
417
+ } = options;
418
+ const { streamMessage: streamFromAPI, activeThreadId, isStreaming: globalStreaming } = useLibreApps();
419
+ const [isStreaming, setIsStreaming] = useState(false);
420
+ const [currentMessage, setCurrentMessage] = useState("");
421
+ const [error, setError] = useState(null);
422
+ const [progress, setProgress] = useState(0);
423
+ const abortControllerRef = useRef(null);
424
+ const bufferRef = useRef([]);
425
+ const lastUpdateRef = useRef(Date.now());
426
+ const streamMessage = useCallback(async (content) => {
427
+ setIsStreaming(true);
428
+ setError(null);
429
+ setCurrentMessage("");
430
+ setProgress(0);
431
+ bufferRef.current = [];
432
+ abortControllerRef.current = new AbortController();
433
+ try {
434
+ const targetThread = threadId || activeThreadId;
435
+ if (!targetThread) {
436
+ throw new Error("No thread available");
437
+ }
438
+ const stream = streamFromAPI(content, targetThread);
439
+ let totalChunks = 0;
440
+ let estimatedTotal = 100;
441
+ for await (const message of stream) {
442
+ if (abortControllerRef.current?.signal.aborted) {
443
+ break;
444
+ }
445
+ totalChunks++;
446
+ const chunk = typeof message.content === "string" ? message.content : "";
447
+ bufferRef.current.push(chunk);
448
+ const now = Date.now();
449
+ const shouldUpdate = bufferRef.current.length >= bufferSize || throttleMs > 0 && now - lastUpdateRef.current >= throttleMs;
450
+ if (shouldUpdate) {
451
+ const bufferedContent = bufferRef.current.join("");
452
+ setCurrentMessage((prev) => prev + bufferedContent);
453
+ onChunk?.(bufferedContent);
454
+ bufferRef.current = [];
455
+ lastUpdateRef.current = now;
456
+ }
457
+ const estimatedProgress = Math.min(95, totalChunks / estimatedTotal * 100);
458
+ setProgress(estimatedProgress);
459
+ if (totalChunks > 10 && totalChunks % 10 === 0) {
460
+ estimatedTotal = Math.max(estimatedTotal, totalChunks * 1.5);
461
+ }
462
+ }
463
+ if (bufferRef.current.length > 0) {
464
+ const remainingContent = bufferRef.current.join("");
465
+ setCurrentMessage((prev) => prev + remainingContent);
466
+ onChunk?.(remainingContent);
467
+ bufferRef.current = [];
468
+ }
469
+ setProgress(100);
470
+ const completeMessage = {
471
+ id: `stream-${Date.now()}`,
472
+ role: "assistant",
473
+ content: currentMessage,
474
+ timestamp: /* @__PURE__ */ new Date(),
475
+ threadId: targetThread
476
+ };
477
+ onComplete?.(completeMessage);
478
+ } catch (err) {
479
+ const error2 = err instanceof Error ? err : new Error("Streaming failed");
480
+ setError(error2);
481
+ onError?.(error2);
482
+ } finally {
483
+ setIsStreaming(false);
484
+ abortControllerRef.current = null;
485
+ }
486
+ }, [streamFromAPI, threadId, activeThreadId, onChunk, onComplete, onError, bufferSize, throttleMs, currentMessage]);
487
+ const stopStreaming = useCallback(() => {
488
+ if (abortControllerRef.current) {
489
+ abortControllerRef.current.abort();
490
+ setIsStreaming(false);
491
+ }
492
+ }, []);
493
+ const clearMessage = useCallback(() => {
494
+ setCurrentMessage("");
495
+ setProgress(0);
496
+ }, []);
497
+ useEffect(() => {
498
+ if (!globalStreaming && isStreaming) {
499
+ setIsStreaming(false);
500
+ }
501
+ }, [globalStreaming, isStreaming]);
502
+ return {
503
+ streamMessage,
504
+ isStreaming,
505
+ currentMessage,
506
+ error,
507
+ stopStreaming,
508
+ clearMessage,
509
+ progress
510
+ };
511
+ }
512
+ function cn(...inputs) {
513
+ return twMerge(clsx(inputs));
514
+ }
515
+ function generateId(prefix) {
516
+ const id = nanoid();
517
+ return prefix ? `${prefix}-${id}` : id;
518
+ }
519
+
520
+ // src/utils/stream.ts
521
+ async function parseStream(stream) {
522
+ const reader = stream.getReader();
523
+ const decoder = new TextDecoder();
524
+ const chunks = [];
525
+ while (true) {
526
+ const { done, value } = await reader.read();
527
+ if (done) break;
528
+ const chunk = decoder.decode(value);
529
+ chunks.push(chunk);
530
+ }
531
+ return chunks.join("");
532
+ }
533
+
534
+ // src/index.ts
535
+ var VERSION = "1.0.0";
536
+
537
+ export { LibreAppsProvider, VERSION, cn, generateId, parseStream, useLibreApps, useMessage, useStreaming };
538
+ //# sourceMappingURL=index.mjs.map
539
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/LibreAppsProvider.tsx","../src/hooks/useMessage.ts","../src/hooks/useStreaming.ts","../src/utils/cn.ts","../src/utils/id.ts","../src/utils/stream.ts","../src/index.ts"],"names":["error","useState","useCallback","useRef","useEffect","nanoid"],"mappings":"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","file":"index.mjs","sourcesContent":["\"use client\"\n\nimport React, { createContext, useContext, useCallback, useEffect, useMemo, useState } from 'react'\nimport { nanoid } from 'nanoid'\nimport { z } from 'zod'\n\n// Types\nexport interface LibreAppsComponent {\n name: string\n component: React.ComponentType<any>\n description?: string\n parameters?: z.ZodType<any>\n generateUI?: (params: any) => React.ReactElement\n}\n\nexport interface LibreAppsTool {\n name: string\n description: string\n parameters: z.ZodType<any>\n execute: (params: any) => Promise<any>\n}\n\nexport interface Message {\n id: string\n role: 'user' | 'assistant' | 'system' | 'tool'\n content: string | React.ReactElement\n timestamp: Date\n threadId: string\n toolCalls?: ToolCall[]\n metadata?: Record<string, any>\n}\n\nexport interface ToolCall {\n id: string\n name: string\n arguments: any\n result?: any\n status: 'pending' | 'running' | 'completed' | 'failed'\n}\n\nexport interface Thread {\n id: string\n messages: Message[]\n createdAt: Date\n updatedAt: Date\n metadata?: Record<string, any>\n}\n\nexport interface LibreAppsContextValue {\n // Configuration\n apiKey?: string\n apiUrl?: string\n model?: string\n \n // Components & Tools\n components: Map<string, LibreAppsComponent>\n tools: Map<string, LibreAppsTool>\n \n // Thread Management\n threads: Map<string, Thread>\n activeThreadId?: string\n \n // Message Operations\n sendMessage: (content: string, threadId?: string) => Promise<Message>\n streamMessage: (content: string, threadId?: string) => AsyncGenerator<Message>\n \n // Thread Operations\n createThread: (metadata?: Record<string, any>) => Thread\n switchThread: (threadId: string) => void\n deleteThread: (threadId: string) => void\n \n // Component Operations\n registerComponent: (component: LibreAppsComponent) => void\n unregisterComponent: (name: string) => void\n renderComponent: (name: string, props: any) => React.ReactElement | null\n \n // Tool Operations\n registerTool: (tool: LibreAppsTool) => void\n unregisterTool: (name: string) => void\n executeTool: (name: string, params: any) => Promise<any>\n \n // State Management\n isStreaming: boolean\n responseStage?: 'thinking' | 'generating' | 'tool-calling' | 'completed'\n error?: Error\n}\n\nconst LibreAppsContext = createContext<LibreAppsContextValue | undefined>(undefined)\n\nexport interface LibreAppsProviderProps {\n children: React.ReactNode\n apiKey?: string\n apiUrl?: string\n model?: string\n components?: LibreAppsComponent[]\n tools?: LibreAppsTool[]\n initialMessages?: Message[]\n onMessage?: (message: Message) => void\n onError?: (error: Error) => void\n enableStreaming?: boolean\n enableMCP?: boolean\n mcpServers?: string[]\n}\n\nexport function LibreAppsProvider({\n children,\n apiKey,\n apiUrl = 'https://api.libreapps.com/v1',\n model = 'gpt-4-turbo-preview',\n components: initialComponents = [],\n tools: initialTools = [],\n initialMessages = [],\n onMessage,\n onError,\n enableStreaming = true,\n // @ts-expect-error - MCP integration coming soon\n enableMCP = false, // eslint-disable-line @typescript-eslint/no-unused-vars\n // @ts-expect-error - MCP server support coming soon\n mcpServers = [] // eslint-disable-line @typescript-eslint/no-unused-vars\n}: LibreAppsProviderProps) {\n // State\n const [components] = useState(() => new Map(initialComponents.map(c => [c.name, c])))\n const [tools] = useState(() => new Map(initialTools.map(t => [t.name, t])))\n const [threads, setThreads] = useState<Map<string, Thread>>(new Map())\n const [activeThreadId, setActiveThreadId] = useState<string>()\n const [isStreaming, setIsStreaming] = useState(false)\n const [responseStage, setResponseStage] = useState<LibreAppsContextValue['responseStage']>()\n const [error, setError] = useState<Error>()\n \n // Initialize default thread\n useEffect(() => {\n const defaultThread = createThread({ name: 'default' })\n if (initialMessages.length > 0) {\n defaultThread.messages = initialMessages\n }\n setActiveThreadId(defaultThread.id)\n }, [])\n \n // Thread Operations\n const createThread = useCallback((metadata?: Record<string, any>): Thread => {\n const thread: Thread = {\n id: nanoid(),\n messages: [],\n createdAt: new Date(),\n updatedAt: new Date(),\n metadata\n }\n setThreads(prev => new Map(prev).set(thread.id, thread))\n return thread\n }, [])\n \n const switchThread = useCallback((threadId: string) => {\n if (threads.has(threadId)) {\n setActiveThreadId(threadId)\n } else {\n throw new Error(`Thread ${threadId} not found`)\n }\n }, [threads])\n \n const deleteThread = useCallback((threadId: string) => {\n setThreads(prev => {\n const next = new Map(prev)\n next.delete(threadId)\n return next\n })\n if (activeThreadId === threadId) {\n const remainingThreads = Array.from(threads.keys()).filter(id => id !== threadId)\n setActiveThreadId(remainingThreads[0])\n }\n }, [activeThreadId, threads])\n \n // Message Operations\n const sendMessage = useCallback(async (content: string, threadId?: string): Promise<Message> => {\n const targetThreadId = threadId || activeThreadId\n if (!targetThreadId) {\n throw new Error('No active thread')\n }\n \n const thread = threads.get(targetThreadId)\n if (!thread) {\n throw new Error(`Thread ${targetThreadId} not found`)\n }\n \n // Create user message\n const userMessage: Message = {\n id: nanoid(),\n role: 'user',\n content,\n timestamp: new Date(),\n threadId: targetThreadId\n }\n \n // Add to thread\n thread.messages.push(userMessage)\n thread.updatedAt = new Date()\n setThreads(new Map(threads))\n \n // Notify callback\n onMessage?.(userMessage)\n \n // Send to API\n setIsStreaming(true)\n setResponseStage('thinking')\n \n try {\n const response = await fetch(`${apiUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`\n },\n body: JSON.stringify({\n model,\n messages: thread.messages.map(m => ({\n role: m.role,\n content: typeof m.content === 'string' ? m.content : 'Component rendered'\n })),\n tools: Array.from(tools.values()).map(t => ({\n type: 'function',\n function: {\n name: t.name,\n description: t.description,\n parameters: t.parameters\n }\n })),\n stream: enableStreaming\n })\n })\n \n if (!response.ok) {\n throw new Error(`API error: ${response.statusText}`)\n }\n \n setResponseStage('generating')\n \n // Handle response\n const data = await response.json()\n const assistantMessage: Message = {\n id: nanoid(),\n role: 'assistant',\n content: data.choices[0].message.content,\n timestamp: new Date(),\n threadId: targetThreadId\n }\n \n // Handle tool calls\n if (data.choices[0].message.tool_calls) {\n setResponseStage('tool-calling')\n assistantMessage.toolCalls = await Promise.all(\n data.choices[0].message.tool_calls.map(async (call: any) => {\n const tool = tools.get(call.function.name)\n if (!tool) {\n return {\n id: call.id,\n name: call.function.name,\n arguments: call.function.arguments,\n status: 'failed',\n result: `Tool ${call.function.name} not found`\n }\n }\n \n try {\n const result = await tool.execute(JSON.parse(call.function.arguments))\n return {\n id: call.id,\n name: call.function.name,\n arguments: call.function.arguments,\n status: 'completed',\n result\n }\n } catch (error) {\n return {\n id: call.id,\n name: call.function.name,\n arguments: call.function.arguments,\n status: 'failed',\n result: error instanceof Error ? error.message : 'Unknown error'\n }\n }\n })\n )\n }\n \n // Add assistant message\n thread.messages.push(assistantMessage)\n thread.updatedAt = new Date()\n setThreads(new Map(threads))\n \n // Notify callback\n onMessage?.(assistantMessage)\n \n setResponseStage('completed')\n return assistantMessage\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Unknown error')\n setError(error)\n onError?.(error)\n throw error\n } finally {\n setIsStreaming(false)\n setResponseStage(undefined)\n }\n }, [apiKey, apiUrl, model, activeThreadId, threads, tools, onMessage, onError, enableStreaming])\n \n // Streaming Message Operation\n const streamMessage = useCallback(async function* (\n content: string, \n threadId?: string\n ): AsyncGenerator<Message> {\n const targetThreadId = threadId || activeThreadId\n if (!targetThreadId) {\n throw new Error('No active thread')\n }\n \n const thread = threads.get(targetThreadId)\n if (!thread) {\n throw new Error(`Thread ${targetThreadId} not found`)\n }\n \n // Create user message\n const userMessage: Message = {\n id: nanoid(),\n role: 'user',\n content,\n timestamp: new Date(),\n threadId: targetThreadId\n }\n \n thread.messages.push(userMessage)\n yield userMessage\n \n // Stream from API\n setIsStreaming(true)\n setResponseStage('thinking')\n \n try {\n const response = await fetch(`${apiUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`\n },\n body: JSON.stringify({\n model,\n messages: thread.messages.map(m => ({\n role: m.role,\n content: typeof m.content === 'string' ? m.content : 'Component rendered'\n })),\n stream: true\n })\n })\n \n if (!response.ok) {\n throw new Error(`API error: ${response.statusText}`)\n }\n \n setResponseStage('generating')\n \n const reader = response.body?.getReader()\n if (!reader) {\n throw new Error('No response body')\n }\n \n const decoder = new TextDecoder()\n let assistantMessage: Message = {\n id: nanoid(),\n role: 'assistant',\n content: '',\n timestamp: new Date(),\n threadId: targetThreadId\n }\n \n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n \n const chunk = decoder.decode(value)\n const lines = chunk.split('\\n').filter(line => line.trim() !== '')\n \n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6)\n if (data === '[DONE]') continue\n \n try {\n const parsed = JSON.parse(data)\n if (parsed.choices?.[0]?.delta?.content) {\n assistantMessage.content += parsed.choices[0].delta.content\n yield { ...assistantMessage }\n }\n } catch (e) {\n console.error('Error parsing SSE data:', e)\n }\n }\n }\n }\n \n thread.messages.push(assistantMessage)\n thread.updatedAt = new Date()\n setThreads(new Map(threads))\n \n setResponseStage('completed')\n } finally {\n setIsStreaming(false)\n setResponseStage(undefined)\n }\n }, [apiKey, apiUrl, model, activeThreadId, threads])\n \n // Component Operations\n const registerComponent = useCallback((component: LibreAppsComponent) => {\n components.set(component.name, component)\n }, [components])\n \n const unregisterComponent = useCallback((name: string) => {\n components.delete(name)\n }, [components])\n \n const renderComponent = useCallback((name: string, props: any): React.ReactElement | null => {\n const component = components.get(name)\n if (!component) return null\n \n if (component.generateUI) {\n return component.generateUI(props)\n }\n \n const Component = component.component\n return <Component {...props} />\n }, [components])\n \n // Tool Operations\n const registerTool = useCallback((tool: LibreAppsTool) => {\n tools.set(tool.name, tool)\n }, [tools])\n \n const unregisterTool = useCallback((name: string) => {\n tools.delete(name)\n }, [tools])\n \n const executeTool = useCallback(async (name: string, params: any): Promise<any> => {\n const tool = tools.get(name)\n if (!tool) {\n throw new Error(`Tool ${name} not found`)\n }\n return tool.execute(params)\n }, [tools])\n \n // Context value\n const contextValue = useMemo<LibreAppsContextValue>(() => ({\n apiKey,\n apiUrl,\n model,\n components,\n tools,\n threads,\n activeThreadId,\n sendMessage,\n streamMessage,\n createThread,\n switchThread,\n deleteThread,\n registerComponent,\n unregisterComponent,\n renderComponent,\n registerTool,\n unregisterTool,\n executeTool,\n isStreaming,\n responseStage,\n error\n }), [\n apiKey,\n apiUrl,\n model,\n components,\n tools,\n threads,\n activeThreadId,\n sendMessage,\n streamMessage,\n createThread,\n switchThread,\n deleteThread,\n registerComponent,\n unregisterComponent,\n renderComponent,\n registerTool,\n unregisterTool,\n executeTool,\n isStreaming,\n responseStage,\n error\n ])\n \n return (\n <LibreAppsContext.Provider value={contextValue}>\n {children}\n </LibreAppsContext.Provider>\n )\n}\n\n// Hook to use LibreApps context\nexport function useLibreApps() {\n const context = useContext(LibreAppsContext)\n if (!context) {\n throw new Error('useLibreApps must be used within LibreAppsProvider')\n }\n return context\n}","\"use client\"\n\nimport { useState, useCallback, useRef } from 'react'\nimport { useLibreApps } from '../components/LibreAppsProvider'\nimport type { Message } from '../components/LibreAppsProvider'\n\nexport interface UseMessageOptions {\n threadId?: string\n onSuccess?: (message: Message) => void\n onError?: (error: Error) => void\n autoRetry?: boolean\n maxRetries?: number\n retryDelay?: number\n}\n\nexport interface UseMessageReturn {\n sendMessage: (content: string) => Promise<Message>\n sendMessageWithAttachments: (content: string, attachments: File[]) => Promise<Message>\n isLoading: boolean\n error: Error | null\n lastMessage: Message | null\n clearError: () => void\n retry: () => Promise<void>\n}\n\nexport function useMessage(options: UseMessageOptions = {}): UseMessageReturn {\n const {\n threadId,\n onSuccess,\n onError,\n autoRetry = false,\n maxRetries = 3,\n retryDelay = 1000\n } = options\n \n const { sendMessage: sendToAPI, activeThreadId } = useLibreApps()\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n const [lastMessage, setLastMessage] = useState<Message | null>(null)\n const lastContentRef = useRef<string>('')\n const retryCountRef = useRef(0)\n \n const sendMessage = useCallback(async (content: string): Promise<Message> => {\n setIsLoading(true)\n setError(null)\n lastContentRef.current = content\n retryCountRef.current = 0\n \n try {\n const targetThread = threadId || activeThreadId\n if (!targetThread) {\n throw new Error('No thread available')\n }\n \n const message = await sendToAPI(content, targetThread)\n setLastMessage(message)\n onSuccess?.(message)\n return message\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to send message')\n setError(error)\n onError?.(error)\n \n if (autoRetry && retryCountRef.current < maxRetries) {\n retryCountRef.current++\n setTimeout(() => retry(), retryDelay * retryCountRef.current)\n }\n \n throw error\n } finally {\n setIsLoading(false)\n }\n }, [sendToAPI, threadId, activeThreadId, onSuccess, onError, autoRetry, maxRetries, retryDelay])\n \n const sendMessageWithAttachments = useCallback(async (\n content: string, \n attachments: File[]\n ): Promise<Message> => {\n // TODO: Implement file upload and attachment handling\n // For now, we'll just append file names to the content\n const attachmentInfo = attachments.map(f => `[Attached: ${f.name}]`).join(' ')\n const enrichedContent = `${content}\\n${attachmentInfo}`\n return sendMessage(enrichedContent)\n }, [sendMessage])\n \n const clearError = useCallback(() => {\n setError(null)\n }, [])\n \n const retry = useCallback(async () => {\n if (lastContentRef.current) {\n await sendMessage(lastContentRef.current)\n }\n }, [sendMessage])\n \n return {\n sendMessage,\n sendMessageWithAttachments,\n isLoading,\n error,\n lastMessage,\n clearError,\n retry\n }\n}","\"use client\"\n\nimport { useState, useCallback, useRef, useEffect } from 'react'\nimport { useLibreApps } from '../components/LibreAppsProvider'\nimport type { Message } from '../components/LibreAppsProvider'\n\nexport interface UseStreamingOptions {\n threadId?: string\n onChunk?: (chunk: string) => void\n onComplete?: (message: Message) => void\n onError?: (error: Error) => void\n bufferSize?: number\n throttleMs?: number\n}\n\nexport interface UseStreamingReturn {\n streamMessage: (content: string) => Promise<void>\n isStreaming: boolean\n currentMessage: string\n error: Error | null\n stopStreaming: () => void\n clearMessage: () => void\n progress: number // 0-100\n}\n\nexport function useStreaming(options: UseStreamingOptions = {}): UseStreamingReturn {\n const {\n threadId,\n onChunk,\n onComplete,\n onError,\n bufferSize = 1,\n throttleMs = 0\n } = options\n \n const { streamMessage: streamFromAPI, activeThreadId, isStreaming: globalStreaming } = useLibreApps()\n const [isStreaming, setIsStreaming] = useState(false)\n const [currentMessage, setCurrentMessage] = useState('')\n const [error, setError] = useState<Error | null>(null)\n const [progress, setProgress] = useState(0)\n const abortControllerRef = useRef<AbortController | null>(null)\n const bufferRef = useRef<string[]>([])\n const lastUpdateRef = useRef<number>(Date.now())\n \n const streamMessage = useCallback(async (content: string): Promise<void> => {\n setIsStreaming(true)\n setError(null)\n setCurrentMessage('')\n setProgress(0)\n bufferRef.current = []\n \n // Create abort controller\n abortControllerRef.current = new AbortController()\n \n try {\n const targetThread = threadId || activeThreadId\n if (!targetThread) {\n throw new Error('No thread available')\n }\n \n const stream = streamFromAPI(content, targetThread)\n let totalChunks = 0\n let estimatedTotal = 100 // Start with estimate, will adjust\n \n for await (const message of stream) {\n if (abortControllerRef.current?.signal.aborted) {\n break\n }\n \n totalChunks++\n \n // Extract string content from message\n const chunk = typeof message.content === 'string' ? message.content : ''\n \n // Buffer management\n bufferRef.current.push(chunk)\n \n // Throttling\n const now = Date.now()\n const shouldUpdate = (\n bufferRef.current.length >= bufferSize ||\n (throttleMs > 0 && now - lastUpdateRef.current >= throttleMs)\n )\n \n if (shouldUpdate) {\n const bufferedContent = bufferRef.current.join('')\n setCurrentMessage(prev => prev + bufferedContent)\n onChunk?.(bufferedContent)\n bufferRef.current = []\n lastUpdateRef.current = now\n }\n \n // Update progress (estimate based on typical response length)\n const estimatedProgress = Math.min(95, (totalChunks / estimatedTotal) * 100)\n setProgress(estimatedProgress)\n \n // Adjust estimate based on response speed\n if (totalChunks > 10 && totalChunks % 10 === 0) {\n estimatedTotal = Math.max(estimatedTotal, totalChunks * 1.5)\n }\n }\n \n // Flush remaining buffer\n if (bufferRef.current.length > 0) {\n const remainingContent = bufferRef.current.join('')\n setCurrentMessage(prev => prev + remainingContent)\n onChunk?.(remainingContent)\n bufferRef.current = []\n }\n \n setProgress(100)\n \n // Create complete message\n const completeMessage: Message = {\n id: `stream-${Date.now()}`,\n role: 'assistant',\n content: currentMessage,\n timestamp: new Date(),\n threadId: targetThread\n }\n \n onComplete?.(completeMessage)\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Streaming failed')\n setError(error)\n onError?.(error)\n } finally {\n setIsStreaming(false)\n abortControllerRef.current = null\n }\n }, [streamFromAPI, threadId, activeThreadId, onChunk, onComplete, onError, bufferSize, throttleMs, currentMessage])\n \n const stopStreaming = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort()\n setIsStreaming(false)\n }\n }, [])\n \n const clearMessage = useCallback(() => {\n setCurrentMessage('')\n setProgress(0)\n }, [])\n \n // Sync with global streaming state\n useEffect(() => {\n if (!globalStreaming && isStreaming) {\n setIsStreaming(false)\n }\n }, [globalStreaming, isStreaming])\n \n return {\n streamMessage,\n isStreaming,\n currentMessage,\n error,\n stopStreaming,\n clearMessage,\n progress\n }\n}","import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}","import { nanoid } from 'nanoid'\n\nexport function generateId(prefix?: string): string {\n const id = nanoid()\n return prefix ? `${prefix}-${id}` : id\n}","export async function parseStream(stream: ReadableStream<Uint8Array>) {\n const reader = stream.getReader()\n const decoder = new TextDecoder()\n const chunks: string[] = []\n \n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n \n const chunk = decoder.decode(value)\n chunks.push(chunk)\n }\n \n return chunks.join('')\n}\n\nexport function* streamToGenerator<T>(stream: ReadableStream<T>) {\n const reader = stream.getReader()\n \n async function* generator() {\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n yield value\n }\n } finally {\n reader.releaseLock()\n }\n }\n \n return generator()\n}","// @libreapps/react - React package for building AI-powered applications\n// with generative UI and natural language interactions\n\n// Core Provider and Context\nexport { \n LibreAppsProvider, \n useLibreApps,\n type LibreAppsProviderProps,\n type LibreAppsContextValue,\n type LibreAppsComponent,\n type LibreAppsTool,\n type Message,\n type Thread,\n type ToolCall\n} from './components/LibreAppsProvider'\n\n// Hooks\nexport { useMessage, type UseMessageOptions, type UseMessageReturn } from './hooks/useMessage'\nexport { useStreaming, type UseStreamingOptions, type UseStreamingReturn } from './hooks/useStreaming'\n// TODO: Implement the following hooks\n// export { useThread } from './hooks/useThread'\n// export { useComponent } from './hooks/useComponent'\n// export { useTool } from './hooks/useTool'\n// export { useSuggestions } from './hooks/useSuggestions'\n// export { useModelConfig } from './hooks/useModelConfig'\n// export { useMCP } from './hooks/useMCP'\n// export { useGenerativeUI } from './hooks/useGenerativeUI'\n// export { useAuth } from './hooks/useAuth'\n// export { useAttachments } from './hooks/useAttachments'\n\n// Utilities\nexport { cn } from './utils/cn'\nexport { generateId } from './utils/id'\nexport { parseStream } from './utils/stream'\n\n// Types\nexport * from './types'\n\n// Version\nexport const VERSION = '1.0.0'"]}