@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.
Files changed (173) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +155 -136
  3. package/apps/desktop/renderer/dist/assets/index-CxDZnMBH.css +10 -0
  4. package/apps/desktop/renderer/dist/assets/index-k47Qiokg.js +93 -0
  5. package/apps/desktop/renderer/dist/index.html +2 -2
  6. package/dist/cli/cli.js +136 -0
  7. package/dist/cli/extension-cmd.d.ts +15 -0
  8. package/dist/cli/extension-cmd.js +107 -0
  9. package/dist/core/agent/agent-dir.d.ts +6 -0
  10. package/dist/core/agent/agent-dir.js +8 -0
  11. package/dist/core/agent/agent-manager.d.ts +27 -6
  12. package/dist/core/agent/agent-manager.js +147 -26
  13. package/dist/core/agent/proxy/adapters/claude-code-adapter.d.ts +2 -0
  14. package/dist/core/agent/proxy/adapters/claude-code-adapter.js +186 -0
  15. package/dist/core/agent/proxy/adapters/coze-adapter.d.ts +2 -0
  16. package/dist/core/agent/proxy/adapters/coze-adapter.js +406 -0
  17. package/dist/core/agent/proxy/adapters/local-adapter.d.ts +2 -0
  18. package/dist/core/agent/proxy/adapters/local-adapter.js +95 -0
  19. package/dist/core/agent/proxy/adapters/openclawx-adapter.d.ts +2 -0
  20. package/dist/core/agent/proxy/adapters/openclawx-adapter.js +115 -0
  21. package/dist/core/agent/proxy/adapters/opencode-adapter.d.ts +11 -0
  22. package/dist/core/agent/proxy/adapters/opencode-adapter.js +786 -0
  23. package/dist/core/agent/proxy/adapters/opencode-free-models.d.ts +20 -0
  24. package/dist/core/agent/proxy/adapters/opencode-free-models.js +14 -0
  25. package/dist/core/agent/proxy/adapters/opencode-local-runner.d.ts +5 -0
  26. package/dist/core/agent/proxy/adapters/opencode-local-runner.js +95 -0
  27. package/dist/core/agent/proxy/index.d.ts +3 -0
  28. package/dist/core/agent/proxy/index.js +18 -0
  29. package/dist/core/agent/proxy/registry.d.ts +7 -0
  30. package/dist/core/agent/proxy/registry.js +13 -0
  31. package/dist/core/agent/proxy/run-for-channel.d.ts +3 -0
  32. package/dist/core/agent/proxy/run-for-channel.js +31 -0
  33. package/dist/core/agent/proxy/types.d.ts +30 -0
  34. package/dist/core/agent/proxy/types.js +1 -0
  35. package/dist/core/agent/run.js +1 -1
  36. package/dist/core/agent/token-usage-log-extension.d.ts +14 -0
  37. package/dist/core/agent/token-usage-log-extension.js +61 -0
  38. package/dist/core/config/agent-reload-pending.d.ts +9 -0
  39. package/dist/core/config/agent-reload-pending.js +67 -0
  40. package/dist/core/config/desktop-config.d.ts +136 -5
  41. package/dist/core/config/desktop-config.js +470 -46
  42. package/dist/core/config/provider-support-default.js +27 -0
  43. package/dist/core/extensions/index.d.ts +1 -0
  44. package/dist/core/extensions/index.js +1 -0
  45. package/dist/core/extensions/load.d.ts +11 -0
  46. package/dist/core/extensions/load.js +101 -0
  47. package/dist/core/inbound-message-preprocess.d.ts +27 -0
  48. package/dist/core/inbound-message-preprocess.js +96 -0
  49. package/dist/core/local-llm-server/download-model.d.ts +16 -0
  50. package/dist/core/local-llm-server/download-model.js +37 -0
  51. package/dist/core/local-llm-server/index.d.ts +32 -0
  52. package/dist/core/local-llm-server/index.js +152 -0
  53. package/dist/core/local-llm-server/llm-context.d.ts +66 -0
  54. package/dist/core/local-llm-server/llm-context.js +270 -0
  55. package/dist/core/local-llm-server/model-resolve.d.ts +27 -0
  56. package/dist/core/local-llm-server/model-resolve.js +90 -0
  57. package/dist/core/local-llm-server/server.d.ts +1 -0
  58. package/dist/core/local-llm-server/server.js +234 -0
  59. package/dist/core/local-llm-server/start-from-config.d.ts +5 -0
  60. package/dist/core/local-llm-server/start-from-config.js +50 -0
  61. package/dist/core/mcp/adapter.d.ts +4 -2
  62. package/dist/core/mcp/adapter.js +10 -4
  63. package/dist/core/mcp/client.d.ts +4 -0
  64. package/dist/core/mcp/client.js +2 -0
  65. package/dist/core/mcp/config.d.ts +14 -3
  66. package/dist/core/mcp/config.js +68 -3
  67. package/dist/core/mcp/index.d.ts +10 -6
  68. package/dist/core/mcp/index.js +7 -3
  69. package/dist/core/mcp/operator.d.ts +28 -2
  70. package/dist/core/mcp/operator.js +131 -30
  71. package/dist/core/mcp/transport/index.d.ts +4 -0
  72. package/dist/core/mcp/transport/index.js +6 -1
  73. package/dist/core/mcp/transport/stdio.d.ts +12 -0
  74. package/dist/core/mcp/transport/stdio.js +147 -29
  75. package/dist/core/mcp/types.d.ts +18 -0
  76. package/dist/core/memory/compaction-extension.d.ts +4 -3
  77. package/dist/core/memory/compaction-extension.js +6 -14
  78. package/dist/core/memory/embedding-types.d.ts +10 -0
  79. package/dist/core/memory/embedding-types.js +5 -0
  80. package/dist/core/memory/embedding.d.ts +2 -1
  81. package/dist/core/memory/embedding.js +38 -6
  82. package/dist/core/memory/index.js +3 -0
  83. package/dist/core/memory/local-embedding-llama.d.ts +13 -0
  84. package/dist/core/memory/local-embedding-llama.js +78 -0
  85. package/dist/core/memory/local-embedding.d.ts +11 -0
  86. package/dist/core/memory/local-embedding.js +69 -0
  87. package/dist/core/memory/persist-compaction-on-close.d.ts +14 -0
  88. package/dist/core/memory/persist-compaction-on-close.js +32 -0
  89. package/dist/core/session-outlet/index.d.ts +19 -0
  90. package/dist/core/session-outlet/index.js +33 -0
  91. package/dist/core/session-outlet/outlet.d.ts +15 -0
  92. package/dist/core/session-outlet/outlet.js +49 -0
  93. package/dist/core/session-outlet/types.d.ts +35 -0
  94. package/dist/core/session-outlet/types.js +5 -0
  95. package/dist/core/tools/bookmark-tool.d.ts +4 -0
  96. package/dist/core/tools/bookmark-tool.js +59 -3
  97. package/dist/core/tools/index.d.ts +3 -1
  98. package/dist/core/tools/index.js +3 -1
  99. package/dist/core/tools/memory-recall-tool.d.ts +6 -0
  100. package/dist/core/tools/memory-recall-tool.js +77 -0
  101. package/dist/core/tools/truncate-result.d.ts +14 -0
  102. package/dist/core/tools/truncate-result.js +27 -0
  103. package/dist/core/tools/web-search/create-web-search-tool.d.ts +17 -0
  104. package/dist/core/tools/web-search/create-web-search-tool.js +87 -0
  105. package/dist/core/tools/web-search/index.d.ts +4 -0
  106. package/dist/core/tools/web-search/index.js +2 -0
  107. package/dist/core/tools/web-search/providers/brave.d.ts +2 -0
  108. package/dist/core/tools/web-search/providers/brave.js +87 -0
  109. package/dist/core/tools/web-search/providers/duck-duck-scrape.d.ts +2 -0
  110. package/dist/core/tools/web-search/providers/duck-duck-scrape.js +47 -0
  111. package/dist/core/tools/web-search/providers/index.d.ts +5 -0
  112. package/dist/core/tools/web-search/providers/index.js +13 -0
  113. package/dist/core/tools/web-search/types.d.ts +35 -0
  114. package/dist/core/tools/web-search/types.js +4 -0
  115. package/dist/gateway/channel/adapters/telegram.js +13 -2
  116. package/dist/gateway/channel/adapters/wechat.d.ts +24 -0
  117. package/dist/gateway/channel/adapters/wechat.js +205 -0
  118. package/dist/gateway/channel/channel-core.d.ts +1 -0
  119. package/dist/gateway/channel/channel-core.js +101 -59
  120. package/dist/gateway/channel/run-agent.d.ts +2 -4
  121. package/dist/gateway/channel/run-agent.js +13 -125
  122. package/dist/gateway/methods/agent-cancel.d.ts +3 -1
  123. package/dist/gateway/methods/agent-cancel.js +16 -2
  124. package/dist/gateway/methods/agent-chat.d.ts +4 -0
  125. package/dist/gateway/methods/agent-chat.js +377 -118
  126. package/dist/gateway/methods/run-scheduled-task.js +9 -7
  127. package/dist/gateway/proxy-run-abort.d.ts +6 -0
  128. package/dist/gateway/proxy-run-abort.js +39 -0
  129. package/dist/gateway/server.js +123 -19
  130. package/dist/server/agent-config/agent-config.controller.d.ts +10 -2
  131. package/dist/server/agent-config/agent-config.controller.js +19 -4
  132. package/dist/server/agent-config/agent-config.module.js +3 -1
  133. package/dist/server/agent-config/agent-config.service.d.ts +91 -6
  134. package/dist/server/agent-config/agent-config.service.js +115 -3
  135. package/dist/server/agents/agents.controller.d.ts +16 -0
  136. package/dist/server/agents/agents.controller.js +62 -1
  137. package/dist/server/agents/agents.gateway.js +1 -1
  138. package/dist/server/agents/agents.service.js +1 -1
  139. package/dist/server/bootstrap.d.ts +1 -0
  140. package/dist/server/bootstrap.js +28 -4
  141. package/dist/server/config/config.controller.d.ts +134 -2
  142. package/dist/server/config/config.controller.js +199 -3
  143. package/dist/server/config/config.module.js +5 -4
  144. package/dist/server/config/config.service.d.ts +32 -2
  145. package/dist/server/config/config.service.js +69 -9
  146. package/dist/server/config/local-models.service.d.ts +67 -0
  147. package/dist/server/config/local-models.service.js +242 -0
  148. package/dist/server/workspace/workspace.service.d.ts +7 -0
  149. package/dist/server/workspace/workspace.service.js +16 -0
  150. package/package.json +10 -2
  151. package/presets/preset-agents.json +128 -0
  152. package/presets/preset-config.json +29 -0
  153. package/presets/preset-providers.json +180 -0
  154. package/presets/recommended-local-models.json +36 -0
  155. package/presets/workspaces/code-assistant/skills/code-review/SKILL.md +19 -0
  156. package/presets/workspaces/code-assistant/skills/code-runner/SKILL.md +21 -0
  157. package/presets/workspaces/code-assistant/skills/git-helper/SKILL.md +29 -0
  158. package/presets/workspaces/creator-assistant/skills/.gitkeep +0 -0
  159. package/presets/workspaces/creator-assistant/skills/creator-tools/SKILL.md +15 -0
  160. package/presets/workspaces/doc-assistant/skills/doc-processor/SKILL.md +21 -0
  161. package/presets/workspaces/download-assistant/skills/downloader/SKILL.md +20 -0
  162. package/presets/workspaces/file-assistant/skills/file-converter/SKILL.md +21 -0
  163. package/presets/workspaces/file-assistant/skills/file-organizer/SKILL.md +17 -0
  164. package/presets/workspaces/file-assistant/skills/file-search/SKILL.md +22 -0
  165. package/presets/workspaces/morning-briefing/skills/news-fetcher/SKILL.md +16 -0
  166. package/presets/workspaces/morning-briefing/skills/web-summarizer/SKILL.md +20 -0
  167. package/presets/workspaces/news-assistant/skills/news-fetcher/SKILL.md +16 -0
  168. package/presets/workspaces/news-assistant/skills/web-summarizer/SKILL.md +20 -0
  169. package/presets/workspaces/office-automation/skills/rpa-helper/SKILL.md +9 -0
  170. package/presets/workspaces/self-media-bot/skills/self-media-tools/SKILL.md +9 -0
  171. package/skills/url-bookmark/SKILL.md +12 -12
  172. package/apps/desktop/renderer/dist/assets/index-LCp1YPVA.css +0 -10
  173. package/apps/desktop/renderer/dist/assets/index-l5fpDsHs.js +0 -89
@@ -10,8 +10,9 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  var __param = (this && this.__param) || function (paramIndex, decorator) {
11
11
  return function (target, key) { decorator(target, key, paramIndex); }
12
12
  };
13
- import { Controller, Delete, Get, Patch, Post, Body, Param, Header, HttpException, HttpStatus, } from '@nestjs/common';
13
+ import { Controller, Delete, Get, Patch, Post, Body, Param, Res, Header, HttpException, HttpStatus, } from '@nestjs/common';
14
14
  import { AgentsService } from './agents.service.js';
15
+ import { runForChannelStream, runForChannelCollect } from '../../core/agent/proxy/index.js';
15
16
  let AgentsController = class AgentsController {
16
17
  agentsService;
17
18
  constructor(agentsService) {
@@ -86,6 +87,48 @@ let AgentsController = class AgentsController {
86
87
  });
87
88
  return { success: true };
88
89
  }
90
+ /** 供远程 OpenBot 代理调用:一次性返回助手回复 */
91
+ async proxyChat(body) {
92
+ const sessionId = body?.sessionId ?? '';
93
+ const message = body?.message ?? '';
94
+ const agentId = body?.agentId ?? 'default';
95
+ if (!sessionId || !message) {
96
+ throw new HttpException('sessionId and message are required', HttpStatus.BAD_REQUEST);
97
+ }
98
+ try {
99
+ const text = await runForChannelCollect({ sessionId, message, agentId });
100
+ return { success: true, text };
101
+ }
102
+ catch (error) {
103
+ throw new HttpException(error?.message ?? 'Proxy chat failed', HttpStatus.INTERNAL_SERVER_ERROR);
104
+ }
105
+ }
106
+ /** 供远程 OpenBot 代理调用:SSE 流式返回助手回复 */
107
+ async proxyChatStream(body, res) {
108
+ const sessionId = body?.sessionId ?? '';
109
+ const message = body?.message ?? '';
110
+ const agentId = body?.agentId ?? 'default';
111
+ if (!sessionId || !message) {
112
+ res.status(400).json({ error: 'sessionId and message are required' });
113
+ return;
114
+ }
115
+ res.flushHeaders();
116
+ try {
117
+ await runForChannelStream({ sessionId, message, agentId }, {
118
+ onChunk(delta) {
119
+ res.write(`data: ${JSON.stringify({ delta })}\n\n`);
120
+ },
121
+ onDone() {
122
+ res.write(`data: ${JSON.stringify({ done: true })}\n\n`);
123
+ res.end();
124
+ },
125
+ });
126
+ }
127
+ catch (error) {
128
+ res.write(`data: ${JSON.stringify({ error: error?.message ?? 'Stream failed' })}\n\n`);
129
+ res.end();
130
+ }
131
+ }
89
132
  };
90
133
  __decorate([
91
134
  Post('sessions'),
@@ -145,6 +188,24 @@ __decorate([
145
188
  __metadata("design:paramtypes", [String, Object]),
146
189
  __metadata("design:returntype", void 0)
147
190
  ], AgentsController.prototype, "appendMessage", null);
191
+ __decorate([
192
+ Post('proxy-chat'),
193
+ __param(0, Body()),
194
+ __metadata("design:type", Function),
195
+ __metadata("design:paramtypes", [Object]),
196
+ __metadata("design:returntype", Promise)
197
+ ], AgentsController.prototype, "proxyChat", null);
198
+ __decorate([
199
+ Post('proxy-chat/stream'),
200
+ Header('Content-Type', 'text/event-stream'),
201
+ Header('Cache-Control', 'no-cache'),
202
+ Header('Connection', 'keep-alive'),
203
+ __param(0, Body()),
204
+ __param(1, Res()),
205
+ __metadata("design:type", Function),
206
+ __metadata("design:paramtypes", [Object, Object]),
207
+ __metadata("design:returntype", Promise)
208
+ ], AgentsController.prototype, "proxyChatStream", null);
148
209
  AgentsController = __decorate([
149
210
  Controller('agents'),
150
211
  __metadata("design:paramtypes", [AgentsService])
@@ -108,7 +108,7 @@ __decorate([
108
108
  AgentsGateway = __decorate([
109
109
  WebSocketGateway({
110
110
  cors: {
111
- origin: ['http://localhost:5173', 'http://localhost:38081'],
111
+ origin: ['http://localhost:5173', 'http://127.0.0.1:5173', 'http://localhost:38080', 'http://localhost:38081', 'http://127.0.0.1:38080', 'http://127.0.0.1:38081'],
112
112
  credentials: true,
113
113
  },
114
114
  }),
@@ -146,7 +146,7 @@ let AgentsService = class AgentsService {
146
146
  if (result.changes > 0) {
147
147
  this.db.persist();
148
148
  }
149
- agentManager.deleteSessionsByBusinessId(sessionId);
149
+ await agentManager.deleteSessionsByBusinessId(sessionId);
150
150
  }
151
151
  getMessageHistory(sessionId) {
152
152
  const rows = this.db.all('SELECT * FROM chat_messages WHERE session_id = ? ORDER BY timestamp ASC', [sessionId]);
@@ -11,5 +11,6 @@ export interface NestAppResult {
11
11
  export declare function createNestAppEmbedded(): Promise<NestAppResult>;
12
12
  /**
13
13
  * 独立启动时使用:设置 globalPrefix 并监听端口。
14
+ * 先执行桌面配置初始化,保证首次启动即有 local provider 与缺省模型。
14
15
  */
15
16
  export declare function createNestAppStandalone(port?: number): Promise<INestApplication>;
@@ -4,7 +4,10 @@
4
4
  * - 独立:设置 globalPrefix('server-api') 并 listen(port),用于单独启动 Desktop Server。
5
5
  */
6
6
  import { NestFactory } from '@nestjs/core';
7
+ import express from 'express';
7
8
  import { AppModule } from './app.module.js';
9
+ import { ensureDesktopConfigInitialized } from '../core/config/desktop-config.js';
10
+ const BODY_LIMIT = '10mb';
8
11
  /**
9
12
  * 创建 Nest 应用(内嵌模式):不 listen,不设置 globalPrefix。
10
13
  * Gateway 将返回的 express 挂到 /server-api,请求路径会剥掉前缀后进入 Nest。
@@ -13,24 +16,45 @@ export async function createNestAppEmbedded() {
13
16
  const app = await NestFactory.create(AppModule, {
14
17
  cors: true,
15
18
  });
19
+ const expressApp = app.getHttpAdapter().getInstance();
20
+ expressApp.use(express.json({ limit: BODY_LIMIT }));
21
+ expressApp.use(express.urlencoded({ extended: true, limit: BODY_LIMIT }));
16
22
  app.enableCors({
17
- origin: ['http://localhost:5173', 'http://localhost:38080', 'http://localhost:38081'],
23
+ origin: [
24
+ 'http://localhost:5173',
25
+ 'http://127.0.0.1:5173',
26
+ 'http://localhost:38080',
27
+ 'http://localhost:38081',
28
+ 'http://127.0.0.1:38080',
29
+ 'http://127.0.0.1:38081',
30
+ ],
18
31
  credentials: true,
19
32
  });
20
33
  await app.init();
21
- const express = app.getHttpAdapter().getInstance();
22
- return { app, express };
34
+ return { app, express: expressApp };
23
35
  }
24
36
  /**
25
37
  * 独立启动时使用:设置 globalPrefix 并监听端口。
38
+ * 先执行桌面配置初始化,保证首次启动即有 local provider 与缺省模型。
26
39
  */
27
40
  export async function createNestAppStandalone(port = 38081) {
41
+ await ensureDesktopConfigInitialized();
28
42
  const app = await NestFactory.create(AppModule, {
29
43
  cors: true,
30
44
  });
45
+ const expressApp = app.getHttpAdapter().getInstance();
46
+ expressApp.use(express.json({ limit: BODY_LIMIT }));
47
+ expressApp.use(express.urlencoded({ extended: true, limit: BODY_LIMIT }));
31
48
  app.setGlobalPrefix('server-api');
32
49
  app.enableCors({
33
- origin: ['http://localhost:5173', 'http://localhost:38080', 'http://localhost:38081'],
50
+ origin: [
51
+ 'http://localhost:5173',
52
+ 'http://127.0.0.1:5173',
53
+ 'http://localhost:38080',
54
+ 'http://localhost:38081',
55
+ 'http://127.0.0.1:38080',
56
+ 'http://127.0.0.1:38081',
57
+ ],
34
58
  credentials: true,
35
59
  });
36
60
  await app.listen(port);
@@ -1,7 +1,9 @@
1
1
  import { ConfigService, AppConfig } from './config.service.js';
2
+ import { LocalModelsService } from './local-models.service.js';
2
3
  export declare class ConfigController {
3
4
  private readonly configService;
4
- constructor(configService: ConfigService);
5
+ private readonly localModelsService;
6
+ constructor(configService: ConfigService, localModelsService: LocalModelsService);
5
7
  getConfig(): Promise<{
6
8
  success: boolean;
7
9
  data: {
@@ -23,10 +25,35 @@ export declare class ConfigController {
23
25
  };
24
26
  configuredModels?: import("./config.service.js").ConfiguredModelItem[];
25
27
  rag?: {
28
+ embeddingSource?: "local" | "online";
29
+ embeddingModelItemCode?: string;
30
+ localModelPath?: string;
26
31
  embeddingProvider?: string;
27
32
  embeddingModel?: string;
33
+ vectorStore?: "local" | "qdrant";
34
+ qdrant?: {
35
+ url: string;
36
+ apiKey?: string;
37
+ collection?: string;
38
+ };
39
+ };
40
+ memory?: {
41
+ embeddingModelItemCode?: string;
28
42
  };
29
43
  channels?: import("../../core/config/desktop-config.js").ChannelsConfig;
44
+ tools?: {
45
+ webSearch?: {
46
+ defaultProvider?: "brave" | "duck-duck-scrape";
47
+ providers?: {
48
+ brave?: {
49
+ apiKey?: string;
50
+ };
51
+ };
52
+ timeoutSeconds?: number;
53
+ cacheTtlMinutes?: number;
54
+ maxResults?: number;
55
+ };
56
+ };
30
57
  };
31
58
  }>;
32
59
  updateConfig(updates: Partial<AppConfig>): Promise<{
@@ -50,10 +77,35 @@ export declare class ConfigController {
50
77
  };
51
78
  configuredModels?: import("./config.service.js").ConfiguredModelItem[];
52
79
  rag?: {
80
+ embeddingSource?: "local" | "online";
81
+ embeddingModelItemCode?: string;
82
+ localModelPath?: string;
53
83
  embeddingProvider?: string;
54
84
  embeddingModel?: string;
85
+ vectorStore?: "local" | "qdrant";
86
+ qdrant?: {
87
+ url: string;
88
+ apiKey?: string;
89
+ collection?: string;
90
+ };
91
+ };
92
+ memory?: {
93
+ embeddingModelItemCode?: string;
55
94
  };
56
95
  channels?: import("../../core/config/desktop-config.js").ChannelsConfig;
96
+ tools?: {
97
+ webSearch?: {
98
+ defaultProvider?: "brave" | "duck-duck-scrape";
99
+ providers?: {
100
+ brave?: {
101
+ apiKey?: string;
102
+ };
103
+ };
104
+ timeoutSeconds?: number;
105
+ cacheTtlMinutes?: number;
106
+ maxResults?: number;
107
+ };
108
+ };
57
109
  };
58
110
  }>;
59
111
  getProviders(): Promise<{
@@ -62,7 +114,7 @@ export declare class ConfigController {
62
114
  }>;
63
115
  getProviderSupport(): Promise<{
64
116
  success: boolean;
65
- data: import("../../index.js").ProviderSupport;
117
+ data: import("../../core/config/provider-support-default.js").ProviderSupport;
66
118
  }>;
67
119
  getModels(provider: string, type?: string): Promise<{
68
120
  success: boolean;
@@ -72,4 +124,84 @@ export declare class ConfigController {
72
124
  types?: string[];
73
125
  }[];
74
126
  }>;
127
+ /** OpenCode 免费/推荐模型列表,供代理配置界面下拉选择(本地/远程模式默认模型) */
128
+ getOpencodeFreeModels(): {
129
+ success: boolean;
130
+ data: import("../../core/agent/proxy/adapters/opencode-free-models.js").OpenCodeFreeModelOption[];
131
+ };
132
+ /** 列出本地已缓存的 GGUF 模型文件 */
133
+ listLocalModels(): Promise<{
134
+ success: boolean;
135
+ data: import("./local-models.service.js").LocalModelInfo[];
136
+ }>;
137
+ /** 推荐的 GGUF 模型列表(来自 preset,与已安装展示名称一致) */
138
+ getRecommendedModels(): Promise<{
139
+ success: boolean;
140
+ data: import("./local-models.service.js").RecommendedModel[];
141
+ }>;
142
+ /** 仅返回尚未安装的推荐模型(已安装的不显示在下载区) */
143
+ getRecommendedToDownload(): Promise<{
144
+ success: boolean;
145
+ data: import("./local-models.service.js").RecommendedModel[];
146
+ }>;
147
+ /** 本地模型服务状态:是否可用、不可用原因、当前 baseUrl */
148
+ getLocalLlmStatus(): {
149
+ success: boolean;
150
+ data: {
151
+ available: boolean;
152
+ error: string | undefined;
153
+ baseUrl: string | undefined;
154
+ };
155
+ };
156
+ /** 启动本地模型服务:LLM/Embedding 任一已下载即可启动,只启动已存在的模型并提示;失败仅返回错误信息不抛错 */
157
+ startLocalLlm(body: {
158
+ llmModelUri?: string;
159
+ embeddingModelUri?: string;
160
+ }): Promise<{
161
+ success: boolean;
162
+ data: {
163
+ error: string;
164
+ baseUrl?: undefined;
165
+ message?: undefined;
166
+ };
167
+ } | {
168
+ success: boolean;
169
+ data: {
170
+ baseUrl: string;
171
+ message: string;
172
+ error?: undefined;
173
+ };
174
+ }>;
175
+ /** 开始后台下载模型(立即返回,进度通过 GET local-models/progress 轮询)。useMirror=true 使用国内镜像。 */
176
+ startDownload(body: {
177
+ modelUri: string;
178
+ useMirror?: boolean;
179
+ }): Promise<{
180
+ success: boolean;
181
+ data: {
182
+ filename: string;
183
+ };
184
+ }>;
185
+ /** 取消指定模型的下载 */
186
+ cancelDownload(body: {
187
+ modelUri: string;
188
+ }): {
189
+ success: boolean;
190
+ };
191
+ /** 推荐模型列表(含是否已安装),用于展示「已下载」或中国/全球下载按钮 */
192
+ getRecommendedWithStatus(): Promise<{
193
+ success: boolean;
194
+ data: (import("./local-models.service.js").RecommendedModel & {
195
+ isInstalled: boolean;
196
+ })[];
197
+ }>;
198
+ /** 查询下载进度 */
199
+ getDownloadProgress(uri: string): {
200
+ success: boolean;
201
+ data: import("./local-models.service.js").DownloadProgress | null;
202
+ };
203
+ /** 删除本地缓存的 GGUF 模型文件 */
204
+ deleteLocalModel(filename: string): Promise<{
205
+ success: boolean;
206
+ }>;
75
207
  }
@@ -10,12 +10,19 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  var __param = (this && this.__param) || function (paramIndex, decorator) {
11
11
  return function (target, key) { decorator(target, key, paramIndex); }
12
12
  };
13
- import { Controller, Get, Put, Body, Param, Query } from '@nestjs/common';
13
+ import { Controller, Get, Put, Body, Param, Query, Delete, Post } from '@nestjs/common';
14
+ import { OPENCODE_FREE_MODELS } from '../../core/agent/proxy/adapters/opencode-free-models.js';
15
+ import { loadDesktopAgentConfig, setDefaultModel } from '../../core/config/desktop-config.js';
16
+ import { startLocalLlmServer, stopLocalLlmServer } from '../../core/local-llm-server/index.js';
17
+ import { resolveModelPathInCache, LOCAL_LLM_CACHE_DIR } from '../../core/local-llm-server/model-resolve.js';
14
18
  import { ConfigService } from './config.service.js';
19
+ import { LocalModelsService } from './local-models.service.js';
15
20
  let ConfigController = class ConfigController {
16
21
  configService;
17
- constructor(configService) {
22
+ localModelsService;
23
+ constructor(configService, localModelsService) {
18
24
  this.configService = configService;
25
+ this.localModelsService = localModelsService;
19
26
  }
20
27
  async getConfig() {
21
28
  const config = await this.configService.getConfig();
@@ -54,6 +61,123 @@ let ConfigController = class ConfigController {
54
61
  data: models,
55
62
  };
56
63
  }
64
+ /** OpenCode 免费/推荐模型列表,供代理配置界面下拉选择(本地/远程模式默认模型) */
65
+ getOpencodeFreeModels() {
66
+ return {
67
+ success: true,
68
+ data: OPENCODE_FREE_MODELS,
69
+ };
70
+ }
71
+ // ─── 本地模型管理(node-llama-cpp GGUF)────────────────────────────────────
72
+ /** 列出本地已缓存的 GGUF 模型文件 */
73
+ async listLocalModels() {
74
+ return { success: true, data: await this.localModelsService.listModels() };
75
+ }
76
+ /** 推荐的 GGUF 模型列表(来自 preset,与已安装展示名称一致) */
77
+ async getRecommendedModels() {
78
+ const data = await this.localModelsService.getRecommendedModels();
79
+ return { success: true, data };
80
+ }
81
+ /** 仅返回尚未安装的推荐模型(已安装的不显示在下载区) */
82
+ async getRecommendedToDownload() {
83
+ const data = await this.localModelsService.getRecommendedToDownload();
84
+ return { success: true, data };
85
+ }
86
+ /** 本地模型服务状态:是否可用、不可用原因、当前 baseUrl */
87
+ getLocalLlmStatus() {
88
+ const baseUrl = process.env.LOCAL_LLM_BASE_URL;
89
+ const error = process.env.LOCAL_LLM_START_FAILED;
90
+ const available = !!baseUrl;
91
+ return {
92
+ success: true,
93
+ data: { available, error: error || undefined, baseUrl: baseUrl || undefined },
94
+ };
95
+ }
96
+ /** 启动本地模型服务:LLM/Embedding 任一已下载即可启动,只启动已存在的模型并提示;失败仅返回错误信息不抛错 */
97
+ async startLocalLlm(body) {
98
+ stopLocalLlmServer();
99
+ delete process.env.LOCAL_LLM_BASE_URL;
100
+ delete process.env.LOCAL_LLM_START_FAILED;
101
+ const llmPath = body.llmModelUri?.trim();
102
+ const embPath = body.embeddingModelUri?.trim();
103
+ if (!llmPath && !embPath) {
104
+ return { success: false, data: { error: '请至少选择 LLM 或 Embedding 模型之一' } };
105
+ }
106
+ const llmResolved = llmPath ? resolveModelPathInCache(llmPath, LOCAL_LLM_CACHE_DIR) : '';
107
+ const embResolved = embPath ? resolveModelPathInCache(embPath, LOCAL_LLM_CACHE_DIR) : '';
108
+ if (!llmResolved && !embResolved) {
109
+ return { success: false, data: { error: '未找到已下载的模型文件,请先在「模型管理」中下载' } };
110
+ }
111
+ if (llmPath) {
112
+ try {
113
+ await setDefaultModel('local', llmPath);
114
+ }
115
+ catch {
116
+ // 保存失败不阻断启动
117
+ }
118
+ }
119
+ let contextSize;
120
+ try {
121
+ const defaultAgent = await loadDesktopAgentConfig('default');
122
+ if (defaultAgent?.contextSize != null && defaultAgent.contextSize > 0) {
123
+ contextSize = defaultAgent.contextSize;
124
+ }
125
+ }
126
+ catch {
127
+ // ignore
128
+ }
129
+ if (contextSize == null) {
130
+ const envMax = process.env.LOCAL_LLM_CONTEXT_MAX;
131
+ contextSize = envMax != null && String(envMax).trim() !== '' ? parseInt(envMax, 10) || 32768 : 32768;
132
+ }
133
+ const opts = {
134
+ ...(llmResolved ? { llmModelPath: llmResolved } : {}),
135
+ ...(embResolved ? { embeddingModelPath: embResolved } : {}),
136
+ contextSize,
137
+ };
138
+ try {
139
+ const handle = await startLocalLlmServer(opts);
140
+ process.env.LOCAL_LLM_BASE_URL = handle.baseUrl;
141
+ const message = llmResolved && embResolved
142
+ ? '已启动 LLM + Embedding'
143
+ : llmResolved
144
+ ? '已启动 LLM 模型(当前未使用 Embedding)'
145
+ : '已启动 Embedding 模型(当前未使用 LLM)';
146
+ return { success: true, data: { baseUrl: handle.baseUrl, message } };
147
+ }
148
+ catch (e) {
149
+ const msg = e instanceof Error ? e.message : String(e);
150
+ process.env.LOCAL_LLM_START_FAILED = msg;
151
+ return { success: false, data: { error: msg } };
152
+ }
153
+ }
154
+ /** 开始后台下载模型(立即返回,进度通过 GET local-models/progress 轮询)。useMirror=true 使用国内镜像。 */
155
+ async startDownload(body) {
156
+ const result = await this.localModelsService.startDownload(body.modelUri, {
157
+ useMirror: body.useMirror === true,
158
+ });
159
+ return { success: true, data: result };
160
+ }
161
+ /** 取消指定模型的下载 */
162
+ cancelDownload(body) {
163
+ this.localModelsService.cancelDownload(body.modelUri);
164
+ return { success: true };
165
+ }
166
+ /** 推荐模型列表(含是否已安装),用于展示「已下载」或中国/全球下载按钮 */
167
+ async getRecommendedWithStatus() {
168
+ const models = await this.localModelsService.getRecommendedWithStatus();
169
+ return { success: true, data: models };
170
+ }
171
+ /** 查询下载进度 */
172
+ getDownloadProgress(uri) {
173
+ const progress = this.localModelsService.getDownloadProgress(uri);
174
+ return { success: true, data: progress };
175
+ }
176
+ /** 删除本地缓存的 GGUF 模型文件 */
177
+ async deleteLocalModel(filename) {
178
+ await this.localModelsService.deleteModel(filename);
179
+ return { success: true };
180
+ }
57
181
  };
58
182
  __decorate([
59
183
  Get(),
@@ -88,8 +212,80 @@ __decorate([
88
212
  __metadata("design:paramtypes", [String, String]),
89
213
  __metadata("design:returntype", Promise)
90
214
  ], ConfigController.prototype, "getModels", null);
215
+ __decorate([
216
+ Get('opencode-free-models'),
217
+ __metadata("design:type", Function),
218
+ __metadata("design:paramtypes", []),
219
+ __metadata("design:returntype", void 0)
220
+ ], ConfigController.prototype, "getOpencodeFreeModels", null);
221
+ __decorate([
222
+ Get('local-models'),
223
+ __metadata("design:type", Function),
224
+ __metadata("design:paramtypes", []),
225
+ __metadata("design:returntype", Promise)
226
+ ], ConfigController.prototype, "listLocalModels", null);
227
+ __decorate([
228
+ Get('local-models/recommended'),
229
+ __metadata("design:type", Function),
230
+ __metadata("design:paramtypes", []),
231
+ __metadata("design:returntype", Promise)
232
+ ], ConfigController.prototype, "getRecommendedModels", null);
233
+ __decorate([
234
+ Get('local-models/recommended-to-download'),
235
+ __metadata("design:type", Function),
236
+ __metadata("design:paramtypes", []),
237
+ __metadata("design:returntype", Promise)
238
+ ], ConfigController.prototype, "getRecommendedToDownload", null);
239
+ __decorate([
240
+ Get('local-models/status'),
241
+ __metadata("design:type", Function),
242
+ __metadata("design:paramtypes", []),
243
+ __metadata("design:returntype", void 0)
244
+ ], ConfigController.prototype, "getLocalLlmStatus", null);
245
+ __decorate([
246
+ Post('local-models/start'),
247
+ __param(0, Body()),
248
+ __metadata("design:type", Function),
249
+ __metadata("design:paramtypes", [Object]),
250
+ __metadata("design:returntype", Promise)
251
+ ], ConfigController.prototype, "startLocalLlm", null);
252
+ __decorate([
253
+ Post('local-models/download'),
254
+ __param(0, Body()),
255
+ __metadata("design:type", Function),
256
+ __metadata("design:paramtypes", [Object]),
257
+ __metadata("design:returntype", Promise)
258
+ ], ConfigController.prototype, "startDownload", null);
259
+ __decorate([
260
+ Post('local-models/cancel-download'),
261
+ __param(0, Body()),
262
+ __metadata("design:type", Function),
263
+ __metadata("design:paramtypes", [Object]),
264
+ __metadata("design:returntype", void 0)
265
+ ], ConfigController.prototype, "cancelDownload", null);
266
+ __decorate([
267
+ Get('local-models/recommended-with-status'),
268
+ __metadata("design:type", Function),
269
+ __metadata("design:paramtypes", []),
270
+ __metadata("design:returntype", Promise)
271
+ ], ConfigController.prototype, "getRecommendedWithStatus", null);
272
+ __decorate([
273
+ Get('local-models/progress'),
274
+ __param(0, Query('uri')),
275
+ __metadata("design:type", Function),
276
+ __metadata("design:paramtypes", [String]),
277
+ __metadata("design:returntype", void 0)
278
+ ], ConfigController.prototype, "getDownloadProgress", null);
279
+ __decorate([
280
+ Delete('local-models/:filename'),
281
+ __param(0, Param('filename')),
282
+ __metadata("design:type", Function),
283
+ __metadata("design:paramtypes", [String]),
284
+ __metadata("design:returntype", Promise)
285
+ ], ConfigController.prototype, "deleteLocalModel", null);
91
286
  ConfigController = __decorate([
92
287
  Controller('config'),
93
- __metadata("design:paramtypes", [ConfigService])
288
+ __metadata("design:paramtypes", [ConfigService,
289
+ LocalModelsService])
94
290
  ], ConfigController);
95
291
  export { ConfigController };
@@ -4,18 +4,19 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { Module } from '@nestjs/common';
7
+ import { Module, forwardRef } from '@nestjs/common';
8
8
  import { ConfigController } from './config.controller.js';
9
9
  import { ConfigService } from './config.service.js';
10
+ import { LocalModelsService } from './local-models.service.js';
10
11
  import { AgentConfigModule } from '../agent-config/agent-config.module.js';
11
12
  let ConfigModule = class ConfigModule {
12
13
  };
13
14
  ConfigModule = __decorate([
14
15
  Module({
15
- imports: [AgentConfigModule],
16
+ imports: [forwardRef(() => AgentConfigModule)],
16
17
  controllers: [ConfigController],
17
- providers: [ConfigService],
18
- exports: [ConfigService],
18
+ providers: [ConfigService, LocalModelsService],
19
+ exports: [ConfigService, LocalModelsService],
19
20
  })
20
21
  ], ConfigModule);
21
22
  export { ConfigModule };
@@ -51,24 +51,54 @@ export interface AppConfig {
51
51
  };
52
52
  /** 已配置的模型列表(备用),从该列表中选一个为缺省模型 */
53
53
  configuredModels?: ConfiguredModelItem[];
54
- /** RAG 知识库:embedding 使用该 provider+model,未配置时基于 RAG 的长记忆空转 */
54
+ /** RAG 知识库:向量模型(本地/在线)+ 向量库(本地/远程 Qdrant) */
55
55
  rag?: {
56
+ embeddingSource?: 'local' | 'online';
57
+ embeddingModelItemCode?: string;
58
+ localModelPath?: string;
56
59
  embeddingProvider?: string;
57
60
  embeddingModel?: string;
61
+ vectorStore?: 'local' | 'qdrant';
62
+ qdrant?: {
63
+ url: string;
64
+ apiKey?: string;
65
+ collection?: string;
66
+ };
67
+ };
68
+ /** Memory 记忆库:为 Agent 提供默认嵌入模型 */
69
+ memory?: {
70
+ embeddingModelItemCode?: string;
58
71
  };
59
72
  /** 通道配置:飞书、Telegram 等 token/key */
60
73
  channels?: ChannelsConfig;
74
+ /** 工具相关:在线搜索等,Brave API Key 存于 providers.brave.apiKey */
75
+ tools?: {
76
+ webSearch?: {
77
+ defaultProvider?: 'brave' | 'duck-duck-scrape';
78
+ providers?: {
79
+ brave?: {
80
+ apiKey?: string;
81
+ };
82
+ };
83
+ timeoutSeconds?: number;
84
+ cacheTtlMinutes?: number;
85
+ maxResults?: number;
86
+ };
87
+ };
61
88
  }
62
89
  export declare class ConfigService {
63
90
  private readonly agentConfigService;
64
91
  private configPath;
65
92
  private config;
66
93
  constructor(agentConfigService: AgentConfigService);
94
+ /** 预装本地推理缺省:与 desktop-config 的 DEFAULT_LOCAL_LLM_MODEL_ID / DEFAULT_LOCAL_MODEL_ITEM_CODE 一致 */
95
+ private static readonly DEFAULT_LOCAL_MODEL_ID;
96
+ private static readonly DEFAULT_LOCAL_MODEL_ITEM_CODE;
67
97
  private getDefaultConfig;
68
98
  /** 当前缺省智能体 id */
69
99
  getDefaultAgentId(config?: AppConfig): string;
70
100
  private loadConfig;
71
- /** 每次获取前从磁盘重新读取,保证打开配置界面时显示最新(含 CLI 写入的配置) */
101
+ /** 每次获取前从磁盘重新读取,保证打开配置界面时显示最新(含 CLI 写入的配置)。本地 LLM 可用时注入 local 与缺省模型项;OLLAMA_BASE_URL 时注入 ollama baseUrl(如与 Ollama 同栈)。 */
72
102
  getConfig(): Promise<AppConfig>;
73
103
  updateConfig(updates: Partial<AppConfig>): Promise<AppConfig>;
74
104
  private saveConfig;