@dexto/core 1.7.0 → 1.7.2
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/context/manager.cjs +3 -2
- package/dist/context/manager.d.ts.map +1 -1
- package/dist/context/manager.js +3 -2
- package/dist/llm/formatters/vercel.cjs +43 -29
- package/dist/llm/formatters/vercel.d.ts.map +1 -1
- package/dist/llm/formatters/vercel.js +49 -30
- package/dist/llm/registry/models.generated.cjs +967 -201
- package/dist/llm/registry/models.generated.d.ts +317 -27
- package/dist/llm/registry/models.generated.d.ts.map +1 -1
- package/dist/llm/registry/models.generated.js +967 -201
- package/dist/session/history/database.cjs +37 -54
- package/dist/session/history/database.d.ts +3 -18
- package/dist/session/history/database.d.ts.map +1 -1
- package/dist/session/history/database.js +37 -54
- package/package.json +1 -1
|
@@ -33,7 +33,7 @@ class DatabaseHistoryProvider {
|
|
|
33
33
|
logger;
|
|
34
34
|
// Cache state
|
|
35
35
|
cache = null;
|
|
36
|
-
|
|
36
|
+
pendingUpdates = /* @__PURE__ */ new Map();
|
|
37
37
|
flushTimer = null;
|
|
38
38
|
flushPromise = null;
|
|
39
39
|
// Flush configuration
|
|
@@ -49,25 +49,25 @@ class DatabaseHistoryProvider {
|
|
|
49
49
|
`DatabaseHistoryProvider: Session ${this.sessionId} hit message limit (${limit}), history may be truncated`
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
|
-
const
|
|
52
|
+
const seenIndexes = /* @__PURE__ */ new Map();
|
|
53
53
|
this.cache = [];
|
|
54
54
|
let duplicateCount = 0;
|
|
55
55
|
for (const msg of rawMessages) {
|
|
56
|
-
|
|
56
|
+
const seenIndex = msg.id ? seenIndexes.get(msg.id) : void 0;
|
|
57
|
+
if (seenIndex !== void 0) {
|
|
57
58
|
duplicateCount++;
|
|
59
|
+
this.cache[seenIndex] = msg;
|
|
58
60
|
continue;
|
|
59
61
|
}
|
|
60
62
|
if (msg.id) {
|
|
61
|
-
|
|
63
|
+
seenIndexes.set(msg.id, this.cache.length);
|
|
62
64
|
}
|
|
63
65
|
this.cache.push(msg);
|
|
64
66
|
}
|
|
65
67
|
if (duplicateCount > 0) {
|
|
66
68
|
this.logger.warn(
|
|
67
|
-
`DatabaseHistoryProvider: Found ${duplicateCount} duplicate
|
|
69
|
+
`DatabaseHistoryProvider: Found ${duplicateCount} duplicate message updates for session ${this.sessionId}, deduped to ${this.cache.length}`
|
|
68
70
|
);
|
|
69
|
-
this.dirty = true;
|
|
70
|
-
this.scheduleFlush();
|
|
71
71
|
} else {
|
|
72
72
|
this.logger.debug(
|
|
73
73
|
`DatabaseHistoryProvider: Loaded ${this.cache.length} messages for session ${this.sessionId}`
|
|
@@ -125,10 +125,14 @@ class DatabaseHistoryProvider {
|
|
|
125
125
|
if (this.cache === null) {
|
|
126
126
|
await this.getHistory();
|
|
127
127
|
}
|
|
128
|
-
const
|
|
128
|
+
const cache = this.cache;
|
|
129
|
+
if (cache === null) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const index = cache.findIndex((m) => m.id === message.id);
|
|
129
133
|
if (index !== -1) {
|
|
130
|
-
|
|
131
|
-
this.
|
|
134
|
+
cache[index] = message;
|
|
135
|
+
this.pendingUpdates.set(message.id, message);
|
|
132
136
|
this.scheduleFlush();
|
|
133
137
|
this.logger.debug(
|
|
134
138
|
`DatabaseHistoryProvider: Updated message ${message.id} in cache for session ${this.sessionId}`
|
|
@@ -142,7 +146,7 @@ class DatabaseHistoryProvider {
|
|
|
142
146
|
async clearHistory() {
|
|
143
147
|
this.cancelPendingFlush();
|
|
144
148
|
this.cache = [];
|
|
145
|
-
this.
|
|
149
|
+
this.pendingUpdates.clear();
|
|
146
150
|
const key = this.getMessagesKey();
|
|
147
151
|
try {
|
|
148
152
|
await this.database.delete(key);
|
|
@@ -159,67 +163,49 @@ class DatabaseHistoryProvider {
|
|
|
159
163
|
);
|
|
160
164
|
}
|
|
161
165
|
}
|
|
162
|
-
/**
|
|
163
|
-
* Flush any pending updates to the database.
|
|
164
|
-
* Should be called at turn boundaries to ensure durability.
|
|
165
|
-
*/
|
|
166
166
|
async flush() {
|
|
167
167
|
if (this.flushPromise) {
|
|
168
168
|
await this.flushPromise;
|
|
169
|
-
return;
|
|
170
169
|
}
|
|
171
170
|
this.cancelPendingFlush();
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
this.flushPromise = null;
|
|
171
|
+
while (this.pendingUpdates.size > 0) {
|
|
172
|
+
this.flushPromise = this.flushPendingUpdates();
|
|
173
|
+
try {
|
|
174
|
+
await this.flushPromise;
|
|
175
|
+
} finally {
|
|
176
|
+
this.flushPromise = null;
|
|
177
|
+
}
|
|
180
178
|
}
|
|
181
179
|
}
|
|
182
|
-
|
|
183
|
-
* Internal flush implementation.
|
|
184
|
-
* Writes entire cache to DB (delete + re-append all).
|
|
185
|
-
*/
|
|
186
|
-
async doFlush() {
|
|
187
|
-
if (!this.dirty || !this.cache) {
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
180
|
+
async flushPendingUpdates() {
|
|
190
181
|
const key = this.getMessagesKey();
|
|
191
|
-
const
|
|
192
|
-
|
|
182
|
+
const updates = [...this.pendingUpdates.values()];
|
|
183
|
+
this.pendingUpdates.clear();
|
|
193
184
|
this.logger.debug(
|
|
194
|
-
`DatabaseHistoryProvider: FLUSH
|
|
185
|
+
`DatabaseHistoryProvider: FLUSH UPDATES key=${key} count=${updates.length} ids=[${updates.map((m) => m.id).join(",")}]`
|
|
195
186
|
);
|
|
187
|
+
let failedIndex = updates.length;
|
|
196
188
|
try {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
await this.database.append(key, msg);
|
|
201
|
-
}
|
|
202
|
-
this.logger.debug(
|
|
203
|
-
`DatabaseHistoryProvider: FLUSH REAPPENDED key=${key} count=${messageCount}`
|
|
204
|
-
);
|
|
205
|
-
if (!this.flushTimer) {
|
|
206
|
-
this.dirty = false;
|
|
189
|
+
for (const [index, message] of updates.entries()) {
|
|
190
|
+
failedIndex = index;
|
|
191
|
+
await this.database.append(key, message);
|
|
207
192
|
}
|
|
208
193
|
} catch (error) {
|
|
194
|
+
for (const message of updates.slice(failedIndex)) {
|
|
195
|
+
if (message.id && !this.pendingUpdates.has(message.id)) {
|
|
196
|
+
this.pendingUpdates.set(message.id, message);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
209
199
|
this.logger.error(
|
|
210
|
-
`DatabaseHistoryProvider: Error flushing
|
|
200
|
+
`DatabaseHistoryProvider: Error flushing message updates for session ${this.sessionId}: ${error instanceof Error ? error.message : String(error)}`
|
|
211
201
|
);
|
|
212
202
|
throw import_errors.SessionError.storageFailed(
|
|
213
203
|
this.sessionId,
|
|
214
|
-
"flush
|
|
204
|
+
"flush message updates",
|
|
215
205
|
error instanceof Error ? error.message : String(error)
|
|
216
206
|
);
|
|
217
207
|
}
|
|
218
208
|
}
|
|
219
|
-
/**
|
|
220
|
-
* Schedule a debounced flush.
|
|
221
|
-
* Batches rapid updateMessage() calls into a single DB write.
|
|
222
|
-
*/
|
|
223
209
|
scheduleFlush() {
|
|
224
210
|
if (this.flushTimer) {
|
|
225
211
|
return;
|
|
@@ -230,9 +216,6 @@ class DatabaseHistoryProvider {
|
|
|
230
216
|
});
|
|
231
217
|
}, DatabaseHistoryProvider.FLUSH_DELAY_MS);
|
|
232
218
|
}
|
|
233
|
-
/**
|
|
234
|
-
* Cancel any pending scheduled flush.
|
|
235
|
-
*/
|
|
236
219
|
cancelPendingFlush() {
|
|
237
220
|
if (this.flushTimer) {
|
|
238
221
|
clearTimeout(this.flushTimer);
|
|
@@ -10,7 +10,7 @@ import type { ConversationHistoryProvider } from './types.js';
|
|
|
10
10
|
* - getHistory(): Returns cached messages after first load (eliminates repeated DB reads)
|
|
11
11
|
* - saveMessage(): Updates cache AND writes to DB immediately (new messages are critical)
|
|
12
12
|
* - updateMessage(): Updates cache immediately, debounces DB writes (batches rapid updates)
|
|
13
|
-
* - flush():
|
|
13
|
+
* - flush(): Appends the latest pending updates to DB (called at turn boundaries)
|
|
14
14
|
* - clearHistory(): Clears cache and DB immediately
|
|
15
15
|
*
|
|
16
16
|
* Durability guarantees:
|
|
@@ -23,7 +23,7 @@ export declare class DatabaseHistoryProvider implements ConversationHistoryProvi
|
|
|
23
23
|
private database;
|
|
24
24
|
private logger;
|
|
25
25
|
private cache;
|
|
26
|
-
private
|
|
26
|
+
private pendingUpdates;
|
|
27
27
|
private flushTimer;
|
|
28
28
|
private flushPromise;
|
|
29
29
|
private static readonly FLUSH_DELAY_MS;
|
|
@@ -32,24 +32,9 @@ export declare class DatabaseHistoryProvider implements ConversationHistoryProvi
|
|
|
32
32
|
saveMessage(message: InternalMessage): Promise<void>;
|
|
33
33
|
updateMessage(message: InternalMessage): Promise<void>;
|
|
34
34
|
clearHistory(): Promise<void>;
|
|
35
|
-
/**
|
|
36
|
-
* Flush any pending updates to the database.
|
|
37
|
-
* Should be called at turn boundaries to ensure durability.
|
|
38
|
-
*/
|
|
39
35
|
flush(): Promise<void>;
|
|
40
|
-
|
|
41
|
-
* Internal flush implementation.
|
|
42
|
-
* Writes entire cache to DB (delete + re-append all).
|
|
43
|
-
*/
|
|
44
|
-
private doFlush;
|
|
45
|
-
/**
|
|
46
|
-
* Schedule a debounced flush.
|
|
47
|
-
* Batches rapid updateMessage() calls into a single DB write.
|
|
48
|
-
*/
|
|
36
|
+
private flushPendingUpdates;
|
|
49
37
|
private scheduleFlush;
|
|
50
|
-
/**
|
|
51
|
-
* Cancel any pending scheduled flush.
|
|
52
|
-
*/
|
|
53
38
|
private cancelPendingFlush;
|
|
54
39
|
private getMessagesKey;
|
|
55
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/session/history/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAE9D;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,uBAAwB,YAAW,2BAA2B;IAanE,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,QAAQ;IAbpB,OAAO,CAAC,MAAM,CAAS;IAGvB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/session/history/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAE9D;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,uBAAwB,YAAW,2BAA2B;IAanE,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,QAAQ;IAbpB,OAAO,CAAC,MAAM,CAAS;IAGvB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,YAAY,CAA8B;IAGlD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAO;gBAGjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAC1B,MAAM,EAAE,MAAM;IAKZ,UAAU,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAyDxC,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAwCpD,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCtD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAkBd,mBAAmB;IAgCjC,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,cAAc;CAGzB"}
|
|
@@ -11,7 +11,7 @@ class DatabaseHistoryProvider {
|
|
|
11
11
|
logger;
|
|
12
12
|
// Cache state
|
|
13
13
|
cache = null;
|
|
14
|
-
|
|
14
|
+
pendingUpdates = /* @__PURE__ */ new Map();
|
|
15
15
|
flushTimer = null;
|
|
16
16
|
flushPromise = null;
|
|
17
17
|
// Flush configuration
|
|
@@ -27,25 +27,25 @@ class DatabaseHistoryProvider {
|
|
|
27
27
|
`DatabaseHistoryProvider: Session ${this.sessionId} hit message limit (${limit}), history may be truncated`
|
|
28
28
|
);
|
|
29
29
|
}
|
|
30
|
-
const
|
|
30
|
+
const seenIndexes = /* @__PURE__ */ new Map();
|
|
31
31
|
this.cache = [];
|
|
32
32
|
let duplicateCount = 0;
|
|
33
33
|
for (const msg of rawMessages) {
|
|
34
|
-
|
|
34
|
+
const seenIndex = msg.id ? seenIndexes.get(msg.id) : void 0;
|
|
35
|
+
if (seenIndex !== void 0) {
|
|
35
36
|
duplicateCount++;
|
|
37
|
+
this.cache[seenIndex] = msg;
|
|
36
38
|
continue;
|
|
37
39
|
}
|
|
38
40
|
if (msg.id) {
|
|
39
|
-
|
|
41
|
+
seenIndexes.set(msg.id, this.cache.length);
|
|
40
42
|
}
|
|
41
43
|
this.cache.push(msg);
|
|
42
44
|
}
|
|
43
45
|
if (duplicateCount > 0) {
|
|
44
46
|
this.logger.warn(
|
|
45
|
-
`DatabaseHistoryProvider: Found ${duplicateCount} duplicate
|
|
47
|
+
`DatabaseHistoryProvider: Found ${duplicateCount} duplicate message updates for session ${this.sessionId}, deduped to ${this.cache.length}`
|
|
46
48
|
);
|
|
47
|
-
this.dirty = true;
|
|
48
|
-
this.scheduleFlush();
|
|
49
49
|
} else {
|
|
50
50
|
this.logger.debug(
|
|
51
51
|
`DatabaseHistoryProvider: Loaded ${this.cache.length} messages for session ${this.sessionId}`
|
|
@@ -103,10 +103,14 @@ class DatabaseHistoryProvider {
|
|
|
103
103
|
if (this.cache === null) {
|
|
104
104
|
await this.getHistory();
|
|
105
105
|
}
|
|
106
|
-
const
|
|
106
|
+
const cache = this.cache;
|
|
107
|
+
if (cache === null) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const index = cache.findIndex((m) => m.id === message.id);
|
|
107
111
|
if (index !== -1) {
|
|
108
|
-
|
|
109
|
-
this.
|
|
112
|
+
cache[index] = message;
|
|
113
|
+
this.pendingUpdates.set(message.id, message);
|
|
110
114
|
this.scheduleFlush();
|
|
111
115
|
this.logger.debug(
|
|
112
116
|
`DatabaseHistoryProvider: Updated message ${message.id} in cache for session ${this.sessionId}`
|
|
@@ -120,7 +124,7 @@ class DatabaseHistoryProvider {
|
|
|
120
124
|
async clearHistory() {
|
|
121
125
|
this.cancelPendingFlush();
|
|
122
126
|
this.cache = [];
|
|
123
|
-
this.
|
|
127
|
+
this.pendingUpdates.clear();
|
|
124
128
|
const key = this.getMessagesKey();
|
|
125
129
|
try {
|
|
126
130
|
await this.database.delete(key);
|
|
@@ -137,67 +141,49 @@ class DatabaseHistoryProvider {
|
|
|
137
141
|
);
|
|
138
142
|
}
|
|
139
143
|
}
|
|
140
|
-
/**
|
|
141
|
-
* Flush any pending updates to the database.
|
|
142
|
-
* Should be called at turn boundaries to ensure durability.
|
|
143
|
-
*/
|
|
144
144
|
async flush() {
|
|
145
145
|
if (this.flushPromise) {
|
|
146
146
|
await this.flushPromise;
|
|
147
|
-
return;
|
|
148
147
|
}
|
|
149
148
|
this.cancelPendingFlush();
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
this.flushPromise = null;
|
|
149
|
+
while (this.pendingUpdates.size > 0) {
|
|
150
|
+
this.flushPromise = this.flushPendingUpdates();
|
|
151
|
+
try {
|
|
152
|
+
await this.flushPromise;
|
|
153
|
+
} finally {
|
|
154
|
+
this.flushPromise = null;
|
|
155
|
+
}
|
|
158
156
|
}
|
|
159
157
|
}
|
|
160
|
-
|
|
161
|
-
* Internal flush implementation.
|
|
162
|
-
* Writes entire cache to DB (delete + re-append all).
|
|
163
|
-
*/
|
|
164
|
-
async doFlush() {
|
|
165
|
-
if (!this.dirty || !this.cache) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
158
|
+
async flushPendingUpdates() {
|
|
168
159
|
const key = this.getMessagesKey();
|
|
169
|
-
const
|
|
170
|
-
|
|
160
|
+
const updates = [...this.pendingUpdates.values()];
|
|
161
|
+
this.pendingUpdates.clear();
|
|
171
162
|
this.logger.debug(
|
|
172
|
-
`DatabaseHistoryProvider: FLUSH
|
|
163
|
+
`DatabaseHistoryProvider: FLUSH UPDATES key=${key} count=${updates.length} ids=[${updates.map((m) => m.id).join(",")}]`
|
|
173
164
|
);
|
|
165
|
+
let failedIndex = updates.length;
|
|
174
166
|
try {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
await this.database.append(key, msg);
|
|
179
|
-
}
|
|
180
|
-
this.logger.debug(
|
|
181
|
-
`DatabaseHistoryProvider: FLUSH REAPPENDED key=${key} count=${messageCount}`
|
|
182
|
-
);
|
|
183
|
-
if (!this.flushTimer) {
|
|
184
|
-
this.dirty = false;
|
|
167
|
+
for (const [index, message] of updates.entries()) {
|
|
168
|
+
failedIndex = index;
|
|
169
|
+
await this.database.append(key, message);
|
|
185
170
|
}
|
|
186
171
|
} catch (error) {
|
|
172
|
+
for (const message of updates.slice(failedIndex)) {
|
|
173
|
+
if (message.id && !this.pendingUpdates.has(message.id)) {
|
|
174
|
+
this.pendingUpdates.set(message.id, message);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
187
177
|
this.logger.error(
|
|
188
|
-
`DatabaseHistoryProvider: Error flushing
|
|
178
|
+
`DatabaseHistoryProvider: Error flushing message updates for session ${this.sessionId}: ${error instanceof Error ? error.message : String(error)}`
|
|
189
179
|
);
|
|
190
180
|
throw SessionError.storageFailed(
|
|
191
181
|
this.sessionId,
|
|
192
|
-
"flush
|
|
182
|
+
"flush message updates",
|
|
193
183
|
error instanceof Error ? error.message : String(error)
|
|
194
184
|
);
|
|
195
185
|
}
|
|
196
186
|
}
|
|
197
|
-
/**
|
|
198
|
-
* Schedule a debounced flush.
|
|
199
|
-
* Batches rapid updateMessage() calls into a single DB write.
|
|
200
|
-
*/
|
|
201
187
|
scheduleFlush() {
|
|
202
188
|
if (this.flushTimer) {
|
|
203
189
|
return;
|
|
@@ -208,9 +194,6 @@ class DatabaseHistoryProvider {
|
|
|
208
194
|
});
|
|
209
195
|
}, DatabaseHistoryProvider.FLUSH_DELAY_MS);
|
|
210
196
|
}
|
|
211
|
-
/**
|
|
212
|
-
* Cancel any pending scheduled flush.
|
|
213
|
-
*/
|
|
214
197
|
cancelPendingFlush() {
|
|
215
198
|
if (this.flushTimer) {
|
|
216
199
|
clearTimeout(this.flushTimer);
|