@next-open-ai/openbot 0.1.8 → 0.1.10
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.
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<link
|
|
12
12
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Roboto+Mono:wght@400;500&display=swap"
|
|
13
13
|
rel="stylesheet">
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-J1y_YkPz.js"></script>
|
|
15
15
|
<link rel="stylesheet" crossorigin href="/assets/index-BBoPEPR6.css">
|
|
16
16
|
</head>
|
|
17
17
|
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import { OnModuleDestroy } from '@nestjs/common';
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
|
2
|
+
/** RunResult compatible with better-sqlite3 for callers that use .changes / .lastInsertRowid */
|
|
3
|
+
export interface RunResult {
|
|
4
|
+
changes: number;
|
|
5
|
+
lastInsertRowid: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class DatabaseService implements OnModuleInit, OnModuleDestroy {
|
|
8
|
+
private sqlDb;
|
|
9
|
+
private dbPath;
|
|
10
|
+
private initPromise;
|
|
11
|
+
onModuleInit(): Promise<void>;
|
|
12
|
+
private doInit;
|
|
13
|
+
private getDb;
|
|
6
14
|
private runMigrations;
|
|
7
|
-
run(sql: string, params?: unknown[]):
|
|
15
|
+
run(sql: string, params?: unknown[]): RunResult;
|
|
8
16
|
get<T>(sql: string, params?: unknown[]): T | undefined;
|
|
9
17
|
all<T>(sql: string, params?: unknown[]): T[];
|
|
10
18
|
onModuleDestroy(): void;
|
|
@@ -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/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.10",
|
|
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",
|
|
@@ -24,10 +24,8 @@
|
|
|
24
24
|
"bin": {
|
|
25
25
|
"openbot": "./dist/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"
|