@alquimia-ai/tools 1.13.1 → 2.0.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.
Files changed (79) hide show
  1. package/dist/actions/index.d.mts +7 -17
  2. package/dist/actions/index.d.ts +7 -17
  3. package/dist/actions/index.js +45 -152
  4. package/dist/actions/index.js.map +1 -1
  5. package/dist/actions/index.mjs +45 -152
  6. package/dist/actions/index.mjs.map +1 -1
  7. package/dist/adapters/fetch.d.mts +12 -0
  8. package/dist/adapters/fetch.d.ts +12 -0
  9. package/dist/adapters/fetch.js +44 -0
  10. package/dist/adapters/fetch.js.map +1 -0
  11. package/dist/adapters/fetch.mjs +23 -0
  12. package/dist/adapters/fetch.mjs.map +1 -0
  13. package/dist/adapters/index.d.mts +11 -0
  14. package/dist/adapters/index.d.ts +11 -0
  15. package/dist/adapters/index.js +19 -0
  16. package/dist/adapters/index.js.map +1 -0
  17. package/dist/adapters/index.mjs +1 -0
  18. package/dist/adapters/index.mjs.map +1 -0
  19. package/dist/adapters/next.d.mts +10 -0
  20. package/dist/adapters/next.d.ts +10 -0
  21. package/dist/adapters/next.js +42 -0
  22. package/dist/adapters/next.js.map +1 -0
  23. package/dist/adapters/next.mjs +21 -0
  24. package/dist/adapters/next.mjs.map +1 -0
  25. package/dist/hooks/index.d.mts +22 -2
  26. package/dist/hooks/index.d.ts +22 -2
  27. package/dist/hooks/index.js +283 -66
  28. package/dist/hooks/index.js.map +1 -1
  29. package/dist/hooks/index.mjs +274 -67
  30. package/dist/hooks/index.mjs.map +1 -1
  31. package/dist/next/index.d.mts +49 -0
  32. package/dist/next/index.d.ts +49 -0
  33. package/dist/next/index.js +332 -0
  34. package/dist/next/index.js.map +1 -0
  35. package/dist/next/index.mjs +309 -0
  36. package/dist/next/index.mjs.map +1 -0
  37. package/dist/providers/index.d.mts +7 -3
  38. package/dist/providers/index.d.ts +7 -3
  39. package/dist/providers/index.js +15 -14
  40. package/dist/providers/index.js.map +1 -1
  41. package/dist/providers/index.mjs +15 -14
  42. package/dist/providers/index.mjs.map +1 -1
  43. package/dist/proxy.d.mts +15 -0
  44. package/dist/proxy.d.ts +15 -0
  45. package/dist/proxy.js +147 -0
  46. package/dist/proxy.js.map +1 -0
  47. package/dist/proxy.mjs +126 -0
  48. package/dist/proxy.mjs.map +1 -0
  49. package/dist/sdk/index.d.mts +8 -14
  50. package/dist/sdk/index.d.ts +8 -14
  51. package/dist/sdk/index.js +49 -49
  52. package/dist/sdk/index.js.map +1 -1
  53. package/dist/sdk/index.mjs +49 -49
  54. package/dist/sdk/index.mjs.map +1 -1
  55. package/dist/services/index.d.mts +25 -3
  56. package/dist/services/index.d.ts +25 -3
  57. package/dist/types/index.d.mts +2 -1
  58. package/dist/types/index.d.ts +2 -1
  59. package/dist/types/index.js.map +1 -1
  60. package/dist/types/index.mjs.map +1 -1
  61. package/dist/utils/index.d.mts +1 -2
  62. package/dist/utils/index.d.ts +1 -2
  63. package/dist/utils/index.js +0 -17
  64. package/dist/utils/index.js.map +1 -1
  65. package/dist/utils/index.mjs +0 -17
  66. package/dist/utils/index.mjs.map +1 -1
  67. package/package.json +35 -5
  68. package/dist/providers/elastic/index.d.mts +0 -23
  69. package/dist/providers/elastic/index.d.ts +0 -23
  70. package/dist/providers/elastic/index.js +0 -102
  71. package/dist/providers/elastic/index.js.map +0 -1
  72. package/dist/providers/elastic/index.mjs +0 -69
  73. package/dist/providers/elastic/index.mjs.map +0 -1
  74. package/dist/services/apm/index.d.mts +0 -26
  75. package/dist/services/apm/index.d.ts +0 -26
  76. package/dist/services/apm/index.js +0 -86
  77. package/dist/services/apm/index.js.map +0 -1
  78. package/dist/services/apm/index.mjs +0 -63
  79. package/dist/services/apm/index.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/index.ts","../../src/hooks/alquimia.hook.tsx","../../src/utils/utils.ts","../../src/hooks/useRatings.ts"],"sourcesContent":["export { useAlquimia } from \"./alquimia.hook\";\nexport { useRatings } from \"./useRatings\";","import { useRef, useState } from \"react\";\nimport { AlquimiaSDK } from \"../sdk\";\nimport {\n AIMessageChunk,\n AlquimiaMessage,\n AlquimiaEventData,\n ToolEvent\n} from \"../types/type\";\nimport { createMessageId, extractAnswerContent, mergeThinkingsByControlId, mergeToolEvents } from \"../utils\";\nexport function useAlquimia(sdk: AlquimiaSDK) {\n const [input, setInput] = useState<string>(\"\");\n const [isMessageLoading, setIsMessageLoading] = useState<boolean>(false);\n const [isStreamingLoading, setIsStreamingLoading] = useState<boolean>(false);\n const [isMessageStreaming, setIsMessageStreaming] = useState<boolean>(false);\n const [streamingMessageId, setStreamingMessageId] = useState<string | null>(null);\n const [isAudioRecording, setIsAudioRecording] = useState<boolean>(false);\n const [messages, setMessages] = useState<AlquimiaMessage[]>([]);\n const eventSourceRef = useRef<EventSource | null>(null);\n const [sessionId, setSessionId] = useState<string | null>(null);\n const [activeTool, setActiveTool] = useState<any | null>(null);\n const [lastRequest, setLastRequest] = useState<string | null>(null);\n const [evaluationStrategy, setEvaluationStrategy] = useState<string>(\"\");\n const [hasThinkings, setHasThinkings] = useState<boolean>(false);\n const [attachments, setAttachments] = useState<File[]>([]);\n const [isUploadingAttachments, setIsUploadingAttachments] = useState<boolean>(false);\n\n const isLoading = isMessageLoading || isStreamingLoading || isUploadingAttachments;\n\n function cleanMessages() {\n setMessages([]);\n setHasThinkings(false);\n }\n\n function addAttachment(file: File) {\n setAttachments((prev) => [...prev, file]);\n }\n\n function addAttachments(files: File[]) {\n setAttachments((prev) => [...prev, ...files]);\n }\n\n function removeAttachment(index: number) {\n setAttachments((prev) => prev.filter((_, i) => i !== index));\n }\n\n function clearAttachments() {\n setAttachments([]);\n }\n function processMessageChunk(\n messageId: string,\n chunk: string,\n error_code?: string,\n error_detail?: string,\n stream_id?: string,\n additionalInfo?: string,\n loading?: boolean,\n tooler?: ToolEvent[],\n thinkings?: any[]\n ) {\n setMessages((currentMessages) => {\n const messageIndex = currentMessages.findIndex(\n (message) => message?.id === messageId\n );\n if (messageIndex !== -1) {\n const updatedMessages = [...currentMessages];\n const updatedMessage: AlquimiaMessage = {\n ...updatedMessages[messageIndex],\n content: `${updatedMessages[messageIndex]?.content || \"\"}${chunk}`,\n id: updatedMessages[messageIndex]?.id || \"\",\n role: updatedMessages[messageIndex]?.role || \"assistant\",\n error_code,\n error_detail,\n stream_id,\n additionalInfo,\n created_at: new Date().getTime().toString(),\n loading,\n tooler: mergeToolEvents(\n updatedMessages[messageIndex]?.tooler || [],\n tooler\n ),\n thinkings: mergeThinkingsByControlId(\n updatedMessages[messageIndex]?.thinkings || [],\n thinkings || []\n ),\n };\n updatedMessages[messageIndex] = updatedMessage;\n return updatedMessages;\n } else {\n return [\n ...currentMessages,\n {\n content: `${chunk}`,\n role: \"assistant\",\n id: messageId,\n error_code,\n error_detail,\n stream_id,\n created_at: new Date().getTime().toString(),\n loading,\n tooler: mergeToolEvents([], tooler),\n thinkings,\n },\n ];\n }\n });\n }\n\n async function processAndSendMessage(\n message: string,\n options?: {\n messageType?: string;\n traceParentId?: string;\n sessionId?: string;\n additionalInfo?: string;\n }\n ) {\n addUserMessage(message, options?.messageType);\n \n const messageId = createMessageId();\n setStreamingMessageId(messageId);\n \n await sendMessage(\n message,\n (chunk: AIMessageChunk) => {\n processMessageChunk(\n messageId,\n chunk?.answer || \"\",\n chunk?.error_code,\n chunk?.error_detail,\n chunk?.stream_id,\n options?.additionalInfo,\n chunk?.loading,\n chunk?.tooler,\n chunk?.thinkings\n );\n },\n options?.traceParentId,\n options?.sessionId\n );\n \n setInput(\"\");\n }\n\n async function handleSubmit(\n event: React.FormEvent<HTMLFormElement>,\n traceParentId?: string,\n sessionId?: string,\n additionalInfo?: string\n ) {\n setIsMessageLoading(true);\n event.preventDefault();\n \n if (input) {\n await processAndSendMessage(input, {\n traceParentId,\n sessionId,\n additionalInfo,\n });\n }\n \n setIsMessageLoading(false);\n }\n \n async function handleSystemMessage(\n message: string,\n options?: {\n traceParentId?: string;\n sessionId?: string;\n additionalInfo?: string;\n messageType?: string;\n }\n ) {\n setIsMessageLoading(true);\n \n await processAndSendMessage(message, {\n messageType: options?.messageType || \"system\",\n traceParentId: options?.traceParentId,\n sessionId: options?.sessionId,\n additionalInfo: options?.additionalInfo,\n });\n \n setIsMessageLoading(false);\n }\n\n function handleInputChange(event: React.ChangeEvent<HTMLTextAreaElement>) {\n setInput(event.target.value);\n }\n\n function handleReplaceInput(input: string) {\n setInput(input);\n }\n\n function populateMessages(messages: AlquimiaMessage[]) {\n setMessages(messages);\n }\n\n function handleLoadingCancel() {\n eventSourceRef.current?.close();\n eventSourceRef.current = null;\n setIsMessageLoading(false);\n setIsMessageStreaming(false);\n setStreamingMessageId(null);\n setIsStreamingLoading(false);\n setIsUploadingAttachments(false);\n setInput(\"\");\n }\n\n function addUserMessage(message: string, type?: string) {\n setMessages((prevMessages: AlquimiaMessage[]) => [\n ...prevMessages,\n {\n content: message,\n role: \"user\",\n type: type,\n id: createMessageId(),\n created_at: new Date().getTime().toString(),\n },\n ]);\n }\n\n function getCookie(name: string): string | null {\n const cookies = document.cookie.split(\";\");\n for (let cookie of cookies) {\n const [cookieName, cookieValue] = cookie.trim().split(\"=\");\n if (cookieName === name) {\n return decodeURIComponent(cookieValue as string);\n }\n }\n return null;\n }\n\n function cleanup(isStreaming: boolean, event: EventSource) {\n setIsMessageStreaming(isStreaming);\n setStreamingMessageId(null);\n setIsStreamingLoading(false);\n event.close();\n }\n\n async function sendMessage(\n message: string,\n callBack: (chunk: AIMessageChunk) => void,\n traceParentId?: string,\n sessionId?: string\n ) { \n setIsStreamingLoading(true);\n callBack({\n type: \"loading\",\n loading: true,\n });\n const conversationId = sessionId || getCookie(\"alquimia-session\");\n setIsMessageStreaming(true);\n setActiveTool(null);\n setLastRequest(message);\n\n try {\n const hasAttachments = attachments.length > 0;\n const sdkCall = sdk.widthConversationId(conversationId || \"\");\n\n if (hasAttachments) {\n sdkCall.withAttachments(attachments.map((f) => ({\n filename: f.name,\n content_type: f.type,\n content_size: f.size,\n })));\n }\n\n const response = await sdkCall.sendMessage(message, traceParentId);\n\n if (hasAttachments) {\n setIsUploadingAttachments(true);\n try {\n const attachmentResponses = response.getAttachmentResponses();\n await Promise.all(\n attachments.map((file, i) =>\n response.uploadAttachment(file, attachmentResponses[i])\n )\n );\n } catch (uploadError: any) {\n setIsUploadingAttachments(false);\n setIsMessageStreaming(false);\n setStreamingMessageId(null);\n setIsStreamingLoading(false);\n callBack({\n type: \"error\",\n error_code: \"ATTACHMENT_UPLOAD_ERROR\",\n error_detail: uploadError.message || \"Failed to upload attachment\",\n });\n return;\n }\n setIsUploadingAttachments(false);\n clearAttachments();\n }\n\n const eventSource = new EventSource(response.getUrlStream());\n eventSourceRef.current = eventSource;\n const evaluationStrategy = response.getEvaluationStrategy()!;\n setEvaluationStrategy(evaluationStrategy);\n\n eventSource.onmessage = (event) =>\n handleMessageEvent(event, callBack, eventSource);\n\n eventSource.onerror = (event) => {\n console.error(\"Stream connection error\", event);\n cleanup(false, eventSource);\n callBack({\n type: \"error\",\n error_code: \"STREAM_ERROR\",\n error_detail: \"Failed to establish stream connection. Stream event source error.\",\n stream_id: response.getStreamId() || \"\"\n });\n };\n } catch (error: any) {\n console.error(\"Error sending message:\", error);\n const errMessage = error.response?.data?.detail || error.message || \"Error initiating the stream.\";\n setIsUploadingAttachments(false);\n setIsMessageStreaming(false);\n setStreamingMessageId(null);\n callBack({\n type: \"error\",\n error_code: error.status?.toString() || \"REQUEST_ERROR\",\n error_detail: errMessage,\n });\n }\n }\n\n function handleMessageEvent(\n event: MessageEvent,\n callBack: (chunk: AIMessageChunk) => void,\n eventSource: EventSource\n ) {\n const data: AlquimiaEventData = JSON.parse(event.data);\n \n if (data.errors?.length) {\n for (const error of data.errors) {\n console.error(\"Stream error:\", error);\n callBack({\n type: \"error\",\n error_code: error.event_class || error.status || \"UNKNOWN_ERROR\",\n error_detail: `${error.data}, controlId: ${error.control_id}` || error.error_detail || \"Unknown error\",\n stream_id: data.stream_id || \"\"\n });\n }\n cleanup(false, eventSource);\n return;\n }\n \n if (data.tools_output?.length) {\n callBack({\n type: \"answer\",\n answer: \"\",\n tooler: data.tools_output,\n });\n }\n \n if (data.thinkings?.length) {\n setHasThinkings(true);\n callBack({\n type: \"answer\",\n thinkings: data.thinkings,\n });\n }\n \n const response = data.response;\n const content = response?.event_class === \"AssistantInferenceResponse\"\n ? extractAnswerContent(response?.data?.content)\n : null;\n \n if (content) {\n callBack({\n type: \"answer\",\n answer: content,\n });\n cleanup(false, eventSource);\n }\n }\n\n return {\n activeTool,\n cleanMessages,\n createMessageId,\n handleInputChange,\n handleReplaceInput,\n handleSubmit,\n handleSystemMessage,\n handleLoadingCancel,\n input,\n isLoading,\n isMessageStreaming,\n streamingMessageId,\n isAudioRecording,\n lastRequest,\n messages,\n populateMessages,\n processMessageChunk,\n sendMessage,\n sessionId,\n setActiveTool,\n setSessionId,\n setLastRequest,\n setIsAudioRecording,\n evaluationStrategy,\n hasThinkings,\n attachments,\n addAttachment,\n addAttachments,\n removeAttachment,\n clearAttachments,\n isUploadingAttachments,\n };\n}\n","import {\n BaseAPIConfig,\n ApiError,\n ConversationsMap,\n ThinkingsInferenceResponse,\n Tooler,\n ToolEvent,\n} from \"../types/type\";\n\nexport function generateTranslatePrompt(text: string) {\n const prompt = `\n Arrange the following text according to the given object structure and return it as plain json, values summarized to one word, no formatting:\n {\n restrictions: {\n value: [''],\n description: 'Restrictions to certain foods'\n },\n alergies: {\n value: [''],\n description: 'Alergies to certain foods'\n },\n wine_preference: {\n value: [''],\n description: 'Preferences for the wine'\n },\n meal_preference: {\n value: [''],\n description: 'Preferences for the meal'\n }\n }\n\n Text: \"${text}\"\n\n Output:\n `;\n\n return prompt;\n}\n\nexport function getCookies(name: string) {\n if (typeof document === \"undefined\") return undefined;\n const value = `; ${document.cookie}`;\n const parts = value.split(`; ${name}=`);\n if (parts.length === 2) return parts.pop()?.split(\";\").shift();\n}\n\nexport function generateHeaders(config: BaseAPIConfig): HeadersInit {\n const headers: HeadersInit = {\n \"Content-Type\": \"application/json\",\n };\n\n if (config.token) {\n headers[\"Authorization\"] = `Bearer ${config.token}`;\n }\n\n if (config.headers) {\n Object.entries(config.headers).forEach(([key, value]) => {\n headers[key] = value;\n });\n }\n\n return headers;\n}\n\nexport function isTextContent(buffer: ArrayBuffer): boolean {\n try {\n const text = new TextDecoder().decode(buffer);\n const trimmedText = text.trim();\n\n return (\n /^[\\w\\#\\-\\*\\|\\[\\]\\-\\+\\=\\s\\n\\r\\t\\!]/.test(trimmedText) ||\n trimmedText.startsWith(\"#\") ||\n trimmedText.startsWith(\"![\") ||\n trimmedText.startsWith(\"```\") ||\n trimmedText.startsWith(\"---\") ||\n /^[a-zA-Z0-9\\s\\n\\r\\t]/.test(trimmedText) ||\n /^\\!\\[.*\\]\\(.*\\)/.test(trimmedText)\n );\n } catch {\n return false;\n }\n}\n\nexport function getQueryParam(param: string): string | null {\n if (typeof window !== \"undefined\") {\n const urlParams = new URLSearchParams(window.location.search);\n return urlParams.get(param);\n }\n return null;\n}\n\nexport function defineAssistantId(defaultId: string): string {\n if (typeof window !== \"undefined\" && window.location.pathname === \"/\") {\n const queryAssistantId = getQueryParam(\"talkwith\");\n if (queryAssistantId) {\n localStorage.setItem(\"assistantId\", queryAssistantId);\n return queryAssistantId;\n }\n const storedAssistantId = localStorage.getItem(\"assistantId\");\n return storedAssistantId || defaultId;\n }\n return defaultId;\n}\n\nexport function formatTimeWithUnit(timeMs: number): string {\n if (timeMs >= 1000) {\n return `${(timeMs / 1000).toFixed(1)}s`;\n }\n return `${Math.round(timeMs)}ms`;\n}\n\nexport function serializeAxiosError(error: unknown) {\n if (error instanceof Error) {\n const customError = error as ApiError;\n return {\n message: customError?.message,\n name: customError?.name,\n stack: customError?.stack,\n code: customError?.code,\n status: customError?.status,\n };\n }\n return {\n message: String(error),\n name: \"Unknown Error\",\n };\n}\n\nexport function parseConversationsMapCookie(\n cookieValue: string\n): ConversationsMap {\n try {\n const decodedValue = decodeURIComponent(cookieValue);\n return JSON.parse(decodedValue) as ConversationsMap;\n } catch (e) {\n console.error(\"Error parsing conversations cookie:\", e);\n return {};\n }\n}\n\nexport function getTopicSessionId(topicId: string): string {\n const conversationsStr = getCookies(\"alquimia-sessions\") || \"{}\";\n if (!conversationsStr) {\n const sessionCookie = getCookies(\"alquimia-session\");\n return sessionCookie || \"\";\n }\n\n const conversationsMap = parseConversationsMapCookie(conversationsStr);\n return conversationsMap[topicId] || \"\";\n}\n\nexport function createMessageId() {\n return Math.floor(Math.random() * 1000000).toString();\n}\n\nexport function hasToolSummary(data: any) {\n return data.tool_summary && Object.keys(data.tool_summary).length > 0;\n}\n\nexport function mergeThinkingsByControlId(\n existingThinkings: ThinkingsInferenceResponse[] = [],\n newThinkings: ThinkingsInferenceResponse[] = []\n): ThinkingsInferenceResponse[] {\n const thinkingsMap = new Map(existingThinkings.map((t) => [t.control_id, t]));\n for (const t of newThinkings) {\n if (t && t.control_id) {\n thinkingsMap.set(t.control_id, t);\n }\n }\n return Array.from(thinkingsMap.values());\n}\n\nexport function extractAnswerContent(content: string): string {\n if (typeof content !== \"string\") return \"\";\n const trimmed = content.trim();\n if (trimmed.startsWith(\"{\")) {\n try {\n const repaired = trimmed.replace(/(?<!\\\\)\\n/g, \"\\\\n\");\n const parsed = JSON.parse(repaired);\n if (parsed && typeof parsed === \"object\" && \"answer\" in parsed) {\n return parsed.answer;\n }\n } catch (e) {\n return content;\n }\n }\n return content;\n}\n\nexport function mergeToolerByControlId(\n currentTooler: Tooler[],\n toolEvent: ToolEvent\n): Tooler[] {\n const { event_class, control_id, data, status } = toolEvent;\n const existingTool = currentTooler.find((t) => t.control_id === control_id);\n const base: Tooler = existingTool || { control_id };\n\n let updated: Tooler;\n switch (event_class) {\n case \"ServerToolExecutionCommand\":\n updated = {\n ...base,\n tool_summary: {\n name: data.name,\n parameters: data,\n },\n };\n break;\n case \"ToolExecutionResponse\":\n updated = {\n ...base,\n tool_output: {\n result: data,\n status,\n },\n };\n break;\n case \"A2AInferenceCommand\":\n updated = {\n ...base,\n tool_summary: {\n name: data.name,\n parameters: { ...data, type: \"A2A\" },\n },\n };\n break;\n default:\n return currentTooler;\n }\n\n return currentTooler.some(tool => tool.control_id === control_id)\n ? currentTooler.map(tool => (tool.control_id === control_id ? updated : tool))\n : [...currentTooler, updated];\n}\n\nexport function mergeToolEvents(\n initial: Tooler[],\n toolEvents?: ToolEvent[]\n): Tooler[] {\n return (toolEvents ?? []).reduce(\n (acc, toolEvent) => mergeToolerByControlId(acc, toolEvent),\n initial\n );\n}\n","\nimport { useState, useReducer } from \"react\";\nimport { RatingData } from \"../types/type\";\nimport { getTopicSessionId } from \"../utils/utils\";\n\ninterface RatingState {\n ratingStars: number;\n ratingThumbs: \"thumbsUp\" | \"thumbsDown\" | \"\";\n ratingComment: string;\n}\n\ntype RatingAction =\n | { type: \"SET_RATING_STARS\"; payload: number }\n | { type: \"SET_RATING_THUMBS\"; payload: \"thumbsUp\" | \"thumbsDown\" | \"\" }\n | { type: \"SET_RATING_COMMENT\"; payload: string };\n\nconst initialState: RatingState = {\n ratingStars: 0,\n ratingThumbs: \"\",\n ratingComment: \"\",\n};\n\nfunction ratingReducer(state: RatingState, action: RatingAction): RatingState {\n switch (action.type) {\n case \"SET_RATING_STARS\":\n return { ...state, ratingStars: action.payload };\n case \"SET_RATING_THUMBS\":\n return { ...state, ratingThumbs: action.payload };\n case \"SET_RATING_COMMENT\":\n return { ...state, ratingComment: action.payload };\n default:\n return state;\n }\n}\n\ninterface UseRatingsParams {\n assistantId: string;\n topicId: string;\n sendRating: (ratingData: RatingData) => Promise<any>;\n onError?: (componentName: string, error: Error) => void;\n}\n\n\nexport function useRatings({ assistantId, sendRating, topicId }: UseRatingsParams) {\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [hasReviewed, setHasReviewed] = useState<boolean>(false);\n const [state, dispatch] = useReducer(ratingReducer, initialState);\n\n const setRatingStars = (rating: number) => {\n dispatch({ type: \"SET_RATING_STARS\", payload: rating });\n };\n\n const setRatingThumbs = (rating: \"thumbsUp\" | \"thumbsDown\" | \"\") => {\n dispatch({ type: \"SET_RATING_THUMBS\", payload: rating });\n };\n\n const setRatingComment = (comment: string) => {\n dispatch({ type: \"SET_RATING_COMMENT\", payload: comment });\n };\n\n const thumbsScore = (value: string) => {\n return value === \"thumbsUp\" ? 5 : value === \"thumbsDown\" ? 0 : 0;\n }\n\n const handleRate = async (key: string, value: any | string, onHandleRateSuccess: (success: boolean, err?: string) => void) => {\n setIsLoading(true);\n const sessionId = getTopicSessionId(topicId);\n\n const ratingObj: RatingData = {\n topicId: parseInt(topicId),\n sessionId: sessionId || \"\",\n assistantId: assistantId,\n score: key === \"score\" ? value : thumbsScore(value),\n description: key === \"description\" ? value : state.ratingComment,\n };\n\n try {\n const response = await sendRating(ratingObj);\n if (!response.success) {\n setIsLoading(false);\n onHandleRateSuccess(false, response.error.message);\n return;\n }\n \n if (key === \"score\") {\n setRatingStars(value);\n } else if (key === \"description\") {\n setRatingComment(value);\n }\n setHasReviewed(true);\n setIsLoading(false);\n onHandleRateSuccess(true);\n } catch (err) {\n setIsLoading(false);\n onHandleRateSuccess(false, String(err));\n }\n };\n\n return {\n handleRate,\n ratingStars: state.ratingStars,\n ratingThumbs: state.ratingThumbs,\n ratingComment: state.ratingComment,\n isLoading,\n hasReviewed\n };\n}\n"],"mappings":"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","names":["sessionId","input","messages","evaluationStrategy","import_react"]}
1
+ {"version":3,"sources":["../../src/hooks/index.ts","../../src/hooks/alquimia.hook.tsx","../../src/sdk/alquimia-sdk.ts","../../src/utils/utils.ts","../../src/hooks/useRatings.ts"],"sourcesContent":["export { useAlquimia } from \"./alquimia.hook\";\nexport { useRatings } from \"./useRatings\";","import { useMemo, useRef, useState } from 'react';\nimport AlquimiaSDK from '../sdk/alquimia-sdk';\nimport type { AlquimiaAdapter } from '../adapters';\nimport {\n WhisperProvider,\n StableDiffusionProvider,\n CharacterizationProvider,\n RatingsProvider,\n LoggerProvider,\n} from '../providers';\nimport {\n AIMessageChunk,\n AlquimiaMessage,\n AlquimiaEventData,\n ToolEvent,\n} from '../types/type';\nimport { createMessageId, mergeThinkingsByControlId, mergeToolEvents } from '../utils';\n\nexport interface UseAlquimiaConfig {\n assistantId: string;\n adapter: AlquimiaAdapter;\n providers?: {\n whisper?: WhisperProvider;\n stableDiffusion?: StableDiffusionProvider;\n characterization?: CharacterizationProvider;\n ratings?: RatingsProvider;\n logger?: LoggerProvider;\n };\n options?: {\n enforceCharacterization?: boolean;\n userId?: string;\n extraData?: any;\n };\n}\n\nexport function useAlquimia(config: UseAlquimiaConfig) {\n const sdk = useMemo(() => {\n const instance = new AlquimiaSDK(config.assistantId, config.adapter, {\n enforceCharacterization: config.options?.enforceCharacterization,\n });\n\n if (config.providers?.whisper) instance.withWhisperProvider(config.providers.whisper);\n if (config.providers?.stableDiffusion) instance.withStableDiffusionProvider(config.providers.stableDiffusion);\n if (config.providers?.characterization) instance.withAnalyzeCharacterizationProvider(config.providers.characterization);\n if (config.providers?.ratings) instance.withRatingsProvider(config.providers.ratings);\n if (config.providers?.logger) instance.withLoggerProvider(config.providers.logger);\n if (config.options?.userId) instance.withUserId(config.options.userId);\n if (config.options?.extraData) instance.withExtraData(config.options.extraData);\n\n return instance;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [config.assistantId, config.adapter]);\n\n const [input, setInput] = useState<string>('');\n const [isMessageLoading, setIsMessageLoading] = useState<boolean>(false);\n const [isStreamingLoading, setIsStreamingLoading] = useState<boolean>(false);\n const [isMessageStreaming, setIsMessageStreaming] = useState<boolean>(false);\n const [streamingMessageId, setStreamingMessageId] = useState<string | null>(null);\n const [isAudioRecording, setIsAudioRecording] = useState<boolean>(false);\n const [messages, setMessages] = useState<AlquimiaMessage[]>([]);\n const eventSourceRef = useRef<EventSource | null>(null);\n const [sessionId, setSessionId] = useState<string | null>(null);\n const [activeTool, setActiveTool] = useState<any | null>(null);\n const [lastRequest, setLastRequest] = useState<string | null>(null);\n const [evaluationStrategy, setEvaluationStrategy] = useState<string>('');\n const [hasThinkings, setHasThinkings] = useState<boolean>(false);\n const [attachments, setAttachments] = useState<File[]>([]);\n const [isUploadingAttachments, setIsUploadingAttachments] = useState<boolean>(false);\n\n const isLoading = isMessageLoading || isStreamingLoading || isUploadingAttachments;\n\n function cleanMessages() {\n setMessages([]);\n setHasThinkings(false);\n }\n\n function addAttachment(file: File) {\n setAttachments((prev) => [...prev, file]);\n }\n\n function addAttachments(files: File[]) {\n setAttachments((prev) => [...prev, ...files]);\n }\n\n function removeAttachment(index: number) {\n setAttachments((prev) => prev.filter((_, i) => i !== index));\n }\n\n function clearAttachments() {\n setAttachments([]);\n }\n\n function processMessageChunk(\n messageId: string,\n chunk: string,\n error_code?: string,\n error_detail?: string,\n stream_id?: string,\n additionalInfo?: string,\n loading?: boolean,\n tooler?: ToolEvent[],\n thinkings?: any[]\n ) {\n setMessages((currentMessages) => {\n const messageIndex = currentMessages.findIndex((message) => message?.id === messageId);\n if (messageIndex !== -1) {\n const updatedMessages = [...currentMessages];\n const updatedMessage: AlquimiaMessage = {\n ...updatedMessages[messageIndex],\n content: `${updatedMessages[messageIndex]?.content || ''}${chunk}`,\n id: updatedMessages[messageIndex]?.id || '',\n role: updatedMessages[messageIndex]?.role || 'assistant',\n error_code,\n error_detail,\n stream_id,\n additionalInfo,\n created_at: new Date().getTime().toString(),\n loading,\n tooler: mergeToolEvents(updatedMessages[messageIndex]?.tooler || [], tooler),\n thinkings: mergeThinkingsByControlId(\n updatedMessages[messageIndex]?.thinkings || [],\n thinkings || []\n ),\n };\n updatedMessages[messageIndex] = updatedMessage;\n return updatedMessages;\n } else {\n return [\n ...currentMessages,\n {\n content: `${chunk}`,\n role: 'assistant',\n id: messageId,\n error_code,\n error_detail,\n stream_id,\n created_at: new Date().getTime().toString(),\n loading,\n tooler: mergeToolEvents([], tooler),\n thinkings,\n },\n ];\n }\n });\n }\n\n async function processAndSendMessage(\n message: string,\n options?: {\n messageType?: string;\n traceParentId?: string;\n sessionId?: string;\n additionalInfo?: string;\n }\n ) {\n addUserMessage(message, options?.messageType);\n\n const messageId = createMessageId();\n setStreamingMessageId(messageId);\n\n await sendMessage(\n message,\n (chunk: AIMessageChunk) => {\n processMessageChunk(\n messageId,\n chunk?.answer || '',\n chunk?.error_code,\n chunk?.error_detail,\n chunk?.stream_id,\n options?.additionalInfo,\n chunk?.loading,\n chunk?.tooler,\n chunk?.thinkings\n );\n },\n options?.traceParentId,\n options?.sessionId\n );\n\n setInput('');\n }\n\n async function handleSubmit(\n event: React.FormEvent<HTMLFormElement>,\n traceParentId?: string,\n sessionId?: string,\n additionalInfo?: string\n ) {\n setIsMessageLoading(true);\n event.preventDefault();\n\n if (input) {\n await processAndSendMessage(input, { traceParentId, sessionId, additionalInfo });\n }\n\n setIsMessageLoading(false);\n }\n\n async function handleSystemMessage(\n message: string,\n options?: {\n traceParentId?: string;\n sessionId?: string;\n additionalInfo?: string;\n messageType?: string;\n }\n ) {\n setIsMessageLoading(true);\n\n await processAndSendMessage(message, {\n messageType: options?.messageType || 'system',\n traceParentId: options?.traceParentId,\n sessionId: options?.sessionId,\n additionalInfo: options?.additionalInfo,\n });\n\n setIsMessageLoading(false);\n }\n\n function handleInputChange(event: React.ChangeEvent<HTMLTextAreaElement>) {\n setInput(event.target.value);\n }\n\n function handleReplaceInput(input: string) {\n setInput(input);\n }\n\n function populateMessages(messages: AlquimiaMessage[]) {\n setMessages(messages);\n }\n\n function handleLoadingCancel() {\n eventSourceRef.current?.close();\n eventSourceRef.current = null;\n setIsMessageLoading(false);\n setIsMessageStreaming(false);\n setStreamingMessageId(null);\n setIsStreamingLoading(false);\n setIsUploadingAttachments(false);\n setInput('');\n }\n\n function addUserMessage(message: string, type?: string) {\n setMessages((prevMessages: AlquimiaMessage[]) => [\n ...prevMessages,\n {\n content: message,\n role: 'user',\n type: type,\n id: createMessageId(),\n created_at: new Date().getTime().toString(),\n },\n ]);\n }\n\n function getCookie(name: string): string | null {\n const cookies = document.cookie.split(';');\n for (const cookie of cookies) {\n const [cookieName, cookieValue] = cookie.trim().split('=');\n if (cookieName === name) {\n return decodeURIComponent(cookieValue as string);\n }\n }\n return null;\n }\n\n function cleanup(isStreaming: boolean, event: EventSource) {\n setIsMessageStreaming(isStreaming);\n setStreamingMessageId(null);\n setIsStreamingLoading(false);\n event.close();\n }\n\n async function sendMessage(\n message: string,\n callBack: (chunk: AIMessageChunk) => void,\n traceParentId?: string,\n sessionId?: string\n ) {\n setIsStreamingLoading(true);\n callBack({ type: 'loading', loading: true });\n const conversationId = sessionId || getCookie('alquimia-session');\n setIsMessageStreaming(true);\n setActiveTool(null);\n setLastRequest(message);\n\n try {\n const hasAttachments = attachments.length > 0;\n const sdkCall = sdk.withConversationId(conversationId || '');\n\n if (hasAttachments) {\n sdkCall.withAttachments(\n attachments.map((f) => ({\n filename: f.name,\n content_type: f.type,\n content_size: f.size,\n }))\n );\n }\n\n const response = await sdkCall.sendMessage(message, traceParentId);\n\n if (hasAttachments) {\n setIsUploadingAttachments(true);\n try {\n const attachmentResponses = response.getAttachmentResponses();\n await Promise.all(\n attachments.map((file, i) => response.uploadAttachment(file, attachmentResponses[i]))\n );\n } catch (uploadError: any) {\n setIsUploadingAttachments(false);\n setIsMessageStreaming(false);\n setStreamingMessageId(null);\n setIsStreamingLoading(false);\n callBack({\n type: 'error',\n error_code: 'ATTACHMENT_UPLOAD_ERROR',\n error_detail: uploadError.message || 'Failed to upload attachment',\n });\n return;\n }\n setIsUploadingAttachments(false);\n clearAttachments();\n }\n\n const streamUrl = response.getUrlStream();\n const streamId = response.getStreamId() || '';\n const streamState = {\n streamId,\n connectedAt: Date.now(),\n openedAt: null as number | null,\n messagesReceived: 0,\n lastMessageAt: null as number | null,\n closedByClient: false,\n };\n\n const eventSource = new EventSource(streamUrl);\n eventSourceRef.current = eventSource;\n const evaluationStrategy = response.getEvaluationStrategy()!;\n setEvaluationStrategy(evaluationStrategy);\n\n eventSource.onopen = () => {\n streamState.openedAt = Date.now();\n };\n\n eventSource.onmessage = (event) => {\n streamState.messagesReceived++;\n streamState.lastMessageAt = Date.now();\n handleMessageEvent(event, callBack, eventSource, streamState);\n };\n\n eventSource.onerror = () => {\n if (streamState.closedByClient) return;\n streamState.closedByClient = true;\n\n const elapsed = Date.now() - streamState.connectedAt;\n const sinceLastMessage = streamState.lastMessageAt\n ? Date.now() - streamState.lastMessageAt\n : null;\n\n cleanup(false, eventSource);\n\n let errorDetail: string;\n if (!streamState.openedAt) {\n errorDetail = `Stream failed to connect (after ${elapsed}ms). URL: ${streamUrl}`;\n } else if (streamState.messagesReceived === 0) {\n errorDetail = `Stream connected but received no messages before error (open for ${elapsed}ms).`;\n } else {\n errorDetail = `Stream dropped after ${streamState.messagesReceived} message(s), ${sinceLastMessage}ms since last message (total ${elapsed}ms). Possible timeout.`;\n }\n\n callBack({\n type: 'error',\n error_code: 'STREAM_ERROR',\n error_detail: errorDetail,\n stream_id: streamId,\n });\n };\n } catch (error: any) {\n console.error('Error sending message:', error);\n const errMessage =\n error.response?.data?.detail || error.message || 'Error initiating the stream.';\n setIsUploadingAttachments(false);\n setIsMessageStreaming(false);\n setStreamingMessageId(null);\n callBack({\n type: 'error',\n error_code: error.status?.toString() || 'REQUEST_ERROR',\n error_detail: errMessage,\n });\n }\n }\n\n function handleMessageEvent(\n event: MessageEvent,\n callBack: (chunk: AIMessageChunk) => void,\n eventSource: EventSource,\n streamState?: {\n streamId: string;\n closedByClient: boolean;\n messagesReceived: number;\n }\n ) {\n const data: AlquimiaEventData = JSON.parse(event.data);\n if (data.errors?.length) {\n for (const error of data.errors) {\n const detail =\n error.error_detail ||\n (error.data != null\n ? `${error.data} (controlId: ${error.control_id})`\n : 'Unknown error');\n callBack({\n type: 'error',\n error_code: error.event_class || error.status || 'UNKNOWN_ERROR',\n error_detail: detail,\n stream_id: data.stream_id || '',\n });\n }\n if (streamState) streamState.closedByClient = true;\n cleanup(false, eventSource);\n return;\n }\n\n if (data.tools_output?.length) {\n callBack({ type: 'answer', answer: '', tooler: data.tools_output });\n }\n\n if (data.thinkings?.length) {\n setHasThinkings(true);\n callBack({ type: 'answer', thinkings: data.thinkings });\n }\n\n const response = data.response;\n const content =\n response?.event_class === 'AssistantInferenceResponse' && typeof response.data === 'string'\n ? response.data\n : null;\n\n if (content) {\n callBack({ type: 'answer', answer: content });\n if (streamState) streamState.closedByClient = true;\n cleanup(false, eventSource);\n }\n }\n\n return {\n sdk,\n activeTool,\n cleanMessages,\n createMessageId,\n handleInputChange,\n handleReplaceInput,\n handleSubmit,\n handleSystemMessage,\n handleLoadingCancel,\n input,\n isLoading,\n isMessageLoading,\n isMessageStreaming,\n isStreamingLoading,\n streamingMessageId,\n isAudioRecording,\n lastRequest,\n messages,\n populateMessages,\n processMessageChunk,\n sendMessage,\n sessionId,\n setActiveTool,\n setSessionId,\n setLastRequest,\n setIsAudioRecording,\n evaluationStrategy,\n hasThinkings,\n attachments,\n addAttachment,\n addAttachments,\n removeAttachment,\n clearAttachments,\n isUploadingAttachments,\n };\n}\n","import axios, { AxiosInstance } from 'axios';\nimport {\n StableDiffusionProvider,\n WhisperProvider,\n CharacterizationProvider,\n RatingsProvider,\n LoggerProvider,\n} from '../providers';\nimport { AttachmentPayload, TTSResult } from '../types';\nimport type { AlquimiaAdapter, AlquimiaSDKOptions } from '../adapters';\n\nclass AlquimiaSDK {\n private adapter: AlquimiaAdapter;\n private assistantId: string;\n private axiosInstance: AxiosInstance;\n private conversationId: string | null = null;\n private sessionId: string | null = null;\n private streamId: string | null = null;\n private evaluationStrategy: string | null = null;\n private tools: any = [];\n private extraData: any = null;\n private assistantConfig: any = null;\n private forceProfile: any = {};\n private userId: string | null = null;\n private whisperProvider?: WhisperProvider;\n private stableDiffusionProvider?: StableDiffusionProvider;\n private analyzeCharacterizationProvider?: CharacterizationProvider;\n private ratingsProvider?: RatingsProvider;\n private loggerProvider?: LoggerProvider;\n private enforceCharacterization?: boolean;\n private attachments: AttachmentPayload[] = [];\n private attachmentResponses: string[] = [];\n\n constructor(\n assistantId: string,\n adapter: AlquimiaAdapter,\n options: AlquimiaSDKOptions = {}\n ) {\n if (!assistantId) {\n throw new Error('AlquimiaSDK: assistantId is required');\n }\n if (!adapter) {\n throw new Error(\n 'AlquimiaSDK: adapter is required. Use createNextJsAdapter() or createFetchAdapter()'\n );\n }\n\n this.assistantId = assistantId;\n this.adapter = adapter;\n this.enforceCharacterization = options.enforceCharacterization ?? true;\n\n this.axiosInstance = axios.create();\n this.axiosInstance.interceptors.response.use(\n (response) => response,\n async (error) => {\n if (error.response?.status && this.loggerProvider) {\n await this.loggerProvider.logError('Server Error', error, {\n url: error.config.url,\n method: error.config.method,\n data: error.config.data,\n status: error.response.status,\n responseData: error.response.data,\n });\n }\n return Promise.reject(error);\n }\n );\n\n this.textToSpeech = this.textToSpeech.bind(this);\n this.speechToText = this.speechToText.bind(this);\n }\n\n withConversationId(conversationId: string): AlquimiaSDK {\n this.conversationId = conversationId;\n return this;\n }\n\n withAttachments(attachments: AttachmentPayload[]): AlquimiaSDK {\n this.attachments = attachments;\n return this;\n }\n\n withWhisperProvider(provider: WhisperProvider): AlquimiaSDK {\n this.whisperProvider = provider;\n return this;\n }\n\n withStableDiffusionProvider(provider: StableDiffusionProvider): AlquimiaSDK {\n this.stableDiffusionProvider = provider;\n return this;\n }\n\n withAnalyzeCharacterizationProvider(provider: CharacterizationProvider): AlquimiaSDK {\n this.analyzeCharacterizationProvider = provider;\n return this;\n }\n\n withRatingsProvider(provider: RatingsProvider): AlquimiaSDK {\n this.ratingsProvider = provider;\n return this;\n }\n\n withLoggerProvider(provider: LoggerProvider): AlquimiaSDK {\n this.loggerProvider = provider;\n return this;\n }\n\n withTools(tools: any): AlquimiaSDK {\n this.tools = tools;\n return this;\n }\n\n withExtraData(extraData: any): AlquimiaSDK {\n this.extraData = extraData;\n return this;\n }\n\n withForceProfile(forceProfile: any): AlquimiaSDK {\n this.forceProfile = forceProfile;\n return this;\n }\n\n withAssistantConfig(assistantConfig: any): AlquimiaSDK {\n this.assistantConfig = assistantConfig;\n return this;\n }\n\n withUserId(userId: string): AlquimiaSDK {\n this.userId = userId;\n return this;\n }\n\n getEnforceCharacterization(): boolean {\n return this.enforceCharacterization ?? true;\n }\n\n getEvaluationStrategy(): string | null {\n return this.evaluationStrategy;\n }\n\n textToSpeech(text: string): Promise<TTSResult> {\n if (!this.whisperProvider) {\n throw new Error('Whisper provider not initialized');\n }\n return this.whisperProvider.textToSpeech(text);\n }\n\n speechToText(audio: string): Promise<string> {\n if (!this.whisperProvider) {\n throw new Error('Whisper provider not initialized');\n }\n return this.whisperProvider.speechToText(audio);\n }\n\n async sendMessage(query: string, traceParent?: string): Promise<AlquimiaSDK> {\n if (!this.conversationId) {\n throw new Error(\n 'Conversation not initialized. Call withConversationId() before sendMessage()'\n );\n }\n\n const inferUrl = this.adapter.resolveInferUrl(this.assistantId);\n const adapterHeaders = this.adapter.getHeaders?.() ?? {};\n\n const initMessage = {\n query,\n session_id: this.conversationId,\n ...(this.extraData && { extra_data: this.extraData }),\n force_profile: this.forceProfile,\n ...(this.assistantConfig && { config: this.assistantConfig }),\n tools: this.tools,\n user_id: this.userId,\n attachments: this.attachments,\n };\n\n const result = (\n await this.axiosInstance.post(inferUrl, initMessage, {\n headers: {\n 'Content-Type': 'application/json',\n 'x-trace-parent': traceParent || '',\n ...adapterHeaders,\n },\n })\n ).data;\n\n this.evaluationStrategy =\n result?.config?.dante?.profile?.evaluation_strategy?.evaluation_strategy_id ?? null;\n this.streamId = result.stream_id;\n this.attachmentResponses = result.attachments ?? [];\n this.attachments = [];\n\n return this;\n }\n\n async generateImage(query: string): Promise<string> {\n if (!this.stableDiffusionProvider) {\n throw new Error('Stable Diffusion provider not initialized');\n }\n return this.stableDiffusionProvider.generateImage(query);\n }\n\n async analyzeCharacterization(text: string): Promise<Record<string, any>> {\n if (!this.analyzeCharacterizationProvider) {\n throw new Error('Analyze characterization provider not initialized');\n }\n return this.analyzeCharacterizationProvider.analyzeCharacterization(text);\n }\n\n async rate(data: any): Promise<Record<string, any>> {\n if (!this.ratingsProvider) {\n throw new Error('Ratings provider not initialized');\n }\n return this.ratingsProvider.rate(data);\n }\n\n async logInfo(message: string, data: any): Promise<void> {\n if (!this.loggerProvider) {\n throw new Error('Logger provider not initialized');\n }\n return this.loggerProvider.logInfo(message, data);\n }\n\n async logError(message: string, error: Error, data: any): Promise<void> {\n if (!this.loggerProvider) {\n throw new Error('Logger provider not initialized');\n }\n return this.loggerProvider.logError(message, error, data);\n }\n\n getAttachmentResponses(): string[] {\n return this.attachmentResponses;\n }\n\n async uploadAttachment(file: File, attachmentId: string): Promise<void> {\n if (!this.streamId || !attachmentId) {\n throw new Error('Stream or attachment ID not initialized');\n }\n const url = this.adapter.resolveAttachmentUrl(this.streamId, attachmentId);\n const adapterHeaders = this.adapter.getHeaders?.() ?? {};\n const formData = new FormData();\n formData.append('file', file);\n await this.axiosInstance.post(url, formData, {\n headers: { 'Content-Type': 'multipart/form-data', ...adapterHeaders },\n });\n }\n\n getUrlStream(): string {\n if (!this.streamId) {\n throw new Error('Stream ID not initialized. Call sendMessage() first');\n }\n return this.adapter.resolveStreamUrl(this.streamId);\n }\n\n getStreamId(): string | null {\n return this.streamId;\n }\n}\n\nexport default AlquimiaSDK;\n","import {\n BaseAPIConfig,\n ApiError,\n ConversationsMap,\n ThinkingsInferenceResponse,\n Tooler,\n ToolEvent,\n} from \"../types/type\";\n\nexport function generateTranslatePrompt(text: string) {\n const prompt = `\n Arrange the following text according to the given object structure and return it as plain json, values summarized to one word, no formatting:\n {\n restrictions: {\n value: [''],\n description: 'Restrictions to certain foods'\n },\n alergies: {\n value: [''],\n description: 'Alergies to certain foods'\n },\n wine_preference: {\n value: [''],\n description: 'Preferences for the wine'\n },\n meal_preference: {\n value: [''],\n description: 'Preferences for the meal'\n }\n }\n\n Text: \"${text}\"\n\n Output:\n `;\n\n return prompt;\n}\n\nexport function getCookies(name: string) {\n if (typeof document === \"undefined\") return undefined;\n const value = `; ${document.cookie}`;\n const parts = value.split(`; ${name}=`);\n if (parts.length === 2) return parts.pop()?.split(\";\").shift();\n}\n\nexport function generateHeaders(config: BaseAPIConfig): HeadersInit {\n const headers: HeadersInit = {\n \"Content-Type\": \"application/json\",\n };\n\n if (config.token) {\n headers[\"Authorization\"] = `Bearer ${config.token}`;\n }\n\n if (config.headers) {\n Object.entries(config.headers).forEach(([key, value]) => {\n headers[key] = value;\n });\n }\n\n return headers;\n}\n\nexport function isTextContent(buffer: ArrayBuffer): boolean {\n try {\n const text = new TextDecoder().decode(buffer);\n const trimmedText = text.trim();\n\n return (\n /^[\\w\\#\\-\\*\\|\\[\\]\\-\\+\\=\\s\\n\\r\\t\\!]/.test(trimmedText) ||\n trimmedText.startsWith(\"#\") ||\n trimmedText.startsWith(\"![\") ||\n trimmedText.startsWith(\"```\") ||\n trimmedText.startsWith(\"---\") ||\n /^[a-zA-Z0-9\\s\\n\\r\\t]/.test(trimmedText) ||\n /^\\!\\[.*\\]\\(.*\\)/.test(trimmedText)\n );\n } catch {\n return false;\n }\n}\n\nexport function getQueryParam(param: string): string | null {\n if (typeof window !== \"undefined\") {\n const urlParams = new URLSearchParams(window.location.search);\n return urlParams.get(param);\n }\n return null;\n}\n\nexport function defineAssistantId(defaultId: string): string {\n if (typeof window !== \"undefined\" && window.location.pathname === \"/\") {\n const queryAssistantId = getQueryParam(\"talkwith\");\n if (queryAssistantId) {\n localStorage.setItem(\"assistantId\", queryAssistantId);\n return queryAssistantId;\n }\n const storedAssistantId = localStorage.getItem(\"assistantId\");\n return storedAssistantId || defaultId;\n }\n return defaultId;\n}\n\nexport function formatTimeWithUnit(timeMs: number): string {\n if (timeMs >= 1000) {\n return `${(timeMs / 1000).toFixed(1)}s`;\n }\n return `${Math.round(timeMs)}ms`;\n}\n\nexport function serializeAxiosError(error: unknown) {\n if (error instanceof Error) {\n const customError = error as ApiError;\n return {\n message: customError?.message,\n name: customError?.name,\n stack: customError?.stack,\n code: customError?.code,\n status: customError?.status,\n };\n }\n return {\n message: String(error),\n name: \"Unknown Error\",\n };\n}\n\nexport function parseConversationsMapCookie(\n cookieValue: string\n): ConversationsMap {\n try {\n const decodedValue = decodeURIComponent(cookieValue);\n return JSON.parse(decodedValue) as ConversationsMap;\n } catch (e) {\n console.error(\"Error parsing conversations cookie:\", e);\n return {};\n }\n}\n\nexport function getTopicSessionId(topicId: string): string {\n const conversationsStr = getCookies(\"alquimia-sessions\") || \"{}\";\n if (!conversationsStr) {\n const sessionCookie = getCookies(\"alquimia-session\");\n return sessionCookie || \"\";\n }\n\n const conversationsMap = parseConversationsMapCookie(conversationsStr);\n return conversationsMap[topicId] || \"\";\n}\n\nexport function createMessageId() {\n return Math.floor(Math.random() * 1000000).toString();\n}\n\nexport function hasToolSummary(data: any) {\n return data.tool_summary && Object.keys(data.tool_summary).length > 0;\n}\n\nexport function mergeThinkingsByControlId(\n existingThinkings: ThinkingsInferenceResponse[] = [],\n newThinkings: ThinkingsInferenceResponse[] = []\n): ThinkingsInferenceResponse[] {\n const thinkingsMap = new Map(existingThinkings.map((t) => [t.control_id, t]));\n for (const t of newThinkings) {\n if (t && t.control_id) {\n thinkingsMap.set(t.control_id, t);\n }\n }\n return Array.from(thinkingsMap.values());\n}\n\n\nexport function mergeToolerByControlId(\n currentTooler: Tooler[],\n toolEvent: ToolEvent\n): Tooler[] {\n const { event_class, control_id, data, status } = toolEvent;\n const existingTool = currentTooler.find((t) => t.control_id === control_id);\n const base: Tooler = existingTool || { control_id };\n\n let updated: Tooler;\n switch (event_class) {\n case \"ServerToolExecutionCommand\":\n updated = {\n ...base,\n tool_summary: {\n name: data.name,\n parameters: data,\n },\n };\n break;\n case \"ToolExecutionResponse\":\n updated = {\n ...base,\n tool_output: {\n result: data,\n status,\n },\n };\n break;\n case \"A2AInferenceCommand\":\n updated = {\n ...base,\n tool_summary: {\n name: data.name,\n parameters: { ...data, type: \"A2A\" },\n },\n };\n break;\n default:\n return currentTooler;\n }\n\n return currentTooler.some(tool => tool.control_id === control_id)\n ? currentTooler.map(tool => (tool.control_id === control_id ? updated : tool))\n : [...currentTooler, updated];\n}\n\nexport function mergeToolEvents(\n initial: Tooler[],\n toolEvents?: ToolEvent[]\n): Tooler[] {\n return (toolEvents ?? []).reduce(\n (acc, toolEvent) => mergeToolerByControlId(acc, toolEvent),\n initial\n );\n}\n","\nimport { useState, useReducer } from \"react\";\nimport { RatingData } from \"../types/type\";\nimport { getTopicSessionId } from \"../utils/utils\";\n\ninterface RatingState {\n ratingStars: number;\n ratingThumbs: \"thumbsUp\" | \"thumbsDown\" | \"\";\n ratingComment: string;\n}\n\ntype RatingAction =\n | { type: \"SET_RATING_STARS\"; payload: number }\n | { type: \"SET_RATING_THUMBS\"; payload: \"thumbsUp\" | \"thumbsDown\" | \"\" }\n | { type: \"SET_RATING_COMMENT\"; payload: string };\n\nconst initialState: RatingState = {\n ratingStars: 0,\n ratingThumbs: \"\",\n ratingComment: \"\",\n};\n\nfunction ratingReducer(state: RatingState, action: RatingAction): RatingState {\n switch (action.type) {\n case \"SET_RATING_STARS\":\n return { ...state, ratingStars: action.payload };\n case \"SET_RATING_THUMBS\":\n return { ...state, ratingThumbs: action.payload };\n case \"SET_RATING_COMMENT\":\n return { ...state, ratingComment: action.payload };\n default:\n return state;\n }\n}\n\ninterface UseRatingsParams {\n assistantId: string;\n topicId: string;\n sendRating: (ratingData: RatingData) => Promise<any>;\n onError?: (componentName: string, error: Error) => void;\n}\n\n\nexport function useRatings({ assistantId, sendRating, topicId }: UseRatingsParams) {\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [hasReviewed, setHasReviewed] = useState<boolean>(false);\n const [state, dispatch] = useReducer(ratingReducer, initialState);\n\n const setRatingStars = (rating: number) => {\n dispatch({ type: \"SET_RATING_STARS\", payload: rating });\n };\n\n const setRatingThumbs = (rating: \"thumbsUp\" | \"thumbsDown\" | \"\") => {\n dispatch({ type: \"SET_RATING_THUMBS\", payload: rating });\n };\n\n const setRatingComment = (comment: string) => {\n dispatch({ type: \"SET_RATING_COMMENT\", payload: comment });\n };\n\n const thumbsScore = (value: string) => {\n return value === \"thumbsUp\" ? 5 : value === \"thumbsDown\" ? 0 : 0;\n }\n\n const handleRate = async (key: string, value: any | string, onHandleRateSuccess: (success: boolean, err?: string) => void) => {\n setIsLoading(true);\n const sessionId = getTopicSessionId(topicId);\n\n const ratingObj: RatingData = {\n topicId: parseInt(topicId),\n sessionId: sessionId || \"\",\n assistantId: assistantId,\n score: key === \"score\" ? value : thumbsScore(value),\n description: key === \"description\" ? value : state.ratingComment,\n };\n\n try {\n const response = await sendRating(ratingObj);\n if (!response.success) {\n setIsLoading(false);\n onHandleRateSuccess(false, response.error.message);\n return;\n }\n \n if (key === \"score\") {\n setRatingStars(value);\n } else if (key === \"description\") {\n setRatingComment(value);\n }\n setHasReviewed(true);\n setIsLoading(false);\n onHandleRateSuccess(true);\n } catch (err) {\n setIsLoading(false);\n onHandleRateSuccess(false, String(err));\n }\n };\n\n return {\n handleRate,\n ratingStars: state.ratingStars,\n ratingThumbs: state.ratingThumbs,\n ratingComment: state.ratingComment,\n isLoading,\n hasReviewed\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAA0C;;;ACA1C,mBAAqC;AAWrC,IAAM,cAAN,MAAkB;AAAA,EAsBhB,YACE,aACA,SACA,UAA8B,CAAC,GAC/B;AAtBF,SAAQ,iBAAgC;AACxC,SAAQ,YAA2B;AACnC,SAAQ,WAA0B;AAClC,SAAQ,qBAAoC;AAC5C,SAAQ,QAAa,CAAC;AACtB,SAAQ,YAAiB;AACzB,SAAQ,kBAAuB;AAC/B,SAAQ,eAAoB,CAAC;AAC7B,SAAQ,SAAwB;AAOhC,SAAQ,cAAmC,CAAC;AAC5C,SAAQ,sBAAgC,CAAC;AAOvC,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,SAAK,cAAc;AACnB,SAAK,UAAU;AACf,SAAK,0BAA0B,QAAQ,2BAA2B;AAElE,SAAK,gBAAgB,aAAAA,QAAM,OAAO;AAClC,SAAK,cAAc,aAAa,SAAS;AAAA,MACvC,CAAC,aAAa;AAAA,MACd,OAAO,UAAU;AACf,YAAI,MAAM,UAAU,UAAU,KAAK,gBAAgB;AACjD,gBAAM,KAAK,eAAe,SAAS,gBAAgB,OAAO;AAAA,YACxD,KAAK,MAAM,OAAO;AAAA,YAClB,QAAQ,MAAM,OAAO;AAAA,YACrB,MAAM,MAAM,OAAO;AAAA,YACnB,QAAQ,MAAM,SAAS;AAAA,YACvB,cAAc,MAAM,SAAS;AAAA,UAC/B,CAAC;AAAA,QACH;AACA,eAAO,QAAQ,OAAO,KAAK;AAAA,MAC7B;AAAA,IACF;AAEA,SAAK,eAAe,KAAK,aAAa,KAAK,IAAI;AAC/C,SAAK,eAAe,KAAK,aAAa,KAAK,IAAI;AAAA,EACjD;AAAA,EAEA,mBAAmB,gBAAqC;AACtD,SAAK,iBAAiB;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,aAA+C;AAC7D,SAAK,cAAc;AACnB,WAAO;AAAA,EACT;AAAA,EAEA,oBAAoB,UAAwC;AAC1D,SAAK,kBAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,4BAA4B,UAAgD;AAC1E,SAAK,0BAA0B;AAC/B,WAAO;AAAA,EACT;AAAA,EAEA,oCAAoC,UAAiD;AACnF,SAAK,kCAAkC;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,oBAAoB,UAAwC;AAC1D,SAAK,kBAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,mBAAmB,UAAuC;AACxD,SAAK,iBAAiB;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,OAAyB;AACjC,SAAK,QAAQ;AACb,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,WAA6B;AACzC,SAAK,YAAY;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,cAAgC;AAC/C,SAAK,eAAe;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,oBAAoB,iBAAmC;AACrD,SAAK,kBAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,QAA6B;AACtC,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA,EAEA,6BAAsC;AACpC,WAAO,KAAK,2BAA2B;AAAA,EACzC;AAAA,EAEA,wBAAuC;AACrC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAa,MAAkC;AAC7C,QAAI,CAAC,KAAK,iBAAiB;AACzB,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AACA,WAAO,KAAK,gBAAgB,aAAa,IAAI;AAAA,EAC/C;AAAA,EAEA,aAAa,OAAgC;AAC3C,QAAI,CAAC,KAAK,iBAAiB;AACzB,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AACA,WAAO,KAAK,gBAAgB,aAAa,KAAK;AAAA,EAChD;AAAA,EAEA,MAAM,YAAY,OAAe,aAA4C;AAC3E,QAAI,CAAC,KAAK,gBAAgB;AACxB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,QAAQ,gBAAgB,KAAK,WAAW;AAC9D,UAAM,iBAAiB,KAAK,QAAQ,aAAa,KAAK,CAAC;AAEvD,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,GAAI,KAAK,aAAa,EAAE,YAAY,KAAK,UAAU;AAAA,MACnD,eAAe,KAAK;AAAA,MACpB,GAAI,KAAK,mBAAmB,EAAE,QAAQ,KAAK,gBAAgB;AAAA,MAC3D,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,IACpB;AAEA,UAAM,UACJ,MAAM,KAAK,cAAc,KAAK,UAAU,aAAa;AAAA,MACnD,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,kBAAkB,eAAe;AAAA,QACjC,GAAG;AAAA,MACL;AAAA,IACF,CAAC,GACD;AAEF,SAAK,qBACH,QAAQ,QAAQ,OAAO,SAAS,qBAAqB,0BAA0B;AACjF,SAAK,WAAW,OAAO;AACvB,SAAK,sBAAsB,OAAO,eAAe,CAAC;AAClD,SAAK,cAAc,CAAC;AAEpB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,OAAgC;AAClD,QAAI,CAAC,KAAK,yBAAyB;AACjC,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AACA,WAAO,KAAK,wBAAwB,cAAc,KAAK;AAAA,EACzD;AAAA,EAEA,MAAM,wBAAwB,MAA4C;AACxE,QAAI,CAAC,KAAK,iCAAiC;AACzC,YAAM,IAAI,MAAM,mDAAmD;AAAA,IACrE;AACA,WAAO,KAAK,gCAAgC,wBAAwB,IAAI;AAAA,EAC1E;AAAA,EAEA,MAAM,KAAK,MAAyC;AAClD,QAAI,CAAC,KAAK,iBAAiB;AACzB,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AACA,WAAO,KAAK,gBAAgB,KAAK,IAAI;AAAA,EACvC;AAAA,EAEA,MAAM,QAAQ,SAAiB,MAA0B;AACvD,QAAI,CAAC,KAAK,gBAAgB;AACxB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,KAAK,eAAe,QAAQ,SAAS,IAAI;AAAA,EAClD;AAAA,EAEA,MAAM,SAAS,SAAiB,OAAc,MAA0B;AACtE,QAAI,CAAC,KAAK,gBAAgB;AACxB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,KAAK,eAAe,SAAS,SAAS,OAAO,IAAI;AAAA,EAC1D;AAAA,EAEA,yBAAmC;AACjC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,iBAAiB,MAAY,cAAqC;AACtE,QAAI,CAAC,KAAK,YAAY,CAAC,cAAc;AACnC,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AACA,UAAM,MAAM,KAAK,QAAQ,qBAAqB,KAAK,UAAU,YAAY;AACzE,UAAM,iBAAiB,KAAK,QAAQ,aAAa,KAAK,CAAC;AACvD,UAAM,WAAW,IAAI,SAAS;AAC9B,aAAS,OAAO,QAAQ,IAAI;AAC5B,UAAM,KAAK,cAAc,KAAK,KAAK,UAAU;AAAA,MAC3C,SAAS,EAAE,gBAAgB,uBAAuB,GAAG,eAAe;AAAA,IACtE,CAAC;AAAA,EACH;AAAA,EAEA,eAAuB;AACrB,QAAI,CAAC,KAAK,UAAU;AAClB,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AACA,WAAO,KAAK,QAAQ,iBAAiB,KAAK,QAAQ;AAAA,EACpD;AAAA,EAEA,cAA6B;AAC3B,WAAO,KAAK;AAAA,EACd;AACF;AAEA,IAAO,uBAAQ;;;AC3NR,SAAS,WAAW,MAAc;AACvC,MAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,QAAM,QAAQ,KAAK,SAAS,MAAM;AAClC,QAAM,QAAQ,MAAM,MAAM,KAAK,IAAI,GAAG;AACtC,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,IAAI,GAAG,MAAM,GAAG,EAAE,MAAM;AAC/D;AAoFO,SAAS,4BACd,aACkB;AAClB,MAAI;AACF,UAAM,eAAe,mBAAmB,WAAW;AACnD,WAAO,KAAK,MAAM,YAAY;AAAA,EAChC,SAAS,GAAG;AACV,YAAQ,MAAM,uCAAuC,CAAC;AACtD,WAAO,CAAC;AAAA,EACV;AACF;AAEO,SAAS,kBAAkB,SAAyB;AACzD,QAAM,mBAAmB,WAAW,mBAAmB,KAAK;AAC5D,MAAI,CAAC,kBAAkB;AACrB,UAAM,gBAAgB,WAAW,kBAAkB;AACnD,WAAO,iBAAiB;AAAA,EAC1B;AAEA,QAAM,mBAAmB,4BAA4B,gBAAgB;AACrE,SAAO,iBAAiB,OAAO,KAAK;AACtC;AAEO,SAAS,kBAAkB;AAChC,SAAO,KAAK,MAAM,KAAK,OAAO,IAAI,GAAO,EAAE,SAAS;AACtD;AAMO,SAAS,0BACd,oBAAkD,CAAC,GACnD,eAA6C,CAAC,GAChB;AAC9B,QAAM,eAAe,IAAI,IAAI,kBAAkB,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;AAC5E,aAAW,KAAK,cAAc;AAC5B,QAAI,KAAK,EAAE,YAAY;AACrB,mBAAa,IAAI,EAAE,YAAY,CAAC;AAAA,IAClC;AAAA,EACF;AACA,SAAO,MAAM,KAAK,aAAa,OAAO,CAAC;AACzC;AAGO,SAAS,uBACd,eACA,WACU;AACV,QAAM,EAAE,aAAa,YAAY,MAAM,OAAO,IAAI;AAClD,QAAM,eAAe,cAAc,KAAK,CAAC,MAAM,EAAE,eAAe,UAAU;AAC1E,QAAM,OAAe,gBAAgB,EAAE,WAAW;AAElD,MAAI;AACJ,UAAQ,aAAa;AAAA,IACnB,KAAK;AACH,gBAAU;AAAA,QACR,GAAG;AAAA,QACH,cAAc;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,YAAY;AAAA,QACd;AAAA,MACF;AACA;AAAA,IACF,KAAK;AACH,gBAAU;AAAA,QACR,GAAG;AAAA,QACH,aAAa;AAAA,UACX,QAAQ;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF,KAAK;AACH,gBAAU;AAAA,QACR,GAAG;AAAA,QACH,cAAc;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,YAAY,EAAE,GAAG,MAAM,MAAM,MAAM;AAAA,QACrC;AAAA,MACF;AACA;AAAA,IACF;AACE,aAAO;AAAA,EACX;AAEA,SAAO,cAAc,KAAK,UAAQ,KAAK,eAAe,UAAU,IAC5D,cAAc,IAAI,UAAS,KAAK,eAAe,aAAa,UAAU,IAAK,IAC3E,CAAC,GAAG,eAAe,OAAO;AAChC;AAEO,SAAS,gBACd,SACA,YACU;AACV,UAAQ,cAAc,CAAC,GAAG;AAAA,IACxB,CAAC,KAAK,cAAc,uBAAuB,KAAK,SAAS;AAAA,IACzD;AAAA,EACF;AACF;;;AFhMO,SAAS,YAAY,QAA2B;AACrD,QAAM,UAAM,sBAAQ,MAAM;AACxB,UAAM,WAAW,IAAI,qBAAY,OAAO,aAAa,OAAO,SAAS;AAAA,MACnE,yBAAyB,OAAO,SAAS;AAAA,IAC3C,CAAC;AAED,QAAI,OAAO,WAAW,QAAS,UAAS,oBAAoB,OAAO,UAAU,OAAO;AACpF,QAAI,OAAO,WAAW,gBAAiB,UAAS,4BAA4B,OAAO,UAAU,eAAe;AAC5G,QAAI,OAAO,WAAW,iBAAkB,UAAS,oCAAoC,OAAO,UAAU,gBAAgB;AACtH,QAAI,OAAO,WAAW,QAAS,UAAS,oBAAoB,OAAO,UAAU,OAAO;AACpF,QAAI,OAAO,WAAW,OAAQ,UAAS,mBAAmB,OAAO,UAAU,MAAM;AACjF,QAAI,OAAO,SAAS,OAAQ,UAAS,WAAW,OAAO,QAAQ,MAAM;AACrE,QAAI,OAAO,SAAS,UAAW,UAAS,cAAc,OAAO,QAAQ,SAAS;AAE9E,WAAO;AAAA,EAET,GAAG,CAAC,OAAO,aAAa,OAAO,OAAO,CAAC;AAEvC,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAiB,EAAE;AAC7C,QAAM,CAAC,kBAAkB,mBAAmB,QAAI,uBAAkB,KAAK;AACvE,QAAM,CAAC,oBAAoB,qBAAqB,QAAI,uBAAkB,KAAK;AAC3E,QAAM,CAAC,oBAAoB,qBAAqB,QAAI,uBAAkB,KAAK;AAC3E,QAAM,CAAC,oBAAoB,qBAAqB,QAAI,uBAAwB,IAAI;AAChF,QAAM,CAAC,kBAAkB,mBAAmB,QAAI,uBAAkB,KAAK;AACvE,QAAM,CAAC,UAAU,WAAW,QAAI,uBAA4B,CAAC,CAAC;AAC9D,QAAM,qBAAiB,qBAA2B,IAAI;AACtD,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAwB,IAAI;AAC9D,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAqB,IAAI;AAC7D,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAwB,IAAI;AAClE,QAAM,CAAC,oBAAoB,qBAAqB,QAAI,uBAAiB,EAAE;AACvE,QAAM,CAAC,cAAc,eAAe,QAAI,uBAAkB,KAAK;AAC/D,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAiB,CAAC,CAAC;AACzD,QAAM,CAAC,wBAAwB,yBAAyB,QAAI,uBAAkB,KAAK;AAEnF,QAAM,YAAY,oBAAoB,sBAAsB;AAE5D,WAAS,gBAAgB;AACvB,gBAAY,CAAC,CAAC;AACd,oBAAgB,KAAK;AAAA,EACvB;AAEA,WAAS,cAAc,MAAY;AACjC,mBAAe,CAAC,SAAS,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,EAC1C;AAEA,WAAS,eAAe,OAAe;AACrC,mBAAe,CAAC,SAAS,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC;AAAA,EAC9C;AAEA,WAAS,iBAAiB,OAAe;AACvC,mBAAe,CAAC,SAAS,KAAK,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,CAAC;AAAA,EAC7D;AAEA,WAAS,mBAAmB;AAC1B,mBAAe,CAAC,CAAC;AAAA,EACnB;AAEA,WAAS,oBACP,WACA,OACA,YACA,cACA,WACA,gBACA,SACA,QACA,WACA;AACA,gBAAY,CAAC,oBAAoB;AAC/B,YAAM,eAAe,gBAAgB,UAAU,CAAC,YAAY,SAAS,OAAO,SAAS;AACrF,UAAI,iBAAiB,IAAI;AACvB,cAAM,kBAAkB,CAAC,GAAG,eAAe;AAC3C,cAAM,iBAAkC;AAAA,UACtC,GAAG,gBAAgB,YAAY;AAAA,UAC/B,SAAS,GAAG,gBAAgB,YAAY,GAAG,WAAW,EAAE,GAAG,KAAK;AAAA,UAChE,IAAI,gBAAgB,YAAY,GAAG,MAAM;AAAA,UACzC,MAAM,gBAAgB,YAAY,GAAG,QAAQ;AAAA,UAC7C;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,aAAY,oBAAI,KAAK,GAAE,QAAQ,EAAE,SAAS;AAAA,UAC1C;AAAA,UACA,QAAQ,gBAAgB,gBAAgB,YAAY,GAAG,UAAU,CAAC,GAAG,MAAM;AAAA,UAC3E,WAAW;AAAA,YACT,gBAAgB,YAAY,GAAG,aAAa,CAAC;AAAA,YAC7C,aAAa,CAAC;AAAA,UAChB;AAAA,QACF;AACA,wBAAgB,YAAY,IAAI;AAChC,eAAO;AAAA,MACT,OAAO;AACL,eAAO;AAAA,UACL,GAAG;AAAA,UACH;AAAA,YACE,SAAS,GAAG,KAAK;AAAA,YACjB,MAAM;AAAA,YACN,IAAI;AAAA,YACJ;AAAA,YACA;AAAA,YACA;AAAA,YACA,aAAY,oBAAI,KAAK,GAAE,QAAQ,EAAE,SAAS;AAAA,YAC1C;AAAA,YACA,QAAQ,gBAAgB,CAAC,GAAG,MAAM;AAAA,YAClC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,iBAAe,sBACb,SACA,SAMA;AACA,mBAAe,SAAS,SAAS,WAAW;AAE5C,UAAM,YAAY,gBAAgB;AAClC,0BAAsB,SAAS;AAE/B,UAAM;AAAA,MACJ;AAAA,MACA,CAAC,UAA0B;AACzB;AAAA,UACE;AAAA,UACA,OAAO,UAAU;AAAA,UACjB,OAAO;AAAA,UACP,OAAO;AAAA,UACP,OAAO;AAAA,UACP,SAAS;AAAA,UACT,OAAO;AAAA,UACP,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAEA,aAAS,EAAE;AAAA,EACb;AAEA,iBAAe,aACb,OACA,eACAC,YACA,gBACA;AACA,wBAAoB,IAAI;AACxB,UAAM,eAAe;AAErB,QAAI,OAAO;AACT,YAAM,sBAAsB,OAAO,EAAE,eAAe,WAAAA,YAAW,eAAe,CAAC;AAAA,IACjF;AAEA,wBAAoB,KAAK;AAAA,EAC3B;AAEA,iBAAe,oBACb,SACA,SAMA;AACA,wBAAoB,IAAI;AAExB,UAAM,sBAAsB,SAAS;AAAA,MACnC,aAAa,SAAS,eAAe;AAAA,MACrC,eAAe,SAAS;AAAA,MACxB,WAAW,SAAS;AAAA,MACpB,gBAAgB,SAAS;AAAA,IAC3B,CAAC;AAED,wBAAoB,KAAK;AAAA,EAC3B;AAEA,WAAS,kBAAkB,OAA+C;AACxE,aAAS,MAAM,OAAO,KAAK;AAAA,EAC7B;AAEA,WAAS,mBAAmBC,QAAe;AACzC,aAASA,MAAK;AAAA,EAChB;AAEA,WAAS,iBAAiBC,WAA6B;AACrD,gBAAYA,SAAQ;AAAA,EACtB;AAEA,WAAS,sBAAsB;AAC7B,mBAAe,SAAS,MAAM;AAC9B,mBAAe,UAAU;AACzB,wBAAoB,KAAK;AACzB,0BAAsB,KAAK;AAC3B,0BAAsB,IAAI;AAC1B,0BAAsB,KAAK;AAC3B,8BAA0B,KAAK;AAC/B,aAAS,EAAE;AAAA,EACb;AAEA,WAAS,eAAe,SAAiB,MAAe;AACtD,gBAAY,CAAC,iBAAoC;AAAA,MAC/C,GAAG;AAAA,MACH;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN;AAAA,QACA,IAAI,gBAAgB;AAAA,QACpB,aAAY,oBAAI,KAAK,GAAE,QAAQ,EAAE,SAAS;AAAA,MAC5C;AAAA,IACF,CAAC;AAAA,EACH;AAEA,WAAS,UAAU,MAA6B;AAC9C,UAAM,UAAU,SAAS,OAAO,MAAM,GAAG;AACzC,eAAW,UAAU,SAAS;AAC5B,YAAM,CAAC,YAAY,WAAW,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG;AACzD,UAAI,eAAe,MAAM;AACvB,eAAO,mBAAmB,WAAqB;AAAA,MACjD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,WAAS,QAAQ,aAAsB,OAAoB;AACzD,0BAAsB,WAAW;AACjC,0BAAsB,IAAI;AAC1B,0BAAsB,KAAK;AAC3B,UAAM,MAAM;AAAA,EACd;AAEA,iBAAe,YACb,SACA,UACA,eACAF,YACA;AACA,0BAAsB,IAAI;AAC1B,aAAS,EAAE,MAAM,WAAW,SAAS,KAAK,CAAC;AAC3C,UAAM,iBAAiBA,cAAa,UAAU,kBAAkB;AAChE,0BAAsB,IAAI;AAC1B,kBAAc,IAAI;AAClB,mBAAe,OAAO;AAEtB,QAAI;AACF,YAAM,iBAAiB,YAAY,SAAS;AAC5C,YAAM,UAAU,IAAI,mBAAmB,kBAAkB,EAAE;AAE3D,UAAI,gBAAgB;AAClB,gBAAQ;AAAA,UACN,YAAY,IAAI,CAAC,OAAO;AAAA,YACtB,UAAU,EAAE;AAAA,YACZ,cAAc,EAAE;AAAA,YAChB,cAAc,EAAE;AAAA,UAClB,EAAE;AAAA,QACJ;AAAA,MACF;AAEA,YAAM,WAAW,MAAM,QAAQ,YAAY,SAAS,aAAa;AAEjE,UAAI,gBAAgB;AAClB,kCAA0B,IAAI;AAC9B,YAAI;AACF,gBAAM,sBAAsB,SAAS,uBAAuB;AAC5D,gBAAM,QAAQ;AAAA,YACZ,YAAY,IAAI,CAAC,MAAM,MAAM,SAAS,iBAAiB,MAAM,oBAAoB,CAAC,CAAC,CAAC;AAAA,UACtF;AAAA,QACF,SAAS,aAAkB;AACzB,oCAA0B,KAAK;AAC/B,gCAAsB,KAAK;AAC3B,gCAAsB,IAAI;AAC1B,gCAAsB,KAAK;AAC3B,mBAAS;AAAA,YACP,MAAM;AAAA,YACN,YAAY;AAAA,YACZ,cAAc,YAAY,WAAW;AAAA,UACvC,CAAC;AACD;AAAA,QACF;AACA,kCAA0B,KAAK;AAC/B,yBAAiB;AAAA,MACnB;AAEA,YAAM,YAAY,SAAS,aAAa;AACxC,YAAM,WAAW,SAAS,YAAY,KAAK;AAC3C,YAAM,cAAc;AAAA,QAClB;AAAA,QACA,aAAa,KAAK,IAAI;AAAA,QACtB,UAAU;AAAA,QACV,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,gBAAgB;AAAA,MAClB;AAEA,YAAM,cAAc,IAAI,YAAY,SAAS;AAC7C,qBAAe,UAAU;AACzB,YAAMG,sBAAqB,SAAS,sBAAsB;AAC1D,4BAAsBA,mBAAkB;AAExC,kBAAY,SAAS,MAAM;AACzB,oBAAY,WAAW,KAAK,IAAI;AAAA,MAClC;AAEA,kBAAY,YAAY,CAAC,UAAU;AACjC,oBAAY;AACZ,oBAAY,gBAAgB,KAAK,IAAI;AACrC,2BAAmB,OAAO,UAAU,aAAa,WAAW;AAAA,MAC9D;AAEA,kBAAY,UAAU,MAAM;AAC1B,YAAI,YAAY,eAAgB;AAChC,oBAAY,iBAAiB;AAE7B,cAAM,UAAU,KAAK,IAAI,IAAI,YAAY;AACzC,cAAM,mBAAmB,YAAY,gBACjC,KAAK,IAAI,IAAI,YAAY,gBACzB;AAEJ,gBAAQ,OAAO,WAAW;AAE1B,YAAI;AACJ,YAAI,CAAC,YAAY,UAAU;AACzB,wBAAc,mCAAmC,OAAO,aAAa,SAAS;AAAA,QAChF,WAAW,YAAY,qBAAqB,GAAG;AAC7C,wBAAc,oEAAoE,OAAO;AAAA,QAC3F,OAAO;AACL,wBAAc,wBAAwB,YAAY,gBAAgB,gBAAgB,gBAAgB,gCAAgC,OAAO;AAAA,QAC3I;AAEA,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,cAAc;AAAA,UACd,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAY;AACnB,cAAQ,MAAM,0BAA0B,KAAK;AAC7C,YAAM,aACJ,MAAM,UAAU,MAAM,UAAU,MAAM,WAAW;AACnD,gCAA0B,KAAK;AAC/B,4BAAsB,KAAK;AAC3B,4BAAsB,IAAI;AAC1B,eAAS;AAAA,QACP,MAAM;AAAA,QACN,YAAY,MAAM,QAAQ,SAAS,KAAK;AAAA,QACxC,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,mBACP,OACA,UACA,aACA,aAKA;AACA,UAAM,OAA0B,KAAK,MAAM,MAAM,IAAI;AACrD,QAAI,KAAK,QAAQ,QAAQ;AACvB,iBAAW,SAAS,KAAK,QAAQ;AAC/B,cAAM,SACJ,MAAM,iBACL,MAAM,QAAQ,OACX,GAAG,MAAM,IAAI,gBAAgB,MAAM,UAAU,MAC7C;AACN,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,YAAY,MAAM,eAAe,MAAM,UAAU;AAAA,UACjD,cAAc;AAAA,UACd,WAAW,KAAK,aAAa;AAAA,QAC/B,CAAC;AAAA,MACH;AACA,UAAI,YAAa,aAAY,iBAAiB;AAC9C,cAAQ,OAAO,WAAW;AAC1B;AAAA,IACF;AAEA,QAAI,KAAK,cAAc,QAAQ;AAC7B,eAAS,EAAE,MAAM,UAAU,QAAQ,IAAI,QAAQ,KAAK,aAAa,CAAC;AAAA,IACpE;AAEA,QAAI,KAAK,WAAW,QAAQ;AAC1B,sBAAgB,IAAI;AACpB,eAAS,EAAE,MAAM,UAAU,WAAW,KAAK,UAAU,CAAC;AAAA,IACxD;AAEA,UAAM,WAAW,KAAK;AACtB,UAAM,UACJ,UAAU,gBAAgB,gCAAgC,OAAO,SAAS,SAAS,WAC/E,SAAS,OACT;AAEN,QAAI,SAAS;AACX,eAAS,EAAE,MAAM,UAAU,QAAQ,QAAQ,CAAC;AAC5C,UAAI,YAAa,aAAY,iBAAiB;AAC9C,cAAQ,OAAO,WAAW;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AGheA,IAAAC,gBAAqC;AAerC,IAAM,eAA4B;AAAA,EAChC,aAAa;AAAA,EACb,cAAc;AAAA,EACd,eAAe;AACjB;AAEA,SAAS,cAAc,OAAoB,QAAmC;AAC5E,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,aAAa,OAAO,QAAQ;AAAA,IACjD,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,cAAc,OAAO,QAAQ;AAAA,IAClD,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,eAAe,OAAO,QAAQ;AAAA,IACnD;AACE,aAAO;AAAA,EACX;AACF;AAUO,SAAS,WAAW,EAAE,aAAa,YAAY,QAAQ,GAAqB;AACjF,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAkB,KAAK;AACzD,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAkB,KAAK;AAC7D,QAAM,CAAC,OAAO,QAAQ,QAAI,0BAAW,eAAe,YAAY;AAEhE,QAAM,iBAAiB,CAAC,WAAmB;AACzC,aAAS,EAAE,MAAM,oBAAoB,SAAS,OAAO,CAAC;AAAA,EACxD;AAEA,QAAM,kBAAkB,CAAC,WAA2C;AAClE,aAAS,EAAE,MAAM,qBAAqB,SAAS,OAAO,CAAC;AAAA,EACzD;AAEA,QAAM,mBAAmB,CAAC,YAAoB;AAC5C,aAAS,EAAE,MAAM,sBAAsB,SAAS,QAAQ,CAAC;AAAA,EAC3D;AAEA,QAAM,cAAc,CAAC,UAAkB;AACrC,WAAO,UAAU,aAAa,IAAI,UAAU,eAAe,IAAI;AAAA,EACjE;AAEA,QAAM,aAAa,OAAO,KAAa,OAAqB,wBAAkE;AAC5H,iBAAa,IAAI;AACjB,UAAM,YAAY,kBAAkB,OAAO;AAE3C,UAAM,YAAwB;AAAA,MAC5B,SAAS,SAAS,OAAO;AAAA,MACzB,WAAY,aAAa;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ,UAAU,QAAQ,YAAY,KAAK;AAAA,MAClD,aAAa,QAAQ,gBAAgB,QAAQ,MAAM;AAAA,IACrD;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,WAAW,SAAS;AAC3C,UAAI,CAAC,SAAS,SAAS;AACrB,qBAAa,KAAK;AAClB,4BAAoB,OAAO,SAAS,MAAM,OAAO;AACjD;AAAA,MACF;AAEA,UAAI,QAAQ,SAAS;AACnB,uBAAe,KAAK;AAAA,MACtB,WAAW,QAAQ,eAAe;AAChC,yBAAiB,KAAK;AAAA,MACxB;AACA,qBAAe,IAAI;AACnB,mBAAa,KAAK;AAClB,0BAAoB,IAAI;AAAA,IAC1B,SAAS,KAAK;AACZ,mBAAa,KAAK;AAClB,0BAAoB,OAAO,OAAO,GAAG,CAAC;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,aAAa,MAAM;AAAA,IACnB,cAAc,MAAM;AAAA,IACpB,eAAe,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AACF;","names":["axios","sessionId","input","messages","evaluationStrategy","import_react"]}
@@ -1,5 +1,204 @@
1
1
  // src/hooks/alquimia.hook.tsx
2
- import { useRef, useState } from "react";
2
+ import { useMemo, useRef, useState } from "react";
3
+
4
+ // src/sdk/alquimia-sdk.ts
5
+ import axios from "axios";
6
+ var AlquimiaSDK = class {
7
+ constructor(assistantId, adapter, options = {}) {
8
+ this.conversationId = null;
9
+ this.sessionId = null;
10
+ this.streamId = null;
11
+ this.evaluationStrategy = null;
12
+ this.tools = [];
13
+ this.extraData = null;
14
+ this.assistantConfig = null;
15
+ this.forceProfile = {};
16
+ this.userId = null;
17
+ this.attachments = [];
18
+ this.attachmentResponses = [];
19
+ if (!assistantId) {
20
+ throw new Error("AlquimiaSDK: assistantId is required");
21
+ }
22
+ if (!adapter) {
23
+ throw new Error(
24
+ "AlquimiaSDK: adapter is required. Use createNextJsAdapter() or createFetchAdapter()"
25
+ );
26
+ }
27
+ this.assistantId = assistantId;
28
+ this.adapter = adapter;
29
+ this.enforceCharacterization = options.enforceCharacterization ?? true;
30
+ this.axiosInstance = axios.create();
31
+ this.axiosInstance.interceptors.response.use(
32
+ (response) => response,
33
+ async (error) => {
34
+ if (error.response?.status && this.loggerProvider) {
35
+ await this.loggerProvider.logError("Server Error", error, {
36
+ url: error.config.url,
37
+ method: error.config.method,
38
+ data: error.config.data,
39
+ status: error.response.status,
40
+ responseData: error.response.data
41
+ });
42
+ }
43
+ return Promise.reject(error);
44
+ }
45
+ );
46
+ this.textToSpeech = this.textToSpeech.bind(this);
47
+ this.speechToText = this.speechToText.bind(this);
48
+ }
49
+ withConversationId(conversationId) {
50
+ this.conversationId = conversationId;
51
+ return this;
52
+ }
53
+ withAttachments(attachments) {
54
+ this.attachments = attachments;
55
+ return this;
56
+ }
57
+ withWhisperProvider(provider) {
58
+ this.whisperProvider = provider;
59
+ return this;
60
+ }
61
+ withStableDiffusionProvider(provider) {
62
+ this.stableDiffusionProvider = provider;
63
+ return this;
64
+ }
65
+ withAnalyzeCharacterizationProvider(provider) {
66
+ this.analyzeCharacterizationProvider = provider;
67
+ return this;
68
+ }
69
+ withRatingsProvider(provider) {
70
+ this.ratingsProvider = provider;
71
+ return this;
72
+ }
73
+ withLoggerProvider(provider) {
74
+ this.loggerProvider = provider;
75
+ return this;
76
+ }
77
+ withTools(tools) {
78
+ this.tools = tools;
79
+ return this;
80
+ }
81
+ withExtraData(extraData) {
82
+ this.extraData = extraData;
83
+ return this;
84
+ }
85
+ withForceProfile(forceProfile) {
86
+ this.forceProfile = forceProfile;
87
+ return this;
88
+ }
89
+ withAssistantConfig(assistantConfig) {
90
+ this.assistantConfig = assistantConfig;
91
+ return this;
92
+ }
93
+ withUserId(userId) {
94
+ this.userId = userId;
95
+ return this;
96
+ }
97
+ getEnforceCharacterization() {
98
+ return this.enforceCharacterization ?? true;
99
+ }
100
+ getEvaluationStrategy() {
101
+ return this.evaluationStrategy;
102
+ }
103
+ textToSpeech(text) {
104
+ if (!this.whisperProvider) {
105
+ throw new Error("Whisper provider not initialized");
106
+ }
107
+ return this.whisperProvider.textToSpeech(text);
108
+ }
109
+ speechToText(audio) {
110
+ if (!this.whisperProvider) {
111
+ throw new Error("Whisper provider not initialized");
112
+ }
113
+ return this.whisperProvider.speechToText(audio);
114
+ }
115
+ async sendMessage(query, traceParent) {
116
+ if (!this.conversationId) {
117
+ throw new Error(
118
+ "Conversation not initialized. Call withConversationId() before sendMessage()"
119
+ );
120
+ }
121
+ const inferUrl = this.adapter.resolveInferUrl(this.assistantId);
122
+ const adapterHeaders = this.adapter.getHeaders?.() ?? {};
123
+ const initMessage = {
124
+ query,
125
+ session_id: this.conversationId,
126
+ ...this.extraData && { extra_data: this.extraData },
127
+ force_profile: this.forceProfile,
128
+ ...this.assistantConfig && { config: this.assistantConfig },
129
+ tools: this.tools,
130
+ user_id: this.userId,
131
+ attachments: this.attachments
132
+ };
133
+ const result = (await this.axiosInstance.post(inferUrl, initMessage, {
134
+ headers: {
135
+ "Content-Type": "application/json",
136
+ "x-trace-parent": traceParent || "",
137
+ ...adapterHeaders
138
+ }
139
+ })).data;
140
+ this.evaluationStrategy = result?.config?.dante?.profile?.evaluation_strategy?.evaluation_strategy_id ?? null;
141
+ this.streamId = result.stream_id;
142
+ this.attachmentResponses = result.attachments ?? [];
143
+ this.attachments = [];
144
+ return this;
145
+ }
146
+ async generateImage(query) {
147
+ if (!this.stableDiffusionProvider) {
148
+ throw new Error("Stable Diffusion provider not initialized");
149
+ }
150
+ return this.stableDiffusionProvider.generateImage(query);
151
+ }
152
+ async analyzeCharacterization(text) {
153
+ if (!this.analyzeCharacterizationProvider) {
154
+ throw new Error("Analyze characterization provider not initialized");
155
+ }
156
+ return this.analyzeCharacterizationProvider.analyzeCharacterization(text);
157
+ }
158
+ async rate(data) {
159
+ if (!this.ratingsProvider) {
160
+ throw new Error("Ratings provider not initialized");
161
+ }
162
+ return this.ratingsProvider.rate(data);
163
+ }
164
+ async logInfo(message, data) {
165
+ if (!this.loggerProvider) {
166
+ throw new Error("Logger provider not initialized");
167
+ }
168
+ return this.loggerProvider.logInfo(message, data);
169
+ }
170
+ async logError(message, error, data) {
171
+ if (!this.loggerProvider) {
172
+ throw new Error("Logger provider not initialized");
173
+ }
174
+ return this.loggerProvider.logError(message, error, data);
175
+ }
176
+ getAttachmentResponses() {
177
+ return this.attachmentResponses;
178
+ }
179
+ async uploadAttachment(file, attachmentId) {
180
+ if (!this.streamId || !attachmentId) {
181
+ throw new Error("Stream or attachment ID not initialized");
182
+ }
183
+ const url = this.adapter.resolveAttachmentUrl(this.streamId, attachmentId);
184
+ const adapterHeaders = this.adapter.getHeaders?.() ?? {};
185
+ const formData = new FormData();
186
+ formData.append("file", file);
187
+ await this.axiosInstance.post(url, formData, {
188
+ headers: { "Content-Type": "multipart/form-data", ...adapterHeaders }
189
+ });
190
+ }
191
+ getUrlStream() {
192
+ if (!this.streamId) {
193
+ throw new Error("Stream ID not initialized. Call sendMessage() first");
194
+ }
195
+ return this.adapter.resolveStreamUrl(this.streamId);
196
+ }
197
+ getStreamId() {
198
+ return this.streamId;
199
+ }
200
+ };
201
+ var alquimia_sdk_default = AlquimiaSDK;
3
202
 
4
203
  // src/utils/utils.ts
5
204
  function getCookies(name) {
@@ -38,22 +237,6 @@ function mergeThinkingsByControlId(existingThinkings = [], newThinkings = []) {
38
237
  }
39
238
  return Array.from(thinkingsMap.values());
40
239
  }
41
- function extractAnswerContent(content) {
42
- if (typeof content !== "string") return "";
43
- const trimmed = content.trim();
44
- if (trimmed.startsWith("{")) {
45
- try {
46
- const repaired = trimmed.replace(/(?<!\\)\n/g, "\\n");
47
- const parsed = JSON.parse(repaired);
48
- if (parsed && typeof parsed === "object" && "answer" in parsed) {
49
- return parsed.answer;
50
- }
51
- } catch (e) {
52
- return content;
53
- }
54
- }
55
- return content;
56
- }
57
240
  function mergeToolerByControlId(currentTooler, toolEvent) {
58
241
  const { event_class, control_id, data, status } = toolEvent;
59
242
  const existingTool = currentTooler.find((t) => t.control_id === control_id);
@@ -100,7 +283,20 @@ function mergeToolEvents(initial, toolEvents) {
100
283
  }
101
284
 
102
285
  // src/hooks/alquimia.hook.tsx
103
- function useAlquimia(sdk) {
286
+ function useAlquimia(config) {
287
+ const sdk = useMemo(() => {
288
+ const instance = new alquimia_sdk_default(config.assistantId, config.adapter, {
289
+ enforceCharacterization: config.options?.enforceCharacterization
290
+ });
291
+ if (config.providers?.whisper) instance.withWhisperProvider(config.providers.whisper);
292
+ if (config.providers?.stableDiffusion) instance.withStableDiffusionProvider(config.providers.stableDiffusion);
293
+ if (config.providers?.characterization) instance.withAnalyzeCharacterizationProvider(config.providers.characterization);
294
+ if (config.providers?.ratings) instance.withRatingsProvider(config.providers.ratings);
295
+ if (config.providers?.logger) instance.withLoggerProvider(config.providers.logger);
296
+ if (config.options?.userId) instance.withUserId(config.options.userId);
297
+ if (config.options?.extraData) instance.withExtraData(config.options.extraData);
298
+ return instance;
299
+ }, [config.assistantId, config.adapter]);
104
300
  const [input, setInput] = useState("");
105
301
  const [isMessageLoading, setIsMessageLoading] = useState(false);
106
302
  const [isStreamingLoading, setIsStreamingLoading] = useState(false);
@@ -135,9 +331,7 @@ function useAlquimia(sdk) {
135
331
  }
136
332
  function processMessageChunk(messageId, chunk, error_code, error_detail, stream_id, additionalInfo, loading, tooler, thinkings) {
137
333
  setMessages((currentMessages) => {
138
- const messageIndex = currentMessages.findIndex(
139
- (message) => message?.id === messageId
140
- );
334
+ const messageIndex = currentMessages.findIndex((message) => message?.id === messageId);
141
335
  if (messageIndex !== -1) {
142
336
  const updatedMessages = [...currentMessages];
143
337
  const updatedMessage = {
@@ -151,10 +345,7 @@ function useAlquimia(sdk) {
151
345
  additionalInfo,
152
346
  created_at: (/* @__PURE__ */ new Date()).getTime().toString(),
153
347
  loading,
154
- tooler: mergeToolEvents(
155
- updatedMessages[messageIndex]?.tooler || [],
156
- tooler
157
- ),
348
+ tooler: mergeToolEvents(updatedMessages[messageIndex]?.tooler || [], tooler),
158
349
  thinkings: mergeThinkingsByControlId(
159
350
  updatedMessages[messageIndex]?.thinkings || [],
160
351
  thinkings || []
@@ -209,11 +400,7 @@ function useAlquimia(sdk) {
209
400
  setIsMessageLoading(true);
210
401
  event.preventDefault();
211
402
  if (input) {
212
- await processAndSendMessage(input, {
213
- traceParentId,
214
- sessionId: sessionId2,
215
- additionalInfo
216
- });
403
+ await processAndSendMessage(input, { traceParentId, sessionId: sessionId2, additionalInfo });
217
404
  }
218
405
  setIsMessageLoading(false);
219
406
  }
@@ -260,7 +447,7 @@ function useAlquimia(sdk) {
260
447
  }
261
448
  function getCookie(name) {
262
449
  const cookies = document.cookie.split(";");
263
- for (let cookie of cookies) {
450
+ for (const cookie of cookies) {
264
451
  const [cookieName, cookieValue] = cookie.trim().split("=");
265
452
  if (cookieName === name) {
266
453
  return decodeURIComponent(cookieValue);
@@ -276,23 +463,22 @@ function useAlquimia(sdk) {
276
463
  }
277
464
  async function sendMessage(message, callBack, traceParentId, sessionId2) {
278
465
  setIsStreamingLoading(true);
279
- callBack({
280
- type: "loading",
281
- loading: true
282
- });
466
+ callBack({ type: "loading", loading: true });
283
467
  const conversationId = sessionId2 || getCookie("alquimia-session");
284
468
  setIsMessageStreaming(true);
285
469
  setActiveTool(null);
286
470
  setLastRequest(message);
287
471
  try {
288
472
  const hasAttachments = attachments.length > 0;
289
- const sdkCall = sdk.widthConversationId(conversationId || "");
473
+ const sdkCall = sdk.withConversationId(conversationId || "");
290
474
  if (hasAttachments) {
291
- sdkCall.withAttachments(attachments.map((f) => ({
292
- filename: f.name,
293
- content_type: f.type,
294
- content_size: f.size
295
- })));
475
+ sdkCall.withAttachments(
476
+ attachments.map((f) => ({
477
+ filename: f.name,
478
+ content_type: f.type,
479
+ content_size: f.size
480
+ }))
481
+ );
296
482
  }
297
483
  const response = await sdkCall.sendMessage(message, traceParentId);
298
484
  if (hasAttachments) {
@@ -300,9 +486,7 @@ function useAlquimia(sdk) {
300
486
  try {
301
487
  const attachmentResponses = response.getAttachmentResponses();
302
488
  await Promise.all(
303
- attachments.map(
304
- (file, i) => response.uploadAttachment(file, attachmentResponses[i])
305
- )
489
+ attachments.map((file, i) => response.uploadAttachment(file, attachmentResponses[i]))
306
490
  );
307
491
  } catch (uploadError) {
308
492
  setIsUploadingAttachments(false);
@@ -319,19 +503,47 @@ function useAlquimia(sdk) {
319
503
  setIsUploadingAttachments(false);
320
504
  clearAttachments();
321
505
  }
322
- const eventSource = new EventSource(response.getUrlStream());
506
+ const streamUrl = response.getUrlStream();
507
+ const streamId = response.getStreamId() || "";
508
+ const streamState = {
509
+ streamId,
510
+ connectedAt: Date.now(),
511
+ openedAt: null,
512
+ messagesReceived: 0,
513
+ lastMessageAt: null,
514
+ closedByClient: false
515
+ };
516
+ const eventSource = new EventSource(streamUrl);
323
517
  eventSourceRef.current = eventSource;
324
518
  const evaluationStrategy2 = response.getEvaluationStrategy();
325
519
  setEvaluationStrategy(evaluationStrategy2);
326
- eventSource.onmessage = (event) => handleMessageEvent(event, callBack, eventSource);
327
- eventSource.onerror = (event) => {
328
- console.error("Stream connection error", event);
520
+ eventSource.onopen = () => {
521
+ streamState.openedAt = Date.now();
522
+ };
523
+ eventSource.onmessage = (event) => {
524
+ streamState.messagesReceived++;
525
+ streamState.lastMessageAt = Date.now();
526
+ handleMessageEvent(event, callBack, eventSource, streamState);
527
+ };
528
+ eventSource.onerror = () => {
529
+ if (streamState.closedByClient) return;
530
+ streamState.closedByClient = true;
531
+ const elapsed = Date.now() - streamState.connectedAt;
532
+ const sinceLastMessage = streamState.lastMessageAt ? Date.now() - streamState.lastMessageAt : null;
329
533
  cleanup(false, eventSource);
534
+ let errorDetail;
535
+ if (!streamState.openedAt) {
536
+ errorDetail = `Stream failed to connect (after ${elapsed}ms). URL: ${streamUrl}`;
537
+ } else if (streamState.messagesReceived === 0) {
538
+ errorDetail = `Stream connected but received no messages before error (open for ${elapsed}ms).`;
539
+ } else {
540
+ errorDetail = `Stream dropped after ${streamState.messagesReceived} message(s), ${sinceLastMessage}ms since last message (total ${elapsed}ms). Possible timeout.`;
541
+ }
330
542
  callBack({
331
543
  type: "error",
332
544
  error_code: "STREAM_ERROR",
333
- error_detail: "Failed to establish stream connection. Stream event source error.",
334
- stream_id: response.getStreamId() || ""
545
+ error_detail: errorDetail,
546
+ stream_id: streamId
335
547
  });
336
548
  };
337
549
  } catch (error) {
@@ -347,46 +559,39 @@ function useAlquimia(sdk) {
347
559
  });
348
560
  }
349
561
  }
350
- function handleMessageEvent(event, callBack, eventSource) {
562
+ function handleMessageEvent(event, callBack, eventSource, streamState) {
351
563
  const data = JSON.parse(event.data);
352
564
  if (data.errors?.length) {
353
565
  for (const error of data.errors) {
354
- console.error("Stream error:", error);
566
+ const detail = error.error_detail || (error.data != null ? `${error.data} (controlId: ${error.control_id})` : "Unknown error");
355
567
  callBack({
356
568
  type: "error",
357
569
  error_code: error.event_class || error.status || "UNKNOWN_ERROR",
358
- error_detail: `${error.data}, controlId: ${error.control_id}` || error.error_detail || "Unknown error",
570
+ error_detail: detail,
359
571
  stream_id: data.stream_id || ""
360
572
  });
361
573
  }
574
+ if (streamState) streamState.closedByClient = true;
362
575
  cleanup(false, eventSource);
363
576
  return;
364
577
  }
365
578
  if (data.tools_output?.length) {
366
- callBack({
367
- type: "answer",
368
- answer: "",
369
- tooler: data.tools_output
370
- });
579
+ callBack({ type: "answer", answer: "", tooler: data.tools_output });
371
580
  }
372
581
  if (data.thinkings?.length) {
373
582
  setHasThinkings(true);
374
- callBack({
375
- type: "answer",
376
- thinkings: data.thinkings
377
- });
583
+ callBack({ type: "answer", thinkings: data.thinkings });
378
584
  }
379
585
  const response = data.response;
380
- const content = response?.event_class === "AssistantInferenceResponse" ? extractAnswerContent(response?.data?.content) : null;
586
+ const content = response?.event_class === "AssistantInferenceResponse" && typeof response.data === "string" ? response.data : null;
381
587
  if (content) {
382
- callBack({
383
- type: "answer",
384
- answer: content
385
- });
588
+ callBack({ type: "answer", answer: content });
589
+ if (streamState) streamState.closedByClient = true;
386
590
  cleanup(false, eventSource);
387
591
  }
388
592
  }
389
593
  return {
594
+ sdk,
390
595
  activeTool,
391
596
  cleanMessages,
392
597
  createMessageId,
@@ -397,7 +602,9 @@ function useAlquimia(sdk) {
397
602
  handleLoadingCancel,
398
603
  input,
399
604
  isLoading,
605
+ isMessageLoading,
400
606
  isMessageStreaming,
607
+ isStreamingLoading,
401
608
  streamingMessageId,
402
609
  isAudioRecording,
403
610
  lastRequest,