@next-open-ai/openbot 0.1.8 → 0.2.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/README.md +6 -6
- package/{desktop → apps/desktop}/README.md +3 -3
- package/{desktop/renderer/dist/assets/index-DL_hPION.js → apps/desktop/renderer/dist/assets/index-BOS-F8a4.js} +37 -37
- package/{desktop/renderer/dist/assets/index-BBoPEPR6.css → apps/desktop/renderer/dist/assets/index-DxqxayUL.css} +2 -2
- package/{desktop → apps/desktop}/renderer/dist/index.html +2 -2
- package/dist/cli/cli.d.ts +2 -0
- package/dist/cli/cli.js +172 -0
- package/dist/cli.d.ts +4 -1
- package/dist/cli.js +4 -172
- package/dist/gateway/auth-hooks.d.ts +17 -0
- package/dist/gateway/auth-hooks.js +19 -0
- package/dist/gateway/channel-handler.d.ts +6 -0
- package/dist/gateway/channel-handler.js +3 -0
- package/dist/gateway/index.d.ts +1 -1
- package/dist/gateway/index.js +1 -1
- package/dist/gateway/methods/agent-cancel.js +1 -1
- package/dist/gateway/methods/agent-chat.js +3 -3
- package/dist/gateway/methods/install-skill-from-path.js +1 -1
- package/dist/gateway/methods/run-scheduled-task.js +3 -3
- package/dist/gateway/paths.d.ts +20 -0
- package/dist/gateway/paths.js +19 -0
- package/dist/gateway/server.d.ts +2 -4
- package/dist/gateway/server.js +98 -208
- package/dist/gateway/sse-handler.d.ts +6 -0
- package/dist/gateway/sse-handler.js +3 -0
- package/dist/gateway/voice-handler.d.ts +12 -0
- package/dist/gateway/voice-handler.js +18 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/server/agents/agents.service.js +1 -1
- package/dist/server/bootstrap.d.ts +15 -0
- package/dist/server/bootstrap.js +38 -0
- package/dist/server/config/config.service.d.ts +1 -1
- package/dist/server/config/config.service.js +1 -1
- package/dist/server/database/database.service.d.ts +14 -6
- package/dist/server/database/database.service.js +99 -32
- package/dist/server/main.js +6 -19
- package/dist/server/skills/skills.service.js +1 -1
- package/dist/server/workspace/workspace.service.js +1 -1
- package/package.json +23 -20
- package/desktop/renderer/dist/assets/logo-RfPiqt5-.png +0 -0
- /package/dist/{agent → core/agent}/agent-dir.d.ts +0 -0
- /package/dist/{agent → core/agent}/agent-dir.js +0 -0
- /package/dist/{agent → core/agent}/agent-manager.d.ts +0 -0
- /package/dist/{agent → core/agent}/agent-manager.js +0 -0
- /package/dist/{agent → core/agent}/config-manager.d.ts +0 -0
- /package/dist/{agent → core/agent}/config-manager.js +0 -0
- /package/dist/{agent → core/agent}/run.d.ts +0 -0
- /package/dist/{agent → core/agent}/run.js +0 -0
- /package/dist/{agent → core/agent}/skills.d.ts +0 -0
- /package/dist/{agent → core/agent}/skills.js +0 -0
- /package/dist/{config → core/config}/desktop-config.d.ts +0 -0
- /package/dist/{config → core/config}/desktop-config.js +0 -0
- /package/dist/{config → core/config}/provider-support-default.d.ts +0 -0
- /package/dist/{config → core/config}/provider-support-default.js +0 -0
- /package/dist/{installer → core/installer}/index.d.ts +0 -0
- /package/dist/{installer → core/installer}/index.js +0 -0
- /package/dist/{installer → core/installer}/skill-installer.d.ts +0 -0
- /package/dist/{installer → core/installer}/skill-installer.js +0 -0
- /package/dist/{memory → core/memory}/build-summary.d.ts +0 -0
- /package/dist/{memory → core/memory}/build-summary.js +0 -0
- /package/dist/{memory → core/memory}/compaction-extension.d.ts +0 -0
- /package/dist/{memory → core/memory}/compaction-extension.js +0 -0
- /package/dist/{memory → core/memory}/embedding.d.ts +0 -0
- /package/dist/{memory → core/memory}/embedding.js +0 -0
- /package/dist/{memory → core/memory}/index.d.ts +0 -0
- /package/dist/{memory → core/memory}/index.js +0 -0
- /package/dist/{memory → core/memory}/remote-embedding.d.ts +0 -0
- /package/dist/{memory → core/memory}/remote-embedding.js +0 -0
- /package/dist/{memory → core/memory}/types.d.ts +0 -0
- /package/dist/{memory → core/memory}/types.js +0 -0
- /package/dist/{memory → core/memory}/vector-store.d.ts +0 -0
- /package/dist/{memory → core/memory}/vector-store.js +0 -0
- /package/dist/{tools → core/tools}/browser-tool.d.ts +0 -0
- /package/dist/{tools → core/tools}/browser-tool.js +0 -0
- /package/dist/{tools → core/tools}/index.d.ts +0 -0
- /package/dist/{tools → core/tools}/index.js +0 -0
- /package/dist/{tools → core/tools}/install-skill-tool.d.ts +0 -0
- /package/dist/{tools → core/tools}/install-skill-tool.js +0 -0
- /package/dist/{tools → core/tools}/save-experience-tool.d.ts +0 -0
- /package/dist/{tools → core/tools}/save-experience-tool.js +0 -0
|
@@ -5,34 +5,61 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { Injectable } from '@nestjs/common';
|
|
8
|
-
import
|
|
9
|
-
import { mkdirSync, existsSync } from 'fs';
|
|
8
|
+
import { mkdirSync, existsSync, readFileSync, writeFileSync } from 'fs';
|
|
10
9
|
import { join } from 'path';
|
|
11
10
|
import { homedir } from 'os';
|
|
12
11
|
let DatabaseService = class DatabaseService {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
12
|
+
sqlDb = null;
|
|
13
|
+
dbPath = null;
|
|
14
|
+
initPromise = null;
|
|
15
|
+
async onModuleInit() {
|
|
16
|
+
if (this.initPromise)
|
|
17
|
+
return this.initPromise;
|
|
18
|
+
this.initPromise = this.doInit();
|
|
19
|
+
return this.initPromise;
|
|
20
|
+
}
|
|
21
|
+
async doInit() {
|
|
22
|
+
const pathEnv = process.env.OPENBOT_DB_PATH;
|
|
23
|
+
const defaultDir = join(homedir(), '.openbot', 'desktop', 'data');
|
|
24
|
+
const path = pathEnv === ':memory:' || pathEnv === ''
|
|
25
|
+
? ':memory:'
|
|
26
|
+
: pathEnv ?? join(process.env.OPENBOT_DB_DIR ?? defaultDir, 'openbot.db');
|
|
27
|
+
if (path !== ':memory:') {
|
|
28
|
+
const dir = path.endsWith('.db') ? join(path, '..') : path;
|
|
29
|
+
if (!existsSync(dir)) {
|
|
30
|
+
mkdirSync(dir, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const initSqlJs = (await import('sql.js')).default;
|
|
34
|
+
const SQL = await initSqlJs();
|
|
35
|
+
let db;
|
|
36
|
+
if (path === ':memory:') {
|
|
37
|
+
db = new SQL.Database();
|
|
38
|
+
this.dbPath = ':memory:';
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
if (existsSync(path)) {
|
|
42
|
+
const buf = readFileSync(path);
|
|
43
|
+
db = new SQL.Database(new Uint8Array(buf));
|
|
26
44
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
45
|
+
else {
|
|
46
|
+
db = new SQL.Database();
|
|
47
|
+
}
|
|
48
|
+
this.dbPath = path;
|
|
30
49
|
}
|
|
31
|
-
|
|
50
|
+
this.sqlDb = db;
|
|
51
|
+
db.run('PRAGMA foreign_keys = ON;');
|
|
52
|
+
this.runMigrations();
|
|
53
|
+
}
|
|
54
|
+
getDb() {
|
|
55
|
+
if (!this.sqlDb) {
|
|
56
|
+
throw new Error('Database not initialized. Ensure onModuleInit() has completed (Nest awaits it before listening).');
|
|
57
|
+
}
|
|
58
|
+
return this.sqlDb;
|
|
32
59
|
}
|
|
33
60
|
runMigrations() {
|
|
34
|
-
const db = this.
|
|
35
|
-
|
|
61
|
+
const db = this.getDb();
|
|
62
|
+
const ddl = `
|
|
36
63
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
37
64
|
id TEXT PRIMARY KEY,
|
|
38
65
|
created_at INTEGER NOT NULL,
|
|
@@ -100,15 +127,18 @@ let DatabaseService = class DatabaseService {
|
|
|
100
127
|
);
|
|
101
128
|
CREATE INDEX IF NOT EXISTS idx_token_usage_session_id ON token_usage(session_id);
|
|
102
129
|
CREATE INDEX IF NOT EXISTS idx_token_usage_created_at ON token_usage(created_at);
|
|
103
|
-
|
|
104
|
-
|
|
130
|
+
`;
|
|
131
|
+
const statements = ddl.split(';').map((s) => s.trim()).filter(Boolean);
|
|
132
|
+
for (const stmt of statements) {
|
|
133
|
+
db.run(stmt + ';');
|
|
134
|
+
}
|
|
105
135
|
try {
|
|
106
|
-
const info =
|
|
136
|
+
const info = this.all('PRAGMA table_info(sessions)', []);
|
|
107
137
|
if (!info.some((c) => c.name === 'type')) {
|
|
108
|
-
db.
|
|
138
|
+
db.run("ALTER TABLE sessions ADD COLUMN type TEXT DEFAULT 'chat';");
|
|
109
139
|
}
|
|
110
140
|
if (!info.some((c) => c.name === 'agent_id')) {
|
|
111
|
-
db.
|
|
141
|
+
db.run("ALTER TABLE sessions ADD COLUMN agent_id TEXT DEFAULT 'default';");
|
|
112
142
|
}
|
|
113
143
|
}
|
|
114
144
|
catch (_) {
|
|
@@ -116,19 +146,56 @@ let DatabaseService = class DatabaseService {
|
|
|
116
146
|
}
|
|
117
147
|
}
|
|
118
148
|
run(sql, params = []) {
|
|
119
|
-
|
|
149
|
+
const db = this.getDb();
|
|
150
|
+
db.run(sql, params);
|
|
151
|
+
const rows = db.exec('SELECT changes() AS c, last_insert_rowid() AS id');
|
|
152
|
+
const c = rows[0]?.values?.[0]?.[0] ?? 0;
|
|
153
|
+
const id = rows[0]?.values?.[0]?.[1] ?? 0;
|
|
154
|
+
return { changes: Number(c), lastInsertRowid: Number(id) };
|
|
120
155
|
}
|
|
121
156
|
get(sql, params = []) {
|
|
122
|
-
|
|
157
|
+
const db = this.getDb();
|
|
158
|
+
const stmt = db.prepare(sql);
|
|
159
|
+
try {
|
|
160
|
+
stmt.bind(params);
|
|
161
|
+
const hasRow = stmt.step();
|
|
162
|
+
return (hasRow ? stmt.getAsObject() : undefined);
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
stmt.free();
|
|
166
|
+
}
|
|
123
167
|
}
|
|
124
168
|
all(sql, params = []) {
|
|
125
|
-
|
|
169
|
+
const db = this.getDb();
|
|
170
|
+
const stmt = db.prepare(sql);
|
|
171
|
+
try {
|
|
172
|
+
stmt.bind(params);
|
|
173
|
+
const rows = [];
|
|
174
|
+
while (stmt.step()) {
|
|
175
|
+
rows.push(stmt.getAsObject());
|
|
176
|
+
}
|
|
177
|
+
return rows;
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
stmt.free();
|
|
181
|
+
}
|
|
126
182
|
}
|
|
127
183
|
onModuleDestroy() {
|
|
128
|
-
if (this.
|
|
129
|
-
|
|
130
|
-
|
|
184
|
+
if (!this.sqlDb)
|
|
185
|
+
return;
|
|
186
|
+
if (this.dbPath && this.dbPath !== ':memory:') {
|
|
187
|
+
try {
|
|
188
|
+
const data = this.sqlDb.export();
|
|
189
|
+
writeFileSync(this.dbPath, Buffer.from(data));
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
console.error('[DatabaseService] Failed to persist database:', e);
|
|
193
|
+
}
|
|
131
194
|
}
|
|
195
|
+
this.sqlDb.close();
|
|
196
|
+
this.sqlDb = null;
|
|
197
|
+
this.dbPath = null;
|
|
198
|
+
this.initPromise = null;
|
|
132
199
|
}
|
|
133
200
|
};
|
|
134
201
|
DatabaseService = __decorate([
|
package/dist/server/main.js
CHANGED
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OpenBot Desktop
|
|
3
|
-
*
|
|
2
|
+
* OpenBot Desktop 后端入口(独立模式)。
|
|
3
|
+
* 内嵌到 Gateway 时由 gateway/server 调用 createNestAppEmbedded,不经过本文件。
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const app = await NestFactory.create(AppModule, {
|
|
9
|
-
cors: true,
|
|
10
|
-
});
|
|
11
|
-
// Set global prefix
|
|
12
|
-
app.setGlobalPrefix('server-api');
|
|
13
|
-
// Enable CORS for frontend
|
|
14
|
-
app.enableCors({
|
|
15
|
-
origin: ['http://localhost:5173', 'http://localhost:38081'],
|
|
16
|
-
credentials: true,
|
|
17
|
-
});
|
|
18
|
-
const port = process.env.PORT || 38081;
|
|
19
|
-
await app.listen(port);
|
|
5
|
+
import { createNestAppStandalone } from './bootstrap.js';
|
|
6
|
+
const port = Number(process.env.PORT) || 38081;
|
|
7
|
+
createNestAppStandalone(port).then(() => {
|
|
20
8
|
console.log(`🚀 OpenBot Desktop Server running on http://localhost:${port}`);
|
|
21
|
-
}
|
|
22
|
-
bootstrap();
|
|
9
|
+
});
|
|
@@ -16,7 +16,7 @@ import { tmpdir } from 'os';
|
|
|
16
16
|
import { randomUUID } from 'crypto';
|
|
17
17
|
import { exec } from 'child_process';
|
|
18
18
|
import { promisify } from 'util';
|
|
19
|
-
import { getOpenbotAgentDir, getOpenbotWorkspaceDir } from '../../agent/agent-dir.js';
|
|
19
|
+
import { getOpenbotAgentDir, getOpenbotWorkspaceDir } from '../../core/agent/agent-dir.js';
|
|
20
20
|
const execAsync = promisify(exec);
|
|
21
21
|
/** 工作区技能名仅允许英文、数字、下划线、连字符 */
|
|
22
22
|
const SKILL_NAME_REGEX = /^[a-zA-Z0-9_-]+$/;
|
|
@@ -8,7 +8,7 @@ import { Injectable } from '@nestjs/common';
|
|
|
8
8
|
import { readdir, stat, rm } from 'fs/promises';
|
|
9
9
|
import { join, resolve, relative } from 'path';
|
|
10
10
|
import { existsSync } from 'fs';
|
|
11
|
-
import { getOpenbotWorkspaceDir } from '../../agent/agent-dir.js';
|
|
11
|
+
import { getOpenbotWorkspaceDir } from '../../core/agent/agent-dir.js';
|
|
12
12
|
let WorkspaceService = class WorkspaceService {
|
|
13
13
|
getWorkspaceRoot(name) {
|
|
14
14
|
return join(getOpenbotWorkspaceDir(), name);
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.1
|
|
6
|
+
"version": "0.2.1",
|
|
7
7
|
"description": "CLI and library to run prompts with skill paths (Agent Skills style). Use as npm package or openbot CLI.",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "dist/index.js",
|
|
@@ -19,15 +19,13 @@
|
|
|
19
19
|
"dist",
|
|
20
20
|
"skills",
|
|
21
21
|
"README.md",
|
|
22
|
-
"desktop/renderer/dist"
|
|
22
|
+
"apps/desktop/renderer/dist"
|
|
23
23
|
],
|
|
24
24
|
"bin": {
|
|
25
|
-
"openbot": "./dist/cli.js"
|
|
25
|
+
"openbot": "./dist/cli/cli.js"
|
|
26
26
|
},
|
|
27
|
-
"dependencies": {
|
|
28
|
-
|
|
29
|
-
"croner": "^9.1.0",
|
|
30
|
-
"@mariozechner/pi-ai": "^0.51.2",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@mariozechner/pi-ai": "^0.51.2",
|
|
31
29
|
"@mariozechner/pi-coding-agent": "^0.51.2",
|
|
32
30
|
"@nestjs/common": "^10.3.0",
|
|
33
31
|
"@nestjs/core": "^10.3.0",
|
|
@@ -37,18 +35,20 @@
|
|
|
37
35
|
"@sinclair/typebox": "^0.34.41",
|
|
38
36
|
"agent-browser": "^0.8.5",
|
|
39
37
|
"commander": "^14.0.2",
|
|
38
|
+
"croner": "^9.1.0",
|
|
40
39
|
"reflect-metadata": "^0.2.1",
|
|
41
40
|
"rxjs": "^7.8.1",
|
|
41
|
+
"sql.js": "^1.13.0",
|
|
42
42
|
"vectra": "^0.12.3",
|
|
43
43
|
"ws": "^8.19.0"
|
|
44
44
|
},
|
|
45
|
-
"devDependencies": {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"@types/node": "^22.0.0",
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@nestjs/testing": "^10.3.0",
|
|
47
|
+
"@types/express": "^4.17.21",
|
|
49
48
|
"@types/jest": "^29.5.14",
|
|
49
|
+
"@types/node": "^22.0.0",
|
|
50
|
+
"@types/sql.js": "^1.4.9",
|
|
50
51
|
"@types/ws": "^8.18.1",
|
|
51
|
-
"@nestjs/testing": "^10.3.0",
|
|
52
52
|
"jest": "^29.7.0",
|
|
53
53
|
"ts-jest": "^29.2.5",
|
|
54
54
|
"typescript": "^5.7.0"
|
|
@@ -56,16 +56,19 @@
|
|
|
56
56
|
"scripts": {
|
|
57
57
|
"clean": "rm -rf dist",
|
|
58
58
|
"build": "npm run clean && tsc",
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"desktop:
|
|
59
|
+
"build:web": "cd apps/desktop && npm run build:renderer",
|
|
60
|
+
"build:all": "npm run build && npm run build:web",
|
|
61
|
+
"prepublishOnly": "npm run build && cd apps/desktop && npm run build:renderer",
|
|
62
|
+
"start": "node dist/cli/cli.js",
|
|
63
|
+
"run": "node dist/cli/cli.js",
|
|
64
|
+
"dev": "npm run build && node dist/cli/cli.js",
|
|
65
|
+
"desktop:dev": "cd apps/desktop && npm run dev",
|
|
66
|
+
"desktop:build": "cd apps/desktop && npm run build",
|
|
67
|
+
"desktop:install": "cd apps/desktop && npm install",
|
|
66
68
|
"test": "jest --config test/jest.config.cjs",
|
|
67
69
|
"test:memory": "node test/run-memory.mjs",
|
|
68
|
-
"test:e2e": "OPENBOT_DB_PATH=:memory: jest --config test/jest.config.cjs --testPathPattern=e2e"
|
|
70
|
+
"test:e2e": "OPENBOT_DB_PATH=:memory: jest --config test/jest.config.cjs --testPathPattern=e2e",
|
|
71
|
+
"test:gateway-e2e": "npm run build && node test/gateway/server.e2e.mjs"
|
|
69
72
|
},
|
|
70
73
|
"engines": {
|
|
71
74
|
"node": ">=20.0.0"
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|