Files
deerflow-code/frontend-web/src/core/threads/utils.ts
T
2026-05-14 18:13:58 +08:00

68 lines
2.0 KiB
TypeScript

import { useContext } from "react";
import type { Message } from "@langchain/langgraph-sdk";
import { RouteBaseContext } from "@/core/route-base";
import type { AgentThread, AgentThreadContext } from "./types";
type ThreadAgentRef = Pick<AgentThreadContext, "agent_id" | "agent_name">;
type ThreadRouteTarget =
| string
| {
thread_id: string;
context?: ThreadAgentRef | null;
metadata?: Record<string, unknown> | null;
};
function pickAgentRef(
context: ThreadAgentRef | null | undefined,
metadata: Record<string, unknown> | null | undefined,
): string | undefined {
if (context?.agent_id) return context.agent_id;
if (context?.agent_name) return context.agent_name;
const metaId = metadata?.agent_id;
if (typeof metaId === "string" && metaId) return metaId;
const metaName = metadata?.agent_name;
if (typeof metaName === "string" && metaName) return metaName;
return undefined;
}
export function pathOfThread(
thread: ThreadRouteTarget,
context?: ThreadAgentRef | null,
base = "/page/workspace",
) {
const threadId = typeof thread === "string" ? thread : thread.thread_id;
const agentRef =
typeof thread === "string"
? pickAgentRef(context, null)
: pickAgentRef(thread.context, thread.metadata);
return agentRef
? `${base}/agents/${encodeURIComponent(agentRef)}/chats/${threadId}`
: `${base}/chats/${threadId}`;
}
export function usePathOfThread() {
const base = useContext(RouteBaseContext);
return (thread: ThreadRouteTarget, context?: ThreadAgentRef | null) =>
pathOfThread(thread, context, base);
}
export function textOfMessage(message: Message) {
if (typeof message.content === "string") {
return message.content;
} else if (Array.isArray(message.content)) {
for (const part of message.content) {
if (part.type === "text") {
return part.text;
}
}
}
return null;
}
export function titleOfThread(thread: AgentThread) {
return thread.values?.title ?? "Untitled";
}