mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-04 16:14:22 +08:00
feat(agent): implement local image handling and enhance generated image integration in canvas
This commit is contained in:
@@ -7,4 +7,7 @@
|
||||
- 修改当前画布时根据任务使用已配置的 infinite-canvas MCP 工具;复杂批量改动使用 `canvas_apply_ops`。
|
||||
- 用户要求把上传附件放入画布或作为生成参考图时,必须先用 `canvas_create_attachment_nodes` 创建真实图片节点,再把节点 ID 传给生成流程,不要创建空图片占位节点。
|
||||
- 生图与视频工作台分别使用 `workbench_image_*`、`workbench_video_*` 工具;提示词和素材分别使用 `prompts_search`、`assets_*` 工具。
|
||||
- 用户要求生成图片、视频、音频或文本时,默认调用对应的 `canvas_generate_image`、`canvas_generate_video`、`canvas_generate_audio`、`canvas_generate_text`,通过当前画布的生成节点完成任务。
|
||||
- 只有用户明确要求使用“Codex 内置生图”“ImageGen 技能”或意思明确相同的能力时,才使用 Codex 自带的 `imagegen`;不要因为用户只说“生成图片”就自行改用内置生图。内置生图完成后,其结果会由 Canvas Agent 自动展示到对话并插入当前画布,无需再创建空节点或重复生成。
|
||||
- 只有用户明确说要在生图/视频工作台生成时,才使用 `workbench_image_*`、`workbench_video_*`。生成任务提交后应说明已经在画布或工作台开始生成,不要在实际没有结果时声称“已生成”。
|
||||
- 需要生成内容时直接调用对应生成工具,不要绑定特定业务场景,不要模拟鼠标点击,不要要求用户手动复制 JSON。
|
||||
|
||||
@@ -61,7 +61,8 @@ function initializeWorkspace(workspacePath: string) {
|
||||
if (initializedWorkspaces.has(workspacePath)) return;
|
||||
fs.mkdirSync(workspacePath, { recursive: true });
|
||||
const instructionsFile = path.join(workspacePath, "AGENTS.md");
|
||||
if (!fs.existsSync(instructionsFile)) fs.writeFileSync(instructionsFile, AGENT_PROMPT);
|
||||
const current = fs.existsSync(instructionsFile) ? fs.readFileSync(instructionsFile, "utf8") : "";
|
||||
if (!current || current.startsWith("# Infinite Canvas Agent")) fs.writeFileSync(instructionsFile, AGENT_PROMPT);
|
||||
initializedWorkspaces.add(workspacePath);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { spawn } from "node:child_process";
|
||||
import { stat } from "node:fs/promises";
|
||||
import { readFile, stat } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import express, { type NextFunction, type Request, type Response } from "express";
|
||||
|
||||
@@ -82,6 +82,14 @@ export function startHttpServer() {
|
||||
await revealLocalFile(filePath, file.isDirectory());
|
||||
res.json({ ok: true });
|
||||
}));
|
||||
app.post("/agent/local-image", route(async (req, res) => {
|
||||
const filePath = String(req.body?.path || "");
|
||||
if (!path.isAbsolute(filePath) || !/\.(?:avif|gif|jpe?g|png|webp)$/i.test(filePath)) return res.status(400).json({ ok: false, error: "图片路径无效" });
|
||||
const file = await stat(filePath);
|
||||
if (!file.isFile()) return res.status(400).json({ ok: false, error: "图片文件无效" });
|
||||
res.setHeader("Cache-Control", "no-store");
|
||||
res.type(path.extname(filePath)).send(await readFile(filePath));
|
||||
}));
|
||||
app.post("/api/tools", route(async (req, res) => res.json({ ok: true, result: await session.callTool(req.body?.name, req.body?.input || {}) })));
|
||||
app.get("/agent/codex/workspace", (_req, res) => {
|
||||
const workspace = ensureSiteWorkspace(config);
|
||||
|
||||
Reference in New Issue
Block a user