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:
1 parent
16ba5deb0e
commit
32476c7ad4
18 files changed
+457
-60
No files matched your search
@@ -18,6 +18,7 @@
|
||||
|
||||
import { requestCrudService } from "@/service/request-axios-service";
|
||||
import { readCopTaskDetail } from "@/core/auth/task-deeplink";
|
||||
import { fetchTaskDeeplinkConfig } from "@/core/auth/task-deeplink-config";
|
||||
|
||||
/** 本页输入 JSON 暂存的 sessionStorage key(拉取一次后复用,避免重复请求)。 */
|
||||
export const DASHBOARD_INPUT_STORAGE_KEY = "dashboard.inputJson";
|
||||
@@ -221,3 +222,43 @@ export async function fetchDashboardInputJson(
|
||||
if (resolved) persistDashboardInputJson(resolved);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
/* ---------------------- rwfx 进入预检:3q 是否完成 ---------------------- */
|
||||
|
||||
/**
|
||||
* 「3q(研判情报报告)是否完成」状态:
|
||||
* - ``complete`` = selectSqReport 数组里有有效内容;
|
||||
* - ``incomplete`` = 数组为空 / 每条 contentJson 都是 null/空(3q 未完成);
|
||||
* - ``unknown`` = 缺 consumer 地址 / 请求异常(无法判定,调用方应静默放行)。
|
||||
*/
|
||||
export type SqReportStatus = "complete" | "incomplete" | "unknown";
|
||||
|
||||
/**
|
||||
* rwfx(任务分析)进入时的「3q 是否完成」预检:调 selectSqReport,复用 ``extractSqReport``
|
||||
* 判定该任务是否已有有效研判情报。判定口径与大屏绘制取数完全一致(空/全 null → 无内容)。
|
||||
* - 有可用内容 → ``complete``(正常);
|
||||
* - 空 / 全 null → ``incomplete``(rwfx 据此弹框引导去 3qfx);
|
||||
* - 缺地址 / 请求失败 → ``unknown``(不打扰用户)。
|
||||
*
|
||||
* **数据源由后端配置 ``task_deeplink.test`` 决定**(线上 selectSqReport 外部不可用时):
|
||||
* - ``test=true`` → 直接用 ``config.yaml`` 的 ``mock.sq_report`` 假数据判定,**不发请求**
|
||||
* (与目的树查询/行动解析的 mock 同一套机制,见 [[task-deeplink-config]]);
|
||||
* - ``test=false`` → 调真实接口 ``GET {VITE_AIPI_CONSUMER_URL}/cop/selectSqReport?taskId=``。
|
||||
*/
|
||||
export async function fetchSqReportStatus(taskId: string): Promise<SqReportStatus> {
|
||||
if (!taskId) return "unknown";
|
||||
const cfg = await fetchTaskDeeplinkConfig();
|
||||
// test=true:外部接口不可用,直接用后端 config 的假数据判定(不打真实接口)。
|
||||
if (cfg.test) {
|
||||
return extractSqReport(cfg.mock.sqReport, taskId) ? "complete" : "incomplete";
|
||||
}
|
||||
// 真实模式:打真实接口。service 拦截器统一注入鉴权并返回整包 body;空/全 null → null。
|
||||
const url = sqReportUrl();
|
||||
if (!url) return "unknown";
|
||||
try {
|
||||
const body = await requestCrudService.get(url, { taskId });
|
||||
return extractSqReport(body, taskId) ? "complete" : "incomplete";
|
||||
} catch {
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
@@ -34,11 +34,13 @@ export interface TaskDeeplinkConfig {
|
||||
/** 「3q详情」详情页 URL(rwfx 目的树面板链接,跳转追加 ?id= 任务id);留空则前端提示未配置。 */
|
||||
detail3qUrl: string;
|
||||
/** 测试假数据:purposeDetail = 原始 {state,msg,data};delete = {message,success};
|
||||
* actionDetail = 原始 {state,msg,data:{taskId,...}}。 */
|
||||
* actionDetail = 原始 {state,msg,data:{taskId,...}};sqReport = 原始 {state,msg,data:[...]}
|
||||
* (rwfx 3q 预检用,test 为真时生效)。 */
|
||||
mock: {
|
||||
purposeDetail?: unknown;
|
||||
delete?: { message?: string; success?: boolean };
|
||||
actionDetail?: unknown;
|
||||
sqReport?: unknown;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -81,6 +83,7 @@ function normalize(body: unknown): TaskDeeplinkConfig {
|
||||
? (mock.delete as { message?: string; success?: boolean })
|
||||
: undefined,
|
||||
actionDetail: mock.action_detail,
|
||||
sqReport: mock.sq_report,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -81,6 +81,32 @@ export function titleOfThread(thread: AgentThread, fallback = "Untitled") {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 智能体创建过程产生的「引导会话」(bootstrap)。这类会话用 metadata.thread_type
|
||||
* === "bootstrap" 标记,点击后应回到「创建智能体」页继续,而不是普通问答页。
|
||||
*/
|
||||
export function isBootstrapThread(thread: {
|
||||
metadata?: Record<string, unknown> | null;
|
||||
}): boolean {
|
||||
return thread.metadata?.thread_type === "bootstrap";
|
||||
}
|
||||
|
||||
/**
|
||||
* bootstrap 会话点击后回到「创建智能体」页并恢复该会话。该页只挂在
|
||||
* /page/workspace 下(见 WorkspaceRoutes 的 agents/new/:thread_id),故路径固定,
|
||||
* 不随当前 route base 变化。
|
||||
*/
|
||||
export function bootstrapResumePath(threadId: string): string {
|
||||
return `/page/workspace/agents/new/${threadId}`;
|
||||
}
|
||||
|
||||
/** 列表项点击目标:bootstrap 会话回创建页恢复,其余走普通问答路由。 */
|
||||
export function listPathOfThread(thread: AgentThread): string {
|
||||
return isBootstrapThread(thread)
|
||||
? bootstrapResumePath(thread.thread_id)
|
||||
: pathOfThread(thread);
|
||||
}
|
||||
|
||||
export function isThreadPinned(thread: AgentThread): boolean {
|
||||
return (thread.metadata as Record<string, unknown> | null)?.is_pinned === true;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user