|
|
@@ -1,5 +1,6 @@
|
|
|
import { useCallback, useEffect, useState, useRef } from "react";
|
|
|
import type { FC } from "react";
|
|
|
+import ReactMarkdown from "react-markdown";
|
|
|
import { Modal, Form, Toast } from "@douyinfe/semi-ui";
|
|
|
import { traceApi } from "../../api/traceApi";
|
|
|
import type { Goal } from "../../types/goal";
|
|
|
@@ -9,7 +10,8 @@ import styles from "./TopBar.module.css";
|
|
|
interface TopBarProps {
|
|
|
selectedTraceId: string | null;
|
|
|
selectedNode: Goal | Message | null;
|
|
|
- onTraceSelect: (traceId: string) => void;
|
|
|
+ title: string;
|
|
|
+ onTraceSelect: (traceId: string, title?: string) => void;
|
|
|
onTraceCreated?: () => void;
|
|
|
onMessageInserted?: () => void;
|
|
|
}
|
|
|
@@ -17,11 +19,11 @@ interface TopBarProps {
|
|
|
export const TopBar: FC<TopBarProps> = ({
|
|
|
selectedTraceId,
|
|
|
selectedNode,
|
|
|
+ title,
|
|
|
onTraceSelect,
|
|
|
onTraceCreated,
|
|
|
onMessageInserted,
|
|
|
}) => {
|
|
|
- const [title, setTitle] = useState("流程图可视化系统");
|
|
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
|
|
const [isInsertModalVisible, setIsInsertModalVisible] = useState(false);
|
|
|
const [isReflectModalVisible, setIsReflectModalVisible] = useState(false);
|
|
|
@@ -46,20 +48,20 @@ export const TopBar: FC<TopBarProps> = ({
|
|
|
status: status || undefined,
|
|
|
limit: 20,
|
|
|
});
|
|
|
- const firstTrace = data.traces[0];
|
|
|
- const traceId = firstTrace?.parent_trace_id || firstTrace.trace_id;
|
|
|
- if (firstTrace) {
|
|
|
- setTitle(firstTrace.task);
|
|
|
- onTraceSelect(traceId);
|
|
|
- } else {
|
|
|
- setTitle("流程图可视化系统");
|
|
|
- onTraceSelect("");
|
|
|
+ // 初始加载时不自动选择,或者如果 selectedTraceId 为空才选择第一个
|
|
|
+ if (!selectedTraceId && data.traces.length > 0) {
|
|
|
+ const firstTrace = data.traces[0];
|
|
|
+ const traceId = firstTrace?.parent_trace_id || firstTrace.trace_id;
|
|
|
+ onTraceSelect(traceId, firstTrace.task);
|
|
|
+ } else if (data.traces.length === 0) {
|
|
|
+ onTraceSelect("", "流程图可视化系统");
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error("Failed to load traces:", error);
|
|
|
+ Toast.error("加载任务列表失败");
|
|
|
}
|
|
|
},
|
|
|
- [onTraceSelect],
|
|
|
+ [onTraceSelect, selectedTraceId],
|
|
|
);
|
|
|
|
|
|
useEffect(() => {
|
|
|
@@ -188,7 +190,7 @@ export const TopBar: FC<TopBarProps> = ({
|
|
|
const values = reflectFormApiRef.current?.getValues();
|
|
|
const focus = values?.reflect_focus?.trim();
|
|
|
try {
|
|
|
- await traceApi.reflectTrace(selectedTraceId, focus ? { focus } : undefined);
|
|
|
+ await traceApi.reflectTrace(selectedTraceId, focus ? { focus } : {});
|
|
|
Toast.success("已触发反思");
|
|
|
setIsReflectModalVisible(false);
|
|
|
} catch (error) {
|
|
|
@@ -200,7 +202,17 @@ export const TopBar: FC<TopBarProps> = ({
|
|
|
const handleExperience = async () => {
|
|
|
try {
|
|
|
const content = await traceApi.getExperiences();
|
|
|
- setExperienceContent(typeof content === "string" ? content : JSON.stringify(content, null, 2));
|
|
|
+ // 尝试解析 JSON 格式
|
|
|
+ let displayContent = typeof content === "string" ? content : JSON.stringify(content, null, 2);
|
|
|
+ try {
|
|
|
+ const parsed = typeof content === "string" ? JSON.parse(content) : content;
|
|
|
+ if (parsed && typeof parsed === "object" && "content" in parsed) {
|
|
|
+ displayContent = parsed.content;
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ // 解析失败则使用原始字符串
|
|
|
+ }
|
|
|
+ setExperienceContent(displayContent);
|
|
|
setIsExperienceModalVisible(true);
|
|
|
} catch (error) {
|
|
|
console.error("Failed to get experiences:", error);
|
|
|
@@ -314,7 +326,9 @@ export const TopBar: FC<TopBarProps> = ({
|
|
|
style={{ width: 800 }}
|
|
|
bodyStyle={{ maxHeight: "70vh", overflow: "auto" }}
|
|
|
>
|
|
|
- <pre style={{ whiteSpace: "pre-wrap", wordWrap: "break-word" }}>{experienceContent || "暂无经验数据"}</pre>
|
|
|
+ <div style={{ whiteSpace: "pre-wrap", wordWrap: "break-word" }}>
|
|
|
+ {experienceContent ? <ReactMarkdown>{experienceContent}</ReactMarkdown> : "暂无经验数据"}
|
|
|
+ </div>
|
|
|
</Modal>
|
|
|
</header>
|
|
|
);
|