feat(task-deeplink): 3qfx/xdfx 新建对话改手动「开始回答」+ xdfx 行动详情卡片 + 独立问答智能体列表栏

- AgentChatPage: 纯绑定深链(3qfx/xdfx)不再自动发开场信息,改由右上角「开始回答」按钮手动触发,从根上消除新建对话竞态导致的重复发送;移除 autoSentArmedRef/streamThreadId 相关逻辑
- task-deeplink.ts: 抽出 fetchActionDetail 返回整包 ActionDetail,fetchTaskIdFromAction 复用之
- TaskFxWorkspace: xdfx 左栏「当前任务」下新增「行动详情」卡片(行动名称/叙事)
- StrategyRoutes/WorkspaceRoutes: 独立智能体问答整页新增最左「智能体列表」栏(showAgentList);xdfx 右侧宿主改用 TaskBindChat(精简版)
- 新增 agent-chat-sidebar.tsx

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
吉鑫升andClaude Opus 4.8 committed 2026-06-18 20:55:41 +08:00
1 parent 179a3f2b2f
commit 6aaa4c841e
6 files changed
+298 -49

No files matched your search

+41 -9
View File
@@ -111,13 +111,29 @@ export function readCopTaskDetail(): CopTaskDetail | null {
}
}
/** 行动详情接口 ``{action_detail_url}/{actionId}`` 返回的 ``data`` 字段(xdfx 行动分析用)。 */
export interface ActionDetail {
/** 行动id(深链 ?taskId= 传入的就是它)。 */
id: string;
/** 该行动归属的真正「任务id」。 */
taskId: string;
/** 所属目的id。 */
purposeId: string;
/** 行动名称。 */
actionName: string;
/** 行动状态码。 */
actionStatus: number | string;
/** 行动叙事 / 描述。 */
narration: string;
}
/**
* xdfx 深链:用「行动id」调行动详情接口 ``{action_detail_url}/{actionId}``,取出 ``data.taskId``
* 作为真正的「任务id」。``action_test=true`` 时直接用后端配置里的假数据(接口未通时用)。
* 缺地址 / 返回不合法 → 返回 ""(调用方据此回退)。
* xdfx 深链:用「行动id」调行动详情接口 ``{action_detail_url}/{actionId}``,取出整包行动详情。
* ``action_test=true`` 时直接用后端配置里的假数据(接口未通时用)。
* 缺地址 / 返回不合法 → 返回 null。
*/
export async function fetchTaskIdFromAction(actionId: string): Promise<string> {
if (!actionId) return "";
export async function fetchActionDetail(actionId: string): Promise<ActionDetail | null> {
if (!actionId) return null;
const cfg = await fetchTaskDeeplinkConfig();
let body: unknown;
if (cfg.actionTest) {
@@ -127,12 +143,28 @@ export async function fetchTaskIdFromAction(actionId: string): Promise<string> {
// service 拦截器已统一注入 Authorization: Bearer admin 并返回整包 body;行动id 走路径段。
body = await requestCrudService.get(`${base}/${encodeURIComponent(actionId)}`);
} else {
return "";
return null;
}
const data = body && typeof body === "object" ? (body as { data?: unknown }).data : null;
if (!data || typeof data !== "object") return "";
const taskId = (data as Record<string, unknown>).taskId;
return taskId != null && taskId !== "" ? String(taskId) : "";
if (!data || typeof data !== "object") return null;
const d = data as Record<string, unknown>;
return {
id: d.id != null ? String(d.id) : "",
taskId: d.taskId != null ? String(d.taskId) : "",
purposeId: d.purposeId != null ? String(d.purposeId) : "",
actionName: typeof d.actionName === "string" ? d.actionName : "",
actionStatus:
typeof d.actionStatus === "number" || typeof d.actionStatus === "string" ? d.actionStatus : "",
narration: typeof d.narration === "string" ? d.narration : "",
};
}
/**
* xdfx 深链:用「行动id」解析出真正的「任务id」(取行动详情的 ``data.taskId``)。
* 缺地址 / 返回不合法 → 返回 ""(调用方据此回退)。
*/
export async function fetchTaskIdFromAction(actionId: string): Promise<string> {
return (await fetchActionDetail(actionId))?.taskId ?? "";
}
/**