feat: 智能体详情新增「最近对话」列表,完善推荐问题与任务深链配置

- 新增 AgentRecentChats 组件,在智能体详情面板底部按 agent_id 展示最近对话
- 调整问答/智能体侧边栏与最近对话列表展示逻辑
- 补充 dashboard-input、task-deeplink 相关配置与线程工具方法
- 后端推荐问题接口标签处理及 position_sync 微调,新增相关测试

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
吉鑫升andClaude Opus 4.8 committed 2026-06-22 14:47:43 +08:00
1 parent 16ba5deb0e
commit 32476c7ad4
18 files changed
+457 -60

No files matched your search

+1
View File
@@ -469,6 +469,7 @@ export default function AgentChatPage({
disabled={thread.isLoading || isDemoMode}
onAskQuestion={(text) => handleSubmit({ text, files: [] })}
defaultCollapsed={taskCtxOn}
showRecentChats={!taskCtxOn}
/>
</div>
</ThreadContext.Provider>
+8 -3
View File
@@ -7,7 +7,7 @@ import {
SaveIcon,
SearchIcon,
} from "lucide-react";
import { useRouter } from "next/navigation";
import { useParams, useRouter } from "next/navigation";
import { useCallback, useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
@@ -76,7 +76,11 @@ function getCreateAgentErrorMessage(
export default function NewAgentPage() {
const { t } = useI18n();
const router = useRouter();
const threadId = useMemo(() => uuid(), []);
// 从「常用对话」点击某条智能体创建(bootstrap)会话回到本页时,URL 带 thread_id,
// 用它恢复该会话(加载历史消息、继续对话);正常进入则新开一个会话。
const { thread_id: resumeThreadId } = useParams<{ thread_id?: string }>();
const generatedThreadId = useMemo(() => uuid(), []);
const threadId = resumeThreadId || generatedThreadId;
const [nameInput, setNameInput] = useState("");
const [descriptionInput, setDescriptionInput] = useState("");
@@ -93,7 +97,8 @@ export default function NewAgentPage() {
const [isSkillSelectionTouched, setIsSkillSelectionTouched] = useState(false);
const [detailSkillName, setDetailSkillName] = useState<string | null>(null);
const [skillSearch, setSkillSearch] = useState("");
const [threadPrepared, setThreadPrepared] = useState(false);
// 恢复已有 bootstrap 会话时该 thread 已存在,无需再 create(置为 true,跳过创建)。
const [threadPrepared, setThreadPrepared] = useState(!!resumeThreadId);
const { skills, isLoading: isSkillsLoading } = useSkills();
const { models, isLoading: isModelsLoading } = useModels();
@@ -57,6 +57,12 @@ function NotebookDetailPageWithKey() {
return <StudioNotebookDetailPage key={notebookId} />;
}
// 恢复某条 bootstrap 会话时按 thread_id 重挂,切换会话不串台。
function NewAgentPageWithKey() {
const { thread_id } = useParams<{ thread_id: string }>();
return <NewAgentPage key={thread_id} />;
}
function isInIframe(): boolean {
try {
return window.self !== window.top;
@@ -279,6 +285,16 @@ export default function WorkspaceRoutes({
</WorkspaceLayout>
}
/>
{/* 从「常用对话」点击智能体创建(bootstrap)会话回到创建页并恢复该会话。
key 绑定 thread_id —— 切换不同 bootstrap 会话时重挂一个干净的页面。 */}
<Route
path="agents/new/:thread_id"
element={
<WorkspaceLayout {...layoutProps}>
<NewAgentPageWithKey />
</WorkspaceLayout>
}
/>
<Route
path="agents/:agent_id/chats"
element={<Navigate to="/page/workspace/agents" replace />}