fix(agent): 画布助手 - 完善不限预算与技能分页上下文卸载

This commit is contained in:
ddCat
2026-09-15 09:19:54 +08:00
parent 7dc807a4a2
commit 18d4bcbca6
10 changed files with 241 additions and 43 deletions

View File

@@ -137,7 +137,7 @@ export function AgentChatMessage({
return (
<div className={`flex items-start gap-3 ${isUser ? "justify-end" : "justify-start"}`}>
{!isUser ? <AgentTimelineMarker theme={theme} tone="agent" /> : null}
<div className={`min-w-0 text-sm leading-6 ${isUser ? "max-w-[82%] rounded-2xl rounded-br-md px-3.5 py-2.5 text-right" : "max-w-[calc(100%-36px)] flex-1 text-left"}`} style={{ color, ...(isUser ? { background: "#edf6ff" } : {}) }}>
<div className={`min-w-0 text-sm leading-6 ${isUser ? "max-w-[82%] rounded-2xl rounded-br-md px-3.5 py-2.5 text-right" : "max-w-[calc(100%-36px)] flex-1 text-left"}`} style={{ color, ...(isUser ? { background: theme.node.agentUserMessage } : {}) }}>
{item.role === "assistant" ? (
<AIMessageMarkdown className="text-left" isStreaming={isStreaming}>
{item.text}

View File

@@ -67,8 +67,8 @@ export function CanvasCloudAgentPanel({ canvasId, domainProjectId, nodeCount, re
const [permissionMode, setPermissionMode] = useState<AgentPermissionMode>("request_approval");
const [contextScope, setContextScope] = useState<AgentContextKey[]>(["canvas"]);
const [maxCredits, setMaxCredits] = useState("200");
const [maxGenerationTasks, setMaxGenerationTasks] = useState("8");
const [maxVideoSeconds, setMaxVideoSeconds] = useState("60");
const [maxGenerationTasks, setMaxGenerationTasks] = useState("0");
const [maxVideoSeconds, setMaxVideoSeconds] = useState("0");
const [conversations, setConversations] = useState<CloudAgentConversation[]>([]);
const [activeConversationId, setActiveConversationId] = useState(() => nanoid());
const [historyHydrated, setHistoryHydrated] = useState(false);
@@ -477,7 +477,7 @@ export function CanvasCloudAgentPanel({ canvasId, domainProjectId, nodeCount, re
const result = await addSkill(skill.skillId);
setSkills((current) => [...current.filter((item) => item.skillId !== skill.skillId), result.skill]);
setMarketSkills((current) => current.map((item) => (item.skillId === skill.skillId ? result.skill : item)));
setSelectedSkillIds((current) => (current.includes(skill.skillId) || current.length >= 8 ? current : [...current, skill.skillId]));
setSelectedSkillIds((current) => (current.includes(skill.skillId) ? current : [...current, skill.skillId]));
} catch (cause) {
setMessages((current) => appendAgentError(current, `skill-error-${Date.now()}`, cause, "添加 Skill 失败"));
}
@@ -721,7 +721,7 @@ export function CanvasCloudAgentPanel({ canvasId, domainProjectId, nodeCount, re
onSearch={setSkillSearch}
onToggle={(id) => setSelectedSkillIds((current) => {
if (current.includes(id)) return current.filter((item) => item !== id);
return current.length < 8 ? [...current, id] : current;
return [...current, id];
})}
onInstall={installSkill}
onLoadMore={loadMoreSkills}

View File

@@ -11,6 +11,7 @@ export const canvasThemes = {
},
node: {
label: "#4b5563",
agentUserMessage: "#edf6ff",
fill: "#ffffff",
panel: "#ffffff",
stroke: "#e2e4e8",
@@ -77,6 +78,7 @@ export const canvasThemes = {
},
node: {
label: "#a3a3a3",
agentUserMessage: "#182b40",
fill: "#181818",
panel: "#141414",
stroke: "rgba(255,255,255,.12)",

View File

@@ -1,32 +0,0 @@
import { describe, expect, test } from "bun:test";
import { clampGridSplitSize, isValidGridSplit, layoutGridSplitCells } from "./canvas-grid-split";
describe("canvas-grid-split", () => {
test("clamps size into 1..5", () => {
expect(clampGridSplitSize(0)).toBe(1);
expect(clampGridSplitSize(8)).toBe(5);
expect(clampGridSplitSize(2.6)).toBe(3);
});
test("rejects a single cell", () => {
expect(isValidGridSplit({ rows: 1, columns: 1 })).toBe(false);
expect(isValidGridSplit({ rows: 1, columns: 2 })).toBe(true);
expect(isValidGridSplit({ rows: 3, columns: 2 })).toBe(true);
});
test("lays out fitted cells without overlap", () => {
const cells = [
{ row: 0, column: 0, width: 592, height: 432 },
{ row: 0, column: 1, width: 592, height: 432 },
{ row: 1, column: 0, width: 592, height: 432 },
{ row: 1, column: 1, width: 592, height: 432 },
];
const positions = layoutGridSplitCells({ x: 100, y: 40 }, cells, 48);
expect(positions[1]).toEqual({ x: 100 + 592 + 48, y: 40 });
expect(positions[2]).toEqual({ x: 100, y: 40 + 432 + 48 });
expect(positions[3]).toEqual({ x: 100 + 592 + 48, y: 40 + 432 + 48 });
expect(positions[1]!.x).toBeGreaterThanOrEqual(positions[0]!.x + cells[0]!.width + 48);
expect(positions[2]!.y).toBeGreaterThanOrEqual(positions[0]!.y + cells[0]!.height + 48);
});
});