@next-open-ai/openbot 0.6.8 → 0.6.66
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.
- package/LICENSE +21 -0
- package/README.md +155 -136
- package/apps/desktop/renderer/dist/assets/index-CxDZnMBH.css +10 -0
- package/apps/desktop/renderer/dist/assets/index-k47Qiokg.js +93 -0
- package/apps/desktop/renderer/dist/index.html +2 -2
- package/dist/cli/cli.js +136 -0
- package/dist/cli/extension-cmd.d.ts +15 -0
- package/dist/cli/extension-cmd.js +107 -0
- package/dist/core/agent/agent-dir.d.ts +6 -0
- package/dist/core/agent/agent-dir.js +8 -0
- package/dist/core/agent/agent-manager.d.ts +27 -6
- package/dist/core/agent/agent-manager.js +147 -26
- package/dist/core/agent/proxy/adapters/claude-code-adapter.d.ts +2 -0
- package/dist/core/agent/proxy/adapters/claude-code-adapter.js +186 -0
- package/dist/core/agent/proxy/adapters/coze-adapter.d.ts +2 -0
- package/dist/core/agent/proxy/adapters/coze-adapter.js +406 -0
- package/dist/core/agent/proxy/adapters/local-adapter.d.ts +2 -0
- package/dist/core/agent/proxy/adapters/local-adapter.js +95 -0
- package/dist/core/agent/proxy/adapters/openclawx-adapter.d.ts +2 -0
- package/dist/core/agent/proxy/adapters/openclawx-adapter.js +115 -0
- package/dist/core/agent/proxy/adapters/opencode-adapter.d.ts +11 -0
- package/dist/core/agent/proxy/adapters/opencode-adapter.js +786 -0
- package/dist/core/agent/proxy/adapters/opencode-free-models.d.ts +20 -0
- package/dist/core/agent/proxy/adapters/opencode-free-models.js +14 -0
- package/dist/core/agent/proxy/adapters/opencode-local-runner.d.ts +5 -0
- package/dist/core/agent/proxy/adapters/opencode-local-runner.js +95 -0
- package/dist/core/agent/proxy/index.d.ts +3 -0
- package/dist/core/agent/proxy/index.js +18 -0
- package/dist/core/agent/proxy/registry.d.ts +7 -0
- package/dist/core/agent/proxy/registry.js +13 -0
- package/dist/core/agent/proxy/run-for-channel.d.ts +3 -0
- package/dist/core/agent/proxy/run-for-channel.js +31 -0
- package/dist/core/agent/proxy/types.d.ts +30 -0
- package/dist/core/agent/proxy/types.js +1 -0
- package/dist/core/agent/run.js +1 -1
- package/dist/core/agent/token-usage-log-extension.d.ts +14 -0
- package/dist/core/agent/token-usage-log-extension.js +61 -0
- package/dist/core/config/agent-reload-pending.d.ts +9 -0
- package/dist/core/config/agent-reload-pending.js +67 -0
- package/dist/core/config/desktop-config.d.ts +136 -5
- package/dist/core/config/desktop-config.js +470 -46
- package/dist/core/config/provider-support-default.js +27 -0
- package/dist/core/extensions/index.d.ts +1 -0
- package/dist/core/extensions/index.js +1 -0
- package/dist/core/extensions/load.d.ts +11 -0
- package/dist/core/extensions/load.js +101 -0
- package/dist/core/inbound-message-preprocess.d.ts +27 -0
- package/dist/core/inbound-message-preprocess.js +96 -0
- package/dist/core/local-llm-server/download-model.d.ts +16 -0
- package/dist/core/local-llm-server/download-model.js +37 -0
- package/dist/core/local-llm-server/index.d.ts +32 -0
- package/dist/core/local-llm-server/index.js +152 -0
- package/dist/core/local-llm-server/llm-context.d.ts +66 -0
- package/dist/core/local-llm-server/llm-context.js +270 -0
- package/dist/core/local-llm-server/model-resolve.d.ts +27 -0
- package/dist/core/local-llm-server/model-resolve.js +90 -0
- package/dist/core/local-llm-server/server.d.ts +1 -0
- package/dist/core/local-llm-server/server.js +234 -0
- package/dist/core/local-llm-server/start-from-config.d.ts +5 -0
- package/dist/core/local-llm-server/start-from-config.js +50 -0
- package/dist/core/mcp/adapter.d.ts +4 -2
- package/dist/core/mcp/adapter.js +10 -4
- package/dist/core/mcp/client.d.ts +4 -0
- package/dist/core/mcp/client.js +2 -0
- package/dist/core/mcp/config.d.ts +14 -3
- package/dist/core/mcp/config.js +68 -3
- package/dist/core/mcp/index.d.ts +10 -6
- package/dist/core/mcp/index.js +7 -3
- package/dist/core/mcp/operator.d.ts +28 -2
- package/dist/core/mcp/operator.js +131 -30
- package/dist/core/mcp/transport/index.d.ts +4 -0
- package/dist/core/mcp/transport/index.js +6 -1
- package/dist/core/mcp/transport/stdio.d.ts +12 -0
- package/dist/core/mcp/transport/stdio.js +147 -29
- package/dist/core/mcp/types.d.ts +18 -0
- package/dist/core/memory/compaction-extension.d.ts +4 -3
- package/dist/core/memory/compaction-extension.js +6 -14
- package/dist/core/memory/embedding-types.d.ts +10 -0
- package/dist/core/memory/embedding-types.js +5 -0
- package/dist/core/memory/embedding.d.ts +2 -1
- package/dist/core/memory/embedding.js +38 -6
- package/dist/core/memory/index.js +3 -0
- package/dist/core/memory/local-embedding-llama.d.ts +13 -0
- package/dist/core/memory/local-embedding-llama.js +78 -0
- package/dist/core/memory/local-embedding.d.ts +11 -0
- package/dist/core/memory/local-embedding.js +69 -0
- package/dist/core/memory/persist-compaction-on-close.d.ts +14 -0
- package/dist/core/memory/persist-compaction-on-close.js +32 -0
- package/dist/core/session-outlet/index.d.ts +19 -0
- package/dist/core/session-outlet/index.js +33 -0
- package/dist/core/session-outlet/outlet.d.ts +15 -0
- package/dist/core/session-outlet/outlet.js +49 -0
- package/dist/core/session-outlet/types.d.ts +35 -0
- package/dist/core/session-outlet/types.js +5 -0
- package/dist/core/tools/bookmark-tool.d.ts +4 -0
- package/dist/core/tools/bookmark-tool.js +59 -3
- package/dist/core/tools/index.d.ts +3 -1
- package/dist/core/tools/index.js +3 -1
- package/dist/core/tools/memory-recall-tool.d.ts +6 -0
- package/dist/core/tools/memory-recall-tool.js +77 -0
- package/dist/core/tools/truncate-result.d.ts +14 -0
- package/dist/core/tools/truncate-result.js +27 -0
- package/dist/core/tools/web-search/create-web-search-tool.d.ts +17 -0
- package/dist/core/tools/web-search/create-web-search-tool.js +87 -0
- package/dist/core/tools/web-search/index.d.ts +4 -0
- package/dist/core/tools/web-search/index.js +2 -0
- package/dist/core/tools/web-search/providers/brave.d.ts +2 -0
- package/dist/core/tools/web-search/providers/brave.js +87 -0
- package/dist/core/tools/web-search/providers/duck-duck-scrape.d.ts +2 -0
- package/dist/core/tools/web-search/providers/duck-duck-scrape.js +47 -0
- package/dist/core/tools/web-search/providers/index.d.ts +5 -0
- package/dist/core/tools/web-search/providers/index.js +13 -0
- package/dist/core/tools/web-search/types.d.ts +35 -0
- package/dist/core/tools/web-search/types.js +4 -0
- package/dist/gateway/channel/adapters/telegram.js +13 -2
- package/dist/gateway/channel/adapters/wechat.d.ts +24 -0
- package/dist/gateway/channel/adapters/wechat.js +205 -0
- package/dist/gateway/channel/channel-core.d.ts +1 -0
- package/dist/gateway/channel/channel-core.js +101 -59
- package/dist/gateway/channel/run-agent.d.ts +2 -4
- package/dist/gateway/channel/run-agent.js +13 -125
- package/dist/gateway/methods/agent-cancel.d.ts +3 -1
- package/dist/gateway/methods/agent-cancel.js +16 -2
- package/dist/gateway/methods/agent-chat.d.ts +4 -0
- package/dist/gateway/methods/agent-chat.js +377 -118
- package/dist/gateway/methods/run-scheduled-task.js +9 -7
- package/dist/gateway/proxy-run-abort.d.ts +6 -0
- package/dist/gateway/proxy-run-abort.js +39 -0
- package/dist/gateway/server.js +123 -19
- package/dist/server/agent-config/agent-config.controller.d.ts +10 -2
- package/dist/server/agent-config/agent-config.controller.js +19 -4
- package/dist/server/agent-config/agent-config.module.js +3 -1
- package/dist/server/agent-config/agent-config.service.d.ts +91 -6
- package/dist/server/agent-config/agent-config.service.js +115 -3
- package/dist/server/agents/agents.controller.d.ts +16 -0
- package/dist/server/agents/agents.controller.js +62 -1
- package/dist/server/agents/agents.gateway.js +1 -1
- package/dist/server/agents/agents.service.js +1 -1
- package/dist/server/bootstrap.d.ts +1 -0
- package/dist/server/bootstrap.js +28 -4
- package/dist/server/config/config.controller.d.ts +134 -2
- package/dist/server/config/config.controller.js +199 -3
- package/dist/server/config/config.module.js +5 -4
- package/dist/server/config/config.service.d.ts +32 -2
- package/dist/server/config/config.service.js +69 -9
- package/dist/server/config/local-models.service.d.ts +67 -0
- package/dist/server/config/local-models.service.js +242 -0
- package/dist/server/workspace/workspace.service.d.ts +7 -0
- package/dist/server/workspace/workspace.service.js +16 -0
- package/package.json +10 -2
- package/presets/preset-agents.json +128 -0
- package/presets/preset-config.json +29 -0
- package/presets/preset-providers.json +180 -0
- package/presets/recommended-local-models.json +36 -0
- package/presets/workspaces/code-assistant/skills/code-review/SKILL.md +19 -0
- package/presets/workspaces/code-assistant/skills/code-runner/SKILL.md +21 -0
- package/presets/workspaces/code-assistant/skills/git-helper/SKILL.md +29 -0
- package/presets/workspaces/creator-assistant/skills/.gitkeep +0 -0
- package/presets/workspaces/creator-assistant/skills/creator-tools/SKILL.md +15 -0
- package/presets/workspaces/doc-assistant/skills/doc-processor/SKILL.md +21 -0
- package/presets/workspaces/download-assistant/skills/downloader/SKILL.md +20 -0
- package/presets/workspaces/file-assistant/skills/file-converter/SKILL.md +21 -0
- package/presets/workspaces/file-assistant/skills/file-organizer/SKILL.md +17 -0
- package/presets/workspaces/file-assistant/skills/file-search/SKILL.md +22 -0
- package/presets/workspaces/morning-briefing/skills/news-fetcher/SKILL.md +16 -0
- package/presets/workspaces/morning-briefing/skills/web-summarizer/SKILL.md +20 -0
- package/presets/workspaces/news-assistant/skills/news-fetcher/SKILL.md +16 -0
- package/presets/workspaces/news-assistant/skills/web-summarizer/SKILL.md +20 -0
- package/presets/workspaces/office-automation/skills/rpa-helper/SKILL.md +9 -0
- package/presets/workspaces/self-media-bot/skills/self-media-tools/SKILL.md +9 -0
- package/skills/url-bookmark/SKILL.md +12 -12
- package/apps/desktop/renderer/dist/assets/index-LCp1YPVA.css +0 -10
- package/apps/desktop/renderer/dist/assets/index-l5fpDsHs.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-
|
|
15
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-k47Qiokg.js"></script>
|
|
15
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CxDZnMBH.css">
|
|
16
16
|
</head>
|
|
17
17
|
|
|
18
18
|
<body>
|
package/dist/cli/cli.js
CHANGED
|
@@ -6,7 +6,11 @@ import { Command } from "commander";
|
|
|
6
6
|
import { getOpenbotAgentDir } from "../core/agent/agent-dir.js";
|
|
7
7
|
import { run } from "../core/agent/run.js";
|
|
8
8
|
import { loadDesktopAgentConfig, getBoundAgentIdForCli, setProviderApiKey, setDefaultModel, getDesktopConfigList, syncDesktopConfigToModelsJson, ensureDesktopConfigInitialized, } from "../core/config/desktop-config.js";
|
|
9
|
+
import { downloadModel, DEFAULT_LLM_MODEL_URI, } from "../core/local-llm-server/download-model.js";
|
|
10
|
+
import { startLocalLlmServer, stopLocalLlmServer, } from "../core/local-llm-server/index.js";
|
|
11
|
+
import { LOCAL_LLM_CACHE_DIR, isModelFileInCache, toModelPathForStart, } from "../core/local-llm-server/model-resolve.js";
|
|
9
12
|
import { writeGatewayPid, removeGatewayPidFile, serviceInstall, serviceUninstall, serviceStop, } from "./service.js";
|
|
13
|
+
import { installExtension, listExtensions, uninstallExtension } from "./extension-cmd.js";
|
|
10
14
|
const require = createRequire(import.meta.url);
|
|
11
15
|
const PKG = require("../../package.json");
|
|
12
16
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -189,6 +193,138 @@ configCmd
|
|
|
189
193
|
await syncDesktopConfigToModelsJson();
|
|
190
194
|
console.log("[openbot] Synced desktop providers to agent models.json");
|
|
191
195
|
});
|
|
196
|
+
// Extension: 在 ~/.openbot/plugins 下通过 npm 包安装/列出/卸载扩展,Server 运行时从该目录加载
|
|
197
|
+
const extensionCmd = program
|
|
198
|
+
.command("extension")
|
|
199
|
+
.description("Install, list, or uninstall extensions (npm packages in ~/.openbot/plugins)");
|
|
200
|
+
extensionCmd
|
|
201
|
+
.command("install <pkg>")
|
|
202
|
+
.description("Install an extension package (e.g. openbot extension install my-extension)")
|
|
203
|
+
.action((pkg) => {
|
|
204
|
+
installExtension(pkg);
|
|
205
|
+
});
|
|
206
|
+
extensionCmd
|
|
207
|
+
.command("list")
|
|
208
|
+
.description("List installed extensions")
|
|
209
|
+
.action(() => {
|
|
210
|
+
const list = listExtensions();
|
|
211
|
+
if (list.length === 0) {
|
|
212
|
+
console.log("No extensions installed. Run: openbot extension install <package>");
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
console.log("Installed extensions:\n");
|
|
216
|
+
console.table(list.map((r) => ({ Package: r.name, Spec: r.spec })));
|
|
217
|
+
});
|
|
218
|
+
extensionCmd
|
|
219
|
+
.command("uninstall <pkg>")
|
|
220
|
+
.description("Uninstall an extension package")
|
|
221
|
+
.action((pkg) => {
|
|
222
|
+
uninstallExtension(pkg);
|
|
223
|
+
});
|
|
224
|
+
// 本地模型:下载与启动服务
|
|
225
|
+
const localCmd = program
|
|
226
|
+
.command("local")
|
|
227
|
+
.description("下载本地 GGUF 模型与启动本地 LLM 服务");
|
|
228
|
+
localCmd
|
|
229
|
+
.command("download")
|
|
230
|
+
.description("下载推荐模型到 ~/.openbot/.cached_models/,不指定模型时下载 Qwen 3.5 4B")
|
|
231
|
+
.argument("[modelUri]", "模型 URI(如 hf:unsloth/Qwen3.5-4B-GGUF/Qwen3.5-4B-Q5_K_M.gguf),不传则下载 Qwen 3.5 4B")
|
|
232
|
+
.option("--mirror", "使用国内镜像 hf-mirror.com 下载")
|
|
233
|
+
.action(async (modelUri, opts) => {
|
|
234
|
+
const uri = (modelUri || "").trim() || DEFAULT_LLM_MODEL_URI;
|
|
235
|
+
console.log(`[openbot] 下载模型: ${uri}`);
|
|
236
|
+
if (opts.mirror)
|
|
237
|
+
console.log("[openbot] 使用国内镜像 hf-mirror.com");
|
|
238
|
+
try {
|
|
239
|
+
const path = await downloadModel(uri, {
|
|
240
|
+
useMirror: opts.mirror,
|
|
241
|
+
onProgress: (p) => {
|
|
242
|
+
const percent = p.totalSize ? Math.round((p.downloadedSize / p.totalSize) * 100) : (p.percent ?? 0);
|
|
243
|
+
const mb = (p.downloadedSize / 1024 / 1024).toFixed(1);
|
|
244
|
+
const totalMb = p.totalSize ? (p.totalSize / 1024 / 1024).toFixed(1) : "?";
|
|
245
|
+
process.stderr.write(`\r[openbot] 下载中 ${percent}% (${mb} / ${totalMb} MB)`);
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
console.log(`\n[openbot] 已保存: ${path}`);
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
252
|
+
console.error("\n[openbot] 下载失败:", msg);
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
localCmd
|
|
257
|
+
.command("start")
|
|
258
|
+
.description("启动本地 LLM 服务(至少指定 --llm 或 --embedding 之一)")
|
|
259
|
+
.option("--llm <uriOrFile>", "LLM 模型:hf: URI 或已下载文件名,不传则使用桌面缺省模型")
|
|
260
|
+
.option("--embedding <uriOrFile>", "Embedding 模型:hf: URI 或已下载文件名(可选)")
|
|
261
|
+
.option("--context-size <n>", "上下文长度(token 数),默认 32768 或环境变量 LOCAL_LLM_CONTEXT_MAX", (v) => parseInt(v, 10) || 32768)
|
|
262
|
+
.option("--port <port>", "服务端口", "11435")
|
|
263
|
+
.action(async (opts) => {
|
|
264
|
+
let llmPath;
|
|
265
|
+
let embPath;
|
|
266
|
+
if (opts.llm?.trim()) {
|
|
267
|
+
const llmArg = opts.llm.trim();
|
|
268
|
+
if (!llmArg.startsWith("hf:") && !isModelFileInCache(llmArg, LOCAL_LLM_CACHE_DIR)) {
|
|
269
|
+
console.error("[openbot] 模型未下载或路径不存在,请先执行: openbot local download [modelUri]");
|
|
270
|
+
process.exit(1);
|
|
271
|
+
}
|
|
272
|
+
llmPath = toModelPathForStart(llmArg, LOCAL_LLM_CACHE_DIR);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
const agentConfig = await loadDesktopAgentConfig("default");
|
|
276
|
+
const defaultModel = agentConfig?.model?.trim();
|
|
277
|
+
if (defaultModel) {
|
|
278
|
+
llmPath = toModelPathForStart(defaultModel, LOCAL_LLM_CACHE_DIR);
|
|
279
|
+
if (!isModelFileInCache(defaultModel, LOCAL_LLM_CACHE_DIR)) {
|
|
280
|
+
console.error("[openbot] 缺省模型未下载,请先执行: openbot local download");
|
|
281
|
+
process.exit(1);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
if (opts.embedding?.trim()) {
|
|
286
|
+
const embArg = opts.embedding.trim();
|
|
287
|
+
if (!embArg.startsWith("hf:") && !isModelFileInCache(embArg, LOCAL_LLM_CACHE_DIR)) {
|
|
288
|
+
console.error("[openbot] Embedding 模型未下载或路径不存在,请先执行: openbot local download <embedding-uri>");
|
|
289
|
+
process.exit(1);
|
|
290
|
+
}
|
|
291
|
+
embPath = toModelPathForStart(embArg, LOCAL_LLM_CACHE_DIR);
|
|
292
|
+
}
|
|
293
|
+
if (!llmPath && !embPath) {
|
|
294
|
+
console.error("[openbot] 请至少指定 --llm 或 --embedding,或先配置桌面缺省模型");
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
const contextSize = opts.contextSize ??
|
|
298
|
+
(process.env.LOCAL_LLM_CONTEXT_MAX ? parseInt(process.env.LOCAL_LLM_CONTEXT_MAX, 10) : undefined) ??
|
|
299
|
+
32768;
|
|
300
|
+
const port = parseInt(opts.port || "11435", 10);
|
|
301
|
+
try {
|
|
302
|
+
const handle = await startLocalLlmServer({
|
|
303
|
+
port,
|
|
304
|
+
llmModelPath: llmPath,
|
|
305
|
+
embeddingModelPath: embPath,
|
|
306
|
+
contextSize,
|
|
307
|
+
});
|
|
308
|
+
console.log(`[openbot] 本地模型服务已启动: ${handle.baseUrl}`);
|
|
309
|
+
console.log("[openbot] 按 Ctrl+C 停止服务");
|
|
310
|
+
await new Promise((resolve) => {
|
|
311
|
+
process.on("SIGINT", () => {
|
|
312
|
+
stopLocalLlmServer();
|
|
313
|
+
resolve();
|
|
314
|
+
});
|
|
315
|
+
process.on("SIGTERM", () => {
|
|
316
|
+
stopLocalLlmServer();
|
|
317
|
+
resolve();
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
process.exit(0);
|
|
321
|
+
}
|
|
322
|
+
catch (err) {
|
|
323
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
324
|
+
console.error("[openbot] 启动失败:", msg);
|
|
325
|
+
process.exit(1);
|
|
326
|
+
}
|
|
327
|
+
});
|
|
192
328
|
(async () => {
|
|
193
329
|
await ensureDesktopConfigInitialized();
|
|
194
330
|
await program.parseAsync(process.argv);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 安装扩展:将包加入 dependencies 并在 plugins 目录下执行 npm install
|
|
3
|
+
*/
|
|
4
|
+
export declare function installExtension(pkgSpec: string): void;
|
|
5
|
+
/**
|
|
6
|
+
* 列出已安装的扩展(package.json 的 dependencies)
|
|
7
|
+
*/
|
|
8
|
+
export declare function listExtensions(): {
|
|
9
|
+
name: string;
|
|
10
|
+
spec: string;
|
|
11
|
+
}[];
|
|
12
|
+
/**
|
|
13
|
+
* 卸载扩展:从 dependencies 移除并在 plugins 目录下执行 npm install
|
|
14
|
+
*/
|
|
15
|
+
export declare function uninstallExtension(pkgName: string): void;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openbot extension install / list / uninstall
|
|
3
|
+
* 在 ~/.openbot/plugins 下维护 package.json 与 node_modules,Server 运行时从该目录加载扩展。
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { execSync } from "node:child_process";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { getOpenbotPluginsDir } from "../core/agent/agent-dir.js";
|
|
9
|
+
const PLUGINS_PACKAGE_NAME = "openbot-plugins-root";
|
|
10
|
+
function ensurePluginsDir() {
|
|
11
|
+
const dir = getOpenbotPluginsDir();
|
|
12
|
+
if (!existsSync(dir)) {
|
|
13
|
+
mkdirSync(dir, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
const pkgPath = join(dir, "package.json");
|
|
16
|
+
if (!existsSync(pkgPath)) {
|
|
17
|
+
writeFileSync(pkgPath, JSON.stringify({
|
|
18
|
+
name: PLUGINS_PACKAGE_NAME,
|
|
19
|
+
version: "1.0.0",
|
|
20
|
+
private: true,
|
|
21
|
+
description: "OpenBot extension packages (managed by openbot extension install)",
|
|
22
|
+
dependencies: {},
|
|
23
|
+
}, null, 2), "utf-8");
|
|
24
|
+
}
|
|
25
|
+
return dir;
|
|
26
|
+
}
|
|
27
|
+
function readPluginsPackageJson(pluginsDir) {
|
|
28
|
+
const pkgPath = join(pluginsDir, "package.json");
|
|
29
|
+
if (!existsSync(pkgPath))
|
|
30
|
+
return {};
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function writePluginsPackageJson(pluginsDir, pkg) {
|
|
39
|
+
const pkgPath = join(pluginsDir, "package.json");
|
|
40
|
+
const full = {
|
|
41
|
+
name: PLUGINS_PACKAGE_NAME,
|
|
42
|
+
version: "1.0.0",
|
|
43
|
+
private: true,
|
|
44
|
+
description: "OpenBot extension packages (managed by openbot extension install)",
|
|
45
|
+
...pkg,
|
|
46
|
+
};
|
|
47
|
+
writeFileSync(pkgPath, JSON.stringify(full, null, 2), "utf-8");
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 解析用户输入的 pkgSpec(如 "foo" 或 "foo@1.0.0")为 { name, spec }。
|
|
51
|
+
*/
|
|
52
|
+
function parsePkgSpec(pkgSpec) {
|
|
53
|
+
const at = pkgSpec.indexOf("@");
|
|
54
|
+
if (at === -1)
|
|
55
|
+
return { name: pkgSpec.trim(), spec: "*" };
|
|
56
|
+
return { name: pkgSpec.slice(0, at).trim(), spec: pkgSpec.slice(at + 1).trim() || "*" };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 安装扩展:将包加入 dependencies 并在 plugins 目录下执行 npm install
|
|
60
|
+
*/
|
|
61
|
+
export function installExtension(pkgSpec) {
|
|
62
|
+
const pluginsDir = ensurePluginsDir();
|
|
63
|
+
const { name, spec } = parsePkgSpec(pkgSpec);
|
|
64
|
+
const pkg = readPluginsPackageJson(pluginsDir);
|
|
65
|
+
const deps = { ...pkg.dependencies };
|
|
66
|
+
deps[name] = spec; // 覆盖为本次指定的版本
|
|
67
|
+
writePluginsPackageJson(pluginsDir, { ...pkg, dependencies: deps });
|
|
68
|
+
execSync("npm install", {
|
|
69
|
+
cwd: pluginsDir,
|
|
70
|
+
stdio: "inherit",
|
|
71
|
+
});
|
|
72
|
+
console.log(`[openbot] Installed extension: ${name} (in ${pluginsDir})`);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 列出已安装的扩展(package.json 的 dependencies)
|
|
76
|
+
*/
|
|
77
|
+
export function listExtensions() {
|
|
78
|
+
const pluginsDir = getOpenbotPluginsDir();
|
|
79
|
+
if (!existsSync(pluginsDir))
|
|
80
|
+
return [];
|
|
81
|
+
const pkg = readPluginsPackageJson(pluginsDir);
|
|
82
|
+
const deps = pkg.dependencies ?? {};
|
|
83
|
+
return Object.entries(deps).map(([name, spec]) => ({ name, spec }));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 卸载扩展:从 dependencies 移除并在 plugins 目录下执行 npm install
|
|
87
|
+
*/
|
|
88
|
+
export function uninstallExtension(pkgName) {
|
|
89
|
+
const pluginsDir = getOpenbotPluginsDir();
|
|
90
|
+
if (!existsSync(pluginsDir)) {
|
|
91
|
+
console.warn("[openbot] No plugins directory found.");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const pkg = readPluginsPackageJson(pluginsDir);
|
|
95
|
+
const deps = { ...(pkg.dependencies ?? {}) };
|
|
96
|
+
if (!(pkgName in deps)) {
|
|
97
|
+
console.warn(`[openbot] Extension "${pkgName}" is not installed.`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
delete deps[pkgName];
|
|
101
|
+
writePluginsPackageJson(pluginsDir, { ...pkg, dependencies: deps });
|
|
102
|
+
execSync("npm install", {
|
|
103
|
+
cwd: pluginsDir,
|
|
104
|
+
stdio: "inherit",
|
|
105
|
+
});
|
|
106
|
+
console.log(`[openbot] Uninstalled extension: ${pkgName}`);
|
|
107
|
+
}
|
|
@@ -8,6 +8,12 @@ export declare function getOpenbotAgentDir(): string;
|
|
|
8
8
|
* 可通过环境变量 OPENBOT_WORKSPACE_DIR 覆盖
|
|
9
9
|
*/
|
|
10
10
|
export declare function getOpenbotWorkspaceDir(): string;
|
|
11
|
+
/**
|
|
12
|
+
* 获取 openbot 扩展(插件)目录(默认 ~/.openbot/plugins)
|
|
13
|
+
* 可通过环境变量 OPENBOT_PLUGINS_DIR 覆盖
|
|
14
|
+
* openbot extension install 会在此目录下维护 package.json 与 node_modules
|
|
15
|
+
*/
|
|
16
|
+
export declare function getOpenbotPluginsDir(): string;
|
|
11
17
|
/**
|
|
12
18
|
* 确保 agent 目录存在,并创建默认配置文件
|
|
13
19
|
*/
|
|
@@ -15,6 +15,14 @@ export function getOpenbotAgentDir() {
|
|
|
15
15
|
export function getOpenbotWorkspaceDir() {
|
|
16
16
|
return process.env.OPENBOT_WORKSPACE_DIR ?? join(homedir(), ".openbot", "workspace");
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* 获取 openbot 扩展(插件)目录(默认 ~/.openbot/plugins)
|
|
20
|
+
* 可通过环境变量 OPENBOT_PLUGINS_DIR 覆盖
|
|
21
|
+
* openbot extension install 会在此目录下维护 package.json 与 node_modules
|
|
22
|
+
*/
|
|
23
|
+
export function getOpenbotPluginsDir() {
|
|
24
|
+
return process.env.OPENBOT_PLUGINS_DIR ?? join(homedir(), ".openbot", "plugins");
|
|
25
|
+
}
|
|
18
26
|
/**
|
|
19
27
|
* 确保 agent 目录存在,并创建默认配置文件
|
|
20
28
|
*/
|
|
@@ -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;
|
|
@@ -14,6 +14,8 @@ export declare class AgentManager {
|
|
|
14
14
|
private sessions;
|
|
15
15
|
/** 每个 session 最后被使用的时间戳,用于 LRU 淘汰 */
|
|
16
16
|
private sessionLastActiveAt;
|
|
17
|
+
/** 每个 SessionAgent 当前最新的 compaction summary,关闭会话时写入向量库(infotype: compaction) */
|
|
18
|
+
private sessionLatestCompactionSummary;
|
|
17
19
|
private agentDir;
|
|
18
20
|
private workspaceDir;
|
|
19
21
|
private skillPaths;
|
|
@@ -57,16 +59,35 @@ export declare class AgentManager {
|
|
|
57
59
|
apiKey?: string;
|
|
58
60
|
maxSessions?: number;
|
|
59
61
|
targetAgentId?: string;
|
|
60
|
-
mcpServers?: McpServerConfig[];
|
|
62
|
+
mcpServers?: McpServerConfig[] | McpServersStandardFormat;
|
|
63
|
+
/** MCP 单次返回最大 token;不配置则不限制 */
|
|
64
|
+
mcpMaxResultTokens?: number;
|
|
61
65
|
/** 自定义系统提示词(来自 agent 配置),会与技能等一起组成最终 systemPrompt */
|
|
62
66
|
systemPrompt?: string;
|
|
67
|
+
/** 是否使用长记忆(memory_recall/save_experience);默认 true */
|
|
68
|
+
useLongMemory?: boolean;
|
|
69
|
+
/** 在线搜索:启用时注册 web_search 工具 */
|
|
70
|
+
webSearch?: {
|
|
71
|
+
enabled: boolean;
|
|
72
|
+
provider: "brave" | "duck-duck-scrape";
|
|
73
|
+
apiKey?: string;
|
|
74
|
+
timeoutSeconds?: number;
|
|
75
|
+
cacheTtlMinutes?: number;
|
|
76
|
+
maxResults?: number;
|
|
77
|
+
/** 单次搜索返回最大 token;不配置则不限制;前端默认 64K */
|
|
78
|
+
maxResultTokens?: number;
|
|
79
|
+
};
|
|
63
80
|
}): Promise<AgentSession>;
|
|
64
81
|
/** 按复合 key 获取(key = sessionId + "::" + agentId) */
|
|
65
82
|
getSession(compositeKey: string): AgentSession | undefined;
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
|
|
83
|
+
/** 按业务 sessionId 查找一个 Session(取最近活跃的),用于 agent.cancel 等 */
|
|
84
|
+
getSessionBySessionId(sessionId: string): AgentSession | undefined;
|
|
85
|
+
/** 删除一个 Agent Session(传入复合 key);关闭前将本 session 最新 compaction summary 写入向量库 */
|
|
86
|
+
deleteSession(compositeKey: string): Promise<boolean>;
|
|
87
|
+
/** 按业务 sessionId 删除该会话下所有 agent 的 Core Session(如删除会话时);关闭前将各 session 最新 compaction 写入向量库 */
|
|
88
|
+
deleteSessionsByBusinessId(sessionId: string): Promise<void>;
|
|
89
|
+
/** 按 agentId 删除该智能体下所有 Session(配置更新后使旧会话失效,下次请求会用新配置建新会话) */
|
|
90
|
+
deleteSessionsByAgentId(agentId: string): Promise<void>;
|
|
70
91
|
clearAll(): void;
|
|
71
92
|
}
|
|
72
93
|
export declare const agentManager: AgentManager;
|