@huyooo/ai-chat-storage 0.1.6 → 0.1.7
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/dist/{chunk-BRWTH4LQ.js → chunk-7AKL7W3Y.js} +139 -22
- package/dist/{chunk-GCKDCC3O.js → chunk-LZ2LBU6Q.js} +173 -15
- package/dist/index.d.ts +127 -11
- package/dist/index.js +4 -4
- package/dist/{postgres-PBPM2KDK.js → postgres-4AZE26G4.js} +1 -1
- package/dist/{sqlite-AJRNISP2.js → sqlite-5SSRI3KS.js} +1 -1
- package/package.json +3 -3
|
@@ -28,9 +28,11 @@ async function initSchema(sql) {
|
|
|
28
28
|
user_id TEXT,
|
|
29
29
|
role TEXT NOT NULL,
|
|
30
30
|
content TEXT NOT NULL,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
model TEXT,
|
|
32
|
+
mode TEXT,
|
|
33
|
+
web_search_enabled BOOLEAN,
|
|
34
|
+
thinking_enabled BOOLEAN,
|
|
35
|
+
steps TEXT,
|
|
34
36
|
operation_ids TEXT,
|
|
35
37
|
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
36
38
|
)
|
|
@@ -75,6 +77,24 @@ async function initSchema(sql) {
|
|
|
75
77
|
auto_delete_at TIMESTAMPTZ NOT NULL
|
|
76
78
|
)
|
|
77
79
|
`;
|
|
80
|
+
await sql`
|
|
81
|
+
CREATE TABLE IF NOT EXISTS user_settings (
|
|
82
|
+
id TEXT PRIMARY KEY,
|
|
83
|
+
app_id TEXT,
|
|
84
|
+
user_id TEXT,
|
|
85
|
+
key TEXT NOT NULL,
|
|
86
|
+
value TEXT NOT NULL,
|
|
87
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
88
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
89
|
+
UNIQUE(app_id, user_id, key)
|
|
90
|
+
)
|
|
91
|
+
`;
|
|
92
|
+
await sql`
|
|
93
|
+
CREATE INDEX IF NOT EXISTS idx_user_settings_tenant ON user_settings(app_id, user_id);
|
|
94
|
+
`;
|
|
95
|
+
await sql`
|
|
96
|
+
CREATE INDEX IF NOT EXISTS idx_user_settings_key ON user_settings(key);
|
|
97
|
+
`;
|
|
78
98
|
try {
|
|
79
99
|
await sql`
|
|
80
100
|
CREATE TABLE IF NOT EXISTS embeddings (
|
|
@@ -146,13 +166,16 @@ function toSessionRecord(row) {
|
|
|
146
166
|
title: row.title,
|
|
147
167
|
model: row.model,
|
|
148
168
|
mode: row.mode,
|
|
169
|
+
webSearchEnabled: row.web_search_enabled,
|
|
170
|
+
thinkingEnabled: row.thinking_enabled,
|
|
171
|
+
hidden: row.hidden,
|
|
149
172
|
createdAt: new Date(row.created_at),
|
|
150
173
|
updatedAt: new Date(row.updated_at)
|
|
151
174
|
};
|
|
152
175
|
}
|
|
153
176
|
async function getSessions(sql, ctx) {
|
|
154
177
|
const rows = await sql`
|
|
155
|
-
SELECT id, app_id, user_id, title, model, mode, created_at, updated_at
|
|
178
|
+
SELECT id, app_id, user_id, title, model, mode, web_search_enabled, thinking_enabled, hidden, created_at, updated_at
|
|
156
179
|
FROM sessions
|
|
157
180
|
WHERE (${ctx.appId || null}::TEXT IS NULL OR app_id = ${ctx.appId || null})
|
|
158
181
|
AND (${ctx.userId || null}::TEXT IS NULL OR user_id = ${ctx.userId || null})
|
|
@@ -162,7 +185,7 @@ async function getSessions(sql, ctx) {
|
|
|
162
185
|
}
|
|
163
186
|
async function getSession(sql, id, ctx) {
|
|
164
187
|
const rows = await sql`
|
|
165
|
-
SELECT id, app_id, user_id, title, model, mode, created_at, updated_at
|
|
188
|
+
SELECT id, app_id, user_id, title, model, mode, web_search_enabled, thinking_enabled, hidden, created_at, updated_at
|
|
166
189
|
FROM sessions
|
|
167
190
|
WHERE id = ${id}
|
|
168
191
|
AND (${ctx.appId || null}::TEXT IS NULL OR app_id = ${ctx.appId || null})
|
|
@@ -172,9 +195,10 @@ async function getSession(sql, id, ctx) {
|
|
|
172
195
|
}
|
|
173
196
|
async function createSession(sql, input, ctx) {
|
|
174
197
|
const now = /* @__PURE__ */ new Date();
|
|
198
|
+
const hidden = input.hidden ?? false;
|
|
175
199
|
await sql`
|
|
176
|
-
INSERT INTO sessions (id, app_id, user_id, title, model, mode, created_at, updated_at)
|
|
177
|
-
VALUES (${input.id}, ${ctx.appId || null}, ${ctx.userId || null}, ${input.title}, ${input.model}, ${input.mode}, ${now}, ${now})
|
|
200
|
+
INSERT INTO sessions (id, app_id, user_id, title, model, mode, web_search_enabled, thinking_enabled, hidden, created_at, updated_at)
|
|
201
|
+
VALUES (${input.id}, ${ctx.appId || null}, ${ctx.userId || null}, ${input.title}, ${input.model}, ${input.mode}, ${input.webSearchEnabled}, ${input.thinkingEnabled}, ${hidden}, ${now}, ${now})
|
|
178
202
|
`;
|
|
179
203
|
return {
|
|
180
204
|
id: input.id,
|
|
@@ -183,6 +207,9 @@ async function createSession(sql, input, ctx) {
|
|
|
183
207
|
title: input.title,
|
|
184
208
|
model: input.model,
|
|
185
209
|
mode: input.mode,
|
|
210
|
+
webSearchEnabled: input.webSearchEnabled,
|
|
211
|
+
thinkingEnabled: input.thinkingEnabled,
|
|
212
|
+
hidden,
|
|
186
213
|
createdAt: now,
|
|
187
214
|
updatedAt: now
|
|
188
215
|
};
|
|
@@ -192,9 +219,12 @@ async function updateSession(sql, id, data, ctx) {
|
|
|
192
219
|
await sql`
|
|
193
220
|
UPDATE sessions
|
|
194
221
|
SET updated_at = ${now},
|
|
195
|
-
title = COALESCE(${data.title
|
|
196
|
-
model = COALESCE(${data.model
|
|
197
|
-
mode = COALESCE(${data.mode
|
|
222
|
+
title = COALESCE(${data.title ?? null}, title),
|
|
223
|
+
model = COALESCE(${data.model ?? null}, model),
|
|
224
|
+
mode = COALESCE(${data.mode ?? null}, mode),
|
|
225
|
+
web_search_enabled = COALESCE(${data.webSearchEnabled ?? null}, web_search_enabled),
|
|
226
|
+
thinking_enabled = COALESCE(${data.thinkingEnabled ?? null}, thinking_enabled),
|
|
227
|
+
hidden = COALESCE(${data.hidden ?? null}, hidden)
|
|
198
228
|
WHERE id = ${id}
|
|
199
229
|
AND (${ctx.appId || null}::TEXT IS NULL OR app_id = ${ctx.appId || null})
|
|
200
230
|
AND (${ctx.userId || null}::TEXT IS NULL OR user_id = ${ctx.userId || null})
|
|
@@ -218,17 +248,19 @@ function toMessageRecord(row) {
|
|
|
218
248
|
userId: row.user_id,
|
|
219
249
|
role: row.role,
|
|
220
250
|
content: row.content,
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
251
|
+
model: row.model,
|
|
252
|
+
mode: row.mode,
|
|
253
|
+
webSearchEnabled: row.web_search_enabled,
|
|
254
|
+
thinkingEnabled: row.thinking_enabled,
|
|
255
|
+
steps: row.steps,
|
|
224
256
|
operationIds: row.operation_ids,
|
|
225
257
|
timestamp: new Date(row.timestamp)
|
|
226
258
|
};
|
|
227
259
|
}
|
|
228
260
|
async function getMessages(sql, sessionId) {
|
|
229
261
|
const rows = await sql`
|
|
230
|
-
SELECT id, session_id, app_id, user_id, role, content,
|
|
231
|
-
|
|
262
|
+
SELECT id, session_id, app_id, user_id, role, content, model, mode,
|
|
263
|
+
web_search_enabled, thinking_enabled, steps, operation_ids, timestamp
|
|
232
264
|
FROM messages
|
|
233
265
|
WHERE session_id = ${sessionId}
|
|
234
266
|
ORDER BY timestamp
|
|
@@ -237,8 +269,8 @@ async function getMessages(sql, sessionId) {
|
|
|
237
269
|
}
|
|
238
270
|
async function getMessage(sql, id, ctx) {
|
|
239
271
|
const rows = await sql`
|
|
240
|
-
SELECT id, session_id, app_id, user_id, role, content,
|
|
241
|
-
|
|
272
|
+
SELECT id, session_id, app_id, user_id, role, content, model, mode,
|
|
273
|
+
web_search_enabled, thinking_enabled, steps, operation_ids, timestamp
|
|
242
274
|
FROM messages
|
|
243
275
|
WHERE id = ${id}
|
|
244
276
|
AND (${ctx.appId || null}::TEXT IS NULL OR app_id = ${ctx.appId || null})
|
|
@@ -249,8 +281,8 @@ async function getMessage(sql, id, ctx) {
|
|
|
249
281
|
async function saveMessage(sql, input, ctx) {
|
|
250
282
|
const now = /* @__PURE__ */ new Date();
|
|
251
283
|
await sql`
|
|
252
|
-
INSERT INTO messages (id, session_id, app_id, user_id, role, content,
|
|
253
|
-
VALUES (${input.id}, ${input.sessionId}, ${ctx.appId || null}, ${ctx.userId || null}, ${input.role}, ${input.content}, ${input.
|
|
284
|
+
INSERT INTO messages (id, session_id, app_id, user_id, role, content, model, mode, web_search_enabled, thinking_enabled, steps, operation_ids, timestamp)
|
|
285
|
+
VALUES (${input.id}, ${input.sessionId}, ${ctx.appId || null}, ${ctx.userId || null}, ${input.role}, ${input.content}, ${input.model}, ${input.mode}, ${input.webSearchEnabled}, ${input.thinkingEnabled}, ${input.steps}, ${input.operationIds}, ${now})
|
|
254
286
|
`;
|
|
255
287
|
await sql`UPDATE sessions SET updated_at = ${now} WHERE id = ${input.sessionId}`;
|
|
256
288
|
return {
|
|
@@ -260,13 +292,50 @@ async function saveMessage(sql, input, ctx) {
|
|
|
260
292
|
userId: ctx.userId || null,
|
|
261
293
|
role: input.role,
|
|
262
294
|
content: input.content,
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
295
|
+
model: input.model,
|
|
296
|
+
mode: input.mode,
|
|
297
|
+
webSearchEnabled: input.webSearchEnabled,
|
|
298
|
+
thinkingEnabled: input.thinkingEnabled,
|
|
299
|
+
steps: input.steps,
|
|
266
300
|
operationIds: input.operationIds,
|
|
267
301
|
timestamp: now
|
|
268
302
|
};
|
|
269
303
|
}
|
|
304
|
+
async function updateMessage(sql, id, data, ctx) {
|
|
305
|
+
const updates = [];
|
|
306
|
+
if (data.content !== void 0) {
|
|
307
|
+
updates.push("content");
|
|
308
|
+
}
|
|
309
|
+
if (data.steps !== void 0) {
|
|
310
|
+
updates.push("steps");
|
|
311
|
+
}
|
|
312
|
+
if (updates.length === 0) return;
|
|
313
|
+
if (data.content !== void 0 && data.steps !== void 0) {
|
|
314
|
+
await sql`
|
|
315
|
+
UPDATE messages
|
|
316
|
+
SET content = ${data.content}, steps = ${data.steps}
|
|
317
|
+
WHERE id = ${id}
|
|
318
|
+
AND (${ctx.appId || null}::TEXT IS NULL OR app_id = ${ctx.appId || null})
|
|
319
|
+
AND (${ctx.userId || null}::TEXT IS NULL OR user_id = ${ctx.userId || null})
|
|
320
|
+
`;
|
|
321
|
+
} else if (data.content !== void 0) {
|
|
322
|
+
await sql`
|
|
323
|
+
UPDATE messages
|
|
324
|
+
SET content = ${data.content}
|
|
325
|
+
WHERE id = ${id}
|
|
326
|
+
AND (${ctx.appId || null}::TEXT IS NULL OR app_id = ${ctx.appId || null})
|
|
327
|
+
AND (${ctx.userId || null}::TEXT IS NULL OR user_id = ${ctx.userId || null})
|
|
328
|
+
`;
|
|
329
|
+
} else if (data.steps !== void 0) {
|
|
330
|
+
await sql`
|
|
331
|
+
UPDATE messages
|
|
332
|
+
SET steps = ${data.steps}
|
|
333
|
+
WHERE id = ${id}
|
|
334
|
+
AND (${ctx.appId || null}::TEXT IS NULL OR app_id = ${ctx.appId || null})
|
|
335
|
+
AND (${ctx.userId || null}::TEXT IS NULL OR user_id = ${ctx.userId || null})
|
|
336
|
+
`;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
270
339
|
async function deleteMessagesAfter(sql, sessionId, timestamp) {
|
|
271
340
|
await sql`
|
|
272
341
|
DELETE FROM messages
|
|
@@ -567,6 +636,10 @@ var PostgresAdapter = class {
|
|
|
567
636
|
await this.ensureInitialized();
|
|
568
637
|
return saveMessage(this.sql, input, ctx);
|
|
569
638
|
}
|
|
639
|
+
async updateMessage(id, data, ctx) {
|
|
640
|
+
await this.ensureInitialized();
|
|
641
|
+
await updateMessage(this.sql, id, data, ctx);
|
|
642
|
+
}
|
|
570
643
|
async deleteMessagesAfter(sessionId, timestamp, ctx) {
|
|
571
644
|
await this.ensureInitialized();
|
|
572
645
|
const session = await this.getSession(sessionId, ctx);
|
|
@@ -631,6 +704,50 @@ var PostgresAdapter = class {
|
|
|
631
704
|
await this.ensureInitialized();
|
|
632
705
|
return searchSimilar(this.sql, queryEmbedding, options, ctx);
|
|
633
706
|
}
|
|
707
|
+
// ============ 用户设置 ============
|
|
708
|
+
async getUserSetting(key, ctx) {
|
|
709
|
+
await this.ensureInitialized();
|
|
710
|
+
const id = `${ctx.appId || "default"}_${ctx.userId || "default"}_${key}`;
|
|
711
|
+
const result = await this.sql`
|
|
712
|
+
SELECT value FROM user_settings
|
|
713
|
+
WHERE id = ${id}
|
|
714
|
+
LIMIT 1
|
|
715
|
+
`;
|
|
716
|
+
return result.length > 0 ? result[0].value : null;
|
|
717
|
+
}
|
|
718
|
+
async setUserSetting(key, value, ctx) {
|
|
719
|
+
await this.ensureInitialized();
|
|
720
|
+
const id = `${ctx.appId || "default"}_${ctx.userId || "default"}_${key}`;
|
|
721
|
+
await this.sql`
|
|
722
|
+
INSERT INTO user_settings (id, app_id, user_id, key, value, created_at, updated_at)
|
|
723
|
+
VALUES (${id}, ${ctx.appId || null}, ${ctx.userId || null}, ${key}, ${value}, NOW(), NOW())
|
|
724
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
725
|
+
value = ${value},
|
|
726
|
+
updated_at = NOW()
|
|
727
|
+
`;
|
|
728
|
+
}
|
|
729
|
+
async getUserSettings(ctx) {
|
|
730
|
+
await this.ensureInitialized();
|
|
731
|
+
const results = await this.sql`
|
|
732
|
+
SELECT key, value FROM user_settings
|
|
733
|
+
WHERE app_id IS NOT DISTINCT FROM ${ctx.appId || null}
|
|
734
|
+
AND user_id IS NOT DISTINCT FROM ${ctx.userId || null}
|
|
735
|
+
`;
|
|
736
|
+
const settings = {};
|
|
737
|
+
for (const row of results) {
|
|
738
|
+
settings[row.key] = row.value;
|
|
739
|
+
}
|
|
740
|
+
return settings;
|
|
741
|
+
}
|
|
742
|
+
async deleteUserSetting(key, ctx) {
|
|
743
|
+
await this.ensureInitialized();
|
|
744
|
+
await this.sql`
|
|
745
|
+
DELETE FROM user_settings
|
|
746
|
+
WHERE key = ${key}
|
|
747
|
+
AND app_id IS NOT DISTINCT FROM ${ctx.appId || null}
|
|
748
|
+
AND user_id IS NOT DISTINCT FROM ${ctx.userId || null}
|
|
749
|
+
`;
|
|
750
|
+
}
|
|
634
751
|
// ============ 生命周期 ============
|
|
635
752
|
async close() {
|
|
636
753
|
await this.sql.end();
|
|
@@ -11,6 +11,10 @@ var sessions = sqliteTable("sessions", {
|
|
|
11
11
|
title: text("title").notNull(),
|
|
12
12
|
model: text("model").notNull(),
|
|
13
13
|
mode: text("mode").notNull(),
|
|
14
|
+
webSearchEnabled: integer("web_search_enabled", { mode: "boolean" }).notNull().default(true),
|
|
15
|
+
thinkingEnabled: integer("thinking_enabled", { mode: "boolean" }).notNull().default(true),
|
|
16
|
+
/** 是否在 tab 栏隐藏(关闭但不删除) */
|
|
17
|
+
hidden: integer("hidden", { mode: "boolean" }).notNull().default(false),
|
|
14
18
|
createdAt: integer("created_at", { mode: "timestamp" }).notNull(),
|
|
15
19
|
updatedAt: integer("updated_at", { mode: "timestamp" }).notNull()
|
|
16
20
|
}, (table) => [
|
|
@@ -24,9 +28,16 @@ var messages = sqliteTable("messages", {
|
|
|
24
28
|
userId: text("user_id"),
|
|
25
29
|
role: text("role").notNull(),
|
|
26
30
|
content: text("content").notNull(),
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
/** 生成此消息时使用的模型 */
|
|
32
|
+
model: text("model"),
|
|
33
|
+
/** 生成此消息时使用的模式 (ask/agent) */
|
|
34
|
+
mode: text("mode"),
|
|
35
|
+
/** 生成此消息时是否启用 web 搜索 */
|
|
36
|
+
webSearchEnabled: integer("web_search_enabled", { mode: "boolean" }),
|
|
37
|
+
/** 生成此消息时是否启用深度思考 */
|
|
38
|
+
thinkingEnabled: integer("thinking_enabled", { mode: "boolean" }),
|
|
39
|
+
/** 执行步骤列表 JSON */
|
|
40
|
+
steps: text("steps"),
|
|
30
41
|
operationIds: text("operation_ids"),
|
|
31
42
|
timestamp: integer("timestamp", { mode: "timestamp" }).notNull()
|
|
32
43
|
}, (table) => [
|
|
@@ -105,6 +116,9 @@ function initSchema(sqlite) {
|
|
|
105
116
|
title TEXT NOT NULL,
|
|
106
117
|
model TEXT NOT NULL,
|
|
107
118
|
mode TEXT NOT NULL,
|
|
119
|
+
web_search_enabled INTEGER NOT NULL DEFAULT 1,
|
|
120
|
+
thinking_enabled INTEGER NOT NULL DEFAULT 1,
|
|
121
|
+
hidden INTEGER NOT NULL DEFAULT 0,
|
|
108
122
|
created_at INTEGER NOT NULL,
|
|
109
123
|
updated_at INTEGER NOT NULL
|
|
110
124
|
);
|
|
@@ -116,9 +130,11 @@ function initSchema(sqlite) {
|
|
|
116
130
|
user_id TEXT,
|
|
117
131
|
role TEXT NOT NULL,
|
|
118
132
|
content TEXT NOT NULL,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
133
|
+
model TEXT,
|
|
134
|
+
mode TEXT,
|
|
135
|
+
web_search_enabled INTEGER,
|
|
136
|
+
thinking_enabled INTEGER,
|
|
137
|
+
steps TEXT,
|
|
122
138
|
operation_ids TEXT,
|
|
123
139
|
timestamp INTEGER NOT NULL
|
|
124
140
|
);
|
|
@@ -173,6 +189,17 @@ function initSchema(sqlite) {
|
|
|
173
189
|
created_at INTEGER NOT NULL
|
|
174
190
|
);
|
|
175
191
|
|
|
192
|
+
CREATE TABLE IF NOT EXISTS user_settings (
|
|
193
|
+
id TEXT PRIMARY KEY,
|
|
194
|
+
app_id TEXT,
|
|
195
|
+
user_id TEXT,
|
|
196
|
+
key TEXT NOT NULL,
|
|
197
|
+
value TEXT NOT NULL,
|
|
198
|
+
created_at INTEGER NOT NULL,
|
|
199
|
+
updated_at INTEGER NOT NULL,
|
|
200
|
+
UNIQUE(app_id, user_id, key)
|
|
201
|
+
);
|
|
202
|
+
|
|
176
203
|
-- \u7D22\u5F15
|
|
177
204
|
CREATE INDEX IF NOT EXISTS idx_sessions_tenant ON sessions(app_id, user_id);
|
|
178
205
|
CREATE INDEX IF NOT EXISTS idx_sessions_updated ON sessions(updated_at);
|
|
@@ -185,7 +212,41 @@ function initSchema(sqlite) {
|
|
|
185
212
|
CREATE INDEX IF NOT EXISTS idx_trash_tenant ON trash(app_id, user_id);
|
|
186
213
|
CREATE INDEX IF NOT EXISTS idx_trash_auto_delete ON trash(auto_delete_at);
|
|
187
214
|
CREATE INDEX IF NOT EXISTS idx_embeddings_session ON embeddings(session_id);
|
|
215
|
+
CREATE INDEX IF NOT EXISTS idx_user_settings_tenant ON user_settings(app_id, user_id);
|
|
216
|
+
CREATE INDEX IF NOT EXISTS idx_user_settings_key ON user_settings(key);
|
|
188
217
|
`);
|
|
218
|
+
try {
|
|
219
|
+
sqlite.exec(`ALTER TABLE sessions ADD COLUMN web_search_enabled INTEGER NOT NULL DEFAULT 1`);
|
|
220
|
+
} catch {
|
|
221
|
+
}
|
|
222
|
+
try {
|
|
223
|
+
sqlite.exec(`ALTER TABLE sessions ADD COLUMN thinking_enabled INTEGER NOT NULL DEFAULT 1`);
|
|
224
|
+
} catch {
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
sqlite.exec(`ALTER TABLE messages ADD COLUMN model TEXT`);
|
|
228
|
+
} catch {
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
sqlite.exec(`ALTER TABLE messages ADD COLUMN mode TEXT`);
|
|
232
|
+
} catch {
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
sqlite.exec(`ALTER TABLE messages ADD COLUMN web_search_enabled INTEGER`);
|
|
236
|
+
} catch {
|
|
237
|
+
}
|
|
238
|
+
try {
|
|
239
|
+
sqlite.exec(`ALTER TABLE messages ADD COLUMN thinking_enabled INTEGER`);
|
|
240
|
+
} catch {
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
sqlite.exec(`ALTER TABLE sessions ADD COLUMN hidden INTEGER NOT NULL DEFAULT 0`);
|
|
244
|
+
} catch {
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
sqlite.exec(`ALTER TABLE messages ADD COLUMN steps TEXT`);
|
|
248
|
+
} catch {
|
|
249
|
+
}
|
|
189
250
|
}
|
|
190
251
|
function buildSessionsTenantCondition(ctx) {
|
|
191
252
|
const conditions = [];
|
|
@@ -235,6 +296,9 @@ function toSessionRecord(row) {
|
|
|
235
296
|
title: row.title,
|
|
236
297
|
model: row.model,
|
|
237
298
|
mode: row.mode,
|
|
299
|
+
webSearchEnabled: row.webSearchEnabled,
|
|
300
|
+
thinkingEnabled: row.thinkingEnabled,
|
|
301
|
+
hidden: row.hidden,
|
|
238
302
|
createdAt: row.createdAt,
|
|
239
303
|
updatedAt: row.updatedAt
|
|
240
304
|
};
|
|
@@ -259,6 +323,9 @@ function createSession(db, input, ctx) {
|
|
|
259
323
|
title: input.title,
|
|
260
324
|
model: input.model,
|
|
261
325
|
mode: input.mode,
|
|
326
|
+
webSearchEnabled: input.webSearchEnabled,
|
|
327
|
+
thinkingEnabled: input.thinkingEnabled,
|
|
328
|
+
hidden: input.hidden ?? false,
|
|
262
329
|
createdAt: now,
|
|
263
330
|
updatedAt: now
|
|
264
331
|
};
|
|
@@ -269,6 +336,9 @@ function createSession(db, input, ctx) {
|
|
|
269
336
|
title: record.title,
|
|
270
337
|
model: record.model,
|
|
271
338
|
mode: record.mode,
|
|
339
|
+
webSearchEnabled: record.webSearchEnabled,
|
|
340
|
+
thinkingEnabled: record.thinkingEnabled,
|
|
341
|
+
hidden: record.hidden,
|
|
272
342
|
createdAt: record.createdAt,
|
|
273
343
|
updatedAt: record.updatedAt
|
|
274
344
|
}).run();
|
|
@@ -281,6 +351,9 @@ function updateSession(db, id, data, ctx) {
|
|
|
281
351
|
if (data.title !== void 0) updateData.title = data.title;
|
|
282
352
|
if (data.model !== void 0) updateData.model = data.model;
|
|
283
353
|
if (data.mode !== void 0) updateData.mode = data.mode;
|
|
354
|
+
if (data.webSearchEnabled !== void 0) updateData.webSearchEnabled = data.webSearchEnabled;
|
|
355
|
+
if (data.thinkingEnabled !== void 0) updateData.thinkingEnabled = data.thinkingEnabled;
|
|
356
|
+
if (data.hidden !== void 0) updateData.hidden = data.hidden;
|
|
284
357
|
db.update(sessions).set(updateData).where(condition).run();
|
|
285
358
|
}
|
|
286
359
|
function deleteSession(db, id, ctx) {
|
|
@@ -299,9 +372,11 @@ function toMessageRecord(row) {
|
|
|
299
372
|
userId: row.userId,
|
|
300
373
|
role: row.role,
|
|
301
374
|
content: row.content,
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
375
|
+
model: row.model,
|
|
376
|
+
mode: row.mode,
|
|
377
|
+
webSearchEnabled: row.webSearchEnabled,
|
|
378
|
+
thinkingEnabled: row.thinkingEnabled,
|
|
379
|
+
steps: row.steps,
|
|
305
380
|
operationIds: row.operationIds,
|
|
306
381
|
timestamp: row.timestamp
|
|
307
382
|
};
|
|
@@ -325,9 +400,11 @@ function saveMessage(db, input, ctx) {
|
|
|
325
400
|
userId: ctx.userId || null,
|
|
326
401
|
role: input.role,
|
|
327
402
|
content: input.content,
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
403
|
+
model: input.model,
|
|
404
|
+
mode: input.mode,
|
|
405
|
+
webSearchEnabled: input.webSearchEnabled,
|
|
406
|
+
thinkingEnabled: input.thinkingEnabled,
|
|
407
|
+
steps: input.steps,
|
|
331
408
|
operationIds: input.operationIds,
|
|
332
409
|
timestamp: now
|
|
333
410
|
};
|
|
@@ -338,15 +415,31 @@ function saveMessage(db, input, ctx) {
|
|
|
338
415
|
userId: record.userId,
|
|
339
416
|
role: record.role,
|
|
340
417
|
content: record.content,
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
418
|
+
model: record.model,
|
|
419
|
+
mode: record.mode,
|
|
420
|
+
webSearchEnabled: record.webSearchEnabled,
|
|
421
|
+
thinkingEnabled: record.thinkingEnabled,
|
|
422
|
+
steps: record.steps,
|
|
344
423
|
operationIds: record.operationIds,
|
|
345
424
|
timestamp: record.timestamp
|
|
346
425
|
}).run();
|
|
347
426
|
db.update(sessions).set({ updatedAt: now }).where(eq3(sessions.id, input.sessionId)).run();
|
|
348
427
|
return record;
|
|
349
428
|
}
|
|
429
|
+
function updateMessage(db, id, data, ctx) {
|
|
430
|
+
const tenantCondition = buildMessagesTenantCondition(ctx);
|
|
431
|
+
const condition = tenantCondition ? and3(eq3(messages.id, id), tenantCondition) : eq3(messages.id, id);
|
|
432
|
+
const updateData = {};
|
|
433
|
+
if (data.content !== void 0) {
|
|
434
|
+
updateData.content = data.content;
|
|
435
|
+
}
|
|
436
|
+
if (data.steps !== void 0) {
|
|
437
|
+
updateData.steps = data.steps;
|
|
438
|
+
}
|
|
439
|
+
if (Object.keys(updateData).length > 0) {
|
|
440
|
+
db.update(messages).set(updateData).where(condition).run();
|
|
441
|
+
}
|
|
442
|
+
}
|
|
350
443
|
function deleteMessagesAfter(db, sessionId, timestamp) {
|
|
351
444
|
db.delete(messages).where(and3(
|
|
352
445
|
eq3(messages.sessionId, sessionId),
|
|
@@ -569,11 +662,60 @@ function deleteSessionEmbeddings(db, sessionId) {
|
|
|
569
662
|
db.delete(embeddings).where(eq7(embeddings.sessionId, sessionId)).run();
|
|
570
663
|
}
|
|
571
664
|
|
|
665
|
+
// src/adapters/sqlite/user-settings.ts
|
|
666
|
+
function getUserSetting(sqlite, key, ctx) {
|
|
667
|
+
const stmt = sqlite.prepare(`
|
|
668
|
+
SELECT value FROM user_settings
|
|
669
|
+
WHERE key = ? AND app_id IS ? AND user_id IS ?
|
|
670
|
+
LIMIT 1
|
|
671
|
+
`);
|
|
672
|
+
const result = stmt.get(key, ctx.appId || null, ctx.userId || null);
|
|
673
|
+
return result?.value || null;
|
|
674
|
+
}
|
|
675
|
+
function setUserSetting(sqlite, key, value, ctx) {
|
|
676
|
+
const now = Date.now();
|
|
677
|
+
const id = `${ctx.appId || "default"}_${ctx.userId || "default"}_${key}`;
|
|
678
|
+
const checkStmt = sqlite.prepare(`
|
|
679
|
+
SELECT created_at FROM user_settings WHERE id = ?
|
|
680
|
+
`);
|
|
681
|
+
const existing = checkStmt.get(id);
|
|
682
|
+
const createdAt = existing?.created_at || now;
|
|
683
|
+
const stmt = sqlite.prepare(`
|
|
684
|
+
INSERT OR REPLACE INTO user_settings
|
|
685
|
+
(id, app_id, user_id, key, value, created_at, updated_at)
|
|
686
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
687
|
+
`);
|
|
688
|
+
stmt.run(id, ctx.appId || null, ctx.userId || null, key, value, createdAt, now);
|
|
689
|
+
}
|
|
690
|
+
function getUserSettings(sqlite, ctx) {
|
|
691
|
+
const stmt = sqlite.prepare(`
|
|
692
|
+
SELECT key, value FROM user_settings
|
|
693
|
+
WHERE app_id IS ? AND user_id IS ?
|
|
694
|
+
`);
|
|
695
|
+
const results = stmt.all(ctx.appId || null, ctx.userId || null);
|
|
696
|
+
const settings = {};
|
|
697
|
+
for (const row of results) {
|
|
698
|
+
settings[row.key] = row.value;
|
|
699
|
+
}
|
|
700
|
+
return settings;
|
|
701
|
+
}
|
|
702
|
+
function deleteUserSetting(sqlite, key, ctx) {
|
|
703
|
+
const stmt = sqlite.prepare(`
|
|
704
|
+
DELETE FROM user_settings
|
|
705
|
+
WHERE key = ? AND app_id IS ? AND user_id IS ?
|
|
706
|
+
`);
|
|
707
|
+
stmt.run(key, ctx.appId || null, ctx.userId || null);
|
|
708
|
+
}
|
|
709
|
+
|
|
572
710
|
// src/adapters/sqlite/index.ts
|
|
573
711
|
var SqliteAdapter = class {
|
|
574
712
|
sqlite;
|
|
575
713
|
db;
|
|
576
714
|
config;
|
|
715
|
+
// 暴露 sqlite 实例供 user-settings 使用
|
|
716
|
+
get sqliteInstance() {
|
|
717
|
+
return this.sqlite;
|
|
718
|
+
}
|
|
577
719
|
constructor(dbPath, config = { type: "sqlite" }) {
|
|
578
720
|
this.sqlite = new Database(dbPath);
|
|
579
721
|
this.db = drizzle(this.sqlite);
|
|
@@ -611,6 +753,9 @@ var SqliteAdapter = class {
|
|
|
611
753
|
async saveMessage(input, ctx) {
|
|
612
754
|
return saveMessage(this.db, input, ctx);
|
|
613
755
|
}
|
|
756
|
+
async updateMessage(id, data, ctx) {
|
|
757
|
+
updateMessage(this.db, id, data, ctx);
|
|
758
|
+
}
|
|
614
759
|
async deleteMessagesAfter(sessionId, timestamp, ctx) {
|
|
615
760
|
const session = await this.getSession(sessionId, ctx);
|
|
616
761
|
if (!session) return;
|
|
@@ -661,6 +806,19 @@ var SqliteAdapter = class {
|
|
|
661
806
|
async searchSimilar(queryEmbedding, options, ctx) {
|
|
662
807
|
return searchSimilar(this.db, queryEmbedding, options, ctx);
|
|
663
808
|
}
|
|
809
|
+
// ============ 用户设置 ============
|
|
810
|
+
async getUserSetting(key, ctx) {
|
|
811
|
+
return getUserSetting(this.sqlite, key, ctx);
|
|
812
|
+
}
|
|
813
|
+
async setUserSetting(key, value, ctx) {
|
|
814
|
+
return setUserSetting(this.sqlite, key, value, ctx);
|
|
815
|
+
}
|
|
816
|
+
async getUserSettings(ctx) {
|
|
817
|
+
return getUserSettings(this.sqlite, ctx);
|
|
818
|
+
}
|
|
819
|
+
async deleteUserSetting(key, ctx) {
|
|
820
|
+
return deleteUserSetting(this.sqlite, key, ctx);
|
|
821
|
+
}
|
|
664
822
|
// ============ 生命周期 ============
|
|
665
823
|
async close() {
|
|
666
824
|
this.sqlite.close();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
|
|
2
|
+
import Database from 'better-sqlite3';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* 存储层类型定义
|
|
@@ -16,11 +17,15 @@ interface SessionRecord {
|
|
|
16
17
|
title: string;
|
|
17
18
|
model: string;
|
|
18
19
|
mode: 'agent' | 'plan' | 'ask';
|
|
20
|
+
webSearchEnabled: boolean;
|
|
21
|
+
thinkingEnabled: boolean;
|
|
22
|
+
/** 是否在 tab 栏隐藏(关闭但不删除) */
|
|
23
|
+
hidden: boolean;
|
|
19
24
|
createdAt: Date;
|
|
20
25
|
updatedAt: Date;
|
|
21
26
|
}
|
|
22
27
|
type CreateSessionInput = Omit<SessionRecord, 'createdAt' | 'updatedAt' | 'appId' | 'userId'>;
|
|
23
|
-
type UpdateSessionInput = Partial<Pick<SessionRecord, 'title' | 'model' | 'mode'>>;
|
|
28
|
+
type UpdateSessionInput = Partial<Pick<SessionRecord, 'title' | 'model' | 'mode' | 'webSearchEnabled' | 'thinkingEnabled' | 'hidden'>>;
|
|
24
29
|
interface MessageRecord {
|
|
25
30
|
id: string;
|
|
26
31
|
sessionId: string;
|
|
@@ -28,13 +33,22 @@ interface MessageRecord {
|
|
|
28
33
|
userId: string | null;
|
|
29
34
|
role: 'user' | 'assistant';
|
|
30
35
|
content: string;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
/** 生成此消息时使用的模型 */
|
|
37
|
+
model: string | null;
|
|
38
|
+
/** 生成此消息时使用的模式 (ask/agent) */
|
|
39
|
+
mode: string | null;
|
|
40
|
+
/** 生成此消息时是否启用 web 搜索 */
|
|
41
|
+
webSearchEnabled: boolean | null;
|
|
42
|
+
/** 生成此消息时是否启用深度思考 */
|
|
43
|
+
thinkingEnabled: boolean | null;
|
|
44
|
+
/** 执行步骤列表 JSON */
|
|
45
|
+
steps: string | null;
|
|
34
46
|
operationIds: string | null;
|
|
35
47
|
timestamp: Date;
|
|
36
48
|
}
|
|
37
49
|
type CreateMessageInput = Omit<MessageRecord, 'timestamp' | 'appId' | 'userId'>;
|
|
50
|
+
/** 更新消息输入(只更新 content 和 steps) */
|
|
51
|
+
type UpdateMessageInput = Partial<Pick<MessageRecord, 'content' | 'steps'>>;
|
|
38
52
|
type OperationStatus = 'pending' | 'confirmed' | 'executed' | 'reverted' | 'failed';
|
|
39
53
|
interface OperationRecord {
|
|
40
54
|
id: string;
|
|
@@ -106,6 +120,8 @@ interface StorageAdapter {
|
|
|
106
120
|
getMessages(sessionId: string, ctx: StorageContext): Promise<MessageRecord[]>;
|
|
107
121
|
getMessage(id: string, ctx: StorageContext): Promise<MessageRecord | null>;
|
|
108
122
|
saveMessage(message: CreateMessageInput, ctx: StorageContext): Promise<MessageRecord>;
|
|
123
|
+
/** 更新消息(用于增量保存助手消息) */
|
|
124
|
+
updateMessage(id: string, data: UpdateMessageInput, ctx: StorageContext): Promise<void>;
|
|
109
125
|
deleteMessagesAfter(sessionId: string, timestamp: Date, ctx: StorageContext): Promise<void>;
|
|
110
126
|
getOperations(sessionId: string, ctx: StorageContext): Promise<OperationRecord[]>;
|
|
111
127
|
getOperationsByMessage(messageId: string, ctx: StorageContext): Promise<OperationRecord[]>;
|
|
@@ -118,6 +134,10 @@ interface StorageAdapter {
|
|
|
118
134
|
moveToTrash?(item: Omit<TrashRecord, 'deletedAt' | 'autoDeleteAt' | 'appId' | 'userId'>, ctx: StorageContext): Promise<TrashRecord>;
|
|
119
135
|
restoreFromTrash?(id: string, ctx: StorageContext): Promise<TrashRecord>;
|
|
120
136
|
emptyExpiredTrash?(): Promise<number>;
|
|
137
|
+
getUserSetting(key: string, ctx: StorageContext): Promise<string | null>;
|
|
138
|
+
setUserSetting(key: string, value: string, ctx: StorageContext): Promise<void>;
|
|
139
|
+
getUserSettings(ctx: StorageContext): Promise<Record<string, string>>;
|
|
140
|
+
deleteUserSetting(key: string, ctx: StorageContext): Promise<void>;
|
|
121
141
|
saveEmbedding?(id: string, content: string, embedding: number[], metadata: {
|
|
122
142
|
sessionId: string;
|
|
123
143
|
messageId?: string;
|
|
@@ -257,6 +277,57 @@ declare const sessions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
257
277
|
}, {}, {
|
|
258
278
|
length: number | undefined;
|
|
259
279
|
}>;
|
|
280
|
+
webSearchEnabled: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
281
|
+
name: "web_search_enabled";
|
|
282
|
+
tableName: "sessions";
|
|
283
|
+
dataType: "boolean";
|
|
284
|
+
columnType: "SQLiteBoolean";
|
|
285
|
+
data: boolean;
|
|
286
|
+
driverParam: number;
|
|
287
|
+
notNull: true;
|
|
288
|
+
hasDefault: true;
|
|
289
|
+
isPrimaryKey: false;
|
|
290
|
+
isAutoincrement: false;
|
|
291
|
+
hasRuntimeDefault: false;
|
|
292
|
+
enumValues: undefined;
|
|
293
|
+
baseColumn: never;
|
|
294
|
+
identity: undefined;
|
|
295
|
+
generated: undefined;
|
|
296
|
+
}, {}, {}>;
|
|
297
|
+
thinkingEnabled: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
298
|
+
name: "thinking_enabled";
|
|
299
|
+
tableName: "sessions";
|
|
300
|
+
dataType: "boolean";
|
|
301
|
+
columnType: "SQLiteBoolean";
|
|
302
|
+
data: boolean;
|
|
303
|
+
driverParam: number;
|
|
304
|
+
notNull: true;
|
|
305
|
+
hasDefault: true;
|
|
306
|
+
isPrimaryKey: false;
|
|
307
|
+
isAutoincrement: false;
|
|
308
|
+
hasRuntimeDefault: false;
|
|
309
|
+
enumValues: undefined;
|
|
310
|
+
baseColumn: never;
|
|
311
|
+
identity: undefined;
|
|
312
|
+
generated: undefined;
|
|
313
|
+
}, {}, {}>;
|
|
314
|
+
hidden: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
315
|
+
name: "hidden";
|
|
316
|
+
tableName: "sessions";
|
|
317
|
+
dataType: "boolean";
|
|
318
|
+
columnType: "SQLiteBoolean";
|
|
319
|
+
data: boolean;
|
|
320
|
+
driverParam: number;
|
|
321
|
+
notNull: true;
|
|
322
|
+
hasDefault: true;
|
|
323
|
+
isPrimaryKey: false;
|
|
324
|
+
isAutoincrement: false;
|
|
325
|
+
hasRuntimeDefault: false;
|
|
326
|
+
enumValues: undefined;
|
|
327
|
+
baseColumn: never;
|
|
328
|
+
identity: undefined;
|
|
329
|
+
generated: undefined;
|
|
330
|
+
}, {}, {}>;
|
|
260
331
|
createdAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
261
332
|
name: "created_at";
|
|
262
333
|
tableName: "sessions";
|
|
@@ -413,8 +484,8 @@ declare const messages: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
413
484
|
}, {}, {
|
|
414
485
|
length: number | undefined;
|
|
415
486
|
}>;
|
|
416
|
-
|
|
417
|
-
name: "
|
|
487
|
+
model: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
488
|
+
name: "model";
|
|
418
489
|
tableName: "messages";
|
|
419
490
|
dataType: "string";
|
|
420
491
|
columnType: "SQLiteText";
|
|
@@ -432,8 +503,8 @@ declare const messages: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
432
503
|
}, {}, {
|
|
433
504
|
length: number | undefined;
|
|
434
505
|
}>;
|
|
435
|
-
|
|
436
|
-
name: "
|
|
506
|
+
mode: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
507
|
+
name: "mode";
|
|
437
508
|
tableName: "messages";
|
|
438
509
|
dataType: "string";
|
|
439
510
|
columnType: "SQLiteText";
|
|
@@ -451,8 +522,42 @@ declare const messages: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
451
522
|
}, {}, {
|
|
452
523
|
length: number | undefined;
|
|
453
524
|
}>;
|
|
454
|
-
|
|
455
|
-
name: "
|
|
525
|
+
webSearchEnabled: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
526
|
+
name: "web_search_enabled";
|
|
527
|
+
tableName: "messages";
|
|
528
|
+
dataType: "boolean";
|
|
529
|
+
columnType: "SQLiteBoolean";
|
|
530
|
+
data: boolean;
|
|
531
|
+
driverParam: number;
|
|
532
|
+
notNull: false;
|
|
533
|
+
hasDefault: false;
|
|
534
|
+
isPrimaryKey: false;
|
|
535
|
+
isAutoincrement: false;
|
|
536
|
+
hasRuntimeDefault: false;
|
|
537
|
+
enumValues: undefined;
|
|
538
|
+
baseColumn: never;
|
|
539
|
+
identity: undefined;
|
|
540
|
+
generated: undefined;
|
|
541
|
+
}, {}, {}>;
|
|
542
|
+
thinkingEnabled: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
543
|
+
name: "thinking_enabled";
|
|
544
|
+
tableName: "messages";
|
|
545
|
+
dataType: "boolean";
|
|
546
|
+
columnType: "SQLiteBoolean";
|
|
547
|
+
data: boolean;
|
|
548
|
+
driverParam: number;
|
|
549
|
+
notNull: false;
|
|
550
|
+
hasDefault: false;
|
|
551
|
+
isPrimaryKey: false;
|
|
552
|
+
isAutoincrement: false;
|
|
553
|
+
hasRuntimeDefault: false;
|
|
554
|
+
enumValues: undefined;
|
|
555
|
+
baseColumn: never;
|
|
556
|
+
identity: undefined;
|
|
557
|
+
generated: undefined;
|
|
558
|
+
}, {}, {}>;
|
|
559
|
+
steps: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
560
|
+
name: "steps";
|
|
456
561
|
tableName: "messages";
|
|
457
562
|
dataType: "string";
|
|
458
563
|
columnType: "SQLiteText";
|
|
@@ -1259,6 +1364,7 @@ declare class SqliteAdapter implements StorageAdapter {
|
|
|
1259
1364
|
private sqlite;
|
|
1260
1365
|
private db;
|
|
1261
1366
|
private config;
|
|
1367
|
+
get sqliteInstance(): Database.Database;
|
|
1262
1368
|
constructor(dbPath: string, config?: StorageConfig);
|
|
1263
1369
|
getSessions(ctx: StorageContext): Promise<SessionRecord[]>;
|
|
1264
1370
|
getSession(id: string, ctx: StorageContext): Promise<SessionRecord | null>;
|
|
@@ -1268,6 +1374,7 @@ declare class SqliteAdapter implements StorageAdapter {
|
|
|
1268
1374
|
getMessages(sessionId: string, ctx: StorageContext): Promise<MessageRecord[]>;
|
|
1269
1375
|
getMessage(id: string, ctx: StorageContext): Promise<MessageRecord | null>;
|
|
1270
1376
|
saveMessage(input: CreateMessageInput, ctx: StorageContext): Promise<MessageRecord>;
|
|
1377
|
+
updateMessage(id: string, data: UpdateMessageInput, ctx: StorageContext): Promise<void>;
|
|
1271
1378
|
deleteMessagesAfter(sessionId: string, timestamp: Date, ctx: StorageContext): Promise<void>;
|
|
1272
1379
|
getOperations(sessionId: string, ctx: StorageContext): Promise<OperationRecord[]>;
|
|
1273
1380
|
getOperationsByMessage(messageId: string, ctx: StorageContext): Promise<OperationRecord[]>;
|
|
@@ -1286,6 +1393,10 @@ declare class SqliteAdapter implements StorageAdapter {
|
|
|
1286
1393
|
contentType: EmbeddingRecord['contentType'];
|
|
1287
1394
|
}, ctx: StorageContext): Promise<void>;
|
|
1288
1395
|
searchSimilar(queryEmbedding: number[], options: VectorSearchOptions, ctx: StorageContext): Promise<VectorSearchResult[]>;
|
|
1396
|
+
getUserSetting(key: string, ctx: StorageContext): Promise<string | null>;
|
|
1397
|
+
setUserSetting(key: string, value: string, ctx: StorageContext): Promise<void>;
|
|
1398
|
+
getUserSettings(ctx: StorageContext): Promise<Record<string, string>>;
|
|
1399
|
+
deleteUserSetting(key: string, ctx: StorageContext): Promise<void>;
|
|
1289
1400
|
close(): Promise<void>;
|
|
1290
1401
|
}
|
|
1291
1402
|
|
|
@@ -1309,6 +1420,7 @@ declare class PostgresAdapter implements StorageAdapter {
|
|
|
1309
1420
|
getMessages(sessionId: string, ctx: StorageContext): Promise<MessageRecord[]>;
|
|
1310
1421
|
getMessage(id: string, ctx: StorageContext): Promise<MessageRecord | null>;
|
|
1311
1422
|
saveMessage(input: CreateMessageInput, ctx: StorageContext): Promise<MessageRecord>;
|
|
1423
|
+
updateMessage(id: string, data: UpdateMessageInput, ctx: StorageContext): Promise<void>;
|
|
1312
1424
|
deleteMessagesAfter(sessionId: string, timestamp: Date, ctx: StorageContext): Promise<void>;
|
|
1313
1425
|
getOperations(sessionId: string, ctx: StorageContext): Promise<OperationRecord[]>;
|
|
1314
1426
|
getOperationsByMessage(messageId: string, ctx: StorageContext): Promise<OperationRecord[]>;
|
|
@@ -1327,6 +1439,10 @@ declare class PostgresAdapter implements StorageAdapter {
|
|
|
1327
1439
|
contentType: EmbeddingRecord['contentType'];
|
|
1328
1440
|
}, ctx: StorageContext): Promise<void>;
|
|
1329
1441
|
searchSimilar(queryEmbedding: number[], options: VectorSearchOptions, ctx: StorageContext): Promise<VectorSearchResult[]>;
|
|
1442
|
+
getUserSetting(key: string, ctx: StorageContext): Promise<string | null>;
|
|
1443
|
+
setUserSetting(key: string, value: string, ctx: StorageContext): Promise<void>;
|
|
1444
|
+
getUserSettings(ctx: StorageContext): Promise<Record<string, string>>;
|
|
1445
|
+
deleteUserSetting(key: string, ctx: StorageContext): Promise<void>;
|
|
1330
1446
|
close(): Promise<void>;
|
|
1331
1447
|
}
|
|
1332
1448
|
|
|
@@ -1375,4 +1491,4 @@ declare function getDefaultBackupDir(): string;
|
|
|
1375
1491
|
*/
|
|
1376
1492
|
declare function getDefaultTrashDir(): string;
|
|
1377
1493
|
|
|
1378
|
-
export { type BackupRecord, type CreateMessageInput, type CreateOperationInput, type CreateSessionInput, type EmbeddingRecord, type MessageRecord, type OperationRecord, type OperationStatus, PostgresAdapter, type SessionRecord, SqliteAdapter, type StorageAdapter, type StorageConfig, type StorageContext, type TrashRecord, type UpdateSessionInput, type VectorSearchOptions, type VectorSearchResult, backups, createStorage, embeddings, getDefaultBackupDir, getDefaultStoragePath, getDefaultTrashDir, messages, operations, sessions, trash };
|
|
1494
|
+
export { type BackupRecord, type CreateMessageInput, type CreateOperationInput, type CreateSessionInput, type EmbeddingRecord, type MessageRecord, type OperationRecord, type OperationStatus, PostgresAdapter, type SessionRecord, SqliteAdapter, type StorageAdapter, type StorageConfig, type StorageContext, type TrashRecord, type UpdateMessageInput, type UpdateSessionInput, type VectorSearchOptions, type VectorSearchResult, backups, createStorage, embeddings, getDefaultBackupDir, getDefaultStoragePath, getDefaultTrashDir, messages, operations, sessions, trash };
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
operations,
|
|
7
7
|
sessions,
|
|
8
8
|
trash
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-LZ2LBU6Q.js";
|
|
10
10
|
import {
|
|
11
11
|
PostgresAdapter
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-7AKL7W3Y.js";
|
|
13
13
|
|
|
14
14
|
// src/index.ts
|
|
15
15
|
import { mkdirSync, existsSync } from "fs";
|
|
@@ -24,14 +24,14 @@ async function createStorage(config) {
|
|
|
24
24
|
if (!existsSync(dir)) {
|
|
25
25
|
mkdirSync(dir, { recursive: true });
|
|
26
26
|
}
|
|
27
|
-
const { SqliteAdapter: SqliteAdapter2 } = await import("./sqlite-
|
|
27
|
+
const { SqliteAdapter: SqliteAdapter2 } = await import("./sqlite-5SSRI3KS.js");
|
|
28
28
|
return new SqliteAdapter2(config.sqlitePath, config);
|
|
29
29
|
}
|
|
30
30
|
case "postgres": {
|
|
31
31
|
if (!config.postgresUrl) {
|
|
32
32
|
throw new Error("PostgreSQL \u9700\u8981\u63D0\u4F9B postgresUrl \u914D\u7F6E");
|
|
33
33
|
}
|
|
34
|
-
const { PostgresAdapter: PostgresAdapter2 } = await import("./postgres-
|
|
34
|
+
const { PostgresAdapter: PostgresAdapter2 } = await import("./postgres-4AZE26G4.js");
|
|
35
35
|
return new PostgresAdapter2(config.postgresUrl, config);
|
|
36
36
|
}
|
|
37
37
|
default:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huyooo/ai-chat-storage",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "AI Chat 统一存储层 - SQLite",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"
|
|
12
|
-
"
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"files": [
|