@miiflow/assistant-ui 0.1.0
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/LICENSE +21 -0
- package/README.md +563 -0
- package/dist/WelcomeScreen-CsFaFNcu.d.mts +246 -0
- package/dist/WelcomeScreen-TrcbOYob.d.ts +246 -0
- package/dist/avatar-D5eHcfjf.d.mts +109 -0
- package/dist/avatar-DftdWqSs.d.ts +109 -0
- package/dist/branding-SzYU4ncD.d.mts +18 -0
- package/dist/branding-SzYU4ncD.d.ts +18 -0
- package/dist/chunk-3E2HG62U.mjs +2 -0
- package/dist/chunk-3E2HG62U.mjs.map +1 -0
- package/dist/chunk-3ERHTQXR.js +2 -0
- package/dist/chunk-3ERHTQXR.js.map +1 -0
- package/dist/chunk-3GQNGDXX.mjs +22 -0
- package/dist/chunk-3GQNGDXX.mjs.map +1 -0
- package/dist/chunk-3KB4JYSQ.js +2 -0
- package/dist/chunk-3KB4JYSQ.js.map +1 -0
- package/dist/chunk-BA3VCHRC.js +22 -0
- package/dist/chunk-BA3VCHRC.js.map +1 -0
- package/dist/chunk-CRNBTU42.mjs +2 -0
- package/dist/chunk-CRNBTU42.mjs.map +1 -0
- package/dist/chunk-KPGHBLGY.mjs +2 -0
- package/dist/chunk-KPGHBLGY.mjs.map +1 -0
- package/dist/chunk-LJQHWCUK.js +2 -0
- package/dist/chunk-LJQHWCUK.js.map +1 -0
- package/dist/chunk-MFCWFFJV.mjs +2 -0
- package/dist/chunk-MFCWFFJV.mjs.map +1 -0
- package/dist/chunk-NSTK5EUQ.js +2 -0
- package/dist/chunk-NSTK5EUQ.js.map +1 -0
- package/dist/chunk-OCKHJ4WO.js +2 -0
- package/dist/chunk-OCKHJ4WO.js.map +1 -0
- package/dist/chunk-RTT6LULU.mjs +2 -0
- package/dist/chunk-RTT6LULU.mjs.map +1 -0
- package/dist/client/index.d.mts +249 -0
- package/dist/client/index.d.ts +249 -0
- package/dist/client/index.js +9 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/index.mjs +9 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/context/index.d.mts +43 -0
- package/dist/context/index.d.ts +43 -0
- package/dist/context/index.js +2 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/index.mjs +2 -0
- package/dist/context/index.mjs.map +1 -0
- package/dist/hooks/index.d.mts +109 -0
- package/dist/hooks/index.d.ts +109 -0
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +2 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/index.d.mts +157 -0
- package/dist/index.d.ts +157 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/dist/message-B21_kqE2.d.ts +78 -0
- package/dist/message-ufYsvKXP.d.mts +78 -0
- package/dist/primitives/index.d.mts +86 -0
- package/dist/primitives/index.d.ts +86 -0
- package/dist/primitives/index.js +2 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/primitives/index.mjs +2 -0
- package/dist/primitives/index.mjs.map +1 -0
- package/dist/streaming-CF63E6iS.d.mts +426 -0
- package/dist/streaming-CF63E6iS.d.ts +426 -0
- package/dist/styled/index.d.mts +477 -0
- package/dist/styled/index.d.ts +477 -0
- package/dist/styled/index.js +2 -0
- package/dist/styled/index.js.map +1 -0
- package/dist/styled/index.mjs +2 -0
- package/dist/styled/index.mjs.map +1 -0
- package/dist/styles-no-preflight.css +1 -0
- package/dist/styles.css +1 -0
- package/package.json +100 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { C as ChatMessage } from '../message-B21_kqE2.js';
|
|
2
|
+
import { B as BrandingData } from '../branding-SzYU4ncD.js';
|
|
3
|
+
import '../streaming-CF63E6iS.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Types for the Miiflow chat client (transport layer).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
interface MiiflowChatConfig {
|
|
10
|
+
/** Public API key for authentication */
|
|
11
|
+
publicKey: string;
|
|
12
|
+
/** Assistant ID to connect to */
|
|
13
|
+
assistantId: string;
|
|
14
|
+
/** Optional user ID for identity */
|
|
15
|
+
userId?: string;
|
|
16
|
+
/** Optional user display name */
|
|
17
|
+
userName?: string;
|
|
18
|
+
/** Optional user email */
|
|
19
|
+
userEmail?: string;
|
|
20
|
+
/** Optional user metadata (JSON string) */
|
|
21
|
+
userMetadata?: string;
|
|
22
|
+
/** HMAC for identity verification */
|
|
23
|
+
hmac?: string;
|
|
24
|
+
/** Timestamp for HMAC verification */
|
|
25
|
+
timestamp?: string;
|
|
26
|
+
/** Override base URL (auto-detected from bundleUrl otherwise) */
|
|
27
|
+
baseUrl?: string;
|
|
28
|
+
/** Bundle URL used for dev detection (internal, set by script embed) */
|
|
29
|
+
bundleUrl?: string;
|
|
30
|
+
/** Response timeout in milliseconds (default: 60000) */
|
|
31
|
+
responseTimeout?: number;
|
|
32
|
+
/** WebSocket URL for bidirectional events (tool invocations). Auto-derived from baseUrl if not set. */
|
|
33
|
+
webSocketUrl?: string;
|
|
34
|
+
/** Fallback for tool invocations not handled locally (multi-widget routing) */
|
|
35
|
+
onToolInvocationFallback?: (invocation: ToolInvocationRequest) => Promise<boolean>;
|
|
36
|
+
/** Callback fired when a user message is created (for widget event emission) */
|
|
37
|
+
onUserMessageCreated?: (message: {
|
|
38
|
+
id: string;
|
|
39
|
+
content: string;
|
|
40
|
+
}) => void;
|
|
41
|
+
/** Callback fired when an assistant message stream completes (for widget event emission) */
|
|
42
|
+
onAssistantMessageComplete?: (message: {
|
|
43
|
+
id: string;
|
|
44
|
+
content: string;
|
|
45
|
+
}) => void;
|
|
46
|
+
}
|
|
47
|
+
interface EmbedSessionBranding {
|
|
48
|
+
show_header?: boolean;
|
|
49
|
+
custom_name?: string;
|
|
50
|
+
welcome_message?: string;
|
|
51
|
+
chatbox_placeholder?: string;
|
|
52
|
+
background_bubble_color?: string;
|
|
53
|
+
header_background_color?: string;
|
|
54
|
+
message_font_size?: number;
|
|
55
|
+
rotating_placeholders?: string[];
|
|
56
|
+
preset_questions?: string[];
|
|
57
|
+
assistant_avatar?: string;
|
|
58
|
+
chatbot_logo?: string;
|
|
59
|
+
}
|
|
60
|
+
interface EmbedSessionConfig {
|
|
61
|
+
assistant_id: string;
|
|
62
|
+
assistant_name: string;
|
|
63
|
+
assistant_description: string;
|
|
64
|
+
thread_id: string;
|
|
65
|
+
branding?: EmbedSessionBranding;
|
|
66
|
+
}
|
|
67
|
+
interface EmbedSession {
|
|
68
|
+
token: string;
|
|
69
|
+
config: EmbedSessionConfig;
|
|
70
|
+
session_id: string;
|
|
71
|
+
}
|
|
72
|
+
interface MiiflowChatResult {
|
|
73
|
+
/** Chat messages in ChatMessage format (directly compatible with ChatProvider) */
|
|
74
|
+
messages: ChatMessage[];
|
|
75
|
+
/** Whether a response is currently streaming */
|
|
76
|
+
isStreaming: boolean;
|
|
77
|
+
/** ID of the message being streamed */
|
|
78
|
+
streamingMessageId: string | null;
|
|
79
|
+
/** Send a message to the assistant, optionally with attachment IDs */
|
|
80
|
+
sendMessage: (content: string, attachmentIds?: string[]) => Promise<void>;
|
|
81
|
+
/** Upload a file and return its attachment ID */
|
|
82
|
+
uploadFile: (file: File) => Promise<string>;
|
|
83
|
+
/** Remove uploaded attachment metadata (call when user removes attachment before sending) */
|
|
84
|
+
removeUploadedAttachment: (attachmentId: string) => void;
|
|
85
|
+
/** Current session data */
|
|
86
|
+
session: EmbedSession | null;
|
|
87
|
+
/** Whether the session is still initializing */
|
|
88
|
+
loading: boolean;
|
|
89
|
+
/** Error message if initialization or sending failed */
|
|
90
|
+
error: string | null;
|
|
91
|
+
/** Branding data from the session, mapped to BrandingData */
|
|
92
|
+
branding: BrandingData | null;
|
|
93
|
+
/** CSS custom properties derived from branding (spread onto container) */
|
|
94
|
+
brandingCSSVars: React.CSSProperties;
|
|
95
|
+
/** Start a new thread, returns the new thread ID */
|
|
96
|
+
startNewThread: () => Promise<string>;
|
|
97
|
+
/** Register a client-side tool */
|
|
98
|
+
registerTool: (tool: ClientToolDefinition) => Promise<void>;
|
|
99
|
+
/** Register multiple client-side tools */
|
|
100
|
+
registerTools: (tools: ClientToolDefinition[]) => Promise<void>;
|
|
101
|
+
/** Send a system event (invisible to chat, processed by assistant) */
|
|
102
|
+
sendSystemEvent: (event: SystemEvent) => Promise<void>;
|
|
103
|
+
/** Execute a client tool invocation (called when backend invokes a registered tool). Returns true if handled. */
|
|
104
|
+
handleToolInvocation: (invocation: ToolInvocationRequest) => Promise<boolean>;
|
|
105
|
+
/** Update the session externally (e.g. after token refresh) */
|
|
106
|
+
updateSession: (session: EmbedSession) => void;
|
|
107
|
+
}
|
|
108
|
+
interface JSONSchemaProperty {
|
|
109
|
+
type: "string" | "number" | "integer" | "boolean" | "array" | "object" | "null";
|
|
110
|
+
description?: string;
|
|
111
|
+
enum?: Array<string | number | boolean>;
|
|
112
|
+
items?: JSONSchemaProperty;
|
|
113
|
+
properties?: Record<string, JSONSchemaProperty>;
|
|
114
|
+
required?: string[];
|
|
115
|
+
default?: unknown;
|
|
116
|
+
}
|
|
117
|
+
interface JSONSchemaObject {
|
|
118
|
+
type: "object";
|
|
119
|
+
properties: Record<string, JSONSchemaProperty>;
|
|
120
|
+
required?: string[];
|
|
121
|
+
additionalProperties?: boolean | JSONSchemaProperty;
|
|
122
|
+
description?: string;
|
|
123
|
+
}
|
|
124
|
+
type ToolHandler = (params: Record<string, unknown>) => Promise<unknown>;
|
|
125
|
+
interface ClientToolDefinition {
|
|
126
|
+
/** Tool name (alphanumeric + underscore, must start with letter/underscore) */
|
|
127
|
+
name: string;
|
|
128
|
+
/** Description of what the tool does (shown to LLM) */
|
|
129
|
+
description: string;
|
|
130
|
+
/** JSON Schema defining the tool's parameters */
|
|
131
|
+
parameters: JSONSchemaObject;
|
|
132
|
+
/** Handler function to execute when LLM calls this tool */
|
|
133
|
+
handler: ToolHandler;
|
|
134
|
+
}
|
|
135
|
+
interface ToolInvocationRequest {
|
|
136
|
+
invocation_id: string;
|
|
137
|
+
tool_name: string;
|
|
138
|
+
parameters: Record<string, unknown>;
|
|
139
|
+
}
|
|
140
|
+
interface ToolExecutionResult {
|
|
141
|
+
invocation_id: string;
|
|
142
|
+
result?: unknown;
|
|
143
|
+
error?: string;
|
|
144
|
+
}
|
|
145
|
+
interface SystemEvent {
|
|
146
|
+
action: string;
|
|
147
|
+
description: string;
|
|
148
|
+
followUpInstruction: string;
|
|
149
|
+
metadata?: Record<string, unknown>;
|
|
150
|
+
}
|
|
151
|
+
type WidgetEventType = "widget_ready" | "widget_opened" | "widget_closed" | "widget_reconnected" | "session_start" | "session_end" | "thread_started" | "new_message" | "message_sent" | "message_received" | "error" | "load_failed" | "assistant_response_timeout";
|
|
152
|
+
type WidgetEventPayload = Record<string, unknown> | undefined;
|
|
153
|
+
type WidgetEventCallback = (type: WidgetEventType, payload?: WidgetEventPayload) => void;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* useMiiflowChat - React hook for connecting to Miiflow's embedded chat API.
|
|
157
|
+
*
|
|
158
|
+
* Handles session init, SSE streaming, message management, tool registration,
|
|
159
|
+
* and branding. Returns a shape directly compatible with ChatProvider props.
|
|
160
|
+
*/
|
|
161
|
+
|
|
162
|
+
declare function useMiiflowChat(config: MiiflowChatConfig): MiiflowChatResult;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Determine the backend base URL from config.
|
|
166
|
+
*/
|
|
167
|
+
declare function getBackendBaseUrl(config: MiiflowChatConfig): string;
|
|
168
|
+
/**
|
|
169
|
+
* Get or create a persistent anonymous user ID stored in localStorage.
|
|
170
|
+
*/
|
|
171
|
+
declare function getOrCreateUserId(): string;
|
|
172
|
+
/**
|
|
173
|
+
* Initialize an embed session by calling the backend init endpoint.
|
|
174
|
+
*/
|
|
175
|
+
declare function initSession(config: MiiflowChatConfig): Promise<EmbedSession>;
|
|
176
|
+
/**
|
|
177
|
+
* Create a new thread for the current session.
|
|
178
|
+
*/
|
|
179
|
+
declare function createThread(config: MiiflowChatConfig, session: EmbedSession): Promise<{
|
|
180
|
+
threadId: string;
|
|
181
|
+
token?: string;
|
|
182
|
+
}>;
|
|
183
|
+
/**
|
|
184
|
+
* Update user data for the current session.
|
|
185
|
+
*/
|
|
186
|
+
declare function updateUser(config: MiiflowChatConfig, session: EmbedSession, userData: {
|
|
187
|
+
user_id?: string;
|
|
188
|
+
name?: string;
|
|
189
|
+
email?: string;
|
|
190
|
+
}): Promise<void>;
|
|
191
|
+
/**
|
|
192
|
+
* Upload a file attachment via REST endpoint.
|
|
193
|
+
* Returns the attachment ID for use in sendMessage.
|
|
194
|
+
*/
|
|
195
|
+
declare function uploadFile(config: MiiflowChatConfig, session: EmbedSession, file: File): Promise<string>;
|
|
196
|
+
/**
|
|
197
|
+
* Send a system event to the backend (invisible to chat, processed by assistant).
|
|
198
|
+
*/
|
|
199
|
+
declare function sendSystemEvent(config: MiiflowChatConfig, session: EmbedSession, systemEvent: SystemEvent): Promise<void>;
|
|
200
|
+
/**
|
|
201
|
+
* Send a tool execution result back to the backend.
|
|
202
|
+
*/
|
|
203
|
+
declare function sendToolResult(config: MiiflowChatConfig, session: EmbedSession, result: ToolExecutionResult): Promise<void>;
|
|
204
|
+
/**
|
|
205
|
+
* Register tool definitions with the backend.
|
|
206
|
+
*/
|
|
207
|
+
declare function registerToolsOnBackend(config: MiiflowChatConfig, session: EmbedSession, toolDefinitions: Array<Omit<ClientToolDefinition, "handler">>): Promise<void>;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Utility functions for parsing and managing JWT tokens.
|
|
211
|
+
* Used for proactive token refresh before expiration.
|
|
212
|
+
*/
|
|
213
|
+
/**
|
|
214
|
+
* Parse the expiry time from a JWT token.
|
|
215
|
+
* Returns the expiry timestamp in milliseconds, or null if parsing fails.
|
|
216
|
+
*/
|
|
217
|
+
declare function parseTokenExpiry(token: string): number | null;
|
|
218
|
+
/**
|
|
219
|
+
* Check if a token is expiring soon (within the given threshold).
|
|
220
|
+
*/
|
|
221
|
+
declare function isTokenExpiringSoon(token: string, thresholdMs: number): boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Check if a token has already expired.
|
|
224
|
+
*/
|
|
225
|
+
declare function isTokenExpired(token: string): boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Get the time remaining until token expiry in milliseconds.
|
|
228
|
+
*/
|
|
229
|
+
declare function getTimeUntilExpiry(token: string): number;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Client-side validator for tool definitions.
|
|
233
|
+
* Validates tool definitions before they're sent to the backend.
|
|
234
|
+
*/
|
|
235
|
+
|
|
236
|
+
declare class ToolValidationError extends Error {
|
|
237
|
+
constructor(message: string);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Validates a client tool definition.
|
|
241
|
+
* Throws ToolValidationError if validation fails.
|
|
242
|
+
*/
|
|
243
|
+
declare function validateToolDefinition(tool: ClientToolDefinition): void;
|
|
244
|
+
/**
|
|
245
|
+
* Strips the handler function from a tool definition for sending to backend.
|
|
246
|
+
*/
|
|
247
|
+
declare function serializeToolDefinition(tool: ClientToolDefinition): Omit<ClientToolDefinition, "handler">;
|
|
248
|
+
|
|
249
|
+
export { type ClientToolDefinition, type EmbedSession, type EmbedSessionBranding, type EmbedSessionConfig, type JSONSchemaObject, type JSONSchemaProperty, type MiiflowChatConfig, type MiiflowChatResult, type SystemEvent, type ToolExecutionResult, type ToolHandler, type ToolInvocationRequest, ToolValidationError, type WidgetEventCallback, type WidgetEventPayload, type WidgetEventType, createThread, getBackendBaseUrl, getOrCreateUserId, getTimeUntilExpiry, initSession, isTokenExpired, isTokenExpiringSoon, parseTokenExpiry, registerToolsOnBackend, sendSystemEvent, sendToolResult, serializeToolDefinition, updateUser, uploadFile, useMiiflowChat, validateToolDefinition };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use strict';var chunkNSTK5EUQ_js=require('../chunk-NSTK5EUQ.js'),react=require('react');function M(t){return t.baseUrl?t.baseUrl.replace(/\/api\/?$/,""):t.bundleUrl?.includes("localhost")||t.bundleUrl?.includes("127.0.0.1")||false?"http://localhost:8003":"https://api.miiflow.ai"}function U(){let t="miiflow-user-id",a=null;try{a=localStorage.getItem(t);}catch{}if(!a){a=`muid_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;try{localStorage.setItem(t,a);}catch{}}return a}async function ue(t){let a=M(t),u=await fetch(`${a}/api/embed/init`,{method:"POST",headers:{"Content-Type":"application/json","X-Embed-Public-Key":t.publicKey,"x-mii-user-id":U()},body:JSON.stringify({assistant_id:t.assistantId,user_data:{user_id:t.userId,name:t.userName,email:t.userEmail}})});if(!u.ok){let p=await u.text();throw new Error(`Init failed: ${u.status} - ${p}`)}let d=await u.json();if(!d.success)throw new Error(d.error||"Failed to initialize session");return {token:d.token,config:d.config,session_id:d.session_id}}async function ce(t,a){let u=M(t),d=await fetch(`${u}/api/embed/graphql`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a.token}`,"x-mii-user-id":U()},body:JSON.stringify({operationName:"CreateThread",variables:{input:{assistantId:a.config.assistant_id,name:"New Thread",isPreview:false}},query:`mutation CreateThread($input: CreateThreadInput!) {
|
|
2
|
+
createThread(input: $input) {
|
|
3
|
+
thread { id status name isPreview }
|
|
4
|
+
}
|
|
5
|
+
}`})});if(!d.ok)throw new Error(`Failed to create thread: ${d.status}`);let p=await d.json(),g=p.data?.createThread?.thread?.id;if(!g)throw new Error("No thread ID returned");return {threadId:g,token:p.token}}async function ye(t,a,u){let d=M(t);await fetch(`${d}/api/embed/update`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a.token}`},body:JSON.stringify({user_data:u})});}async function de(t,a,u){let p=`${M(t)}/api/embed/upload-attachment`,g=new FormData;g.append("file",u);let f=await fetch(p,{method:"POST",headers:{Authorization:`Bearer ${a.token}`,"x-mii-user-id":U()},body:g});if(!f.ok){let B=await f.text();throw new Error(`Upload failed: ${f.status} - ${B}`)}let v=(await f.json()).attachment?.id;if(!v)throw new Error("No attachment ID returned");return v}async function pe(t,a,u){let d=M(t),p=await fetch(`${d}/api/embed/system-event`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a.token}`,"x-mii-user-id":U()},body:JSON.stringify({thread_id:a.config.thread_id,system_event:{action:u.action,description:u.description,followUpInstruction:u.followUpInstruction,metadata:u.metadata||{}}})});if(!p.ok){let f=await p.text();throw new Error(`Failed to send system event: ${p.status} - ${f}`)}let g=await p.json();if(!g.success)throw new Error(g.error||"Failed to send system event")}async function V(t,a,u){let d=M(t),p=await fetch(`${d}/api/embed/tool-result`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a.token}`},body:JSON.stringify(u)});if(!p.ok){let f=await p.text();throw new Error(`Failed to send tool result: ${p.status} - ${f}`)}let g=await p.json();if(!g.success)throw new Error(`Failed to send tool result: ${g.error}`)}async function Q(t,a,u){let d=M(t);if(u.length===1){let p=await fetch(`${d}/api/embed/register-tool`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a.token}`},body:JSON.stringify(u[0])});if(!p.ok){let f=await p.text();throw new Error(`Failed to register tool: ${p.status} - ${f}`)}let g=await p.json();if(!g.success)throw new Error(`Failed to register tool: ${g.error||"Unknown error"}`)}else if(u.length>1){let p=await fetch(`${d}/api/embed/register-tools`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a.token}`},body:JSON.stringify(u)});if(!p.ok){let f=await p.text();throw new Error(`Failed to register tools: ${p.status} - ${f}`)}let g=await p.json();if(!g.success)throw new Error(`Failed to register tools: ${g.error||"Unknown error"}`)}}var ge=new Set(["string","number","integer","boolean","array","object","null"]),ke=/^[a-zA-Z_][a-zA-Z0-9_]*$/,b=class extends Error{constructor(a){super(a),this.name="ToolValidationError";}};function ie(t){if(!t.name)throw new b("Tool name is required");if(!t.description)throw new b("Tool description is required");if(!t.parameters)throw new b("Tool parameters schema is required");if(typeof t.handler!="function")throw new b("Tool handler must be a function");Ce(t.name),Se(t.description),Te(t.parameters);}function Ce(t){if(typeof t!="string")throw new b("Tool name must be a string");if(t.length===0)throw new b("Tool name cannot be empty");if(t.length>64)throw new b("Tool name too long (max 64 characters)");if(!ke.test(t))throw new b("Tool name must start with letter/underscore and contain only alphanumeric characters and underscores")}function Se(t){if(typeof t!="string")throw new b("Tool description must be a string");if(t.trim().length===0)throw new b("Tool description cannot be empty");if(t.length>500)throw new b("Tool description too long (max 500 characters)")}function Te(t){if(typeof t!="object"||t===null||Array.isArray(t))throw new b("Parameters must be a JSON Schema object");if(t.type!=="object")throw new b("Parameters schema must be of type 'object' (function parameters)");if(t.properties&&typeof t.properties=="object")for(let[a,u]of Object.entries(t.properties))oe(a,u);if(t.required!==void 0){if(!Array.isArray(t.required))throw new b("'required' must be an array");for(let a of t.required)if(typeof a!="string")throw new b("'required' array must contain only strings")}if(t.additionalProperties!==void 0&&typeof t.additionalProperties!="boolean"&&(typeof t.additionalProperties!="object"||t.additionalProperties===null))throw new b("'additionalProperties' must be boolean or object")}function oe(t,a){if(typeof a!="object"||a===null||Array.isArray(a))throw new b(`Property '${t}' schema must be an object`);if(a.type!==void 0){let u=Array.isArray(a.type)?a.type:[a.type];for(let d of u)if(!ge.has(d))throw new b(`Invalid type '${d}' for property '${t}'. Valid types: ${Array.from(ge).join(", ")}`)}if(a.enum!==void 0&&!Array.isArray(a.enum))throw new b(`Property '${t}' enum must be an array`);if(a.properties&&typeof a.properties=="object")for(let[u,d]of Object.entries(a.properties))oe(`${t}.${u}`,d);a.items&&(Array.isArray(a.items)?a.items.forEach((u,d)=>{oe(`${t}[${d}]`,u);}):oe(`${t}[]`,a.items));}function re(t){return {name:t.name,description:t.description,parameters:t.parameters}}var Ie=21e3,De=1e3,xe=3e4;function ve(t,a){if(t.webSocketUrl){let f=new URL(t.webSocketUrl);return f.pathname=`/ws/assistant/thread/${a.config.thread_id}/`,f.searchParams.set("role","user"),f.searchParams.set("user_id",U()),f.searchParams.set("embed_token",a.token),f.toString()}let p=M(t).replace(/\/api$/,"").replace(/^https:/,"wss:").replace(/^http:/,"ws:"),g=U();return `${p}/ws/assistant/thread/${a.config.thread_id}/?role=user&user_id=${encodeURIComponent(g)}&embed_token=${encodeURIComponent(a.token)}`}function Ae(t){let a=t?.config.branding;return a?{customName:a.custom_name,messageFontSize:a.message_font_size,welcomeMessage:a.welcome_message,chatboxPlaceholder:a.chatbox_placeholder,backgroundBubbleColor:a.background_bubble_color,headerBackgroundColor:a.header_background_color,showHeader:a.show_header,rotatingPlaceholders:a.rotating_placeholders,presetQuestions:a.preset_questions,chatbotLogo:a.chatbot_logo,assistantAvatar:a.assistant_avatar}:null}async function Me(t,a,u,d){let p=new TextDecoder,g="",f=null,s=[],v,B,K=false,T="answer",C="",m,S,j,E,I,z,W,P,q,J,O,H,L,X,ee=false,Z="",te=a.config.branding,N=()=>{(C||T==="tool")&&(s.push({type:T,content:C,toolName:m,toolDescription:S,success:j,status:E,subtaskId:I,planData:z,subtaskData:W,isSynthesis:P,isReplan:q,toolArgs:J,replanAttempt:O,maxReplans:H,failureReason:L,progress:X}),C="",m=void 0,S=void 0,j=void 0,E=void 0,I=void 0,z=void 0,W=void 0,P=void 0,q=void 0,J=void 0,O=void 0,H=void 0,L=void 0,X=void 0);},r=()=>{let c=s.map(h=>h);return (C||T==="tool")&&c.push({type:T,content:C,toolName:m,toolDescription:S,success:j,status:E,subtaskId:I,planData:z,subtaskData:W,isSynthesis:P,isReplan:q,toolArgs:J,replanAttempt:O,maxReplans:H,failureReason:L,progress:X}),c},o=()=>{let c=r();if(f)d.onMessageUpdate({id:f,textContent:g,reasoning:c,suggestedActions:v});else {f=`assistant-${Date.now()}`;let h={id:f,textContent:g,participant:{id:"assistant",name:te?.custom_name||a.config.assistant_name,role:"assistant",avatarUrl:te?.assistant_avatar},createdAt:new Date().toISOString(),isStreaming:true,reasoning:c,suggestedActions:v};d.onMessageCreate(h);}};for(;;){let{done:c,value:h}=await t.read();if(c)break;let D=p.decode(h,{stream:true}),w=(Z+D).split(`
|
|
6
|
+
`);D.endsWith(`
|
|
7
|
+
`)?Z="":Z=w.pop()||"";for(let F of w){if(!F.startsWith("data: "))continue;let k=F.slice(6);if(k==="[DONE]")break;try{let e=JSON.parse(k);if(e.type==="assistant_chunk"){if(e.is_tool_planned){(C||T!=="answer")&&(N(),T="answer"),s.push({type:"tool",content:"",toolName:e.tool_name,toolDescription:e.tool_description,status:"planned",subtaskId:e.subtask_id}),o();continue}if(e.is_tool_executing){for(let n=s.length-1;n>=0;n--){let l=s[n];if(l.type==="tool"&&l.toolName===e.tool_name&&(e.subtask_id===void 0||l.subtaskId===e.subtask_id)){s[n].status="executing";break}}o();continue}if(e.is_observation){for(let n=s.length-1;n>=0;n--){let l=s[n];if(l.type==="tool"&&l.toolName===e.tool_name&&(e.subtask_id===void 0||l.subtaskId===e.subtask_id)){s[n].status="completed";break}}o();continue}if(e.suggested_actions){v=e.suggested_actions.map(n=>({id:n.action,label:n.label,value:n.action})),o();continue}if(e.is_wave_start){(C||T!=="answer")&&(N(),T="answer"),s.push({type:"wave_start",content:"",waveNumber:e.wave_number,isParallel:!0,waveData:{waveNumber:e.wave_number,subtaskIds:e.subtask_ids||[],parallelCount:e.parallel_count||0,totalWaves:e.total_waves||1}}),o();continue}if(e.is_wave_complete){s.push({type:"wave_complete",content:"",waveNumber:e.wave_number,isParallel:!0,waveData:{waveNumber:e.wave_number,subtaskIds:[],parallelCount:0,totalWaves:0,completedIds:e.completed_ids||[],success:e.success,executionTime:e.execution_time}}),o();continue}if(e.is_parallel_subtask_start){s.push({type:"parallel_subtask_start",content:"",subtaskId:e.subtask_id,waveNumber:e.wave_number,isParallel:!0,parallelSubtaskData:{subtaskId:e.subtask_id,waveNumber:e.wave_number,description:e.description}}),o();continue}if(e.is_parallel_subtask_complete){s.push({type:"parallel_subtask_complete",content:"",subtaskId:e.subtask_id,waveNumber:e.wave_number,isParallel:!0,success:e.success,parallelSubtaskData:{subtaskId:e.subtask_id,waveNumber:e.wave_number,success:e.success,result:e.result,error:e.error,executionTime:e.execution_time}}),o();continue}if(e.is_multi_agent_planning){ee=!0,(C||T!=="answer")&&(N(),T="answer"),s.push({type:"multi_agent_planning",content:"",isMultiAgent:!0}),o();continue}if(e.is_reasoning&&e.reasoning_delta){let n=s.findIndex(l=>l.type==="thinking"&&l.isMultiAgent);n>=0?s[n]={...s[n],content:(s[n].content||"")+e.reasoning_delta}:s.push({type:"thinking",content:e.reasoning_delta,isMultiAgent:!0}),o();continue}if(e.is_multi_agent_planning_complete){let n=s.findIndex(l=>l.type==="multi_agent_planning"&&l.isMultiAgent);n>=0?s[n]={...s[n],subagentAllocations:e.subagents||[]}:s.push({type:"multi_agent_planning",content:"",isMultiAgent:!0,subagentAllocations:e.subagents||[]}),o();continue}if(e.is_multi_agent_execution_start)continue;if(e.is_subagent_start){s.push({type:"subagent_start",content:"",isMultiAgent:!0,subagentInfo:{id:e.subagent_id,name:e.subagent_name,task:e.task,status:"running"}}),o();continue}if(e.is_subagent_progress){let n=s.findIndex(l=>l.type==="subagent_start"&&l.subagentInfo?.id===e.subagent_id);n!==-1&&s[n].subagentInfo&&(s[n]={...s[n],content:e.progress||""}),o();continue}if(e.is_subagent_complete){s.push({type:"subagent_complete",content:"",isMultiAgent:!0,subagentInfo:{id:e.subagent_id,name:e.subagent_name,status:"completed",result:e.result,executionTime:e.execution_time}}),o();continue}if(e.is_subagent_failed){s.push({type:"subagent_failed",content:"",isMultiAgent:!0,subagentInfo:{id:e.subagent_id,name:e.subagent_name,status:"failed",error:e.error}}),o();continue}if(e.is_synthesis_start&&ee){s.push({type:"synthesis",content:"",isMultiAgent:!0,isSynthesis:!0}),o();continue}if(e.plan_data){let n=e.plan_data;z={goal:n.goal||"",reasoning:n.reasoning||"",subtasks:(n.subtasks||[]).map(l=>({id:Number(l.id),description:l.description,required_tools:l.required_tools,dependencies:l.dependencies,status:"pending"})),total_subtasks:n.subtasks?.length||0,completed_subtasks:0,failed_subtasks:0,progress_percentage:0};}e.subtask_data&&(W=e.subtask_data),e.is_synthesis_start&&(P=!0),e.is_replan&&(q=!0),e.tool_args&&(J=e.tool_args),e.replan_attempt!==void 0&&(O=e.replan_attempt),e.max_replans!==void 0&&(H=e.max_replans),e.failure_reason&&(L=e.failure_reason),e.progress&&(X=e.progress);let i="answer";if(e.is_thinking?i="thinking":e.is_planning||e.is_plan_complete||e.is_replanning?i="planning":e.is_subtask_start||e.is_subtask_complete||e.is_subtask_failed?i="subtask":e.is_progress_update&&(i="progress"),i!==T&&(N(),T=i),e.tool_name&&(m=e.tool_name),e.success!==void 0&&(j=e.success),e.subtask_id!==void 0&&(I=e.subtask_id),i==="thinking"){C+=e.chunk||"";let n=C.match(/"thought"\s*:\s*"((?:[^"\\]|\\.)*)"/);n&&(C=n[1].replace(/\\n/g,`
|
|
8
|
+
`).replace(/\\"/g,'"').replace(/\\t/g," ").replace(/\\\\/g,"\\"));}else if(i==="answer"){let n=e.chunk?.trim()||"",l=g.trim();n&&l&&n===l||(g+=e.chunk||"");}else C+=e.chunk||"";e.previous_message_id&&d.onUserMessageIdUpdate(u,e.previous_message_id),o();}else if(e.type==="claude_text"){g+=e.chunk||"";let i=s.find(n=>n.type==="claude_text");i?i.content+=e.chunk||"":s.push({type:"claude_text",content:e.chunk||"",orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_thinking")s.push({type:"claude_thinking",content:e.content||"",orchestrator:"claude_agent_sdk"}),o();else if(e.type==="claude_file_read"){let i={toolUseId:e.tool_use_id,operation:"read",filePath:e.file_path,status:e.status,content:e.content,totalLines:e.total_lines,language:e.language,error:e.error,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);n>=0?s[n].fileOperationData=i:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_file_edit"){let i={toolUseId:e.tool_use_id,operation:"edit",filePath:e.file_path,status:e.status,oldString:e.old_string,newString:e.new_string,error:e.error,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);n>=0?s[n].fileOperationData=i:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_file_write"){let i={toolUseId:e.tool_use_id,operation:"write",filePath:e.file_path,status:e.status,error:e.error,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);n>=0?s[n].fileOperationData=i:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_bash"){let i={toolUseId:e.tool_use_id,command:e.command,description:e.description,status:e.status,stdout:e.stdout,stderr:e.stderr,exitCode:e.exit_code,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="terminal"&&l.toolUseId===e.tool_use_id);n>=0?s[n].terminalData=i:s.push({type:"terminal",content:"",toolUseId:e.tool_use_id,terminalData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_search"){let i={toolUseId:e.tool_use_id,tool:e.tool,pattern:e.pattern,path:e.path,status:e.status,results:(e.results||[]).map(l=>({filePath:l.file_path,lineNumber:l.line_number,snippet:l.snippet})),totalCount:e.total_count||0,error:e.error,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="search_results"&&l.toolUseId===e.tool_use_id);n>=0?s[n].searchResultsData=i:s.push({type:"search_results",content:"",toolUseId:e.tool_use_id,searchResultsData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_web_search"||e.type==="claude_web_fetch"){let i={toolUseId:e.tool_use_id,operation:e.type==="claude_web_search"?"search":"fetch",query:e.query,url:e.url,status:e.status,results:e.results,content:e.content,error:e.error,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="web_operation"&&l.toolUseId===e.tool_use_id);n>=0?s[n].webOperationData=i:s.push({type:"web_operation",content:"",toolUseId:e.tool_use_id,webOperationData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_subagent_start"){let i={subagentId:e.subagent_id,subagentType:e.subagent_type,description:e.description,prompt:e.prompt,status:"running",nestedChunks:[]};s.push({type:"subagent",content:"",toolUseId:e.parent_tool_use_id,subagentData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_subagent_chunk"){let i=s.findIndex(n=>n.type==="subagent"&&n.subagentData?.subagentId===e.subagent_id);i>=0&&s[i].subagentData&&s[i].subagentData.nestedChunks.push({type:e.is_tool?"tool":"answer",content:e.chunk||"",toolName:e.tool_name,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_subagent_complete"){let i=s.findIndex(n=>n.type==="subagent"&&n.subagentData?.subagentId===e.subagent_id);i>=0&&s[i].subagentData&&(s[i].subagentData.status="completed",s[i].subagentData.result=e.result,s[i].subagentData.durationMs=e.duration_ms),o();}else if(e.type==="claude_tool_use"||e.type==="claude_tool_result"){let i={toolUseId:e.tool_use_id,toolName:e.tool_name,toolDescription:e.tool_description,toolInput:e.tool_input,status:e.type==="claude_tool_use"?"pending":e.is_error?"error":"completed",content:e.content,isError:e.is_error,durationMs:e.duration_ms},n=s.findIndex(l=>l.claudeToolData?.toolUseId===e.tool_use_id);n>=0?s[n].claudeToolData=i:s.push({type:"tool",content:e.content||"",toolUseId:e.tool_use_id,toolName:e.tool_name,toolDescription:e.tool_description,status:i.status==="pending"?"planned":"completed",claudeToolData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="clarification_needed"){N();let i={question:e.question||"",options:e.options||[],context:e.context,allowFreeText:e.allow_free_text!==!1,subtaskId:e.subtask_id,subtaskDescription:e.subtask_description,subagentName:e.subagent_name,subagentRole:e.subagent_role};s.push({type:"clarification_needed",content:i.question,clarificationData:i,subtaskId:e.subtask_id}),B=i,g||(g=i.question),o();}else if(e.type==="assistant_complete"){N(),K=!0;let i=e.message?.text_content||g,n=e.message?.id,l=e.message?.metadata?.sources;d.onComplete(f,i,n,s,v,l,B),g=i,n&&(f=n);break}else if(e.type==="client_tool_invocation"&&e.invocation&&d.onToolInvocation)d.onToolInvocation(e.invocation);else {if(e.type==="error")throw new Error(e.error||"Stream error");if(e.type==="done"){f&&!K?(N(),d.onComplete(f,g||"",e.message_id,s,v,void 0,B)):e.message_id&&f&&d.onMessageUpdate({id:f,isStreaming:!1}),e.message_id&&(f=e.message_id);break}}}catch(e){if(e instanceof Error&&e.message!=="Stream error"&&(e.message.startsWith("Stream error")||e.message.startsWith("HTTP error")))throw e}}}return {assistantMsgId:f,assistantContent:g}}function Ee(t){let[a,u]=react.useState([]),[d,p]=react.useState(false),[g,f]=react.useState(null),[s,v]=react.useState(null),[B,K]=react.useState(true),[T,C]=react.useState(null),m=react.useRef(t);m.current=t;let S=react.useRef(s);S.current=s;let j=react.useRef(d);j.current=d;let E=react.useRef(new Map),I=react.useRef(new Map);react.useEffect(()=>{let r=false;async function o(){try{let c=await ue(m.current);r||(v(c),K(!1));}catch(c){r||(C(c instanceof Error?c.message:"Failed to initialize"),K(false));}}return o(),()=>{r=true;}},[t.publicKey,t.assistantId]);let z=react.useMemo(()=>Ae(s),[s]),W=chunkNSTK5EUQ_js.b(z),P=react.useRef(new Map),q=react.useCallback(async r=>{let o=S.current;if(!o)throw new Error("Not initialized");let c=await de(m.current,o,r);return P.current.set(c,{id:c,filename:r.name,mimeType:r.type,size:r.size,isImage:r.type.startsWith("image/"),isVideo:r.type.startsWith("video/"),isDocument:!r.type.startsWith("image/")&&!r.type.startsWith("video/")}),c},[]),J=react.useCallback(r=>{P.current.delete(r);},[]),O=react.useCallback(async r=>{let o=S.current;if(!o)throw new Error("Not initialized");let{invocation_id:c,tool_name:h,parameters:D}=r;console.log(`[Miiflow] Tool invocation received: "${h}" (id: ${c})`);let _=E.current.get(h);if(!_)return false;try{let w=await Promise.race([_(D),new Promise((F,k)=>setTimeout(()=>k(new Error("Tool execution timeout (30s)")),3e4))]);return console.log(`[Miiflow] Tool "${h}" executed successfully (id: ${c})`),await V(m.current,o,{invocation_id:c,result:w}),console.log(`[Miiflow] Tool result sent for "${h}" (id: ${c})`),!0}catch(w){return console.error(`[Miiflow] Tool '${h}' execution failed:`,w),await V(m.current,o,{invocation_id:c,error:w instanceof Error?w.message:String(w)}),true}},[]);react.useEffect(()=>{if(!s)return;let r=s,o=null,c=null,h=null,D=0,_=false;function w(){if(_)return;let F=ve(m.current,r);o=new WebSocket(F),o.onopen=()=>{console.log("[Miiflow] WebSocket connected"),D=0,c=setInterval(()=>{o?.readyState===WebSocket.OPEN&&o.send(JSON.stringify({type:"heartbeat"}));},Ie);},o.onmessage=k=>{try{let e=JSON.parse(k.data);e.type==="client_tool_invocation"&&e.invocation&&O(e.invocation).then(async i=>{if(!i){let n=m.current.onToolInvocationFallback;n&&await n(e.invocation)||V(m.current,r,{invocation_id:e.invocation.invocation_id,error:`No handler found for tool '${e.invocation.tool_name}'`}).catch(console.error);}}).catch(console.error);}catch{}},o.onclose=()=>{if(c&&(clearInterval(c),c=null),!_){let k=Math.min(De*Math.pow(2,D),xe);D++,console.log(`[Miiflow] WebSocket closed, reconnecting in ${k}ms`),h=setTimeout(w,k);}},o.onerror=k=>{console.error("[Miiflow] WebSocket error:",k);};}return w(),()=>{_=true,c&&clearInterval(c),h&&clearTimeout(h),o&&(o.onclose=null,o.close());}},[s,O]);let H=react.useCallback(async r=>{let o=S.current;if(!o)throw new Error("Not initialized");await pe(m.current,o,r);},[]),L=react.useCallback(async(r,o)=>{let c=S.current,h=!!r.trim(),D=o&&o.length>0;if(!h&&!D||j.current||!c)return;let _=`msg-${Date.now()}`,w=o?.map(i=>P.current.get(i)).filter(Boolean),F={id:_,textContent:r,participant:{id:"user",name:m.current.userName||"You",role:"user"},createdAt:new Date().toISOString(),attachments:w?.length?w:void 0};o?.forEach(i=>P.current.delete(i));let k=`assistant-pending-${Date.now()}`,e={id:k,textContent:"",participant:{id:"assistant",name:c.config.branding?.custom_name||c.config.assistant_name,role:"assistant",avatarUrl:c.config.branding?.assistant_avatar},createdAt:new Date().toISOString(),isStreaming:true};u(i=>[...i,F,e]),p(true),f(k),m.current.onUserMessageCreated?.({id:_,content:r});try{let i=M(m.current),n=await fetch(`${i}/assistant/message/stream/`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${c.token}`,"x-mii-user-id":U()},body:JSON.stringify({thread_id:c.config.thread_id,text_content:r,message_id:_,metadata:{},attachment_ids:o||[]})});if(!n.ok)throw new Error(`HTTP error: ${n.status}`);let l=n.body?.getReader();if(!l)throw new Error("No response body");let ne=await Me(l,c,_,{onMessageCreate:y=>{f(y.id),u(x=>[...x.filter(R=>R.id!==k),y]);},onMessageUpdate:y=>{u(x=>x.map(A=>A.id===y.id?{...A,...y}:A));},onUserMessageIdUpdate:(y,x)=>{u(A=>A.map(R=>R.id===y?{...R,id:x}:R));},onComplete:(y,x,A,R,ae,_e,be)=>{y&&u(we=>we.map(se=>se.id===y?{...se,id:A||se.id,textContent:x,isStreaming:!1,reasoning:R,suggestedActions:ae,citations:_e,pendingClarification:be}:se)),m.current.onAssistantMessageComplete?.({id:A||y||"",content:x});},onToolInvocation:async y=>{if(!await O(y)){let A=m.current.onToolInvocationFallback;if(!(A?await A(y):!1)){let ae=S.current;ae&&await V(m.current,ae,{invocation_id:y.invocation_id,error:`No handler found for tool '${y.tool_name}'`});}}}});ne.assistantMsgId&&u(y=>y.map(x=>x.id===ne.assistantMsgId?{...x,isStreaming:!1}:x));}catch(i){console.error("[Miiflow] Send error:",i);let n=S.current,l={id:`error-${Date.now()}`,textContent:"Sorry, I encountered an error. Please try again.",participant:{id:"assistant",name:n?.config.branding?.custom_name||n?.config.assistant_name||"Assistant",role:"assistant",avatarUrl:n?.config.branding?.assistant_avatar},createdAt:new Date().toISOString()};u(ne=>[...ne.filter(y=>y.id!==k),l]),C(i instanceof Error?i.message:"Send failed");}finally{p(false),f(null);}},[O]),X=react.useCallback(async()=>{let r=S.current;if(!r)throw new Error("Not initialized");let o=await ce(m.current,r);o.token||console.warn("[Miiflow] CreateThread did not return new token \u2014 tools may register to wrong thread");let c={...r,config:{...r.config,thread_id:o.threadId},token:o.token||r.token};if(S.current=c,v(c),u([]),I.current.size>0){console.log(`[Miiflow] Re-registering ${I.current.size} tools on new thread`);try{await Q(m.current,c,Array.from(I.current.values()));}catch(h){console.warn("[Miiflow] Failed to re-register tools:",h);}}return o.threadId},[]),ee=react.useCallback(async r=>{let o=S.current;if(!o)throw new Error("Not initialized");ie(r),E.current.set(r.name,r.handler);let c=re(r);I.current.set(r.name,c);try{await Q(m.current,o,[c]),console.log(`[Miiflow] Tool registered: "${r.name}"`);}catch(h){throw E.current.delete(r.name),I.current.delete(r.name),h}},[]),Z=react.useCallback(async r=>{let o=S.current;if(!o)throw new Error("Not initialized");for(let _ of r)ie(_);let c=new Map(E.current),h=new Map(I.current),D=[];for(let _ of r){E.current.set(_.name,_.handler);let w=re(_);I.current.set(_.name,w),D.push(w);}try{await Q(m.current,o,D);let _=r.map(w=>w.name);console.log(`[Miiflow] Tools registered: ${JSON.stringify(_)} (${r.length} tools)`);}catch(_){throw E.current=c,I.current=h,_}},[]),te=react.useMemo(()=>a.map(r=>({id:r.id,textContent:r.textContent?.replace(/\[ref:[^\]]+\]/g,"")||r.textContent,participant:r.participant,createdAt:r.createdAt,isStreaming:r.isStreaming,reasoning:r.reasoning,suggestedActions:r.suggestedActions,citations:r.citations,attachments:r.attachments,pendingClarification:r.pendingClarification})),[a]),N=react.useCallback(r=>{v(r);},[]);return {messages:te,isStreaming:d,streamingMessageId:g,sendMessage:L,uploadFile:q,removeUploadedAttachment:J,session:s,loading:B,error:T,branding:z,brandingCSSVars:W,startNewThread:X,registerTool:ee,registerTools:Z,sendSystemEvent:H,handleToolInvocation:O,updateSession:N}}function le(t){try{let a=t.split(".");if(a.length!==3)return null;let u=a[1].replace(/-/g,"+").replace(/_/g,"/"),d=atob(u),p=JSON.parse(d);return typeof p.exp=="number"?p.exp*1e3:null}catch{return null}}function Oe(t,a){let u=le(t);return u===null?true:u-Date.now()<=a}function Pe(t){let a=le(t);return a===null?true:Date.now()>=a}function Ne(t){let a=le(t);return a===null?0:Math.max(0,a-Date.now())}exports.ToolValidationError=b;exports.createThread=ce;exports.getBackendBaseUrl=M;exports.getOrCreateUserId=U;exports.getTimeUntilExpiry=Ne;exports.initSession=ue;exports.isTokenExpired=Pe;exports.isTokenExpiringSoon=Oe;exports.parseTokenExpiry=le;exports.registerToolsOnBackend=Q;exports.sendSystemEvent=pe;exports.sendToolResult=V;exports.serializeToolDefinition=re;exports.updateUser=ye;exports.uploadFile=de;exports.useMiiflowChat=Ee;exports.validateToolDefinition=ie;//# sourceMappingURL=index.js.map
|
|
9
|
+
//# sourceMappingURL=index.js.map
|