@next-open-ai/openclawx 0.6.6
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/README.md +523 -0
- package/apps/desktop/README.md +210 -0
- package/apps/desktop/renderer/dist/assets/index-CYkSfhcp.css +10 -0
- package/apps/desktop/renderer/dist/assets/index-FI6O25Ms.js +89 -0
- package/apps/desktop/renderer/dist/index.html +22 -0
- package/dist/cli/cli.d.ts +2 -0
- package/dist/cli/cli.js +198 -0
- package/dist/cli/service.d.ts +13 -0
- package/dist/cli/service.js +243 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +5 -0
- package/dist/core/agent/agent-dir.d.ts +14 -0
- package/dist/core/agent/agent-dir.js +75 -0
- package/dist/core/agent/agent-manager.d.ts +64 -0
- package/dist/core/agent/agent-manager.js +278 -0
- package/dist/core/agent/config-manager.d.ts +25 -0
- package/dist/core/agent/config-manager.js +84 -0
- package/dist/core/agent/run.d.ts +26 -0
- package/dist/core/agent/run.js +65 -0
- package/dist/core/agent/skills.d.ts +20 -0
- package/dist/core/agent/skills.js +86 -0
- package/dist/core/config/desktop-config.d.ts +90 -0
- package/dist/core/config/desktop-config.js +521 -0
- package/dist/core/config/provider-support-default.d.ts +21 -0
- package/dist/core/config/provider-support-default.js +57 -0
- package/dist/core/installer/index.d.ts +1 -0
- package/dist/core/installer/index.js +1 -0
- package/dist/core/installer/skill-installer.d.ts +39 -0
- package/dist/core/installer/skill-installer.js +215 -0
- package/dist/core/mcp/adapter.d.ts +17 -0
- package/dist/core/mcp/adapter.js +49 -0
- package/dist/core/mcp/client.d.ts +24 -0
- package/dist/core/mcp/client.js +70 -0
- package/dist/core/mcp/config.d.ts +22 -0
- package/dist/core/mcp/config.js +69 -0
- package/dist/core/mcp/index.d.ts +18 -0
- package/dist/core/mcp/index.js +20 -0
- package/dist/core/mcp/operator.d.ts +15 -0
- package/dist/core/mcp/operator.js +72 -0
- package/dist/core/mcp/transport/index.d.ts +11 -0
- package/dist/core/mcp/transport/index.js +16 -0
- package/dist/core/mcp/transport/sse.d.ts +20 -0
- package/dist/core/mcp/transport/sse.js +82 -0
- package/dist/core/mcp/transport/stdio.d.ts +32 -0
- package/dist/core/mcp/transport/stdio.js +132 -0
- package/dist/core/mcp/types.d.ts +72 -0
- package/dist/core/mcp/types.js +5 -0
- package/dist/core/memory/build-summary.d.ts +6 -0
- package/dist/core/memory/build-summary.js +27 -0
- package/dist/core/memory/compaction-extension.d.ts +6 -0
- package/dist/core/memory/compaction-extension.js +23 -0
- package/dist/core/memory/embedding.d.ts +4 -0
- package/dist/core/memory/embedding.js +15 -0
- package/dist/core/memory/index.d.ts +29 -0
- package/dist/core/memory/index.js +70 -0
- package/dist/core/memory/remote-embedding.d.ts +10 -0
- package/dist/core/memory/remote-embedding.js +36 -0
- package/dist/core/memory/types.d.ts +16 -0
- package/dist/core/memory/types.js +1 -0
- package/dist/core/memory/vector-store.d.ts +15 -0
- package/dist/core/memory/vector-store.js +65 -0
- package/dist/core/tools/bookmark-tool.d.ts +9 -0
- package/dist/core/tools/bookmark-tool.js +118 -0
- package/dist/core/tools/browser-tool.d.ts +10 -0
- package/dist/core/tools/browser-tool.js +362 -0
- package/dist/core/tools/index.d.ts +4 -0
- package/dist/core/tools/index.js +4 -0
- package/dist/core/tools/install-skill-tool.d.ts +6 -0
- package/dist/core/tools/install-skill-tool.js +53 -0
- package/dist/core/tools/save-experience-tool.d.ts +5 -0
- package/dist/core/tools/save-experience-tool.js +54 -0
- package/dist/gateway/auth-hooks.d.ts +17 -0
- package/dist/gateway/auth-hooks.js +19 -0
- package/dist/gateway/backend-url.d.ts +2 -0
- package/dist/gateway/backend-url.js +11 -0
- package/dist/gateway/channel-handler.d.ts +6 -0
- package/dist/gateway/channel-handler.js +3 -0
- package/dist/gateway/clients.d.ts +5 -0
- package/dist/gateway/clients.js +4 -0
- package/dist/gateway/connection-handler.d.ts +6 -0
- package/dist/gateway/connection-handler.js +48 -0
- package/dist/gateway/index.d.ts +3 -0
- package/dist/gateway/index.js +2 -0
- package/dist/gateway/message-handler.d.ts +5 -0
- package/dist/gateway/message-handler.js +65 -0
- package/dist/gateway/methods/agent-cancel.d.ts +10 -0
- package/dist/gateway/methods/agent-cancel.js +17 -0
- package/dist/gateway/methods/agent-chat.d.ts +8 -0
- package/dist/gateway/methods/agent-chat.js +148 -0
- package/dist/gateway/methods/connect.d.ts +9 -0
- package/dist/gateway/methods/connect.js +18 -0
- package/dist/gateway/methods/install-skill-from-path.d.ts +13 -0
- package/dist/gateway/methods/install-skill-from-path.js +15 -0
- package/dist/gateway/methods/install-skill-from-upload.d.ts +14 -0
- package/dist/gateway/methods/install-skill-from-upload.js +13 -0
- package/dist/gateway/methods/run-scheduled-task.d.ts +15 -0
- package/dist/gateway/methods/run-scheduled-task.js +127 -0
- package/dist/gateway/paths.d.ts +20 -0
- package/dist/gateway/paths.js +19 -0
- package/dist/gateway/server.d.ts +8 -0
- package/dist/gateway/server.js +190 -0
- package/dist/gateway/sse-handler.d.ts +6 -0
- package/dist/gateway/sse-handler.js +3 -0
- package/dist/gateway/types.d.ts +90 -0
- package/dist/gateway/types.js +1 -0
- package/dist/gateway/utils.d.ts +22 -0
- package/dist/gateway/utils.js +67 -0
- package/dist/gateway/voice-handler.d.ts +12 -0
- package/dist/gateway/voice-handler.js +18 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/server/agent-config/agent-config.controller.d.ts +30 -0
- package/dist/server/agent-config/agent-config.controller.js +83 -0
- package/dist/server/agent-config/agent-config.module.d.ts +2 -0
- package/dist/server/agent-config/agent-config.module.js +19 -0
- package/dist/server/agent-config/agent-config.service.d.ts +53 -0
- package/dist/server/agent-config/agent-config.service.js +213 -0
- package/dist/server/agents/agents.controller.d.ts +41 -0
- package/dist/server/agents/agents.controller.js +118 -0
- package/dist/server/agents/agents.gateway.d.ts +21 -0
- package/dist/server/agents/agents.gateway.js +103 -0
- package/dist/server/agents/agents.module.d.ts +2 -0
- package/dist/server/agents/agents.module.js +20 -0
- package/dist/server/agents/agents.service.d.ts +63 -0
- package/dist/server/agents/agents.service.js +169 -0
- package/dist/server/app.module.d.ts +2 -0
- package/dist/server/app.module.js +38 -0
- package/dist/server/auth/auth.controller.d.ts +20 -0
- package/dist/server/auth/auth.controller.js +64 -0
- package/dist/server/auth/auth.module.d.ts +2 -0
- package/dist/server/auth/auth.module.js +19 -0
- package/dist/server/bootstrap.d.ts +15 -0
- package/dist/server/bootstrap.js +38 -0
- package/dist/server/config/config.controller.d.ts +73 -0
- package/dist/server/config/config.controller.js +95 -0
- package/dist/server/config/config.module.d.ts +2 -0
- package/dist/server/config/config.module.js +21 -0
- package/dist/server/config/config.service.d.ts +82 -0
- package/dist/server/config/config.service.js +123 -0
- package/dist/server/database/database.module.d.ts +2 -0
- package/dist/server/database/database.module.js +18 -0
- package/dist/server/database/database.service.d.ts +26 -0
- package/dist/server/database/database.service.js +253 -0
- package/dist/server/main.d.ts +1 -0
- package/dist/server/main.js +9 -0
- package/dist/server/saved-items/saved-items.controller.d.ts +57 -0
- package/dist/server/saved-items/saved-items.controller.js +229 -0
- package/dist/server/saved-items/saved-items.module.d.ts +2 -0
- package/dist/server/saved-items/saved-items.module.js +25 -0
- package/dist/server/saved-items/saved-items.service.d.ts +31 -0
- package/dist/server/saved-items/saved-items.service.js +105 -0
- package/dist/server/saved-items/tags.controller.d.ts +30 -0
- package/dist/server/saved-items/tags.controller.js +85 -0
- package/dist/server/saved-items/tags.service.d.ts +24 -0
- package/dist/server/saved-items/tags.service.js +84 -0
- package/dist/server/skills/skills.controller.d.ts +63 -0
- package/dist/server/skills/skills.controller.js +194 -0
- package/dist/server/skills/skills.module.d.ts +2 -0
- package/dist/server/skills/skills.module.js +22 -0
- package/dist/server/skills/skills.service.d.ts +65 -0
- package/dist/server/skills/skills.service.js +388 -0
- package/dist/server/tasks/tasks.controller.d.ts +52 -0
- package/dist/server/tasks/tasks.controller.js +163 -0
- package/dist/server/tasks/tasks.module.d.ts +2 -0
- package/dist/server/tasks/tasks.module.js +23 -0
- package/dist/server/tasks/tasks.service.d.ts +86 -0
- package/dist/server/tasks/tasks.service.js +327 -0
- package/dist/server/usage/usage.controller.d.ts +12 -0
- package/dist/server/usage/usage.controller.js +46 -0
- package/dist/server/usage/usage.module.d.ts +2 -0
- package/dist/server/usage/usage.module.js +19 -0
- package/dist/server/usage/usage.service.d.ts +21 -0
- package/dist/server/usage/usage.service.js +55 -0
- package/dist/server/users/users.controller.d.ts +35 -0
- package/dist/server/users/users.controller.js +69 -0
- package/dist/server/users/users.module.d.ts +2 -0
- package/dist/server/users/users.module.js +19 -0
- package/dist/server/users/users.service.d.ts +39 -0
- package/dist/server/users/users.service.js +140 -0
- package/dist/server/workspace/workspace.controller.d.ts +24 -0
- package/dist/server/workspace/workspace.controller.js +132 -0
- package/dist/server/workspace/workspace.module.d.ts +2 -0
- package/dist/server/workspace/workspace.module.js +21 -0
- package/dist/server/workspace/workspace.service.d.ts +36 -0
- package/dist/server/workspace/workspace.service.js +142 -0
- package/package.json +90 -0
- package/skills/agent-browser/SKILL.md +207 -0
- package/skills/agent-browser/references/authentication.md +202 -0
- package/skills/agent-browser/references/commands.md +259 -0
- package/skills/agent-browser/references/proxy-support.md +188 -0
- package/skills/agent-browser/references/session-management.md +193 -0
- package/skills/agent-browser/references/snapshot-refs.md +194 -0
- package/skills/agent-browser/references/video-recording.md +173 -0
- package/skills/agent-browser/templates/authenticated-session.sh +97 -0
- package/skills/agent-browser/templates/capture-workflow.sh +69 -0
- package/skills/agent-browser/templates/form-automation.sh +62 -0
- package/skills/find-skills/SKILL.md +140 -0
- package/skills/url-bookmark/SKILL.md +36 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { createAgentSession, AuthStorage, DefaultResourceLoader, ModelRegistry, SessionManager as CoreSessionManager, createReadTool, createWriteTool, createEditTool, createBashTool, createFindTool, createGrepTool, createLsTool } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
4
|
+
import { createCompactionMemoryExtensionFactory } from "../memory/compaction-extension.js";
|
|
5
|
+
import { getCompactionContextForSystemPrompt } from "../memory/index.js";
|
|
6
|
+
import { createBrowserTool, createSaveExperienceTool, createInstallSkillTool, createGetBookmarkTagsTool, createSaveBookmarkTool } from "../tools/index.js";
|
|
7
|
+
import { createMcpToolsForSession } from "../mcp/index.js";
|
|
8
|
+
import { registerBuiltInApiProviders } from "@mariozechner/pi-ai/dist/providers/register-builtins.js";
|
|
9
|
+
import { getOpenbotAgentDir, getOpenbotWorkspaceDir, ensureDefaultAgentDir } from "./agent-dir.js";
|
|
10
|
+
import { formatSkillsForPrompt } from "./skills.js";
|
|
11
|
+
// Ensure all built-in providers are registered
|
|
12
|
+
registerBuiltInApiProviders();
|
|
13
|
+
/** system prompt 中每个技能描述最大字符数,超出截断以省 token */
|
|
14
|
+
const MAX_SKILL_DESC_IN_PROMPT = 250;
|
|
15
|
+
/**
|
|
16
|
+
* Unified Agent Manager for both CLI and Gateway
|
|
17
|
+
*/
|
|
18
|
+
export class AgentManager {
|
|
19
|
+
sessions = new Map();
|
|
20
|
+
/** 每个 session 最后被使用的时间戳,用于 LRU 淘汰 */
|
|
21
|
+
sessionLastActiveAt = new Map();
|
|
22
|
+
agentDir;
|
|
23
|
+
workspaceDir;
|
|
24
|
+
skillPaths = [];
|
|
25
|
+
preLoadedSkills = [];
|
|
26
|
+
constructor(options = {}) {
|
|
27
|
+
this.agentDir = options.agentDir || getOpenbotAgentDir();
|
|
28
|
+
// Centralized workspace root: ~/.openbot/workspace/
|
|
29
|
+
const workspaceRoot = getOpenbotWorkspaceDir();
|
|
30
|
+
const workspaceName = options.workspace || "default";
|
|
31
|
+
this.workspaceDir = join(workspaceRoot, workspaceName);
|
|
32
|
+
this.skillPaths = options.skillPaths || [];
|
|
33
|
+
this.preLoadedSkills = options.skills || [];
|
|
34
|
+
// Ensure workspace directory exists
|
|
35
|
+
if (!existsSync(this.workspaceDir)) {
|
|
36
|
+
mkdirSync(this.workspaceDir, { recursive: true });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Re-configure the manager
|
|
41
|
+
*/
|
|
42
|
+
configure(options) {
|
|
43
|
+
if (options.agentDir)
|
|
44
|
+
this.agentDir = options.agentDir;
|
|
45
|
+
if (options.workspace) {
|
|
46
|
+
const workspaceRoot = getOpenbotWorkspaceDir();
|
|
47
|
+
this.workspaceDir = join(workspaceRoot, options.workspace);
|
|
48
|
+
if (!existsSync(this.workspaceDir)) {
|
|
49
|
+
mkdirSync(this.workspaceDir, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (options.skillPaths)
|
|
53
|
+
this.skillPaths = options.skillPaths;
|
|
54
|
+
if (options.skills)
|
|
55
|
+
this.preLoadedSkills = options.skills;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build system prompt with skills and browser tool description
|
|
59
|
+
*/
|
|
60
|
+
buildSystemPrompt(skills) {
|
|
61
|
+
const shortSkills = skills.map((s) => ({
|
|
62
|
+
...s,
|
|
63
|
+
description: s.description.length <= MAX_SKILL_DESC_IN_PROMPT
|
|
64
|
+
? s.description
|
|
65
|
+
: s.description.slice(0, MAX_SKILL_DESC_IN_PROMPT) + "…",
|
|
66
|
+
}));
|
|
67
|
+
const skillsBlock = formatSkillsForPrompt(shortSkills);
|
|
68
|
+
const browserToolDesc = `
|
|
69
|
+
## Browser Tool
|
|
70
|
+
|
|
71
|
+
You have access to a \`browser\` tool for web automation:
|
|
72
|
+
- **navigate**: Navigate to a URL
|
|
73
|
+
- **snapshot**: Get page content with element refs (@e1, @e2, etc.)
|
|
74
|
+
- **screenshot**: Capture page image
|
|
75
|
+
- **click**: Click element (use selector or ref from snapshot)
|
|
76
|
+
- **type**: Type text into element
|
|
77
|
+
- **fill**: Clear and fill input field
|
|
78
|
+
- **scroll**: Scroll page (up/down/left/right)
|
|
79
|
+
- **extract**: Get text from element
|
|
80
|
+
- **wait**: Wait for element to appear
|
|
81
|
+
- **download**: Download file from URL or by clicking download button/link
|
|
82
|
+
- **back/forward**: Navigate browser history
|
|
83
|
+
- **close**: Close browser
|
|
84
|
+
|
|
85
|
+
Use refs from snapshots (e.g., @e1) for reliable element selection.
|
|
86
|
+
For downloads, provide either a direct URL or a selector to click.`;
|
|
87
|
+
const parts = [
|
|
88
|
+
"You are a helpful assistant. When users ask about skills, explain what skills are available.",
|
|
89
|
+
browserToolDesc,
|
|
90
|
+
skillsBlock,
|
|
91
|
+
].filter(Boolean);
|
|
92
|
+
return parts.join("\n\n");
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get the initial context (prompt and skills)
|
|
96
|
+
*/
|
|
97
|
+
async getContext() {
|
|
98
|
+
const loader = this.createResourceLoader(this.workspaceDir);
|
|
99
|
+
await loader.reload();
|
|
100
|
+
const loadedSkills = loader.getSkills().skills;
|
|
101
|
+
const systemPrompt = this.buildSystemPrompt(loadedSkills);
|
|
102
|
+
return { systemPrompt, skills: loadedSkills };
|
|
103
|
+
}
|
|
104
|
+
createResourceLoader(workspaceDir, sessionId, compactionBlock) {
|
|
105
|
+
const loader = new DefaultResourceLoader({
|
|
106
|
+
cwd: workspaceDir,
|
|
107
|
+
agentDir: this.agentDir,
|
|
108
|
+
noSkills: true, // Disable SDK's built-in skills logic to take full control
|
|
109
|
+
additionalSkillPaths: this.resolveSkillPaths(workspaceDir),
|
|
110
|
+
extensionFactories: sessionId ? [createCompactionMemoryExtensionFactory(sessionId)] : [],
|
|
111
|
+
systemPromptOverride: (base) => {
|
|
112
|
+
const loadedSkills = loader.getSkills().skills;
|
|
113
|
+
let customPrompt = this.buildSystemPrompt(loadedSkills);
|
|
114
|
+
if (compactionBlock?.trim()) {
|
|
115
|
+
customPrompt = customPrompt + "\n\n" + compactionBlock.trim();
|
|
116
|
+
}
|
|
117
|
+
return customPrompt;
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
return loader;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Resolve all relevant skill paths (Global, Project, Workspace)
|
|
124
|
+
* @param workspaceDir 当前会话使用的工作区目录,不传则用 manager 默认
|
|
125
|
+
*/
|
|
126
|
+
resolveSkillPaths(workspaceDir) {
|
|
127
|
+
const paths = new Set();
|
|
128
|
+
const wsDir = workspaceDir ?? this.workspaceDir;
|
|
129
|
+
// 1. Managed skills (Global: ~/.openbot/agent/skills)
|
|
130
|
+
const managedSkillsDir = join(this.agentDir, "skills");
|
|
131
|
+
if (existsSync(managedSkillsDir))
|
|
132
|
+
paths.add(managedSkillsDir);
|
|
133
|
+
// 2. Extra paths (CLI -s / Config)
|
|
134
|
+
this.skillPaths.forEach(p => paths.add(p));
|
|
135
|
+
// 3. Project skills (./skills)
|
|
136
|
+
const projectSkillsDir = join(process.cwd(), "skills");
|
|
137
|
+
if (existsSync(projectSkillsDir))
|
|
138
|
+
paths.add(projectSkillsDir);
|
|
139
|
+
// 4. Workspace skills (./workspace/<name>/skills)
|
|
140
|
+
const workspaceSkillsDir = join(wsDir, "skills");
|
|
141
|
+
if (existsSync(workspaceSkillsDir))
|
|
142
|
+
paths.add(workspaceSkillsDir);
|
|
143
|
+
return Array.from(paths);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get or create an agent session.
|
|
147
|
+
* @param options.workspace 该会话绑定的工作区名(来自 agent 配置),不传则用 default,创建时 cwd/技能路径依此
|
|
148
|
+
* @param options.provider / options.modelId 来自 agent 配置的大模型,不传则用环境变量默认
|
|
149
|
+
* @param options.maxSessions 若提供且当前 session 数 >= 该值,会先淘汰最后调用时间最早的 session 再创建新的
|
|
150
|
+
* @param options.targetAgentId 创建时绑定到 install_skill 工具,用于安装目标(具体 agentId 或 global)
|
|
151
|
+
*/
|
|
152
|
+
async getOrCreateSession(sessionId, options = {}) {
|
|
153
|
+
const now = Date.now();
|
|
154
|
+
if (this.sessions.has(sessionId)) {
|
|
155
|
+
this.sessionLastActiveAt.set(sessionId, now);
|
|
156
|
+
return this.sessions.get(sessionId);
|
|
157
|
+
}
|
|
158
|
+
const { maxSessions } = options;
|
|
159
|
+
if (typeof maxSessions === "number" && maxSessions > 0 && this.sessions.size >= maxSessions) {
|
|
160
|
+
let oldestId = null;
|
|
161
|
+
let oldestAt = Infinity;
|
|
162
|
+
for (const [id, at] of this.sessionLastActiveAt) {
|
|
163
|
+
if (this.sessions.has(id) && at < oldestAt) {
|
|
164
|
+
oldestAt = at;
|
|
165
|
+
oldestId = id;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (oldestId != null) {
|
|
169
|
+
this.deleteSession(oldestId);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const workspaceRoot = getOpenbotWorkspaceDir();
|
|
173
|
+
const workspaceName = options.workspace ?? "default";
|
|
174
|
+
const sessionWorkspaceDir = join(workspaceRoot, workspaceName);
|
|
175
|
+
if (!existsSync(sessionWorkspaceDir)) {
|
|
176
|
+
mkdirSync(sessionWorkspaceDir, { recursive: true });
|
|
177
|
+
}
|
|
178
|
+
const provider = options.provider ?? process.env.OPENBOT_PROVIDER ?? "deepseek";
|
|
179
|
+
const modelId = options.modelId ?? process.env.OPENBOT_MODEL ?? "deepseek-chat";
|
|
180
|
+
const apiKey = options.apiKey;
|
|
181
|
+
ensureDefaultAgentDir(this.agentDir);
|
|
182
|
+
const authPath = join(this.agentDir, "auth.json");
|
|
183
|
+
const modelsPath = join(this.agentDir, "models.json");
|
|
184
|
+
const authStorage = new AuthStorage(authPath);
|
|
185
|
+
if (apiKey) {
|
|
186
|
+
authStorage.setRuntimeApiKey(provider, apiKey);
|
|
187
|
+
}
|
|
188
|
+
if (await authStorage.hasAuth(provider)) {
|
|
189
|
+
const key = await authStorage.getApiKey(provider);
|
|
190
|
+
if (key) {
|
|
191
|
+
if (provider === "deepseek") {
|
|
192
|
+
process.env.OPENAI_API_KEY = key;
|
|
193
|
+
}
|
|
194
|
+
else if (provider === "dashscope") {
|
|
195
|
+
process.env.DASHSCOPE_API_KEY = key;
|
|
196
|
+
}
|
|
197
|
+
else if (provider === "nvidia") {
|
|
198
|
+
process.env.NVIDIA_API_KEY = key;
|
|
199
|
+
}
|
|
200
|
+
else if (provider === "kimi") {
|
|
201
|
+
process.env.MOONSHOT_API_KEY = key;
|
|
202
|
+
}
|
|
203
|
+
else if (provider === "openai" || provider === "openai-custom") {
|
|
204
|
+
process.env.OPENAI_API_KEY = key;
|
|
205
|
+
}
|
|
206
|
+
if (!process.env.OPENAI_API_KEY) {
|
|
207
|
+
process.env.OPENAI_API_KEY = key;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const modelRegistry = new ModelRegistry(authStorage, modelsPath);
|
|
212
|
+
authStorage.setFallbackResolver((p) => {
|
|
213
|
+
if (p === "deepseek")
|
|
214
|
+
return process.env.OPENAI_API_KEY || process.env.DEEPSEEK_API_KEY;
|
|
215
|
+
if (p === "dashscope")
|
|
216
|
+
return process.env.DASHSCOPE_API_KEY || process.env.OPENAI_API_KEY;
|
|
217
|
+
if (p === "nvidia")
|
|
218
|
+
return process.env.NVIDIA_API_KEY || process.env.OPENAI_API_KEY;
|
|
219
|
+
if (p === "kimi")
|
|
220
|
+
return process.env.MOONSHOT_API_KEY || process.env.KIMI_API_KEY || process.env.OPENAI_API_KEY;
|
|
221
|
+
if (p === "openai" || p === "openai-custom")
|
|
222
|
+
return process.env.OPENAI_API_KEY;
|
|
223
|
+
return process.env.OPENAI_API_KEY;
|
|
224
|
+
});
|
|
225
|
+
const compactionBlock = await getCompactionContextForSystemPrompt(sessionId);
|
|
226
|
+
const loader = this.createResourceLoader(sessionWorkspaceDir, sessionId, compactionBlock);
|
|
227
|
+
await loader.reload();
|
|
228
|
+
const coreTools = {
|
|
229
|
+
read: createReadTool(sessionWorkspaceDir),
|
|
230
|
+
write: createWriteTool(sessionWorkspaceDir),
|
|
231
|
+
edit: createEditTool(sessionWorkspaceDir),
|
|
232
|
+
bash: createBashTool(sessionWorkspaceDir),
|
|
233
|
+
find: createFindTool(sessionWorkspaceDir),
|
|
234
|
+
grep: createGrepTool(sessionWorkspaceDir),
|
|
235
|
+
ls: createLsTool(sessionWorkspaceDir),
|
|
236
|
+
};
|
|
237
|
+
const mcpTools = await createMcpToolsForSession({ mcpServers: options.mcpServers });
|
|
238
|
+
const customTools = [
|
|
239
|
+
createBrowserTool(sessionWorkspaceDir),
|
|
240
|
+
createSaveExperienceTool(sessionId),
|
|
241
|
+
createInstallSkillTool(options.targetAgentId),
|
|
242
|
+
createGetBookmarkTagsTool(),
|
|
243
|
+
createSaveBookmarkTool(),
|
|
244
|
+
...mcpTools,
|
|
245
|
+
];
|
|
246
|
+
const { session } = await createAgentSession({
|
|
247
|
+
agentDir: this.agentDir,
|
|
248
|
+
sessionManager: CoreSessionManager.inMemory(),
|
|
249
|
+
authStorage,
|
|
250
|
+
modelRegistry,
|
|
251
|
+
cwd: sessionWorkspaceDir,
|
|
252
|
+
resourceLoader: loader,
|
|
253
|
+
customTools,
|
|
254
|
+
baseToolsOverride: coreTools,
|
|
255
|
+
});
|
|
256
|
+
const model = modelRegistry.find(provider, modelId);
|
|
257
|
+
if (model) {
|
|
258
|
+
console.log(`Setting model to ${model.provider}/${model.id} (workspace: ${workspaceName})`);
|
|
259
|
+
await session.setModel(model);
|
|
260
|
+
}
|
|
261
|
+
this.sessions.set(sessionId, session);
|
|
262
|
+
this.sessionLastActiveAt.set(sessionId, now);
|
|
263
|
+
return session;
|
|
264
|
+
}
|
|
265
|
+
getSession(sessionId) {
|
|
266
|
+
return this.sessions.get(sessionId);
|
|
267
|
+
}
|
|
268
|
+
deleteSession(sessionId) {
|
|
269
|
+
this.sessionLastActiveAt.delete(sessionId);
|
|
270
|
+
return this.sessions.delete(sessionId);
|
|
271
|
+
}
|
|
272
|
+
clearAll() {
|
|
273
|
+
this.sessions.clear();
|
|
274
|
+
this.sessionLastActiveAt.clear();
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// Singleton for easy access (e.g., from Gateway)
|
|
278
|
+
export const agentManager = new AgentManager();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface ConfigInfo {
|
|
2
|
+
provider: string;
|
|
3
|
+
model: string;
|
|
4
|
+
hasKey: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Manage agent configuration (auth.json, models.json)
|
|
8
|
+
*/
|
|
9
|
+
export declare class ConfigManager {
|
|
10
|
+
private agentDir;
|
|
11
|
+
private authStorage;
|
|
12
|
+
constructor(agentDir?: string);
|
|
13
|
+
/**
|
|
14
|
+
* Save API key for a provider
|
|
15
|
+
*/
|
|
16
|
+
login(provider: string, apiKey: string): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Update default model for a provider in models.json
|
|
19
|
+
*/
|
|
20
|
+
setModel(provider: string, modelId: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* List current configurations
|
|
23
|
+
*/
|
|
24
|
+
list(): ConfigInfo[];
|
|
25
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { AuthStorage } from "@mariozechner/pi-coding-agent";
|
|
4
|
+
import { getOpenbotAgentDir, ensureDefaultAgentDir } from "./agent-dir.js";
|
|
5
|
+
/**
|
|
6
|
+
* Manage agent configuration (auth.json, models.json)
|
|
7
|
+
*/
|
|
8
|
+
export class ConfigManager {
|
|
9
|
+
agentDir;
|
|
10
|
+
authStorage;
|
|
11
|
+
constructor(agentDir = getOpenbotAgentDir()) {
|
|
12
|
+
this.agentDir = agentDir;
|
|
13
|
+
ensureDefaultAgentDir(this.agentDir);
|
|
14
|
+
const authPath = join(this.agentDir, "auth.json");
|
|
15
|
+
this.authStorage = new AuthStorage(authPath);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Save API key for a provider
|
|
19
|
+
*/
|
|
20
|
+
async login(provider, apiKey) {
|
|
21
|
+
this.authStorage.set(provider, {
|
|
22
|
+
type: "api_key",
|
|
23
|
+
key: apiKey
|
|
24
|
+
});
|
|
25
|
+
console.log(`[config] Successfully saved API key for provider: ${provider}`);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Update default model for a provider in models.json
|
|
29
|
+
*/
|
|
30
|
+
async setModel(provider, modelId) {
|
|
31
|
+
const modelsPath = join(this.agentDir, "models.json");
|
|
32
|
+
if (!existsSync(modelsPath)) {
|
|
33
|
+
throw new Error(`models.json not found at ${modelsPath}`);
|
|
34
|
+
}
|
|
35
|
+
const config = JSON.parse(readFileSync(modelsPath, "utf-8"));
|
|
36
|
+
if (!config.providers[provider]) {
|
|
37
|
+
throw new Error(`Provider "${provider}" not found in models.json`);
|
|
38
|
+
}
|
|
39
|
+
// Check if model exists in that provider's list
|
|
40
|
+
const providerConfig = config.providers[provider];
|
|
41
|
+
const modelExists = providerConfig.models?.some((m) => m.id === modelId);
|
|
42
|
+
if (!modelExists) {
|
|
43
|
+
console.warn(`[config] Warning: Model "${modelId}" not found in the defined list for "${provider}". Adding it anyway.`);
|
|
44
|
+
if (!providerConfig.models)
|
|
45
|
+
providerConfig.models = [];
|
|
46
|
+
providerConfig.models.push({
|
|
47
|
+
id: modelId,
|
|
48
|
+
name: modelId,
|
|
49
|
+
contextWindow: 128000,
|
|
50
|
+
supportsTools: true
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
// In this simple implementation, we assume the first model in the list
|
|
54
|
+
// might be intended as default by some logic, although the registry
|
|
55
|
+
// usually needs explicit selection.
|
|
56
|
+
// For now, let's just reorder so the selected model is first.
|
|
57
|
+
const modelIndex = providerConfig.models.findIndex((m) => m.id === modelId);
|
|
58
|
+
if (modelIndex > 0) {
|
|
59
|
+
const [model] = providerConfig.models.splice(modelIndex, 1);
|
|
60
|
+
providerConfig.models.unshift(model);
|
|
61
|
+
}
|
|
62
|
+
writeFileSync(modelsPath, JSON.stringify(config, null, 2), "utf-8");
|
|
63
|
+
console.log(`[config] Updated default model for "${provider}" to "${modelId}"`);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* List current configurations
|
|
67
|
+
*/
|
|
68
|
+
list() {
|
|
69
|
+
const modelsPath = join(this.agentDir, "models.json");
|
|
70
|
+
if (!existsSync(modelsPath))
|
|
71
|
+
return [];
|
|
72
|
+
const config = JSON.parse(readFileSync(modelsPath, "utf-8"));
|
|
73
|
+
const results = [];
|
|
74
|
+
for (const [providerId, providerConfig] of Object.entries(config.providers)) {
|
|
75
|
+
const firstModel = providerConfig.models?.[0]?.id || "none";
|
|
76
|
+
results.push({
|
|
77
|
+
provider: providerId,
|
|
78
|
+
model: firstModel,
|
|
79
|
+
hasKey: this.authStorage.has(providerId)
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return results;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface RunOptions {
|
|
2
|
+
/** Workspace name (e.g. "default") */
|
|
3
|
+
workspace?: string;
|
|
4
|
+
/** Additional skill paths */
|
|
5
|
+
skillPaths?: string[];
|
|
6
|
+
/** 用户提示词 */
|
|
7
|
+
userPrompt: string;
|
|
8
|
+
/** 是否仅打印组装后的内容,不调 LLM */
|
|
9
|
+
dryRun?: boolean;
|
|
10
|
+
/** API key,不传则从 pi 的 auth 或 OPENAI_API_KEY 读取 */
|
|
11
|
+
apiKey?: string;
|
|
12
|
+
/** 模型 ID(如 deepseek-chat、qwen-max) */
|
|
13
|
+
model?: string;
|
|
14
|
+
/** Provider(如 deepseek、dashscope、openai) */
|
|
15
|
+
provider?: string;
|
|
16
|
+
/** Agent 配置目录,默认 ~/.openbot/agent */
|
|
17
|
+
agentDir?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface RunResult {
|
|
20
|
+
systemPrompt: string;
|
|
21
|
+
userPrompt: string;
|
|
22
|
+
/** 若调用了 API,则为助手回复 */
|
|
23
|
+
assistantContent?: string;
|
|
24
|
+
dryRun: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function run(options: RunOptions): Promise<RunResult>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { getOpenbotAgentDir } from "./agent-dir.js";
|
|
2
|
+
import { AgentManager } from "./agent-manager.js";
|
|
3
|
+
export async function run(options) {
|
|
4
|
+
const { workspace = "default", skillPaths = [], userPrompt, dryRun: explicitDryRun, apiKey, model: modelId = "deepseek-chat", provider = "deepseek", agentDir = getOpenbotAgentDir(), } = options;
|
|
5
|
+
const manager = new AgentManager({ agentDir, workspace, skillPaths });
|
|
6
|
+
const { systemPrompt } = await manager.getContext();
|
|
7
|
+
// Determine dry run
|
|
8
|
+
const dryRun = !!explicitDryRun; // Ensure boolean
|
|
9
|
+
const result = {
|
|
10
|
+
systemPrompt,
|
|
11
|
+
userPrompt,
|
|
12
|
+
dryRun,
|
|
13
|
+
};
|
|
14
|
+
if (dryRun) {
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
// Create a temporary session for this run
|
|
18
|
+
const sessionId = `cli-${Date.now()}`;
|
|
19
|
+
const session = await manager.getOrCreateSession(sessionId, {
|
|
20
|
+
provider,
|
|
21
|
+
modelId,
|
|
22
|
+
apiKey,
|
|
23
|
+
});
|
|
24
|
+
// Collect assistant response
|
|
25
|
+
let assistantContent = "";
|
|
26
|
+
session.subscribe((event) => {
|
|
27
|
+
switch (event.type) {
|
|
28
|
+
case "message_update": {
|
|
29
|
+
const evt = event.assistantMessageEvent;
|
|
30
|
+
if (evt.type === "text_delta") {
|
|
31
|
+
assistantContent += evt.delta;
|
|
32
|
+
process.stdout.write(evt.delta);
|
|
33
|
+
}
|
|
34
|
+
else if (evt.type === "thinking_delta") {
|
|
35
|
+
process.stdout.write(evt.delta);
|
|
36
|
+
}
|
|
37
|
+
else if (evt.type === "error") {
|
|
38
|
+
console.error(`\n[model:error] ${evt.error.errorMessage || "Unknown error"}`);
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case "message_end": {
|
|
43
|
+
if (event.message.role === "assistant" && event.message.errorMessage) {
|
|
44
|
+
console.error(`\n[message:error] ${event.message.errorMessage}`);
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
case "tool_execution_start": {
|
|
49
|
+
console.log(`\n[tool:start] ${event.toolName}(${JSON.stringify(event.args)})`);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case "tool_execution_end": {
|
|
53
|
+
const status = event.isError ? "failed" : "ok";
|
|
54
|
+
console.log(`[tool:end] ${event.toolName} -> ${status}`);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
// Send prompt and wait for completion
|
|
60
|
+
await session.prompt(userPrompt);
|
|
61
|
+
// Clean up session
|
|
62
|
+
manager.deleteSession(sessionId);
|
|
63
|
+
result.assistantContent = assistantContent.trim();
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Skill } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
export type { Skill };
|
|
3
|
+
export interface LoadSkillsFromDirOptions {
|
|
4
|
+
dir: string;
|
|
5
|
+
source: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 从目录加载 skills(委托给 pi-coding-agent,规则与其一致)
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadSkillsFromDir(options: LoadSkillsFromDirOptions): Skill[];
|
|
11
|
+
/**
|
|
12
|
+
* 从多个路径加载 skills(文件或目录),合并去重(按 name)
|
|
13
|
+
* 目录使用 pi-coding-agent 的 loadSkillsFromDir,单文件使用本地解析
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadSkillsFromPaths(paths: string[], source?: string): Skill[];
|
|
16
|
+
/**
|
|
17
|
+
* 将 Skill[] 格式化为系统提示中的一段(委托给 pi-coding-agent,对齐 agentskills.io)
|
|
18
|
+
*/
|
|
19
|
+
declare function formatSkillsForPrompt(skills: Skill[]): string;
|
|
20
|
+
export { formatSkillsForPrompt };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { join, dirname, basename } from "node:path";
|
|
3
|
+
import { formatSkillsForPrompt as piFormatSkillsForPrompt, loadSkillsFromDir as piLoadSkillsFromDir, } from "@mariozechner/pi-coding-agent";
|
|
4
|
+
/**
|
|
5
|
+
* 简单 frontmatter 解析:--- 与 --- 之间的 YAML 风格键值
|
|
6
|
+
*/
|
|
7
|
+
function parseFrontmatter(raw) {
|
|
8
|
+
const match = raw.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
9
|
+
if (!match)
|
|
10
|
+
return {};
|
|
11
|
+
const block = match[1];
|
|
12
|
+
const out = {};
|
|
13
|
+
for (const line of block.split("\n")) {
|
|
14
|
+
const m = line.match(/^\s*([a-z-]+)\s*:\s*(.*)$/);
|
|
15
|
+
if (m)
|
|
16
|
+
out[m[1].trim()] = m[2].trim().replace(/^["']|["']$/g, "");
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
name: out.name,
|
|
20
|
+
description: out.description,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 从单文件加载一个 Skill(与 pi-coding-agent Skill 结构一致)
|
|
25
|
+
*/
|
|
26
|
+
function loadSkillFromFile(filePath, source) {
|
|
27
|
+
try {
|
|
28
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
29
|
+
const { name, description } = parseFrontmatter(raw);
|
|
30
|
+
const skillDir = dirname(filePath);
|
|
31
|
+
const parentDirName = basename(skillDir);
|
|
32
|
+
const finalName = (name || parentDirName).trim();
|
|
33
|
+
const finalDesc = (description || "").trim();
|
|
34
|
+
if (!finalDesc)
|
|
35
|
+
return null;
|
|
36
|
+
return {
|
|
37
|
+
name: finalName,
|
|
38
|
+
description: finalDesc,
|
|
39
|
+
filePath,
|
|
40
|
+
baseDir: skillDir,
|
|
41
|
+
source,
|
|
42
|
+
disableModelInvocation: false,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 从目录加载 skills(委托给 pi-coding-agent,规则与其一致)
|
|
51
|
+
*/
|
|
52
|
+
export function loadSkillsFromDir(options) {
|
|
53
|
+
const result = piLoadSkillsFromDir(options);
|
|
54
|
+
return result.skills ?? [];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* 从多个路径加载 skills(文件或目录),合并去重(按 name)
|
|
58
|
+
* 目录使用 pi-coding-agent 的 loadSkillsFromDir,单文件使用本地解析
|
|
59
|
+
*/
|
|
60
|
+
export function loadSkillsFromPaths(paths, source = "user") {
|
|
61
|
+
const byName = new Map();
|
|
62
|
+
for (const p of paths) {
|
|
63
|
+
const resolved = p.startsWith("~") ? join(process.env.HOME || "", p.slice(1)) : p;
|
|
64
|
+
if (!existsSync(resolved))
|
|
65
|
+
continue;
|
|
66
|
+
const stat = statSync(resolved);
|
|
67
|
+
if (stat.isFile() && resolved.endsWith(".md")) {
|
|
68
|
+
const skill = loadSkillFromFile(resolved, source);
|
|
69
|
+
if (skill)
|
|
70
|
+
byName.set(skill.name, skill);
|
|
71
|
+
}
|
|
72
|
+
else if (stat.isDirectory()) {
|
|
73
|
+
for (const skill of loadSkillsFromDir({ dir: resolved, source })) {
|
|
74
|
+
byName.set(skill.name, skill);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return Array.from(byName.values());
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 将 Skill[] 格式化为系统提示中的一段(委托给 pi-coding-agent,对齐 agentskills.io)
|
|
82
|
+
*/
|
|
83
|
+
function formatSkillsForPrompt(skills) {
|
|
84
|
+
return piFormatSkillsForPrompt(skills);
|
|
85
|
+
}
|
|
86
|
+
export { formatSkillsForPrompt };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { type ProviderSupport, type ProviderSupportEntry, type ProviderSupportModel, type ModelSupportType } from "./provider-support-default.js";
|
|
2
|
+
export type { ProviderSupport, ProviderSupportEntry, ProviderSupportModel, ModelSupportType };
|
|
3
|
+
/** RAG 长记忆:使用远端 embedding 模型;未配置时基于 RAG 的长记忆空转 */
|
|
4
|
+
export interface RagEmbeddingConfig {
|
|
5
|
+
provider: string;
|
|
6
|
+
modelId: string;
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
/** MCP 服务器配置(与 core/mcp 类型一致,避免 core/config 依赖 core/mcp 实现) */
|
|
11
|
+
export type DesktopMcpServerConfig = import("../mcp/index.js").McpServerConfig;
|
|
12
|
+
/**
|
|
13
|
+
* 同步读取桌面全局配置中的 maxAgentSessions 等。
|
|
14
|
+
* Gateway 进程内使用,用于会话上限等。
|
|
15
|
+
*/
|
|
16
|
+
export declare function getDesktopConfig(): {
|
|
17
|
+
maxAgentSessions: number;
|
|
18
|
+
};
|
|
19
|
+
/** 同步读取 RAG embedding 配置;未配置或无效时返回 null,长记忆将空转 */
|
|
20
|
+
export declare function getRagEmbeddingConfigSync(): RagEmbeddingConfig | null;
|
|
21
|
+
export interface DesktopAgentConfig {
|
|
22
|
+
provider: string;
|
|
23
|
+
model: string;
|
|
24
|
+
apiKey?: string;
|
|
25
|
+
/** 工作区名,来自 agents.json 的 agent.workspace 或 agent.id */
|
|
26
|
+
workspace?: string;
|
|
27
|
+
/** MCP 服务器配置,创建 Session 时传入 */
|
|
28
|
+
mcpServers?: DesktopMcpServerConfig[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 从 config.json 读取缺省智能体 id(defaultAgentId)。
|
|
32
|
+
* 若未配置、或该 id 在 agents.json 中不存在,则返回 default。
|
|
33
|
+
*/
|
|
34
|
+
export declare function getBoundAgentIdForCli(): Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
* 根据 agentId 从桌面配置中读取该 agent 的 provider、model 及 API Key。
|
|
37
|
+
* 若文件不存在或解析失败返回 null,调用方使用环境变量或默认值。
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadDesktopAgentConfig(agentId: string): Promise<DesktopAgentConfig | null>;
|
|
40
|
+
/** 供 CLI config list 使用:从桌面 config 读出的配置列表项 */
|
|
41
|
+
export interface DesktopConfigListEntry {
|
|
42
|
+
provider: string;
|
|
43
|
+
defaultModel: string;
|
|
44
|
+
hasKey: boolean;
|
|
45
|
+
}
|
|
46
|
+
/** 供 CLI config list 使用:桌面配置列表(中心化配置源) */
|
|
47
|
+
export interface DesktopConfigList {
|
|
48
|
+
defaultProvider: string;
|
|
49
|
+
defaultModel: string;
|
|
50
|
+
defaultModelItemCode?: string;
|
|
51
|
+
providers: DesktopConfigListEntry[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 将某 provider 的 API Key 写入桌面 config(中心化配置源)。
|
|
55
|
+
* openbot login 使用:缺省 alias 与 provider 同名;若有 baseUrl 则一并写入。
|
|
56
|
+
* 若传入 modelId 或未传则取该 provider 第一个模型,会补齐 defaultProvider/defaultModel、configuredModels、agents 默认智能体,后续可直接运行。
|
|
57
|
+
*/
|
|
58
|
+
export declare function setProviderApiKey(provider: string, apiKey: string, modelId?: string): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* 将全局默认 provider/model 写入桌面 config,并在 configuredModels 中增加/更新对应项,agents.json 中缺省智能体写入 modelItemCode。
|
|
61
|
+
* openbot config set-model 使用此方法。
|
|
62
|
+
*/
|
|
63
|
+
export declare function setDefaultModel(provider: string, modelId: string): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* 供 CLI config list 使用,从桌面 config 读出配置列表。
|
|
66
|
+
*/
|
|
67
|
+
export declare function getDesktopConfigList(): Promise<DesktopConfigList>;
|
|
68
|
+
/**
|
|
69
|
+
* 确保桌面目录下存在 provider-support.json(不存在则写入默认内容)。
|
|
70
|
+
* 供配置供应商时作备选下拉列表项。
|
|
71
|
+
*/
|
|
72
|
+
export declare function ensureProviderSupportFile(): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* CLI / Gateway 运行时调用,确保 config.json、provider-support.json、agents.json 均完成初始化。
|
|
75
|
+
*/
|
|
76
|
+
export declare function ensureDesktopConfigInitialized(): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* 取某 provider 在 provider-support 中的第一个 llm 模型 id;若无则返回第一个模型 id。
|
|
79
|
+
*/
|
|
80
|
+
export declare function getFirstModelForProvider(provider: string): Promise<string | null>;
|
|
81
|
+
/**
|
|
82
|
+
* 读取桌面 provider-support.json(流行 provider 及模型目录)。
|
|
83
|
+
* 若文件不存在则先写入默认内容再返回;若存在则与默认合并,补全默认中已有而文件中缺失的 provider(如新增的 openai-custom)。
|
|
84
|
+
*/
|
|
85
|
+
export declare function getProviderSupport(): Promise<ProviderSupport>;
|
|
86
|
+
/**
|
|
87
|
+
* 根据桌面 config(已配置的 providers + configuredModels)与 provider-support,生成并写入 agent 目录的 models.json。
|
|
88
|
+
* 仅包含在 config 的 providers 中已配置的 provider;每个 provider 的 models 来自 configuredModels,结构含 reasoning、cost 等。
|
|
89
|
+
*/
|
|
90
|
+
export declare function syncDesktopConfigToModelsJson(): Promise<void>;
|