技能中文名: - 单个「AI 生成」与「一键补充中文名」均可在请求体 model_name 选择大模型 - 一键补充改为仅管理员开放 - _generate_skill_name_zh 在模型自身失败(构建/超时/API 报错)时抛 SkillNameZhModelError,与模型返回无效名称区分;单个接口返回 502「大模型报错,无法补全技能中文名」,批量在 model_error 中带回代表性报错 知识库沉淀: - 对话保存到知识库 / 批量导入均新增可选 model_name(透传至 capture_thread → extract_thread_llm_multi) - 批量返回 llm_fallback 计数;模型异常时仍按既有逻辑回退规则抽取并落草稿, 前端明确提示「已改用规则抽取」(保存按钮保持后台异步) 前端新增 components/workspace/model-name-select.tsx 复用下拉(默认=系统配置模型) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
60 lines
1.6 KiB
TypeScript
60 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "@/components/ui/select";
|
|
import { useModels } from "@/core/models/hooks";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
/** Sentinel for "use the backend's default/configured model" (no override). */
|
|
const DEFAULT_VALUE = "__default__";
|
|
|
|
/**
|
|
* Compact dropdown to optionally pick an LLM model for a one-off action
|
|
* (skill-name generation, knowledge ingestion, …). The value is the model
|
|
* `name`; `null` means "use the configured default" (no override sent).
|
|
*/
|
|
export function ModelNameSelect({
|
|
value,
|
|
onChange,
|
|
disabled,
|
|
className,
|
|
triggerClassName,
|
|
defaultLabel = "默认模型",
|
|
}: {
|
|
value: string | null;
|
|
onChange: (modelName: string | null) => void;
|
|
disabled?: boolean;
|
|
className?: string;
|
|
triggerClassName?: string;
|
|
defaultLabel?: string;
|
|
}) {
|
|
const { models } = useModels();
|
|
return (
|
|
<Select
|
|
value={value ?? DEFAULT_VALUE}
|
|
onValueChange={(v) => onChange(v === DEFAULT_VALUE ? null : v)}
|
|
disabled={disabled}
|
|
>
|
|
<SelectTrigger
|
|
className={cn("h-8 gap-1.5 text-xs", triggerClassName, className)}
|
|
title="选择用于本次操作的大模型(默认使用系统配置的模型)"
|
|
>
|
|
<SelectValue placeholder={defaultLabel} />
|
|
</SelectTrigger>
|
|
<SelectContent position="popper" side="bottom" sideOffset={4}>
|
|
<SelectItem value={DEFAULT_VALUE}>{defaultLabel}</SelectItem>
|
|
{models.map((m) => (
|
|
<SelectItem key={m.name} value={m.name}>
|
|
{m.display_name || m.name}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
);
|
|
}
|