[페이지 분류 강화 작업]
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useForm } from "react-hook-form";
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
useCrawlJob,
|
||||
useStartSiteCrawl,
|
||||
} from "@/hooks/useCrawl";
|
||||
import { isCrawlTerminal } from "@/lib/api/crawl";
|
||||
import { crawlApi, isCrawlTerminal } from "@/lib/api/crawl";
|
||||
|
||||
const startCrawlSchema = z.object({
|
||||
source_name: z.string().min(1, "소스를 선택하세요"),
|
||||
@@ -150,7 +150,53 @@ export default function CrawlPage() {
|
||||
const sources = project?.sources ?? [];
|
||||
const sourceName = watch("source_name");
|
||||
const extractionMode = watch("extraction_mode");
|
||||
const provider = watch("extractor_provider");
|
||||
const baseUrl = watch("extractor_base_url");
|
||||
const usesLlm = extractionMode !== "rule_only";
|
||||
|
||||
const [loadedModelHint, setLoadedModelHint] = useState<string>("");
|
||||
const [modelLookupStatus, setModelLookupStatus] = useState<
|
||||
"idle" | "loading" | "ok" | "error"
|
||||
>("idle");
|
||||
const [modelLookupError, setModelLookupError] = useState<string>("");
|
||||
useEffect(() => {
|
||||
if (!usesLlm || provider !== "lm_studio") {
|
||||
setLoadedModelHint("");
|
||||
setModelLookupStatus("idle");
|
||||
setModelLookupError("");
|
||||
return;
|
||||
}
|
||||
let cancelled = false;
|
||||
setModelLookupStatus("loading");
|
||||
setModelLookupError("");
|
||||
(async () => {
|
||||
try {
|
||||
const res = await crawlApi.listExtractorModels(provider, baseUrl);
|
||||
if (cancelled) return;
|
||||
if (!res.ok) {
|
||||
setModelLookupStatus("error");
|
||||
setModelLookupError(res.error || "모델 조회 실패");
|
||||
return;
|
||||
}
|
||||
const first = res.models?.[0]?.id;
|
||||
if (!first) {
|
||||
setModelLookupStatus("error");
|
||||
setModelLookupError("로드된 모델이 없습니다");
|
||||
return;
|
||||
}
|
||||
setLoadedModelHint(first);
|
||||
setValue("extractor_model", first, { shouldDirty: false });
|
||||
setModelLookupStatus("ok");
|
||||
} catch (e) {
|
||||
if (cancelled) return;
|
||||
setModelLookupStatus("error");
|
||||
setModelLookupError((e as Error).message);
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [provider, baseUrl, usesLlm, setValue]);
|
||||
const selectedSource = sources.find((s) => s.name === sourceName);
|
||||
const progress = job?.progress;
|
||||
const visited = progress?.visited_count ?? 0;
|
||||
@@ -385,9 +431,30 @@ export default function CrawlPage() {
|
||||
<Label htmlFor="extractor_model">Model</Label>
|
||||
<Input
|
||||
id="extractor_model"
|
||||
placeholder="deepseek-r1-distill-qwen-7b"
|
||||
placeholder={
|
||||
loadedModelHint || "deepseek-r1-distill-qwen-7b"
|
||||
}
|
||||
{...register("extractor_model")}
|
||||
/>
|
||||
{provider === "lm_studio" &&
|
||||
modelLookupStatus === "loading" && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
LM Studio 로드 모델 확인 중...
|
||||
</p>
|
||||
)}
|
||||
{provider === "lm_studio" &&
|
||||
modelLookupStatus === "ok" &&
|
||||
loadedModelHint && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
LM Studio 로드 모델: {loadedModelHint}
|
||||
</p>
|
||||
)}
|
||||
{provider === "lm_studio" &&
|
||||
modelLookupStatus === "error" && (
|
||||
<p className="text-xs text-destructive">
|
||||
LM Studio 모델 조회 실패: {modelLookupError}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<Label htmlFor="extractor_base_url">Base URL</Label>
|
||||
|
||||
Reference in New Issue
Block a user