mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-07-31 05:31:13 +08:00
feat(agent): enhance dynamic tool call handling to display specific tool names and accurate execution status
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
+ [优化] Agent 动态工具卡片显示具体工具名称、准确执行状态和失败原因,避免统一显示为含糊的「工具操作」。
|
||||
+ [修复] 画布 Agent 默认通过画布节点生成内容,仅在用户明确指定时使用 Codex 内置生图并将结果展示到对话和当前画布。
|
||||
+ [优化] Agent 面板标题、功能标签与新对话操作合并为单行顶部栏,减少面板空间占用。
|
||||
+ [新增] 画布 Agent 支持请求批准、自动审查和完全访问三档 Codex 权限,并可在对话中审批文件、命令与网络访问。
|
||||
|
||||
@@ -70,7 +70,14 @@ export function threadMessages(thread: unknown, planUpdates: CodexPlanUpdate[] =
|
||||
if (type === "imageView") messages.push({ id, role: "tool", title: "查看图片", text: String(field(item, "path") || "已查看图片"), detail: { kind: "image", status: "completed" } });
|
||||
if (type === "imageGeneration") messages.push({ id, role: "tool", title: "内置生图", text: String(field(item, "savedPath") || "图片生成完成"), detail: { kind: "image", status: field(item, "status"), savedPath: field(item, "savedPath") } });
|
||||
if (type === "contextCompaction") messages.push({ id, role: "tool", title: "整理上下文", text: "已整理当前对话,继续处理任务", detail: { kind: "context", status: "completed" } });
|
||||
if (type === "dynamicToolCall") messages.push({ id, role: "tool", title: "使用工具", text: "已完成工具操作", detail: { kind: "tool", status: field(item, "status") } });
|
||||
if (type === "dynamicToolCall") {
|
||||
const tool = String(field(item, "tool") || "");
|
||||
const title = toolName(tool);
|
||||
const error = String(field(field(item, "error"), "message") || "");
|
||||
const status = String(field(item, "status") || "");
|
||||
const failed = Boolean(error) || field(item, "success") === false || status === "failed" || status === "error";
|
||||
messages.push({ id, role: "tool", title, text: error || readableText(field(item, "contentItems")) || `${title}${failed ? "失败" : "完成"}`, detail: { kind: "tool", status: failed ? "failed" : status } });
|
||||
}
|
||||
if (type === "collabToolCall") messages.push({ id, role: "tool", title: "协作处理", text: "已完成协作任务", detail: { kind: "tool", status: field(item, "status") } });
|
||||
});
|
||||
if (planMessage && !planAdded) messages.push(planMessage);
|
||||
@@ -255,6 +262,11 @@ function routeName(path: string) {
|
||||
|
||||
/** 将 MCP 工具名称转换为聊天记录中的中文标题。 */
|
||||
function toolName(name: string) {
|
||||
if (name === "imagegen" || name.endsWith("__imagegen")) return "生成图片";
|
||||
if (name === "view_image" || name.endsWith("__view_image")) return "查看图片";
|
||||
if (name === "exec" || name === "exec_command" || name.endsWith("__exec_command")) return "执行命令";
|
||||
if (name === "apply_patch" || name.endsWith("__apply_patch")) return "修改文件";
|
||||
if (name === "web__run" || name.endsWith("__web__run")) return "搜索资料";
|
||||
if (name === "site_navigate") return "打开页面";
|
||||
if (name === "canvas_list_projects") return "查看画布列表";
|
||||
if (name === "canvas_apply_ops") return "画布操作";
|
||||
@@ -289,5 +301,5 @@ function toolName(name: string) {
|
||||
if (name === "assets_list") return "查看我的素材";
|
||||
if (name === "assets_add") return "添加到我的素材";
|
||||
if (name === "generation_get_status") return "查看生成状态";
|
||||
return "工具操作";
|
||||
return name ? `调用工具:${name}` : "工具操作";
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ description: 当前版本已实现但仍需人工验证的变更项
|
||||
|
||||
# 待测试
|
||||
|
||||
- Agent 动态工具信息:执行内置生图、查看图片、命令、文件修改或其他动态工具时,卡片标题应显示具体工具名称;执行失败时正文应显示真实错误原因,刷新并恢复历史对话后仍应保持一致,不再统一显示「工具操作已完成」。
|
||||
- Agent 画布生图:重启 Canvas Agent 后,其自动生成的工作区 `AGENTS.md` 应同步为最新版指令(用户自行编写的其他 `AGENTS.md` 不应被覆盖);输入“生成一张图片”时应调用 `canvas_generate_image`,通过当前画布节点创建并运行生成流程;只有明确输入“使用 Codex 内置生图/ImageGen 技能生成”时才允许调用内置能力,Codex App Server 返回的 `imageGeneration` 结果应显示在对话中并作为保持原比例的图片节点添加到当前画布;Agent 不应在没有生成结果时提前声称“已生成”。
|
||||
- Agent 顶部栏:标题只显示垂直居中的「Agent」,连接、对话、历史、日志、新对话和收起操作应位于同一行;面板较窄时标签仍可横向滚动且操作不应错位。
|
||||
- Agent Markdown 样式:右侧 Agent 回复中的代码块应为横向占满消息区域、无语言标题和无双层边框的紧凑代码条,单行内容不应保留纵向大面积空白,复制操作仅在悬停时弱化显示;行内代码、链接在浅色和深色主题下应清晰;点击外部链接后应显示中文紧凑确认弹窗,长路径能够正常换行且复制、继续打开和关闭操作可用;点击 `/Users/`、`/home/` 等本地绝对文件路径时应改为提示在系统文件管理器中定位,支持复制路径,且浏览器地址不应跳转为 localhost 文件路径。
|
||||
|
||||
@@ -36,6 +36,8 @@ export type AgentEventItem = {
|
||||
aggregatedOutput?: unknown;
|
||||
exitCode?: unknown;
|
||||
durationMs?: unknown;
|
||||
contentItems?: unknown;
|
||||
success?: unknown;
|
||||
changes?: unknown;
|
||||
summary?: unknown;
|
||||
query?: unknown;
|
||||
@@ -94,7 +96,18 @@ export function formatAgentActivity(event: AgentEventPayload): Omit<AgentChatIte
|
||||
const name = String(item.tool || "");
|
||||
return { role: "tool", title: toolName(name), text: completed ? item.error?.message || toolSummary(item) : `正在${toolAction(name)}…`, detail: toolDetail(item, item.error ? "failed" : status) };
|
||||
}
|
||||
if (item.type === "dynamic_tool_call") return { role: "tool", title: "使用工具", text: completed ? "已完成工具操作" : "正在执行工具操作…", detail: { kind: "tool", status } };
|
||||
if (item.type === "dynamic_tool_call") {
|
||||
const name = String(item.tool || "");
|
||||
const title = toolName(name);
|
||||
const failed = Boolean(item.error) || item.success === false || ["failed", "error"].includes(status);
|
||||
const currentStatus = failed ? "failed" : status;
|
||||
return {
|
||||
role: "tool",
|
||||
title,
|
||||
text: completed ? item.error?.message || readableText(item.contentItems) || `${title}${failed ? "失败" : "完成"}` : `正在${toolAction(name)}…`,
|
||||
detail: toolDetail(item, currentStatus),
|
||||
};
|
||||
}
|
||||
if (item.type === "collab_tool_call") return { role: "tool", title: "协作处理", text: completed ? "已完成协作任务" : "正在协作处理任务…", detail: { kind: "tool", status } };
|
||||
return null;
|
||||
}
|
||||
@@ -278,6 +291,11 @@ export function isConnectionErrorMessage(item: AgentChatItem) {
|
||||
}
|
||||
|
||||
export function toolName(name: string) {
|
||||
if (name === "imagegen" || name.endsWith("__imagegen")) return "生成图片";
|
||||
if (name === "view_image" || name.endsWith("__view_image")) return "查看图片";
|
||||
if (name === "exec" || name === "exec_command" || name.endsWith("__exec_command")) return "执行命令";
|
||||
if (name === "apply_patch" || name.endsWith("__apply_patch")) return "修改文件";
|
||||
if (name === "web__run" || name.endsWith("__web__run")) return "搜索资料";
|
||||
if (name === "canvas_apply_ops") return "画布操作";
|
||||
if (name === "canvas_get_state") return "读取画布";
|
||||
if (name === "canvas_get_selection") return "读取选区";
|
||||
@@ -304,7 +322,7 @@ export function toolName(name: string) {
|
||||
if (name === "canvas_run_generation") return "触发生成";
|
||||
if (name === "site_navigate") return "打开页面";
|
||||
if (isSiteTool(name)) return SITE_TOOL_LABELS[name];
|
||||
return "工具操作";
|
||||
return name ? `调用工具:${name}` : "工具操作";
|
||||
}
|
||||
|
||||
export function siteToolSummary(name: string, result: unknown) {
|
||||
|
||||
Reference in New Issue
Block a user