@diegoaltoworks/chatter 1.0.0 → 2.1.0
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/README.md +3 -1
- package/dist/channels/gates.d.ts +21 -2
- package/dist/channels/gates.d.ts.map +1 -1
- package/dist/channels/index.d.ts +5 -3
- package/dist/channels/index.d.ts.map +1 -1
- package/dist/channels/index.js +31 -13
- package/dist/channels/index.mjs +30 -13
- package/dist/channels/matrix/channel.d.ts +2 -0
- package/dist/channels/matrix/channel.d.ts.map +1 -1
- package/dist/channels/matrix/handler.d.ts +9 -0
- package/dist/channels/matrix/handler.d.ts.map +1 -1
- package/dist/channels/matrix/index.d.ts +1 -1
- package/dist/channels/matrix/index.d.ts.map +1 -1
- package/dist/channels/matrix/index.js +75 -20
- package/dist/channels/matrix/index.mjs +74 -20
- package/dist/channels/matrix/updates.d.ts +8 -2
- package/dist/channels/matrix/updates.d.ts.map +1 -1
- package/dist/channels/pipeline.d.ts +34 -4
- package/dist/channels/pipeline.d.ts.map +1 -1
- package/dist/channels/polling.d.ts +11 -0
- package/dist/channels/polling.d.ts.map +1 -1
- package/dist/channels/telegram/channel.d.ts +2 -0
- package/dist/channels/telegram/channel.d.ts.map +1 -1
- package/dist/channels/telegram/handler.d.ts +9 -0
- package/dist/channels/telegram/handler.d.ts.map +1 -1
- package/dist/channels/telegram/index.d.ts +1 -1
- package/dist/channels/telegram/index.d.ts.map +1 -1
- package/dist/channels/telegram/index.js +73 -24
- package/dist/channels/telegram/index.mjs +72 -24
- package/dist/channels/telegram/updates.d.ts +8 -2
- package/dist/channels/telegram/updates.d.ts.map +1 -1
- package/dist/channels/telegram/webhook.d.ts +10 -0
- package/dist/channels/telegram/webhook.d.ts.map +1 -1
- package/dist/channels/whatsapp/channel.d.ts +8 -0
- package/dist/channels/whatsapp/channel.d.ts.map +1 -1
- package/dist/channels/whatsapp/inbound.d.ts +2 -0
- package/dist/channels/whatsapp/inbound.d.ts.map +1 -1
- package/dist/channels/whatsapp/index.js +45 -18
- package/dist/channels/whatsapp/index.mjs +45 -18
- package/dist/core/answer.d.ts +9 -2
- package/dist/core/answer.d.ts.map +1 -1
- package/dist/core/chunking.d.ts +31 -0
- package/dist/core/chunking.d.ts.map +1 -0
- package/dist/core/guardrails.d.ts +11 -1
- package/dist/core/guardrails.d.ts.map +1 -1
- package/dist/core/llm.d.ts +3 -1
- package/dist/core/llm.d.ts.map +1 -1
- package/dist/core/retrieval.d.ts +39 -0
- package/dist/core/retrieval.d.ts.map +1 -1
- package/dist/history/index.js +12 -9
- package/dist/history/index.mjs +12 -9
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +261 -52
- package/dist/index.mjs +254 -47
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +217 -30
- package/dist/mcp-server.mjs +216 -29
- package/dist/personas/index.d.ts +1 -1
- package/dist/personas/index.d.ts.map +1 -1
- package/dist/personas/index.js +21 -7
- package/dist/personas/index.mjs +21 -7
- package/dist/personas/resolver.d.ts +35 -8
- package/dist/personas/resolver.d.ts.map +1 -1
- package/dist/personas/timeContext.d.ts.map +1 -1
- package/dist/routes/demo.d.ts.map +1 -1
- package/dist/routes/openai.d.ts.map +1 -1
- package/dist/routes/private.d.ts.map +1 -1
- package/dist/routes/public.d.ts.map +1 -1
- package/dist/scheduler/index.js +12 -9
- package/dist/scheduler/index.mjs +12 -9
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +251 -50
- package/dist/server.mjs +246 -45
- package/dist/types.d.ts +39 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +13 -13
package/dist/mcp-server.mjs
CHANGED
|
@@ -92,6 +92,126 @@ var init_buildLock = __esm({
|
|
|
92
92
|
}
|
|
93
93
|
});
|
|
94
94
|
|
|
95
|
+
// src/core/chunking.ts
|
|
96
|
+
function headingOf(line) {
|
|
97
|
+
const match = HEADING.exec(line);
|
|
98
|
+
if (!match) return void 0;
|
|
99
|
+
const title = (match[2] ?? "").replace(/[ \t]+#+$/, "").replace(/^#+$/, "").trim();
|
|
100
|
+
return { level: match[1].length, title };
|
|
101
|
+
}
|
|
102
|
+
function startsTable(lines, i) {
|
|
103
|
+
return lines[i].includes("|") && i + 1 < lines.length && TABLE_DELIMITER.test(lines[i + 1]);
|
|
104
|
+
}
|
|
105
|
+
function fenceEnd(lines, start) {
|
|
106
|
+
const opener = FENCE.exec(lines[start]);
|
|
107
|
+
if (!opener) return start + 1;
|
|
108
|
+
const marker = opener[1];
|
|
109
|
+
const closer = new RegExp(`^ {0,3}${marker[0] === "`" ? "`" : "~"}{${marker.length},}[ \\t]*$`);
|
|
110
|
+
for (let i = start + 1; i < lines.length; i++) if (closer.test(lines[i])) return i + 1;
|
|
111
|
+
return lines.length;
|
|
112
|
+
}
|
|
113
|
+
function listEnd(lines, start) {
|
|
114
|
+
let end = start + 1;
|
|
115
|
+
for (let i = start + 1; i < lines.length; i++) {
|
|
116
|
+
const line = lines[i];
|
|
117
|
+
if (isBlank(line)) {
|
|
118
|
+
let next = i + 1;
|
|
119
|
+
while (next < lines.length && isBlank(lines[next])) next++;
|
|
120
|
+
if (next < lines.length && (LIST_ITEM.test(lines[next]) || isIndented(lines[next]))) {
|
|
121
|
+
i = next - 1;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
if (headingOf(line) && !isIndented(line)) break;
|
|
127
|
+
if (FENCE.test(line) && !isIndented(line)) break;
|
|
128
|
+
end = i + 1;
|
|
129
|
+
}
|
|
130
|
+
return end;
|
|
131
|
+
}
|
|
132
|
+
function tableEnd(lines, start) {
|
|
133
|
+
let end = start + 2;
|
|
134
|
+
while (end < lines.length && !isBlank(lines[end]) && lines[end].includes("|")) end++;
|
|
135
|
+
return end;
|
|
136
|
+
}
|
|
137
|
+
function paragraphEnd(lines, start) {
|
|
138
|
+
let end = start + 1;
|
|
139
|
+
while (end < lines.length && !isBlank(lines[end]) && !headingOf(lines[end]) && !FENCE.test(lines[end]) && !LIST_ITEM.test(lines[end])) {
|
|
140
|
+
end++;
|
|
141
|
+
}
|
|
142
|
+
return end;
|
|
143
|
+
}
|
|
144
|
+
function scan(text) {
|
|
145
|
+
const lines = text.replace(/\r\n?/g, "\n").split("\n");
|
|
146
|
+
const sections = [{ trail: [], blocks: [] }];
|
|
147
|
+
const stack = [];
|
|
148
|
+
let i = 0;
|
|
149
|
+
while (i < lines.length) {
|
|
150
|
+
const line = lines[i];
|
|
151
|
+
if (isBlank(line)) {
|
|
152
|
+
i++;
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const heading = FENCE.test(line) ? void 0 : headingOf(line);
|
|
156
|
+
if (heading) {
|
|
157
|
+
while (stack.length && stack[stack.length - 1].level >= heading.level) stack.pop();
|
|
158
|
+
stack.push(heading);
|
|
159
|
+
sections.push({ trail: stack.map((h) => h.title), heading: line, blocks: [] });
|
|
160
|
+
i++;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
let end;
|
|
164
|
+
if (FENCE.test(line)) end = fenceEnd(lines, i);
|
|
165
|
+
else if (LIST_ITEM.test(line)) end = listEnd(lines, i);
|
|
166
|
+
else if (startsTable(lines, i)) end = tableEnd(lines, i);
|
|
167
|
+
else end = paragraphEnd(lines, i);
|
|
168
|
+
sections[sections.length - 1].blocks.push({ lines: lines.slice(i, end) });
|
|
169
|
+
i = end;
|
|
170
|
+
}
|
|
171
|
+
return sections;
|
|
172
|
+
}
|
|
173
|
+
function chunkSections(text, max = 900) {
|
|
174
|
+
const cap = Math.max(1, max);
|
|
175
|
+
const out = [];
|
|
176
|
+
const emit = (parts, section) => {
|
|
177
|
+
const body = parts.join("\n\n");
|
|
178
|
+
if (body.trim() === "") return;
|
|
179
|
+
out.push({ text: body, section: [...section], position: out.length });
|
|
180
|
+
};
|
|
181
|
+
for (const section of scan(text)) {
|
|
182
|
+
let parts = section.heading ? [section.heading.trim()] : [];
|
|
183
|
+
let size = parts.join("\n\n").length;
|
|
184
|
+
let hasBlock = false;
|
|
185
|
+
for (const block of section.blocks) {
|
|
186
|
+
const piece = block.lines.join("\n");
|
|
187
|
+
const added = piece.length + (parts.length ? 2 : 0);
|
|
188
|
+
if (hasBlock && size + added > cap) {
|
|
189
|
+
emit(parts, section.trail);
|
|
190
|
+
parts = [];
|
|
191
|
+
size = 0;
|
|
192
|
+
hasBlock = false;
|
|
193
|
+
}
|
|
194
|
+
size += piece.length + (parts.length ? 2 : 0);
|
|
195
|
+
parts.push(piece);
|
|
196
|
+
hasBlock = true;
|
|
197
|
+
}
|
|
198
|
+
emit(parts, section.trail);
|
|
199
|
+
}
|
|
200
|
+
return out;
|
|
201
|
+
}
|
|
202
|
+
var FENCE, HEADING, LIST_ITEM, TABLE_DELIMITER, isBlank, isIndented;
|
|
203
|
+
var init_chunking = __esm({
|
|
204
|
+
"src/core/chunking.ts"() {
|
|
205
|
+
"use strict";
|
|
206
|
+
FENCE = /^ {0,3}(`{3,}|~{3,})/;
|
|
207
|
+
HEADING = /^ {0,3}(#{1,6})(?:[ \t]+(.*?))?[ \t]*$/;
|
|
208
|
+
LIST_ITEM = /^[ \t]*(?:[-*+]|\d{1,9}[.)])[ \t]+\S/;
|
|
209
|
+
TABLE_DELIMITER = /^[ \t]*\|?[ \t]*:?-+:?[ \t]*(?:\|[ \t]*:?-+:?[ \t]*)*\|?[ \t]*$/;
|
|
210
|
+
isBlank = (line) => line.trim() === "";
|
|
211
|
+
isIndented = (line) => /^(?: {2,}|\t)/.test(line);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
95
215
|
// src/core/loaders.ts
|
|
96
216
|
import { readdirSync, readFileSync as readFileSync2, statSync } from "node:fs";
|
|
97
217
|
import { join as join2 } from "node:path";
|
|
@@ -134,6 +254,7 @@ __export(retrieval_exports, {
|
|
|
134
254
|
openLibsqlClient: () => openLibsqlClient,
|
|
135
255
|
wrapMissingLibsqlError: () => wrapMissingLibsqlError
|
|
136
256
|
});
|
|
257
|
+
import { relative, sep } from "node:path";
|
|
137
258
|
function createOpenAIEmbedder(client) {
|
|
138
259
|
return async (input) => {
|
|
139
260
|
const res = await client.embeddings.create({ model: EMB_MODEL, input });
|
|
@@ -176,6 +297,7 @@ var init_retrieval = __esm({
|
|
|
176
297
|
"src/core/retrieval.ts"() {
|
|
177
298
|
"use strict";
|
|
178
299
|
init_buildLock();
|
|
300
|
+
init_chunking();
|
|
179
301
|
init_loaders();
|
|
180
302
|
init_logger();
|
|
181
303
|
EMB_MODEL = "text-embedding-3-large";
|
|
@@ -186,6 +308,7 @@ var init_retrieval = __esm({
|
|
|
186
308
|
this.embed = embed;
|
|
187
309
|
this.db = options.databaseClient;
|
|
188
310
|
this.knowledgeDir = options.knowledgeDir || DEFAULT_KNOWLEDGE_DIR;
|
|
311
|
+
this.chunking = options.chunking ?? "lines";
|
|
189
312
|
this.logger = options.logger ?? createConsoleLogger();
|
|
190
313
|
this.buildLock = options.buildLock ?? createTursoBuildLock(this.db);
|
|
191
314
|
this.instanceId = options.instanceId ?? crypto.randomUUID();
|
|
@@ -199,6 +322,7 @@ var init_retrieval = __esm({
|
|
|
199
322
|
*/
|
|
200
323
|
db;
|
|
201
324
|
knowledgeDir;
|
|
325
|
+
chunking;
|
|
202
326
|
logger;
|
|
203
327
|
buildLock;
|
|
204
328
|
instanceId;
|
|
@@ -259,11 +383,41 @@ var init_retrieval = __esm({
|
|
|
259
383
|
this.logger.info("No knowledge documents and no existing chunks - nothing to build");
|
|
260
384
|
return;
|
|
261
385
|
}
|
|
386
|
+
this.logger.info(`Chunking mode: ${this.chunking}`);
|
|
387
|
+
if (this.chunking === "sections") await this.ensureSectionColumns();
|
|
262
388
|
const rows = [];
|
|
263
389
|
for (const d of docs) {
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
|
|
390
|
+
if (this.chunking === "sections") {
|
|
391
|
+
const source = relative(this.knowledgeDir, d.source).split(sep).join("/");
|
|
392
|
+
for (const c of chunkSections(d.text)) {
|
|
393
|
+
const section = c.section.join(" > ");
|
|
394
|
+
const id = await sha256(`${d.bucket}|${source}|${section}|${c.text}`);
|
|
395
|
+
const context = section ? `${source} > ${section}` : source;
|
|
396
|
+
rows.push({
|
|
397
|
+
id,
|
|
398
|
+
bucket: d.bucket,
|
|
399
|
+
source,
|
|
400
|
+
text: c.text,
|
|
401
|
+
embedText: `${context}
|
|
402
|
+
|
|
403
|
+
${c.text}`,
|
|
404
|
+
section,
|
|
405
|
+
position: c.position
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
} else {
|
|
409
|
+
for (const part of chunk(d.text)) {
|
|
410
|
+
const id = await sha256(`${d.bucket}|${d.source}|${part}`);
|
|
411
|
+
rows.push({
|
|
412
|
+
id,
|
|
413
|
+
bucket: d.bucket,
|
|
414
|
+
source: d.source,
|
|
415
|
+
text: part,
|
|
416
|
+
embedText: part,
|
|
417
|
+
section: null,
|
|
418
|
+
position: null
|
|
419
|
+
});
|
|
420
|
+
}
|
|
267
421
|
}
|
|
268
422
|
}
|
|
269
423
|
this.logger.info(`Created ${rows.length} chunks from knowledge documents`);
|
|
@@ -272,11 +426,17 @@ var init_retrieval = __esm({
|
|
|
272
426
|
for (let i = 0; i < rows.length; i += UPSERT_BATCH) {
|
|
273
427
|
const batch = rows.slice(i, i + UPSERT_BATCH);
|
|
274
428
|
await this.db.batch(
|
|
275
|
-
batch.map(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
429
|
+
batch.map(
|
|
430
|
+
(r) => this.chunking === "sections" ? {
|
|
431
|
+
sql: `INSERT INTO chunks(id,bucket,source,text,section,position) VALUES(?,?,?,?,?,?)
|
|
432
|
+
ON CONFLICT(id) DO NOTHING`,
|
|
433
|
+
args: [r.id, r.bucket, r.source, r.text, r.section, r.position]
|
|
434
|
+
} : {
|
|
435
|
+
sql: `INSERT INTO chunks(id,bucket,source,text) VALUES(?,?,?,?)
|
|
436
|
+
ON CONFLICT(id) DO NOTHING`,
|
|
437
|
+
args: [r.id, r.bucket, r.source, r.text]
|
|
438
|
+
}
|
|
439
|
+
),
|
|
280
440
|
"write"
|
|
281
441
|
);
|
|
282
442
|
}
|
|
@@ -297,7 +457,7 @@ var init_retrieval = __esm({
|
|
|
297
457
|
return;
|
|
298
458
|
}
|
|
299
459
|
this.logger.info(`Embedding ${missing.length} new/updated chunks with ${EMB_MODEL}...`);
|
|
300
|
-
const textById = new Map(rows.map((r) => [r.id, r.
|
|
460
|
+
const textById = new Map(rows.map((r) => [r.id, r.embedText]));
|
|
301
461
|
const BATCH = 96;
|
|
302
462
|
for (let i = 0; i < missing.length; i += BATCH) {
|
|
303
463
|
const batchIds = missing.slice(i, i + BATCH);
|
|
@@ -318,6 +478,18 @@ var init_retrieval = __esm({
|
|
|
318
478
|
}
|
|
319
479
|
this.logger.info(`Successfully embedded ${missing.length} new chunks`);
|
|
320
480
|
}
|
|
481
|
+
/**
|
|
482
|
+
* Adds the nullable `section`/`position` columns to a `chunks` table that
|
|
483
|
+
* every released version created without them. Checked via table_info so it
|
|
484
|
+
* is a no-op once present; only `'sections'` mode ever calls it.
|
|
485
|
+
*/
|
|
486
|
+
async ensureSectionColumns() {
|
|
487
|
+
const info = await this.db.execute("PRAGMA table_info(chunks)");
|
|
488
|
+
const have = new Set(info.rows.map((r) => String(r.name)));
|
|
489
|
+
if (!have.has("section")) await this.db.execute("ALTER TABLE chunks ADD COLUMN section TEXT");
|
|
490
|
+
if (!have.has("position"))
|
|
491
|
+
await this.db.execute("ALTER TABLE chunks ADD COLUMN position INTEGER");
|
|
492
|
+
}
|
|
321
493
|
// Remove chunks from database that no longer exist in markdown files
|
|
322
494
|
async cleanupStaleChunks(currentIds) {
|
|
323
495
|
const result = await this.db.execute("SELECT id FROM chunks");
|
|
@@ -364,25 +536,34 @@ var init_retrieval = __esm({
|
|
|
364
536
|
* interpolated. An empty list retrieves nothing, and short-circuits before
|
|
365
537
|
* the embedding call.
|
|
366
538
|
*/
|
|
367
|
-
async
|
|
539
|
+
async queryChunks(q, k = 6, allowed = ["base"]) {
|
|
368
540
|
if (allowed.length === 0) return [];
|
|
369
541
|
const [qv] = await this.embed([q]);
|
|
370
542
|
const placeholders = allowed.map(() => "?").join(",");
|
|
371
543
|
const res = await this.db.execute({
|
|
372
|
-
sql: `SELECT c
|
|
544
|
+
sql: `SELECT c.*, e.embedding
|
|
373
545
|
FROM chunks c
|
|
374
546
|
JOIN embeddings e ON e.id = c.id
|
|
375
547
|
WHERE c.bucket IN (${placeholders})`,
|
|
376
548
|
args: allowed
|
|
377
549
|
});
|
|
378
|
-
const scored =
|
|
379
|
-
for (const row of res.rows) {
|
|
550
|
+
const scored = res.rows.map((row) => {
|
|
380
551
|
const emb = JSON.parse(String(row.embedding));
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
552
|
+
const trail = row.section == null ? "" : String(row.section);
|
|
553
|
+
return {
|
|
554
|
+
text: String(row.text),
|
|
555
|
+
bucket: String(row.bucket ?? ""),
|
|
556
|
+
source: String(row.source ?? ""),
|
|
557
|
+
section: trail ? trail.split(" > ") : [],
|
|
558
|
+
score: _VectorStore.cosine(qv, emb)
|
|
559
|
+
};
|
|
560
|
+
});
|
|
561
|
+
scored.sort((a, b) => b.score - a.score);
|
|
562
|
+
return scored.slice(0, k);
|
|
563
|
+
}
|
|
564
|
+
/** Same results as {@link queryChunks}, as bare text. */
|
|
565
|
+
async query(q, k = 6, allowed = ["base"]) {
|
|
566
|
+
return (await this.queryChunks(q, k, allowed)).map((c) => c.text);
|
|
386
567
|
}
|
|
387
568
|
};
|
|
388
569
|
}
|
|
@@ -518,9 +699,10 @@ function detectLeakage(text) {
|
|
|
518
699
|
function scrubOutput(text) {
|
|
519
700
|
return text.replace(/sk-[A-Za-z0-9]{15,}/g, "[REDACTED]").replace(/AIza[0-9A-Za-z_-]{30,}/g, "[REDACTED]");
|
|
520
701
|
}
|
|
521
|
-
|
|
702
|
+
var DEFAULT_REFUSAL = "Sorry, I can't share internal instructions. How else can I help?";
|
|
703
|
+
function guardOutput(text, refusal) {
|
|
522
704
|
if (detectLeakage(text)) {
|
|
523
|
-
return
|
|
705
|
+
return typeof refusal === "string" && refusal.trim() ? refusal : DEFAULT_REFUSAL;
|
|
524
706
|
}
|
|
525
707
|
return scrubOutput(text);
|
|
526
708
|
}
|
|
@@ -532,7 +714,8 @@ async function completeOnce({
|
|
|
532
714
|
system,
|
|
533
715
|
messages,
|
|
534
716
|
temperature = 0.2,
|
|
535
|
-
model = DEFAULT_MODEL
|
|
717
|
+
model = DEFAULT_MODEL,
|
|
718
|
+
refusal
|
|
536
719
|
}) {
|
|
537
720
|
const res = await client.chat.completions.create({
|
|
538
721
|
model,
|
|
@@ -541,19 +724,19 @@ async function completeOnce({
|
|
|
541
724
|
});
|
|
542
725
|
const text = res.choices[0]?.message?.content ?? "";
|
|
543
726
|
return {
|
|
544
|
-
content: guardOutput(text),
|
|
727
|
+
content: guardOutput(text, refusal),
|
|
545
728
|
usage: res.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
|
|
546
729
|
};
|
|
547
730
|
}
|
|
548
731
|
|
|
549
732
|
// src/core/answer.ts
|
|
550
733
|
var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
|
|
551
|
-
async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }) {
|
|
734
|
+
async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal) {
|
|
552
735
|
const result = await answerFn({ system, messages, mode, sender, conversationId });
|
|
553
736
|
const raw = typeof result === "string" ? result : result?.content;
|
|
554
737
|
const usage = typeof result === "string" ? void 0 : result?.usage;
|
|
555
738
|
return {
|
|
556
|
-
content: guardOutput(typeof raw === "string" ? raw : ""),
|
|
739
|
+
content: guardOutput(typeof raw === "string" ? raw : "", refusal),
|
|
557
740
|
usage: usage ?? noUsage()
|
|
558
741
|
};
|
|
559
742
|
}
|
|
@@ -566,12 +749,13 @@ async function answerOnce({
|
|
|
566
749
|
sender,
|
|
567
750
|
conversationId,
|
|
568
751
|
temperature,
|
|
569
|
-
model
|
|
752
|
+
model,
|
|
753
|
+
refusal
|
|
570
754
|
}) {
|
|
571
755
|
if (answerFn) {
|
|
572
|
-
return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId });
|
|
756
|
+
return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal);
|
|
573
757
|
}
|
|
574
|
-
return completeOnce({ client, system, messages, temperature, model });
|
|
758
|
+
return completeOnce({ client, system, messages, temperature, model, refusal });
|
|
575
759
|
}
|
|
576
760
|
async function applyTransformReply(transformReply, input, logger) {
|
|
577
761
|
if (!transformReply) return input.text;
|
|
@@ -1001,6 +1185,7 @@ async function createMCPServer(config) {
|
|
|
1001
1185
|
store = new VectorStore2(createOpenAIEmbedder2(client), {
|
|
1002
1186
|
databaseClient: db,
|
|
1003
1187
|
knowledgeDir: config.knowledgeDir || DEFAULT_KNOWLEDGE_DIR2,
|
|
1188
|
+
chunking: config.chunking,
|
|
1004
1189
|
logger: log
|
|
1005
1190
|
});
|
|
1006
1191
|
}
|
|
@@ -1072,7 +1257,8 @@ async function createMCPServer(config) {
|
|
|
1072
1257
|
messages: conversationMessages,
|
|
1073
1258
|
mode: "public",
|
|
1074
1259
|
conversationId: convId,
|
|
1075
|
-
model
|
|
1260
|
+
model,
|
|
1261
|
+
refusal: config.refusal
|
|
1076
1262
|
});
|
|
1077
1263
|
const replyText = await applyTransformReply(
|
|
1078
1264
|
config.transformReply,
|
|
@@ -1162,7 +1348,8 @@ async function createMCPServer(config) {
|
|
|
1162
1348
|
messages: conversationMessages,
|
|
1163
1349
|
mode: "private",
|
|
1164
1350
|
conversationId: convId,
|
|
1165
|
-
model
|
|
1351
|
+
model,
|
|
1352
|
+
refusal: config.refusal
|
|
1166
1353
|
});
|
|
1167
1354
|
const replyText = await applyTransformReply(
|
|
1168
1355
|
config.transformReply,
|
package/dist/personas/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export type { Greeter, GreeterOptions } from "./greeter";
|
|
10
10
|
export { createGreeter } from "./greeter";
|
|
11
|
-
export type { PersonaContact, PersonaDefinition, PersonaRegistry, PersonaResolver, PersonaResolverOptions, } from "./resolver";
|
|
11
|
+
export type { PersonaContact, PersonaDefinition, PersonaEndpoint, PersonaKey, PersonaRegistry, PersonaResolver, PersonaResolverOptions, } from "./resolver";
|
|
12
12
|
export { createPersonaResolver } from "./resolver";
|
|
13
13
|
export { timeContext } from "./timeContext";
|
|
14
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/personas/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/personas/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,eAAe,EACf,eAAe,EACf,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/personas/index.js
CHANGED
|
@@ -124,7 +124,19 @@ function createPersonaResolver(options = {}) {
|
|
|
124
124
|
return void 0;
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
-
function
|
|
127
|
+
function endpointPersonaId(endpointId) {
|
|
128
|
+
if (!endpointId) return null;
|
|
129
|
+
try {
|
|
130
|
+
return loadRegistry().endpoints?.[endpointId]?.persona ?? null;
|
|
131
|
+
} catch {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function rollPersonaId(key) {
|
|
136
|
+
const { contactId, endpointId } = typeof key === "string" ? { contactId: key } : key;
|
|
137
|
+
const boundToEndpoint = endpointPersonaId(endpointId);
|
|
138
|
+
if (boundToEndpoint) return boundToEndpoint;
|
|
139
|
+
if (contactId === void 0) return null;
|
|
128
140
|
try {
|
|
129
141
|
const reg = loadRegistry();
|
|
130
142
|
const nowMs = now();
|
|
@@ -132,8 +144,8 @@ function createPersonaResolver(options = {}) {
|
|
|
132
144
|
if (existing && existing.expiresAt > nowMs) {
|
|
133
145
|
return existing.personaId;
|
|
134
146
|
}
|
|
135
|
-
for (const [
|
|
136
|
-
if (value.expiresAt <= nowMs) window.delete(
|
|
147
|
+
for (const [held, value] of window) {
|
|
148
|
+
if (value.expiresAt <= nowMs) window.delete(held);
|
|
137
149
|
}
|
|
138
150
|
const contact = reg.contacts?.[contactId];
|
|
139
151
|
let personaId = null;
|
|
@@ -181,8 +193,8 @@ function createPersonaResolver(options = {}) {
|
|
|
181
193
|
return null;
|
|
182
194
|
}
|
|
183
195
|
}
|
|
184
|
-
function resolvePersonaLayer(
|
|
185
|
-
return personaLayerFor(rollPersonaId(
|
|
196
|
+
function resolvePersonaLayer(key) {
|
|
197
|
+
return personaLayerFor(rollPersonaId(key)) ?? personaLayerFor(defaultPersonaId());
|
|
186
198
|
}
|
|
187
199
|
return {
|
|
188
200
|
rollPersonaId,
|
|
@@ -199,7 +211,7 @@ function timeContext(zones, now = Date.now()) {
|
|
|
199
211
|
const at = new Date(now);
|
|
200
212
|
const parts = zones.flatMap((zone) => {
|
|
201
213
|
try {
|
|
202
|
-
const
|
|
214
|
+
const fields = new Intl.DateTimeFormat("en-GB", {
|
|
203
215
|
timeZone: zone,
|
|
204
216
|
weekday: "long",
|
|
205
217
|
day: "numeric",
|
|
@@ -208,7 +220,9 @@ function timeContext(zones, now = Date.now()) {
|
|
|
208
220
|
hour: "2-digit",
|
|
209
221
|
minute: "2-digit",
|
|
210
222
|
hour12: false
|
|
211
|
-
}).
|
|
223
|
+
}).formatToParts(at);
|
|
224
|
+
const part = (type) => fields.find((field) => field.type === type)?.value ?? "";
|
|
225
|
+
const formatted = `${part("weekday")} ${part("day")} ${part("month")} ${part("year")} at ${part("hour")}:${part("minute")}`;
|
|
212
226
|
return [`${formatted} (${zone})`];
|
|
213
227
|
} catch {
|
|
214
228
|
return [];
|
package/dist/personas/index.mjs
CHANGED
|
@@ -96,7 +96,19 @@ function createPersonaResolver(options = {}) {
|
|
|
96
96
|
return void 0;
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
|
-
function
|
|
99
|
+
function endpointPersonaId(endpointId) {
|
|
100
|
+
if (!endpointId) return null;
|
|
101
|
+
try {
|
|
102
|
+
return loadRegistry().endpoints?.[endpointId]?.persona ?? null;
|
|
103
|
+
} catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function rollPersonaId(key) {
|
|
108
|
+
const { contactId, endpointId } = typeof key === "string" ? { contactId: key } : key;
|
|
109
|
+
const boundToEndpoint = endpointPersonaId(endpointId);
|
|
110
|
+
if (boundToEndpoint) return boundToEndpoint;
|
|
111
|
+
if (contactId === void 0) return null;
|
|
100
112
|
try {
|
|
101
113
|
const reg = loadRegistry();
|
|
102
114
|
const nowMs = now();
|
|
@@ -104,8 +116,8 @@ function createPersonaResolver(options = {}) {
|
|
|
104
116
|
if (existing && existing.expiresAt > nowMs) {
|
|
105
117
|
return existing.personaId;
|
|
106
118
|
}
|
|
107
|
-
for (const [
|
|
108
|
-
if (value.expiresAt <= nowMs) window.delete(
|
|
119
|
+
for (const [held, value] of window) {
|
|
120
|
+
if (value.expiresAt <= nowMs) window.delete(held);
|
|
109
121
|
}
|
|
110
122
|
const contact = reg.contacts?.[contactId];
|
|
111
123
|
let personaId = null;
|
|
@@ -153,8 +165,8 @@ function createPersonaResolver(options = {}) {
|
|
|
153
165
|
return null;
|
|
154
166
|
}
|
|
155
167
|
}
|
|
156
|
-
function resolvePersonaLayer(
|
|
157
|
-
return personaLayerFor(rollPersonaId(
|
|
168
|
+
function resolvePersonaLayer(key) {
|
|
169
|
+
return personaLayerFor(rollPersonaId(key)) ?? personaLayerFor(defaultPersonaId());
|
|
158
170
|
}
|
|
159
171
|
return {
|
|
160
172
|
rollPersonaId,
|
|
@@ -171,7 +183,7 @@ function timeContext(zones, now = Date.now()) {
|
|
|
171
183
|
const at = new Date(now);
|
|
172
184
|
const parts = zones.flatMap((zone) => {
|
|
173
185
|
try {
|
|
174
|
-
const
|
|
186
|
+
const fields = new Intl.DateTimeFormat("en-GB", {
|
|
175
187
|
timeZone: zone,
|
|
176
188
|
weekday: "long",
|
|
177
189
|
day: "numeric",
|
|
@@ -180,7 +192,9 @@ function timeContext(zones, now = Date.now()) {
|
|
|
180
192
|
hour: "2-digit",
|
|
181
193
|
minute: "2-digit",
|
|
182
194
|
hour12: false
|
|
183
|
-
}).
|
|
195
|
+
}).formatToParts(at);
|
|
196
|
+
const part = (type) => fields.find((field) => field.type === type)?.value ?? "";
|
|
197
|
+
const formatted = `${part("weekday")} ${part("day")} ${part("month")} ${part("year")} at ${part("hour")}:${part("minute")}`;
|
|
184
198
|
return [`${formatted} (${zone})`];
|
|
185
199
|
} catch {
|
|
186
200
|
return [];
|
|
@@ -20,6 +20,14 @@ export interface PersonaContact {
|
|
|
20
20
|
/** Overrides `personaProbability` for this contact when set. */
|
|
21
21
|
probability?: number;
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* A persona bound to one of the bot's own endpoints - which of its numbers,
|
|
25
|
+
* tokens or rooms the message arrived on, rather than who sent it.
|
|
26
|
+
*/
|
|
27
|
+
export interface PersonaEndpoint {
|
|
28
|
+
/** Persona id this endpoint always answers as. */
|
|
29
|
+
persona: string;
|
|
30
|
+
}
|
|
23
31
|
export interface PersonaRegistry {
|
|
24
32
|
/** Persona id used when a contact is unmapped or its roll doesn't land. */
|
|
25
33
|
defaultPersona: string;
|
|
@@ -28,8 +36,23 @@ export interface PersonaRegistry {
|
|
|
28
36
|
/** Minutes a roll is held before the next message re-rolls it. Default 10. */
|
|
29
37
|
personaWindowMinutes?: number;
|
|
30
38
|
contacts?: Record<string, PersonaContact>;
|
|
39
|
+
/**
|
|
40
|
+
* Personas keyed on the endpoint that received the message
|
|
41
|
+
* (`ChannelMessage.endpointId`), for a bot whose voice is decided by which
|
|
42
|
+
* of its own identities was reached rather than by who reached it.
|
|
43
|
+
*/
|
|
44
|
+
endpoints?: Record<string, PersonaEndpoint>;
|
|
31
45
|
personas: Record<string, PersonaDefinition>;
|
|
32
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Who a persona is resolved for. A bare string is the contact id, which is
|
|
49
|
+
* every call that predates endpoint keying; the object form adds the endpoint
|
|
50
|
+
* the message arrived on, and either half may be omitted.
|
|
51
|
+
*/
|
|
52
|
+
export type PersonaKey = string | {
|
|
53
|
+
contactId?: string;
|
|
54
|
+
endpointId?: string;
|
|
55
|
+
};
|
|
33
56
|
export interface PersonaResolverOptions {
|
|
34
57
|
/** Inline registry — takes priority over `registryPath` when both are set. */
|
|
35
58
|
registry?: PersonaRegistry;
|
|
@@ -48,17 +71,21 @@ export interface PersonaResolverOptions {
|
|
|
48
71
|
}
|
|
49
72
|
export interface PersonaResolver {
|
|
50
73
|
/**
|
|
51
|
-
* The persona id in effect
|
|
52
|
-
*
|
|
53
|
-
*
|
|
74
|
+
* The persona id in effect right now. A key naming an endpoint that the
|
|
75
|
+
* registry binds resolves to that persona deterministically - no roll, no
|
|
76
|
+
* window - because an endpoint-bound voice is a property of the identity
|
|
77
|
+
* reached, not something that varies over a conversation. Otherwise the
|
|
78
|
+
* contact is rolled at `personaProbability` once per window and held for
|
|
79
|
+
* `personaWindowMinutes`. `null` means "use the default persona" (no key,
|
|
80
|
+
* an unmapped contact, or a lost roll).
|
|
54
81
|
*/
|
|
55
|
-
rollPersonaId(
|
|
82
|
+
rollPersonaId(key: PersonaKey): string | null;
|
|
56
83
|
/**
|
|
57
|
-
* The interpolated prompt layer for the
|
|
58
|
-
* falling back to the default persona's layer. Feeds
|
|
59
|
-
* `personaLayer` directly.
|
|
84
|
+
* The interpolated prompt layer for the persona {@link rollPersonaId}
|
|
85
|
+
* yields, falling back to the default persona's layer. Feeds
|
|
86
|
+
* `prepareChat`'s `personaLayer` directly.
|
|
60
87
|
*/
|
|
61
|
-
resolvePersonaLayer(
|
|
88
|
+
resolvePersonaLayer(key: PersonaKey): string | null;
|
|
62
89
|
/** Deterministic layer for an explicit persona id (no dice roll), or null. */
|
|
63
90
|
personaLayerFor(personaId: string | null): string | null;
|
|
64
91
|
/** Registry contact record, or undefined. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/personas/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,cAAc,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,sBAAsB;IACrC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0HAA0H;IAC1H,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/personas/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,cAAc,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC7C;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9E,MAAM,WAAW,sBAAsB;IACrC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0HAA0H;IAC1H,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B;;;;;;;;OAQG;IACH,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;IAC9C;;;;OAIG;IACH,mBAAmB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;IACpD,8EAA8E;IAC9E,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IACzD,6CAA6C;IAC7C,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAC1D,wEAAwE;IACxE,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAAC;CACnC;AAYD,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAmJ3F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeContext.d.ts","sourceRoot":"","sources":["../../src/personas/timeContext.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"timeContext.d.ts","sourceRoot":"","sources":["../../src/personas/timeContext.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,CA6B7E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/routes/demo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAa5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AA6FnD,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/routes/demo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAa5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AA6FnD,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,8EAqIlD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/routes/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAW5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAsDnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/routes/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAW5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAsDnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EAsLpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../../src/routes/private.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,aAAa,CAAC,IAAI,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../../src/routes/private.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,aAAa,CAAC,IAAI,EAAE,kBAAkB,8EAyFrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/routes/public.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAW5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/routes/public.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAW5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EA+FpD"}
|