diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d65287..a8480fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## v0.7.0 - 2026-07-14 + + [新增] Agent 对话消息改用 streamdown 流式渲染,提升Markdown 内容展示效果。 + [新增] Agent 新增画布、工作台、提示词库和素材等站点级工具。 + [新增] Agent 面板改为全站常驻右侧栏,开关时同步推动顶栏和页面内容,并保留独立入口按钮。 @@ -16,6 +18,7 @@ + [调整] 画布节点顶部工具条改为点击选中节点后显示,避免鼠标经过节点时频繁弹出。 + [优化] 本地 Agent 连接说明明确区分插件 / 手动 MCP 才会增加 Codex token 消耗。 + [优化] 优化本地 Agent 连接说明,区分 Codex 插件启动和直接运行 Agent 两种方式。 ++ [修复] 修复 Gemini 格式生图时因内置比例列表触发误报导致生成失败的问题。 ## v0.6.0 - 2026-07-09 diff --git a/canvas-agent/package.json b/canvas-agent/package.json index 06f2d4e..3c6287a 100644 --- a/canvas-agent/package.json +++ b/canvas-agent/package.json @@ -1,6 +1,6 @@ { "name": "@basketikun/canvas-agent", - "version": "0.1.0", + "version": "0.2.0", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/web/src/components/canvas/canvas-local-agent-panel.tsx b/web/src/components/canvas/canvas-local-agent-panel.tsx index 79412b0..6ec1786 100644 --- a/web/src/components/canvas/canvas-local-agent-panel.tsx +++ b/web/src/components/canvas/canvas-local-agent-panel.tsx @@ -2,7 +2,7 @@ import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "rea import { useNavigate, useSearchParams } from "react-router-dom"; import { App, Button, Input, Segmented, Tooltip } from "antd"; import copyToClipboard from "copy-to-clipboard"; -import { Copy, FolderOpen, History, KeyRound, Link2, LoaderCircle, PlugZap, Plus, RefreshCw, RotateCcw, Square, Terminal, Trash2 } from "lucide-react"; +import { Copy, FolderOpen, History, KeyRound, Link2, LoaderCircle, PlugZap, Plus, RefreshCw, Square, Terminal, Trash2 } from "lucide-react"; import { canvasThemes } from "@/lib/canvas-theme"; import { useThemeStore } from "@/stores/use-theme-store"; @@ -320,14 +320,6 @@ export function CanvasLocalAgentPanel({ embedded, headless, autoConnect }: { emb await runToolCall(endpoint, token, tool); }; - const undoLastTool = () => { - const restored = canvasContextRef.current?.undoOps() || null; - if (!restored) return; - setAgentState({ activity: "已撤销" }); - addMessage({ role: "tool", title: "已撤销", text: "上一次工具操作", detail: restored }); - if (connected) void postState(endpoint, token, clientIdRef.current, restored); - }; - const toggleAgentConnection = async ({ silent = false }: { silent?: boolean } = {}) => { if (enabled) { clearAgentSession({ enabled: false, connected: false, activity: "离线", connectError: "" }); @@ -513,8 +505,8 @@ export function CanvasLocalAgentPanel({ embedded, headless, autoConnect }: { emb }} right={ <> - } diff --git a/web/src/services/api/image.ts b/web/src/services/api/image.ts index 3d08b75..1959759 100644 --- a/web/src/services/api/image.ts +++ b/web/src/services/api/image.ts @@ -146,16 +146,21 @@ function resolveSize(quality: string | undefined, ratio: string): string { return `${width}x${height}`; } -function parseImageRatio(value: string) { +function parseRatioValue(value: string) { const parts = value.split(":"); if (parts.length !== 2) throw new Error("图像尺寸格式不支持,请使用 auto、9:16 或 1024x1024"); const w = Number(parts[0]); const h = Number(parts[1]); if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) throw new Error("图像比例必须是正数,例如 9:16"); - if (Math.max(w, h) / Math.min(w, h) > IMAGE_MAX_RATIO) throw new Error("图像宽高比不能超过 3:1,请调整尺寸"); return { width: w, height: h }; } +function parseImageRatio(value: string) { + const ratio = parseRatioValue(value); + if (Math.max(ratio.width, ratio.height) / Math.min(ratio.width, ratio.height) > IMAGE_MAX_RATIO) throw new Error("图像宽高比不能超过 3:1,请调整尺寸"); + return ratio; +} + function parseImageDimensions(value: string) { const match = value.match(/^(\d+)x(\d+)$/i); if (!match) return null; @@ -197,8 +202,8 @@ function closestGeminiAspectRatio(value: string) { const ratio = parseImageRatio(value); const target = ratio.width / ratio.height; return GEMINI_SUPPORTED_RATIOS.reduce((best, item) => { - const current = parseImageRatio(item); - const bestRatio = parseImageRatio(best); + const current = parseRatioValue(item); + const bestRatio = parseRatioValue(best); return Math.abs(current.width / current.height - target) < Math.abs(bestRatio.width / bestRatio.height - target) ? item : best; }); }