opc-agent 4.2.13 → 5.0.0-rc.1
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/.opc/memory.db +0 -0
- package/.opc/schedules.json +784 -0
- package/.opc/voice-tmp/tts-1776835848670.mp3 +0 -0
- package/.opc/voice-tmp/tts-1776835873696.mp3 +0 -0
- package/README.md +125 -141
- package/README.zh-CN.md +75 -160
- package/TASK.md +34 -0
- package/data/brain.db/deepbrain.sqlite +0 -0
- package/dist/channels/api.d.ts +14 -0
- package/dist/channels/api.d.ts.map +1 -0
- package/dist/channels/api.js +58 -0
- package/dist/channels/api.js.map +1 -0
- package/dist/channels/voice.d.ts +21 -0
- package/dist/channels/voice.d.ts.map +1 -1
- package/dist/channels/voice.js +31 -1
- package/dist/channels/voice.js.map +1 -1
- package/dist/cli/chat.d.ts.map +1 -1
- package/dist/cli/chat.js +104 -0
- package/dist/cli/chat.js.map +1 -1
- package/dist/cli/setup.d.ts +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +263 -33
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli.js +201 -116
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-loop.d.ts +3 -0
- package/dist/core/agent-loop.d.ts.map +1 -0
- package/dist/core/agent-loop.js +51 -0
- package/dist/core/agent-loop.js.map +1 -0
- package/dist/core/context-assembler.d.ts +12 -0
- package/dist/core/context-assembler.d.ts.map +1 -0
- package/dist/core/context-assembler.js +81 -0
- package/dist/core/context-assembler.js.map +1 -0
- package/dist/core/guardrails.d.ts +16 -0
- package/dist/core/guardrails.d.ts.map +1 -0
- package/dist/core/guardrails.js +62 -0
- package/dist/core/guardrails.js.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/iteration-budget.d.ts +12 -0
- package/dist/core/iteration-budget.d.ts.map +1 -0
- package/dist/core/iteration-budget.js +26 -0
- package/dist/core/iteration-budget.js.map +1 -0
- package/dist/core/runtime.js +1 -1
- package/dist/core/runtime.js.map +1 -1
- package/dist/core/types.d.ts +412 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/deepbrain/embedding.d.ts +7 -0
- package/dist/deepbrain/embedding.d.ts.map +1 -0
- package/dist/deepbrain/embedding.js +108 -0
- package/dist/deepbrain/embedding.js.map +1 -0
- package/dist/deepbrain/index.d.ts +8 -0
- package/dist/deepbrain/index.d.ts.map +1 -0
- package/dist/deepbrain/index.js +19 -0
- package/dist/deepbrain/index.js.map +1 -0
- package/dist/deepbrain/migrate.d.ts +2 -0
- package/dist/deepbrain/migrate.d.ts.map +1 -0
- package/dist/deepbrain/migrate.js +139 -0
- package/dist/deepbrain/migrate.js.map +1 -0
- package/dist/deepbrain/provider.d.ts +13 -0
- package/dist/deepbrain/provider.d.ts.map +1 -0
- package/dist/deepbrain/provider.js +85 -0
- package/dist/deepbrain/provider.js.map +1 -0
- package/dist/deepbrain/recall.d.ts +9 -0
- package/dist/deepbrain/recall.d.ts.map +1 -0
- package/dist/deepbrain/recall.js +48 -0
- package/dist/deepbrain/recall.js.map +1 -0
- package/dist/deepbrain/store.d.ts +36 -0
- package/dist/deepbrain/store.d.ts.map +1 -0
- package/dist/deepbrain/store.js +342 -0
- package/dist/deepbrain/store.js.map +1 -0
- package/dist/deepbrain/workspace-files.d.ts +5 -0
- package/dist/deepbrain/workspace-files.d.ts.map +1 -0
- package/dist/deepbrain/workspace-files.js +159 -0
- package/dist/deepbrain/workspace-files.js.map +1 -0
- package/dist/evolution/index.d.ts +1 -0
- package/dist/evolution/index.d.ts.map +1 -0
- package/dist/evolution/index.js +3 -0
- package/dist/evolution/index.js.map +1 -0
- package/dist/evolution/l1-experience.d.ts +11 -0
- package/dist/evolution/l1-experience.d.ts.map +1 -0
- package/dist/evolution/l1-experience.js +185 -0
- package/dist/evolution/l1-experience.js.map +1 -0
- package/dist/evolution/l2-consolidation.d.ts +4 -0
- package/dist/evolution/l2-consolidation.d.ts.map +1 -0
- package/dist/evolution/l2-consolidation.js +106 -0
- package/dist/evolution/l2-consolidation.js.map +1 -0
- package/dist/evolution/l2-memskill.d.ts +12 -0
- package/dist/evolution/l2-memskill.d.ts.map +1 -0
- package/dist/evolution/l2-memskill.js +57 -0
- package/dist/evolution/l2-memskill.js.map +1 -0
- package/dist/evolution/l3-skill-discover.d.ts +4 -0
- package/dist/evolution/l3-skill-discover.d.ts.map +1 -0
- package/dist/evolution/l3-skill-discover.js +139 -0
- package/dist/evolution/l3-skill-discover.js.map +1 -0
- package/dist/evolution/l3-skill-verify.d.ts +12 -0
- package/dist/evolution/l3-skill-verify.d.ts.map +1 -0
- package/dist/evolution/l3-skill-verify.js +122 -0
- package/dist/evolution/l3-skill-verify.js.map +1 -0
- package/dist/evolution/l4-desensitize.d.ts +7 -0
- package/dist/evolution/l4-desensitize.d.ts.map +1 -0
- package/dist/evolution/l4-desensitize.js +30 -0
- package/dist/evolution/l4-desensitize.js.map +1 -0
- package/dist/evolution/l4-group-evolve.d.ts +8 -0
- package/dist/evolution/l4-group-evolve.d.ts.map +1 -0
- package/dist/evolution/l4-group-evolve.js +15 -0
- package/dist/evolution/l4-group-evolve.js.map +1 -0
- package/dist/evolution/maturity-scorer.d.ts +11 -0
- package/dist/evolution/maturity-scorer.d.ts.map +1 -0
- package/dist/evolution/maturity-scorer.js +21 -0
- package/dist/evolution/maturity-scorer.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -5
- package/dist/index.js.map +1 -1
- package/dist/providers/agentkits.d.ts +20 -0
- package/dist/providers/agentkits.d.ts.map +1 -0
- package/dist/providers/agentkits.js +173 -0
- package/dist/providers/agentkits.js.map +1 -0
- package/dist/providers/model-provider.d.ts +16 -0
- package/dist/providers/model-provider.d.ts.map +1 -0
- package/dist/providers/model-provider.js +13 -0
- package/dist/providers/model-provider.js.map +1 -0
- package/dist/providers/model-recommender.d.ts +15 -0
- package/dist/providers/model-recommender.d.ts.map +1 -0
- package/dist/providers/model-recommender.js +71 -0
- package/dist/providers/model-recommender.js.map +1 -0
- package/dist/providers/ollama.d.ts +22 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +176 -0
- package/dist/providers/ollama.js.map +1 -0
- package/dist/providers/openai-compat.d.ts +23 -0
- package/dist/providers/openai-compat.d.ts.map +1 -0
- package/dist/providers/openai-compat.js +184 -0
- package/dist/providers/openai-compat.js.map +1 -0
- package/dist/providers/router.d.ts +11 -0
- package/dist/providers/router.d.ts.map +1 -0
- package/dist/providers/router.js +48 -0
- package/dist/providers/router.js.map +1 -0
- package/dist/scheduler/cron.d.ts +19 -0
- package/dist/scheduler/cron.d.ts.map +1 -0
- package/dist/scheduler/cron.js +64 -0
- package/dist/scheduler/cron.js.map +1 -0
- package/dist/schema/oad.d.ts +72 -72
- package/dist/skills/loader.d.ts +16 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +114 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/matcher.d.ts +18 -0
- package/dist/skills/matcher.d.ts.map +1 -0
- package/dist/skills/matcher.js +70 -0
- package/dist/skills/matcher.js.map +1 -0
- package/dist/studio/agent-pool.d.ts +17 -0
- package/dist/studio/agent-pool.d.ts.map +1 -0
- package/dist/studio/agent-pool.js +35 -0
- package/dist/studio/agent-pool.js.map +1 -0
- package/dist/studio/assistant-tools.d.ts +4 -0
- package/dist/studio/assistant-tools.d.ts.map +1 -0
- package/dist/studio/assistant-tools.js +36 -0
- package/dist/studio/assistant-tools.js.map +1 -0
- package/dist/studio/index.d.ts +1 -0
- package/dist/studio/index.d.ts.map +1 -0
- package/dist/studio/index.js +3 -0
- package/dist/studio/index.js.map +1 -0
- package/dist/studio/server.d.ts +3 -0
- package/dist/studio/server.d.ts.map +1 -1
- package/dist/studio/server.js +156 -24
- package/dist/studio/server.js.map +1 -1
- package/dist/templates/index.d.ts +1 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +3 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/roles/index.d.ts +4 -0
- package/dist/templates/roles/index.d.ts.map +1 -0
- package/dist/templates/roles/index.js +46 -0
- package/dist/templates/roles/index.js.map +1 -0
- package/dist/templates/template-provider.d.ts +16 -0
- package/dist/templates/template-provider.d.ts.map +1 -0
- package/dist/templates/template-provider.js +60 -0
- package/dist/templates/template-provider.js.map +1 -0
- package/dist/tools/builtin/definitions.d.ts +7 -0
- package/dist/tools/builtin/definitions.d.ts.map +1 -0
- package/dist/tools/builtin/definitions.js +60 -0
- package/dist/tools/builtin/definitions.js.map +1 -0
- package/dist/tools/execute-code.d.ts +20 -0
- package/dist/tools/execute-code.d.ts.map +1 -0
- package/dist/tools/execute-code.js +92 -0
- package/dist/tools/execute-code.js.map +1 -0
- package/dist/tools/hooks.d.ts +47 -0
- package/dist/tools/hooks.d.ts.map +1 -0
- package/dist/tools/hooks.js +69 -0
- package/dist/tools/hooks.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +16 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/permission.d.ts +20 -0
- package/dist/tools/permission.d.ts.map +1 -0
- package/dist/tools/permission.js +35 -0
- package/dist/tools/permission.js.map +1 -0
- package/dist/tools/registry.d.ts +25 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +42 -0
- package/dist/tools/registry.js.map +1 -0
- package/package.json +1 -1
package/dist/studio/server.js
CHANGED
|
@@ -106,10 +106,45 @@ class StudioServer {
|
|
|
106
106
|
const cfgPath = (0, path_1.join)(opcDir, 'config.json');
|
|
107
107
|
if (!(0, fs_1.existsSync)(cfgPath))
|
|
108
108
|
(0, fs_1.writeFileSync)(cfgPath, JSON.stringify({}, null, 2));
|
|
109
|
-
this.server = (0, http_1.createServer)((req, res) =>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
this.server = (0, http_1.createServer)((req, res) => {
|
|
110
|
+
this.handleRequest(req, res).catch(err => {
|
|
111
|
+
console.error('[Studio] Request handler error:', err);
|
|
112
|
+
if (!res.headersSent) {
|
|
113
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
114
|
+
res.end(JSON.stringify({ error: 'Internal server error' }));
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
await new Promise((resolve, reject) => {
|
|
119
|
+
this.server.once('listening', () => {
|
|
120
|
+
console.log(`[Studio] Listening on port ${this.config.port}`);
|
|
121
|
+
resolve();
|
|
122
|
+
});
|
|
123
|
+
this.server.once('error', (err) => {
|
|
124
|
+
console.error('[Studio] Server failed to bind port:', err.message);
|
|
125
|
+
reject(err);
|
|
126
|
+
});
|
|
127
|
+
this.server.listen(this.config.port, '0.0.0.0');
|
|
128
|
+
});
|
|
129
|
+
try {
|
|
130
|
+
this.cronEngine.start();
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
console.error('[Studio] Cron engine failed to start:', err?.message || err);
|
|
134
|
+
}
|
|
135
|
+
await this.startSubModules();
|
|
136
|
+
const url = `http://localhost:${this.config.port}`;
|
|
137
|
+
console.log(`\n✓ OPC Studio ready → ${url}`);
|
|
138
|
+
if (this.config.openBrowser) {
|
|
139
|
+
try {
|
|
140
|
+
const { exec } = require('child_process');
|
|
141
|
+
const openCmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start ""' : 'xdg-open';
|
|
142
|
+
exec(`${openCmd} ${url}`);
|
|
143
|
+
}
|
|
144
|
+
catch { }
|
|
145
|
+
}
|
|
146
|
+
console.log('Press Ctrl+C to stop');
|
|
147
|
+
await new Promise(() => { });
|
|
113
148
|
}
|
|
114
149
|
async stop() {
|
|
115
150
|
this.cronEngine.stop();
|
|
@@ -122,6 +157,42 @@ class StudioServer {
|
|
|
122
157
|
}
|
|
123
158
|
});
|
|
124
159
|
}
|
|
160
|
+
async startSubModules() {
|
|
161
|
+
const subModules = [
|
|
162
|
+
{ name: 'DeepBrain', icon: '🧠', pkg: 'deepbrain', port: 4001, serveMethod: 'serveUI' },
|
|
163
|
+
{ name: 'AgentKits', icon: '📊', pkg: 'agentkits', port: 4002, serveMethod: 'serveUI' },
|
|
164
|
+
{ name: 'Workstation', icon: '👤', pkg: 'agent-workstation', port: 4003, serveMethod: 'serveUI' },
|
|
165
|
+
];
|
|
166
|
+
const moduleStatuses = [];
|
|
167
|
+
for (const mod of subModules) {
|
|
168
|
+
try {
|
|
169
|
+
const already = await this.checkPort(mod.port);
|
|
170
|
+
if (already) {
|
|
171
|
+
moduleStatuses.push(` ✓ ${mod.icon} ${mod.name} already running on :${mod.port}`);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const modExports = await dynamicImport(mod.pkg);
|
|
175
|
+
if (typeof modExports[mod.serveMethod] === 'function') {
|
|
176
|
+
modExports[mod.serveMethod]({ port: mod.port });
|
|
177
|
+
await new Promise(r => setTimeout(r, 600));
|
|
178
|
+
const started = await this.checkPort(mod.port);
|
|
179
|
+
moduleStatuses.push(started
|
|
180
|
+
? ` ✓ ${mod.icon} ${mod.name} started on :${mod.port}`
|
|
181
|
+
: ` ⚠ ${mod.icon} ${mod.name} failed to start`);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
moduleStatuses.push(` ✓ ${mod.icon} ${mod.name} installed`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
moduleStatuses.push(` ○ ${mod.icon} ${mod.name} not installed (npm i ${mod.pkg})`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (moduleStatuses.length > 0) {
|
|
192
|
+
console.log('\nModules:');
|
|
193
|
+
moduleStatuses.forEach(s => console.log(s));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
125
196
|
async handleRequest(req, res) {
|
|
126
197
|
const url = new URL(req.url || '/', `http://localhost`);
|
|
127
198
|
// Handle CORS preflight
|
|
@@ -326,7 +397,7 @@ class StudioServer {
|
|
|
326
397
|
// --- Settings API routes ---
|
|
327
398
|
if (route === 'settings/models' && req.method === 'GET') {
|
|
328
399
|
const cfg = loadSettingsConfig();
|
|
329
|
-
data = cfg.models || { mode: 'local', provider: 'ollama', chatModel: 'qwen2.5:
|
|
400
|
+
data = cfg.models || { mode: 'local', provider: 'ollama', chatModel: 'qwen2.5:0.5b', embeddingModel: 'nomic-embed-text', providers: {} };
|
|
330
401
|
res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
|
|
331
402
|
res.end(JSON.stringify(data));
|
|
332
403
|
return;
|
|
@@ -631,6 +702,10 @@ class StudioServer {
|
|
|
631
702
|
return;
|
|
632
703
|
}
|
|
633
704
|
}
|
|
705
|
+
// Simple chat endpoint: POST /api/chat { message, agentId }
|
|
706
|
+
if (route === 'chat' && req.method === 'POST') {
|
|
707
|
+
return this.handleSimpleChat(req, res);
|
|
708
|
+
}
|
|
634
709
|
switch (route) {
|
|
635
710
|
case 'modules':
|
|
636
711
|
data = await this.getModulesStatus();
|
|
@@ -960,7 +1035,7 @@ class StudioServer {
|
|
|
960
1035
|
// Try to use the configured LLM to generate the prompt
|
|
961
1036
|
const config = this.getConfig();
|
|
962
1037
|
const provider = config.provider || 'ollama';
|
|
963
|
-
const model = config.model || 'qwen2.5:
|
|
1038
|
+
const model = config.model || 'qwen2.5:0.5b';
|
|
964
1039
|
const baseUrl = config.baseUrl || process.env.OPC_LLM_BASE_URL || 'http://localhost:11434/v1';
|
|
965
1040
|
const apiKey = config.apiKey || process.env.OPC_LLM_API_KEY || 'ollama';
|
|
966
1041
|
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
@@ -1043,16 +1118,17 @@ class StudioServer {
|
|
|
1043
1118
|
try {
|
|
1044
1119
|
const { BaseAgent } = require('../core/agent');
|
|
1045
1120
|
const { InMemoryStore } = require('../memory');
|
|
1046
|
-
// Determine provider config
|
|
1121
|
+
// Determine provider config from OAD
|
|
1047
1122
|
let providerName = agent.provider || process.env.OPC_LLM_PROVIDER;
|
|
1123
|
+
let oadConfig = null;
|
|
1048
1124
|
if (!providerName) {
|
|
1049
1125
|
try {
|
|
1050
1126
|
for (const fname of ['oad.yaml', 'agent.yaml']) {
|
|
1051
1127
|
const oadPath = (0, path_1.join)(this.config.agentDir, fname);
|
|
1052
1128
|
if ((0, fs_1.existsSync)(oadPath)) {
|
|
1053
1129
|
const yaml = require('js-yaml');
|
|
1054
|
-
|
|
1055
|
-
providerName =
|
|
1130
|
+
oadConfig = yaml.load((0, fs_1.readFileSync)(oadPath, 'utf-8'));
|
|
1131
|
+
providerName = oadConfig?.spec?.provider?.default;
|
|
1056
1132
|
if (providerName)
|
|
1057
1133
|
break;
|
|
1058
1134
|
}
|
|
@@ -1061,24 +1137,20 @@ class StudioServer {
|
|
|
1061
1137
|
catch { }
|
|
1062
1138
|
}
|
|
1063
1139
|
providerName = providerName || 'auto';
|
|
1064
|
-
// Build agent dir for this specific agent (for skills, tools, etc.)
|
|
1065
|
-
const agentWorkDir = (0, path_1.join)(this.getAgentsDir(), '..', 'workspaces', agentId);
|
|
1066
|
-
const skillsDir = (0, fs_1.existsSync)((0, path_1.join)(agentWorkDir, 'skills')) ? (0, path_1.join)(agentWorkDir, 'skills') : undefined;
|
|
1067
1140
|
const runtimeAgent = new BaseAgent({
|
|
1068
1141
|
name: agent.name || agentId,
|
|
1069
|
-
systemPrompt: agent.systemPrompt || 'You are a helpful assistant. Please reply in Chinese.',
|
|
1142
|
+
systemPrompt: agent.systemPrompt || oadConfig?.spec?.systemPrompt || 'You are a helpful assistant. Please reply in Chinese.',
|
|
1070
1143
|
provider: providerName,
|
|
1071
|
-
model: agent.model !== 'auto' ? agent.model :
|
|
1144
|
+
model: agent.model !== 'auto' ? agent.model : oadConfig?.spec?.model,
|
|
1072
1145
|
memory: new InMemoryStore(),
|
|
1073
|
-
|
|
1074
|
-
agentDir:
|
|
1146
|
+
historyLimit: 50,
|
|
1147
|
+
agentDir: this.config.agentDir,
|
|
1148
|
+
maxToolRounds: 0, // Disable tool calling for now until streaming tool support is added
|
|
1075
1149
|
});
|
|
1076
1150
|
await runtimeAgent.init();
|
|
1151
|
+
// TODO: Connect DeepBrain long-term memory when streaming handleMessage is ready
|
|
1077
1152
|
// TODO: Add function calling tools for OPC assistant
|
|
1078
|
-
// Tools needed: createAgent, deleteAgent, listAgents, configureChannel, updateAgent
|
|
1079
|
-
// Reference: Hermes Agent pattern - expose Studio APIs as LLM tools
|
|
1080
1153
|
// Use handleMessage for full pipeline (skills → memory → tools → guardrails → LLM)
|
|
1081
|
-
// Then stream the response to client
|
|
1082
1154
|
const msg = {
|
|
1083
1155
|
id: `msg_${Date.now()}`,
|
|
1084
1156
|
role: 'user',
|
|
@@ -1088,11 +1160,10 @@ class StudioServer {
|
|
|
1088
1160
|
};
|
|
1089
1161
|
try {
|
|
1090
1162
|
const response = await runtimeAgent.handleMessage(msg);
|
|
1091
|
-
|
|
1092
|
-
const words = response.content.split('');
|
|
1163
|
+
const text = response.content;
|
|
1093
1164
|
const chunkSize = 3;
|
|
1094
|
-
for (let i = 0; i <
|
|
1095
|
-
const chunk =
|
|
1165
|
+
for (let i = 0; i < text.length; i += chunkSize) {
|
|
1166
|
+
const chunk = text.slice(i, i + chunkSize);
|
|
1096
1167
|
const sseData = JSON.stringify({
|
|
1097
1168
|
choices: [{ delta: { content: chunk }, index: 0 }],
|
|
1098
1169
|
});
|
|
@@ -1109,7 +1180,6 @@ class StudioServer {
|
|
|
1109
1180
|
res.end();
|
|
1110
1181
|
}
|
|
1111
1182
|
catch (err) {
|
|
1112
|
-
// Provider creation failed — send error as SSE so frontend can display it
|
|
1113
1183
|
const errData = JSON.stringify({
|
|
1114
1184
|
choices: [{ delta: { content: `⚠️ Provider error: ${err.message}\n\nTip: Install Ollama or set OPENAI_API_KEY.` }, index: 0 }],
|
|
1115
1185
|
});
|
|
@@ -1118,6 +1188,68 @@ class StudioServer {
|
|
|
1118
1188
|
res.end();
|
|
1119
1189
|
}
|
|
1120
1190
|
}
|
|
1191
|
+
async handleSimpleChat(req, res) {
|
|
1192
|
+
const corsHeaders = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' };
|
|
1193
|
+
let body;
|
|
1194
|
+
try {
|
|
1195
|
+
body = JSON.parse(await this.readBody(req));
|
|
1196
|
+
}
|
|
1197
|
+
catch {
|
|
1198
|
+
res.writeHead(400, corsHeaders);
|
|
1199
|
+
res.end(JSON.stringify({ error: 'Invalid JSON body' }));
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1202
|
+
const { message, agentId } = body;
|
|
1203
|
+
if (!message) {
|
|
1204
|
+
res.writeHead(400, corsHeaders);
|
|
1205
|
+
res.end(JSON.stringify({ error: 'message is required' }));
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
// Resolve agent's system prompt
|
|
1209
|
+
let systemPrompt = 'You are a helpful assistant. Please reply in Chinese.';
|
|
1210
|
+
let model = 'qwen2.5:0.5b';
|
|
1211
|
+
if (agentId) {
|
|
1212
|
+
const agent = this.getAgentById(agentId);
|
|
1213
|
+
if (!agent.error) {
|
|
1214
|
+
if (agent.systemPrompt)
|
|
1215
|
+
systemPrompt = agent.systemPrompt;
|
|
1216
|
+
if (agent.model && agent.model !== 'auto')
|
|
1217
|
+
model = agent.model;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
// Read model from settings if available
|
|
1221
|
+
const cfg = loadSettingsConfig();
|
|
1222
|
+
if (cfg.models?.chatModel)
|
|
1223
|
+
model = cfg.models.chatModel;
|
|
1224
|
+
const ollamaBase = process.env.OPC_LLM_BASE_URL || 'http://localhost:11434/v1';
|
|
1225
|
+
try {
|
|
1226
|
+
const ollamaRes = await fetch(`${ollamaBase}/chat/completions`, {
|
|
1227
|
+
method: 'POST',
|
|
1228
|
+
headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ollama' },
|
|
1229
|
+
body: JSON.stringify({
|
|
1230
|
+
model,
|
|
1231
|
+
messages: [
|
|
1232
|
+
{ role: 'system', content: systemPrompt },
|
|
1233
|
+
{ role: 'user', content: message },
|
|
1234
|
+
],
|
|
1235
|
+
}),
|
|
1236
|
+
});
|
|
1237
|
+
if (!ollamaRes.ok) {
|
|
1238
|
+
const errText = await ollamaRes.text();
|
|
1239
|
+
res.writeHead(502, corsHeaders);
|
|
1240
|
+
res.end(JSON.stringify({ error: `Ollama error ${ollamaRes.status}: ${errText}` }));
|
|
1241
|
+
return;
|
|
1242
|
+
}
|
|
1243
|
+
const data = await ollamaRes.json();
|
|
1244
|
+
const reply = data.choices?.[0]?.message?.content || '';
|
|
1245
|
+
res.writeHead(200, corsHeaders);
|
|
1246
|
+
res.end(JSON.stringify({ reply, agentId: agentId || 'default', model }));
|
|
1247
|
+
}
|
|
1248
|
+
catch (e) {
|
|
1249
|
+
res.writeHead(502, corsHeaders);
|
|
1250
|
+
res.end(JSON.stringify({ error: `Failed to reach Ollama: ${e.message}` }));
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1121
1253
|
sendSimulatedResponse(res, lastMsg, agent) {
|
|
1122
1254
|
const response = `Hello! I'm ${agent.name}. You said: "${lastMsg}"\n\nI'm ready to help you. (Note: Connect a model provider for real AI responses)`;
|
|
1123
1255
|
const words = response.split(' ');
|