mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-05 17:04:27 +08:00
feat(agent): clarify local Agent connection instructions for Codex plugin and manual MCP usage
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
+ [优化] 本地 Agent 连接说明明确区分插件 / 手动 MCP 才会增加 Codex token 消耗,直接运行 Agent 不受影响。
|
||||||
|
+ [优化] 优化本地 Agent 连接说明,区分 Codex 插件启动和直接运行 Agent 两种方式。
|
||||||
+ [新增] Agent 对话消息改用 streamdown 流式渲染,提升长回复与 Markdown 内容展示效果。
|
+ [新增] Agent 对话消息改用 streamdown 流式渲染,提升长回复与 Markdown 内容展示效果。
|
||||||
+ [新增] Agent 新增画布、工作台、提示词库和素材等站点级工具,支持读取配置、触发生成与新增素材。
|
+ [新增] Agent 新增画布、工作台、提示词库和素材等站点级工具,支持读取配置、触发生成与新增素材。
|
||||||
+ [新增] Agent 面板改为全站常驻右侧栏,开关时同步推动顶栏和页面内容,并保留独立入口按钮。
|
+ [新增] Agent 面板改为全站常驻右侧栏,开关时同步推动顶栏和页面内容,并保留独立入口按钮。
|
||||||
|
|||||||
+15
-1
@@ -40,6 +40,20 @@ Canvas Agent 默认只监听 `127.0.0.1`。网页第一次带正确 token 连接
|
|||||||
|
|
||||||
如果希望 Codex 终端能直接操作画布,需要先把 Canvas Agent 注册成 Codex MCP。
|
如果希望 Codex 终端能直接操作画布,需要先把 Canvas Agent 注册成 Codex MCP。
|
||||||
|
|
||||||
|
直接运行 `npx -y @basketikun/canvas-agent` 只启动本地 Agent 服务,不会安装 MCP,也不会增加 Codex 工具上下文。只有安装 Codex app 插件,或手动执行 `codex mcp add` 后,`infinite-canvas` 工具才会进入 Codex 上下文;由于工具较多,不使用时建议移除。
|
||||||
|
|
||||||
|
通过插件安装时移除插件:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
codex plugin remove infinite-canvas
|
||||||
|
```
|
||||||
|
|
||||||
|
手动添加 MCP 时移除 MCP:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
codex mcp remove infinite-canvas
|
||||||
|
```
|
||||||
|
|
||||||
### Codex app 插件
|
### Codex app 插件
|
||||||
|
|
||||||
仓库内提供了 Codex app 插件:`plugins/infinite-canvas`。在 Codex app 中添加本仓库的 marketplace 后,可以安装 `Infinite Canvas` 插件;插件会注册同一个 `infinite-canvas` MCP,并带上画布操作说明。
|
仓库内提供了 Codex app 插件:`plugins/infinite-canvas`。在 Codex app 中添加本仓库的 marketplace 后,可以安装 `Infinite Canvas` 插件;插件会注册同一个 `infinite-canvas` MCP,并带上画布操作说明。
|
||||||
@@ -52,7 +66,7 @@ codex plugin marketplace add "$(pwd)"
|
|||||||
codex plugin add infinite-canvas@infinite-canvas-local
|
codex plugin add infinite-canvas@infinite-canvas-local
|
||||||
```
|
```
|
||||||
|
|
||||||
插件默认通过 npm 启动 MCP:
|
插件默认通过 npm 启动 MCP;这个命令只提供 MCP 工具,不会把 MCP 写入全局配置,也不会在退出时自动卸载:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx -y @basketikun/canvas-agent mcp
|
npx -y @basketikun/canvas-agent mcp
|
||||||
|
|||||||
@@ -103,7 +103,9 @@ export function startHttpServer() {
|
|||||||
console.log("Infinite Canvas Agent");
|
console.log("Infinite Canvas Agent");
|
||||||
console.log(`Local URL: ${config.url}`);
|
console.log(`Local URL: ${config.url}`);
|
||||||
console.log(`Connect token: ${config.token}`);
|
console.log(`Connect token: ${config.token}`);
|
||||||
console.log("Codex MCP: codex mcp add infinite-canvas -- npx -y @basketikun/canvas-agent mcp");
|
console.log("Codex MCP is not installed by this command.");
|
||||||
|
console.log("Optional MCP add: codex mcp add infinite-canvas -- npx -y @basketikun/canvas-agent mcp");
|
||||||
|
console.log("Remove manually added MCP: codex mcp remove infinite-canvas");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ description: 当前版本已实现但仍需人工验证的变更项
|
|||||||
|
|
||||||
# 待测试
|
# 待测试
|
||||||
|
|
||||||
|
- 本地 Agent 连接说明:新增提醒说明只有安装 Codex 插件或手动添加 MCP 后才会增加 Codex token 消耗,直接运行 `npx -y @basketikun/canvas-agent` 不会安装 MCP;需验证文案位置清晰。
|
||||||
|
- 本地 Agent 连接说明:画布面板和配置页 Codex Tab 改为区分“Codex 插件启动画布”和“直接运行 Agent 后网页连接”两种方式,需验证文案和布局清晰。
|
||||||
- 全站 Agent:Agent 面板从画布页抽离为全站常驻面板,挂在全局布局右侧,开/关只挤压左侧内容不遮挡;顶栏和画布工具条各有一个开关按钮,需验证在首页、生图、视频、素材、提示词库、画布等页面都能打开面板并保持 SSE 连接不断开。
|
- 全站 Agent:Agent 面板从画布页抽离为全站常驻面板,挂在全局布局右侧,开/关只挤压左侧内容不遮挡;顶栏和画布工具条各有一个开关按钮,需验证在首页、生图、视频、素材、提示词库、画布等页面都能打开面板并保持 SSE 连接不断开。
|
||||||
- 全站 Agent:新增 `site_navigate` 工具,Agent 可直接跳转 `/`、`/canvas`、`/canvas/:id`、`/image`、`/video`、`/prompts`、`/assets`、`/config`;导航直接执行不走工具确认,需验证跳转正确且面板不消失。
|
- 全站 Agent:新增 `site_navigate` 工具,Agent 可直接跳转 `/`、`/canvas`、`/canvas/:id`、`/image`、`/video`、`/prompts`、`/assets`、`/config`;导航直接执行不走工具确认,需验证跳转正确且面板不消失。
|
||||||
- 全站 Agent:画布工具(canvas_apply_ops 等)仅在当前处于画布页时可用,不在画布页调用会返回“当前不在画布页,请先用 site_navigate 打开画布”,需验证 Agent 会先导航到画布再执行画布操作。
|
- 全站 Agent:画布工具(canvas_apply_ops 等)仅在当前处于画布页时可用,不在画布页调用会返回“当前不在画布页,请先用 site_navigate 打开画布”,需验证 Agent 会先导航到画布再执行画布操作。
|
||||||
|
|||||||
@@ -59,6 +59,18 @@ codex plugin add infinite-canvas@personal
|
|||||||
|
|
||||||
安装后建议开启一个新的 Codex 对话,让新的 skill 和 MCP 工具完整加载。
|
安装后建议开启一个新的 Codex 对话,让新的 skill 和 MCP 工具完整加载。
|
||||||
|
|
||||||
|
安装 Codex 插件后会加载 `infinite-canvas` MCP。这个 MCP 内置工具较多,会增加 Codex 上下文和 token 消耗;不使用插件时建议移除插件:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
codex plugin remove infinite-canvas
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你另外手动执行过 `codex mcp add`,再移除手动添加的 MCP:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
codex mcp remove infinite-canvas
|
||||||
|
```
|
||||||
|
|
||||||
### 本仓库开发调试
|
### 本仓库开发调试
|
||||||
|
|
||||||
如果你就在 Infinite Canvas 仓库中调试插件,可以直接添加仓库自带 marketplace。建议使用仓库绝对路径,避免 Codex 从其他工作目录解析失败:
|
如果你就在 Infinite Canvas 仓库中调试插件,可以直接添加仓库自带 marketplace。建议使用仓库绝对路径,避免 Codex 从其他工作目录解析失败:
|
||||||
@@ -86,7 +98,7 @@ codex plugin add infinite-canvas@infinite-canvas-local
|
|||||||
|
|
||||||
## 工作机制
|
## 工作机制
|
||||||
|
|
||||||
插件默认通过以下命令启动 MCP,并会在 MCP 启动时自动尝试拉起本地 Agent:
|
插件默认通过以下命令启动 MCP;这个命令只提供 MCP 工具,不会把 MCP 写入全局配置,也不会在退出时自动卸载。需要打开画布时,`open-canvas` 技能会另外启动本地 Agent:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx -y @basketikun/canvas-agent mcp
|
npx -y @basketikun/canvas-agent mcp
|
||||||
|
|||||||
@@ -16,10 +16,11 @@ const MAX_ATTACHMENTS = 6;
|
|||||||
const MAX_ATTACHMENT_PAYLOAD_BYTES = 28 * 1024 * 1024;
|
const MAX_ATTACHMENT_PAYLOAD_BYTES = 28 * 1024 * 1024;
|
||||||
const DEFAULT_AGENT_URL = "http://127.0.0.1:17371";
|
const DEFAULT_AGENT_URL = "http://127.0.0.1:17371";
|
||||||
const AGENT_CONNECT_STEPS = [
|
const AGENT_CONNECT_STEPS = [
|
||||||
{ title: "安装 Codex 插件", text: "在 Codex app 安装 Infinite Canvas 插件后,首次使用插件会自动启动本地 Agent。" },
|
{ title: "方式一:在 Codex 中使用插件", text: "在 Codex app 安装 Infinite Canvas 插件后,通过插件启动画布,插件会自动启动本地 Agent 并带上连接信息。" },
|
||||||
{ title: "打开画布连接", text: "回到这里点击连接,网页会自动读取本机 Agent 配置。" },
|
{ title: "方式二:直接运行 Agent", text: "不使用 Codex 插件时,在终端运行下面命令,再回到网页里连接或手动填入 Local URL 和 Connect token。", command: "npx -y @basketikun/canvas-agent" },
|
||||||
{ title: "手动启动备用", text: "如果自动发现失败,再运行下面命令。", command: "npx -y @basketikun/canvas-agent" },
|
|
||||||
];
|
];
|
||||||
|
const AGENT_PLUGIN_REMOVE_COMMAND = "codex plugin remove infinite-canvas";
|
||||||
|
const AGENT_MCP_REMOVE_COMMAND = "codex mcp remove infinite-canvas";
|
||||||
|
|
||||||
type AgentEventPayload = {
|
type AgentEventPayload = {
|
||||||
agent?: string;
|
agent?: string;
|
||||||
@@ -635,7 +636,7 @@ function AgentConnectView({ theme, url, token, enabled, connected, activity, con
|
|||||||
<div>
|
<div>
|
||||||
<div className="text-base font-semibold leading-6">连接本地 Agent</div>
|
<div className="text-base font-semibold leading-6">连接本地 Agent</div>
|
||||||
<div className="mt-1 text-xs leading-5" style={{ color: theme.node.muted }}>
|
<div className="mt-1 text-xs leading-5" style={{ color: theme.node.muted }}>
|
||||||
安装 Codex 插件后,画布会优先自动连接本机 Agent。
|
按使用场景选择一种连接方式。
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
@@ -657,6 +658,25 @@ function AgentConnectView({ theme, url, token, enabled, connected, activity, con
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-lg border px-3 py-2.5 text-xs leading-5" style={{ borderColor: theme.node.stroke, color: theme.node.muted }}>
|
||||||
|
<div className="font-medium" style={{ color: theme.node.text }}>Codex 插件提醒</div>
|
||||||
|
<div className="mt-1">只有安装 Codex 插件或手动添加 MCP 后,工具列表才会进入 Codex 上下文并增加 token 消耗;仅运行 `npx -y @basketikun/canvas-agent` 启动本地 Agent 不会安装 MCP。</div>
|
||||||
|
<div className="mt-2 grid gap-1.5">
|
||||||
|
{[
|
||||||
|
["移除插件", AGENT_PLUGIN_REMOVE_COMMAND],
|
||||||
|
["移除手动 MCP", AGENT_MCP_REMOVE_COMMAND],
|
||||||
|
].map(([label, command]) => (
|
||||||
|
<div key={command} className="flex items-center gap-2 rounded-md border bg-transparent px-2 py-1.5" style={{ borderColor: theme.node.stroke, color: theme.node.text }}>
|
||||||
|
<span className="shrink-0 text-[11px]" style={{ color: theme.node.muted }}>{label}</span>
|
||||||
|
<code className="min-w-0 flex-1 overflow-x-auto whitespace-nowrap text-[11px] leading-5">{command}</code>
|
||||||
|
<Tooltip title="复制命令">
|
||||||
|
<Button size="small" type="text" className="!h-6 !w-6 !min-w-6" icon={<Copy className="size-3.5" />} onClick={() => copyCommand(command)} />
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="rounded-lg border p-3" style={{ borderColor: theme.node.stroke }}>
|
<div className="rounded-lg border p-3" style={{ borderColor: theme.node.stroke }}>
|
||||||
<div className="flex flex-wrap items-start justify-between gap-3">
|
<div className="flex flex-wrap items-start justify-between gap-3">
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
|
|||||||
@@ -46,10 +46,11 @@ const webdavDomainLabels: Record<AppSyncDomainKey, string> = {
|
|||||||
"video-workbench": "视频创作台",
|
"video-workbench": "视频创作台",
|
||||||
};
|
};
|
||||||
const codexSetupSteps = [
|
const codexSetupSteps = [
|
||||||
{ title: "安装 Codex 插件", text: "先在 Codex App 安装 Infinite Canvas 插件,插件会注册 MCP 并尝试启动本地 Canvas Agent。" },
|
{ title: "方式一:在 Codex 中使用插件", text: "先在 Codex App 安装 Infinite Canvas 插件,再通过插件启动画布,插件会自动启动本地 Canvas Agent 并带上连接信息。" },
|
||||||
{ title: "连接本地 Agent", text: "在本页填入 Local URL 和 Connect token 后点击连接。" },
|
{ title: "方式二:直接运行 Agent", text: "不使用 Codex 插件时,在终端运行下面命令,再回到网页里连接或手动填入 Local URL 和 Connect token。", command: "npx -y @basketikun/canvas-agent" },
|
||||||
{ title: "手动启动备用", text: "如果插件没有自动启动本地服务,在终端运行下面命令。", command: "npx -y @basketikun/canvas-agent" },
|
|
||||||
];
|
];
|
||||||
|
const codexPluginRemoveCommand = "codex plugin remove infinite-canvas";
|
||||||
|
const codexMcpRemoveCommand = "codex mcp remove infinite-canvas";
|
||||||
|
|
||||||
function createWebdavDomainProgress(): Record<AppSyncDomainKey, WebdavDomainProgress> {
|
function createWebdavDomainProgress(): Record<AppSyncDomainKey, WebdavDomainProgress> {
|
||||||
return webdavDomainKeys.reduce(
|
return webdavDomainKeys.reduce(
|
||||||
@@ -438,16 +439,23 @@ export function AppConfigPanel({ showDoneButton = false, initialTab = "channels"
|
|||||||
</div>
|
</div>
|
||||||
<div className={agentConnectError ? "text-xs text-red-600" : "text-xs text-stone-500"}>{agentConnectError ? "连接失败" : agentConnected ? agentActivity || "已连接" : agentEnabled ? "连接中" : "未连接"}</div>
|
<div className={agentConnectError ? "text-xs text-red-600" : "text-xs text-stone-500"}>{agentConnectError ? "连接失败" : agentConnected ? agentActivity || "已连接" : agentEnabled ? "连接中" : "未连接"}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4 grid gap-2 md:grid-cols-3">
|
<div className="mb-4 grid gap-2 md:grid-cols-2">
|
||||||
{codexSetupSteps.map((step, index) => (
|
{codexSetupSteps.map((step, index) => (
|
||||||
<div key={step.title} className="rounded-md border border-stone-200 p-3 dark:border-stone-800">
|
<div key={step.title} className="rounded-md border border-stone-200 p-3 dark:border-stone-800">
|
||||||
<div className="text-xs font-semibold text-stone-500">步骤 {index + 1}</div>
|
<div className="text-xs font-semibold text-stone-500">连接方式 {index + 1}</div>
|
||||||
<div className="mt-1 text-sm font-medium">{step.title}</div>
|
<div className="mt-1 text-sm font-medium">{step.title}</div>
|
||||||
<div className="mt-1 text-xs leading-5 text-stone-500">{step.text}</div>
|
<div className="mt-1 text-xs leading-5 text-stone-500">{step.text}</div>
|
||||||
{step.command ? <code className="mt-2 block overflow-x-auto rounded bg-stone-100 px-2 py-1.5 text-[11px] text-stone-700 dark:bg-stone-900 dark:text-stone-200">{step.command}</code> : null}
|
{step.command ? <code className="mt-2 block overflow-x-auto rounded bg-stone-100 px-2 py-1.5 text-[11px] text-stone-700 dark:bg-stone-900 dark:text-stone-200">{step.command}</code> : null}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-4 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs leading-5 text-amber-800 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200">
|
||||||
|
<div className="font-semibold">Codex 插件提醒</div>
|
||||||
|
<div className="mt-1">只有安装 Codex 插件或手动添加 MCP 后,工具列表才会进入 Codex 上下文并增加 token 消耗;仅运行 `npx -y @basketikun/canvas-agent` 启动本地 Agent 不会安装 MCP。</div>
|
||||||
|
<code className="mt-2 block overflow-x-auto rounded bg-white/70 px-2 py-1.5 text-[11px] text-amber-900 dark:bg-black/20 dark:text-amber-100">移除插件:{codexPluginRemoveCommand}</code>
|
||||||
|
<code className="mt-1 block overflow-x-auto rounded bg-white/70 px-2 py-1.5 text-[11px] text-amber-900 dark:bg-black/20 dark:text-amber-100">移除手动 MCP:{codexMcpRemoveCommand}</code>
|
||||||
|
</div>
|
||||||
<div className="grid gap-4 md:grid-cols-2">
|
<div className="grid gap-4 md:grid-cols-2">
|
||||||
<Form.Item label="Local URL" className="mb-4">
|
<Form.Item label="Local URL" className="mb-4">
|
||||||
<Input prefix={<Link2 className="mr-1 size-4 text-stone-400" />} value={agentUrl} placeholder="http://127.0.0.1:17371" onChange={(event) => updateAgentConfig({ url: event.target.value })} />
|
<Input prefix={<Link2 className="mr-1 size-4 text-stone-400" />} value={agentUrl} placeholder="http://127.0.0.1:17371" onChange={(event) => updateAgentConfig({ url: event.target.value })} />
|
||||||
|
|||||||
Reference in New Issue
Block a user