@next-open-ai/openclawx 0.8.26 → 0.8.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +5 -3
  2. package/apps/desktop/renderer/dist/assets/index-D9748VrD.js +89 -0
  3. package/apps/desktop/renderer/dist/assets/{index-B0_RWD2F.css → index-DVbrfeA6.css} +2 -2
  4. package/apps/desktop/renderer/dist/index.html +2 -2
  5. package/dist/core/agent/agent-manager.d.ts +4 -2
  6. package/dist/core/agent/agent-manager.js +10 -0
  7. package/dist/core/config/agent-reload-pending.d.ts +9 -0
  8. package/dist/core/config/agent-reload-pending.js +66 -0
  9. package/dist/core/config/desktop-config.d.ts +4 -2
  10. package/dist/core/config/desktop-config.js +4 -2
  11. package/dist/core/mcp/config.d.ts +14 -3
  12. package/dist/core/mcp/config.js +68 -3
  13. package/dist/core/mcp/index.d.ts +5 -5
  14. package/dist/core/mcp/index.js +2 -2
  15. package/dist/core/mcp/types.d.ts +18 -0
  16. package/dist/gateway/methods/agent-chat.js +4 -0
  17. package/dist/gateway/methods/run-scheduled-task.js +4 -0
  18. package/dist/server/agent-config/agent-config.service.d.ts +3 -3
  19. package/dist/server/agent-config/agent-config.service.js +2 -0
  20. package/package.json +2 -1
  21. package/presets/preset-agents.json +94 -0
  22. package/presets/preset-config.json +11 -0
  23. package/presets/preset-providers.json +173 -0
  24. package/presets/workspaces/code-assistant/skills/code-review/SKILL.md +19 -0
  25. package/presets/workspaces/code-assistant/skills/code-runner/SKILL.md +21 -0
  26. package/presets/workspaces/code-assistant/skills/git-helper/SKILL.md +29 -0
  27. package/presets/workspaces/creator-assistant/skills/.gitkeep +0 -0
  28. package/presets/workspaces/creator-assistant/skills/creator-tools/SKILL.md +15 -0
  29. package/presets/workspaces/doc-assistant/skills/doc-processor/SKILL.md +21 -0
  30. package/presets/workspaces/download-assistant/skills/downloader/SKILL.md +20 -0
  31. package/presets/workspaces/file-assistant/skills/file-converter/SKILL.md +21 -0
  32. package/presets/workspaces/file-assistant/skills/file-organizer/SKILL.md +17 -0
  33. package/presets/workspaces/file-assistant/skills/file-search/SKILL.md +22 -0
  34. package/presets/workspaces/morning-briefing/skills/news-fetcher/SKILL.md +16 -0
  35. package/presets/workspaces/morning-briefing/skills/web-summarizer/SKILL.md +20 -0
  36. package/presets/workspaces/news-assistant/skills/news-fetcher/SKILL.md +16 -0
  37. package/presets/workspaces/news-assistant/skills/web-summarizer/SKILL.md +20 -0
  38. package/apps/desktop/renderer/dist/assets/index-B8jRTtME.js +0 -89
@@ -11,8 +11,8 @@
11
11
  <link
12
12
  href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Roboto+Mono:wght@400;500&display=swap"
13
13
  rel="stylesheet">
14
- <script type="module" crossorigin src="/assets/index-B8jRTtME.js"></script>
15
- <link rel="stylesheet" crossorigin href="/assets/index-B0_RWD2F.css">
14
+ <script type="module" crossorigin src="/assets/index-D9748VrD.js"></script>
15
+ <link rel="stylesheet" crossorigin href="/assets/index-DVbrfeA6.css">
16
16
  </head>
17
17
 
18
18
  <body>
@@ -1,5 +1,5 @@
1
1
  import type { AgentSession } from "@mariozechner/pi-coding-agent";
2
- import type { McpServerConfig } from "../mcp/index.js";
2
+ import type { McpServerConfig, McpServersStandardFormat } from "../mcp/index.js";
3
3
  import type { Skill } from "./skills.js";
4
4
  export interface AgentManagerOptions {
5
5
  agentDir?: string;
@@ -59,7 +59,7 @@ export declare class AgentManager {
59
59
  apiKey?: string;
60
60
  maxSessions?: number;
61
61
  targetAgentId?: string;
62
- mcpServers?: McpServerConfig[];
62
+ mcpServers?: McpServerConfig[] | McpServersStandardFormat;
63
63
  /** 自定义系统提示词(来自 agent 配置),会与技能等一起组成最终 systemPrompt */
64
64
  systemPrompt?: string;
65
65
  /** 是否使用长记忆(memory_recall/save_experience);默认 true */
@@ -73,6 +73,8 @@ export declare class AgentManager {
73
73
  deleteSession(compositeKey: string): Promise<boolean>;
74
74
  /** 按业务 sessionId 删除该会话下所有 agent 的 Core Session(如删除会话时);关闭前将各 session 最新 compaction 写入向量库 */
75
75
  deleteSessionsByBusinessId(sessionId: string): Promise<void>;
76
+ /** 按 agentId 删除该智能体下所有 Session(配置更新后使旧会话失效,下次请求会用新配置建新会话) */
77
+ deleteSessionsByAgentId(agentId: string): Promise<void>;
76
78
  clearAll(): void;
77
79
  }
78
80
  export declare const agentManager: AgentManager;
@@ -97,7 +97,9 @@ For downloads, provide either a direct URL or a selector to click.`;
97
97
 
98
98
  - **save_experience**: Store summaries in long-term memory. **At the end of each round of conversation** (after you have finished replying to the user), briefly summarize the main outcomes, conclusions, or reusable points and call \`save_experience\` with that summary.
99
99
  - **memory_recall**: Retrieve relevant memories by semantic search. **When the user asks about past work, decisions, dates, people, preferences, todos, complex tasks, scheduled tasks, or anything that may need past experience**, call \`memory_recall\` first with a suitable query, then answer using the recalled content. Do not inject any history or memory into your replies unless you have just retrieved it via \`memory_recall\` for that question.`;
100
+ const terminologyNote = "【术语】本系统中「智能体」「助手」「专家」均指同一概念(Agent),可互换使用。用户说切换助手/专家或提到某个助手/专家时,即指切换或使用对应智能体。";
100
101
  const parts = [
102
+ terminologyNote,
101
103
  "You are a helpful assistant. When users ask about skills, explain what skills are available.",
102
104
  browserToolDesc,
103
105
  skillsBlock,
@@ -326,6 +328,14 @@ For downloads, provide either a direct URL or a selector to click.`;
326
328
  this.sessions.delete(key);
327
329
  }
328
330
  }
331
+ /** 按 agentId 删除该智能体下所有 Session(配置更新后使旧会话失效,下次请求会用新配置建新会话) */
332
+ async deleteSessionsByAgentId(agentId) {
333
+ const suffix = COMPOSITE_KEY_SEP + agentId;
334
+ const keysToProcess = Array.from(this.sessions.keys()).filter((k) => k.endsWith(suffix));
335
+ for (const key of keysToProcess) {
336
+ await this.deleteSession(key);
337
+ }
338
+ }
329
339
  clearAll() {
330
340
  this.sessions.clear();
331
341
  this.sessionLastActiveAt.clear();
@@ -0,0 +1,9 @@
1
+ /** 保存配置后调用:将 agentId 加入待重载列表 */
2
+ export declare function addPendingAgentReload(agentId: string): Promise<void>;
3
+ /** 获取当前待重载的 agentId 列表(仅读) */
4
+ export declare function getPendingAgentReloadIds(): Promise<string[]>;
5
+ /**
6
+ * 若该 agent 在待重载列表中则移除并返回 true,否则返回 false。
7
+ * 在使旧 Session 失效前调用,便于调用方先 invalidate 再 getOrCreateSession。
8
+ */
9
+ export declare function consumePendingAgentReload(agentId: string): Promise<boolean>;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Agent 配置更新后「待重载」标志:存于 ~/.openbot/desktop/.agent-reload-pending.json。
3
+ * Nest 保存配置时写入 agentId;Gateway/本地会话在 getOrCreateSession 前若发现该 agent 有待重载,
4
+ * 则先使该 agent 下所有旧 Session 失效,再用新配置创建新 Session,然后清除标志,实现配置实时生效。
5
+ */
6
+ import { readFile, writeFile, mkdir } from "fs/promises";
7
+ import { existsSync } from "fs";
8
+ import { join } from "path";
9
+ import { homedir } from "os";
10
+ const FILENAME = ".agent-reload-pending.json";
11
+ function getDesktopDir() {
12
+ const home = process.env.HOME || process.env.USERPROFILE || homedir();
13
+ return join(home, ".openbot", "desktop");
14
+ }
15
+ function getFilePath() {
16
+ return join(getDesktopDir(), FILENAME);
17
+ }
18
+ async function readPending() {
19
+ const path = getFilePath();
20
+ if (!existsSync(path))
21
+ return [];
22
+ try {
23
+ const raw = await readFile(path, "utf-8");
24
+ const data = JSON.parse(raw);
25
+ return Array.isArray(data.agentIds) ? data.agentIds : [];
26
+ }
27
+ catch {
28
+ return [];
29
+ }
30
+ }
31
+ async function writePending(agentIds) {
32
+ const dir = getDesktopDir();
33
+ if (!existsSync(dir))
34
+ await mkdir(dir, { recursive: true });
35
+ await writeFile(join(dir, FILENAME), JSON.stringify({ agentIds }, null, 0), "utf-8");
36
+ }
37
+ /** 保存配置后调用:将 agentId 加入待重载列表 */
38
+ export async function addPendingAgentReload(agentId) {
39
+ if (!agentId || !agentId.trim())
40
+ return;
41
+ const id = agentId.trim();
42
+ const list = await readPending();
43
+ if (list.includes(id))
44
+ return;
45
+ await writePending([...list, id]);
46
+ }
47
+ /** 获取当前待重载的 agentId 列表(仅读) */
48
+ export async function getPendingAgentReloadIds() {
49
+ return readPending();
50
+ }
51
+ /**
52
+ * 若该 agent 在待重载列表中则移除并返回 true,否则返回 false。
53
+ * 在使旧 Session 失效前调用,便于调用方先 invalidate 再 getOrCreateSession。
54
+ */
55
+ export async function consumePendingAgentReload(agentId) {
56
+ if (!agentId || !agentId.trim())
57
+ return false;
58
+ const id = agentId.trim();
59
+ const list = await readPending();
60
+ const idx = list.indexOf(id);
61
+ if (idx < 0)
62
+ return false;
63
+ const next = list.slice(0, idx).concat(list.slice(idx + 1));
64
+ await writePending(next);
65
+ return true;
66
+ }
@@ -54,6 +54,8 @@ export interface ChannelsConfig {
54
54
  }
55
55
  /** MCP 服务器配置(与 core/mcp 类型一致,避免 core/config 依赖 core/mcp 实现) */
56
56
  export type DesktopMcpServerConfig = import("../mcp/index.js").McpServerConfig;
57
+ /** MCP 标准 JSON 格式(key 为服务器名称),存储与 UI 可读写 */
58
+ export type DesktopMcpServersStandardFormat = import("../mcp/index.js").McpServersStandardFormat;
57
59
  /** Agent 执行器类型:local=本机 pi-coding-agent,coze/openclawx/opencode=远程代理 */
58
60
  export type AgentRunnerType = "local" | "coze" | "openclawx" | "opencode";
59
61
  /** Coze 站点:国内站 api.coze.cn / 国际站 api.coze.com,凭证不通用 */
@@ -139,8 +141,8 @@ export interface DesktopAgentConfig {
139
141
  apiKey?: string;
140
142
  /** 工作区名,来自 agents.json 的 agent.workspace 或 agent.id */
141
143
  workspace?: string;
142
- /** MCP 服务器配置,创建 Session 时传入 */
143
- mcpServers?: DesktopMcpServerConfig[];
144
+ /** MCP 服务器配置(数组或标准对象格式),创建 Session 时传入并归一化 */
145
+ mcpServers?: DesktopMcpServerConfig[] | DesktopMcpServersStandardFormat;
144
146
  /** 自定义系统提示词,会与技能等一起组成最终 systemPrompt */
145
147
  systemPrompt?: string;
146
148
  /** 执行器类型,缺省 local */
@@ -233,8 +233,10 @@ export async function loadDesktopAgentConfig(agentId) {
233
233
  workspaceName = agent.workspace;
234
234
  else if (agent.id)
235
235
  workspaceName = agent.id;
236
- if (agent.mcpServers && Array.isArray(agent.mcpServers)) {
237
- mcpServers = agent.mcpServers;
236
+ if (agent.mcpServers != null) {
237
+ if (Array.isArray(agent.mcpServers) || (typeof agent.mcpServers === "object" && !Array.isArray(agent.mcpServers))) {
238
+ mcpServers = agent.mcpServers;
239
+ }
238
240
  }
239
241
  if (agent.systemPrompt && typeof agent.systemPrompt === "string") {
240
242
  systemPrompt = agent.systemPrompt.trim();
@@ -1,13 +1,24 @@
1
1
  /**
2
2
  * MCP 配置解析与校验。
3
3
  * 从 getOrCreateSession 的 options.mcpServers 中取出并规范化,支持 stdio 与 sse。
4
+ * 支持两种输入:数组(含 transport)或标准 JSON 对象(key 为名称,由 command/url 推断 transport)。
4
5
  */
5
- import type { McpServerConfig, McpServerConfigStdio, McpServerConfigSse } from "./types.js";
6
+ import type { McpServerConfig, McpServerConfigStdio, McpServerConfigSse, McpServersStandardFormat } from "./types.js";
7
+ /**
8
+ * 将标准格式(mcpServers 对象)转为内部数组格式。
9
+ * 有 command 视为 stdio,有 url 视为 sse;无效项跳过。
10
+ */
11
+ export declare function standardFormatToArray(mcpServers: McpServersStandardFormat): McpServerConfig[];
12
+ /**
13
+ * 将内部数组格式转为标准 JSON 对象(用于展示/编辑)。
14
+ * 无名称的项使用 "MCP Server 1"、"MCP Server 2" 等占位 key。
15
+ */
16
+ export declare function arrayToStandardFormat(mcpServers: McpServerConfig[]): McpServersStandardFormat;
6
17
  /**
7
18
  * 从会话选项里解析出本会话启用的 MCP 服务器配置列表。
8
- * 支持 stdio(本地进程)与 sse(远程 HTTP)。
19
+ * 支持:数组(含 transport)、标准 JSON 对象(key 为名称,由 command/url 推断)。
9
20
  */
10
- export declare function resolveMcpServersForSession(mcpServers: McpServerConfig[] | undefined): McpServerConfig[];
21
+ export declare function resolveMcpServersForSession(mcpServers: McpServerConfig[] | McpServersStandardFormat | undefined): McpServerConfig[];
11
22
  /**
12
23
  * 为 stdio 配置生成缓存键(用于 Operator 复用同一进程连接)
13
24
  */
@@ -1,15 +1,80 @@
1
1
  /**
2
2
  * MCP 配置解析与校验。
3
3
  * 从 getOrCreateSession 的 options.mcpServers 中取出并规范化,支持 stdio 与 sse。
4
+ * 支持两种输入:数组(含 transport)或标准 JSON 对象(key 为名称,由 command/url 推断 transport)。
4
5
  */
6
+ /**
7
+ * 将标准格式(mcpServers 对象)转为内部数组格式。
8
+ * 有 command 视为 stdio,有 url 视为 sse;无效项跳过。
9
+ */
10
+ export function standardFormatToArray(mcpServers) {
11
+ const result = [];
12
+ for (const [_, entry] of Object.entries(mcpServers)) {
13
+ if (!entry || typeof entry !== "object")
14
+ continue;
15
+ const cmd = typeof entry.command === "string" ? entry.command.trim() : "";
16
+ const url = typeof entry.url === "string" ? entry.url.trim() : "";
17
+ if (cmd) {
18
+ result.push({
19
+ transport: "stdio",
20
+ command: cmd,
21
+ args: Array.isArray(entry.args) ? entry.args : undefined,
22
+ env: entry.env && typeof entry.env === "object" ? entry.env : undefined,
23
+ });
24
+ }
25
+ else if (url) {
26
+ result.push({
27
+ transport: "sse",
28
+ url,
29
+ headers: entry.headers && typeof entry.headers === "object" ? entry.headers : undefined,
30
+ });
31
+ }
32
+ else {
33
+ console.warn("[mcp] 跳过无效标准格式项:需 command(stdio)或 url(sse)");
34
+ }
35
+ }
36
+ return result;
37
+ }
38
+ /**
39
+ * 将内部数组格式转为标准 JSON 对象(用于展示/编辑)。
40
+ * 无名称的项使用 "MCP Server 1"、"MCP Server 2" 等占位 key。
41
+ */
42
+ export function arrayToStandardFormat(mcpServers) {
43
+ const out = {};
44
+ mcpServers.forEach((s, i) => {
45
+ const name = `MCP Server ${i + 1}`;
46
+ if (s.transport === "stdio") {
47
+ const e = {
48
+ command: s.command,
49
+ args: s.args,
50
+ env: s.env,
51
+ };
52
+ out[name] = e;
53
+ }
54
+ else {
55
+ const e = {
56
+ url: s.url,
57
+ headers: s.headers,
58
+ };
59
+ out[name] = e;
60
+ }
61
+ });
62
+ return out;
63
+ }
64
+ function isStandardFormat(obj) {
65
+ return obj !== null && typeof obj === "object" && !Array.isArray(obj);
66
+ }
5
67
  /**
6
68
  * 从会话选项里解析出本会话启用的 MCP 服务器配置列表。
7
- * 支持 stdio(本地进程)与 sse(远程 HTTP)。
69
+ * 支持:数组(含 transport)、标准 JSON 对象(key 为名称,由 command/url 推断)。
8
70
  */
9
71
  export function resolveMcpServersForSession(mcpServers) {
10
- if (!Array.isArray(mcpServers) || mcpServers.length === 0) {
72
+ if (mcpServers == null)
73
+ return [];
74
+ if (isStandardFormat(mcpServers))
75
+ return standardFormatToArray(mcpServers);
76
+ if (!Array.isArray(mcpServers) || mcpServers.length === 0)
11
77
  return [];
12
- }
13
78
  const result = [];
14
79
  for (const s of mcpServers) {
15
80
  if (!s || typeof s !== "object")
@@ -3,16 +3,16 @@
3
3
  * 配置在创建 Session 时通过 options.mcpServers 传入,与 Skill 类似。
4
4
  */
5
5
  import type { ToolDefinition } from "@mariozechner/pi-coding-agent";
6
- import type { McpServerConfig } from "./types.js";
7
- export type { McpServerConfig, McpServerConfigStdio, McpServerConfigSse, McpTool } from "./types.js";
8
- export { resolveMcpServersForSession, stdioConfigKey, sseConfigKey, mcpConfigKey } from "./config.js";
6
+ import type { McpServerConfig, McpServersStandardFormat } from "./types.js";
7
+ export type { McpServerConfig, McpServerConfigStdio, McpServerConfigSse, McpServerConfigStandardEntry, McpServersStandardFormat, McpTool, } from "./types.js";
8
+ export { resolveMcpServersForSession, standardFormatToArray, arrayToStandardFormat, stdioConfigKey, sseConfigKey, mcpConfigKey, } from "./config.js";
9
9
  export { McpClient } from "./client.js";
10
10
  export { getMcpToolDefinitions, shutdownMcpClients } from "./operator.js";
11
11
  export { mcpToolToToolDefinition, mcpToolsToToolDefinitions } from "./adapter.js";
12
12
  /**
13
13
  * 根据会话选项中的 mcpServers 配置,返回该会话可用的 MCP 工具(ToolDefinition 数组)。
14
- * AgentManager.getOrCreateSession 中调用,并入 customTools。
14
+ * 支持数组或标准 JSON 对象格式;在 AgentManager.getOrCreateSession 中调用,并入 customTools。
15
15
  */
16
16
  export declare function createMcpToolsForSession(options: {
17
- mcpServers?: McpServerConfig[];
17
+ mcpServers?: McpServerConfig[] | McpServersStandardFormat;
18
18
  }): Promise<ToolDefinition[]>;
@@ -4,13 +4,13 @@
4
4
  */
5
5
  import { resolveMcpServersForSession } from "./config.js";
6
6
  import { getMcpToolDefinitions } from "./operator.js";
7
- export { resolveMcpServersForSession, stdioConfigKey, sseConfigKey, mcpConfigKey } from "./config.js";
7
+ export { resolveMcpServersForSession, standardFormatToArray, arrayToStandardFormat, stdioConfigKey, sseConfigKey, mcpConfigKey, } from "./config.js";
8
8
  export { McpClient } from "./client.js";
9
9
  export { getMcpToolDefinitions, shutdownMcpClients } from "./operator.js";
10
10
  export { mcpToolToToolDefinition, mcpToolsToToolDefinitions } from "./adapter.js";
11
11
  /**
12
12
  * 根据会话选项中的 mcpServers 配置,返回该会话可用的 MCP 工具(ToolDefinition 数组)。
13
- * AgentManager.getOrCreateSession 中调用,并入 customTools。
13
+ * 支持数组或标准 JSON 对象格式;在 AgentManager.getOrCreateSession 中调用,并入 customTools。
14
14
  */
15
15
  export async function createMcpToolsForSession(options) {
16
16
  const configs = resolveMcpServersForSession(options.mcpServers);
@@ -22,6 +22,24 @@ export interface McpServerConfigSse {
22
22
  }
23
23
  /** 单条 MCP 服务器配置(由调用方在创建 Session 时传入,与 Skill 类似) */
24
24
  export type McpServerConfig = McpServerConfigStdio | McpServerConfigSse;
25
+ /**
26
+ * 标准 JSON 格式中的单条 MCP 配置(无 transport,由 command/url 推断)。
27
+ * 与 Claude/Anthropic 等生态常用格式一致。
28
+ */
29
+ export interface McpServerConfigStandardEntry {
30
+ /** stdio:可执行命令 */
31
+ command?: string;
32
+ /** stdio:命令行参数 */
33
+ args?: string[];
34
+ /** stdio:环境变量 */
35
+ env?: Record<string, string>;
36
+ /** sse:远程服务地址 */
37
+ url?: string;
38
+ /** sse:请求头 */
39
+ headers?: Record<string, string>;
40
+ }
41
+ /** 标准 JSON 格式:mcpServers 为对象,key 为服务器名称 */
42
+ export type McpServersStandardFormat = Record<string, McpServerConfigStandardEntry>;
25
43
  /** MCP 协议中 Tool 的 inputSchema 为 JSON Schema 对象 */
26
44
  export interface McpToolInputSchema {
27
45
  type?: string;
@@ -4,6 +4,7 @@ import { getSessionCurrentAgentResolver, getSessionCurrentAgentUpdater } from ".
4
4
  import { send, createEvent } from "../utils.js";
5
5
  import { connectedClients } from "../clients.js";
6
6
  import { getDesktopConfig, loadDesktopAgentConfig } from "../../core/config/desktop-config.js";
7
+ import { consumePendingAgentReload } from "../../core/config/agent-reload-pending.js";
7
8
  import { registerProxyRunAbort } from "../proxy-run-abort.js";
8
9
  const COMPOSITE_KEY_SEP = "::";
9
10
  /**
@@ -111,6 +112,9 @@ async function handleAgentChatInner(client, targetSessionId, message, params) {
111
112
  }
112
113
  const effectiveTargetAgentId = sessionType === "system" ? targetAgentId : currentAgentId;
113
114
  const { maxAgentSessions } = getDesktopConfig();
115
+ if (await consumePendingAgentReload(currentAgentId)) {
116
+ await agentManager.deleteSessionsByAgentId(currentAgentId);
117
+ }
114
118
  let session;
115
119
  try {
116
120
  session = await agentManager.getOrCreateSession(targetSessionId, {
@@ -1,5 +1,6 @@
1
1
  import { agentManager } from "../../core/agent/agent-manager.js";
2
2
  import { loadDesktopAgentConfig } from "../../core/config/desktop-config.js";
3
+ import { consumePendingAgentReload } from "../../core/config/agent-reload-pending.js";
3
4
  async function readBody(req) {
4
5
  return new Promise((resolve, reject) => {
5
6
  const chunks = [];
@@ -49,6 +50,9 @@ export async function handleRunScheduledTask(req, res) {
49
50
  apiKey = agentConfig.apiKey;
50
51
  }
51
52
  const COMPOSITE_KEY_SEP = "::";
53
+ if (await consumePendingAgentReload(sessionAgentId)) {
54
+ await agentManager.deleteSessionsByAgentId(sessionAgentId);
55
+ }
52
56
  try {
53
57
  const session = await agentManager.getOrCreateSession(sessionId, {
54
58
  agentId: sessionAgentId,
@@ -1,4 +1,4 @@
1
- import type { McpServerConfig } from '../../core/mcp/index.js';
1
+ import type { McpServerConfig, McpServersStandardFormat } from '../../core/mcp/index.js';
2
2
  import { DatabaseService } from '../database/database.service.js';
3
3
  import { WorkspaceService } from '../workspace/workspace.service.js';
4
4
  /** 缺省智能体 ID / 工作空间名,不可删除;对应目录 ~/.openbot/workspace/default */
@@ -58,8 +58,8 @@ export interface AgentConfigItem {
58
58
  modelItemCode?: string;
59
59
  /** 是否为系统缺省智能体(主智能体),不可删除 */
60
60
  isDefault?: boolean;
61
- /** MCP 服务器配置列表,创建 Session 时传入(与 Skill 类似) */
62
- mcpServers?: McpServerConfig[];
61
+ /** MCP 配置:数组(含 transport)或标准 JSON 对象(key 为服务器名称),创建 Session 时归一化使用 */
62
+ mcpServers?: McpServerConfig[] | McpServersStandardFormat;
63
63
  /** 自定义系统提示词,会与技能等一起组成最终 systemPrompt */
64
64
  systemPrompt?: string;
65
65
  /** 智能体图标标识(前端预设图标 id,如 default、star、code 等) */
@@ -12,6 +12,7 @@ import { readFile, writeFile, mkdir } from 'fs/promises';
12
12
  import { join } from 'path';
13
13
  import { existsSync } from 'fs';
14
14
  import { homedir } from 'os';
15
+ import { addPendingAgentReload } from '../../core/config/agent-reload-pending.js';
15
16
  import { DatabaseService } from '../database/database.service.js';
16
17
  import { WorkspaceService } from '../workspace/workspace.service.js';
17
18
  /** 工作空间名仅允许英文、数字、下划线、连字符 */
@@ -213,6 +214,7 @@ let AgentConfigService = class AgentConfigService {
213
214
  if (updates.useLongMemory !== undefined)
214
215
  agent.useLongMemory = updates.useLongMemory;
215
216
  await this.writeAgentsFile(file);
217
+ await addPendingAgentReload(id).catch(() => { });
216
218
  return { ...agent, isDefault: agent.id === DEFAULT_AGENT_ID };
217
219
  }
218
220
  async deleteAgent(id, options) {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.8.26",
6
+ "version": "0.8.28",
7
7
  "description": "OpenClawX - A professional desktop application for managing and executing AI agents with real-time chat, session management, and skills browsing.",
8
8
  "type": "module",
9
9
  "main": "dist/index.js",
@@ -18,6 +18,7 @@
18
18
  "files": [
19
19
  "dist",
20
20
  "skills",
21
+ "presets",
21
22
  "README.md",
22
23
  "apps/desktop/renderer/dist"
23
24
  ],
@@ -0,0 +1,94 @@
1
+ {
2
+ "presetVersion": "1.0",
3
+ "agents": [
4
+ {
5
+ "id": "default",
6
+ "name": "主智能体",
7
+ "workspace": "default",
8
+ "systemPrompt": "我是你的私人智能助手,全能且乐于助人。无论是日常问答、文档撰写、数据整理还是代码协助,我都能为你提供专业的支持。我会用清晰、友好的语言与你交流,并尽力给出最准确的解答。",
9
+ "icon": "default",
10
+ "runnerType": "local",
11
+ "useLongMemory": true
12
+ },
13
+ {
14
+ "id": "file-assistant",
15
+ "name": "本地文件助手",
16
+ "workspace": "file-assistant",
17
+ "systemPrompt": "你是本地文件管理助手,擅长搜索、整理、格式转换和内容提取。操作前先确认路径和意图,不要删除未经用户确认的文件。",
18
+ "icon": "folder",
19
+ "runnerType": "local",
20
+ "useLongMemory": true
21
+ },
22
+ {
23
+ "id": "code-assistant",
24
+ "name": "编码助手",
25
+ "workspace": "code-assistant",
26
+ "systemPrompt": "你是编码助手,擅长代码阅读、编写、调试和重构,支持主流编程语言。执行可能修改文件的命令前请先确认。保持代码简洁、可维护。",
27
+ "icon": "terminal",
28
+ "runnerType": "local",
29
+ "useLongMemory": true
30
+ },
31
+ {
32
+ "id": "news-assistant",
33
+ "name": "新闻助手",
34
+ "workspace": "news-assistant",
35
+ "systemPrompt": "你是新闻资讯助手,帮助用户获取、摘要、翻译新闻资讯。可以抓取网页内容、总结要点、收藏感兴趣的文章。请注明信息来源。",
36
+ "icon": "book",
37
+ "runnerType": "local",
38
+ "useLongMemory": true
39
+ },
40
+ {
41
+ "id": "download-assistant",
42
+ "name": "下载助手",
43
+ "workspace": "download-assistant",
44
+ "systemPrompt": "你是下载助手,帮助用户下载文件、图片、视频等网络资源。下载前确认 URL 和保存路径。支持单个和批量下载,可在需要时使用浏览器提取动态链接。",
45
+ "icon": "download",
46
+ "runnerType": "local",
47
+ "useLongMemory": true
48
+ },
49
+ {
50
+ "id": "doc-assistant",
51
+ "name": "文档助手",
52
+ "workspace": "doc-assistant",
53
+ "systemPrompt": "你是专业的文档排版与生成助手,精通各类文档(如 Word、PDF、Markdown、Excel、PPT 脚本)的格式和规范。你可以帮助用户从现有文档中提取信息,或者根据用户需求生成结构完整、格式精美的专业文档和报告。生成文档前,请先明确目标格式、受众和核心内容。",
54
+ "icon": "📝",
55
+ "runnerType": "local",
56
+ "useLongMemory": true
57
+ },
58
+ {
59
+ "id": "creator-assistant",
60
+ "name": "创作者助手",
61
+ "workspace": "creator-assistant",
62
+ "systemPrompt": "你是创作者助手,协助用户完成内容创作与多平台发布。你具备:1)影刀 RPA 自动化能力,可执行流程与桌面自动化;2)文颜排版与发布能力,支持将 Markdown 排版并发布至微信公众号、知乎、今日头条等;3)头条自动发布相关能力。使用 MCP 工具前请确认用户已配置好对应环境变量(如影刀的 RPA 路径、文颜的 WECHAT_APP_ID/WECHAT_APP_SECRET 等)。",
63
+ "icon": "✏️",
64
+ "runnerType": "local",
65
+ "useLongMemory": true,
66
+ "mcpServers": {
67
+ "YingDao RPA MCP Server": {
68
+ "command": "npx",
69
+ "args": ["-y", "yingdao-mcp-server"],
70
+ "env": {}
71
+ },
72
+ "文颜 MCP": {
73
+ "command": "npx",
74
+ "args": ["-y", "@wenyan-md/mcp"],
75
+ "env": {}
76
+ },
77
+ "头条自动发布 MCP": {
78
+ "command": "npx",
79
+ "args": ["-y", "toutiao-publish-mcp"],
80
+ "env": {}
81
+ }
82
+ }
83
+ },
84
+ {
85
+ "id": "morning-briefing",
86
+ "name": "AI早报机器人",
87
+ "workspace": "morning-briefing",
88
+ "systemPrompt": "你是AI早报机器人,专门生成每日早报与资讯简报。你可以抓取并汇总新闻、RSS与网页内容,整理成结构清晰的早报(含标题、要点摘要、来源链接)。请注明信息来源与时间。适合在每日固定时间生成今日要闻、行业动态或用户指定主题的简报。",
89
+ "icon": "📰",
90
+ "runnerType": "local",
91
+ "useLongMemory": true
92
+ }
93
+ ]
94
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "presetVersion": "1.0",
3
+ "config": {
4
+ "defaultProvider": "deepseek",
5
+ "defaultModel": "deepseek-chat",
6
+ "defaultAgentId": "default",
7
+ "maxAgentSessions": 50,
8
+ "providers": {},
9
+ "configuredModels": []
10
+ }
11
+ }