@next-open-ai/openclawx 0.8.48 → 0.8.58
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/apps/desktop/renderer/dist/assets/index-M5VGUUpo.js +93 -0
- package/apps/desktop/renderer/dist/assets/{index-BHY1xIZQ.css → index-y8oE2q_u.css} +1 -1
- package/apps/desktop/renderer/dist/index.html +2 -2
- package/dist/cli/cli.js +107 -0
- package/dist/core/agent/agent-manager.js +4 -0
- package/dist/core/config/desktop-config.d.ts +2 -1
- package/dist/core/config/desktop-config.js +92 -26
- 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.js +26 -5
- package/dist/core/local-llm-server/llm-context.d.ts +9 -4
- package/dist/core/local-llm-server/llm-context.js +35 -14
- package/dist/core/local-llm-server/model-resolve.d.ts +8 -1
- package/dist/core/local-llm-server/model-resolve.js +44 -12
- package/dist/core/local-llm-server/server.js +11 -12
- 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/transport/stdio.d.ts +6 -0
- package/dist/core/mcp/transport/stdio.js +107 -27
- package/dist/core/memory/local-embedding-llama.js +2 -4
- package/dist/gateway/methods/agent-chat.js +9 -0
- package/dist/gateway/server.js +8 -51
- package/dist/server/bootstrap.d.ts +1 -0
- package/dist/server/bootstrap.js +3 -0
- package/dist/server/config/config.controller.d.ts +25 -2
- package/dist/server/config/config.controller.js +62 -12
- package/dist/server/config/config.service.d.ts +4 -1
- package/dist/server/config/config.service.js +62 -9
- package/dist/server/config/local-models.service.d.ts +16 -1
- package/dist/server/config/local-models.service.js +78 -46
- package/package.json +1 -1
- package/presets/preset-agents.json +6 -2
- package/presets/preset-config.json +24 -6
- package/apps/desktop/renderer/dist/assets/index-DQxlVuBe.js +0 -93
- package/presets/workspaces/finance-expert/skills/akshare-helper/SKILL.md +0 -9
|
@@ -7,14 +7,16 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
9
|
};
|
|
10
|
+
var ConfigService_1;
|
|
10
11
|
import { Injectable } from '@nestjs/common';
|
|
11
12
|
import { readFile, writeFile, mkdir } from 'fs/promises';
|
|
12
|
-
import { join } from 'path';
|
|
13
|
+
import { join, dirname } from 'path';
|
|
13
14
|
import { existsSync } from 'fs';
|
|
14
15
|
import { homedir } from 'os';
|
|
15
16
|
import { getProviderSupport, syncDesktopConfigToModelsJson } from '../../core/config/desktop-config.js';
|
|
16
17
|
import { AgentConfigService } from '../agent-config/agent-config.service.js';
|
|
17
18
|
let ConfigService = class ConfigService {
|
|
19
|
+
static { ConfigService_1 = this; }
|
|
18
20
|
agentConfigService;
|
|
19
21
|
configPath;
|
|
20
22
|
config;
|
|
@@ -30,16 +32,30 @@ let ConfigService = class ConfigService {
|
|
|
30
32
|
this.config = this.getDefaultConfig();
|
|
31
33
|
this.loadConfig();
|
|
32
34
|
}
|
|
35
|
+
/** 预装本地推理缺省:与 desktop-config 的 DEFAULT_LOCAL_LLM_MODEL_ID / DEFAULT_LOCAL_MODEL_ITEM_CODE 一致 */
|
|
36
|
+
static DEFAULT_LOCAL_MODEL_ID = 'hf_Qwen_Qwen3-4B-GGUF_Qwen3-4B-Q4_K_M.gguf';
|
|
37
|
+
static DEFAULT_LOCAL_MODEL_ITEM_CODE = 'local-qwen3-4b';
|
|
33
38
|
getDefaultConfig() {
|
|
34
39
|
return {
|
|
35
40
|
gatewayUrl: 'ws://localhost:38080',
|
|
36
|
-
defaultProvider: '
|
|
37
|
-
defaultModel:
|
|
41
|
+
defaultProvider: 'local',
|
|
42
|
+
defaultModel: ConfigService_1.DEFAULT_LOCAL_MODEL_ID,
|
|
43
|
+
defaultModelItemCode: ConfigService_1.DEFAULT_LOCAL_MODEL_ITEM_CODE,
|
|
38
44
|
defaultAgentId: 'default',
|
|
39
45
|
theme: 'dark',
|
|
40
46
|
maxAgentSessions: 5,
|
|
41
|
-
providers: {
|
|
42
|
-
|
|
47
|
+
providers: {
|
|
48
|
+
local: { baseUrl: 'http://127.0.0.1:11435/v1' },
|
|
49
|
+
},
|
|
50
|
+
configuredModels: [
|
|
51
|
+
{
|
|
52
|
+
provider: 'local',
|
|
53
|
+
modelId: ConfigService_1.DEFAULT_LOCAL_MODEL_ID,
|
|
54
|
+
modelItemCode: ConfigService_1.DEFAULT_LOCAL_MODEL_ITEM_CODE,
|
|
55
|
+
type: 'llm',
|
|
56
|
+
alias: 'Qwen3 4B Q4_K_M',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
43
59
|
rag: undefined,
|
|
44
60
|
memory: {},
|
|
45
61
|
channels: {},
|
|
@@ -54,18 +70,54 @@ let ConfigService = class ConfigService {
|
|
|
54
70
|
try {
|
|
55
71
|
if (existsSync(this.configPath)) {
|
|
56
72
|
const content = await readFile(this.configPath, 'utf-8');
|
|
57
|
-
|
|
73
|
+
const parsed = JSON.parse(content);
|
|
74
|
+
this.config = { ...this.getDefaultConfig(), ...parsed };
|
|
58
75
|
this.config.defaultAgentId = this.getDefaultAgentId(this.config);
|
|
76
|
+
// 保证 local 与缺省本地模型始终存在,避免旧配置或空配置覆盖产品默认
|
|
77
|
+
const def = this.getDefaultConfig();
|
|
78
|
+
if (!this.config.providers?.local) {
|
|
79
|
+
this.config.providers = { ...(this.config.providers || {}), local: def.providers.local };
|
|
80
|
+
}
|
|
81
|
+
if (!(this.config.configuredModels || []).some((m) => m.provider === 'local')) {
|
|
82
|
+
this.config.configuredModels = [...(def.configuredModels || []), ...(this.config.configuredModels || [])];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.config = this.getDefaultConfig();
|
|
87
|
+
await this.saveConfig();
|
|
59
88
|
}
|
|
60
89
|
}
|
|
61
90
|
catch (error) {
|
|
62
91
|
console.error('Error loading config:', error);
|
|
63
92
|
}
|
|
64
93
|
}
|
|
65
|
-
/** 每次获取前从磁盘重新读取,保证打开配置界面时显示最新(含 CLI
|
|
94
|
+
/** 每次获取前从磁盘重新读取,保证打开配置界面时显示最新(含 CLI 写入的配置)。本地 LLM 可用时注入 local 与缺省模型项,供所有智能体使用。 */
|
|
66
95
|
async getConfig() {
|
|
67
96
|
await this.loadConfig();
|
|
68
|
-
|
|
97
|
+
const baseUrl = process.env.LOCAL_LLM_BASE_URL?.trim();
|
|
98
|
+
if (!baseUrl)
|
|
99
|
+
return this.config;
|
|
100
|
+
const out = { ...this.config };
|
|
101
|
+
out.providers = { ...(this.config.providers || {}) };
|
|
102
|
+
if (!out.providers['local']) {
|
|
103
|
+
out.providers['local'] = { baseUrl: baseUrl || 'http://127.0.0.1:11435/v1' };
|
|
104
|
+
}
|
|
105
|
+
else if (!out.providers['local'].baseUrl?.trim()) {
|
|
106
|
+
out.providers['local'] = { ...out.providers['local'], baseUrl: baseUrl || 'http://127.0.0.1:11435/v1' };
|
|
107
|
+
}
|
|
108
|
+
const list = [...(out.configuredModels || [])];
|
|
109
|
+
const hasLocal = list.some((m) => m.provider === 'local' && m.modelId === 'local-llm');
|
|
110
|
+
if (!hasLocal) {
|
|
111
|
+
list.push({
|
|
112
|
+
provider: 'local',
|
|
113
|
+
modelId: 'local-llm',
|
|
114
|
+
modelItemCode: 'local-llm',
|
|
115
|
+
type: 'llm',
|
|
116
|
+
alias: '本地 LLM(当前加载)',
|
|
117
|
+
});
|
|
118
|
+
out.configuredModels = list;
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
69
121
|
}
|
|
70
122
|
async updateConfig(updates) {
|
|
71
123
|
this.config = { ...this.config, ...updates };
|
|
@@ -85,6 +137,7 @@ let ConfigService = class ConfigService {
|
|
|
85
137
|
}
|
|
86
138
|
async saveConfig() {
|
|
87
139
|
try {
|
|
140
|
+
await mkdir(dirname(this.configPath), { recursive: true });
|
|
88
141
|
await writeFile(this.configPath, JSON.stringify(this.config, null, 2));
|
|
89
142
|
}
|
|
90
143
|
catch (error) {
|
|
@@ -119,7 +172,7 @@ let ConfigService = class ConfigService {
|
|
|
119
172
|
return getProviderSupport();
|
|
120
173
|
}
|
|
121
174
|
};
|
|
122
|
-
ConfigService = __decorate([
|
|
175
|
+
ConfigService = ConfigService_1 = __decorate([
|
|
123
176
|
Injectable(),
|
|
124
177
|
__metadata("design:paramtypes", [AgentConfigService])
|
|
125
178
|
], ConfigService);
|
|
@@ -39,13 +39,28 @@ export declare class LocalModelsService {
|
|
|
39
39
|
getRecommendedToDownload(): Promise<RecommendedModel[]>;
|
|
40
40
|
/** 检查指定模型(uri 或文件名)是否已在缓存目录存在 */
|
|
41
41
|
isModelFilePresent(modelIdOrUri: string): boolean;
|
|
42
|
+
/** 正在下载任务的 AbortController,用于取消 */
|
|
43
|
+
private abortControllerMap;
|
|
42
44
|
/** 获取某个 modelUri 的下载进度(不存在则表示未在下载) */
|
|
43
45
|
getDownloadProgress(modelUri: string): DownloadProgress | null;
|
|
46
|
+
/**
|
|
47
|
+
* 取消指定 modelUri 的下载(若正在下载)。
|
|
48
|
+
*/
|
|
49
|
+
cancelDownload(modelUri: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* 返回所有推荐模型及是否已安装,用于前端展示「已下载」或下载按钮。
|
|
52
|
+
*/
|
|
53
|
+
getRecommendedWithStatus(): Promise<Array<RecommendedModel & {
|
|
54
|
+
isInstalled: boolean;
|
|
55
|
+
}>>;
|
|
44
56
|
/**
|
|
45
57
|
* 后台下载模型(通过 node-llama-cpp resolveModelFile)。
|
|
58
|
+
* useMirror=true 使用国内镜像 hf-mirror.com,false 使用官方 huggingface.co。
|
|
46
59
|
* 返回后立即响应,进度通过 getDownloadProgress 轮询获取。
|
|
47
60
|
*/
|
|
48
|
-
startDownload(modelUri: string
|
|
61
|
+
startDownload(modelUri: string, options?: {
|
|
62
|
+
useMirror?: boolean;
|
|
63
|
+
}): Promise<{
|
|
49
64
|
filename: string;
|
|
50
65
|
}>;
|
|
51
66
|
private runDownload;
|
|
@@ -11,14 +11,13 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
11
11
|
* 本地 GGUF 模型管理服务。
|
|
12
12
|
* 负责列出、下载(通过 node-llama-cpp resolveModelFile)、删除本地缓存的 GGUF 模型文件。
|
|
13
13
|
* 推荐列表从 presets/recommended-local-models.json 加载,已安装的与推荐使用同一套展示名称且已安装的不再出现在「备下载」列表。
|
|
14
|
-
* 模型缓存目录:~/.
|
|
14
|
+
* 模型缓存目录:~/.openbot/.cached_models/
|
|
15
15
|
*/
|
|
16
16
|
import { Injectable } from '@nestjs/common';
|
|
17
17
|
import { readdir, stat, unlink, readFile } from 'node:fs/promises';
|
|
18
18
|
import { join, basename } from 'node:path';
|
|
19
|
-
import { homedir } from 'node:os';
|
|
20
19
|
import { existsSync, mkdirSync } from 'node:fs';
|
|
21
|
-
import { modelUriToFilename, modelUriBasename } from '../../core/local-llm-server/model-resolve.js';
|
|
20
|
+
import { modelUriToFilename, modelUriBasename, LOCAL_LLM_CACHE_DIR } from '../../core/local-llm-server/model-resolve.js';
|
|
22
21
|
/** 根据文件名推断模型类型 */
|
|
23
22
|
function inferModelType(filename) {
|
|
24
23
|
const lower = filename.toLowerCase();
|
|
@@ -64,7 +63,7 @@ let LocalModelsService = class LocalModelsService {
|
|
|
64
63
|
/** 正在下载的任务:modelUri → 进度 */
|
|
65
64
|
downloadingMap = new Map();
|
|
66
65
|
constructor() {
|
|
67
|
-
this.cacheDir =
|
|
66
|
+
this.cacheDir = LOCAL_LLM_CACHE_DIR;
|
|
68
67
|
if (!existsSync(this.cacheDir)) {
|
|
69
68
|
mkdirSync(this.cacheDir, { recursive: true });
|
|
70
69
|
}
|
|
@@ -144,64 +143,97 @@ let LocalModelsService = class LocalModelsService {
|
|
|
144
143
|
return false;
|
|
145
144
|
return existsSync(join(this.cacheDir, filename));
|
|
146
145
|
}
|
|
146
|
+
/** 正在下载任务的 AbortController,用于取消 */
|
|
147
|
+
abortControllerMap = new Map();
|
|
147
148
|
/** 获取某个 modelUri 的下载进度(不存在则表示未在下载) */
|
|
148
149
|
getDownloadProgress(modelUri) {
|
|
149
150
|
return this.downloadingMap.get(modelUri) ?? null;
|
|
150
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* 取消指定 modelUri 的下载(若正在下载)。
|
|
154
|
+
*/
|
|
155
|
+
cancelDownload(modelUri) {
|
|
156
|
+
const controller = this.abortControllerMap.get(modelUri);
|
|
157
|
+
if (controller) {
|
|
158
|
+
controller.abort();
|
|
159
|
+
this.downloadingMap.set(modelUri, { status: '已取消' });
|
|
160
|
+
this.abortControllerMap.delete(modelUri);
|
|
161
|
+
setTimeout(() => this.downloadingMap.delete(modelUri), 3000);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* 返回所有推荐模型及是否已安装,用于前端展示「已下载」或下载按钮。
|
|
166
|
+
*/
|
|
167
|
+
async getRecommendedWithStatus() {
|
|
168
|
+
const [recommended, installed] = await Promise.all([
|
|
169
|
+
this.getRecommendedModelsFromPreset(),
|
|
170
|
+
this.listModels(),
|
|
171
|
+
]);
|
|
172
|
+
const installedFilenames = new Set(installed.map((m) => m.filename));
|
|
173
|
+
return recommended.map((rec) => ({
|
|
174
|
+
...rec,
|
|
175
|
+
isInstalled: recommendedMatchesInstalled(rec, installedFilenames),
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
151
178
|
/**
|
|
152
179
|
* 后台下载模型(通过 node-llama-cpp resolveModelFile)。
|
|
180
|
+
* useMirror=true 使用国内镜像 hf-mirror.com,false 使用官方 huggingface.co。
|
|
153
181
|
* 返回后立即响应,进度通过 getDownloadProgress 轮询获取。
|
|
154
182
|
*/
|
|
155
|
-
async startDownload(modelUri) {
|
|
183
|
+
async startDownload(modelUri, options) {
|
|
156
184
|
if (this.downloadingMap.has(modelUri)) {
|
|
157
|
-
// 已在下载中,返回预期文件名
|
|
158
185
|
return { filename: modelUriToFilename(modelUri) };
|
|
159
186
|
}
|
|
187
|
+
const controller = new AbortController();
|
|
188
|
+
this.abortControllerMap.set(modelUri, controller);
|
|
160
189
|
this.downloadingMap.set(modelUri, { status: '准备下载...' });
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
190
|
+
this.runDownload(modelUri, controller.signal, options?.useMirror === true).catch((e) => {
|
|
191
|
+
if (e?.name === 'AbortError' || (typeof e?.message === 'string' && e.message.includes('abort'))) {
|
|
192
|
+
this.downloadingMap.set(modelUri, { status: '已取消' });
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
196
|
+
let errorMsg = `失败: ${msg}`;
|
|
197
|
+
if (msg.includes('401') || msg.includes('Unauthorized')) {
|
|
198
|
+
errorMsg = '下载失败: 需要 Hugging Face Token。请设置环境变量 HF_TOKEN 或 HUGGING_FACE_TOKEN';
|
|
199
|
+
}
|
|
200
|
+
this.downloadingMap.set(modelUri, { status: errorMsg });
|
|
201
|
+
}
|
|
202
|
+
this.abortControllerMap.delete(modelUri);
|
|
203
|
+
setTimeout(() => this.downloadingMap.delete(modelUri), 5000);
|
|
164
204
|
});
|
|
165
205
|
return { filename: modelUriToFilename(modelUri) };
|
|
166
206
|
}
|
|
167
|
-
async runDownload(modelUri) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
this.downloadingMap.set(modelUri, { status: `完成: ${filename}`, percent: 100 });
|
|
192
|
-
// 5 秒后清除进度记录
|
|
193
|
-
setTimeout(() => this.downloadingMap.delete(modelUri), 5000);
|
|
194
|
-
}
|
|
195
|
-
catch (e) {
|
|
196
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
197
|
-
let errorMsg = `失败: ${msg}`;
|
|
198
|
-
// 如果是 401 错误,提供更友好的提示
|
|
199
|
-
if (msg.includes('401') || msg.includes('Unauthorized')) {
|
|
200
|
-
errorMsg = '下载失败: 需要 Hugging Face Token。请设置环境变量 HF_TOKEN 或 HUGGING_FACE_TOKEN';
|
|
201
|
-
}
|
|
202
|
-
this.downloadingMap.set(modelUri, { status: errorMsg });
|
|
203
|
-
throw e;
|
|
207
|
+
async runDownload(modelUri, signal, useMirror) {
|
|
208
|
+
const { resolveModelFile } = await import('node-llama-cpp');
|
|
209
|
+
this.downloadingMap.set(modelUri, { status: '解析模型地址...' });
|
|
210
|
+
const hfToken = process.env.HF_TOKEN || process.env.HUGGING_FACE_TOKEN;
|
|
211
|
+
const options = {
|
|
212
|
+
directory: this.cacheDir,
|
|
213
|
+
onProgress: ({ downloadedSize, totalSize }) => {
|
|
214
|
+
if (signal?.aborted)
|
|
215
|
+
return;
|
|
216
|
+
const percent = totalSize ? Math.round((downloadedSize / totalSize) * 100) : 0;
|
|
217
|
+
this.downloadingMap.set(modelUri, {
|
|
218
|
+
status: '下载中',
|
|
219
|
+
completed: downloadedSize,
|
|
220
|
+
total: totalSize,
|
|
221
|
+
percent,
|
|
222
|
+
});
|
|
223
|
+
},
|
|
224
|
+
signal,
|
|
225
|
+
endpoints: {
|
|
226
|
+
huggingFace: useMirror ? 'https://hf-mirror.com/' : 'https://huggingface.co/',
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
if (hfToken) {
|
|
230
|
+
options.headers = { Authorization: `Bearer ${hfToken}` };
|
|
204
231
|
}
|
|
232
|
+
const resolved = await resolveModelFile(modelUri, options);
|
|
233
|
+
const filename = basename(resolved);
|
|
234
|
+
this.downloadingMap.set(modelUri, { status: `完成: ${filename}`, percent: 100 });
|
|
235
|
+
this.abortControllerMap.delete(modelUri);
|
|
236
|
+
setTimeout(() => this.downloadingMap.delete(modelUri), 5000);
|
|
205
237
|
}
|
|
206
238
|
};
|
|
207
239
|
LocalModelsService = __decorate([
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.8.
|
|
6
|
+
"version": "0.8.58",
|
|
7
7
|
"description": "OpenClawX - A professional desktop application for managing and executing AI agents with real-time chat, session management, and skills browsing.",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "dist/index.js",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"useLongMemory": true,
|
|
69
69
|
"mcpServers": {
|
|
70
70
|
"akshare-tools": {
|
|
71
|
-
"command": "
|
|
71
|
+
"command": "uvx",
|
|
72
72
|
"args": ["-y", "akshare-tools"],
|
|
73
73
|
"env": {}
|
|
74
74
|
}
|
|
@@ -107,7 +107,11 @@
|
|
|
107
107
|
"影刀 RPA MCP Server": {
|
|
108
108
|
"command": "npx",
|
|
109
109
|
"args": ["-y", "yingdao-mcp-server"],
|
|
110
|
-
"env": {
|
|
110
|
+
"env": {
|
|
111
|
+
"RPA_MODEL": "qwen3-4b-q4_k_m",
|
|
112
|
+
"SHADOWBOT_PATH": "/Applications/影刀.app",
|
|
113
|
+
"USER_FOLDER": "/Users/ctrip/Library/Application Support/Shadowbot/users/718771925823332354"
|
|
114
|
+
}
|
|
111
115
|
}
|
|
112
116
|
}
|
|
113
117
|
},
|
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"presetVersion": "1.0",
|
|
3
3
|
"config": {
|
|
4
|
-
"defaultProvider": "
|
|
5
|
-
"defaultModel": "
|
|
4
|
+
"defaultProvider": "local",
|
|
5
|
+
"defaultModel": "hf_Qwen_Qwen3-4B-GGUF_Qwen3-4B-Q4_K_M.gguf",
|
|
6
|
+
"defaultModelItemCode": "local-qwen3-4b",
|
|
6
7
|
"defaultAgentId": "default",
|
|
7
|
-
"maxAgentSessions":
|
|
8
|
-
"providers": {
|
|
9
|
-
|
|
8
|
+
"maxAgentSessions": 5,
|
|
9
|
+
"providers": {
|
|
10
|
+
"local": { "baseUrl": "http://127.0.0.1:11435/v1" }
|
|
11
|
+
},
|
|
12
|
+
"configuredModels": [
|
|
13
|
+
{
|
|
14
|
+
"provider": "local",
|
|
15
|
+
"modelId": "hf_Qwen_Qwen3-4B-GGUF_Qwen3-4B-Q4_K_M.gguf",
|
|
16
|
+
"type": "llm",
|
|
17
|
+
"alias": "Qwen3 4B Q4_K_M",
|
|
18
|
+
"modelItemCode": "local-qwen3-4b"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"provider": "local",
|
|
22
|
+
"modelId": "hf_ggml-org_embeddinggemma-300M-GGUF_embeddinggemma-300M-Q8_0.gguf",
|
|
23
|
+
"type": "embedding",
|
|
24
|
+
"alias": "EmbeddingGemma 300M Q8 (768维)",
|
|
25
|
+
"modelItemCode": "local-embeddinggemma-300m"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
10
28
|
}
|
|
11
|
-
}
|
|
29
|
+
}
|