feat: Agent 任务名与对话标题双能力自动生成

新增 task_auto_title_enabled / chat_auto_title_enabled(默认关)、
共享 GenerateAutoTitle、spawn_task 同步写 name、对话首条先截断再异步 AI,
设置页「自动标题」双 Switch。closes #55
This commit is contained in:
artex-bot committed 2026-10-27 12:33:53 +08:00
1 parent e740334b90
commit 6c781f21f4
11 files changed
+310 -1

No files matched your search

@@ -24,6 +24,8 @@ export default function SystemSettingsPage() {
const [credentialBinding, setCredentialBinding] = React.useState(false);
const [savingCredentials, setSavingCredentials] = React.useState(false);
const [intelligenceEnabled, setIntelligenceEnabled] = React.useState(false);
const [taskAutoTitleEnabled, setTaskAutoTitleEnabled] = React.useState(false);
const [chatAutoTitleEnabled, setChatAutoTitleEnabled] = React.useState(false);
const [savingIntelligence, setSavingIntelligence] = React.useState(false);
const [trafficCapture, setTrafficCapture] = React.useState(false);
const [agentTrafficBinding, setAgentTrafficBinding] = React.useState(false);
@@ -60,6 +62,8 @@ export default function SystemSettingsPage() {
setCredentialAgent(!!s.credential_agent_enabled);
setCredentialBinding(!!s.credential_traffic_binding);
setIntelligenceEnabled(!!s.task_intelligence_enabled);
setTaskAutoTitleEnabled(!!s.task_auto_title_enabled);
setChatAutoTitleEnabled(!!s.chat_auto_title_enabled);
setTrafficCapture(!!s.traffic_capture);
setAgentTrafficBinding(!!s.agent_traffic_binding);
setWebSearch(!!s.web_search_enabled);
@@ -229,6 +233,22 @@ export default function SystemSettingsPage() {
});
};
const toggleAutoTitle = (key: "task_auto_title_enabled" | "chat_auto_title_enabled", value: boolean) => {
const setter = key === "task_auto_title_enabled" ? setTaskAutoTitleEnabled : setChatAutoTitleEnabled;
const patch: Partial<Settings> =
key === "task_auto_title_enabled"
? { task_auto_title_enabled: value }
: { chat_auto_title_enabled: value };
setter(value);
api
.setSettings(patch)
.then(apply)
.catch((e) => {
setter(!value);
toast.error("保存失败:" + (e as Error).message);
});
};
// Persist a web-search patch (enable and/or backend). Optimistic with refetch.
const saveWebSearch = (patch: Partial<Settings>) => {
setSaving(true);
@@ -513,6 +533,39 @@ export default function SystemSettingsPage() {
</CardContent>
</Card>
<Card className="mb-4 break-inside-avoid md:mb-6">
<CardHeader>
<CardTitle>自动标题</CardTitle>
<CardDescription>为 Agent 创建的任务和对话首条消息生成简短标题。两个开关独立生效,默认关闭。</CardDescription>
</CardHeader>
<CardContent>
<Field orientation="horizontal">
<FieldContent>
<FieldLabel htmlFor="task-auto-title">任务名称</FieldLabel>
<FieldDescription>Agent 创建任务时自动生成任务名称;失败时保留未命名任务。</FieldDescription>
</FieldContent>
<Switch
id="task-auto-title"
checked={taskAutoTitleEnabled}
disabled={!loaded}
onCheckedChange={(value) => toggleAutoTitle("task_auto_title_enabled", value)}
/>
</Field>
<Field orientation="horizontal" className="mt-5">
<FieldContent>
<FieldLabel htmlFor="chat-auto-title">会话标题</FieldLabel>
<FieldDescription>对话首条消息后自动生成会话标题;先显示消息截断文本,失败时保留截断标题。</FieldDescription>
</FieldContent>
<Switch
id="chat-auto-title"
checked={chatAutoTitleEnabled}
disabled={!loaded}
onCheckedChange={(value) => toggleAutoTitle("chat_auto_title_enabled", value)}
/>
</Field>
</CardContent>
</Card>
<Card className="mb-4 break-inside-avoid md:mb-6">
<CardHeader>
<CardTitle>任务情报</CardTitle>
+2
View File
@@ -3327,6 +3327,8 @@ export const settings: Settings = {
task_intelligence_enabled: false,
credential_agent_enabled: false,
credential_traffic_binding: false,
task_auto_title_enabled: false,
chat_auto_title_enabled: false,
traffic_capture: true,
agent_traffic_binding: false,
llm_record: false,
+2
View File
@@ -969,6 +969,8 @@ export interface Settings {
credential_agent_enabled: boolean;
credential_traffic_binding: boolean;
task_intelligence_enabled: boolean; // 默认关闭;关闭不注入情报工具或提示
task_auto_title_enabled: boolean; // Agent 创建任务时自动生成任务名称
chat_auto_title_enabled: boolean; // 对话首条消息后自动生成会话标题
agent_traffic_binding: boolean; // Agent 自动绑定流量证据,默认关闭;不影响人工绑定
llm_record: boolean; // LLM 录制开关(默认关);关闭时不记录任何 LLM 调用
// Web search. brave_key_set / tavily_key_set reflect whether a key is stored