@reverbia/sdk 1.0.0-next.20251124100226 → 1.0.0-next.20251125084053
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/react/index.cjs +875 -620
- package/dist/react/index.d.mts +78 -4
- package/dist/react/index.d.ts +78 -4
- package/dist/react/index.mjs +614 -365
- package/package.json +3 -1
package/dist/react/index.cjs
CHANGED
|
@@ -31,575 +31,298 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
createMemoryContextSystemMessage: () => createMemoryContextSystemMessage,
|
|
34
|
+
decryptData: () => decryptData,
|
|
35
|
+
decryptDataBytes: () => decryptDataBytes,
|
|
36
|
+
encryptData: () => encryptData,
|
|
34
37
|
extractConversationContext: () => extractConversationContext,
|
|
35
38
|
formatMemoriesForChat: () => formatMemoriesForChat,
|
|
36
39
|
useChat: () => useChat,
|
|
40
|
+
useEncryption: () => useEncryption,
|
|
37
41
|
useMemory: () => useMemory
|
|
38
42
|
});
|
|
39
43
|
module.exports = __toCommonJS(index_exports);
|
|
40
44
|
|
|
41
45
|
// src/react/useChat.ts
|
|
42
46
|
var import_react = require("react");
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
|
|
48
|
+
// src/client/core/bodySerializer.gen.ts
|
|
49
|
+
var jsonBodySerializer = {
|
|
50
|
+
bodySerializer: (body) => JSON.stringify(
|
|
51
|
+
body,
|
|
52
|
+
(_key, value) => typeof value === "bigint" ? value.toString() : value
|
|
53
|
+
)
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// src/client/core/params.gen.ts
|
|
57
|
+
var extraPrefixesMap = {
|
|
58
|
+
$body_: "body",
|
|
59
|
+
$headers_: "headers",
|
|
60
|
+
$path_: "path",
|
|
61
|
+
$query_: "query"
|
|
62
|
+
};
|
|
63
|
+
var extraPrefixes = Object.entries(extraPrefixesMap);
|
|
64
|
+
|
|
65
|
+
// src/client/core/serverSentEvents.gen.ts
|
|
66
|
+
var createSseClient = ({
|
|
67
|
+
onRequest,
|
|
68
|
+
onSseError,
|
|
69
|
+
onSseEvent,
|
|
70
|
+
responseTransformer,
|
|
71
|
+
responseValidator,
|
|
72
|
+
sseDefaultRetryDelay,
|
|
73
|
+
sseMaxRetryAttempts,
|
|
74
|
+
sseMaxRetryDelay,
|
|
75
|
+
sseSleepFn,
|
|
76
|
+
url,
|
|
77
|
+
...options
|
|
78
|
+
}) => {
|
|
79
|
+
let lastEventId;
|
|
80
|
+
const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
81
|
+
const createStream = async function* () {
|
|
82
|
+
let retryDelay = sseDefaultRetryDelay ?? 3e3;
|
|
83
|
+
let attempt = 0;
|
|
84
|
+
const signal = options.signal ?? new AbortController().signal;
|
|
85
|
+
while (true) {
|
|
86
|
+
if (signal.aborted) break;
|
|
87
|
+
attempt++;
|
|
88
|
+
const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
|
|
89
|
+
if (lastEventId !== void 0) {
|
|
90
|
+
headers.set("Last-Event-ID", lastEventId);
|
|
63
91
|
}
|
|
64
|
-
setIsLoading(true);
|
|
65
92
|
try {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
93
|
+
const requestInit = {
|
|
94
|
+
redirect: "follow",
|
|
95
|
+
...options,
|
|
96
|
+
body: options.serializedBody,
|
|
97
|
+
headers,
|
|
98
|
+
signal
|
|
99
|
+
};
|
|
100
|
+
let request = new Request(url, requestInit);
|
|
101
|
+
if (onRequest) {
|
|
102
|
+
request = await onRequest(url, requestInit);
|
|
71
103
|
}
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
104
|
+
const _fetch = options.fetch ?? globalThis.fetch;
|
|
105
|
+
const response = await _fetch(request);
|
|
106
|
+
if (!response.ok)
|
|
107
|
+
throw new Error(
|
|
108
|
+
`SSE failed: ${response.status} ${response.statusText}`
|
|
109
|
+
);
|
|
110
|
+
if (!response.body) throw new Error("No body in SSE response");
|
|
111
|
+
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
|
|
112
|
+
let buffer = "";
|
|
113
|
+
const abortHandler = () => {
|
|
114
|
+
try {
|
|
115
|
+
reader.cancel();
|
|
116
|
+
} catch {
|
|
79
117
|
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
118
|
+
};
|
|
119
|
+
signal.addEventListener("abort", abortHandler);
|
|
120
|
+
try {
|
|
121
|
+
while (true) {
|
|
122
|
+
const { done, value } = await reader.read();
|
|
123
|
+
if (done) break;
|
|
124
|
+
buffer += value;
|
|
125
|
+
const chunks = buffer.split("\n\n");
|
|
126
|
+
buffer = chunks.pop() ?? "";
|
|
127
|
+
for (const chunk of chunks) {
|
|
128
|
+
const lines = chunk.split("\n");
|
|
129
|
+
const dataLines = [];
|
|
130
|
+
let eventName;
|
|
131
|
+
for (const line of lines) {
|
|
132
|
+
if (line.startsWith("data:")) {
|
|
133
|
+
dataLines.push(line.replace(/^data:\s*/, ""));
|
|
134
|
+
} else if (line.startsWith("event:")) {
|
|
135
|
+
eventName = line.replace(/^event:\s*/, "");
|
|
136
|
+
} else if (line.startsWith("id:")) {
|
|
137
|
+
lastEventId = line.replace(/^id:\s*/, "");
|
|
138
|
+
} else if (line.startsWith("retry:")) {
|
|
139
|
+
const parsed = Number.parseInt(
|
|
140
|
+
line.replace(/^retry:\s*/, ""),
|
|
141
|
+
10
|
|
142
|
+
);
|
|
143
|
+
if (!Number.isNaN(parsed)) {
|
|
144
|
+
retryDelay = parsed;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
let data;
|
|
149
|
+
let parsedJson = false;
|
|
150
|
+
if (dataLines.length) {
|
|
151
|
+
const rawData = dataLines.join("\n");
|
|
152
|
+
try {
|
|
153
|
+
data = JSON.parse(rawData);
|
|
154
|
+
parsedJson = true;
|
|
155
|
+
} catch {
|
|
156
|
+
data = rawData;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (parsedJson) {
|
|
160
|
+
if (responseValidator) {
|
|
161
|
+
await responseValidator(data);
|
|
162
|
+
}
|
|
163
|
+
if (responseTransformer) {
|
|
164
|
+
data = await responseTransformer(data);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
onSseEvent?.({
|
|
168
|
+
data,
|
|
169
|
+
event: eventName,
|
|
170
|
+
id: lastEventId,
|
|
171
|
+
retry: retryDelay
|
|
172
|
+
});
|
|
173
|
+
if (dataLines.length) {
|
|
174
|
+
yield data;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
} finally {
|
|
179
|
+
signal.removeEventListener("abort", abortHandler);
|
|
180
|
+
reader.releaseLock();
|
|
85
181
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
182
|
+
break;
|
|
183
|
+
} catch (error) {
|
|
184
|
+
onSseError?.(error);
|
|
185
|
+
if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
|
|
186
|
+
break;
|
|
90
187
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return { data: null, error };
|
|
188
|
+
const backoff = Math.min(
|
|
189
|
+
retryDelay * 2 ** (attempt - 1),
|
|
190
|
+
sseMaxRetryDelay ?? 3e4
|
|
191
|
+
);
|
|
192
|
+
await sleep(backoff);
|
|
97
193
|
}
|
|
98
|
-
}
|
|
99
|
-
[getToken]
|
|
100
|
-
);
|
|
101
|
-
return {
|
|
102
|
-
isLoading,
|
|
103
|
-
sendMessage
|
|
194
|
+
}
|
|
104
195
|
};
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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):
|
|
196
|
+
const stream = createStream();
|
|
197
|
+
return { stream };
|
|
198
|
+
};
|
|
123
199
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
"
|
|
133
|
-
|
|
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 [];
|
|
200
|
+
// src/client/core/pathSerializer.gen.ts
|
|
201
|
+
var separatorArrayExplode = (style) => {
|
|
202
|
+
switch (style) {
|
|
203
|
+
case "label":
|
|
204
|
+
return ".";
|
|
205
|
+
case "matrix":
|
|
206
|
+
return ";";
|
|
207
|
+
case "simple":
|
|
208
|
+
return ",";
|
|
209
|
+
default:
|
|
210
|
+
return "&";
|
|
167
211
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
return
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
}
|
|
212
|
+
};
|
|
213
|
+
var separatorArrayNoExplode = (style) => {
|
|
214
|
+
switch (style) {
|
|
215
|
+
case "form":
|
|
216
|
+
return ",";
|
|
217
|
+
case "pipeDelimited":
|
|
218
|
+
return "|";
|
|
219
|
+
case "spaceDelimited":
|
|
220
|
+
return "%20";
|
|
221
|
+
default:
|
|
222
|
+
return ",";
|
|
207
223
|
}
|
|
208
|
-
return Array.from(deduplicatedMap.values());
|
|
209
224
|
};
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
memories: "++id, uniqueKey, compositeKey, namespace, key, type, createdAt, updatedAt"
|
|
221
|
-
});
|
|
225
|
+
var separatorObjectExplode = (style) => {
|
|
226
|
+
switch (style) {
|
|
227
|
+
case "label":
|
|
228
|
+
return ".";
|
|
229
|
+
case "matrix":
|
|
230
|
+
return ";";
|
|
231
|
+
case "simple":
|
|
232
|
+
return ",";
|
|
233
|
+
default:
|
|
234
|
+
return "&";
|
|
222
235
|
}
|
|
223
236
|
};
|
|
224
|
-
var
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
} else {
|
|
243
|
-
updateData.embedding = [];
|
|
244
|
-
updateData.embeddingModel = void 0;
|
|
237
|
+
var serializeArrayParam = ({
|
|
238
|
+
allowReserved,
|
|
239
|
+
explode,
|
|
240
|
+
name,
|
|
241
|
+
style,
|
|
242
|
+
value
|
|
243
|
+
}) => {
|
|
244
|
+
if (!explode) {
|
|
245
|
+
const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
|
|
246
|
+
switch (style) {
|
|
247
|
+
case "label":
|
|
248
|
+
return `.${joinedValues2}`;
|
|
249
|
+
case "matrix":
|
|
250
|
+
return `;${name}=${joinedValues2}`;
|
|
251
|
+
case "simple":
|
|
252
|
+
return joinedValues2;
|
|
253
|
+
default:
|
|
254
|
+
return `${name}=${joinedValues2}`;
|
|
245
255
|
}
|
|
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
|
+
const separator = separatorArrayExplode(style);
|
|
258
|
+
const joinedValues = value.map((v) => {
|
|
259
|
+
if (style === "label" || style === "simple") {
|
|
260
|
+
return allowReserved ? v : encodeURIComponent(v);
|
|
261
|
+
}
|
|
262
|
+
return serializePrimitiveParam({
|
|
263
|
+
allowReserved,
|
|
264
|
+
name,
|
|
265
|
+
value: v
|
|
266
|
+
});
|
|
267
|
+
}).join(separator);
|
|
268
|
+
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
256
269
|
};
|
|
257
|
-
var
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
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];
|
|
270
|
+
var serializePrimitiveParam = ({
|
|
271
|
+
allowReserved,
|
|
272
|
+
name,
|
|
273
|
+
value
|
|
274
|
+
}) => {
|
|
275
|
+
if (value === void 0 || value === null) {
|
|
276
|
+
return "";
|
|
274
277
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
+
if (typeof value === "object") {
|
|
279
|
+
throw new Error(
|
|
280
|
+
"Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
|
|
281
|
+
);
|
|
278
282
|
}
|
|
279
|
-
return
|
|
283
|
+
return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
|
|
280
284
|
};
|
|
281
|
-
var
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (
|
|
290
|
-
|
|
291
|
-
"[Memory Search] No memories with embeddings found. Memories may need embeddings generated. Use generateAndStoreEmbeddings() to generate embeddings for existing memories."
|
|
292
|
-
);
|
|
293
|
-
return [];
|
|
285
|
+
var serializeObjectParam = ({
|
|
286
|
+
allowReserved,
|
|
287
|
+
explode,
|
|
288
|
+
name,
|
|
289
|
+
style,
|
|
290
|
+
value,
|
|
291
|
+
valueOnly
|
|
292
|
+
}) => {
|
|
293
|
+
if (value instanceof Date) {
|
|
294
|
+
return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
|
|
294
295
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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
|
-
);
|
|
296
|
+
if (style !== "deepObject" && !explode) {
|
|
297
|
+
let values = [];
|
|
298
|
+
Object.entries(value).forEach(([key, v]) => {
|
|
299
|
+
values = [
|
|
300
|
+
...values,
|
|
301
|
+
key,
|
|
302
|
+
allowReserved ? v : encodeURIComponent(v)
|
|
303
|
+
];
|
|
304
|
+
});
|
|
305
|
+
const joinedValues2 = values.join(",");
|
|
306
|
+
switch (style) {
|
|
307
|
+
case "form":
|
|
308
|
+
return `${name}=${joinedValues2}`;
|
|
309
|
+
case "label":
|
|
310
|
+
return `.${joinedValues2}`;
|
|
311
|
+
case "matrix":
|
|
312
|
+
return `;${name}=${joinedValues2}`;
|
|
313
|
+
default:
|
|
314
|
+
return joinedValues2;
|
|
315
|
+
}
|
|
321
316
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
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;
|
|
317
|
+
const separator = separatorObjectExplode(style);
|
|
318
|
+
const joinedValues = Object.entries(value).map(
|
|
319
|
+
([key, v]) => serializePrimitiveParam({
|
|
320
|
+
allowReserved,
|
|
321
|
+
name: style === "deepObject" ? `${name}[${key}]` : key,
|
|
322
|
+
value: v
|
|
323
|
+
})
|
|
324
|
+
).join(separator);
|
|
325
|
+
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
603
326
|
};
|
|
604
327
|
|
|
605
328
|
// src/client/core/utils.gen.ts
|
|
@@ -1050,91 +773,619 @@ var createClient = (config = {}) => {
|
|
|
1050
773
|
...result
|
|
1051
774
|
};
|
|
1052
775
|
}
|
|
1053
|
-
const textError = await response.text();
|
|
1054
|
-
let jsonError;
|
|
1055
|
-
try {
|
|
1056
|
-
jsonError = JSON.parse(textError);
|
|
1057
|
-
} catch {
|
|
776
|
+
const textError = await response.text();
|
|
777
|
+
let jsonError;
|
|
778
|
+
try {
|
|
779
|
+
jsonError = JSON.parse(textError);
|
|
780
|
+
} catch {
|
|
781
|
+
}
|
|
782
|
+
const error = jsonError ?? textError;
|
|
783
|
+
let finalError = error;
|
|
784
|
+
for (const fn of interceptors.error.fns) {
|
|
785
|
+
if (fn) {
|
|
786
|
+
finalError = await fn(error, response, opts);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
finalError = finalError || {};
|
|
790
|
+
if (opts.throwOnError) {
|
|
791
|
+
throw finalError;
|
|
792
|
+
}
|
|
793
|
+
return {
|
|
794
|
+
error: finalError,
|
|
795
|
+
...result
|
|
796
|
+
};
|
|
797
|
+
};
|
|
798
|
+
const makeMethodFn = (method) => (options) => request({ ...options, method });
|
|
799
|
+
const makeSseFn = (method) => async (options) => {
|
|
800
|
+
const { opts, url } = await beforeRequest(options);
|
|
801
|
+
return createSseClient({
|
|
802
|
+
...opts,
|
|
803
|
+
body: opts.body,
|
|
804
|
+
headers: opts.headers,
|
|
805
|
+
method,
|
|
806
|
+
onRequest: async (url2, init) => {
|
|
807
|
+
let request2 = new Request(url2, init);
|
|
808
|
+
const requestInit = {
|
|
809
|
+
...init,
|
|
810
|
+
method: init.method,
|
|
811
|
+
url: url2
|
|
812
|
+
};
|
|
813
|
+
for (const fn of interceptors.request.fns) {
|
|
814
|
+
if (fn) {
|
|
815
|
+
await fn(requestInit);
|
|
816
|
+
request2 = new Request(requestInit.url, requestInit);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
return request2;
|
|
820
|
+
},
|
|
821
|
+
url
|
|
822
|
+
});
|
|
823
|
+
};
|
|
824
|
+
return {
|
|
825
|
+
buildUrl,
|
|
826
|
+
connect: makeMethodFn("CONNECT"),
|
|
827
|
+
delete: makeMethodFn("DELETE"),
|
|
828
|
+
get: makeMethodFn("GET"),
|
|
829
|
+
getConfig,
|
|
830
|
+
head: makeMethodFn("HEAD"),
|
|
831
|
+
interceptors,
|
|
832
|
+
options: makeMethodFn("OPTIONS"),
|
|
833
|
+
patch: makeMethodFn("PATCH"),
|
|
834
|
+
post: makeMethodFn("POST"),
|
|
835
|
+
put: makeMethodFn("PUT"),
|
|
836
|
+
request,
|
|
837
|
+
setConfig,
|
|
838
|
+
sse: {
|
|
839
|
+
connect: makeSseFn("CONNECT"),
|
|
840
|
+
delete: makeSseFn("DELETE"),
|
|
841
|
+
get: makeSseFn("GET"),
|
|
842
|
+
head: makeSseFn("HEAD"),
|
|
843
|
+
options: makeSseFn("OPTIONS"),
|
|
844
|
+
patch: makeSseFn("PATCH"),
|
|
845
|
+
post: makeSseFn("POST"),
|
|
846
|
+
put: makeSseFn("PUT"),
|
|
847
|
+
trace: makeSseFn("TRACE")
|
|
848
|
+
},
|
|
849
|
+
trace: makeMethodFn("TRACE")
|
|
850
|
+
};
|
|
851
|
+
};
|
|
852
|
+
|
|
853
|
+
// src/clientConfig.ts
|
|
854
|
+
var createClientConfig = (config) => ({
|
|
855
|
+
...config,
|
|
856
|
+
baseUrl: "https://ai-portal-dev.zetachain.com"
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
// src/client/client.gen.ts
|
|
860
|
+
var client = createClient(createClientConfig(createConfig()));
|
|
861
|
+
|
|
862
|
+
// src/react/useChat.ts
|
|
863
|
+
function useChat(options) {
|
|
864
|
+
const { getToken, onData: globalOnData, onFinish, onError } = options || {};
|
|
865
|
+
const [isLoading, setIsLoading] = (0, import_react.useState)(false);
|
|
866
|
+
const abortControllerRef = (0, import_react.useRef)(null);
|
|
867
|
+
const stop = (0, import_react.useCallback)(() => {
|
|
868
|
+
if (abortControllerRef.current) {
|
|
869
|
+
abortControllerRef.current.abort();
|
|
870
|
+
abortControllerRef.current = null;
|
|
871
|
+
}
|
|
872
|
+
}, []);
|
|
873
|
+
(0, import_react.useEffect)(() => {
|
|
874
|
+
return () => {
|
|
875
|
+
if (abortControllerRef.current) {
|
|
876
|
+
abortControllerRef.current.abort();
|
|
877
|
+
abortControllerRef.current = null;
|
|
878
|
+
}
|
|
879
|
+
};
|
|
880
|
+
}, []);
|
|
881
|
+
const sendMessage = (0, import_react.useCallback)(
|
|
882
|
+
async ({
|
|
883
|
+
messages,
|
|
884
|
+
model,
|
|
885
|
+
onData
|
|
886
|
+
}) => {
|
|
887
|
+
if (!messages?.length) {
|
|
888
|
+
const errorMsg = "messages are required to call sendMessage.";
|
|
889
|
+
if (onError) onError(new Error(errorMsg));
|
|
890
|
+
return { data: null, error: errorMsg };
|
|
891
|
+
}
|
|
892
|
+
if (!model) {
|
|
893
|
+
const errorMsg = "model is required to call sendMessage.";
|
|
894
|
+
if (onError) onError(new Error(errorMsg));
|
|
895
|
+
return { data: null, error: errorMsg };
|
|
896
|
+
}
|
|
897
|
+
if (!getToken) {
|
|
898
|
+
const errorMsg = "Token getter function is required.";
|
|
899
|
+
if (onError) onError(new Error(errorMsg));
|
|
900
|
+
return { data: null, error: errorMsg };
|
|
901
|
+
}
|
|
902
|
+
if (abortControllerRef.current) {
|
|
903
|
+
abortControllerRef.current.abort();
|
|
904
|
+
}
|
|
905
|
+
const abortController = new AbortController();
|
|
906
|
+
abortControllerRef.current = abortController;
|
|
907
|
+
setIsLoading(true);
|
|
908
|
+
try {
|
|
909
|
+
const token = await getToken();
|
|
910
|
+
if (!token) {
|
|
911
|
+
const errorMsg = "No access token available.";
|
|
912
|
+
setIsLoading(false);
|
|
913
|
+
if (onError) onError(new Error(errorMsg));
|
|
914
|
+
return { data: null, error: errorMsg };
|
|
915
|
+
}
|
|
916
|
+
const sseResult = await client.sse.post({
|
|
917
|
+
url: "/api/v1/chat/completions",
|
|
918
|
+
body: {
|
|
919
|
+
messages,
|
|
920
|
+
model,
|
|
921
|
+
stream: true
|
|
922
|
+
},
|
|
923
|
+
headers: {
|
|
924
|
+
"Content-Type": "application/json",
|
|
925
|
+
Authorization: `Bearer ${token}`
|
|
926
|
+
},
|
|
927
|
+
signal: abortController.signal
|
|
928
|
+
});
|
|
929
|
+
let accumulatedContent = "";
|
|
930
|
+
let completionId = "";
|
|
931
|
+
let completionModel = "";
|
|
932
|
+
let usage;
|
|
933
|
+
let finishReason;
|
|
934
|
+
for await (const chunk of sseResult.stream) {
|
|
935
|
+
if (typeof chunk === "string" && (chunk.trim() === "[DONE]" || chunk.includes("[DONE]"))) {
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
938
|
+
if (chunk && typeof chunk === "object") {
|
|
939
|
+
const chunkData = chunk;
|
|
940
|
+
if (chunkData.id && !completionId) {
|
|
941
|
+
completionId = chunkData.id;
|
|
942
|
+
}
|
|
943
|
+
if (chunkData.model && !completionModel) {
|
|
944
|
+
completionModel = chunkData.model;
|
|
945
|
+
}
|
|
946
|
+
if (chunkData.usage) {
|
|
947
|
+
usage = chunkData.usage;
|
|
948
|
+
}
|
|
949
|
+
if (chunkData.choices && Array.isArray(chunkData.choices) && chunkData.choices.length > 0) {
|
|
950
|
+
const choice = chunkData.choices[0];
|
|
951
|
+
if (choice.delta?.content) {
|
|
952
|
+
const content = choice.delta.content;
|
|
953
|
+
accumulatedContent += content;
|
|
954
|
+
if (onData) {
|
|
955
|
+
onData(content);
|
|
956
|
+
}
|
|
957
|
+
if (globalOnData) {
|
|
958
|
+
globalOnData(content);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
if (choice.finish_reason) {
|
|
962
|
+
finishReason = choice.finish_reason;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
const completion = {
|
|
968
|
+
id: completionId,
|
|
969
|
+
model: completionModel,
|
|
970
|
+
choices: [
|
|
971
|
+
{
|
|
972
|
+
index: 0,
|
|
973
|
+
message: {
|
|
974
|
+
role: "assistant",
|
|
975
|
+
content: accumulatedContent
|
|
976
|
+
},
|
|
977
|
+
finish_reason: finishReason
|
|
978
|
+
}
|
|
979
|
+
],
|
|
980
|
+
usage
|
|
981
|
+
};
|
|
982
|
+
setIsLoading(false);
|
|
983
|
+
if (onFinish) {
|
|
984
|
+
onFinish(completion);
|
|
985
|
+
}
|
|
986
|
+
return { data: completion, error: null };
|
|
987
|
+
} catch (err) {
|
|
988
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
989
|
+
setIsLoading(false);
|
|
990
|
+
return { data: null, error: "Request aborted" };
|
|
991
|
+
}
|
|
992
|
+
const errorMsg = err instanceof Error ? err.message : "Failed to send message.";
|
|
993
|
+
const errorObj = err instanceof Error ? err : new Error(errorMsg);
|
|
994
|
+
setIsLoading(false);
|
|
995
|
+
if (onError) {
|
|
996
|
+
onError(errorObj);
|
|
997
|
+
}
|
|
998
|
+
return { data: null, error: errorMsg };
|
|
999
|
+
} finally {
|
|
1000
|
+
if (abortControllerRef.current === abortController) {
|
|
1001
|
+
abortControllerRef.current = null;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
},
|
|
1005
|
+
[getToken, globalOnData, onFinish, onError]
|
|
1006
|
+
);
|
|
1007
|
+
return {
|
|
1008
|
+
isLoading,
|
|
1009
|
+
sendMessage,
|
|
1010
|
+
stop
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
// src/react/useEncryption.ts
|
|
1015
|
+
var import_react2 = require("react");
|
|
1016
|
+
var import_react_auth = require("@privy-io/react-auth");
|
|
1017
|
+
var SIGN_MESSAGE = "The app is asking you to sign this message to generate a key, which will be used to encrypt data.";
|
|
1018
|
+
var SIGNATURE_STORAGE_KEY = "privy_encryption_key";
|
|
1019
|
+
function getStorageItem(key) {
|
|
1020
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
1021
|
+
return null;
|
|
1022
|
+
}
|
|
1023
|
+
try {
|
|
1024
|
+
return localStorage.getItem(key);
|
|
1025
|
+
} catch {
|
|
1026
|
+
return null;
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
function setStorageItem(key, value) {
|
|
1030
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
1031
|
+
return false;
|
|
1032
|
+
}
|
|
1033
|
+
try {
|
|
1034
|
+
localStorage.setItem(key, value);
|
|
1035
|
+
return true;
|
|
1036
|
+
} catch {
|
|
1037
|
+
return false;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
function hexToBytes(hex) {
|
|
1041
|
+
const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
1042
|
+
const bytes = new Uint8Array(cleanHex.length / 2);
|
|
1043
|
+
for (let i = 0; i < cleanHex.length; i += 2) {
|
|
1044
|
+
bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
|
|
1045
|
+
}
|
|
1046
|
+
return bytes;
|
|
1047
|
+
}
|
|
1048
|
+
function bytesToHex(bytes) {
|
|
1049
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1050
|
+
}
|
|
1051
|
+
async function deriveKeyFromSignature(signature) {
|
|
1052
|
+
const sigBytes = hexToBytes(signature);
|
|
1053
|
+
const hashBuffer = await crypto.subtle.digest(
|
|
1054
|
+
"SHA-256",
|
|
1055
|
+
sigBytes.buffer
|
|
1056
|
+
);
|
|
1057
|
+
const hashBytes = new Uint8Array(hashBuffer);
|
|
1058
|
+
return bytesToHex(hashBytes);
|
|
1059
|
+
}
|
|
1060
|
+
async function getEncryptionKey() {
|
|
1061
|
+
const keyHex = getStorageItem(SIGNATURE_STORAGE_KEY);
|
|
1062
|
+
if (!keyHex) {
|
|
1063
|
+
throw new Error("Encryption key not found. Please sign in first.");
|
|
1064
|
+
}
|
|
1065
|
+
const keyBytes = hexToBytes(keyHex);
|
|
1066
|
+
return crypto.subtle.importKey(
|
|
1067
|
+
"raw",
|
|
1068
|
+
keyBytes.buffer,
|
|
1069
|
+
{ name: "AES-GCM" },
|
|
1070
|
+
false,
|
|
1071
|
+
["encrypt", "decrypt"]
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
1074
|
+
async function encryptData(plaintext) {
|
|
1075
|
+
const key = await getEncryptionKey();
|
|
1076
|
+
const plaintextBytes = typeof plaintext === "string" ? new TextEncoder().encode(plaintext) : plaintext;
|
|
1077
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
1078
|
+
const encryptedData = await crypto.subtle.encrypt(
|
|
1079
|
+
{
|
|
1080
|
+
name: "AES-GCM",
|
|
1081
|
+
iv
|
|
1082
|
+
},
|
|
1083
|
+
key,
|
|
1084
|
+
plaintextBytes.buffer
|
|
1085
|
+
);
|
|
1086
|
+
const encryptedBytes = new Uint8Array(encryptedData);
|
|
1087
|
+
const combined = new Uint8Array(iv.length + encryptedBytes.length);
|
|
1088
|
+
combined.set(iv, 0);
|
|
1089
|
+
combined.set(encryptedBytes, iv.length);
|
|
1090
|
+
return bytesToHex(combined);
|
|
1091
|
+
}
|
|
1092
|
+
async function decryptData(encryptedHex) {
|
|
1093
|
+
const key = await getEncryptionKey();
|
|
1094
|
+
const combined = hexToBytes(encryptedHex);
|
|
1095
|
+
const iv = combined.slice(0, 12);
|
|
1096
|
+
const encryptedData = combined.slice(12);
|
|
1097
|
+
const decryptedData = await crypto.subtle.decrypt(
|
|
1098
|
+
{
|
|
1099
|
+
name: "AES-GCM",
|
|
1100
|
+
iv
|
|
1101
|
+
},
|
|
1102
|
+
key,
|
|
1103
|
+
encryptedData
|
|
1104
|
+
);
|
|
1105
|
+
return new TextDecoder().decode(decryptedData);
|
|
1106
|
+
}
|
|
1107
|
+
async function decryptDataBytes(encryptedHex) {
|
|
1108
|
+
const key = await getEncryptionKey();
|
|
1109
|
+
const combined = hexToBytes(encryptedHex);
|
|
1110
|
+
const iv = combined.slice(0, 12);
|
|
1111
|
+
const encryptedData = combined.slice(12);
|
|
1112
|
+
const decryptedData = await crypto.subtle.decrypt(
|
|
1113
|
+
{
|
|
1114
|
+
name: "AES-GCM",
|
|
1115
|
+
iv
|
|
1116
|
+
},
|
|
1117
|
+
key,
|
|
1118
|
+
encryptedData
|
|
1119
|
+
);
|
|
1120
|
+
return new Uint8Array(decryptedData);
|
|
1121
|
+
}
|
|
1122
|
+
function useEncryption(authenticated) {
|
|
1123
|
+
const { signMessage } = (0, import_react_auth.useSignMessage)();
|
|
1124
|
+
const { wallets } = (0, import_react_auth.useWallets)();
|
|
1125
|
+
const hasRequestedSignature = (0, import_react2.useRef)(false);
|
|
1126
|
+
const hasCheckedStorage = (0, import_react2.useRef)(false);
|
|
1127
|
+
(0, import_react2.useEffect)(() => {
|
|
1128
|
+
if (!authenticated || wallets.length === 0) {
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1131
|
+
const existingKey = getStorageItem(SIGNATURE_STORAGE_KEY);
|
|
1132
|
+
if (existingKey) {
|
|
1133
|
+
if (!hasCheckedStorage.current) {
|
|
1134
|
+
hasCheckedStorage.current = true;
|
|
1135
|
+
}
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
const requestSignature = async () => {
|
|
1139
|
+
if (!hasRequestedSignature.current) {
|
|
1140
|
+
hasRequestedSignature.current = true;
|
|
1141
|
+
try {
|
|
1142
|
+
const { signature } = await signMessage(
|
|
1143
|
+
{ message: SIGN_MESSAGE },
|
|
1144
|
+
{
|
|
1145
|
+
address: wallets[0].address
|
|
1146
|
+
}
|
|
1147
|
+
);
|
|
1148
|
+
const encryptionKey = await deriveKeyFromSignature(signature);
|
|
1149
|
+
const stored = setStorageItem(SIGNATURE_STORAGE_KEY, encryptionKey);
|
|
1150
|
+
if (!stored) {
|
|
1151
|
+
throw new Error("Failed to store encryption key in localStorage");
|
|
1152
|
+
}
|
|
1153
|
+
} catch (error) {
|
|
1154
|
+
hasRequestedSignature.current = false;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
};
|
|
1158
|
+
requestSignature();
|
|
1159
|
+
}, [
|
|
1160
|
+
authenticated,
|
|
1161
|
+
wallets.length > 0 ? wallets[0]?.address : null,
|
|
1162
|
+
signMessage
|
|
1163
|
+
]);
|
|
1164
|
+
(0, import_react2.useEffect)(() => {
|
|
1165
|
+
if (!authenticated) {
|
|
1166
|
+
hasRequestedSignature.current = false;
|
|
1167
|
+
hasCheckedStorage.current = false;
|
|
1168
|
+
}
|
|
1169
|
+
}, [authenticated]);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
// src/react/useMemory.ts
|
|
1173
|
+
var import_react3 = require("react");
|
|
1174
|
+
var import_client6 = require("@reverbia/sdk");
|
|
1175
|
+
|
|
1176
|
+
// src/lib/memory/service.ts
|
|
1177
|
+
var FACT_EXTRACTION_PROMPT = `You are a memory extraction system. Extract durable user memories from chat messages.
|
|
1178
|
+
|
|
1179
|
+
CRITICAL: You MUST respond with ONLY valid JSON. No explanations, no markdown, no code blocks, just pure JSON.
|
|
1180
|
+
|
|
1181
|
+
Only extract facts that will be useful in future conversations, such as identity, stable preferences, ongoing projects, skills, and constraints.
|
|
1182
|
+
|
|
1183
|
+
Do not extract sensitive attributes, temporary things, or single-use instructions.
|
|
1184
|
+
|
|
1185
|
+
If there are no memories to extract, return: {"items": []}
|
|
1186
|
+
|
|
1187
|
+
Response format (JSON only, no other text):
|
|
1188
|
+
|
|
1189
|
+
{
|
|
1190
|
+
"items": [
|
|
1191
|
+
{
|
|
1192
|
+
"type": "identity",
|
|
1193
|
+
"namespace": "identity",
|
|
1194
|
+
"key": "name",
|
|
1195
|
+
"value": "Charlie",
|
|
1196
|
+
"rawEvidence": "I'm Charlie",
|
|
1197
|
+
"confidence": 0.98,
|
|
1198
|
+
"pii": true
|
|
1199
|
+
},
|
|
1200
|
+
{
|
|
1201
|
+
"type": "identity",
|
|
1202
|
+
"namespace": "work",
|
|
1203
|
+
"key": "company",
|
|
1204
|
+
"value": "ZetaChain",
|
|
1205
|
+
"rawEvidence": "called ZetaChain",
|
|
1206
|
+
"confidence": 0.99,
|
|
1207
|
+
"pii": false
|
|
1208
|
+
},
|
|
1209
|
+
{
|
|
1210
|
+
"type": "preference",
|
|
1211
|
+
"namespace": "answer_style",
|
|
1212
|
+
"key": "verbosity",
|
|
1213
|
+
"value": "concise_direct",
|
|
1214
|
+
"rawEvidence": "I prefer concise, direct answers",
|
|
1215
|
+
"confidence": 0.96,
|
|
1216
|
+
"pii": false
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
"type": "identity",
|
|
1220
|
+
"namespace": "timezone",
|
|
1221
|
+
"key": "tz",
|
|
1222
|
+
"value": "America/Los_Angeles",
|
|
1223
|
+
"rawEvidence": "I'm in PST",
|
|
1224
|
+
"confidence": 0.9,
|
|
1225
|
+
"pii": false
|
|
1226
|
+
}
|
|
1227
|
+
]
|
|
1228
|
+
}`;
|
|
1229
|
+
var preprocessMemories = (items, minConfidence = 0.6) => {
|
|
1230
|
+
if (!items || !Array.isArray(items)) {
|
|
1231
|
+
return [];
|
|
1232
|
+
}
|
|
1233
|
+
const validItems = items.filter((item) => {
|
|
1234
|
+
if (item.namespace == null || item.key == null || item.value == null) {
|
|
1235
|
+
console.warn(
|
|
1236
|
+
"Dropping memory item with null/undefined namespace, key, or value:",
|
|
1237
|
+
item
|
|
1238
|
+
);
|
|
1239
|
+
return false;
|
|
1058
1240
|
}
|
|
1059
|
-
const
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1241
|
+
const namespace = String(item.namespace).trim();
|
|
1242
|
+
const key = String(item.key).trim();
|
|
1243
|
+
const value = String(item.value).trim();
|
|
1244
|
+
if (namespace === "" || key === "" || value === "") {
|
|
1245
|
+
console.warn(
|
|
1246
|
+
"Dropping memory item with empty namespace, key, or value after trimming:",
|
|
1247
|
+
item
|
|
1248
|
+
);
|
|
1249
|
+
return false;
|
|
1065
1250
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1251
|
+
if (typeof item.confidence !== "number" || item.confidence < minConfidence) {
|
|
1252
|
+
console.warn(
|
|
1253
|
+
`Dropping memory item with confidence ${item.confidence} below threshold ${minConfidence}:`,
|
|
1254
|
+
item
|
|
1255
|
+
);
|
|
1256
|
+
return false;
|
|
1069
1257
|
}
|
|
1070
|
-
return
|
|
1071
|
-
|
|
1072
|
-
|
|
1258
|
+
return true;
|
|
1259
|
+
});
|
|
1260
|
+
const deduplicatedMap = /* @__PURE__ */ new Map();
|
|
1261
|
+
for (const item of validItems) {
|
|
1262
|
+
const uniqueKey = `${item.namespace}:${item.key}:${item.value}`;
|
|
1263
|
+
const existing = deduplicatedMap.get(uniqueKey);
|
|
1264
|
+
if (!existing || item.confidence > existing.confidence) {
|
|
1265
|
+
deduplicatedMap.set(uniqueKey, item);
|
|
1266
|
+
} else {
|
|
1267
|
+
console.debug(
|
|
1268
|
+
`Deduplicating memory item: keeping entry with higher confidence (${existing.confidence} > ${item.confidence})`,
|
|
1269
|
+
{ namespace: item.namespace, key: item.key, value: item.value }
|
|
1270
|
+
);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
return Array.from(deduplicatedMap.values());
|
|
1274
|
+
};
|
|
1275
|
+
|
|
1276
|
+
// src/lib/memory/db.ts
|
|
1277
|
+
var import_dexie = __toESM(require("dexie"));
|
|
1278
|
+
var MemoryDatabase = class extends import_dexie.default {
|
|
1279
|
+
constructor() {
|
|
1280
|
+
super("MemoryDatabase");
|
|
1281
|
+
this.version(2).stores({
|
|
1282
|
+
memories: "++id, uniqueKey, compositeKey, namespace, key, type, createdAt, updatedAt"
|
|
1283
|
+
});
|
|
1284
|
+
this.version(3).stores({
|
|
1285
|
+
memories: "++id, uniqueKey, compositeKey, namespace, key, type, createdAt, updatedAt"
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
};
|
|
1289
|
+
var memoryDb = new MemoryDatabase();
|
|
1290
|
+
var saveMemory = async (memory) => {
|
|
1291
|
+
const compositeKey = `${memory.namespace}:${memory.key}`;
|
|
1292
|
+
const uniqueKey = `${memory.namespace}:${memory.key}:${memory.value}`;
|
|
1293
|
+
const now = Date.now();
|
|
1294
|
+
const existing = await memoryDb.memories.where("uniqueKey").equals(uniqueKey).first();
|
|
1295
|
+
if (existing) {
|
|
1296
|
+
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;
|
|
1297
|
+
const updateData = {
|
|
1298
|
+
...memory,
|
|
1299
|
+
compositeKey,
|
|
1300
|
+
uniqueKey,
|
|
1301
|
+
updatedAt: now,
|
|
1302
|
+
createdAt: existing.createdAt
|
|
1073
1303
|
};
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
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
|
|
1304
|
+
if (shouldPreserveEmbedding) {
|
|
1305
|
+
updateData.embedding = existing.embedding;
|
|
1306
|
+
updateData.embeddingModel = existing.embeddingModel;
|
|
1307
|
+
} else {
|
|
1308
|
+
updateData.embedding = [];
|
|
1309
|
+
updateData.embeddingModel = void 0;
|
|
1310
|
+
}
|
|
1311
|
+
await memoryDb.memories.update(existing.id, updateData);
|
|
1312
|
+
} else {
|
|
1313
|
+
await memoryDb.memories.add({
|
|
1314
|
+
...memory,
|
|
1315
|
+
compositeKey,
|
|
1316
|
+
uniqueKey,
|
|
1317
|
+
createdAt: now,
|
|
1318
|
+
updatedAt: now
|
|
1099
1319
|
});
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1320
|
+
}
|
|
1321
|
+
};
|
|
1322
|
+
var saveMemories = async (memories) => {
|
|
1323
|
+
await Promise.all(memories.map((memory) => saveMemory(memory)));
|
|
1324
|
+
};
|
|
1325
|
+
var getAllMemories = async () => {
|
|
1326
|
+
return memoryDb.memories.toArray();
|
|
1327
|
+
};
|
|
1328
|
+
var cosineSimilarity = (a, b) => {
|
|
1329
|
+
if (a.length !== b.length) {
|
|
1330
|
+
throw new Error("Vectors must have the same length");
|
|
1331
|
+
}
|
|
1332
|
+
let dotProduct = 0;
|
|
1333
|
+
let normA = 0;
|
|
1334
|
+
let normB = 0;
|
|
1335
|
+
for (let i = 0; i < a.length; i++) {
|
|
1336
|
+
dotProduct += a[i] * b[i];
|
|
1337
|
+
normA += a[i] * a[i];
|
|
1338
|
+
normB += b[i] * b[i];
|
|
1339
|
+
}
|
|
1340
|
+
const denominator = Math.sqrt(normA) * Math.sqrt(normB);
|
|
1341
|
+
if (denominator === 0) {
|
|
1342
|
+
return 0;
|
|
1343
|
+
}
|
|
1344
|
+
return dotProduct / denominator;
|
|
1345
|
+
};
|
|
1346
|
+
var searchSimilarMemories = async (queryEmbedding, limit = 10, minSimilarity = 0.6) => {
|
|
1347
|
+
const allMemories = await getAllMemories();
|
|
1348
|
+
const memoriesWithEmbeddings = allMemories.filter(
|
|
1349
|
+
(m) => m.embedding && m.embedding.length > 0
|
|
1350
|
+
);
|
|
1351
|
+
console.log(
|
|
1352
|
+
`[Memory Search] Total memories: ${allMemories.length}, memories with embeddings: ${memoriesWithEmbeddings.length}`
|
|
1353
|
+
);
|
|
1354
|
+
if (memoriesWithEmbeddings.length === 0) {
|
|
1355
|
+
console.warn(
|
|
1356
|
+
"[Memory Search] No memories with embeddings found. Memories may need embeddings generated. Use generateAndStoreEmbeddings() to generate embeddings for existing memories."
|
|
1357
|
+
);
|
|
1358
|
+
return [];
|
|
1359
|
+
}
|
|
1360
|
+
const allResults = memoriesWithEmbeddings.map((memory) => {
|
|
1361
|
+
const similarity = cosineSimilarity(queryEmbedding, memory.embedding);
|
|
1362
|
+
return {
|
|
1363
|
+
...memory,
|
|
1364
|
+
similarity
|
|
1365
|
+
};
|
|
1366
|
+
}).sort((a, b) => b.similarity - a.similarity);
|
|
1367
|
+
console.log(
|
|
1368
|
+
`[Memory Search] All similarity scores:`,
|
|
1369
|
+
allResults.map((r) => ({
|
|
1370
|
+
key: `${r.namespace}:${r.key}`,
|
|
1371
|
+
value: r.value,
|
|
1372
|
+
similarity: r.similarity.toFixed(4)
|
|
1373
|
+
}))
|
|
1374
|
+
);
|
|
1375
|
+
const results = allResults.filter((result) => result.similarity >= minSimilarity).slice(0, limit);
|
|
1376
|
+
if (results.length === 0 && allResults.length > 0) {
|
|
1377
|
+
const topSimilarity = allResults[0].similarity;
|
|
1378
|
+
const suggestedThreshold = Math.max(0.3, topSimilarity - 0.1);
|
|
1379
|
+
console.warn(
|
|
1380
|
+
`[Memory Search] No memories above threshold ${minSimilarity}. Highest similarity was ${topSimilarity.toFixed(4)}. Consider lowering the threshold to ${suggestedThreshold.toFixed(2)}`
|
|
1381
|
+
);
|
|
1382
|
+
} else {
|
|
1383
|
+
console.log(
|
|
1384
|
+
`[Memory Search] Found ${results.length} memories above similarity threshold ${minSimilarity}. Top similarity: ${results[0]?.similarity.toFixed(4) || "N/A"}`
|
|
1385
|
+
);
|
|
1386
|
+
}
|
|
1387
|
+
return results;
|
|
1128
1388
|
};
|
|
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
1389
|
|
|
1139
1390
|
// src/client/sdk.gen.ts
|
|
1140
1391
|
var postApiV1Embeddings = (options) => {
|
|
@@ -1252,8 +1503,8 @@ function useMemory(options = {}) {
|
|
|
1252
1503
|
onFactsExtracted,
|
|
1253
1504
|
getToken
|
|
1254
1505
|
} = options;
|
|
1255
|
-
const extractionInProgressRef = (0,
|
|
1256
|
-
const extractMemoriesFromMessage = (0,
|
|
1506
|
+
const extractionInProgressRef = (0, import_react3.useRef)(false);
|
|
1507
|
+
const extractMemoriesFromMessage = (0, import_react3.useCallback)(
|
|
1257
1508
|
async (options2) => {
|
|
1258
1509
|
const { messages, model } = options2;
|
|
1259
1510
|
if (!getToken || extractionInProgressRef.current) {
|
|
@@ -1422,7 +1673,7 @@ function useMemory(options = {}) {
|
|
|
1422
1673
|
onFactsExtracted
|
|
1423
1674
|
]
|
|
1424
1675
|
);
|
|
1425
|
-
const searchMemories = (0,
|
|
1676
|
+
const searchMemories = (0, import_react3.useCallback)(
|
|
1426
1677
|
async (query, limit = 10, minSimilarity = 0.6) => {
|
|
1427
1678
|
if (!getToken || !embeddingModel) {
|
|
1428
1679
|
console.warn(
|
|
@@ -1524,8 +1775,12 @@ var extractConversationContext = (messages, maxMessages = 3) => {
|
|
|
1524
1775
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1525
1776
|
0 && (module.exports = {
|
|
1526
1777
|
createMemoryContextSystemMessage,
|
|
1778
|
+
decryptData,
|
|
1779
|
+
decryptDataBytes,
|
|
1780
|
+
encryptData,
|
|
1527
1781
|
extractConversationContext,
|
|
1528
1782
|
formatMemoriesForChat,
|
|
1529
1783
|
useChat,
|
|
1784
|
+
useEncryption,
|
|
1530
1785
|
useMemory
|
|
1531
1786
|
});
|