新增智能体收藏、定时任务必须生成MD校验、问答时间显示及账号绑定的常用提示词

- 智能体支持从广场收藏到「我的」(新增 agent_favorites 表与收藏/取消收藏接口)
- 定时任务新增「必须生成Markdown文件」开关:注入提示词并校验生成的 .md 文件且正文超过100字,否则记为失败(存于 execution_context,无需迁移)
- 聊天问答展示时间(年月日 时分):问题在右下角、回答在左下角
- 常用提示词改为与账号绑定(新增 user_custom_prompts 表与 /api/user-prompts 接口),仅在首页输入框上方以居中标签 + 轮播展示,齿轮置于最右侧管理

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
吉鑫升andClaude Opus 4.7 committed 2026-05-28 17:16:15 +08:00
1 parent 4410acaee8
commit 10e35055e0
45 files changed
+1653 -145

No files matched your search

@@ -84,6 +84,7 @@ const emptyForm = {
timezone: "Asia/Shanghai",
prompt: "",
execution_agent_name: "",
require_markdown: false,
};
export default function ScheduledTasksPage() {
@@ -173,6 +174,7 @@ export default function ScheduledTasksPage() {
timezone: task.timezone,
prompt: task.prompt,
execution_agent_name: task.execution_agent_name ?? "",
require_markdown: !!task.execution_context?.require_markdown,
});
// Prefer the canonical cron_expr over the user-typed schedule_text: the
// latter may be natural language ("每天9点") that parseCron can't read,
@@ -202,6 +204,7 @@ export default function ScheduledTasksPage() {
timezone: form.timezone || "Asia/Shanghai",
prompt: form.prompt,
execution_agent_name: form.execution_agent_name || null,
require_markdown: form.require_markdown,
});
setSelectedTaskId(task.task_id);
toast.success("任务已创建");
@@ -215,6 +218,7 @@ export default function ScheduledTasksPage() {
timezone: form.timezone,
prompt: form.prompt,
execution_agent_name: form.execution_agent_name || null,
require_markdown: form.require_markdown,
},
});
toast.success("任务已更新");
@@ -825,6 +829,20 @@ export default function ScheduledTasksPage() {
}
placeholder="任务 Prompt"
/>
<div className="flex items-center justify-between rounded-md border p-3">
<div className="min-w-0 pr-3">
<p className="text-sm font-medium">必须生成 Markdown 文件</p>
<p className="text-muted-foreground text-xs">
开启后会提示大模型生成 Markdown(.md) 文件;系统会校验本次是否生成了 .md 文件且文件正文超过 100 字,未达到则记为失败。
</p>
</div>
<Switch
checked={form.require_markdown}
onCheckedChange={(v) =>
setForm((value) => ({ ...value, require_markdown: v }))
}
/>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={closeDialog}>