diff --git a/packages/app-expo/src/components/onboarding/steps/EmbeddingPage.tsx b/packages/app-expo/src/components/onboarding/steps/EmbeddingPage.tsx index 21b2e79d..df178cbe 100644 --- a/packages/app-expo/src/components/onboarding/steps/EmbeddingPage.tsx +++ b/packages/app-expo/src/components/onboarding/steps/EmbeddingPage.tsx @@ -4,18 +4,12 @@ import { useVectorModelStore } from "@/stores/vector-model-store"; import { useTheme } from "@/styles/theme"; import { useNavigation } from "@react-navigation/native"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; +import { detectRemoteEmbeddingDimension } from "@readany/core/rag"; import type { VectorModelConfig } from "@readany/core/types"; import { Check, Cloud, Plus, Trash2, X } from "lucide-react-native"; -import { useCallback, useState } from "react"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { - ActivityIndicator, - Pressable, - StyleSheet, - Text, - TextInput, - View, -} from "react-native"; +import { ActivityIndicator, Pressable, StyleSheet, Text, TextInput, View } from "react-native"; import Animated, { SlideInRight } from "react-native-reanimated"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import SearchSvg from "../../../../assets/illustrations/search.svg"; @@ -26,15 +20,11 @@ type NavProp = NativeStackNavigationProp; export function EmbeddingPage() { const { t } = useTranslation(); const navigation = useNavigation(); - const { colors, isDark } = useTheme(); + const { colors } = useTheme(); const insets = useSafeAreaInsets(); - const { - vectorModels, - addVectorModel, - deleteVectorModel, - setSelectedVectorModelId, - } = useVectorModelStore(); + const { vectorModels, addVectorModel, deleteVectorModel, setSelectedVectorModelId } = + useVectorModelStore(); const [showAddForm, setShowAddForm] = useState(false); const [formData, setFormData] = useState({ name: "", url: "", modelId: "", apiKey: "" }); @@ -54,23 +44,8 @@ export function EmbeddingPage() { const testRemoteModel = async (model: VectorModelConfig) => { setTestingId(model.id); try { - const testUrl = model.url.replace(/\/$/, ""); - const isOllama = testUrl.endsWith("/api/embed"); - const headers: Record = { "Content-Type": "application/json" }; - if (model.apiKey?.trim()) headers.Authorization = `Bearer ${model.apiKey}`; - - const requestBody = isOllama - ? { model: model.modelId, input: "test" } - : { input: ["test"], model: model.modelId, encoding_format: "float" }; - - const res = await fetch(testUrl, { - method: "POST", - headers, - body: JSON.stringify(requestBody), - }); - if (res.ok) { - setSelectedVectorModelId(model.id); - } + await detectRemoteEmbeddingDimension(model); + setSelectedVectorModelId(model.id); } catch (err) { console.warn("[Onboarding] Embedding model test failed:", err); } finally { @@ -273,9 +248,7 @@ export function EmbeddingPage() { ]} > - - {m.name} - + {m.name} {m.modelId} diff --git a/packages/app/src/components/onboarding/steps/EmbeddingPage.tsx b/packages/app/src/components/onboarding/steps/EmbeddingPage.tsx index bc58e32f..2305724b 100644 --- a/packages/app/src/components/onboarding/steps/EmbeddingPage.tsx +++ b/packages/app/src/components/onboarding/steps/EmbeddingPage.tsx @@ -1,10 +1,10 @@ import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { PasswordInput } from "@/components/ui/password-input"; -import { Switch } from "@/components/ui/switch"; import { useVectorModelStore } from "@/stores/vector-model-store"; import { BUILTIN_EMBEDDING_MODELS } from "@readany/core/ai/builtin-embedding-models"; import { loadEmbeddingPipeline } from "@readany/core/ai/local-embedding-service"; +import { detectRemoteEmbeddingDimension } from "@readany/core/rag"; import type { VectorModelConfig } from "@readany/core/types"; import { Check, Download, Loader2, Plus, Trash2, X } from "lucide-react"; import { useCallback, useState } from "react"; @@ -12,7 +12,14 @@ import { useTranslation } from "react-i18next"; import { OnboardingLayout } from "../OnboardingLayout"; -export function EmbeddingPage({ onNext, onPrev, step, totalSteps }: any) { +interface EmbeddingPageProps { + onNext: () => void; + onPrev: () => void; + step: number; + totalSteps: number; +} + +export function EmbeddingPage({ onNext, onPrev, step, totalSteps }: EmbeddingPageProps) { const { t } = useTranslation(); const { vectorModelMode, @@ -70,23 +77,8 @@ export function EmbeddingPage({ onNext, onPrev, step, totalSteps }: any) { async (model: VectorModelConfig) => { setTestingId(model.id); try { - const testUrl = model.url.replace(/\/$/, ""); - const isOllama = testUrl.endsWith("/api/embed"); - const headers: Record = { "Content-Type": "application/json" }; - if (model.apiKey?.trim()) headers.Authorization = `Bearer ${model.apiKey}`; - - const requestBody = isOllama - ? { model: model.modelId, input: "test" } - : { input: ["test"], model: model.modelId, encoding_format: "float" }; - - const res = await fetch(testUrl, { - method: "POST", - headers, - body: JSON.stringify(requestBody), - }); - if (res.ok) { - setSelectedVectorModelId(model.id); - } + await detectRemoteEmbeddingDimension(model); + setSelectedVectorModelId(model.id); } catch (err) { console.warn("[Onboarding] Embedding model test failed:", err); } finally { @@ -141,8 +133,9 @@ export function EmbeddingPage({ onNext, onPrev, step, totalSteps }: any) {
-
setVectorModelMode("remote")} >
@@ -153,14 +146,19 @@ export function EmbeddingPage({ onNext, onPrev, step, totalSteps }: any) { {t("onboarding.embedding.remoteDesc", "Connect to external embedding API.")}

- setVectorModelMode(c ? "remote" : "builtin")} - /> -
+
{vectorModelMode === "remote" && ( @@ -204,20 +206,28 @@ export function EmbeddingPage({ onNext, onPrev, step, totalSteps }: any) {
-
-
-
-