@reverbia/sdk 1.0.0-next.20251120124145 → 1.0.0-next.20251121094738
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/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/react/index.cjs +1446 -5
- package/dist/react/index.d.mts +106 -1
- package/dist/react/index.d.ts +106 -1
- package/dist/react/index.mjs +1431 -4
- package/package.json +6 -4
package/dist/react/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,12 +17,24 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/react/index.ts
|
|
21
31
|
var index_exports = {};
|
|
22
32
|
__export(index_exports, {
|
|
23
|
-
|
|
33
|
+
createMemoryContextSystemMessage: () => createMemoryContextSystemMessage,
|
|
34
|
+
extractConversationContext: () => extractConversationContext,
|
|
35
|
+
formatMemoriesForChat: () => formatMemoriesForChat,
|
|
36
|
+
useChat: () => useChat,
|
|
37
|
+
useMemory: () => useMemory
|
|
24
38
|
});
|
|
25
39
|
module.exports = __toCommonJS(index_exports);
|
|
26
40
|
|
|
@@ -59,16 +73,21 @@ function useChat(options) {
|
|
|
59
73
|
body: {
|
|
60
74
|
messages,
|
|
61
75
|
model
|
|
62
|
-
},
|
|
63
|
-
headers: {
|
|
64
|
-
Authorization: `Bearer ${token}`
|
|
65
76
|
}
|
|
77
|
+
// headers: {
|
|
78
|
+
// Authorization: `Bearer ${token}`,
|
|
79
|
+
// },
|
|
66
80
|
});
|
|
67
81
|
if (!completion.data) {
|
|
68
82
|
const error = completion.error?.error ?? "API did not return a completion response.";
|
|
69
83
|
setIsLoading(false);
|
|
70
84
|
return { data: null, error };
|
|
71
85
|
}
|
|
86
|
+
if (typeof completion.data === "string") {
|
|
87
|
+
const error = "API returned a string response instead of a completion object.";
|
|
88
|
+
setIsLoading(false);
|
|
89
|
+
return { data: null, error };
|
|
90
|
+
}
|
|
72
91
|
setIsLoading(false);
|
|
73
92
|
return { data: completion.data, error: null };
|
|
74
93
|
} catch (err) {
|
|
@@ -84,7 +103,1429 @@ function useChat(options) {
|
|
|
84
103
|
sendMessage
|
|
85
104
|
};
|
|
86
105
|
}
|
|
106
|
+
|
|
107
|
+
// src/react/useMemory.ts
|
|
108
|
+
var import_react2 = require("react");
|
|
109
|
+
var import_client6 = require("@reverbia/sdk");
|
|
110
|
+
|
|
111
|
+
// src/lib/memory/service.ts
|
|
112
|
+
var FACT_EXTRACTION_PROMPT = `You are a memory extraction system. Extract durable user memories from chat messages.
|
|
113
|
+
|
|
114
|
+
CRITICAL: You MUST respond with ONLY valid JSON. No explanations, no markdown, no code blocks, just pure JSON.
|
|
115
|
+
|
|
116
|
+
Only extract facts that will be useful in future conversations, such as identity, stable preferences, ongoing projects, skills, and constraints.
|
|
117
|
+
|
|
118
|
+
Do not extract sensitive attributes, temporary things, or single-use instructions.
|
|
119
|
+
|
|
120
|
+
If there are no memories to extract, return: {"items": []}
|
|
121
|
+
|
|
122
|
+
Response format (JSON only, no other text):
|
|
123
|
+
|
|
124
|
+
{
|
|
125
|
+
"items": [
|
|
126
|
+
{
|
|
127
|
+
"type": "identity",
|
|
128
|
+
"namespace": "identity",
|
|
129
|
+
"key": "name",
|
|
130
|
+
"value": "Charlie",
|
|
131
|
+
"rawEvidence": "I'm Charlie",
|
|
132
|
+
"confidence": 0.98,
|
|
133
|
+
"pii": true
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"type": "identity",
|
|
137
|
+
"namespace": "work",
|
|
138
|
+
"key": "company",
|
|
139
|
+
"value": "ZetaChain",
|
|
140
|
+
"rawEvidence": "called ZetaChain",
|
|
141
|
+
"confidence": 0.99,
|
|
142
|
+
"pii": false
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"type": "preference",
|
|
146
|
+
"namespace": "answer_style",
|
|
147
|
+
"key": "verbosity",
|
|
148
|
+
"value": "concise_direct",
|
|
149
|
+
"rawEvidence": "I prefer concise, direct answers",
|
|
150
|
+
"confidence": 0.96,
|
|
151
|
+
"pii": false
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"type": "identity",
|
|
155
|
+
"namespace": "timezone",
|
|
156
|
+
"key": "tz",
|
|
157
|
+
"value": "America/Los_Angeles",
|
|
158
|
+
"rawEvidence": "I'm in PST",
|
|
159
|
+
"confidence": 0.9,
|
|
160
|
+
"pii": false
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
}`;
|
|
164
|
+
var preprocessMemories = (items, minConfidence = 0.6) => {
|
|
165
|
+
if (!items || !Array.isArray(items)) {
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
const validItems = items.filter((item) => {
|
|
169
|
+
if (item.namespace == null || item.key == null || item.value == null) {
|
|
170
|
+
console.warn(
|
|
171
|
+
"Dropping memory item with null/undefined namespace, key, or value:",
|
|
172
|
+
item
|
|
173
|
+
);
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
const namespace = String(item.namespace).trim();
|
|
177
|
+
const key = String(item.key).trim();
|
|
178
|
+
const value = String(item.value).trim();
|
|
179
|
+
if (namespace === "" || key === "" || value === "") {
|
|
180
|
+
console.warn(
|
|
181
|
+
"Dropping memory item with empty namespace, key, or value after trimming:",
|
|
182
|
+
item
|
|
183
|
+
);
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
if (typeof item.confidence !== "number" || item.confidence < minConfidence) {
|
|
187
|
+
console.warn(
|
|
188
|
+
`Dropping memory item with confidence ${item.confidence} below threshold ${minConfidence}:`,
|
|
189
|
+
item
|
|
190
|
+
);
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
return true;
|
|
194
|
+
});
|
|
195
|
+
const deduplicatedMap = /* @__PURE__ */ new Map();
|
|
196
|
+
for (const item of validItems) {
|
|
197
|
+
const uniqueKey = `${item.namespace}:${item.key}:${item.value}`;
|
|
198
|
+
const existing = deduplicatedMap.get(uniqueKey);
|
|
199
|
+
if (!existing || item.confidence > existing.confidence) {
|
|
200
|
+
deduplicatedMap.set(uniqueKey, item);
|
|
201
|
+
} else {
|
|
202
|
+
console.debug(
|
|
203
|
+
`Deduplicating memory item: keeping entry with higher confidence (${existing.confidence} > ${item.confidence})`,
|
|
204
|
+
{ namespace: item.namespace, key: item.key, value: item.value }
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return Array.from(deduplicatedMap.values());
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// src/lib/memory/db.ts
|
|
212
|
+
var import_dexie = __toESM(require("dexie"));
|
|
213
|
+
var MemoryDatabase = class extends import_dexie.default {
|
|
214
|
+
constructor() {
|
|
215
|
+
super("MemoryDatabase");
|
|
216
|
+
this.version(2).stores({
|
|
217
|
+
memories: "++id, uniqueKey, compositeKey, namespace, key, type, createdAt, updatedAt"
|
|
218
|
+
});
|
|
219
|
+
this.version(3).stores({
|
|
220
|
+
memories: "++id, uniqueKey, compositeKey, namespace, key, type, createdAt, updatedAt"
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
var memoryDb = new MemoryDatabase();
|
|
225
|
+
var saveMemory = async (memory) => {
|
|
226
|
+
const compositeKey = `${memory.namespace}:${memory.key}`;
|
|
227
|
+
const uniqueKey = `${memory.namespace}:${memory.key}:${memory.value}`;
|
|
228
|
+
const now = Date.now();
|
|
229
|
+
const existing = await memoryDb.memories.where("uniqueKey").equals(uniqueKey).first();
|
|
230
|
+
if (existing) {
|
|
231
|
+
const shouldPreserveEmbedding = existing.value === memory.value && existing.rawEvidence === memory.rawEvidence && existing.type === memory.type && existing.namespace === memory.namespace && existing.key === memory.key && existing.embedding !== void 0 && existing.embedding.length > 0;
|
|
232
|
+
const updateData = {
|
|
233
|
+
...memory,
|
|
234
|
+
compositeKey,
|
|
235
|
+
uniqueKey,
|
|
236
|
+
updatedAt: now,
|
|
237
|
+
createdAt: existing.createdAt
|
|
238
|
+
};
|
|
239
|
+
if (shouldPreserveEmbedding) {
|
|
240
|
+
updateData.embedding = existing.embedding;
|
|
241
|
+
updateData.embeddingModel = existing.embeddingModel;
|
|
242
|
+
} else {
|
|
243
|
+
updateData.embedding = [];
|
|
244
|
+
updateData.embeddingModel = void 0;
|
|
245
|
+
}
|
|
246
|
+
await memoryDb.memories.update(existing.id, updateData);
|
|
247
|
+
} else {
|
|
248
|
+
await memoryDb.memories.add({
|
|
249
|
+
...memory,
|
|
250
|
+
compositeKey,
|
|
251
|
+
uniqueKey,
|
|
252
|
+
createdAt: now,
|
|
253
|
+
updatedAt: now
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
var saveMemories = async (memories) => {
|
|
258
|
+
await Promise.all(memories.map((memory) => saveMemory(memory)));
|
|
259
|
+
};
|
|
260
|
+
var getAllMemories = async () => {
|
|
261
|
+
return memoryDb.memories.toArray();
|
|
262
|
+
};
|
|
263
|
+
var cosineSimilarity = (a, b) => {
|
|
264
|
+
if (a.length !== b.length) {
|
|
265
|
+
throw new Error("Vectors must have the same length");
|
|
266
|
+
}
|
|
267
|
+
let dotProduct = 0;
|
|
268
|
+
let normA = 0;
|
|
269
|
+
let normB = 0;
|
|
270
|
+
for (let i = 0; i < a.length; i++) {
|
|
271
|
+
dotProduct += a[i] * b[i];
|
|
272
|
+
normA += a[i] * a[i];
|
|
273
|
+
normB += b[i] * b[i];
|
|
274
|
+
}
|
|
275
|
+
const denominator = Math.sqrt(normA) * Math.sqrt(normB);
|
|
276
|
+
if (denominator === 0) {
|
|
277
|
+
return 0;
|
|
278
|
+
}
|
|
279
|
+
return dotProduct / denominator;
|
|
280
|
+
};
|
|
281
|
+
var searchSimilarMemories = async (queryEmbedding, limit = 10, minSimilarity = 0.6) => {
|
|
282
|
+
const allMemories = await getAllMemories();
|
|
283
|
+
const memoriesWithEmbeddings = allMemories.filter(
|
|
284
|
+
(m) => m.embedding && m.embedding.length > 0
|
|
285
|
+
);
|
|
286
|
+
console.log(
|
|
287
|
+
`[Memory Search] Total memories: ${allMemories.length}, memories with embeddings: ${memoriesWithEmbeddings.length}`
|
|
288
|
+
);
|
|
289
|
+
if (memoriesWithEmbeddings.length === 0) {
|
|
290
|
+
console.warn(
|
|
291
|
+
"[Memory Search] No memories with embeddings found. Memories may need embeddings generated. Use generateAndStoreEmbeddings() to generate embeddings for existing memories."
|
|
292
|
+
);
|
|
293
|
+
return [];
|
|
294
|
+
}
|
|
295
|
+
const allResults = memoriesWithEmbeddings.map((memory) => {
|
|
296
|
+
const similarity = cosineSimilarity(queryEmbedding, memory.embedding);
|
|
297
|
+
return {
|
|
298
|
+
...memory,
|
|
299
|
+
similarity
|
|
300
|
+
};
|
|
301
|
+
}).sort((a, b) => b.similarity - a.similarity);
|
|
302
|
+
console.log(
|
|
303
|
+
`[Memory Search] All similarity scores:`,
|
|
304
|
+
allResults.map((r) => ({
|
|
305
|
+
key: `${r.namespace}:${r.key}`,
|
|
306
|
+
value: r.value,
|
|
307
|
+
similarity: r.similarity.toFixed(4)
|
|
308
|
+
}))
|
|
309
|
+
);
|
|
310
|
+
const results = allResults.filter((result) => result.similarity >= minSimilarity).slice(0, limit);
|
|
311
|
+
if (results.length === 0 && allResults.length > 0) {
|
|
312
|
+
const topSimilarity = allResults[0].similarity;
|
|
313
|
+
const suggestedThreshold = Math.max(0.3, topSimilarity - 0.1);
|
|
314
|
+
console.warn(
|
|
315
|
+
`[Memory Search] No memories above threshold ${minSimilarity}. Highest similarity was ${topSimilarity.toFixed(4)}. Consider lowering the threshold to ${suggestedThreshold.toFixed(2)}`
|
|
316
|
+
);
|
|
317
|
+
} else {
|
|
318
|
+
console.log(
|
|
319
|
+
`[Memory Search] Found ${results.length} memories above similarity threshold ${minSimilarity}. Top similarity: ${results[0]?.similarity.toFixed(4) || "N/A"}`
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
return results;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
// src/client/core/bodySerializer.gen.ts
|
|
326
|
+
var jsonBodySerializer = {
|
|
327
|
+
bodySerializer: (body) => JSON.stringify(
|
|
328
|
+
body,
|
|
329
|
+
(_key, value) => typeof value === "bigint" ? value.toString() : value
|
|
330
|
+
)
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
// src/client/core/params.gen.ts
|
|
334
|
+
var extraPrefixesMap = {
|
|
335
|
+
$body_: "body",
|
|
336
|
+
$headers_: "headers",
|
|
337
|
+
$path_: "path",
|
|
338
|
+
$query_: "query"
|
|
339
|
+
};
|
|
340
|
+
var extraPrefixes = Object.entries(extraPrefixesMap);
|
|
341
|
+
|
|
342
|
+
// src/client/core/serverSentEvents.gen.ts
|
|
343
|
+
var createSseClient = ({
|
|
344
|
+
onRequest,
|
|
345
|
+
onSseError,
|
|
346
|
+
onSseEvent,
|
|
347
|
+
responseTransformer,
|
|
348
|
+
responseValidator,
|
|
349
|
+
sseDefaultRetryDelay,
|
|
350
|
+
sseMaxRetryAttempts,
|
|
351
|
+
sseMaxRetryDelay,
|
|
352
|
+
sseSleepFn,
|
|
353
|
+
url,
|
|
354
|
+
...options
|
|
355
|
+
}) => {
|
|
356
|
+
let lastEventId;
|
|
357
|
+
const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
358
|
+
const createStream = async function* () {
|
|
359
|
+
let retryDelay = sseDefaultRetryDelay ?? 3e3;
|
|
360
|
+
let attempt = 0;
|
|
361
|
+
const signal = options.signal ?? new AbortController().signal;
|
|
362
|
+
while (true) {
|
|
363
|
+
if (signal.aborted) break;
|
|
364
|
+
attempt++;
|
|
365
|
+
const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
|
|
366
|
+
if (lastEventId !== void 0) {
|
|
367
|
+
headers.set("Last-Event-ID", lastEventId);
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
const requestInit = {
|
|
371
|
+
redirect: "follow",
|
|
372
|
+
...options,
|
|
373
|
+
body: options.serializedBody,
|
|
374
|
+
headers,
|
|
375
|
+
signal
|
|
376
|
+
};
|
|
377
|
+
let request = new Request(url, requestInit);
|
|
378
|
+
if (onRequest) {
|
|
379
|
+
request = await onRequest(url, requestInit);
|
|
380
|
+
}
|
|
381
|
+
const _fetch = options.fetch ?? globalThis.fetch;
|
|
382
|
+
const response = await _fetch(request);
|
|
383
|
+
if (!response.ok)
|
|
384
|
+
throw new Error(
|
|
385
|
+
`SSE failed: ${response.status} ${response.statusText}`
|
|
386
|
+
);
|
|
387
|
+
if (!response.body) throw new Error("No body in SSE response");
|
|
388
|
+
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
|
|
389
|
+
let buffer = "";
|
|
390
|
+
const abortHandler = () => {
|
|
391
|
+
try {
|
|
392
|
+
reader.cancel();
|
|
393
|
+
} catch {
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
signal.addEventListener("abort", abortHandler);
|
|
397
|
+
try {
|
|
398
|
+
while (true) {
|
|
399
|
+
const { done, value } = await reader.read();
|
|
400
|
+
if (done) break;
|
|
401
|
+
buffer += value;
|
|
402
|
+
const chunks = buffer.split("\n\n");
|
|
403
|
+
buffer = chunks.pop() ?? "";
|
|
404
|
+
for (const chunk of chunks) {
|
|
405
|
+
const lines = chunk.split("\n");
|
|
406
|
+
const dataLines = [];
|
|
407
|
+
let eventName;
|
|
408
|
+
for (const line of lines) {
|
|
409
|
+
if (line.startsWith("data:")) {
|
|
410
|
+
dataLines.push(line.replace(/^data:\s*/, ""));
|
|
411
|
+
} else if (line.startsWith("event:")) {
|
|
412
|
+
eventName = line.replace(/^event:\s*/, "");
|
|
413
|
+
} else if (line.startsWith("id:")) {
|
|
414
|
+
lastEventId = line.replace(/^id:\s*/, "");
|
|
415
|
+
} else if (line.startsWith("retry:")) {
|
|
416
|
+
const parsed = Number.parseInt(
|
|
417
|
+
line.replace(/^retry:\s*/, ""),
|
|
418
|
+
10
|
|
419
|
+
);
|
|
420
|
+
if (!Number.isNaN(parsed)) {
|
|
421
|
+
retryDelay = parsed;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
let data;
|
|
426
|
+
let parsedJson = false;
|
|
427
|
+
if (dataLines.length) {
|
|
428
|
+
const rawData = dataLines.join("\n");
|
|
429
|
+
try {
|
|
430
|
+
data = JSON.parse(rawData);
|
|
431
|
+
parsedJson = true;
|
|
432
|
+
} catch {
|
|
433
|
+
data = rawData;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (parsedJson) {
|
|
437
|
+
if (responseValidator) {
|
|
438
|
+
await responseValidator(data);
|
|
439
|
+
}
|
|
440
|
+
if (responseTransformer) {
|
|
441
|
+
data = await responseTransformer(data);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
onSseEvent?.({
|
|
445
|
+
data,
|
|
446
|
+
event: eventName,
|
|
447
|
+
id: lastEventId,
|
|
448
|
+
retry: retryDelay
|
|
449
|
+
});
|
|
450
|
+
if (dataLines.length) {
|
|
451
|
+
yield data;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
} finally {
|
|
456
|
+
signal.removeEventListener("abort", abortHandler);
|
|
457
|
+
reader.releaseLock();
|
|
458
|
+
}
|
|
459
|
+
break;
|
|
460
|
+
} catch (error) {
|
|
461
|
+
onSseError?.(error);
|
|
462
|
+
if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
const backoff = Math.min(
|
|
466
|
+
retryDelay * 2 ** (attempt - 1),
|
|
467
|
+
sseMaxRetryDelay ?? 3e4
|
|
468
|
+
);
|
|
469
|
+
await sleep(backoff);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
const stream = createStream();
|
|
474
|
+
return { stream };
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
// src/client/core/pathSerializer.gen.ts
|
|
478
|
+
var separatorArrayExplode = (style) => {
|
|
479
|
+
switch (style) {
|
|
480
|
+
case "label":
|
|
481
|
+
return ".";
|
|
482
|
+
case "matrix":
|
|
483
|
+
return ";";
|
|
484
|
+
case "simple":
|
|
485
|
+
return ",";
|
|
486
|
+
default:
|
|
487
|
+
return "&";
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
var separatorArrayNoExplode = (style) => {
|
|
491
|
+
switch (style) {
|
|
492
|
+
case "form":
|
|
493
|
+
return ",";
|
|
494
|
+
case "pipeDelimited":
|
|
495
|
+
return "|";
|
|
496
|
+
case "spaceDelimited":
|
|
497
|
+
return "%20";
|
|
498
|
+
default:
|
|
499
|
+
return ",";
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
var separatorObjectExplode = (style) => {
|
|
503
|
+
switch (style) {
|
|
504
|
+
case "label":
|
|
505
|
+
return ".";
|
|
506
|
+
case "matrix":
|
|
507
|
+
return ";";
|
|
508
|
+
case "simple":
|
|
509
|
+
return ",";
|
|
510
|
+
default:
|
|
511
|
+
return "&";
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
var serializeArrayParam = ({
|
|
515
|
+
allowReserved,
|
|
516
|
+
explode,
|
|
517
|
+
name,
|
|
518
|
+
style,
|
|
519
|
+
value
|
|
520
|
+
}) => {
|
|
521
|
+
if (!explode) {
|
|
522
|
+
const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
|
|
523
|
+
switch (style) {
|
|
524
|
+
case "label":
|
|
525
|
+
return `.${joinedValues2}`;
|
|
526
|
+
case "matrix":
|
|
527
|
+
return `;${name}=${joinedValues2}`;
|
|
528
|
+
case "simple":
|
|
529
|
+
return joinedValues2;
|
|
530
|
+
default:
|
|
531
|
+
return `${name}=${joinedValues2}`;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
const separator = separatorArrayExplode(style);
|
|
535
|
+
const joinedValues = value.map((v) => {
|
|
536
|
+
if (style === "label" || style === "simple") {
|
|
537
|
+
return allowReserved ? v : encodeURIComponent(v);
|
|
538
|
+
}
|
|
539
|
+
return serializePrimitiveParam({
|
|
540
|
+
allowReserved,
|
|
541
|
+
name,
|
|
542
|
+
value: v
|
|
543
|
+
});
|
|
544
|
+
}).join(separator);
|
|
545
|
+
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
546
|
+
};
|
|
547
|
+
var serializePrimitiveParam = ({
|
|
548
|
+
allowReserved,
|
|
549
|
+
name,
|
|
550
|
+
value
|
|
551
|
+
}) => {
|
|
552
|
+
if (value === void 0 || value === null) {
|
|
553
|
+
return "";
|
|
554
|
+
}
|
|
555
|
+
if (typeof value === "object") {
|
|
556
|
+
throw new Error(
|
|
557
|
+
"Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
|
|
561
|
+
};
|
|
562
|
+
var serializeObjectParam = ({
|
|
563
|
+
allowReserved,
|
|
564
|
+
explode,
|
|
565
|
+
name,
|
|
566
|
+
style,
|
|
567
|
+
value,
|
|
568
|
+
valueOnly
|
|
569
|
+
}) => {
|
|
570
|
+
if (value instanceof Date) {
|
|
571
|
+
return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
|
|
572
|
+
}
|
|
573
|
+
if (style !== "deepObject" && !explode) {
|
|
574
|
+
let values = [];
|
|
575
|
+
Object.entries(value).forEach(([key, v]) => {
|
|
576
|
+
values = [
|
|
577
|
+
...values,
|
|
578
|
+
key,
|
|
579
|
+
allowReserved ? v : encodeURIComponent(v)
|
|
580
|
+
];
|
|
581
|
+
});
|
|
582
|
+
const joinedValues2 = values.join(",");
|
|
583
|
+
switch (style) {
|
|
584
|
+
case "form":
|
|
585
|
+
return `${name}=${joinedValues2}`;
|
|
586
|
+
case "label":
|
|
587
|
+
return `.${joinedValues2}`;
|
|
588
|
+
case "matrix":
|
|
589
|
+
return `;${name}=${joinedValues2}`;
|
|
590
|
+
default:
|
|
591
|
+
return joinedValues2;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
const separator = separatorObjectExplode(style);
|
|
595
|
+
const joinedValues = Object.entries(value).map(
|
|
596
|
+
([key, v]) => serializePrimitiveParam({
|
|
597
|
+
allowReserved,
|
|
598
|
+
name: style === "deepObject" ? `${name}[${key}]` : key,
|
|
599
|
+
value: v
|
|
600
|
+
})
|
|
601
|
+
).join(separator);
|
|
602
|
+
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
// src/client/core/utils.gen.ts
|
|
606
|
+
function getValidRequestBody(options) {
|
|
607
|
+
const hasBody = options.body !== void 0;
|
|
608
|
+
const isSerializedBody = hasBody && options.bodySerializer;
|
|
609
|
+
if (isSerializedBody) {
|
|
610
|
+
if ("serializedBody" in options) {
|
|
611
|
+
const hasSerializedBody = options.serializedBody !== void 0 && options.serializedBody !== "";
|
|
612
|
+
return hasSerializedBody ? options.serializedBody : null;
|
|
613
|
+
}
|
|
614
|
+
return options.body !== "" ? options.body : null;
|
|
615
|
+
}
|
|
616
|
+
if (hasBody) {
|
|
617
|
+
return options.body;
|
|
618
|
+
}
|
|
619
|
+
return void 0;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// src/client/core/auth.gen.ts
|
|
623
|
+
var getAuthToken = async (auth, callback) => {
|
|
624
|
+
const token = typeof callback === "function" ? await callback(auth) : callback;
|
|
625
|
+
if (!token) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
if (auth.scheme === "bearer") {
|
|
629
|
+
return `Bearer ${token}`;
|
|
630
|
+
}
|
|
631
|
+
if (auth.scheme === "basic") {
|
|
632
|
+
return `Basic ${btoa(token)}`;
|
|
633
|
+
}
|
|
634
|
+
return token;
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
// src/client/client/utils.gen.ts
|
|
638
|
+
var PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
639
|
+
var defaultPathSerializer = ({ path, url: _url }) => {
|
|
640
|
+
let url = _url;
|
|
641
|
+
const matches = _url.match(PATH_PARAM_RE);
|
|
642
|
+
if (matches) {
|
|
643
|
+
for (const match of matches) {
|
|
644
|
+
let explode = false;
|
|
645
|
+
let name = match.substring(1, match.length - 1);
|
|
646
|
+
let style = "simple";
|
|
647
|
+
if (name.endsWith("*")) {
|
|
648
|
+
explode = true;
|
|
649
|
+
name = name.substring(0, name.length - 1);
|
|
650
|
+
}
|
|
651
|
+
if (name.startsWith(".")) {
|
|
652
|
+
name = name.substring(1);
|
|
653
|
+
style = "label";
|
|
654
|
+
} else if (name.startsWith(";")) {
|
|
655
|
+
name = name.substring(1);
|
|
656
|
+
style = "matrix";
|
|
657
|
+
}
|
|
658
|
+
const value = path[name];
|
|
659
|
+
if (value === void 0 || value === null) {
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
if (Array.isArray(value)) {
|
|
663
|
+
url = url.replace(
|
|
664
|
+
match,
|
|
665
|
+
serializeArrayParam({ explode, name, style, value })
|
|
666
|
+
);
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
if (typeof value === "object") {
|
|
670
|
+
url = url.replace(
|
|
671
|
+
match,
|
|
672
|
+
serializeObjectParam({
|
|
673
|
+
explode,
|
|
674
|
+
name,
|
|
675
|
+
style,
|
|
676
|
+
value,
|
|
677
|
+
valueOnly: true
|
|
678
|
+
})
|
|
679
|
+
);
|
|
680
|
+
continue;
|
|
681
|
+
}
|
|
682
|
+
if (style === "matrix") {
|
|
683
|
+
url = url.replace(
|
|
684
|
+
match,
|
|
685
|
+
`;${serializePrimitiveParam({
|
|
686
|
+
name,
|
|
687
|
+
value
|
|
688
|
+
})}`
|
|
689
|
+
);
|
|
690
|
+
continue;
|
|
691
|
+
}
|
|
692
|
+
const replaceValue = encodeURIComponent(
|
|
693
|
+
style === "label" ? `.${value}` : value
|
|
694
|
+
);
|
|
695
|
+
url = url.replace(match, replaceValue);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return url;
|
|
699
|
+
};
|
|
700
|
+
var createQuerySerializer = ({
|
|
701
|
+
parameters = {},
|
|
702
|
+
...args
|
|
703
|
+
} = {}) => {
|
|
704
|
+
const querySerializer = (queryParams) => {
|
|
705
|
+
const search = [];
|
|
706
|
+
if (queryParams && typeof queryParams === "object") {
|
|
707
|
+
for (const name in queryParams) {
|
|
708
|
+
const value = queryParams[name];
|
|
709
|
+
if (value === void 0 || value === null) {
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
712
|
+
const options = parameters[name] || args;
|
|
713
|
+
if (Array.isArray(value)) {
|
|
714
|
+
const serializedArray = serializeArrayParam({
|
|
715
|
+
allowReserved: options.allowReserved,
|
|
716
|
+
explode: true,
|
|
717
|
+
name,
|
|
718
|
+
style: "form",
|
|
719
|
+
value,
|
|
720
|
+
...options.array
|
|
721
|
+
});
|
|
722
|
+
if (serializedArray) search.push(serializedArray);
|
|
723
|
+
} else if (typeof value === "object") {
|
|
724
|
+
const serializedObject = serializeObjectParam({
|
|
725
|
+
allowReserved: options.allowReserved,
|
|
726
|
+
explode: true,
|
|
727
|
+
name,
|
|
728
|
+
style: "deepObject",
|
|
729
|
+
value,
|
|
730
|
+
...options.object
|
|
731
|
+
});
|
|
732
|
+
if (serializedObject) search.push(serializedObject);
|
|
733
|
+
} else {
|
|
734
|
+
const serializedPrimitive = serializePrimitiveParam({
|
|
735
|
+
allowReserved: options.allowReserved,
|
|
736
|
+
name,
|
|
737
|
+
value
|
|
738
|
+
});
|
|
739
|
+
if (serializedPrimitive) search.push(serializedPrimitive);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return search.join("&");
|
|
744
|
+
};
|
|
745
|
+
return querySerializer;
|
|
746
|
+
};
|
|
747
|
+
var getParseAs = (contentType) => {
|
|
748
|
+
if (!contentType) {
|
|
749
|
+
return "stream";
|
|
750
|
+
}
|
|
751
|
+
const cleanContent = contentType.split(";")[0]?.trim();
|
|
752
|
+
if (!cleanContent) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) {
|
|
756
|
+
return "json";
|
|
757
|
+
}
|
|
758
|
+
if (cleanContent === "multipart/form-data") {
|
|
759
|
+
return "formData";
|
|
760
|
+
}
|
|
761
|
+
if (["application/", "audio/", "image/", "video/"].some(
|
|
762
|
+
(type) => cleanContent.startsWith(type)
|
|
763
|
+
)) {
|
|
764
|
+
return "blob";
|
|
765
|
+
}
|
|
766
|
+
if (cleanContent.startsWith("text/")) {
|
|
767
|
+
return "text";
|
|
768
|
+
}
|
|
769
|
+
return;
|
|
770
|
+
};
|
|
771
|
+
var checkForExistence = (options, name) => {
|
|
772
|
+
if (!name) {
|
|
773
|
+
return false;
|
|
774
|
+
}
|
|
775
|
+
if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) {
|
|
776
|
+
return true;
|
|
777
|
+
}
|
|
778
|
+
return false;
|
|
779
|
+
};
|
|
780
|
+
var setAuthParams = async ({
|
|
781
|
+
security,
|
|
782
|
+
...options
|
|
783
|
+
}) => {
|
|
784
|
+
for (const auth of security) {
|
|
785
|
+
if (checkForExistence(options, auth.name)) {
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
const token = await getAuthToken(auth, options.auth);
|
|
789
|
+
if (!token) {
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
const name = auth.name ?? "Authorization";
|
|
793
|
+
switch (auth.in) {
|
|
794
|
+
case "query":
|
|
795
|
+
if (!options.query) {
|
|
796
|
+
options.query = {};
|
|
797
|
+
}
|
|
798
|
+
options.query[name] = token;
|
|
799
|
+
break;
|
|
800
|
+
case "cookie":
|
|
801
|
+
options.headers.append("Cookie", `${name}=${token}`);
|
|
802
|
+
break;
|
|
803
|
+
case "header":
|
|
804
|
+
default:
|
|
805
|
+
options.headers.set(name, token);
|
|
806
|
+
break;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
};
|
|
810
|
+
var buildUrl = (options) => {
|
|
811
|
+
const url = getUrl({
|
|
812
|
+
baseUrl: options.baseUrl,
|
|
813
|
+
path: options.path,
|
|
814
|
+
query: options.query,
|
|
815
|
+
querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
|
|
816
|
+
url: options.url
|
|
817
|
+
});
|
|
818
|
+
return url;
|
|
819
|
+
};
|
|
820
|
+
var getUrl = ({
|
|
821
|
+
baseUrl,
|
|
822
|
+
path,
|
|
823
|
+
query,
|
|
824
|
+
querySerializer,
|
|
825
|
+
url: _url
|
|
826
|
+
}) => {
|
|
827
|
+
const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
|
|
828
|
+
let url = (baseUrl ?? "") + pathUrl;
|
|
829
|
+
if (path) {
|
|
830
|
+
url = defaultPathSerializer({ path, url });
|
|
831
|
+
}
|
|
832
|
+
let search = query ? querySerializer(query) : "";
|
|
833
|
+
if (search.startsWith("?")) {
|
|
834
|
+
search = search.substring(1);
|
|
835
|
+
}
|
|
836
|
+
if (search) {
|
|
837
|
+
url += `?${search}`;
|
|
838
|
+
}
|
|
839
|
+
return url;
|
|
840
|
+
};
|
|
841
|
+
var mergeConfigs = (a, b) => {
|
|
842
|
+
const config = { ...a, ...b };
|
|
843
|
+
if (config.baseUrl?.endsWith("/")) {
|
|
844
|
+
config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
|
|
845
|
+
}
|
|
846
|
+
config.headers = mergeHeaders(a.headers, b.headers);
|
|
847
|
+
return config;
|
|
848
|
+
};
|
|
849
|
+
var headersEntries = (headers) => {
|
|
850
|
+
const entries = [];
|
|
851
|
+
headers.forEach((value, key) => {
|
|
852
|
+
entries.push([key, value]);
|
|
853
|
+
});
|
|
854
|
+
return entries;
|
|
855
|
+
};
|
|
856
|
+
var mergeHeaders = (...headers) => {
|
|
857
|
+
const mergedHeaders = new Headers();
|
|
858
|
+
for (const header of headers) {
|
|
859
|
+
if (!header || typeof header !== "object") {
|
|
860
|
+
continue;
|
|
861
|
+
}
|
|
862
|
+
const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
|
|
863
|
+
for (const [key, value] of iterator) {
|
|
864
|
+
if (value === null) {
|
|
865
|
+
mergedHeaders.delete(key);
|
|
866
|
+
} else if (Array.isArray(value)) {
|
|
867
|
+
for (const v of value) {
|
|
868
|
+
mergedHeaders.append(key, v);
|
|
869
|
+
}
|
|
870
|
+
} else if (value !== void 0) {
|
|
871
|
+
mergedHeaders.set(
|
|
872
|
+
key,
|
|
873
|
+
typeof value === "object" ? JSON.stringify(value) : value
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
return mergedHeaders;
|
|
879
|
+
};
|
|
880
|
+
var Interceptors = class {
|
|
881
|
+
constructor() {
|
|
882
|
+
this.fns = [];
|
|
883
|
+
}
|
|
884
|
+
clear() {
|
|
885
|
+
this.fns = [];
|
|
886
|
+
}
|
|
887
|
+
eject(id) {
|
|
888
|
+
const index = this.getInterceptorIndex(id);
|
|
889
|
+
if (this.fns[index]) {
|
|
890
|
+
this.fns[index] = null;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
exists(id) {
|
|
894
|
+
const index = this.getInterceptorIndex(id);
|
|
895
|
+
return Boolean(this.fns[index]);
|
|
896
|
+
}
|
|
897
|
+
getInterceptorIndex(id) {
|
|
898
|
+
if (typeof id === "number") {
|
|
899
|
+
return this.fns[id] ? id : -1;
|
|
900
|
+
}
|
|
901
|
+
return this.fns.indexOf(id);
|
|
902
|
+
}
|
|
903
|
+
update(id, fn) {
|
|
904
|
+
const index = this.getInterceptorIndex(id);
|
|
905
|
+
if (this.fns[index]) {
|
|
906
|
+
this.fns[index] = fn;
|
|
907
|
+
return id;
|
|
908
|
+
}
|
|
909
|
+
return false;
|
|
910
|
+
}
|
|
911
|
+
use(fn) {
|
|
912
|
+
this.fns.push(fn);
|
|
913
|
+
return this.fns.length - 1;
|
|
914
|
+
}
|
|
915
|
+
};
|
|
916
|
+
var createInterceptors = () => ({
|
|
917
|
+
error: new Interceptors(),
|
|
918
|
+
request: new Interceptors(),
|
|
919
|
+
response: new Interceptors()
|
|
920
|
+
});
|
|
921
|
+
var defaultQuerySerializer = createQuerySerializer({
|
|
922
|
+
allowReserved: false,
|
|
923
|
+
array: {
|
|
924
|
+
explode: true,
|
|
925
|
+
style: "form"
|
|
926
|
+
},
|
|
927
|
+
object: {
|
|
928
|
+
explode: true,
|
|
929
|
+
style: "deepObject"
|
|
930
|
+
}
|
|
931
|
+
});
|
|
932
|
+
var defaultHeaders = {
|
|
933
|
+
"Content-Type": "application/json"
|
|
934
|
+
};
|
|
935
|
+
var createConfig = (override = {}) => ({
|
|
936
|
+
...jsonBodySerializer,
|
|
937
|
+
headers: defaultHeaders,
|
|
938
|
+
parseAs: "auto",
|
|
939
|
+
querySerializer: defaultQuerySerializer,
|
|
940
|
+
...override
|
|
941
|
+
});
|
|
942
|
+
|
|
943
|
+
// src/client/client/client.gen.ts
|
|
944
|
+
var createClient = (config = {}) => {
|
|
945
|
+
let _config = mergeConfigs(createConfig(), config);
|
|
946
|
+
const getConfig = () => ({ ..._config });
|
|
947
|
+
const setConfig = (config2) => {
|
|
948
|
+
_config = mergeConfigs(_config, config2);
|
|
949
|
+
return getConfig();
|
|
950
|
+
};
|
|
951
|
+
const interceptors = createInterceptors();
|
|
952
|
+
const beforeRequest = async (options) => {
|
|
953
|
+
const opts = {
|
|
954
|
+
..._config,
|
|
955
|
+
...options,
|
|
956
|
+
fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
|
|
957
|
+
headers: mergeHeaders(_config.headers, options.headers),
|
|
958
|
+
serializedBody: void 0
|
|
959
|
+
};
|
|
960
|
+
if (opts.security) {
|
|
961
|
+
await setAuthParams({
|
|
962
|
+
...opts,
|
|
963
|
+
security: opts.security
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
if (opts.requestValidator) {
|
|
967
|
+
await opts.requestValidator(opts);
|
|
968
|
+
}
|
|
969
|
+
if (opts.body !== void 0 && opts.bodySerializer) {
|
|
970
|
+
opts.serializedBody = opts.bodySerializer(opts.body);
|
|
971
|
+
}
|
|
972
|
+
if (opts.body === void 0 || opts.serializedBody === "") {
|
|
973
|
+
opts.headers.delete("Content-Type");
|
|
974
|
+
}
|
|
975
|
+
const url = buildUrl(opts);
|
|
976
|
+
return { opts, url };
|
|
977
|
+
};
|
|
978
|
+
const request = async (options) => {
|
|
979
|
+
const { opts, url } = await beforeRequest(options);
|
|
980
|
+
for (const fn of interceptors.request.fns) {
|
|
981
|
+
if (fn) {
|
|
982
|
+
await fn(opts);
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
const _fetch = opts.fetch;
|
|
986
|
+
const requestInit = {
|
|
987
|
+
...opts,
|
|
988
|
+
body: getValidRequestBody(opts)
|
|
989
|
+
};
|
|
990
|
+
let response = await _fetch(url, requestInit);
|
|
991
|
+
for (const fn of interceptors.response.fns) {
|
|
992
|
+
if (fn) {
|
|
993
|
+
response = await fn(response, opts);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
const result = {
|
|
997
|
+
response
|
|
998
|
+
};
|
|
999
|
+
if (response.ok) {
|
|
1000
|
+
const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
|
|
1001
|
+
if (response.status === 204 || response.headers.get("Content-Length") === "0") {
|
|
1002
|
+
let emptyData;
|
|
1003
|
+
switch (parseAs) {
|
|
1004
|
+
case "arrayBuffer":
|
|
1005
|
+
case "blob":
|
|
1006
|
+
case "text":
|
|
1007
|
+
emptyData = await response[parseAs]();
|
|
1008
|
+
break;
|
|
1009
|
+
case "formData":
|
|
1010
|
+
emptyData = new FormData();
|
|
1011
|
+
break;
|
|
1012
|
+
case "stream":
|
|
1013
|
+
emptyData = response.body;
|
|
1014
|
+
break;
|
|
1015
|
+
case "json":
|
|
1016
|
+
default:
|
|
1017
|
+
emptyData = {};
|
|
1018
|
+
break;
|
|
1019
|
+
}
|
|
1020
|
+
return {
|
|
1021
|
+
data: emptyData,
|
|
1022
|
+
...result
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
let data;
|
|
1026
|
+
switch (parseAs) {
|
|
1027
|
+
case "arrayBuffer":
|
|
1028
|
+
case "blob":
|
|
1029
|
+
case "formData":
|
|
1030
|
+
case "json":
|
|
1031
|
+
case "text":
|
|
1032
|
+
data = await response[parseAs]();
|
|
1033
|
+
break;
|
|
1034
|
+
case "stream":
|
|
1035
|
+
return {
|
|
1036
|
+
data: response.body,
|
|
1037
|
+
...result
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
if (parseAs === "json") {
|
|
1041
|
+
if (opts.responseValidator) {
|
|
1042
|
+
await opts.responseValidator(data);
|
|
1043
|
+
}
|
|
1044
|
+
if (opts.responseTransformer) {
|
|
1045
|
+
data = await opts.responseTransformer(data);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
return {
|
|
1049
|
+
data,
|
|
1050
|
+
...result
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
const textError = await response.text();
|
|
1054
|
+
let jsonError;
|
|
1055
|
+
try {
|
|
1056
|
+
jsonError = JSON.parse(textError);
|
|
1057
|
+
} catch {
|
|
1058
|
+
}
|
|
1059
|
+
const error = jsonError ?? textError;
|
|
1060
|
+
let finalError = error;
|
|
1061
|
+
for (const fn of interceptors.error.fns) {
|
|
1062
|
+
if (fn) {
|
|
1063
|
+
finalError = await fn(error, response, opts);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
finalError = finalError || {};
|
|
1067
|
+
if (opts.throwOnError) {
|
|
1068
|
+
throw finalError;
|
|
1069
|
+
}
|
|
1070
|
+
return {
|
|
1071
|
+
error: finalError,
|
|
1072
|
+
...result
|
|
1073
|
+
};
|
|
1074
|
+
};
|
|
1075
|
+
const makeMethodFn = (method) => (options) => request({ ...options, method });
|
|
1076
|
+
const makeSseFn = (method) => async (options) => {
|
|
1077
|
+
const { opts, url } = await beforeRequest(options);
|
|
1078
|
+
return createSseClient({
|
|
1079
|
+
...opts,
|
|
1080
|
+
body: opts.body,
|
|
1081
|
+
headers: opts.headers,
|
|
1082
|
+
method,
|
|
1083
|
+
onRequest: async (url2, init) => {
|
|
1084
|
+
let request2 = new Request(url2, init);
|
|
1085
|
+
const requestInit = {
|
|
1086
|
+
...init,
|
|
1087
|
+
method: init.method,
|
|
1088
|
+
url: url2
|
|
1089
|
+
};
|
|
1090
|
+
for (const fn of interceptors.request.fns) {
|
|
1091
|
+
if (fn) {
|
|
1092
|
+
await fn(requestInit);
|
|
1093
|
+
request2 = new Request(requestInit.url, requestInit);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
return request2;
|
|
1097
|
+
},
|
|
1098
|
+
url
|
|
1099
|
+
});
|
|
1100
|
+
};
|
|
1101
|
+
return {
|
|
1102
|
+
buildUrl,
|
|
1103
|
+
connect: makeMethodFn("CONNECT"),
|
|
1104
|
+
delete: makeMethodFn("DELETE"),
|
|
1105
|
+
get: makeMethodFn("GET"),
|
|
1106
|
+
getConfig,
|
|
1107
|
+
head: makeMethodFn("HEAD"),
|
|
1108
|
+
interceptors,
|
|
1109
|
+
options: makeMethodFn("OPTIONS"),
|
|
1110
|
+
patch: makeMethodFn("PATCH"),
|
|
1111
|
+
post: makeMethodFn("POST"),
|
|
1112
|
+
put: makeMethodFn("PUT"),
|
|
1113
|
+
request,
|
|
1114
|
+
setConfig,
|
|
1115
|
+
sse: {
|
|
1116
|
+
connect: makeSseFn("CONNECT"),
|
|
1117
|
+
delete: makeSseFn("DELETE"),
|
|
1118
|
+
get: makeSseFn("GET"),
|
|
1119
|
+
head: makeSseFn("HEAD"),
|
|
1120
|
+
options: makeSseFn("OPTIONS"),
|
|
1121
|
+
patch: makeSseFn("PATCH"),
|
|
1122
|
+
post: makeSseFn("POST"),
|
|
1123
|
+
put: makeSseFn("PUT"),
|
|
1124
|
+
trace: makeSseFn("TRACE")
|
|
1125
|
+
},
|
|
1126
|
+
trace: makeMethodFn("TRACE")
|
|
1127
|
+
};
|
|
1128
|
+
};
|
|
1129
|
+
|
|
1130
|
+
// src/clientConfig.ts
|
|
1131
|
+
var createClientConfig = (config) => ({
|
|
1132
|
+
...config,
|
|
1133
|
+
baseUrl: "https://ai-portal-dev.zetachain.com"
|
|
1134
|
+
});
|
|
1135
|
+
|
|
1136
|
+
// src/client/client.gen.ts
|
|
1137
|
+
var client = createClient(createClientConfig(createConfig()));
|
|
1138
|
+
|
|
1139
|
+
// src/client/sdk.gen.ts
|
|
1140
|
+
var postApiV1Embeddings = (options) => {
|
|
1141
|
+
return (options.client ?? client).post({
|
|
1142
|
+
url: "/api/v1/embeddings",
|
|
1143
|
+
...options,
|
|
1144
|
+
headers: {
|
|
1145
|
+
"Content-Type": "application/json",
|
|
1146
|
+
...options.headers
|
|
1147
|
+
}
|
|
1148
|
+
});
|
|
1149
|
+
};
|
|
1150
|
+
|
|
1151
|
+
// src/lib/memory/embeddings.ts
|
|
1152
|
+
var generateEmbeddingForText = async (text, options = {}) => {
|
|
1153
|
+
const { model = "openai/text-embedding-3-small", getToken } = options;
|
|
1154
|
+
try {
|
|
1155
|
+
const token = getToken ? await getToken() : null;
|
|
1156
|
+
const headers = {};
|
|
1157
|
+
if (token) {
|
|
1158
|
+
headers.Authorization = `Bearer ${token}`;
|
|
1159
|
+
}
|
|
1160
|
+
const response = await postApiV1Embeddings({
|
|
1161
|
+
body: {
|
|
1162
|
+
input: text,
|
|
1163
|
+
model
|
|
1164
|
+
}
|
|
1165
|
+
// headers,
|
|
1166
|
+
});
|
|
1167
|
+
if (!response.data || !response.data.data || response.data.data.length === 0) {
|
|
1168
|
+
throw new Error(
|
|
1169
|
+
`Failed to generate embedding: ${response.error?.error ?? "No data returned"}`
|
|
1170
|
+
);
|
|
1171
|
+
}
|
|
1172
|
+
const embedding = response.data.data[0]?.embedding;
|
|
1173
|
+
if (!embedding || !Array.isArray(embedding)) {
|
|
1174
|
+
throw new Error("Invalid embedding format returned from API");
|
|
1175
|
+
}
|
|
1176
|
+
return embedding;
|
|
1177
|
+
} catch (error) {
|
|
1178
|
+
console.error("Failed to generate embedding:", error);
|
|
1179
|
+
throw error;
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
var generateEmbeddingForMemory = async (memory, options = {}) => {
|
|
1183
|
+
const text = [
|
|
1184
|
+
memory.rawEvidence,
|
|
1185
|
+
memory.type,
|
|
1186
|
+
memory.namespace,
|
|
1187
|
+
memory.key,
|
|
1188
|
+
memory.value
|
|
1189
|
+
].filter(Boolean).join(" ");
|
|
1190
|
+
return generateEmbeddingForText(text, options);
|
|
1191
|
+
};
|
|
1192
|
+
var generateEmbeddingsForMemories = async (memories, options = {}) => {
|
|
1193
|
+
const { model = "openai/text-embedding-3-small", getToken } = options;
|
|
1194
|
+
const embeddings = /* @__PURE__ */ new Map();
|
|
1195
|
+
for (const memory of memories) {
|
|
1196
|
+
const uniqueKey = `${memory.namespace}:${memory.key}:${memory.value}`;
|
|
1197
|
+
try {
|
|
1198
|
+
const embedding = await generateEmbeddingForMemory(memory, {
|
|
1199
|
+
model,
|
|
1200
|
+
getToken
|
|
1201
|
+
});
|
|
1202
|
+
embeddings.set(uniqueKey, embedding);
|
|
1203
|
+
} catch (error) {
|
|
1204
|
+
console.error(
|
|
1205
|
+
`Failed to generate embedding for memory ${uniqueKey}:`,
|
|
1206
|
+
error
|
|
1207
|
+
);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
return embeddings;
|
|
1211
|
+
};
|
|
1212
|
+
var updateMemoriesWithEmbeddings = async (embeddings, embeddingModel) => {
|
|
1213
|
+
const updates = Array.from(embeddings.entries()).map(
|
|
1214
|
+
async ([uniqueKey, embedding]) => {
|
|
1215
|
+
const existing = await memoryDb.memories.where("uniqueKey").equals(uniqueKey).first();
|
|
1216
|
+
if (existing?.id) {
|
|
1217
|
+
await memoryDb.memories.update(existing.id, {
|
|
1218
|
+
embedding,
|
|
1219
|
+
embeddingModel,
|
|
1220
|
+
updatedAt: Date.now(),
|
|
1221
|
+
createdAt: existing.createdAt
|
|
1222
|
+
});
|
|
1223
|
+
} else {
|
|
1224
|
+
console.warn(
|
|
1225
|
+
`[Embeddings] Memory with uniqueKey ${uniqueKey} not found. It may have been updated or deleted before embedding was generated.`
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
);
|
|
1230
|
+
await Promise.all(updates);
|
|
1231
|
+
};
|
|
1232
|
+
var generateAndStoreEmbeddings = async (memories, options = {}) => {
|
|
1233
|
+
const { model = "openai/text-embedding-3-small" } = options;
|
|
1234
|
+
if (memories.length === 0) {
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1237
|
+
console.log(`Generating embeddings for ${memories.length} memories...`);
|
|
1238
|
+
const embeddings = await generateEmbeddingsForMemories(memories, options);
|
|
1239
|
+
await updateMemoriesWithEmbeddings(embeddings, model);
|
|
1240
|
+
console.log(`Generated and stored ${embeddings.size} embeddings`);
|
|
1241
|
+
};
|
|
1242
|
+
var generateQueryEmbedding = async (query, options = {}) => {
|
|
1243
|
+
return generateEmbeddingForText(query, options);
|
|
1244
|
+
};
|
|
1245
|
+
|
|
1246
|
+
// src/react/useMemory.ts
|
|
1247
|
+
function useMemory(options = {}) {
|
|
1248
|
+
const {
|
|
1249
|
+
memoryModel = "openai/gpt-4o",
|
|
1250
|
+
embeddingModel = "openai/text-embedding-3-small",
|
|
1251
|
+
generateEmbeddings = true,
|
|
1252
|
+
onFactsExtracted,
|
|
1253
|
+
getToken
|
|
1254
|
+
} = options;
|
|
1255
|
+
const extractionInProgressRef = (0, import_react2.useRef)(false);
|
|
1256
|
+
const extractMemoriesFromMessage = (0, import_react2.useCallback)(
|
|
1257
|
+
async (options2) => {
|
|
1258
|
+
const { messages, model } = options2;
|
|
1259
|
+
if (!getToken || extractionInProgressRef.current) {
|
|
1260
|
+
return null;
|
|
1261
|
+
}
|
|
1262
|
+
extractionInProgressRef.current = true;
|
|
1263
|
+
try {
|
|
1264
|
+
const token = await getToken();
|
|
1265
|
+
if (!token) {
|
|
1266
|
+
console.error("No access token available for memory extraction");
|
|
1267
|
+
return null;
|
|
1268
|
+
}
|
|
1269
|
+
const completion = await (0, import_client6.postApiV1ChatCompletions)({
|
|
1270
|
+
body: {
|
|
1271
|
+
messages: [
|
|
1272
|
+
{
|
|
1273
|
+
role: "system",
|
|
1274
|
+
content: FACT_EXTRACTION_PROMPT
|
|
1275
|
+
},
|
|
1276
|
+
...messages
|
|
1277
|
+
],
|
|
1278
|
+
model: model || memoryModel
|
|
1279
|
+
}
|
|
1280
|
+
// headers: {
|
|
1281
|
+
// Authorization: `Bearer ${token}`,
|
|
1282
|
+
// },
|
|
1283
|
+
});
|
|
1284
|
+
if (!completion.data) {
|
|
1285
|
+
console.error(
|
|
1286
|
+
"Memory extraction failed:",
|
|
1287
|
+
completion.error?.error ?? "API did not return a response"
|
|
1288
|
+
);
|
|
1289
|
+
return null;
|
|
1290
|
+
}
|
|
1291
|
+
if (typeof completion.data === "string") {
|
|
1292
|
+
console.error(
|
|
1293
|
+
"Memory extraction failed: API returned a string response instead of a completion object"
|
|
1294
|
+
);
|
|
1295
|
+
return null;
|
|
1296
|
+
}
|
|
1297
|
+
const content = completion.data.choices?.[0]?.message?.content?.trim() || "";
|
|
1298
|
+
if (!content) {
|
|
1299
|
+
console.error("No content in memory extraction response");
|
|
1300
|
+
return null;
|
|
1301
|
+
}
|
|
1302
|
+
let jsonContent = content;
|
|
1303
|
+
jsonContent = jsonContent.replace(/^data:\s*/gm, "").trim();
|
|
1304
|
+
if (jsonContent.startsWith("{")) {
|
|
1305
|
+
let braceCount = 0;
|
|
1306
|
+
let jsonStart = -1;
|
|
1307
|
+
let jsonEnd = -1;
|
|
1308
|
+
for (let i = 0; i < jsonContent.length; i++) {
|
|
1309
|
+
if (jsonContent[i] === "{") {
|
|
1310
|
+
if (jsonStart === -1) jsonStart = i;
|
|
1311
|
+
braceCount++;
|
|
1312
|
+
} else if (jsonContent[i] === "}") {
|
|
1313
|
+
braceCount--;
|
|
1314
|
+
if (braceCount === 0 && jsonStart !== -1) {
|
|
1315
|
+
jsonEnd = i + 1;
|
|
1316
|
+
break;
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
if (jsonStart !== -1 && jsonEnd !== -1) {
|
|
1321
|
+
jsonContent = jsonContent.substring(jsonStart, jsonEnd);
|
|
1322
|
+
}
|
|
1323
|
+
} else {
|
|
1324
|
+
const jsonMatch = jsonContent.match(
|
|
1325
|
+
/```(?:json)?\s*(\{[\s\S]*?\})\s*```/
|
|
1326
|
+
);
|
|
1327
|
+
if (jsonMatch && jsonMatch[1]) {
|
|
1328
|
+
jsonContent = jsonMatch[1].trim();
|
|
1329
|
+
} else {
|
|
1330
|
+
const jsonObjectMatch = jsonContent.match(/\{[\s\S]*\}/);
|
|
1331
|
+
if (jsonObjectMatch && jsonObjectMatch[0]) {
|
|
1332
|
+
jsonContent = jsonObjectMatch[0];
|
|
1333
|
+
} else {
|
|
1334
|
+
console.warn(
|
|
1335
|
+
"Memory extraction returned non-JSON response. The model may not have found any memories to extract, or it returned natural language instead of JSON.",
|
|
1336
|
+
"\nFirst 200 chars of response:",
|
|
1337
|
+
content.substring(0, 200)
|
|
1338
|
+
);
|
|
1339
|
+
return { items: [] };
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
const trimmedJson = jsonContent.trim();
|
|
1344
|
+
if (!trimmedJson.startsWith("{") || !trimmedJson.includes("items")) {
|
|
1345
|
+
console.warn(
|
|
1346
|
+
"Memory extraction response doesn't appear to be valid JSON. The model may not have found any memories to extract, or returned natural language instead of JSON.",
|
|
1347
|
+
"\nResponse preview:",
|
|
1348
|
+
content.substring(0, 200)
|
|
1349
|
+
);
|
|
1350
|
+
return { items: [] };
|
|
1351
|
+
}
|
|
1352
|
+
let result;
|
|
1353
|
+
try {
|
|
1354
|
+
result = JSON.parse(jsonContent);
|
|
1355
|
+
if (!result || typeof result !== "object") {
|
|
1356
|
+
throw new Error("Invalid JSON structure: not an object");
|
|
1357
|
+
}
|
|
1358
|
+
if (!Array.isArray(result.items)) {
|
|
1359
|
+
console.warn(
|
|
1360
|
+
"Memory extraction result missing 'items' array. Result:",
|
|
1361
|
+
result
|
|
1362
|
+
);
|
|
1363
|
+
return { items: [] };
|
|
1364
|
+
}
|
|
1365
|
+
} catch (parseError) {
|
|
1366
|
+
console.error(
|
|
1367
|
+
"Failed to parse memory extraction JSON:",
|
|
1368
|
+
parseError instanceof Error ? parseError.message : parseError
|
|
1369
|
+
);
|
|
1370
|
+
console.error("Attempted to parse:", jsonContent.substring(0, 200));
|
|
1371
|
+
console.error("Full raw content:", content.substring(0, 500));
|
|
1372
|
+
return { items: [] };
|
|
1373
|
+
}
|
|
1374
|
+
if (result.items && Array.isArray(result.items)) {
|
|
1375
|
+
const originalCount = result.items.length;
|
|
1376
|
+
result.items = preprocessMemories(result.items);
|
|
1377
|
+
const filteredCount = result.items.length;
|
|
1378
|
+
if (originalCount !== filteredCount) {
|
|
1379
|
+
console.log(
|
|
1380
|
+
`Preprocessed memories: ${originalCount} -> ${filteredCount} (dropped ${originalCount - filteredCount} entries)`
|
|
1381
|
+
);
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
console.log("Extracted memories:", JSON.stringify(result, null, 2));
|
|
1385
|
+
if (result.items && result.items.length > 0) {
|
|
1386
|
+
try {
|
|
1387
|
+
await saveMemories(result.items);
|
|
1388
|
+
console.log(`Saved ${result.items.length} memories to IndexedDB`);
|
|
1389
|
+
if (generateEmbeddings && embeddingModel) {
|
|
1390
|
+
try {
|
|
1391
|
+
await generateAndStoreEmbeddings(result.items, {
|
|
1392
|
+
model: embeddingModel,
|
|
1393
|
+
getToken: getToken || void 0
|
|
1394
|
+
});
|
|
1395
|
+
console.log(
|
|
1396
|
+
`Generated embeddings for ${result.items.length} memories`
|
|
1397
|
+
);
|
|
1398
|
+
} catch (error) {
|
|
1399
|
+
console.error("Failed to generate embeddings:", error);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
} catch (error) {
|
|
1403
|
+
console.error("Failed to save memories to IndexedDB:", error);
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
if (onFactsExtracted) {
|
|
1407
|
+
onFactsExtracted(result);
|
|
1408
|
+
}
|
|
1409
|
+
return result;
|
|
1410
|
+
} catch (error) {
|
|
1411
|
+
console.error("Failed to extract facts:", error);
|
|
1412
|
+
return null;
|
|
1413
|
+
} finally {
|
|
1414
|
+
extractionInProgressRef.current = false;
|
|
1415
|
+
}
|
|
1416
|
+
},
|
|
1417
|
+
[
|
|
1418
|
+
memoryModel,
|
|
1419
|
+
embeddingModel,
|
|
1420
|
+
generateEmbeddings,
|
|
1421
|
+
getToken,
|
|
1422
|
+
onFactsExtracted
|
|
1423
|
+
]
|
|
1424
|
+
);
|
|
1425
|
+
const searchMemories = (0, import_react2.useCallback)(
|
|
1426
|
+
async (query, limit = 10, minSimilarity = 0.6) => {
|
|
1427
|
+
if (!getToken || !embeddingModel) {
|
|
1428
|
+
console.warn(
|
|
1429
|
+
"Cannot search memories: getToken or embeddingModel not provided"
|
|
1430
|
+
);
|
|
1431
|
+
return [];
|
|
1432
|
+
}
|
|
1433
|
+
try {
|
|
1434
|
+
console.log(`[Memory Search] Searching for: "${query}"`);
|
|
1435
|
+
const queryEmbedding = await generateQueryEmbedding(query, {
|
|
1436
|
+
model: embeddingModel,
|
|
1437
|
+
getToken
|
|
1438
|
+
});
|
|
1439
|
+
console.log(
|
|
1440
|
+
`[Memory Search] Generated query embedding (${queryEmbedding.length} dimensions)`
|
|
1441
|
+
);
|
|
1442
|
+
const results = await searchSimilarMemories(
|
|
1443
|
+
queryEmbedding,
|
|
1444
|
+
limit,
|
|
1445
|
+
minSimilarity
|
|
1446
|
+
);
|
|
1447
|
+
if (results.length === 0) {
|
|
1448
|
+
console.warn(
|
|
1449
|
+
`[Memory Search] No memories found above similarity threshold ${minSimilarity}. Try lowering the threshold or ensure memories have embeddings generated.`
|
|
1450
|
+
);
|
|
1451
|
+
} else {
|
|
1452
|
+
console.log(
|
|
1453
|
+
`[Memory Search] Found ${results.length} memories. Similarity scores: ${results.map((r) => r.similarity.toFixed(3)).join(", ")}`
|
|
1454
|
+
);
|
|
1455
|
+
}
|
|
1456
|
+
return results;
|
|
1457
|
+
} catch (error) {
|
|
1458
|
+
console.error("Failed to search memories:", error);
|
|
1459
|
+
return [];
|
|
1460
|
+
}
|
|
1461
|
+
},
|
|
1462
|
+
[embeddingModel, getToken]
|
|
1463
|
+
);
|
|
1464
|
+
return {
|
|
1465
|
+
extractMemoriesFromMessage,
|
|
1466
|
+
searchMemories
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
// src/lib/memory/chat.ts
|
|
1471
|
+
var formatMemoriesForChat = (memories, format = "compact") => {
|
|
1472
|
+
if (memories.length === 0) {
|
|
1473
|
+
return "";
|
|
1474
|
+
}
|
|
1475
|
+
const sections = [];
|
|
1476
|
+
const byNamespace = /* @__PURE__ */ new Map();
|
|
1477
|
+
for (const memory of memories) {
|
|
1478
|
+
if (!byNamespace.has(memory.namespace)) {
|
|
1479
|
+
byNamespace.set(memory.namespace, []);
|
|
1480
|
+
}
|
|
1481
|
+
byNamespace.get(memory.namespace).push(memory);
|
|
1482
|
+
}
|
|
1483
|
+
for (const [namespace, namespaceMemories] of byNamespace) {
|
|
1484
|
+
const items = [];
|
|
1485
|
+
for (const memory of namespaceMemories) {
|
|
1486
|
+
if (format === "detailed") {
|
|
1487
|
+
items.push(
|
|
1488
|
+
`- ${memory.key}: ${memory.value} (${memory.type}, confidence: ${memory.confidence.toFixed(2)}${memory.similarity ? `, relevance: ${memory.similarity.toFixed(2)}` : ""})`
|
|
1489
|
+
);
|
|
1490
|
+
if (memory.rawEvidence) {
|
|
1491
|
+
items.push(` Evidence: "${memory.rawEvidence}"`);
|
|
1492
|
+
}
|
|
1493
|
+
} else {
|
|
1494
|
+
items.push(`${memory.key}: ${memory.value}`);
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
if (items.length > 0) {
|
|
1498
|
+
sections.push(`[${namespace}]
|
|
1499
|
+
${items.join("\n")}`);
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
return sections.join("\n\n");
|
|
1503
|
+
};
|
|
1504
|
+
var createMemoryContextSystemMessage = (memories, baseSystemPrompt) => {
|
|
1505
|
+
const memoryContext = formatMemoriesForChat(memories, "compact");
|
|
1506
|
+
if (!memoryContext) {
|
|
1507
|
+
return baseSystemPrompt || "";
|
|
1508
|
+
}
|
|
1509
|
+
const memorySection = `## User Context
|
|
1510
|
+
${memoryContext}
|
|
1511
|
+
|
|
1512
|
+
Use this information to provide personalized and relevant responses.`;
|
|
1513
|
+
if (baseSystemPrompt) {
|
|
1514
|
+
return `${baseSystemPrompt}
|
|
1515
|
+
|
|
1516
|
+
${memorySection}`;
|
|
1517
|
+
}
|
|
1518
|
+
return memorySection;
|
|
1519
|
+
};
|
|
1520
|
+
var extractConversationContext = (messages, maxMessages = 3) => {
|
|
1521
|
+
const userMessages = messages.filter((msg) => msg.role === "user").slice(-maxMessages).map((msg) => msg.content).join(" ");
|
|
1522
|
+
return userMessages.trim();
|
|
1523
|
+
};
|
|
87
1524
|
// Annotate the CommonJS export names for ESM import in node:
|
|
88
1525
|
0 && (module.exports = {
|
|
89
|
-
|
|
1526
|
+
createMemoryContextSystemMessage,
|
|
1527
|
+
extractConversationContext,
|
|
1528
|
+
formatMemoriesForChat,
|
|
1529
|
+
useChat,
|
|
1530
|
+
useMemory
|
|
90
1531
|
});
|