瀏覽代碼

frontend fix

guantao 5 小時之前
父節點
當前提交
1d5c11add4

+ 15 - 133
agent/core/runner.py

@@ -267,55 +267,6 @@ class AgentRunner:
         # 知识保存跟踪(每个 trace 独立)
         # 知识保存跟踪(每个 trace 独立)
         self._saved_knowledge_ids: Dict[str, List[str]] = {}  # trace_id → [knowledge_ids]
         self._saved_knowledge_ids: Dict[str, List[str]] = {}  # trace_id → [knowledge_ids]
 
 
-        # 知识确认等待(每个 trace 独立)
-        self._pending_confirmations: Dict[str, asyncio.Future] = {}  # trace_id → Future
-
-    async def _wait_for_confirmation(self, trace_id: str, confirm_type: str, data: Dict[str, Any], timeout: float = 300) -> Dict[str, Any]:
-        """
-        广播知识确认请求并暂停等待前端响应。
-
-        Args:
-            trace_id: Trace ID
-            confirm_type: "knowledge_injection" | "knowledge_save"
-            data: 确认请求的数据(知识内容等)
-            timeout: 超时秒数,默认 300 秒
-
-        Returns:
-            用户响应 {"action": "confirm"|"reject", "edited_args"?: {...}}
-        """
-        from agent.trace.websocket import broadcast_knowledge_confirm_request
-        await broadcast_knowledge_confirm_request(trace_id, confirm_type, data)
-
-        loop = asyncio.get_event_loop()
-        future = loop.create_future()
-        self._pending_confirmations[trace_id] = future
-
-        try:
-            result = await asyncio.wait_for(future, timeout=timeout)
-            return result
-        except asyncio.TimeoutError:
-            logger.warning(f"[Knowledge Confirm] 等待确认超时 ({timeout}s),默认确认: trace={trace_id}, type={confirm_type}")
-            return {"action": "confirm"}
-        finally:
-            self._pending_confirmations.pop(trace_id, None)
-
-    async def resolve_confirmation(self, trace_id: str, response: Dict[str, Any]) -> bool:
-        """
-        前端调用,resolve 等待中的确认 Future。
-
-        Args:
-            trace_id: Trace ID
-            response: {"action": "confirm"|"reject", "edited_args"?: {...}}
-
-        Returns:
-            True 如果成功 resolve,False 如果没有等待中的确认
-        """
-        future = self._pending_confirmations.get(trace_id)
-        if future is None or future.done():
-            return False
-        future.set_result(response)
-        return True
-
     # ===== 核心公开方法 =====
     # ===== 核心公开方法 =====
 
 
     async def run(
     async def run(
@@ -460,10 +411,6 @@ class AgentRunner:
         if cancel_event is None:
         if cancel_event is None:
             return False
             return False
         cancel_event.set()
         cancel_event.set()
-        # 如果有等待中的知识确认,立即 resolve 以解除阻塞
-        future = self._pending_confirmations.get(trace_id)
-        if future and not future.done():
-            future.set_result({"action": "confirm"})
         return True
         return True
 
 
     # ===== 单次调用(保留)=====
     # ===== 单次调用(保留)=====
@@ -1100,41 +1047,21 @@ class AgentRunner:
                             context={"runner": self},
                             context={"runner": self},
                         )
                         )
                         if relevant_exps:
                         if relevant_exps:
-                            # 暂停等待用户确认知识注入
-                            try:
-                                confirm_result = await self._wait_for_confirmation(
-                                    trace_id, "knowledge_injection", {
-                                        "goal_id": current_goal.id,
-                                        "goal_description": current_goal.description,
-                                        "knowledge_items": relevant_exps,
-                                    }
-                                )
-                                if confirm_result.get("action") == "reject":
-                                    logger.info(f"[Knowledge Injection] 用户拒绝注入知识到 goal {current_goal.id}")
-                                    relevant_exps = []
-                            except Exception as e:
-                                logger.warning(f"[Knowledge Injection] 确认流程异常,默认注入: {e}")
-
-                            if relevant_exps:
-                                # 保存到 goal 对象
-                                current_goal.knowledge = relevant_exps
-                                logger.info(f"[Knowledge Injection] 已将 {len(relevant_exps)} 条知识注入到 goal {current_goal.id}: {current_goal.description[:40]}")
-                                logger.debug(f"[Knowledge Injection] 注入的知识 IDs: {[exp.get('id') for exp in relevant_exps]}")
-                                # 持久化保存 goal_tree
-                                await self.trace_store.update_goal_tree(trace_id, goal_tree)
-                                self.used_ex_ids = [exp['id'] for exp in relevant_exps]
-                                parts = [f"[{exp['id']}] {exp['content']}" for exp in relevant_exps]
-                                _cached_exp_text = "## 参考历史经验\n" + "\n\n".join(parts)
-                                logger.info(
-                                    "经验检索: goal='%s', 命中 %d 条 %s",
-                                    current_goal.description[:40],
-                                    len(relevant_exps),
-                                    self.used_ex_ids,
-                                )
-                            else:
-                                current_goal.knowledge = []
-                                await self.trace_store.update_goal_tree(trace_id, goal_tree)
-                                _cached_exp_text = ""
+                            # 保存到 goal 对象
+                            current_goal.knowledge = relevant_exps
+                            logger.info(f"[Knowledge Injection] 已将 {len(relevant_exps)} 条知识注入到 goal {current_goal.id}: {current_goal.description[:40]}")
+                            logger.debug(f"[Knowledge Injection] 注入的知识 IDs: {[exp.get('id') for exp in relevant_exps]}")
+                            # 持久化保存 goal_tree
+                            await self.trace_store.update_goal_tree(trace_id, goal_tree)
+                            self.used_ex_ids = [exp['id'] for exp in relevant_exps]
+                            parts = [f"[{exp['id']}] {exp['content']}" for exp in relevant_exps]
+                            _cached_exp_text = "## 参考历史经验\n" + "\n\n".join(parts)
+                            logger.info(
+                                "经验检索: goal='%s', 命中 %d 条 %s",
+                                current_goal.description[:40],
+                                len(relevant_exps),
+                                self.used_ex_ids,
+                            )
                         else:
                         else:
                             current_goal.knowledge = []
                             current_goal.knowledge = []
                             logger.info(f"[Knowledge Injection] goal {current_goal.id} 未找到相关知识")
                             logger.info(f"[Knowledge Injection] goal {current_goal.id} 未找到相关知识")
@@ -1363,51 +1290,6 @@ class AgentRunner:
                     elif tool_args is None:
                     elif tool_args is None:
                         tool_args = {}
                         tool_args = {}
 
 
-                    # save_knowledge 暂停确认:在实际执行前等待用户确认
-                    if tool_name == "save_knowledge":
-                        try:
-                            confirm_result = await self._wait_for_confirmation(
-                                trace_id, "knowledge_save", {
-                                    "tool_args": tool_args,
-                                }
-                            )
-                            if confirm_result.get("action") == "reject":
-                                logger.info(f"[Knowledge Save] 用户拒绝保存知识: {tool_args.get('scenario', '')[:40]}")
-                                tool_result = {"text": "用户拒绝保存此知识。"}
-                                # 跳过实际执行,直接构造 tool result
-                                tool_text = tool_result["text"]
-                                tool_images = []
-                                tool_usage = None
-
-                                history.append({
-                                    "role": "tool",
-                                    "tool_call_id": tc["id"],
-                                    "content": tool_text,
-                                })
-
-                                if self.trace_store:
-                                    tool_message = Message.create(
-                                        trace_id=trace_id,
-                                        role="tool",
-                                        sequence=sequence,
-                                        goal_id=current_goal_id,
-                                        parent_sequence=head_seq if head_seq > 0 else None,
-                                        content=tool_text,
-                                        tool_call_id=tc["id"],
-                                        tool_name=tool_name,
-                                    )
-                                    await self.trace_store.add_message(tool_message)
-                                    yield tool_message
-                                    head_seq = sequence
-                                    sequence += 1
-                                continue
-                            elif confirm_result.get("edited_args"):
-                                # 用户编辑了内容
-                                tool_args.update(confirm_result["edited_args"])
-                                logger.info(f"[Knowledge Save] 用户编辑了知识内容后确认保存")
-                        except Exception as e:
-                            logger.warning(f"[Knowledge Save] 确认流程异常,默认执行: {e}")
-
                     tool_result = await self.tools.execute(
                     tool_result = await self.tools.execute(
                         tool_name,
                         tool_name,
                         tool_args,
                         tool_args,

+ 2 - 34
agent/trace/run_api.py

@@ -100,18 +100,6 @@ class StopResponse(BaseModel):
     status: str  # "stopping" | "not_running"
     status: str  # "stopping" | "not_running"
 
 
 
 
-class KnowledgeConfirmRequest(BaseModel):
-    """知识确认请求"""
-    action: str = Field(..., description="confirm | reject")
-    edited_args: Optional[Dict[str, Any]] = Field(None, description="用户编辑后的参数(可选)")
-
-
-class KnowledgeConfirmResponse(BaseModel):
-    """知识确认响应"""
-    trace_id: str
-    status: str  # "resolved" | "no_pending"
-
-
 class ReflectResponse(BaseModel):
 class ReflectResponse(BaseModel):
     """反思响应"""
     """反思响应"""
     trace_id: str
     trace_id: str
@@ -470,26 +458,6 @@ async def stop_trace(trace_id: str):
     return StopResponse(trace_id=trace_id, status="stopping")
     return StopResponse(trace_id=trace_id, status="stopping")
 
 
 
 
-@router.post("/{trace_id}/knowledge-confirm", response_model=KnowledgeConfirmResponse)
-async def knowledge_confirm(trace_id: str, req: KnowledgeConfirmRequest):
-    """
-    响应知识确认请求(注入或保存)
-
-    前端用户确认/拒绝后调用此端点,resolve runner 中等待的 Future。
-    """
-    runner = _get_runner()
-
-    resolved = await runner.resolve_confirmation(trace_id, {
-        "action": req.action,
-        "edited_args": req.edited_args,
-    })
-
-    if not resolved:
-        return KnowledgeConfirmResponse(trace_id=trace_id, status="no_pending")
-
-    return KnowledgeConfirmResponse(trace_id=trace_id, status="resolved")
-
-
 @router.post("/{trace_id}/reflect", response_model=ReflectResponse)
 @router.post("/{trace_id}/reflect", response_model=ReflectResponse)
 async def reflect_trace(trace_id: str, req: ReflectRequest):
 async def reflect_trace(trace_id: str, req: ReflectRequest):
     """
     """
@@ -519,7 +487,7 @@ async def reflect_trace(trace_id: str, req: ReflectRequest):
         raise HTTPException(status_code=409, detail="Cannot reflect on a running trace. Stop it first.")
         raise HTTPException(status_code=409, detail="Cannot reflect on a running trace. Stop it first.")
 
 
     # 1. 构建完整历史消息(沿 parent chain)
     # 1. 构建完整历史消息(沿 parent chain)
-    history, _, _, _ = await runner._build_history(
+    history, _, _ = await runner._build_history(
         trace_id=trace_id,
         trace_id=trace_id,
         new_messages=[],
         new_messages=[],
         goal_tree=None,
         goal_tree=None,
@@ -533,7 +501,7 @@ async def reflect_trace(trace_id: str, req: ReflectRequest):
         trace_id=trace_id,
         trace_id=trace_id,
         messages=history,
         messages=history,
         llm_call_fn=runner.llm_call,
         llm_call_fn=runner.llm_call,
-        model=trace.model or "anthropic/claude-3-5-sonnet",
+        model=runner.model or "anthropic/claude-3-5-sonnet",
         focus=req.focus
         focus=req.focus
     )
     )
 
 

+ 0 - 41
agent/trace/websocket.py

@@ -395,47 +395,6 @@ async def broadcast_trace_status_changed(trace_id: str, status: str):
     await _broadcast_to_trace(trace_id, message)
     await _broadcast_to_trace(trace_id, message)
 
 
 
 
-async def broadcast_knowledge_confirm_request(trace_id: str, confirm_type: str, data: dict):
-    """
-    广播知识确认请求事件,前端收到后弹出确认弹窗。
-    如果当前没有活跃 WebSocket 连接,会等待连接建立后再广播(最多等 60 秒)。
-
-    Args:
-        trace_id: Trace ID
-        confirm_type: "knowledge_injection" | "knowledge_save"
-        data: 确认请求数据(知识内容等)
-    """
-    # 等待 WebSocket 连接建立
-    waited = 0
-    while (trace_id not in _active_connections or not _active_connections[trace_id]) and waited < 60:
-        await asyncio.sleep(1)
-        waited += 1
-
-    if trace_id not in _active_connections or not _active_connections[trace_id]:
-        import logging
-        logging.getLogger(__name__).warning(
-            f"[Knowledge Confirm] 等待 WebSocket 连接超时 (60s),无法广播确认请求: trace={trace_id}, type={confirm_type}"
-        )
-        return
-
-    store = get_trace_store()
-    event_id = await store.append_event(trace_id, "knowledge_confirm_request", {
-        "confirm_type": confirm_type,
-        "data": data,
-    })
-
-    message = {
-        "event": "knowledge_confirm_request",
-        "event_id": event_id,
-        "ts": datetime.now().isoformat(),
-        "trace_id": trace_id,
-        "confirm_type": confirm_type,
-        "data": data,
-    }
-
-    await _broadcast_to_trace(trace_id, message)
-
-
 # ===== 内部辅助函数 =====
 # ===== 内部辅助函数 =====
 
 
 
 

+ 0 - 6
frontend/react-template/src/api/traceApi.ts

@@ -56,12 +56,6 @@ export const traceApi = {
       data,
       data,
     });
     });
   },
   },
-  confirmKnowledge(traceId: string, data: { action: "confirm" | "reject"; edited_args?: Record<string, unknown> }) {
-    return request<{ trace_id: string; status: string }>(`/api/traces/${traceId}/knowledge-confirm`, {
-      method: "POST",
-      data,
-    });
-  },
   getExperiences() {
   getExperiences() {
     return request<string>("/api/experiences");
     return request<string>("/api/experiences");
   },
   },

+ 1 - 48
frontend/react-template/src/components/AgentControlPanel/AgentControlPanel.tsx

@@ -1,7 +1,6 @@
 import { useCallback, useEffect, useRef, useState } from "react";
 import { useCallback, useEffect, useRef, useState } from "react";
 import type { FC } from "react";
 import type { FC } from "react";
 import { traceApi } from "../../api/traceApi";
 import { traceApi } from "../../api/traceApi";
-import { KnowledgeConfirmModal, type KnowledgeConfirmData } from "../KnowledgeConfirmModal/KnowledgeConfirmModal";
 import styles from "./AgentControlPanel.module.css";
 import styles from "./AgentControlPanel.module.css";
 
 
 interface LogLine {
 interface LogLine {
@@ -89,15 +88,12 @@ export const AgentControlPanel: FC<AgentControlPanelProps> = ({
     const [isSubmitting, setIsSubmitting] = useState(false);
     const [isSubmitting, setIsSubmitting] = useState(false);
     const [isReflecting, setIsReflecting] = useState(false);
     const [isReflecting, setIsReflecting] = useState(false);
     const [isCompacting, setIsCompacting] = useState(false);
     const [isCompacting, setIsCompacting] = useState(false);
-    const [knowledgeConfirm, setKnowledgeConfirm] = useState<KnowledgeConfirmData | null>(null);
     const logsEndRef = useRef<HTMLDivElement>(null);
     const logsEndRef = useRef<HTMLDivElement>(null);
     const backendLogsEndRef = useRef<HTMLDivElement>(null);
     const backendLogsEndRef = useRef<HTMLDivElement>(null);
     const wsRef = useRef<WebSocket | null>(null);
     const wsRef = useRef<WebSocket | null>(null);
     const logWsRef = useRef<WebSocket | null>(null);
     const logWsRef = useRef<WebSocket | null>(null);
     const autoScrollRef = useRef(true);
     const autoScrollRef = useRef(true);
     const logContainerRef = useRef<HTMLDivElement>(null);
     const logContainerRef = useRef<HTMLDivElement>(null);
-    const handledConfirmEventsRef = useRef<Set<number>>(new Set());
-    const isReplayingRef = useRef(true); // 历史事件重放阶段标记
 
 
     const appendLog = useCallback((line: LogLine) => {
     const appendLog = useCallback((line: LogLine) => {
         setLogs((prev) => [...prev.slice(-500), line]); // 最多保留500条
         setLogs((prev) => [...prev.slice(-500), line]); // 最多保留500条
@@ -106,7 +102,6 @@ export const AgentControlPanel: FC<AgentControlPanelProps> = ({
     // WebSocket 监听 trace 事件
     // WebSocket 监听 trace 事件
     useEffect(() => {
     useEffect(() => {
         if (!traceId) return;
         if (!traceId) return;
-        isReplayingRef.current = true; // 每次新连接重置为重放状态
         const wsBase = API_BASE.replace(/^http(s?):\/\//, "ws$1://").replace(/\/+$/, "");
         const wsBase = API_BASE.replace(/^http(s?):\/\//, "ws$1://").replace(/\/+$/, "");
         const url = `${wsBase}/api/traces/${traceId}/watch?since_event_id=0`;
         const url = `${wsBase}/api/traces/${traceId}/watch?since_event_id=0`;
         const ws = new WebSocket(url);
         const ws = new WebSocket(url);
@@ -121,35 +116,12 @@ export const AgentControlPanel: FC<AgentControlPanelProps> = ({
             try {
             try {
                 const data: TraceEvent = JSON.parse(event.data);
                 const data: TraceEvent = JSON.parse(event.data);
 
 
-                // 连接成功事件:即根据服务端返回的真实状态初始化按
+                // 连接成功事件:即根据服务端返回的真实状态初始化按
                 if (data.event === "connected") {
                 if (data.event === "connected") {
                     const realStatus = data.trace_status || (data.is_running ? "running" : "unknown");
                     const realStatus = data.trace_status || (data.is_running ? "running" : "unknown");
                     setTraceStatus(realStatus);
                     setTraceStatus(realStatus);
                     setIsStatusLoaded(true);
                     setIsStatusLoaded(true);
                     appendLog({ time: now(), type: "system", text: `当前状态: ${realStatus.toUpperCase()}` });
                     appendLog({ time: now(), type: "system", text: `当前状态: ${realStatus.toUpperCase()}` });
-                    // connected 事件之后的历史重放结束,后续为实时事件
-                    // 使用 setTimeout 确保在同批历史事件处理完后再标记
-                    setTimeout(() => { isReplayingRef.current = false; }, 0);
-                    return;
-                }
-
-                // 知识确认请求:仅在实时运行时弹窗,跳过历史重放;同一 event_id 不重复弹
-                if (data.event === "knowledge_confirm_request") {
-                    const eventId = (data as unknown as { event_id?: number }).event_id;
-                    if (isReplayingRef.current) return; // 历史重放阶段,跳过
-                    if (eventId != null && handledConfirmEventsRef.current.has(eventId)) return; // 已处理过
-                    if (eventId != null) handledConfirmEventsRef.current.add(eventId);
-                    const d = data as unknown as { confirm_type: string; data: Record<string, unknown> };
-                    // 先暂停执行,让状态面板感知到
-                    if (traceId) {
-                        traceApi.stopTrace(traceId).catch(() => {});
-                    }
-                    setKnowledgeConfirm({
-                        confirm_type: d.confirm_type as KnowledgeConfirmData["confirm_type"],
-                        data: d.data as KnowledgeConfirmData["data"],
-                    });
-                    const label = d.confirm_type === "knowledge_injection" ? "知识注入" : "知识保存";
-                    appendLog({ time: now(), type: "warn", text: `等待用户确认: ${label}` });
                     return;
                     return;
                 }
                 }
 
 
@@ -347,20 +319,6 @@ export const AgentControlPanel: FC<AgentControlPanelProps> = ({
         }
         }
     };
     };
 
 
-    const handleKnowledgeConfirm = async (action: "confirm" | "reject", editedArgs?: Record<string, unknown>) => {
-        if (!traceId) return;
-        const label = knowledgeConfirm?.confirm_type === "knowledge_injection" ? "知识注入" : "知识保存";
-        setKnowledgeConfirm(null);
-        try {
-            await traceApi.confirmKnowledge(traceId, { action, edited_args: editedArgs });
-            appendLog({ time: now(), type: "system", text: `${label}: 用户${action === "confirm" ? "确认" : "拒绝"}` });
-            // 确认/拒绝后恢复执行
-            await traceApi.runTrace(traceId);
-        } catch {
-            appendLog({ time: now(), type: "error", text: `${label}确认请求失败` });
-        }
-    };
-
     const handleSubmitIntervention = async () => {
     const handleSubmitIntervention = async () => {
         const text = interventionText.trim();
         const text = interventionText.trim();
         if (!text || !traceId) return;
         if (!text || !traceId) return;
@@ -558,11 +516,6 @@ export const AgentControlPanel: FC<AgentControlPanelProps> = ({
                     </span>
                     </span>
                 </div>
                 </div>
             </div>
             </div>
-            <KnowledgeConfirmModal
-                visible={knowledgeConfirm !== null}
-                confirmData={knowledgeConfirm}
-                onConfirm={handleKnowledgeConfirm}
-            />
         </div>
         </div>
     );
     );
 };
 };

+ 0 - 166
frontend/react-template/src/components/KnowledgeConfirmModal/KnowledgeConfirmModal.tsx

@@ -1,166 +0,0 @@
-import { useState, type FC } from "react";
-import { Modal, TextArea, Tag, Descriptions } from "@douyinfe/semi-ui";
-
-interface KnowledgeItem {
-  id: string;
-  scenario?: string;
-  content: string;
-  tags?: { type?: string[] };
-  score?: number;
-}
-
-export interface KnowledgeConfirmData {
-  confirm_type: "knowledge_injection" | "knowledge_save";
-  data: {
-    // knowledge_injection
-    goal_id?: string;
-    goal_description?: string;
-    knowledge_items?: KnowledgeItem[];
-    // knowledge_save
-    tool_args?: {
-      scenario?: string;
-      content?: string;
-      tags_type?: string[];
-      urls?: string[];
-      score?: number;
-    };
-  };
-}
-
-interface KnowledgeConfirmModalProps {
-  visible: boolean;
-  confirmData: KnowledgeConfirmData | null;
-  onConfirm: (action: "confirm" | "reject", editedArgs?: Record<string, unknown>) => void;
-}
-
-export const KnowledgeConfirmModal: FC<KnowledgeConfirmModalProps> = ({
-  visible,
-  confirmData,
-  onConfirm,
-}) => {
-  const [editedContent, setEditedContent] = useState("");
-  const [editedScenario, setEditedScenario] = useState("");
-
-  const isInjection = confirmData?.confirm_type === "knowledge_injection";
-  const isSave = confirmData?.confirm_type === "knowledge_save";
-
-  const handleOpen = () => {
-    if (isSave && confirmData?.data.tool_args) {
-      setEditedContent(confirmData.data.tool_args.content || "");
-      setEditedScenario(confirmData.data.tool_args.scenario || "");
-    }
-  };
-
-  const handleConfirm = () => {
-    if (isSave) {
-      const args = confirmData?.data.tool_args;
-      const hasEdits =
-        editedContent !== (args?.content || "") ||
-        editedScenario !== (args?.scenario || "");
-      onConfirm(
-        "confirm",
-        hasEdits ? { content: editedContent, scenario: editedScenario } : undefined,
-      );
-    } else {
-      onConfirm("confirm");
-    }
-  };
-
-  if (!confirmData) return null;
-
-  return (
-    <Modal
-      visible={visible}
-      title={isInjection ? "📚 知识注入确认" : "💾 知识保存确认"}
-      onCancel={() => onConfirm("reject")}
-      onOk={handleConfirm}
-      okText="确认"
-      cancelText="拒绝"
-      centered
-      width={700}
-      afterVisibleChange={(v: boolean) => v && handleOpen()}
-      bodyStyle={{ maxHeight: "70vh", overflow: "auto" }}
-    >
-      {isInjection && (
-        <div>
-          <Descriptions
-            data={[
-              { key: "目标 Goal", value: confirmData.data.goal_description || "-" },
-              { key: "匹配知识数", value: String(confirmData.data.knowledge_items?.length || 0) },
-            ]}
-            style={{ marginBottom: 16 }}
-          />
-          <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
-            {confirmData.data.knowledge_items?.map((item) => (
-              <div
-                key={item.id}
-                style={{
-                  border: "1px solid #e0e0e0",
-                  borderRadius: 8,
-                  padding: 12,
-                  background: "#fafafa",
-                }}
-              >
-                <div style={{ marginBottom: 6, fontWeight: 600, fontSize: 13 }}>
-                  {item.id}
-                  {item.tags?.type?.map((t) => (
-                    <Tag key={t} size="small" style={{ marginLeft: 6 }} color="blue">
-                      {t}
-                    </Tag>
-                  ))}
-                </div>
-                {item.scenario && (
-                  <div style={{ fontSize: 12, color: "#666", marginBottom: 4 }}>
-                    场景: {item.scenario}
-                  </div>
-                )}
-                <div style={{ fontSize: 13, whiteSpace: "pre-wrap" }}>{item.content}</div>
-              </div>
-            ))}
-          </div>
-        </div>
-      )}
-
-      {isSave && confirmData.data.tool_args && (
-        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
-          <div>
-            <div style={{ marginBottom: 4, fontWeight: 600, fontSize: 13 }}>标签</div>
-            <div>
-              {confirmData.data.tool_args.tags_type?.map((t) => (
-                <Tag key={t} size="small" color="blue" style={{ marginRight: 4 }}>
-                  {t}
-                </Tag>
-              ))}
-            </div>
-          </div>
-          <div>
-            <div style={{ marginBottom: 4, fontWeight: 600, fontSize: 13 }}>场景</div>
-            <TextArea
-              value={editedScenario}
-              onChange={(v: string) => setEditedScenario(v)}
-              autosize={{ minRows: 2, maxRows: 5 }}
-            />
-          </div>
-          <div>
-            <div style={{ marginBottom: 4, fontWeight: 600, fontSize: 13 }}>内容</div>
-            <TextArea
-              value={editedContent}
-              onChange={(v: string) => setEditedContent(v)}
-              autosize={{ minRows: 4, maxRows: 12 }}
-            />
-          </div>
-          {confirmData.data.tool_args.urls && confirmData.data.tool_args.urls.length > 0 && (
-            <div>
-              <div style={{ marginBottom: 4, fontWeight: 600, fontSize: 13 }}>参考链接</div>
-              <ul style={{ margin: 0, paddingLeft: 20, fontSize: 12 }}>
-                {confirmData.data.tool_args.urls.map((url, i) => (
-                  <li key={i}>{url}</li>
-                ))}
-              </ul>
-            </div>
-          )}
-        </div>
-      )}
-    </Modal>
-  );
-};