expo-ai-core 1.0.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 +162 -0
- package/dist/index.cjs +1345 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +218 -0
- package/dist/index.d.ts +218 -0
- package/dist/index.js +1321 -0
- package/dist/index.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/helpers.ts","../src/providers/shared.ts","../src/providers/gemini.ts","../src/providers/openai.ts","../src/utils/cache.ts","../src/hooks/useAIChat.ts","../src/hooks/useAIVoice.ts","../src/components/AIInput.tsx","../src/components/MarkdownText.tsx","../src/components/AIMessageBubble.tsx","../src/components/AITypingIndicator.tsx","../src/components/AIChatView.tsx"],"names":["useMemo","useState","useRef","useEffect","useCallback","View","jsx","TextInput","Pressable","ActivityIndicator","jsxs","Text","StyleSheet","styles","Linking","defaultTheme","Animated","KeyboardAvoidingView","Platform","FlatList","Fragment"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { AIConversationMessage, AIMessage } from \"../types\";\r\n\r\nexport function createId(prefix = \"msg\"): string {\r\n const randomPart = Math.random().toString(36).slice(2, 10);\r\n const timePart = Date.now().toString(36);\r\n\r\n if (\r\n typeof globalThis.crypto !== \"undefined\" &&\r\n \"randomUUID\" in globalThis.crypto\r\n ) {\r\n return `${prefix}_${globalThis.crypto.randomUUID()}`;\r\n }\r\n\r\n return `${prefix}_${timePart}_${randomPart}`;\r\n}\r\n\r\nexport function trimContent(value: string): string {\r\n return value.trim();\r\n}\r\n\r\nexport function isNonEmptyString(value: unknown): value is string {\r\n return typeof value === \"string\" && value.trim().length > 0;\r\n}\r\n\r\nexport function toConversationMessages(\r\n messages: AIMessage[],\r\n systemPrompt?: string,\r\n): AIConversationMessage[] {\r\n const conversation: AIConversationMessage[] = [];\r\n\r\n if (systemPrompt && systemPrompt.trim()) {\r\n conversation.push({ role: \"system\", content: systemPrompt.trim() });\r\n }\r\n\r\n for (const message of messages) {\r\n conversation.push({ role: message.role, content: message.content });\r\n }\r\n\r\n return conversation;\r\n}\r\n\r\nexport function mergeAssistantText(\r\n previous: string,\r\n nextChunk: string,\r\n): string {\r\n if (!nextChunk) {\r\n return previous;\r\n }\r\n\r\n return `${previous}${nextChunk}`;\r\n}\r\n\r\nexport function safeJsonParse<T>(input: string, fallback: T): T {\r\n try {\r\n return JSON.parse(input) as T;\r\n } catch {\r\n return fallback;\r\n }\r\n}\r\n\r\nexport function clamp(value: number, min: number, max: number): number {\r\n return Math.min(Math.max(value, min), max);\r\n}\r\n\r\nexport function createLogger(enabled?: boolean) {\r\n const prefix = \"[expo-ai-core]\";\r\n\r\n return {\r\n log: (...args: unknown[]) => {\r\n if (enabled) {\r\n console.log(prefix, ...args);\r\n }\r\n },\r\n warn: (...args: unknown[]) => {\r\n if (enabled) {\r\n console.warn(prefix, ...args);\r\n }\r\n },\r\n error: (...args: unknown[]) => {\r\n if (enabled) {\r\n console.error(prefix, ...args);\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport function buildDefaultCacheKey(provider: string, model?: string): string {\r\n return `expo-ai-core:${provider}:${model ?? \"default\"}`;\r\n}\r\n\r\nexport function toPlainText(value: unknown): string {\r\n if (typeof value === \"string\") {\r\n return value;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return value.map(toPlainText).join(\"\");\r\n }\r\n\r\n if (value && typeof value === \"object\") {\r\n const record = value as Record<string, unknown>;\r\n if (typeof record.text === \"string\") {\r\n return record.text;\r\n }\r\n\r\n if (typeof record.content === \"string\") {\r\n return record.content;\r\n }\r\n }\r\n\r\n return \"\";\r\n}\r\n","import type {\r\n AIConversationMessage,\r\n AIProvider,\r\n AIProviderResult,\r\n} from \"../types\";\r\nimport { createLogger } from \"../utils/helpers\";\r\n\r\nexport interface ProviderConfig {\r\n apiKey: string;\r\n model?: string;\r\n systemPrompt?: string;\r\n timeoutMs?: number;\r\n debug?: boolean;\r\n}\r\n\r\nexport function createRequestController(\r\n signal?: AbortSignal,\r\n timeoutMs?: number,\r\n) {\r\n const controller = new AbortController();\r\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\r\n\r\n const abortFromExternal = () => {\r\n if (!controller.signal.aborted) {\r\n controller.abort(signal?.reason ?? new Error(\"Request aborted\"));\r\n }\r\n };\r\n\r\n if (signal) {\r\n if (signal.aborted) {\r\n abortFromExternal();\r\n } else {\r\n signal.addEventListener(\"abort\", abortFromExternal, { once: true });\r\n }\r\n }\r\n\r\n if (typeof timeoutMs === \"number\" && timeoutMs > 0) {\r\n timeoutId = setTimeout(() => {\r\n if (!controller.signal.aborted) {\r\n controller.abort(new Error(`Request timed out after ${timeoutMs}ms`));\r\n }\r\n }, timeoutMs);\r\n }\r\n\r\n return {\r\n signal: controller.signal,\r\n abort: (reason?: unknown) => controller.abort(reason),\r\n cleanup: () => {\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n }\r\n\r\n if (signal) {\r\n signal.removeEventListener(\"abort\", abortFromExternal);\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport function encodeMessages(\r\n messages: AIConversationMessage[],\r\n): AIConversationMessage[] {\r\n return messages.map((message) => ({\r\n role: message.role,\r\n content: message.content,\r\n }));\r\n}\r\n\r\nexport function getLogger(debug?: boolean) {\r\n return createLogger(debug);\r\n}\r\n\r\nexport function buildTextResult(\r\n content: string,\r\n raw?: unknown,\r\n): AIProviderResult {\r\n return { content, raw };\r\n}\r\n\r\nexport function createProvider<T extends AIProvider>(provider: T): T {\r\n return provider;\r\n}\r\n\r\nexport function readOpenAIContent(payload: any): string {\r\n const choice = payload?.choices?.[0];\r\n return choice?.message?.content ?? choice?.delta?.content ?? \"\";\r\n}\r\n\r\nexport function readGeminiContent(payload: any): string {\r\n const candidate = payload?.candidates?.[0];\r\n const parts = candidate?.content?.parts ?? [];\r\n return parts\r\n .map((part: any) => (typeof part?.text === \"string\" ? part.text : \"\"))\r\n .join(\"\");\r\n}\r\n\r\nexport async function readStreamingBody(\r\n response: Response,\r\n onChunk: (chunk: string) => void,\r\n signal?: AbortSignal,\r\n): Promise<void> {\r\n if (response.body && \"getReader\" in response.body) {\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n\r\n while (true) {\r\n if (signal?.aborted) {\r\n await reader.cancel().catch(() => undefined);\r\n break;\r\n }\r\n\r\n const { done, value } = await reader.read();\r\n if (done) {\r\n break;\r\n }\r\n\r\n if (value) {\r\n onChunk(decoder.decode(value, { stream: true }));\r\n }\r\n }\r\n\r\n const finalChunk = decoder.decode();\r\n if (finalChunk) {\r\n onChunk(finalChunk);\r\n }\r\n return;\r\n }\r\n\r\n const text = await response.text();\r\n onChunk(text);\r\n}\r\n\r\nexport function consumeSseLines(\r\n chunk: string,\r\n buffer: string,\r\n onData: (data: string) => void,\r\n): string {\r\n const combined = `${buffer}${chunk}`;\r\n const lines = combined.split(/\\r?\\n/);\r\n const nextBuffer = lines.pop() ?? \"\";\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed) {\r\n continue;\r\n }\r\n\r\n if (trimmed.startsWith(\"data:\")) {\r\n onData(trimmed.slice(5).trim());\r\n continue;\r\n }\r\n\r\n if (trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\")) {\r\n onData(trimmed);\r\n }\r\n }\r\n\r\n return nextBuffer;\r\n}\r\n\r\nexport function appendToken(current: string, token: string): string {\r\n return `${current}${token}`;\r\n}\r\n","import type { AIProvider, AIProviderRequest, AIProviderResult } from \"../types\";\r\nimport {\r\n appendToken,\r\n buildTextResult,\r\n consumeSseLines,\r\n createProvider,\r\n createRequestController,\r\n getLogger,\r\n readGeminiContent,\r\n readStreamingBody,\r\n} from \"./shared\";\r\n\r\nconst DEFAULT_GEMINI_MODEL = \"gemini-2.5-flash\";\r\nconst GEMINI_ENDPOINT =\r\n \"https://generativelanguage.googleapis.com/v1beta/models\";\r\n\r\nexport interface GeminiProviderOptions {\r\n apiKey: string;\r\n model?: string;\r\n systemPrompt?: string;\r\n timeoutMs?: number;\r\n debug?: boolean;\r\n baseUrl?: string;\r\n}\r\n\r\nfunction mapGeminiMessages(messages: AIProviderRequest[\"messages\"]) {\r\n return messages.map((message) => ({\r\n role: message.role === \"assistant\" ? \"model\" : \"user\",\r\n parts: [{ text: message.content }],\r\n }));\r\n}\r\n\r\nasync function requestGemini(\r\n options: GeminiProviderOptions,\r\n request: AIProviderRequest & { stream?: boolean },\r\n handlers?: { onToken?: (token: string) => void },\r\n): Promise<AIProviderResult> {\r\n const logger = getLogger(options.debug);\r\n const controller = createRequestController(\r\n request.signal,\r\n request.timeoutMs ?? options.timeoutMs,\r\n );\r\n const model = options.model ?? DEFAULT_GEMINI_MODEL;\r\n const url = `${options.baseUrl ?? GEMINI_ENDPOINT}/${model}:${request.stream ? \"streamGenerateContent\" : \"generateContent\"}?key=${encodeURIComponent(options.apiKey)}`;\r\n const contents = mapGeminiMessages(request.messages);\r\n\r\n const body = {\r\n ...(options.systemPrompt\r\n ? { systemInstruction: { parts: [{ text: options.systemPrompt }] } }\r\n : null),\r\n contents,\r\n generationConfig: {\r\n temperature: 0.7,\r\n },\r\n };\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: \"POST\",\r\n signal: controller.signal,\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify(body),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => \"\");\r\n throw new Error(\r\n errorText || `Gemini request failed with status ${response.status}`,\r\n );\r\n }\r\n\r\n if (!request.stream) {\r\n const payload = await response.json();\r\n const content = readGeminiContent(payload);\r\n return buildTextResult(content, payload);\r\n }\r\n\r\n let collected = \"\";\r\n let buffer = \"\";\r\n\r\n await readStreamingBody(\r\n response,\r\n (chunk) => {\r\n buffer = consumeSseLines(chunk, buffer, (data) => {\r\n if (data === \"[DONE]\") {\r\n return;\r\n }\r\n\r\n const payload = typeof data === \"string\" ? JSON.parse(data) : data;\r\n const token = readGeminiContent(payload);\r\n\r\n if (token) {\r\n collected = appendToken(collected, token);\r\n handlers?.onToken?.(token);\r\n }\r\n });\r\n },\r\n controller.signal,\r\n );\r\n\r\n return buildTextResult(collected);\r\n } catch (error) {\r\n logger.error(\"Gemini request failed\", error);\r\n throw error;\r\n } finally {\r\n controller.cleanup();\r\n }\r\n}\r\n\r\nexport function createGeminiProvider(\r\n options: GeminiProviderOptions,\r\n): AIProvider {\r\n return createProvider({\r\n name: \"gemini\",\r\n sendMessage(request) {\r\n return requestGemini(options, { ...request, stream: false });\r\n },\r\n streamMessage(request) {\r\n return requestGemini(\r\n options,\r\n { ...request, stream: true },\r\n { onToken: request.onToken },\r\n );\r\n },\r\n });\r\n}\r\n","import type { AIProvider, AIProviderRequest, AIProviderResult } from \"../types\";\r\nimport {\r\n buildTextResult,\r\n consumeSseLines,\r\n createProvider,\r\n createRequestController,\r\n getLogger,\r\n readOpenAIContent,\r\n readStreamingBody,\r\n} from \"./shared\";\r\n\r\nconst DEFAULT_OPENAI_MODEL = \"gpt-4o-mini\";\r\nconst OPENAI_ENDPOINT = \"https://api.openai.com/v1/chat/completions\";\r\n\r\nexport interface OpenAIProviderOptions {\r\n apiKey: string;\r\n model?: string;\r\n systemPrompt?: string;\r\n timeoutMs?: number;\r\n debug?: boolean;\r\n baseUrl?: string;\r\n}\r\n\r\nasync function requestOpenAI(\r\n options: OpenAIProviderOptions,\r\n request: AIProviderRequest & { stream?: boolean },\r\n handlers?: { onToken?: (token: string) => void },\r\n): Promise<AIProviderResult> {\r\n const logger = getLogger(options.debug);\r\n const controller = createRequestController(\r\n request.signal,\r\n request.timeoutMs ?? options.timeoutMs,\r\n );\r\n const messages = options.systemPrompt\r\n ? [{ role: \"system\", content: options.systemPrompt }, ...request.messages]\r\n : request.messages;\r\n const body = {\r\n model: options.model ?? DEFAULT_OPENAI_MODEL,\r\n messages,\r\n stream: Boolean(request.stream),\r\n };\r\n\r\n try {\r\n const response = await fetch(options.baseUrl ?? OPENAI_ENDPOINT, {\r\n method: \"POST\",\r\n signal: controller.signal,\r\n headers: {\r\n Authorization: `Bearer ${options.apiKey}`,\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify(body),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => \"\");\r\n throw new Error(\r\n errorText || `OpenAI request failed with status ${response.status}`,\r\n );\r\n }\r\n\r\n if (!request.stream) {\r\n const payload = await response.json();\r\n const content = readOpenAIContent(payload);\r\n return buildTextResult(content, payload);\r\n }\r\n\r\n let collected = \"\";\r\n let buffer = \"\";\r\n\r\n await readStreamingBody(\r\n response,\r\n (chunk) => {\r\n buffer = consumeSseLines(chunk, buffer, (data) => {\r\n if (data === \"[DONE]\") {\r\n return;\r\n }\r\n\r\n const payload = typeof data === \"string\" ? JSON.parse(data) : data;\r\n const token = readOpenAIContent(payload);\r\n\r\n if (token) {\r\n collected = `${collected}${token}`;\r\n handlers?.onToken?.(token);\r\n }\r\n });\r\n },\r\n controller.signal,\r\n );\r\n\r\n return buildTextResult(collected);\r\n } catch (error) {\r\n logger.error(\"OpenAI request failed\", error);\r\n throw error;\r\n } finally {\r\n controller.cleanup();\r\n }\r\n}\r\n\r\nexport function createOpenAIProvider(\r\n options: OpenAIProviderOptions,\r\n): AIProvider {\r\n return createProvider({\r\n name: \"openai\",\r\n sendMessage(request) {\r\n return requestOpenAI(options, { ...request, stream: false });\r\n },\r\n streamMessage(request) {\r\n return requestOpenAI(\r\n options,\r\n { ...request, stream: true },\r\n { onToken: request.onToken },\r\n );\r\n },\r\n });\r\n}\r\n","import type { AIMessage } from \"../types\";\r\nimport { safeJsonParse } from \"./helpers\";\r\n\r\ntype StorageLike = {\r\n getItem: (key: string) => Promise<string | null>;\r\n setItem: (key: string, value: string) => Promise<void>;\r\n removeItem: (key: string) => Promise<void>;\r\n};\r\n\r\nexport interface AICacheSnapshot {\r\n messages: AIMessage[];\r\n input: string;\r\n updatedAt: number;\r\n}\r\n\r\nconst memoryStore = new Map<string, string>();\r\nlet asyncStoragePromise: Promise<StorageLike | null> | null = null;\r\n\r\nasync function resolveStorage(): Promise<StorageLike | null> {\r\n if (!asyncStoragePromise) {\r\n asyncStoragePromise = import(\"@react-native-async-storage/async-storage\")\r\n .then((module) => (module.default ?? module) as StorageLike)\r\n .catch(() => null);\r\n }\r\n\r\n return asyncStoragePromise;\r\n}\r\n\r\nasync function readRaw(key: string): Promise<string | null> {\r\n const storage = await resolveStorage();\r\n\r\n if (storage) {\r\n return storage.getItem(key);\r\n }\r\n\r\n return memoryStore.get(key) ?? null;\r\n}\r\n\r\nasync function writeRaw(key: string, value: string): Promise<void> {\r\n const storage = await resolveStorage();\r\n\r\n if (storage) {\r\n await storage.setItem(key, value);\r\n return;\r\n }\r\n\r\n memoryStore.set(key, value);\r\n}\r\n\r\nasync function deleteRaw(key: string): Promise<void> {\r\n const storage = await resolveStorage();\r\n\r\n if (storage) {\r\n await storage.removeItem(key);\r\n return;\r\n }\r\n\r\n memoryStore.delete(key);\r\n}\r\n\r\nexport async function loadCache<T extends AICacheSnapshot>(\r\n key: string,\r\n): Promise<T | null> {\r\n const raw = await readRaw(key);\r\n\r\n if (!raw) {\r\n return null;\r\n }\r\n\r\n return safeJsonParse<T | null>(raw, null);\r\n}\r\n\r\nexport async function saveCache(\r\n key: string,\r\n snapshot: AICacheSnapshot,\r\n): Promise<void> {\r\n await writeRaw(key, JSON.stringify(snapshot));\r\n}\r\n\r\nexport async function clearCache(key: string): Promise<void> {\r\n await deleteRaw(key);\r\n}\r\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport type { AIChatOptions, AIChatReturn, AIMessage } from \"../types\";\r\nimport { createGeminiProvider } from \"../providers/gemini\";\r\nimport { createOpenAIProvider } from \"../providers/openai\";\r\nimport { buildDefaultCacheKey, createId, trimContent } from \"../utils/helpers\";\r\nimport { clearCache, loadCache, saveCache } from \"../utils/cache\";\r\nimport type { AIProvider } from \"../types\";\r\nimport type { AICacheSnapshot } from \"../utils/cache\";\r\n\r\nfunction createChatProvider(\r\n options: Pick<\r\n AIChatOptions,\r\n \"provider\" | \"apiKey\" | \"model\" | \"systemPrompt\" | \"timeoutMs\" | \"debug\"\r\n >,\r\n): AIProvider {\r\n if (options.provider === \"gemini\") {\r\n return createGeminiProvider({\r\n apiKey: options.apiKey,\r\n model: options.model,\r\n systemPrompt: options.systemPrompt,\r\n timeoutMs: options.timeoutMs,\r\n debug: options.debug,\r\n });\r\n }\r\n\r\n return createOpenAIProvider({\r\n apiKey: options.apiKey,\r\n model: options.model,\r\n systemPrompt: options.systemPrompt,\r\n timeoutMs: options.timeoutMs,\r\n debug: options.debug,\r\n });\r\n}\r\n\r\nexport function useAIChat(options: AIChatOptions): AIChatReturn {\r\n const {\r\n provider,\r\n apiKey,\r\n model,\r\n systemPrompt,\r\n cacheKey = buildDefaultCacheKey(provider, model),\r\n initialMessages = [],\r\n timeoutMs = 30000,\r\n enableCache = true,\r\n debug,\r\n } = options;\r\n\r\n const providerInstance = useMemo(\r\n () =>\r\n createChatProvider({\r\n provider,\r\n apiKey,\r\n model,\r\n systemPrompt,\r\n timeoutMs,\r\n debug,\r\n }),\r\n [provider, apiKey, model, systemPrompt, timeoutMs, debug],\r\n );\r\n\r\n const [messages, setMessages] = useState<AIMessage[]>(initialMessages);\r\n const [input, setInput] = useState(\"\");\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const messagesRef = useRef(messages);\r\n const inputRef = useRef(input);\r\n const abortRef = useRef<AbortController | null>(null);\r\n const assistantIdRef = useRef<string | null>(null);\r\n const partialRef = useRef(\"\");\r\n const loadingRef = useRef(false);\r\n const streamFlushScheduledRef = useRef(false);\r\n\r\n useEffect(() => {\r\n messagesRef.current = messages;\r\n }, [messages]);\r\n\r\n useEffect(() => {\r\n inputRef.current = input;\r\n }, [input]);\r\n\r\n useEffect(() => {\r\n let mounted = true;\r\n\r\n async function restore() {\r\n if (!enableCache) {\r\n return;\r\n }\r\n\r\n const snapshot = await loadCache<AICacheSnapshot>(cacheKey);\r\n if (!mounted || !snapshot) {\r\n return;\r\n }\r\n\r\n if (snapshot.messages.length > 0 && messagesRef.current.length === 0) {\r\n setMessages(snapshot.messages);\r\n }\r\n\r\n if (typeof snapshot.input === \"string\" && !inputRef.current) {\r\n setInput(snapshot.input);\r\n }\r\n }\r\n\r\n void restore();\r\n\r\n return () => {\r\n mounted = false;\r\n };\r\n }, [cacheKey, enableCache]);\r\n\r\n useEffect(() => {\r\n if (!enableCache) {\r\n return;\r\n }\r\n\r\n void saveCache(cacheKey, {\r\n messages,\r\n input,\r\n updatedAt: Date.now(),\r\n });\r\n }, [cacheKey, enableCache, messages, input]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n abortRef.current?.abort();\r\n };\r\n }, []);\r\n\r\n const flushPartial = useCallback((value: string) => {\r\n partialRef.current = value;\r\n\r\n if (streamFlushScheduledRef.current) {\r\n return;\r\n }\r\n\r\n streamFlushScheduledRef.current = true;\r\n requestAnimationFrame(() => {\r\n streamFlushScheduledRef.current = false;\r\n const assistantId = assistantIdRef.current;\r\n if (!assistantId) {\r\n return;\r\n }\r\n\r\n setMessages((current: AIMessage[]) =>\r\n current.map((message: AIMessage) =>\r\n message.id === assistantId\r\n ? { ...message, content: partialRef.current, status: \"streaming\" }\r\n : message,\r\n ),\r\n );\r\n });\r\n }, []);\r\n\r\n const stopGenerating = useCallback(() => {\r\n abortRef.current?.abort();\r\n abortRef.current = null;\r\n loadingRef.current = false;\r\n setIsLoading(false);\r\n }, []);\r\n\r\n const sendMessage = useCallback(\r\n async (messageText?: string): Promise<AIMessage | null> => {\r\n const text = trimContent(messageText ?? inputRef.current);\r\n if (!text || loadingRef.current) {\r\n return null;\r\n }\r\n\r\n const userMessage: AIMessage = {\r\n id: createId(\"user\"),\r\n role: \"user\",\r\n content: text,\r\n createdAt: Date.now(),\r\n status: \"sent\",\r\n };\r\n\r\n const assistantMessage: AIMessage = {\r\n id: createId(\"assistant\"),\r\n role: \"assistant\",\r\n content: \"\",\r\n createdAt: Date.now(),\r\n status: \"streaming\",\r\n };\r\n\r\n assistantIdRef.current = assistantMessage.id;\r\n partialRef.current = \"\";\r\n loadingRef.current = true;\r\n setError(null);\r\n setInput(\"\");\r\n setIsLoading(true);\r\n setMessages((current: AIMessage[]) => [\r\n ...current,\r\n userMessage,\r\n assistantMessage,\r\n ]);\r\n\r\n const controller = new AbortController();\r\n abortRef.current = controller;\r\n\r\n try {\r\n const conversation = [...messagesRef.current, userMessage];\r\n const result = await providerInstance.streamMessage({\r\n messages: conversation.map((message) => ({\r\n role: message.role,\r\n content: message.content,\r\n })),\r\n signal: controller.signal,\r\n timeoutMs,\r\n onToken: (token: string) => {\r\n flushPartial(`${partialRef.current}${token}`);\r\n },\r\n });\r\n\r\n const content = result.content || partialRef.current;\r\n setMessages((current: AIMessage[]) => {\r\n const assistantId = assistantIdRef.current;\r\n if (!assistantId) {\r\n return current;\r\n }\r\n\r\n return current.map((message: AIMessage) =>\r\n message.id === assistantId\r\n ? { ...message, content, status: \"sent\" }\r\n : message,\r\n );\r\n });\r\n\r\n const completedAssistantMessage: AIMessage = {\r\n ...assistantMessage,\r\n content,\r\n status: \"sent\",\r\n };\r\n\r\n return completedAssistantMessage;\r\n } catch (caughtError) {\r\n const message =\r\n caughtError instanceof Error\r\n ? caughtError.message\r\n : \"Failed to send message\";\r\n setError(message);\r\n setMessages((current: AIMessage[]) => {\r\n const assistantId = assistantIdRef.current;\r\n if (!assistantId) {\r\n return current;\r\n }\r\n\r\n return current.map((item: AIMessage) =>\r\n item.id === assistantId\r\n ? {\r\n ...item,\r\n content: partialRef.current,\r\n status: \"error\",\r\n error: message,\r\n }\r\n : item,\r\n );\r\n });\r\n return null;\r\n } finally {\r\n loadingRef.current = false;\r\n setIsLoading(false);\r\n abortRef.current = null;\r\n assistantIdRef.current = null;\r\n }\r\n },\r\n [flushPartial, providerInstance, timeoutMs],\r\n );\r\n\r\n const clearMessages = useCallback(() => {\r\n setMessages([]);\r\n setError(null);\r\n if (enableCache) {\r\n void clearCache(cacheKey);\r\n }\r\n }, [cacheKey, enableCache]);\r\n\r\n const retryLastMessage = useCallback(async (): Promise<AIMessage | null> => {\r\n const lastUserEntry = [...messagesRef.current]\r\n .map((message, index) => ({ message, index }))\r\n .reverse()\r\n .find((entry) => entry.message.role === \"user\");\r\n if (!lastUserEntry) {\r\n return null;\r\n }\r\n\r\n const lastUserIndex = lastUserEntry.index;\r\n const nextMessages = messagesRef.current.slice(0, lastUserIndex);\r\n const content = lastUserEntry.message.content;\r\n setMessages(nextMessages);\r\n messagesRef.current = nextMessages;\r\n return sendMessage(content);\r\n }, [sendMessage]);\r\n\r\n return {\r\n messages,\r\n input,\r\n setInput,\r\n sendMessage,\r\n isLoading,\r\n error,\r\n stopGenerating,\r\n clearMessages,\r\n retryLastMessage,\r\n };\r\n}\r\n","import { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport type { AIVoiceReturn, VoiceOptions } from \"../types\";\r\n\r\nexport function useAIVoice(options: VoiceOptions = {}): AIVoiceReturn {\r\n const [transcript, setTranscript] = useState(\"\");\r\n const [isListening, setIsListening] = useState(false);\r\n const [recordingUri, setRecordingUri] = useState<string | null>(null);\r\n const [error, setError] = useState<string | null>(null);\r\n const recognitionRef = useRef<any>(null);\r\n const recordingRef = useRef<any>(null);\r\n const cleanupRef = useRef<(() => void) | null>(null);\r\n\r\n const clearTranscript = useCallback(() => {\r\n setTranscript(\"\");\r\n setError(null);\r\n }, []);\r\n\r\n const speak = useCallback(\r\n async (text: string) => {\r\n if (!text.trim()) {\r\n return;\r\n }\r\n\r\n try {\r\n const speechModule = await import(\"expo-speech\").catch(() => null);\r\n const speech = (speechModule?.default ?? speechModule) as any;\r\n\r\n if (speech?.speak) {\r\n speech.speak(text, {\r\n rate: options.speechRate ?? 1,\r\n pitch: options.speechPitch ?? 1,\r\n });\r\n return;\r\n }\r\n\r\n if (\r\n typeof globalThis !== \"undefined\" &&\r\n \"speechSynthesis\" in globalThis\r\n ) {\r\n const utterance = new SpeechSynthesisUtterance(text);\r\n utterance.rate = options.speechRate ?? 1;\r\n utterance.pitch = options.speechPitch ?? 1;\r\n globalThis.speechSynthesis.speak(utterance);\r\n }\r\n } catch (caughtError) {\r\n setError(\r\n caughtError instanceof Error\r\n ? caughtError.message\r\n : \"Failed to speak text\",\r\n );\r\n }\r\n },\r\n [options.speechPitch, options.speechRate],\r\n );\r\n\r\n const stopListening = useCallback(async () => {\r\n const recognition = recognitionRef.current;\r\n\r\n if (recognition) {\r\n recognition.stop?.();\r\n recognitionRef.current = null;\r\n cleanupRef.current?.();\r\n cleanupRef.current = null;\r\n setIsListening(false);\r\n return;\r\n }\r\n\r\n const recording = recordingRef.current;\r\n if (recording) {\r\n try {\r\n await recording.stopAndUnloadAsync();\r\n setRecordingUri(recording.getURI?.() ?? null);\r\n } catch (caughtError) {\r\n setError(\r\n caughtError instanceof Error\r\n ? caughtError.message\r\n : \"Failed to stop recording\",\r\n );\r\n } finally {\r\n recordingRef.current = null;\r\n setIsListening(false);\r\n }\r\n }\r\n }, []);\r\n\r\n const startListening = useCallback(async () => {\r\n setError(null);\r\n clearTranscript();\r\n\r\n const SpeechRecognition =\r\n (globalThis as any).SpeechRecognition ??\r\n (globalThis as any).webkitSpeechRecognition ??\r\n null;\r\n\r\n if (SpeechRecognition) {\r\n const recognition = new SpeechRecognition();\r\n recognition.lang = options.language ?? \"en-US\";\r\n recognition.continuous = options.continuous ?? false;\r\n recognition.interimResults = options.interimResults ?? true;\r\n recognition.maxAlternatives = 1;\r\n\r\n recognition.onresult = (event: any) => {\r\n let nextTranscript = \"\";\r\n\r\n for (let index = 0; index < event.results.length; index += 1) {\r\n const result = event.results[index];\r\n nextTranscript += result[0]?.transcript ?? \"\";\r\n }\r\n\r\n setTranscript(nextTranscript.trim());\r\n };\r\n\r\n recognition.onerror = (event: any) => {\r\n setError(\r\n event?.error ? String(event.error) : \"Speech recognition failed\",\r\n );\r\n setIsListening(false);\r\n };\r\n\r\n recognition.onend = () => {\r\n setIsListening(false);\r\n recognitionRef.current = null;\r\n };\r\n\r\n recognitionRef.current = recognition;\r\n recognition.start();\r\n setIsListening(true);\r\n return;\r\n }\r\n\r\n try {\r\n const expoAv = await import(\"expo-av\").catch(() => null);\r\n const Audio = expoAv?.Audio ?? null;\r\n\r\n if (!Audio) {\r\n throw new Error(\"Speech recognition is unavailable on this platform\");\r\n }\r\n\r\n const permission = await Audio.requestPermissionsAsync();\r\n if (!permission.granted) {\r\n throw new Error(\"Microphone permission is required\");\r\n }\r\n\r\n await Audio.setAudioModeAsync({\r\n allowsRecordingIOS: true,\r\n playsInSilentModeIOS: true,\r\n shouldDuckAndroid: true,\r\n staysActiveInBackground: false,\r\n });\r\n\r\n const recording = new Audio.Recording();\r\n await recording.prepareToRecordAsync(\r\n Audio.RecordingOptionsPresets.HIGH_QUALITY,\r\n );\r\n await recording.startAsync();\r\n recordingRef.current = recording;\r\n setIsListening(true);\r\n setError(\r\n \"Speech recognition is not available in Expo Go. Audio recording started instead.\",\r\n );\r\n } catch (caughtError) {\r\n setError(\r\n caughtError instanceof Error\r\n ? caughtError.message\r\n : \"Failed to start listening\",\r\n );\r\n setIsListening(false);\r\n }\r\n }, [\r\n clearTranscript,\r\n options.continuous,\r\n options.interimResults,\r\n options.language,\r\n ]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n recognitionRef.current?.stop?.();\r\n cleanupRef.current?.();\r\n const recording = recordingRef.current;\r\n if (recording) {\r\n void recording.stopAndUnloadAsync().catch(() => undefined);\r\n }\r\n };\r\n }, []);\r\n\r\n return {\r\n startListening,\r\n stopListening,\r\n transcript,\r\n isListening,\r\n recordingUri,\r\n error,\r\n speak,\r\n clearTranscript,\r\n };\r\n}\r\n","import React from 'react';\r\nimport { ActivityIndicator, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';\r\nimport type { AIInputProps, AITheme } from '../types';\r\n\r\nconst defaultTheme: Partial<AITheme> = {\r\n surfaceColor: '#111827',\r\n textColor: '#f9fafb',\r\n textMutedColor: '#94a3b8',\r\n borderColor: '#334155',\r\n primaryColor: '#38bdf8'\r\n};\r\n\r\nexport function AIInput({\r\n value,\r\n onChangeText,\r\n onSend,\r\n placeholder = 'Type a message',\r\n disabled,\r\n loading,\r\n className,\r\n style,\r\n inputStyle,\r\n buttonStyle,\r\n buttonTextStyle,\r\n multiline = true,\r\n showSendIcon = true,\r\n sendLabel = 'Send'\r\n}: AIInputProps) {\r\n const isDisabled = disabled || loading || value.trim().length === 0;\r\n\r\n return (\r\n <View {...({ className } as any)} style={[styles.container, style, { borderColor: defaultTheme.borderColor, backgroundColor: defaultTheme.surfaceColor }]}>\r\n <TextInput\r\n value={value}\r\n onChangeText={onChangeText}\r\n placeholder={placeholder}\r\n placeholderTextColor={defaultTheme.textMutedColor}\r\n editable={!disabled}\r\n multiline={multiline}\r\n style={[styles.input, { color: defaultTheme.textColor }, inputStyle]}\r\n />\r\n <Pressable\r\n accessibilityRole=\"button\"\r\n onPress={() => {\r\n if (!isDisabled) {\r\n void onSend();\r\n }\r\n }}\r\n style={({ pressed }: { pressed: boolean }) => [\r\n styles.button,\r\n {\r\n opacity: isDisabled ? 0.5 : pressed ? 0.85 : 1,\r\n backgroundColor: defaultTheme.primaryColor\r\n },\r\n buttonStyle\r\n ]}\r\n >\r\n {loading ? (\r\n <ActivityIndicator color=\"#ffffff\" />\r\n ) : (\r\n <Text style={[styles.buttonText, buttonTextStyle]}>{showSendIcon ? '➤ ' : ''}{sendLabel}</Text>\r\n )}\r\n </Pressable>\r\n </View>\r\n );\r\n}\r\n\r\nconst styles = StyleSheet.create({\r\n container: {\r\n borderRadius: 20,\r\n borderWidth: StyleSheet.hairlineWidth,\r\n flexDirection: 'row',\r\n gap: 10,\r\n padding: 12,\r\n alignItems: 'flex-end'\r\n },\r\n input: {\r\n flex: 1,\r\n minHeight: 44,\r\n maxHeight: 140,\r\n fontSize: 15,\r\n paddingVertical: 8\r\n },\r\n button: {\r\n alignItems: 'center',\r\n borderRadius: 14,\r\n minHeight: 42,\r\n justifyContent: 'center',\r\n paddingHorizontal: 16,\r\n paddingVertical: 10\r\n },\r\n buttonText: {\r\n color: '#ffffff',\r\n fontSize: 14,\r\n fontWeight: '700'\r\n }\r\n});\r\n","import React, { useMemo } from 'react';\r\nimport { Linking, StyleSheet, Text, View } from 'react-native';\r\n\r\ninterface MarkdownTextProps {\r\n content: string;\r\n textStyle?: import('react-native').StyleProp<import('react-native').TextStyle>;\r\n codeStyle?: import('react-native').StyleProp<import('react-native').TextStyle>;\r\n onLinkPress?: (url: string) => void;\r\n selectable?: boolean;\r\n}\r\n\r\nconst inlinePatterns = [\r\n { type: 'link', regex: /\\[([^\\]]+)\\]\\(([^)]+)\\)/g },\r\n { type: 'code', regex: /`([^`]+)`/g },\r\n { type: 'bold', regex: /\\*\\*([^*]+)\\*\\*/g }\r\n] as const;\r\n\r\ntype InlinePart =\r\n | { kind: 'text'; value: string }\r\n | { kind: 'code'; value: string }\r\n | { kind: 'bold'; value: string }\r\n | { kind: 'link'; value: string; url: string };\r\n\r\nfunction parseInline(content: string): InlinePart[] {\r\n const parts: InlinePart[] = [];\r\n let cursor = 0;\r\n const pattern = /\\[([^\\]]+)\\]\\(([^)]+)\\)|`([^`]+)`|\\*\\*([^*]+)\\*\\*/g;\r\n\r\n for (;;) {\r\n const match = pattern.exec(content);\r\n if (!match) {\r\n break;\r\n }\r\n\r\n if (match.index > cursor) {\r\n parts.push({ kind: 'text', value: content.slice(cursor, match.index) });\r\n }\r\n\r\n if (match[1] && match[2]) {\r\n parts.push({ kind: 'link', value: match[1], url: match[2] });\r\n } else if (match[3]) {\r\n parts.push({ kind: 'code', value: match[3] });\r\n } else if (match[4]) {\r\n parts.push({ kind: 'bold', value: match[4] });\r\n }\r\n\r\n cursor = pattern.lastIndex;\r\n }\r\n\r\n if (cursor < content.length) {\r\n parts.push({ kind: 'text', value: content.slice(cursor) });\r\n }\r\n\r\n return parts;\r\n}\r\n\r\nfunction renderInlineParts(parts: InlinePart[], onLinkPress?: (url: string) => void) {\r\n return parts.map((part, index) => {\r\n if (part.kind === 'text') {\r\n return part.value;\r\n }\r\n\r\n if (part.kind === 'code') {\r\n return (\r\n <Text key={`code-${index}`} style={styles.inlineCode}>\r\n {part.value}\r\n </Text>\r\n );\r\n }\r\n\r\n if (part.kind === 'bold') {\r\n return (\r\n <Text key={`bold-${index}`} style={styles.bold}>\r\n {part.value}\r\n </Text>\r\n );\r\n }\r\n\r\n return (\r\n <Text\r\n key={`link-${index}`}\r\n style={styles.link}\r\n onPress={() => {\r\n if (onLinkPress) {\r\n onLinkPress(part.url);\r\n return;\r\n }\r\n\r\n Linking.openURL(part.url).catch(() => undefined);\r\n }}\r\n >\r\n {part.value}\r\n </Text>\r\n );\r\n });\r\n}\r\n\r\nfunction splitMarkdownBlocks(content: string) {\r\n const blocks: Array<{ type: 'text' | 'code'; value: string; language?: string }> = [];\r\n const regex = /```([a-zA-Z0-9_-]+)?\\n([\\s\\S]*?)```/g;\r\n let cursor = 0;\r\n\r\n for (;;) {\r\n const match = regex.exec(content);\r\n if (!match) {\r\n break;\r\n }\r\n\r\n if (match.index > cursor) {\r\n blocks.push({ type: 'text', value: content.slice(cursor, match.index) });\r\n }\r\n\r\n blocks.push({ type: 'code', value: match[2], language: match[1] });\r\n cursor = regex.lastIndex;\r\n }\r\n\r\n if (cursor < content.length) {\r\n blocks.push({ type: 'text', value: content.slice(cursor) });\r\n }\r\n\r\n return blocks;\r\n}\r\n\r\nexport function MarkdownText({ content, textStyle, codeStyle, onLinkPress, selectable = true }: MarkdownTextProps) {\r\n const blocks = useMemo(() => splitMarkdownBlocks(content), [content]);\r\n\r\n return (\r\n <View>\r\n {blocks.map((block: { type: 'text' | 'code'; value: string; language?: string }, blockIndex: number) => {\r\n if (block.type === 'code') {\r\n return (\r\n <View key={`codeblock-${blockIndex}`} style={styles.codeBlock}>\r\n <Text selectable={selectable} style={[styles.codeText, codeStyle]}>\r\n {block.value.trimEnd()}\r\n </Text>\r\n </View>\r\n );\r\n }\r\n\r\n const paragraphs = block.value.split(/\\n{2,}/).filter(Boolean);\r\n\r\n return paragraphs.map((paragraph: string, paragraphIndex: number) => (\r\n <Text\r\n key={`text-${blockIndex}-${paragraphIndex}`}\r\n selectable={selectable}\r\n style={textStyle}\r\n >\r\n {renderInlineParts(parseInline(paragraph), onLinkPress)}\r\n {paragraphIndex < paragraphs.length - 1 ? '\\n\\n' : ''}\r\n </Text>\r\n ));\r\n })}\r\n </View>\r\n );\r\n}\r\n\r\nconst styles = StyleSheet.create({\r\n codeBlock: {\r\n borderRadius: 14,\r\n marginTop: 10,\r\n marginBottom: 10,\r\n overflow: 'hidden'\r\n },\r\n codeText: {\r\n backgroundColor: '#111827',\r\n color: '#f9fafb',\r\n fontFamily: 'Courier',\r\n fontSize: 13,\r\n lineHeight: 18,\r\n padding: 12\r\n },\r\n inlineCode: {\r\n backgroundColor: '#374151',\r\n borderRadius: 6,\r\n color: '#f9fafb',\r\n fontFamily: 'Courier',\r\n fontSize: 13,\r\n paddingHorizontal: 4,\r\n paddingVertical: 1\r\n },\r\n bold: {\r\n fontWeight: '700'\r\n },\r\n link: {\r\n color: '#2563eb',\r\n textDecorationLine: 'underline'\r\n }\r\n});\r\n","import React from 'react';\r\nimport { StyleSheet, Text, View } from 'react-native';\r\nimport type { AIMessage, AITheme } from '../types';\r\nimport { MarkdownText } from './MarkdownText';\r\n\r\nconst defaultTheme: AITheme = {\r\n backgroundColor: '#0b1020',\r\n surfaceColor: '#111827',\r\n surfaceMutedColor: '#1f2937',\r\n textColor: '#f9fafb',\r\n textMutedColor: '#cbd5e1',\r\n borderColor: '#334155',\r\n primaryColor: '#38bdf8',\r\n userBubbleColor: '#1d4ed8',\r\n assistantBubbleColor: '#111827',\r\n codeBackgroundColor: '#0f172a',\r\n codeTextColor: '#e2e8f0',\r\n errorColor: '#ef4444'\r\n};\r\n\r\nexport interface AIMessageBubbleProps {\r\n message: AIMessage;\r\n theme?: Partial<AITheme>;\r\n className?: string;\r\n style?: import('react-native').StyleProp<import('react-native').ViewStyle>;\r\n contentStyle?: import('react-native').StyleProp<import('react-native').TextStyle>;\r\n codeStyle?: import('react-native').StyleProp<import('react-native').TextStyle>;\r\n onLinkPress?: (url: string) => void;\r\n showTimestamp?: boolean;\r\n}\r\n\r\nexport function AIMessageBubble({\r\n message,\r\n theme,\r\n className,\r\n style,\r\n contentStyle,\r\n codeStyle,\r\n onLinkPress,\r\n showTimestamp\r\n}: AIMessageBubbleProps) {\r\n const colors = { ...defaultTheme, ...theme };\r\n const isUser = message.role === 'user';\r\n const bubbleColor = isUser ? colors.userBubbleColor : colors.assistantBubbleColor;\r\n const alignSelf = isUser ? 'flex-end' : 'flex-start';\r\n\r\n return (\r\n <View {...({ className } as any)} style={[styles.wrapper, { alignSelf }, style]}>\r\n <View\r\n style={[\r\n styles.bubble,\r\n {\r\n backgroundColor: bubbleColor,\r\n borderColor: colors.borderColor\r\n }\r\n ]}\r\n >\r\n <MarkdownText\r\n content={message.content || (message.status === 'streaming' ? ' ' : '')}\r\n textStyle={[styles.content, { color: colors.textColor }, contentStyle]}\r\n codeStyle={[{ color: colors.codeTextColor }, codeStyle]}\r\n onLinkPress={onLinkPress}\r\n />\r\n {message.status === 'streaming' || message.status === 'sending' ? (\r\n <Text style={[styles.status, { color: colors.textMutedColor }]}>Generating...</Text>\r\n ) : null}\r\n {message.status === 'error' && message.error ? (\r\n <Text style={[styles.status, { color: colors.errorColor }]}>{message.error}</Text>\r\n ) : null}\r\n {showTimestamp ? <Text style={[styles.timestamp, { color: colors.textMutedColor }]}>{new Date(message.createdAt).toLocaleTimeString()}</Text> : null}\r\n </View>\r\n </View>\r\n );\r\n}\r\n\r\nconst styles = StyleSheet.create({\r\n wrapper: {\r\n marginVertical: 6,\r\n maxWidth: '90%'\r\n },\r\n bubble: {\r\n borderRadius: 18,\r\n borderWidth: StyleSheet.hairlineWidth,\r\n paddingHorizontal: 14,\r\n paddingVertical: 12,\r\n shadowColor: '#000',\r\n shadowOpacity: 0.08,\r\n shadowRadius: 8,\r\n shadowOffset: {\r\n width: 0,\r\n height: 2\r\n },\r\n elevation: 1\r\n },\r\n content: {\r\n fontSize: 15,\r\n lineHeight: 21\r\n },\r\n status: {\r\n fontSize: 12,\r\n marginTop: 8,\r\n opacity: 0.85\r\n },\r\n timestamp: {\r\n fontSize: 11,\r\n marginTop: 6,\r\n opacity: 0.65,\r\n textAlign: 'right'\r\n }\r\n});\r\n","import React, { useEffect, useMemo, useRef } from 'react';\r\nimport { Animated, StyleSheet, View } from 'react-native';\r\n\r\nexport interface AITypingIndicatorProps {\r\n color?: string;\r\n style?: import('react-native').StyleProp<import('react-native').ViewStyle>;\r\n}\r\n\r\nexport function AITypingIndicator({ color = '#38bdf8', style }: AITypingIndicatorProps) {\r\n const dotOne = useRef(new Animated.Value(0)).current;\r\n const dotTwo = useRef(new Animated.Value(0)).current;\r\n const dotThree = useRef(new Animated.Value(0)).current;\r\n const animValues = useMemo(() => [dotOne, dotTwo, dotThree], [dotOne, dotTwo, dotThree]);\r\n\r\n useEffect(() => {\r\n const animations = animValues.map((value: Animated.Value, index: number) =>\r\n Animated.loop(\r\n Animated.sequence([\r\n Animated.delay(index * 140),\r\n Animated.timing(value, { toValue: 1, duration: 420, useNativeDriver: true }),\r\n Animated.timing(value, { toValue: 0, duration: 420, useNativeDriver: true })\r\n ])\r\n )\r\n );\r\n\r\n animations.forEach((animation: Animated.CompositeAnimation) => animation.start());\r\n\r\n return () => {\r\n animations.forEach((animation: Animated.CompositeAnimation) => animation.stop());\r\n };\r\n }, [animValues]);\r\n\r\n return (\r\n <View style={[styles.container, style]}>\r\n {animValues.map((value: Animated.Value, index: number) => (\r\n <Animated.View\r\n key={index}\r\n style={[\r\n styles.dot,\r\n {\r\n backgroundColor: color,\r\n opacity: value.interpolate({ inputRange: [0, 1], outputRange: [0.35, 1] }),\r\n transform: [\r\n {\r\n translateY: value.interpolate({ inputRange: [0, 1], outputRange: [0, -4] })\r\n }\r\n ]\r\n }\r\n ]}\r\n />\r\n ))}\r\n </View>\r\n );\r\n}\r\n\r\nconst styles = StyleSheet.create({\r\n container: {\r\n flexDirection: 'row',\r\n gap: 6,\r\n paddingVertical: 6,\r\n alignItems: 'center'\r\n },\r\n dot: {\r\n borderRadius: 999,\r\n height: 8,\r\n width: 8\r\n }\r\n});\r\n","import React, { useEffect, useMemo, useRef } from 'react';\r\nimport { FlatList, KeyboardAvoidingView, Platform, Pressable, StyleSheet, Text, View } from 'react-native';\r\nimport type { AIChatViewProps, AIMessage, AITheme } from '../types';\r\nimport { AIInput } from './AIInput';\r\nimport { AIMessageBubble } from './AIMessageBubble';\r\nimport { AITypingIndicator } from './AITypingIndicator';\r\n\r\nconst defaultTheme: AITheme = {\r\n backgroundColor: '#020617',\r\n surfaceColor: '#0f172a',\r\n surfaceMutedColor: '#1e293b',\r\n textColor: '#f8fafc',\r\n textMutedColor: '#94a3b8',\r\n borderColor: '#334155',\r\n primaryColor: '#38bdf8',\r\n userBubbleColor: '#1d4ed8',\r\n assistantBubbleColor: '#111827',\r\n codeBackgroundColor: '#0f172a',\r\n codeTextColor: '#e2e8f0',\r\n errorColor: '#f87171'\r\n};\r\n\r\nexport function AIChatView({\r\n messages,\r\n input,\r\n setInput,\r\n sendMessage,\r\n isLoading,\r\n error,\r\n title = 'AI Chat',\r\n subtitle,\r\n emptyStateTitle = 'Start a conversation',\r\n emptyStateDescription = 'Send a message to begin chatting with the provider.',\r\n className,\r\n style,\r\n contentContainerStyle,\r\n headerStyle,\r\n footerStyle,\r\n theme,\r\n renderMessage,\r\n renderFooter,\r\n renderHeader,\r\n onPressRetry\r\n}: AIChatViewProps) {\r\n const colors = useMemo(() => ({ ...defaultTheme, ...theme }), [theme]);\r\n const listRef = useRef<FlatList<AIMessage>>(null);\r\n\r\n useEffect(() => {\r\n requestAnimationFrame(() => {\r\n listRef.current?.scrollToEnd({ animated: true });\r\n });\r\n }, [messages.length, isLoading]);\r\n\r\n return (\r\n <KeyboardAvoidingView\r\n {...({ className } as any)}\r\n behavior={Platform.OS === 'ios' ? 'padding' : undefined}\r\n style={[styles.root, { backgroundColor: colors.backgroundColor }, style]}\r\n >\r\n <View style={[styles.header, headerStyle]}>\r\n {renderHeader ? renderHeader() : (\r\n <View>\r\n <Text style={[styles.title, { color: colors.textColor }]}>{title}</Text>\r\n {subtitle ? <Text style={[styles.subtitle, { color: colors.textMutedColor }]}>{subtitle}</Text> : null}\r\n </View>\r\n )}\r\n {onPressRetry ? (\r\n <Pressable onPress={onPressRetry} style={[styles.retryButton, { borderColor: colors.borderColor }]}>\r\n <Text style={[styles.retryText, { color: colors.primaryColor }]}>Retry</Text>\r\n </Pressable>\r\n ) : null}\r\n </View>\r\n\r\n {error ? <Text style={[styles.error, { color: colors.errorColor }]}>{error}</Text> : null}\r\n\r\n <FlatList\r\n ref={listRef}\r\n data={messages}\r\n keyExtractor={(item) => item.id}\r\n contentContainerStyle={[styles.listContent, contentContainerStyle, messages.length === 0 ? styles.emptyList : null]}\r\n renderItem={({ item, index }: { item: AIMessage; index: number }) => (\r\n <>\r\n {renderMessage ? renderMessage(item, index) : <AIMessageBubble message={item} theme={theme} />}\r\n </>\r\n )}\r\n ListEmptyComponent={\r\n <View style={styles.emptyState}>\r\n <Text style={[styles.emptyTitle, { color: colors.textColor }]}>{emptyStateTitle}</Text>\r\n <Text style={[styles.emptyDescription, { color: colors.textMutedColor }]}>{emptyStateDescription}</Text>\r\n </View>\r\n }\r\n ListFooterComponent={\r\n <View style={footerStyle}>\r\n {isLoading ? <AITypingIndicator color={colors.primaryColor} /> : null}\r\n {renderFooter ? renderFooter() : null}\r\n </View>\r\n }\r\n keyboardShouldPersistTaps=\"handled\"\r\n />\r\n\r\n <AIInput\r\n value={input}\r\n onChangeText={setInput}\r\n onSend={() => {\r\n void sendMessage();\r\n }}\r\n loading={isLoading}\r\n style={styles.input}\r\n />\r\n </KeyboardAvoidingView>\r\n );\r\n}\r\n\r\nconst styles = StyleSheet.create({\r\n root: {\r\n flex: 1,\r\n padding: 16\r\n },\r\n header: {\r\n flexDirection: 'row',\r\n alignItems: 'flex-start',\r\n justifyContent: 'space-between',\r\n marginBottom: 12\r\n },\r\n title: {\r\n fontSize: 26,\r\n fontWeight: '800'\r\n },\r\n subtitle: {\r\n fontSize: 14,\r\n marginTop: 4\r\n },\r\n retryButton: {\r\n borderRadius: 999,\r\n borderWidth: StyleSheet.hairlineWidth,\r\n paddingHorizontal: 14,\r\n paddingVertical: 8\r\n },\r\n retryText: {\r\n fontSize: 13,\r\n fontWeight: '700'\r\n },\r\n error: {\r\n fontSize: 13,\r\n marginBottom: 8\r\n },\r\n listContent: {\r\n flexGrow: 1,\r\n paddingBottom: 16\r\n },\r\n emptyList: {\r\n justifyContent: 'center'\r\n },\r\n emptyState: {\r\n alignItems: 'center',\r\n flex: 1,\r\n justifyContent: 'center',\r\n paddingVertical: 48\r\n },\r\n emptyTitle: {\r\n fontSize: 20,\r\n fontWeight: '700'\r\n },\r\n emptyDescription: {\r\n fontSize: 14,\r\n marginTop: 8,\r\n textAlign: 'center'\r\n },\r\n input: {\r\n marginTop: 12\r\n }\r\n});\r\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import * as react_native from 'react-native';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
type AIProviderName = "openai" | "gemini";
|
|
6
|
+
type AIMessageRole = "user" | "assistant";
|
|
7
|
+
type AIMessageStatus = "sending" | "streaming" | "sent" | "error";
|
|
8
|
+
interface AIMessage {
|
|
9
|
+
id: string;
|
|
10
|
+
role: AIMessageRole;
|
|
11
|
+
content: string;
|
|
12
|
+
createdAt: number;
|
|
13
|
+
status?: AIMessageStatus;
|
|
14
|
+
error?: string;
|
|
15
|
+
metadata?: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
interface AIConversationMessage {
|
|
18
|
+
role: "system" | "user" | "assistant";
|
|
19
|
+
content: string;
|
|
20
|
+
}
|
|
21
|
+
interface AIProviderRequest {
|
|
22
|
+
messages: AIConversationMessage[];
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
}
|
|
26
|
+
interface AIProviderResult {
|
|
27
|
+
content: string;
|
|
28
|
+
raw?: unknown;
|
|
29
|
+
}
|
|
30
|
+
interface AIStreamHandlers {
|
|
31
|
+
onToken?: (token: string) => void;
|
|
32
|
+
onDelta?: (content: string) => void;
|
|
33
|
+
onFinish?: (result: AIProviderResult) => void;
|
|
34
|
+
}
|
|
35
|
+
interface AIProvider {
|
|
36
|
+
name: AIProviderName;
|
|
37
|
+
sendMessage: (request: AIProviderRequest) => Promise<AIProviderResult>;
|
|
38
|
+
streamMessage: (request: AIProviderRequest & AIStreamHandlers) => Promise<AIProviderResult>;
|
|
39
|
+
}
|
|
40
|
+
interface AIChatOptions {
|
|
41
|
+
provider: AIProviderName;
|
|
42
|
+
apiKey: string;
|
|
43
|
+
model?: string;
|
|
44
|
+
systemPrompt?: string;
|
|
45
|
+
cacheKey?: string;
|
|
46
|
+
initialMessages?: AIMessage[];
|
|
47
|
+
timeoutMs?: number;
|
|
48
|
+
enableCache?: boolean;
|
|
49
|
+
debug?: boolean;
|
|
50
|
+
}
|
|
51
|
+
interface AIChatReturn {
|
|
52
|
+
messages: AIMessage[];
|
|
53
|
+
input: string;
|
|
54
|
+
setInput: (value: string) => void;
|
|
55
|
+
sendMessage: (message?: string) => Promise<AIMessage | null>;
|
|
56
|
+
isLoading: boolean;
|
|
57
|
+
error: string | null;
|
|
58
|
+
stopGenerating: () => void;
|
|
59
|
+
clearMessages: () => void;
|
|
60
|
+
retryLastMessage: () => Promise<AIMessage | null>;
|
|
61
|
+
}
|
|
62
|
+
interface VoiceOptions {
|
|
63
|
+
language?: string;
|
|
64
|
+
continuous?: boolean;
|
|
65
|
+
interimResults?: boolean;
|
|
66
|
+
autoSpeak?: boolean;
|
|
67
|
+
speechRate?: number;
|
|
68
|
+
speechPitch?: number;
|
|
69
|
+
}
|
|
70
|
+
interface AIVoiceReturn {
|
|
71
|
+
startListening: () => Promise<void>;
|
|
72
|
+
stopListening: () => Promise<void>;
|
|
73
|
+
transcript: string;
|
|
74
|
+
isListening: boolean;
|
|
75
|
+
recordingUri: string | null;
|
|
76
|
+
error: string | null;
|
|
77
|
+
speak: (text: string) => Promise<void>;
|
|
78
|
+
clearTranscript: () => void;
|
|
79
|
+
}
|
|
80
|
+
interface AITheme {
|
|
81
|
+
backgroundColor: string;
|
|
82
|
+
surfaceColor: string;
|
|
83
|
+
surfaceMutedColor: string;
|
|
84
|
+
textColor: string;
|
|
85
|
+
textMutedColor: string;
|
|
86
|
+
borderColor: string;
|
|
87
|
+
primaryColor: string;
|
|
88
|
+
userBubbleColor: string;
|
|
89
|
+
assistantBubbleColor: string;
|
|
90
|
+
codeBackgroundColor: string;
|
|
91
|
+
codeTextColor: string;
|
|
92
|
+
errorColor: string;
|
|
93
|
+
}
|
|
94
|
+
interface AIMessageBubbleProps$1 {
|
|
95
|
+
message: AIMessage;
|
|
96
|
+
theme?: Partial<AITheme>;
|
|
97
|
+
className?: string;
|
|
98
|
+
style?: react_native.StyleProp<react_native.ViewStyle>;
|
|
99
|
+
contentStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
100
|
+
codeStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
101
|
+
onLinkPress?: (url: string) => void;
|
|
102
|
+
showTimestamp?: boolean;
|
|
103
|
+
}
|
|
104
|
+
interface AIInputProps {
|
|
105
|
+
value: string;
|
|
106
|
+
onChangeText: (value: string) => void;
|
|
107
|
+
onSend: () => void | Promise<void>;
|
|
108
|
+
placeholder?: string;
|
|
109
|
+
disabled?: boolean;
|
|
110
|
+
loading?: boolean;
|
|
111
|
+
className?: string;
|
|
112
|
+
style?: react_native.StyleProp<react_native.ViewStyle>;
|
|
113
|
+
inputStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
114
|
+
buttonStyle?: react_native.StyleProp<react_native.ViewStyle>;
|
|
115
|
+
buttonTextStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
116
|
+
multiline?: boolean;
|
|
117
|
+
showSendIcon?: boolean;
|
|
118
|
+
sendLabel?: string;
|
|
119
|
+
}
|
|
120
|
+
interface AIChatViewProps extends AIChatReturn {
|
|
121
|
+
title?: string;
|
|
122
|
+
subtitle?: string;
|
|
123
|
+
emptyStateTitle?: string;
|
|
124
|
+
emptyStateDescription?: string;
|
|
125
|
+
className?: string;
|
|
126
|
+
style?: react_native.StyleProp<react_native.ViewStyle>;
|
|
127
|
+
contentContainerStyle?: react_native.StyleProp<react_native.ViewStyle>;
|
|
128
|
+
headerStyle?: react_native.StyleProp<react_native.ViewStyle>;
|
|
129
|
+
footerStyle?: react_native.StyleProp<react_native.ViewStyle>;
|
|
130
|
+
theme?: Partial<AITheme>;
|
|
131
|
+
renderMessage?: (message: AIMessage, index: number) => react.ReactNode;
|
|
132
|
+
renderFooter?: () => react.ReactNode;
|
|
133
|
+
renderHeader?: () => react.ReactNode;
|
|
134
|
+
onPressRetry?: () => void;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
declare function useAIChat(options: AIChatOptions): AIChatReturn;
|
|
138
|
+
|
|
139
|
+
declare function useAIVoice(options?: VoiceOptions): AIVoiceReturn;
|
|
140
|
+
|
|
141
|
+
declare function AIChatView({ messages, input, setInput, sendMessage, isLoading, error, title, subtitle, emptyStateTitle, emptyStateDescription, className, style, contentContainerStyle, headerStyle, footerStyle, theme, renderMessage, renderFooter, renderHeader, onPressRetry }: AIChatViewProps): react_jsx_runtime.JSX.Element;
|
|
142
|
+
|
|
143
|
+
declare function AIInput({ value, onChangeText, onSend, placeholder, disabled, loading, className, style, inputStyle, buttonStyle, buttonTextStyle, multiline, showSendIcon, sendLabel }: AIInputProps): react_jsx_runtime.JSX.Element;
|
|
144
|
+
|
|
145
|
+
interface AIMessageBubbleProps {
|
|
146
|
+
message: AIMessage;
|
|
147
|
+
theme?: Partial<AITheme>;
|
|
148
|
+
className?: string;
|
|
149
|
+
style?: react_native.StyleProp<react_native.ViewStyle>;
|
|
150
|
+
contentStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
151
|
+
codeStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
152
|
+
onLinkPress?: (url: string) => void;
|
|
153
|
+
showTimestamp?: boolean;
|
|
154
|
+
}
|
|
155
|
+
declare function AIMessageBubble({ message, theme, className, style, contentStyle, codeStyle, onLinkPress, showTimestamp }: AIMessageBubbleProps): react_jsx_runtime.JSX.Element;
|
|
156
|
+
|
|
157
|
+
interface AITypingIndicatorProps {
|
|
158
|
+
color?: string;
|
|
159
|
+
style?: react_native.StyleProp<react_native.ViewStyle>;
|
|
160
|
+
}
|
|
161
|
+
declare function AITypingIndicator({ color, style }: AITypingIndicatorProps): react_jsx_runtime.JSX.Element;
|
|
162
|
+
|
|
163
|
+
interface MarkdownTextProps {
|
|
164
|
+
content: string;
|
|
165
|
+
textStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
166
|
+
codeStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
167
|
+
onLinkPress?: (url: string) => void;
|
|
168
|
+
selectable?: boolean;
|
|
169
|
+
}
|
|
170
|
+
declare function MarkdownText({ content, textStyle, codeStyle, onLinkPress, selectable }: MarkdownTextProps): react_jsx_runtime.JSX.Element;
|
|
171
|
+
|
|
172
|
+
declare function createProvider<T extends AIProvider>(provider: T): T;
|
|
173
|
+
|
|
174
|
+
interface OpenAIProviderOptions {
|
|
175
|
+
apiKey: string;
|
|
176
|
+
model?: string;
|
|
177
|
+
systemPrompt?: string;
|
|
178
|
+
timeoutMs?: number;
|
|
179
|
+
debug?: boolean;
|
|
180
|
+
baseUrl?: string;
|
|
181
|
+
}
|
|
182
|
+
declare function createOpenAIProvider(options: OpenAIProviderOptions): AIProvider;
|
|
183
|
+
|
|
184
|
+
interface GeminiProviderOptions {
|
|
185
|
+
apiKey: string;
|
|
186
|
+
model?: string;
|
|
187
|
+
systemPrompt?: string;
|
|
188
|
+
timeoutMs?: number;
|
|
189
|
+
debug?: boolean;
|
|
190
|
+
baseUrl?: string;
|
|
191
|
+
}
|
|
192
|
+
declare function createGeminiProvider(options: GeminiProviderOptions): AIProvider;
|
|
193
|
+
|
|
194
|
+
interface AICacheSnapshot {
|
|
195
|
+
messages: AIMessage[];
|
|
196
|
+
input: string;
|
|
197
|
+
updatedAt: number;
|
|
198
|
+
}
|
|
199
|
+
declare function loadCache<T extends AICacheSnapshot>(key: string): Promise<T | null>;
|
|
200
|
+
declare function saveCache(key: string, snapshot: AICacheSnapshot): Promise<void>;
|
|
201
|
+
declare function clearCache(key: string): Promise<void>;
|
|
202
|
+
|
|
203
|
+
declare function createId(prefix?: string): string;
|
|
204
|
+
declare function trimContent(value: string): string;
|
|
205
|
+
declare function isNonEmptyString(value: unknown): value is string;
|
|
206
|
+
declare function toConversationMessages(messages: AIMessage[], systemPrompt?: string): AIConversationMessage[];
|
|
207
|
+
declare function mergeAssistantText(previous: string, nextChunk: string): string;
|
|
208
|
+
declare function safeJsonParse<T>(input: string, fallback: T): T;
|
|
209
|
+
declare function clamp(value: number, min: number, max: number): number;
|
|
210
|
+
declare function createLogger(enabled?: boolean): {
|
|
211
|
+
log: (...args: unknown[]) => void;
|
|
212
|
+
warn: (...args: unknown[]) => void;
|
|
213
|
+
error: (...args: unknown[]) => void;
|
|
214
|
+
};
|
|
215
|
+
declare function buildDefaultCacheKey(provider: string, model?: string): string;
|
|
216
|
+
declare function toPlainText(value: unknown): string;
|
|
217
|
+
|
|
218
|
+
export { type AICacheSnapshot, type AIChatOptions, type AIChatReturn, AIChatView, type AIChatViewProps, type AIConversationMessage, AIInput, type AIInputProps, type AIMessage, AIMessageBubble, type AIMessageBubbleProps$1 as AIMessageBubbleProps, type AIMessageRole, type AIMessageStatus, type AIProvider, type AIProviderName, type AIProviderRequest, type AIProviderResult, type AIStreamHandlers, type AITheme, AITypingIndicator, type AIVoiceReturn, MarkdownText, type VoiceOptions, buildDefaultCacheKey, clamp, clearCache, createGeminiProvider, createId, createLogger, createOpenAIProvider, createProvider, isNonEmptyString, loadCache, mergeAssistantText, safeJsonParse, saveCache, toConversationMessages, toPlainText, trimContent, useAIChat, useAIVoice };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import * as react_native from 'react-native';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
type AIProviderName = "openai" | "gemini";
|
|
6
|
+
type AIMessageRole = "user" | "assistant";
|
|
7
|
+
type AIMessageStatus = "sending" | "streaming" | "sent" | "error";
|
|
8
|
+
interface AIMessage {
|
|
9
|
+
id: string;
|
|
10
|
+
role: AIMessageRole;
|
|
11
|
+
content: string;
|
|
12
|
+
createdAt: number;
|
|
13
|
+
status?: AIMessageStatus;
|
|
14
|
+
error?: string;
|
|
15
|
+
metadata?: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
interface AIConversationMessage {
|
|
18
|
+
role: "system" | "user" | "assistant";
|
|
19
|
+
content: string;
|
|
20
|
+
}
|
|
21
|
+
interface AIProviderRequest {
|
|
22
|
+
messages: AIConversationMessage[];
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
}
|
|
26
|
+
interface AIProviderResult {
|
|
27
|
+
content: string;
|
|
28
|
+
raw?: unknown;
|
|
29
|
+
}
|
|
30
|
+
interface AIStreamHandlers {
|
|
31
|
+
onToken?: (token: string) => void;
|
|
32
|
+
onDelta?: (content: string) => void;
|
|
33
|
+
onFinish?: (result: AIProviderResult) => void;
|
|
34
|
+
}
|
|
35
|
+
interface AIProvider {
|
|
36
|
+
name: AIProviderName;
|
|
37
|
+
sendMessage: (request: AIProviderRequest) => Promise<AIProviderResult>;
|
|
38
|
+
streamMessage: (request: AIProviderRequest & AIStreamHandlers) => Promise<AIProviderResult>;
|
|
39
|
+
}
|
|
40
|
+
interface AIChatOptions {
|
|
41
|
+
provider: AIProviderName;
|
|
42
|
+
apiKey: string;
|
|
43
|
+
model?: string;
|
|
44
|
+
systemPrompt?: string;
|
|
45
|
+
cacheKey?: string;
|
|
46
|
+
initialMessages?: AIMessage[];
|
|
47
|
+
timeoutMs?: number;
|
|
48
|
+
enableCache?: boolean;
|
|
49
|
+
debug?: boolean;
|
|
50
|
+
}
|
|
51
|
+
interface AIChatReturn {
|
|
52
|
+
messages: AIMessage[];
|
|
53
|
+
input: string;
|
|
54
|
+
setInput: (value: string) => void;
|
|
55
|
+
sendMessage: (message?: string) => Promise<AIMessage | null>;
|
|
56
|
+
isLoading: boolean;
|
|
57
|
+
error: string | null;
|
|
58
|
+
stopGenerating: () => void;
|
|
59
|
+
clearMessages: () => void;
|
|
60
|
+
retryLastMessage: () => Promise<AIMessage | null>;
|
|
61
|
+
}
|
|
62
|
+
interface VoiceOptions {
|
|
63
|
+
language?: string;
|
|
64
|
+
continuous?: boolean;
|
|
65
|
+
interimResults?: boolean;
|
|
66
|
+
autoSpeak?: boolean;
|
|
67
|
+
speechRate?: number;
|
|
68
|
+
speechPitch?: number;
|
|
69
|
+
}
|
|
70
|
+
interface AIVoiceReturn {
|
|
71
|
+
startListening: () => Promise<void>;
|
|
72
|
+
stopListening: () => Promise<void>;
|
|
73
|
+
transcript: string;
|
|
74
|
+
isListening: boolean;
|
|
75
|
+
recordingUri: string | null;
|
|
76
|
+
error: string | null;
|
|
77
|
+
speak: (text: string) => Promise<void>;
|
|
78
|
+
clearTranscript: () => void;
|
|
79
|
+
}
|
|
80
|
+
interface AITheme {
|
|
81
|
+
backgroundColor: string;
|
|
82
|
+
surfaceColor: string;
|
|
83
|
+
surfaceMutedColor: string;
|
|
84
|
+
textColor: string;
|
|
85
|
+
textMutedColor: string;
|
|
86
|
+
borderColor: string;
|
|
87
|
+
primaryColor: string;
|
|
88
|
+
userBubbleColor: string;
|
|
89
|
+
assistantBubbleColor: string;
|
|
90
|
+
codeBackgroundColor: string;
|
|
91
|
+
codeTextColor: string;
|
|
92
|
+
errorColor: string;
|
|
93
|
+
}
|
|
94
|
+
interface AIMessageBubbleProps$1 {
|
|
95
|
+
message: AIMessage;
|
|
96
|
+
theme?: Partial<AITheme>;
|
|
97
|
+
className?: string;
|
|
98
|
+
style?: react_native.StyleProp<react_native.ViewStyle>;
|
|
99
|
+
contentStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
100
|
+
codeStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
101
|
+
onLinkPress?: (url: string) => void;
|
|
102
|
+
showTimestamp?: boolean;
|
|
103
|
+
}
|
|
104
|
+
interface AIInputProps {
|
|
105
|
+
value: string;
|
|
106
|
+
onChangeText: (value: string) => void;
|
|
107
|
+
onSend: () => void | Promise<void>;
|
|
108
|
+
placeholder?: string;
|
|
109
|
+
disabled?: boolean;
|
|
110
|
+
loading?: boolean;
|
|
111
|
+
className?: string;
|
|
112
|
+
style?: react_native.StyleProp<react_native.ViewStyle>;
|
|
113
|
+
inputStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
114
|
+
buttonStyle?: react_native.StyleProp<react_native.ViewStyle>;
|
|
115
|
+
buttonTextStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
116
|
+
multiline?: boolean;
|
|
117
|
+
showSendIcon?: boolean;
|
|
118
|
+
sendLabel?: string;
|
|
119
|
+
}
|
|
120
|
+
interface AIChatViewProps extends AIChatReturn {
|
|
121
|
+
title?: string;
|
|
122
|
+
subtitle?: string;
|
|
123
|
+
emptyStateTitle?: string;
|
|
124
|
+
emptyStateDescription?: string;
|
|
125
|
+
className?: string;
|
|
126
|
+
style?: react_native.StyleProp<react_native.ViewStyle>;
|
|
127
|
+
contentContainerStyle?: react_native.StyleProp<react_native.ViewStyle>;
|
|
128
|
+
headerStyle?: react_native.StyleProp<react_native.ViewStyle>;
|
|
129
|
+
footerStyle?: react_native.StyleProp<react_native.ViewStyle>;
|
|
130
|
+
theme?: Partial<AITheme>;
|
|
131
|
+
renderMessage?: (message: AIMessage, index: number) => react.ReactNode;
|
|
132
|
+
renderFooter?: () => react.ReactNode;
|
|
133
|
+
renderHeader?: () => react.ReactNode;
|
|
134
|
+
onPressRetry?: () => void;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
declare function useAIChat(options: AIChatOptions): AIChatReturn;
|
|
138
|
+
|
|
139
|
+
declare function useAIVoice(options?: VoiceOptions): AIVoiceReturn;
|
|
140
|
+
|
|
141
|
+
declare function AIChatView({ messages, input, setInput, sendMessage, isLoading, error, title, subtitle, emptyStateTitle, emptyStateDescription, className, style, contentContainerStyle, headerStyle, footerStyle, theme, renderMessage, renderFooter, renderHeader, onPressRetry }: AIChatViewProps): react_jsx_runtime.JSX.Element;
|
|
142
|
+
|
|
143
|
+
declare function AIInput({ value, onChangeText, onSend, placeholder, disabled, loading, className, style, inputStyle, buttonStyle, buttonTextStyle, multiline, showSendIcon, sendLabel }: AIInputProps): react_jsx_runtime.JSX.Element;
|
|
144
|
+
|
|
145
|
+
interface AIMessageBubbleProps {
|
|
146
|
+
message: AIMessage;
|
|
147
|
+
theme?: Partial<AITheme>;
|
|
148
|
+
className?: string;
|
|
149
|
+
style?: react_native.StyleProp<react_native.ViewStyle>;
|
|
150
|
+
contentStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
151
|
+
codeStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
152
|
+
onLinkPress?: (url: string) => void;
|
|
153
|
+
showTimestamp?: boolean;
|
|
154
|
+
}
|
|
155
|
+
declare function AIMessageBubble({ message, theme, className, style, contentStyle, codeStyle, onLinkPress, showTimestamp }: AIMessageBubbleProps): react_jsx_runtime.JSX.Element;
|
|
156
|
+
|
|
157
|
+
interface AITypingIndicatorProps {
|
|
158
|
+
color?: string;
|
|
159
|
+
style?: react_native.StyleProp<react_native.ViewStyle>;
|
|
160
|
+
}
|
|
161
|
+
declare function AITypingIndicator({ color, style }: AITypingIndicatorProps): react_jsx_runtime.JSX.Element;
|
|
162
|
+
|
|
163
|
+
interface MarkdownTextProps {
|
|
164
|
+
content: string;
|
|
165
|
+
textStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
166
|
+
codeStyle?: react_native.StyleProp<react_native.TextStyle>;
|
|
167
|
+
onLinkPress?: (url: string) => void;
|
|
168
|
+
selectable?: boolean;
|
|
169
|
+
}
|
|
170
|
+
declare function MarkdownText({ content, textStyle, codeStyle, onLinkPress, selectable }: MarkdownTextProps): react_jsx_runtime.JSX.Element;
|
|
171
|
+
|
|
172
|
+
declare function createProvider<T extends AIProvider>(provider: T): T;
|
|
173
|
+
|
|
174
|
+
interface OpenAIProviderOptions {
|
|
175
|
+
apiKey: string;
|
|
176
|
+
model?: string;
|
|
177
|
+
systemPrompt?: string;
|
|
178
|
+
timeoutMs?: number;
|
|
179
|
+
debug?: boolean;
|
|
180
|
+
baseUrl?: string;
|
|
181
|
+
}
|
|
182
|
+
declare function createOpenAIProvider(options: OpenAIProviderOptions): AIProvider;
|
|
183
|
+
|
|
184
|
+
interface GeminiProviderOptions {
|
|
185
|
+
apiKey: string;
|
|
186
|
+
model?: string;
|
|
187
|
+
systemPrompt?: string;
|
|
188
|
+
timeoutMs?: number;
|
|
189
|
+
debug?: boolean;
|
|
190
|
+
baseUrl?: string;
|
|
191
|
+
}
|
|
192
|
+
declare function createGeminiProvider(options: GeminiProviderOptions): AIProvider;
|
|
193
|
+
|
|
194
|
+
interface AICacheSnapshot {
|
|
195
|
+
messages: AIMessage[];
|
|
196
|
+
input: string;
|
|
197
|
+
updatedAt: number;
|
|
198
|
+
}
|
|
199
|
+
declare function loadCache<T extends AICacheSnapshot>(key: string): Promise<T | null>;
|
|
200
|
+
declare function saveCache(key: string, snapshot: AICacheSnapshot): Promise<void>;
|
|
201
|
+
declare function clearCache(key: string): Promise<void>;
|
|
202
|
+
|
|
203
|
+
declare function createId(prefix?: string): string;
|
|
204
|
+
declare function trimContent(value: string): string;
|
|
205
|
+
declare function isNonEmptyString(value: unknown): value is string;
|
|
206
|
+
declare function toConversationMessages(messages: AIMessage[], systemPrompt?: string): AIConversationMessage[];
|
|
207
|
+
declare function mergeAssistantText(previous: string, nextChunk: string): string;
|
|
208
|
+
declare function safeJsonParse<T>(input: string, fallback: T): T;
|
|
209
|
+
declare function clamp(value: number, min: number, max: number): number;
|
|
210
|
+
declare function createLogger(enabled?: boolean): {
|
|
211
|
+
log: (...args: unknown[]) => void;
|
|
212
|
+
warn: (...args: unknown[]) => void;
|
|
213
|
+
error: (...args: unknown[]) => void;
|
|
214
|
+
};
|
|
215
|
+
declare function buildDefaultCacheKey(provider: string, model?: string): string;
|
|
216
|
+
declare function toPlainText(value: unknown): string;
|
|
217
|
+
|
|
218
|
+
export { type AICacheSnapshot, type AIChatOptions, type AIChatReturn, AIChatView, type AIChatViewProps, type AIConversationMessage, AIInput, type AIInputProps, type AIMessage, AIMessageBubble, type AIMessageBubbleProps$1 as AIMessageBubbleProps, type AIMessageRole, type AIMessageStatus, type AIProvider, type AIProviderName, type AIProviderRequest, type AIProviderResult, type AIStreamHandlers, type AITheme, AITypingIndicator, type AIVoiceReturn, MarkdownText, type VoiceOptions, buildDefaultCacheKey, clamp, clearCache, createGeminiProvider, createId, createLogger, createOpenAIProvider, createProvider, isNonEmptyString, loadCache, mergeAssistantText, safeJsonParse, saveCache, toConversationMessages, toPlainText, trimContent, useAIChat, useAIVoice };
|