Merge branch 'master' of http://192.168.0.200/knowledge-base-bj/deerflow-server into dhk-1
This commit is contained in:
commit
adabfa2fe3
6 files changed
+69
-18
No files matched your search
@@ -233,12 +233,16 @@ export interface TaskDeeplinkTarget {
|
||||
state?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/** 用 taskName / taskContent 拼出开场信息文本;末尾附上任务 id(task_id),供后端识别任务。 */
|
||||
function buildOpeningText(detail: CopTaskDetail, taskId: string): string {
|
||||
/**
|
||||
* 用 taskName / taskContent 拼出开场信息文本;末尾附上任务 id(task_id),供后端识别任务。
|
||||
* xdfx(行动分析)额外附上「行动id(action_id)」——传入 actionId 时追加该行。
|
||||
*/
|
||||
function buildOpeningText(detail: CopTaskDetail, taskId: string, actionId?: string): string {
|
||||
return [
|
||||
detail.taskName ? `任务名称:${detail.taskName}` : "",
|
||||
detail.taskContent ? `任务内容:${detail.taskContent}` : "",
|
||||
taskId ? `任务id(task_id)为${taskId}` : "",
|
||||
actionId ? `行动id(action_id)为${actionId}` : "",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n");
|
||||
@@ -312,11 +316,15 @@ export async function resolveTaskDeeplinkTarget(
|
||||
// 暂存任务上下文(taskId + agentId + 开场信息),跳到 chats 索引,由工作区按 taskId 决定
|
||||
// 开最新历史对话 / 新建。rwfx 在工作区里额外过「目的树闸门」;3qfx/xdfx 仅 1:N 列表,
|
||||
// 新建对话直接带开场信息自动发出(见 task-purpose / AgentChatPage 的 taskGate / taskBind)。
|
||||
// xdfx(行动分析):聊天记录按「行动id」划分(partitionByAction),且开场信息追加 action_id。
|
||||
const isXdfx = parsed.businessCode === XDFX_BUSINESS_CODE;
|
||||
const actionId = rawId || taskId;
|
||||
persistTaskContext({
|
||||
taskId,
|
||||
agentId,
|
||||
openingText: buildOpeningText(detail, taskId),
|
||||
actionId: rawId || taskId,
|
||||
openingText: buildOpeningText(detail, taskId, isXdfx ? actionId : undefined),
|
||||
actionId,
|
||||
partitionByAction: isXdfx,
|
||||
});
|
||||
return { path: `${taskBase}/agent/${agentId}/chats` };
|
||||
}
|
||||
@@ -41,6 +41,12 @@ export interface TaskContext {
|
||||
openingText: string;
|
||||
/** 深链原始 id(xdfx 为「行动id」,需追加行动id 的按钮用;其它业务等于 taskId)。 */
|
||||
actionId?: string;
|
||||
/**
|
||||
* xdfx(行动分析)专属:聊天记录按「行动id」(actionId) 而非「任务id」划分。
|
||||
* 为 true 时,新建对话额外打 `metadata.actionId` 标签、对话列表按 actionId 过滤
|
||||
* (仍保留 taskId 标签以维持任务深链对话「全局共享、不分用户」的后端语义)。
|
||||
*/
|
||||
partitionByAction?: boolean;
|
||||
}
|
||||
|
||||
const TASK_CONTEXT_STORAGE_KEY = "task.rwfxContext";
|
||||
@@ -311,12 +317,29 @@ export function readTaskContext(): TaskContext | null {
|
||||
agentId: String(parsed.agentId),
|
||||
openingText: typeof parsed.openingText === "string" ? parsed.openingText : "",
|
||||
actionId: typeof parsed.actionId === "string" ? parsed.actionId : undefined,
|
||||
partitionByAction: parsed.partitionByAction === true,
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务深链对话的 thread metadata 标签(既用于「新建对话」打标签,也用于对话列表过滤)。
|
||||
* - 普通业务(rwfx/3qfx):`{ taskId }` —— 按任务划分(1:N)。
|
||||
* - xdfx(partitionByAction):`{ taskId, actionId }` —— 额外按「行动id」划分聊天记录;
|
||||
* 仍带 taskId 以保留后端「任务深链对话全局共享」的语义(后端据 metadata.taskId 跳过分用户过滤)。
|
||||
* 无有效 taskId 时返回 undefined(调用方据此不打标签)。
|
||||
*/
|
||||
export function taskThreadMetadata(
|
||||
ctx: TaskContext | null | undefined,
|
||||
): Record<string, unknown> | undefined {
|
||||
if (!ctx?.taskId) return undefined;
|
||||
return ctx.partitionByAction && ctx.actionId
|
||||
? { taskId: ctx.taskId, actionId: ctx.actionId }
|
||||
: { taskId: ctx.taskId };
|
||||
}
|
||||
|
||||
export function clearTaskContext(): void {
|
||||
try {
|
||||
sessionStorage.removeItem(TASK_CONTEXT_STORAGE_KEY);
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
* 同一个 taskId 可能挂在多条业务链上(rwfx / 3qfx / xdfx 共用任务 id),每条业务用各自的
|
||||
* 智能体。传入 ``agentId`` 时额外按 ``metadata.agent_id`` 过滤(后端 metadata 过滤是 AND/子集
|
||||
* 匹配),把不同业务的对话列表隔离开——否则三种业务的对话会混在一起。
|
||||
*
|
||||
* xdfx(行动分析):聊天记录按「行动id」划分——传入 ``actionId`` 时额外按 ``metadata.actionId``
|
||||
* 过滤(同一任务下的不同行动各自一份对话列表);仍保留 taskId 过滤以命中后端「任务深链对话
|
||||
* 全局共享」的判定(后端据 metadata.taskId 跳过分用户过滤)。
|
||||
*/
|
||||
|
||||
import { useThreadsPage } from "@/core/threads/hooks";
|
||||
@@ -16,13 +20,16 @@ import type { AgentThread } from "@/core/threads/types";
|
||||
export function useTaskThreads(
|
||||
taskId: string | null | undefined,
|
||||
agentId?: string | null | undefined,
|
||||
actionId?: string | null | undefined,
|
||||
) {
|
||||
const enabled = !!taskId;
|
||||
// 任务工作区只在有 taskId 时渲染;无 taskId 时传一个不可能命中的过滤,返回空列表。
|
||||
const metadata = enabled
|
||||
? agentId
|
||||
? { taskId, agent_id: agentId }
|
||||
: { taskId }
|
||||
? {
|
||||
taskId,
|
||||
...(actionId ? { actionId } : {}),
|
||||
...(agentId ? { agent_id: agentId } : {}),
|
||||
}
|
||||
: { taskId: "__none__" };
|
||||
const query = useThreadsPage({ page: 1, pageSize: 100, metadata });
|
||||
const threads: AgentThread[] = enabled ? (query.data?.threads ?? []) : [];
|
||||
|
||||
@@ -31,7 +31,7 @@ import { saveLastAgentId, useThreadSettings } from "@/core/settings";
|
||||
import { stopThreadRun, useThreadStream } from "@/core/threads/hooks";
|
||||
import { textOfMessage } from "@/core/threads/utils";
|
||||
import { env } from "@/env";
|
||||
import { readTaskContext } from "@/core/auth/task-purpose";
|
||||
import { readTaskContext, taskThreadMetadata } from "@/core/auth/task-purpose";
|
||||
import { TaskPurposePanel } from "@/strategy-components/components/task-components/TaskPurposePanel";
|
||||
import { desensitize } from "@/lib/desensitize";
|
||||
|
||||
@@ -143,8 +143,9 @@ export default function AgentChatPage({
|
||||
threadId: isNewThread ? undefined : threadId,
|
||||
assistantId: agent_id,
|
||||
context: { ...settings.context, agent_id },
|
||||
// 任务闸门:新建 thread 打 metadata.taskId 标签,供任务对话列表(1:N)按任务过滤。
|
||||
threadMetadata: taskId ? { taskId } : undefined,
|
||||
// 任务闸门:新建 thread 打 metadata.taskId 标签,供任务对话列表(1:N)按任务过滤;
|
||||
// xdfx 额外打 metadata.actionId 标签,按「行动id」划分聊天记录(见 taskThreadMetadata)。
|
||||
threadMetadata: taskId ? taskThreadMetadata(taskContext) : undefined,
|
||||
onStart: (createdThreadId) => {
|
||||
setThreadId(createdThreadId);
|
||||
setIsNewThread(false);
|
||||
|
||||
+19
-7
@@ -46,11 +46,19 @@ import AgentChatPage from "@/pages/AgentChatPage";
|
||||
import { ChatRuntime } from "@/pages/WorkspaceRoutes";
|
||||
import { TaskJumpBar } from "@/strategy-components/components/task-components/TaskJumpBar";
|
||||
|
||||
function useChatsBase(taskBase: string): { taskId: string; agentId: string; chatsBase: string } {
|
||||
function useChatsBase(taskBase: string): {
|
||||
taskId: string;
|
||||
agentId: string;
|
||||
/** xdfx(partitionByAction):按「行动id」划分聊天记录用;其它业务为 ""(仍按 taskId 划分)。 */
|
||||
actionId: string;
|
||||
chatsBase: string;
|
||||
} {
|
||||
const { agent_id } = useParams<{ agent_id: string }>();
|
||||
const agentId = agent_id ?? "";
|
||||
const taskId = readTaskContext()?.taskId ?? "";
|
||||
return { taskId, agentId, chatsBase: `${taskBase}/agent/${agentId}/chats` };
|
||||
const ctx = readTaskContext();
|
||||
const taskId = ctx?.taskId ?? "";
|
||||
const actionId = ctx?.partitionByAction ? (ctx.actionId ?? "") : "";
|
||||
return { taskId, agentId, actionId, chatsBase: `${taskBase}/agent/${agentId}/chats` };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,19 +150,22 @@ function parseThreadId(pathname: string, chatsBase: string): string | null {
|
||||
function TaskConversationsList({
|
||||
taskId,
|
||||
agentId,
|
||||
actionId,
|
||||
chatsBase,
|
||||
business,
|
||||
lite,
|
||||
}: {
|
||||
taskId: string;
|
||||
agentId: string;
|
||||
/** xdfx:按「行动id」划分聊天记录;其它业务为 ""。 */
|
||||
actionId: string;
|
||||
chatsBase: string;
|
||||
business: TaskBusiness;
|
||||
lite?: boolean;
|
||||
}) {
|
||||
const { pathname } = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const { threads, isLoading } = useTaskThreads(taskId, agentId);
|
||||
const { threads, isLoading } = useTaskThreads(taskId, agentId, actionId);
|
||||
const currentThreadId = useMemo(() => parseThreadId(pathname, chatsBase), [pathname, chatsBase]);
|
||||
const businessName = desensitize(TASK_BUSINESSES.find((b) => b.code === business)?.name ?? "");
|
||||
|
||||
@@ -371,13 +382,14 @@ export function TaskFxWorkspace({
|
||||
business: TaskBusiness;
|
||||
lite?: boolean;
|
||||
}) {
|
||||
const { taskId, agentId, chatsBase } = useChatsBase(taskBase);
|
||||
const { taskId, agentId, actionId, chatsBase } = useChatsBase(taskBase);
|
||||
return (
|
||||
<div className="flex size-full min-h-0 flex-col overflow-hidden">
|
||||
<div className="flex min-h-0 flex-1 overflow-hidden">
|
||||
<TaskConversationsList
|
||||
taskId={taskId}
|
||||
agentId={agentId}
|
||||
actionId={actionId}
|
||||
chatsBase={chatsBase}
|
||||
business={business}
|
||||
lite={lite}
|
||||
@@ -395,9 +407,9 @@ export function TaskFxWorkspace({
|
||||
|
||||
/** chats 索引:有历史对话 → 跳最新;否则 → 跳 new(rwfx 走闸门 / 3qfx/xdfx 直接带开场信息)。 */
|
||||
export function TaskFxIndexResolver({ taskBase }: { taskBase: string }) {
|
||||
const { taskId, agentId, chatsBase } = useChatsBase(taskBase);
|
||||
const { taskId, agentId, actionId, chatsBase } = useChatsBase(taskBase);
|
||||
const navigate = useNavigate();
|
||||
const { isLoading, hasThreads, latestThreadId } = useTaskThreads(taskId, agentId);
|
||||
const { isLoading, hasThreads, latestThreadId } = useTaskThreads(taskId, agentId, actionId);
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoading) return;
|
||||
|
||||
Reference in new issue
Block a user