@diegoaltoworks/chatter 0.61.0 → 0.62.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 +55 -17
- package/dist/auth/secretStrength.d.ts +1 -1
- package/dist/auth/secretStrength.d.ts.map +1 -1
- package/dist/bin/create-apikey.js +45 -28
- package/dist/bin/wa-pair.js +113 -46
- package/dist/channels/backoff.d.ts +10 -0
- package/dist/channels/backoff.d.ts.map +1 -0
- package/dist/channels/gates.d.ts +15 -8
- package/dist/channels/gates.d.ts.map +1 -1
- package/dist/channels/index.d.ts +1 -1
- package/dist/channels/index.d.ts.map +1 -1
- package/dist/channels/index.js +38 -5
- package/dist/channels/index.mjs +37 -5
- package/dist/channels/matrix/api.d.ts +25 -6
- package/dist/channels/matrix/api.d.ts.map +1 -1
- package/dist/channels/matrix/channel.d.ts +4 -56
- package/dist/channels/matrix/channel.d.ts.map +1 -1
- package/dist/channels/matrix/handler.d.ts +16 -9
- package/dist/channels/matrix/handler.d.ts.map +1 -1
- package/dist/channels/matrix/index.d.ts +2 -2
- package/dist/channels/matrix/index.d.ts.map +1 -1
- package/dist/channels/matrix/index.js +196 -40
- package/dist/channels/matrix/index.mjs +189 -39
- package/dist/channels/matrix/sync.d.ts +4 -1
- package/dist/channels/matrix/sync.d.ts.map +1 -1
- package/dist/channels/matrix/updates.d.ts +39 -10
- package/dist/channels/matrix/updates.d.ts.map +1 -1
- package/dist/channels/pipeline.d.ts +14 -14
- package/dist/channels/pipeline.d.ts.map +1 -1
- package/dist/channels/polling.d.ts +67 -0
- package/dist/channels/polling.d.ts.map +1 -0
- package/dist/channels/telegram/channel.d.ts +2 -56
- package/dist/channels/telegram/channel.d.ts.map +1 -1
- package/dist/channels/telegram/index.js +53 -23
- package/dist/channels/telegram/index.mjs +53 -23
- package/dist/channels/telegram/poll.d.ts +5 -1
- package/dist/channels/telegram/poll.d.ts.map +1 -1
- package/dist/channels/telegram/webhook.d.ts +2 -10
- package/dist/channels/telegram/webhook.d.ts.map +1 -1
- package/dist/channels/whatsapp/authState.d.ts +40 -9
- package/dist/channels/whatsapp/authState.d.ts.map +1 -1
- package/dist/channels/whatsapp/channel.d.ts +25 -4
- package/dist/channels/whatsapp/channel.d.ts.map +1 -1
- package/dist/channels/whatsapp/inbound.d.ts +23 -25
- package/dist/channels/whatsapp/inbound.d.ts.map +1 -1
- package/dist/channels/whatsapp/index.d.ts +3 -3
- package/dist/channels/whatsapp/index.d.ts.map +1 -1
- package/dist/channels/whatsapp/index.js +123 -41
- package/dist/channels/whatsapp/index.mjs +120 -41
- package/dist/channels/whatsapp/pairing.d.ts.map +1 -1
- package/dist/client/src/Chat.d.ts.map +1 -1
- package/dist/client/src/ChatButton.d.ts.map +1 -1
- package/dist/client/src/browser.d.ts.map +1 -1
- package/dist/core/answer.d.ts +8 -0
- package/dist/core/answer.d.ts.map +1 -1
- package/dist/core/buildLock.d.ts +52 -0
- package/dist/core/buildLock.d.ts.map +1 -0
- package/dist/core/pipeline.d.ts +42 -5
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/prompts.d.ts +2 -0
- package/dist/core/prompts.d.ts.map +1 -1
- package/dist/core/retrieval.d.ts +100 -25
- package/dist/core/retrieval.d.ts.map +1 -1
- package/dist/core/session.d.ts +8 -0
- package/dist/core/session.d.ts.map +1 -1
- package/dist/flows/index.d.ts +1 -1
- package/dist/flows/index.d.ts.map +1 -1
- package/dist/flows/index.js +8 -6
- package/dist/flows/index.mjs +7 -6
- package/dist/flows/intent.d.ts +1 -1
- package/dist/flows/intent.d.ts.map +1 -1
- package/dist/flows/loader.d.ts +1 -2
- package/dist/flows/loader.d.ts.map +1 -1
- package/dist/flows/params.d.ts +1 -1
- package/dist/flows/params.d.ts.map +1 -1
- package/dist/flows/session.d.ts +4 -2
- package/dist/flows/session.d.ts.map +1 -1
- package/dist/flows/types.d.ts +2 -3
- package/dist/flows/types.d.ts.map +1 -1
- package/dist/history/index.d.ts +1 -1
- package/dist/history/index.d.ts.map +1 -1
- package/dist/history/index.js +6 -3
- package/dist/history/index.mjs +5 -3
- package/dist/history/tursoStore.d.ts +6 -4
- package/dist/history/tursoStore.d.ts.map +1 -1
- package/dist/images/index.js +2 -2
- package/dist/images/index.mjs +2 -2
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +596 -295
- package/dist/index.mjs +595 -295
- package/dist/mcp-server/index.d.ts +5 -5
- package/dist/mcp-server/index.d.ts.map +1 -1
- package/dist/mcp-server/logger.d.ts +12 -2
- package/dist/mcp-server/logger.d.ts.map +1 -1
- package/dist/mcp-server/rate-limiter.d.ts +10 -3
- package/dist/mcp-server/rate-limiter.d.ts.map +1 -1
- package/dist/mcp-server/types.d.ts +20 -5
- package/dist/mcp-server/types.d.ts.map +1 -1
- package/dist/mcp-server.js +479 -244
- package/dist/mcp-server.mjs +485 -244
- package/dist/middleware/apiKey.d.ts +10 -0
- package/dist/middleware/apiKey.d.ts.map +1 -0
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/cors.d.ts.map +1 -1
- package/dist/middleware/ratelimit.d.ts.map +1 -1
- package/dist/middleware/referrer.d.ts.map +1 -1
- package/dist/middleware/session.d.ts +1 -1
- package/dist/middleware/session.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 +1 -1
- package/dist/scheduler/index.mjs +1 -1
- package/dist/scheduler/scheduler.d.ts +9 -1
- package/dist/scheduler/scheduler.d.ts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +491 -268
- package/dist/server.mjs +497 -268
- package/dist/shortener.d.ts +5 -4
- package/dist/shortener.d.ts.map +1 -1
- package/dist/types.d.ts +129 -75
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -1
|
@@ -67,27 +67,55 @@ function ensureAuthSchema(client) {
|
|
|
67
67
|
}
|
|
68
68
|
return ready;
|
|
69
69
|
}
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
function createTursoWaAuthKV(db) {
|
|
71
|
+
return {
|
|
72
|
+
async read(id) {
|
|
73
|
+
await ensureAuthSchema(db);
|
|
74
|
+
const result = await db.execute({
|
|
75
|
+
sql: "SELECT value FROM wa_auth WHERE id = ?",
|
|
76
|
+
args: [id]
|
|
77
|
+
});
|
|
78
|
+
const row = result.rows[0];
|
|
79
|
+
return row ? row.value : null;
|
|
80
|
+
},
|
|
81
|
+
async write(id, value) {
|
|
82
|
+
await ensureAuthSchema(db);
|
|
83
|
+
await db.execute({
|
|
84
|
+
sql: "INSERT OR REPLACE INTO wa_auth (id, value) VALUES (?, ?)",
|
|
85
|
+
args: [id, value]
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
async remove(id) {
|
|
89
|
+
await ensureAuthSchema(db);
|
|
90
|
+
await db.execute({ sql: "DELETE FROM wa_auth WHERE id = ?", args: [id] });
|
|
91
|
+
},
|
|
92
|
+
// Mirrors isAuthRowForSession - keep the two in sync.
|
|
93
|
+
async clear(sessionId) {
|
|
94
|
+
await ensureAuthSchema(db);
|
|
95
|
+
if (sessionId === "default") {
|
|
96
|
+
await db.execute("DELETE FROM wa_auth WHERE id NOT LIKE 's:%'");
|
|
97
|
+
} else {
|
|
98
|
+
await db.execute({
|
|
99
|
+
sql: "DELETE FROM wa_auth WHERE id LIKE ?",
|
|
100
|
+
args: [`s:${sessionId}/%`]
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
async function useAuthState(store, secret, sessionId, runtime) {
|
|
72
107
|
const rowId = (id) => sessionId === "default" ? id : `s:${sessionId}/${id}`;
|
|
73
108
|
async function read(id) {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
});
|
|
78
|
-
const row = result.rows[0];
|
|
79
|
-
if (!row) return null;
|
|
80
|
-
return JSON.parse(await decrypt(row.value, secret), runtime.bufferJSON.reviver);
|
|
109
|
+
const value = await store.read(rowId(id));
|
|
110
|
+
if (value === null) return null;
|
|
111
|
+
return JSON.parse(await decrypt(value, secret), runtime.bufferJSON.reviver);
|
|
81
112
|
}
|
|
82
113
|
async function write(id, value) {
|
|
83
114
|
const payload = await encrypt(JSON.stringify(value, runtime.bufferJSON.replacer), secret);
|
|
84
|
-
await
|
|
85
|
-
sql: "INSERT OR REPLACE INTO wa_auth (id, value) VALUES (?, ?)",
|
|
86
|
-
args: [rowId(id), payload]
|
|
87
|
-
});
|
|
115
|
+
await store.write(rowId(id), payload);
|
|
88
116
|
}
|
|
89
117
|
async function remove(id) {
|
|
90
|
-
await
|
|
118
|
+
await store.remove(rowId(id));
|
|
91
119
|
}
|
|
92
120
|
const creds = await read("creds") ?? runtime.initAuthCreds();
|
|
93
121
|
return {
|
|
@@ -124,18 +152,13 @@ async function useTursoAuthState(db, secret, sessionId, runtime) {
|
|
|
124
152
|
}
|
|
125
153
|
},
|
|
126
154
|
saveCreds: () => write("creds", creds),
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
await db.execute("DELETE FROM wa_auth WHERE id NOT LIKE 's:%'");
|
|
130
|
-
} else {
|
|
131
|
-
await db.execute({
|
|
132
|
-
sql: "DELETE FROM wa_auth WHERE id LIKE ?",
|
|
133
|
-
args: [`s:${sessionId}/%`]
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
}
|
|
155
|
+
// Scoped to THIS session - never nuke a sibling number's pairing.
|
|
156
|
+
clear: () => store.clear(sessionId)
|
|
137
157
|
};
|
|
138
158
|
}
|
|
159
|
+
async function useTursoAuthState(db, secret, sessionId, runtime) {
|
|
160
|
+
return useAuthState(createTursoWaAuthKV(db), secret, sessionId, runtime);
|
|
161
|
+
}
|
|
139
162
|
|
|
140
163
|
// src/channels/whatsapp/baileys.ts
|
|
141
164
|
function wrapMissingBaileysError(cause) {
|
|
@@ -198,6 +221,11 @@ function createConsoleLogger(level = "info") {
|
|
|
198
221
|
};
|
|
199
222
|
}
|
|
200
223
|
|
|
224
|
+
// src/channels/backoff.ts
|
|
225
|
+
function exponentialBackoffMs(baseMs, maxMs, n) {
|
|
226
|
+
return Math.min(baseMs * 2 ** Math.max(0, Math.min(n, 20)), maxMs);
|
|
227
|
+
}
|
|
228
|
+
|
|
201
229
|
// src/channels/whatsapp/lease.ts
|
|
202
230
|
var LEASE_STALE_MS = 9e4;
|
|
203
231
|
var LEASE_HEARTBEAT_MS = 3e4;
|
|
@@ -256,7 +284,7 @@ function createTursoWaLeaseStore(client) {
|
|
|
256
284
|
var RECONNECT_DELAY_MS = 5e3;
|
|
257
285
|
var RECONNECT_MAX_DELAY_MS = 10 * 60 * 1e3;
|
|
258
286
|
function reconnectDelayMs(failures) {
|
|
259
|
-
return
|
|
287
|
+
return exponentialBackoffMs(RECONNECT_DELAY_MS, RECONNECT_MAX_DELAY_MS, failures);
|
|
260
288
|
}
|
|
261
289
|
async function shutdownWaSessions(sessions) {
|
|
262
290
|
await Promise.all(
|
|
@@ -327,9 +355,18 @@ async function acquireSessionLease(sessionId, deps) {
|
|
|
327
355
|
function senderNameFor(channelName, sessionId) {
|
|
328
356
|
return sessionId === "default" ? channelName : `${channelName}:${sessionId}`;
|
|
329
357
|
}
|
|
358
|
+
function normalizeWaMediaPayload(payload) {
|
|
359
|
+
const media = typeof payload === "string" ? { url: payload } : payload;
|
|
360
|
+
if (!media || typeof media !== "object" || typeof media.url !== "string" || !media.url) {
|
|
361
|
+
throw new TypeError(
|
|
362
|
+
`WhatsApp sendMedia payload must be a URL string or { url, caption? }, got: ${typeof payload}`
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
return media;
|
|
366
|
+
}
|
|
330
367
|
function createWhatsAppChannel(config) {
|
|
331
368
|
assertStrongSecret(config.sessionSecret, "WhatsApp sessionSecret (e.g. WA_SESSION_SECRET)");
|
|
332
|
-
const channelName = "whatsapp";
|
|
369
|
+
const channelName = config.name ?? "whatsapp";
|
|
333
370
|
const sessionIds = config.sessionIds && config.sessionIds.length > 0 ? config.sessionIds : ["default"];
|
|
334
371
|
const now = config.now ?? Date.now;
|
|
335
372
|
const schedule = config.schedule ?? ((fn, ms) => void setTimeout(fn, ms));
|
|
@@ -347,8 +384,13 @@ function createWhatsAppChannel(config) {
|
|
|
347
384
|
name: channelName,
|
|
348
385
|
async start(deps) {
|
|
349
386
|
const log = config.logger ?? deps.logger ?? createConsoleLogger();
|
|
350
|
-
|
|
351
|
-
|
|
387
|
+
if ((!config.leaseStore || !config.authStore) && !deps.db) {
|
|
388
|
+
throw new Error(
|
|
389
|
+
"The WhatsApp channel needs a libsql client for auth state and the session lease: set config.database (config.retriever alone does not open one), or supply both config.leaseStore and config.authStore."
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
const leaseStore = config.leaseStore ?? createTursoWaLeaseStore(deps.db);
|
|
393
|
+
const authStore = config.authStore ?? createTursoWaAuthKV(deps.db);
|
|
352
394
|
senders = deps.senders;
|
|
353
395
|
await loadBaileys2();
|
|
354
396
|
async function connect(sessionId) {
|
|
@@ -359,8 +401,8 @@ function createWhatsAppChannel(config) {
|
|
|
359
401
|
initAuthCreds: baileys.initAuthCreds,
|
|
360
402
|
appStateSyncKeyFromObject: (value) => baileys.proto.Message.AppStateSyncKeyData.fromObject(value)
|
|
361
403
|
};
|
|
362
|
-
const { state, saveCreds } = await
|
|
363
|
-
|
|
404
|
+
const { state, saveCreds } = await useAuthState(
|
|
405
|
+
authStore,
|
|
364
406
|
config.sessionSecret,
|
|
365
407
|
sessionId,
|
|
366
408
|
runtime
|
|
@@ -404,6 +446,13 @@ function createWhatsAppChannel(config) {
|
|
|
404
446
|
sendText: async (chatId, text) => {
|
|
405
447
|
await sock.sendMessage(chatId, { text });
|
|
406
448
|
},
|
|
449
|
+
sendMedia: async (chatId, payload) => {
|
|
450
|
+
const { url, caption } = normalizeWaMediaPayload(payload);
|
|
451
|
+
await sock.sendMessage(
|
|
452
|
+
chatId,
|
|
453
|
+
caption !== void 0 ? { image: { url }, caption } : { image: { url } }
|
|
454
|
+
);
|
|
455
|
+
},
|
|
407
456
|
sendReaction: async (chatId, messageRef, emoji) => {
|
|
408
457
|
await sock.sendMessage(chatId, {
|
|
409
458
|
react: { text: emoji, key: messageRef }
|
|
@@ -679,7 +728,8 @@ async function answerOnce({
|
|
|
679
728
|
async function applyTransformReply(transformReply, input, logger) {
|
|
680
729
|
if (!transformReply) return input.text;
|
|
681
730
|
try {
|
|
682
|
-
|
|
731
|
+
const result = await transformReply(input);
|
|
732
|
+
return typeof result === "string" ? result : null;
|
|
683
733
|
} catch (error) {
|
|
684
734
|
logger?.error(
|
|
685
735
|
`transformReply threw for channel "${input.channel}"; sending the original reply`,
|
|
@@ -741,6 +791,7 @@ async function prepareChat({
|
|
|
741
791
|
sender,
|
|
742
792
|
rewriteQuery,
|
|
743
793
|
rerankContext,
|
|
794
|
+
fallbackFn,
|
|
744
795
|
logger
|
|
745
796
|
}) {
|
|
746
797
|
const lastUserMsg = lastUserMessage(messages);
|
|
@@ -757,21 +808,39 @@ async function prepareChat({
|
|
|
757
808
|
logger?.error("rewriteQuery threw; falling back to the original query", error);
|
|
758
809
|
}
|
|
759
810
|
}
|
|
760
|
-
|
|
811
|
+
const resolvedBuckets = buckets ?? defaultBuckets(mode);
|
|
812
|
+
const retrievedChunks = await store.query(query, topK, resolvedBuckets);
|
|
813
|
+
let ctx = retrievedChunks;
|
|
761
814
|
if (rerankContext) {
|
|
762
815
|
try {
|
|
763
|
-
const reranked = await rerankContext({ query, chunks: ctx });
|
|
816
|
+
const reranked = await rerankContext({ query, chunks: [...ctx] });
|
|
764
817
|
if (Array.isArray(reranked) && reranked.every((c) => typeof c === "string")) ctx = reranked;
|
|
765
818
|
} catch (error) {
|
|
766
819
|
logger?.error("rerankContext threw; falling back to the original chunks", error);
|
|
767
820
|
}
|
|
768
821
|
}
|
|
822
|
+
let fallback;
|
|
823
|
+
if (ctx.length === 0 && fallbackFn) {
|
|
824
|
+
try {
|
|
825
|
+
const guidance = await fallbackFn({
|
|
826
|
+
query,
|
|
827
|
+
mode,
|
|
828
|
+
buckets: resolvedBuckets,
|
|
829
|
+
sender,
|
|
830
|
+
retrievedChunks
|
|
831
|
+
});
|
|
832
|
+
if (typeof guidance === "string" && guidance.trim()) fallback = guidance.trim();
|
|
833
|
+
} catch (error) {
|
|
834
|
+
logger?.error("fallbackFn threw; proceeding without fallback guidance", error);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
769
837
|
const persona = personaLayer?.trim() || (mode === "private" ? prompts.privatePersona : prompts.publicPersona);
|
|
770
838
|
const hint = channelHint?.trim();
|
|
771
839
|
const system = [
|
|
772
840
|
prompts.baseSystemRules,
|
|
773
841
|
persona,
|
|
774
842
|
...hint ? [hint] : [],
|
|
843
|
+
...fallback ? [fallback] : [],
|
|
775
844
|
`${label}:
|
|
776
845
|
${ctx.join("\n\n")}`
|
|
777
846
|
].join("\n\n");
|
|
@@ -779,7 +848,7 @@ ${ctx.join("\n\n")}`
|
|
|
779
848
|
}
|
|
780
849
|
|
|
781
850
|
// src/history/compaction.ts
|
|
782
|
-
var
|
|
851
|
+
var COMPACTION_TIMEOUT_MS = 8e3;
|
|
783
852
|
var LOAD_ALL = Number.MAX_SAFE_INTEGER;
|
|
784
853
|
var SUMMARY_PREFIX = "Summary of earlier conversation: ";
|
|
785
854
|
function defaultSummarize(client, model) {
|
|
@@ -807,7 +876,7 @@ function createHistoryCompactor(deps, options) {
|
|
|
807
876
|
throw new Error(`Invalid history compaction keep: ${keep}`);
|
|
808
877
|
}
|
|
809
878
|
const summarize = options.summarize ?? defaultSummarize(deps.client, options.model);
|
|
810
|
-
const timeoutMs = options.timeoutMs ??
|
|
879
|
+
const timeoutMs = options.timeoutMs ?? COMPACTION_TIMEOUT_MS;
|
|
811
880
|
return {
|
|
812
881
|
async maybeCompact(store, conversationId) {
|
|
813
882
|
const turns = await store.load(conversationId, LOAD_ALL);
|
|
@@ -848,6 +917,16 @@ function createHistoryCompactor(deps, options) {
|
|
|
848
917
|
}
|
|
849
918
|
|
|
850
919
|
// src/channels/pipeline.ts
|
|
920
|
+
function resolveBrainHooks(config, fallback) {
|
|
921
|
+
return {
|
|
922
|
+
answerFn: config.answerFn ?? fallback?.answerFn,
|
|
923
|
+
bucketsFor: config.bucketsFor ?? fallback?.bucketsFor,
|
|
924
|
+
rewriteQuery: config.rewriteQuery ?? fallback?.rewriteQuery,
|
|
925
|
+
rerankContext: config.rerankContext ?? fallback?.rerankContext,
|
|
926
|
+
fallbackFn: config.fallbackFn ?? fallback?.fallbackFn,
|
|
927
|
+
transformReply: config.transformReply ?? fallback?.transformReply
|
|
928
|
+
};
|
|
929
|
+
}
|
|
851
930
|
var DEFAULT_HISTORY_LIMIT = 20;
|
|
852
931
|
var DEFAULT_GROUP_RATE_LIMIT = { max: 30, windowMs: 60 * 60 * 1e3 };
|
|
853
932
|
var DEFAULT_DM_RATE_LIMIT = { max: 20, windowMs: 60 * 60 * 1e3 };
|
|
@@ -932,6 +1011,7 @@ function createInboundPipeline(deps, config) {
|
|
|
932
1011
|
sender,
|
|
933
1012
|
rewriteQuery: config.rewriteQuery,
|
|
934
1013
|
rerankContext: config.rerankContext,
|
|
1014
|
+
fallbackFn: config.fallbackFn,
|
|
935
1015
|
logger: config.logger
|
|
936
1016
|
});
|
|
937
1017
|
const { content: produced } = await answerOnce({
|
|
@@ -1067,13 +1147,9 @@ function createWhatsAppInboundHandler(config) {
|
|
|
1067
1147
|
{ client: config.client, store: config.store, prompts: config.prompts },
|
|
1068
1148
|
{
|
|
1069
1149
|
channel: "whatsapp",
|
|
1070
|
-
|
|
1071
|
-
bucketsFor: config.bucketsFor,
|
|
1072
|
-
rewriteQuery: config.rewriteQuery,
|
|
1073
|
-
rerankContext: config.rerankContext,
|
|
1074
|
-
transformReply: config.transformReply,
|
|
1150
|
+
...resolveBrainHooks(config, config.serverConfig),
|
|
1075
1151
|
model: config.model,
|
|
1076
|
-
channelHint: config.channelHint,
|
|
1152
|
+
channelHint: config.channelHint ?? "Channel: WhatsApp.",
|
|
1077
1153
|
personaResolver: personaResolver ? ({ sender, text }) => personaResolver({ senderPhone: sender, text }) : void 0,
|
|
1078
1154
|
history: config.history,
|
|
1079
1155
|
allowedChats,
|
|
@@ -1233,6 +1309,7 @@ export {
|
|
|
1233
1309
|
LEASE_WAIT_MS,
|
|
1234
1310
|
acquireSessionLease,
|
|
1235
1311
|
canAcquireLease,
|
|
1312
|
+
createTursoWaAuthKV,
|
|
1236
1313
|
createTursoWaLeaseStore,
|
|
1237
1314
|
createWhatsAppChannel,
|
|
1238
1315
|
createWhatsAppImageHandler,
|
|
@@ -1248,11 +1325,13 @@ export {
|
|
|
1248
1325
|
jidsMatch,
|
|
1249
1326
|
loadBaileys,
|
|
1250
1327
|
messageContext,
|
|
1328
|
+
normalizeWaMediaPayload,
|
|
1251
1329
|
reconnectDelayMs,
|
|
1252
1330
|
resolveWaMessage,
|
|
1253
1331
|
senderNameFor,
|
|
1254
1332
|
senderPhoneFor,
|
|
1255
1333
|
shutdownWaSessions,
|
|
1256
1334
|
stripOwnMentions,
|
|
1335
|
+
useAuthState,
|
|
1257
1336
|
useTursoAuthState
|
|
1258
1337
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/pairing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;
|
|
1
|
+
{"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/pairing.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/client/src/Chat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEvD,qBAAa,IAAI;IACf,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAC,CAAa;IAE7B,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,UAAU,CAAqB;IAEvC,YAAY,MAAM,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/client/src/Chat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEvD,qBAAa,IAAI;IACf,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAC,CAAa;IAE7B,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,UAAU,CAAqB;IAEvC,YAAY,MAAM,EAAE,UAAU,EA0B7B;IAED,OAAO,CAAC,MAAM;IAoBd,OAAO,CAAC,oBAAoB;YA8Cd,UAAU;IA4DxB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,KAAK,IAAI,IAAI,CAGZ;IAED;;OAEG;IACH,WAAW,IAAI,WAAW,EAAE,CAE3B;IAED;;OAEG;IACH,OAAO,IAAI,IAAI,CAEd;IAED;;OAEG;IACH,OAAO,CAAC,QAAQ;CAGjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatButton.d.ts","sourceRoot":"","sources":["../../../src/client/src/ChatButton.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,MAAM,EAAE,gBAAgB,EASnC;IAED,OAAO,CAAC,MAAM;
|
|
1
|
+
{"version":3,"file":"ChatButton.d.ts","sourceRoot":"","sources":["../../../src/client/src/ChatButton.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,MAAM,EAAE,gBAAgB,EASnC;IAED,OAAO,CAAC,MAAM;IAkBd,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,MAAM;IAQd,IAAI,IAAI,IAAI,CA+CX;IAED,KAAK,IAAI,IAAI,CAcZ;IAED;;OAEG;IACH,OAAO,CAAC,QAAQ;IAIhB;;OAEG;IACH,OAAO,IAAI,IAAI,CAId;IAED;;OAEG;IACH,QAAQ,IAAI,OAAO,CAElB;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/client/src/browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/client/src/browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,OAAO,EAAE;YACP,OAAO,EAAE,OAAO,OAAO,CAAC;YACxB,IAAI,EAAE,OAAO,IAAI,CAAC;YAClB,UAAU,EAAE,OAAO,UAAU,CAAC;SAC/B,CAAC;KACH;CACF;AAYD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
package/dist/core/answer.d.ts
CHANGED
|
@@ -95,6 +95,14 @@ export type TransformReply = (input: TransformReplyInput) => string | null | Pro
|
|
|
95
95
|
* Runs `transformReply` if configured. A throw/rejection is logged and the
|
|
96
96
|
* ORIGINAL text is returned — the delivery invariant: a bug in a plugin hook
|
|
97
97
|
* must never silently swallow an answer the model already produced.
|
|
98
|
+
*
|
|
99
|
+
* The result crosses the same plugin boundary `runAnswerFn` does, so it gets
|
|
100
|
+
* the same treatment: anything that isn't a string is coerced to `null`
|
|
101
|
+
* (treated as a veto) rather than passed through as whatever a
|
|
102
|
+
* non-conforming hook happened to return (`undefined` from a missing
|
|
103
|
+
* `return`, say). Every call site already treats a falsy result as "nothing
|
|
104
|
+
* delivered", but only a normalized `string | null` matches this function's
|
|
105
|
+
* own declared return type.
|
|
98
106
|
*/
|
|
99
107
|
export declare function applyTransformReply(transformReply: TransformReply | undefined, input: TransformReplyInput, logger?: Pick<Logger, "error">): Promise<string | null>;
|
|
100
108
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"answer.d.ts","sourceRoot":"","sources":["../../src/core/answer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAGjC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhE,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,uCAAuC;IACvC,IAAI,EAAE,YAAY,CAAC;IACnB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,WAAW,CAAA;CAAE,CAAC;AAE/E;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC;AAE1F,MAAM,WAAW,aAAa;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAqBD;;GAEG;AACH,wBAAsB,UAAU,CAAC,EAC/B,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,cAAc,EACd,WAAW,EACX,KAAK,GACN,EAAE,aAAa,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC,CAKlE;AAED,4FAA4F;AAC5F,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,mBAAmB,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAEpG
|
|
1
|
+
{"version":3,"file":"answer.d.ts","sourceRoot":"","sources":["../../src/core/answer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAGjC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhE,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,uCAAuC;IACvC,IAAI,EAAE,YAAY,CAAC;IACnB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,WAAW,CAAA;CAAE,CAAC;AAE/E;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC;AAE1F,MAAM,WAAW,aAAa;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAqBD;;GAEG;AACH,wBAAsB,UAAU,CAAC,EAC/B,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,cAAc,EACd,WAAW,EACX,KAAK,GACN,EAAE,aAAa,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC,CAKlE;AAED,4FAA4F;AAC5F,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,mBAAmB,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAEpG;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,cAAc,GAAG,SAAS,EAC1C,KAAK,EAAE,mBAAmB,EAC1B,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYxB;AAED;;;;;;;;GAQG;AACH,wBAAuB,YAAY,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,cAAc,EACd,WAAW,EACX,KAAK,GACN,EAAE,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,CAaxC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single-writer lock around the destructive half of a knowledge-base build.
|
|
3
|
+
*
|
|
4
|
+
* `VectorStore.build()` is a read-diff-delete-insert sequence: it reads the
|
|
5
|
+
* chunk ids already in the database, computes the ids its own `knowledgeDir`
|
|
6
|
+
* produces, and deletes everything not in that set. Two instances booting
|
|
7
|
+
* against the same database at the same time (a rolling deploy, a manual
|
|
8
|
+
* deploy racing an automated one) each run that sequence against a view of
|
|
9
|
+
* the data the other is still mutating, so one boot's cleanup can delete
|
|
10
|
+
* chunks the other has just written or has not finished writing.
|
|
11
|
+
*
|
|
12
|
+
* The lock lives in the same database (`chatter_build_lock`) so it is visible
|
|
13
|
+
* to every instance, and acquiring or renewing it is a single atomic upsert
|
|
14
|
+
* (see `createTursoBuildLock`) - two instances racing the same key can never
|
|
15
|
+
* both believe they hold it. A holder that dies without releasing leaves a
|
|
16
|
+
* stale row instead of wedging every future boot: after `staleMs` with no
|
|
17
|
+
* heartbeat, the next instance may take it over.
|
|
18
|
+
*/
|
|
19
|
+
import type { Client } from "@libsql/client";
|
|
20
|
+
/** Lock key for the knowledge-base build. One build runs per database at a time. */
|
|
21
|
+
export declare const BUILD_LOCK_KEY = "knowledge_build";
|
|
22
|
+
/**
|
|
23
|
+
* A held lock this old with no heartbeat is treated as abandoned. Generous
|
|
24
|
+
* because a first build embeds every chunk it loads, which can take minutes;
|
|
25
|
+
* a holder renews the lock as it goes (see `VectorStore.build`), so only a
|
|
26
|
+
* process that actually died lets the lock go stale.
|
|
27
|
+
*/
|
|
28
|
+
export declare const BUILD_LOCK_STALE_MS: number;
|
|
29
|
+
export interface BuildLockRow {
|
|
30
|
+
holderId: string;
|
|
31
|
+
heartbeatAt: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Pure: may `holderId` take (or keep) the build lock right now, given the
|
|
35
|
+
* current row (null = never held)? Mirrors the SQL WHERE clause in
|
|
36
|
+
* `createTursoBuildLock` - keep the two in sync.
|
|
37
|
+
*/
|
|
38
|
+
export declare function canAcquireBuildLock(existing: BuildLockRow | null, holderId: string, now: number, staleMs?: number): boolean;
|
|
39
|
+
export interface BuildLock {
|
|
40
|
+
/** Atomically acquires or renews the lock; resolves true iff `holderId` now holds it. */
|
|
41
|
+
tryAcquire(key: string, holderId: string, now: number, staleMs: number): Promise<boolean>;
|
|
42
|
+
/** Releases the lock iff still held by `holderId` (no-op otherwise, so a late release never undoes a takeover). */
|
|
43
|
+
release(key: string, holderId: string): Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A libsql-backed {@link BuildLock}. The WHERE clause on DO UPDATE encodes
|
|
47
|
+
* `canAcquireBuildLock`: SQLite skips the update (and RETURNING yields no
|
|
48
|
+
* row) when it is false, so a losing racer sees zero rows back - no separate
|
|
49
|
+
* read-then-write, no race window.
|
|
50
|
+
*/
|
|
51
|
+
export declare function createTursoBuildLock(client: Client): BuildLock;
|
|
52
|
+
//# sourceMappingURL=buildLock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildLock.d.ts","sourceRoot":"","sources":["../../src/core/buildLock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,oFAAoF;AACpF,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,QAAc,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,GAAG,IAAI,EAC7B,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAA4B,GACpC,OAAO,CAIT;AAED,MAAM,WAAW,SAAS;IACxB,yFAAyF;IACzF,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1F,mHAAmH;IACnH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD;AAwBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAyB9D"}
|
package/dist/core/pipeline.d.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { Logger } from "./logger";
|
|
12
12
|
import type { PromptLoader } from "./prompts";
|
|
13
|
-
import type {
|
|
13
|
+
import type { Retriever } from "./retrieval";
|
|
14
14
|
export type PipelineMode = "public" | "private";
|
|
15
15
|
export interface PipelineMessage {
|
|
16
16
|
role: "user" | "assistant";
|
|
@@ -60,11 +60,43 @@ export interface RerankContextArgs {
|
|
|
60
60
|
* fails closed by design; use this hook for relevance/ordering only.
|
|
61
61
|
*/
|
|
62
62
|
export type RerankContext = (ctx: RerankContextArgs) => string[] | Promise<string[]>;
|
|
63
|
+
/** What `fallbackFn` sees for a turn where retrieval came back empty. */
|
|
64
|
+
export interface FallbackContext {
|
|
65
|
+
/** The query retrieval actually ran with, post-`rewriteQuery` if configured. */
|
|
66
|
+
query: string;
|
|
67
|
+
mode: PipelineMode;
|
|
68
|
+
/** Buckets retrieval ran against for this turn. */
|
|
69
|
+
buckets: string[];
|
|
70
|
+
/** Caller identity, where the surface has one. Absent on anonymous surfaces. */
|
|
71
|
+
sender?: string;
|
|
72
|
+
/**
|
|
73
|
+
* What `store.query` returned, before `rerankContext` ran: always
|
|
74
|
+
* non-empty when this is empty because `rerankContext` filtered
|
|
75
|
+
* everything out, and always empty when the store itself found nothing.
|
|
76
|
+
* A hook can use this to tell "some low-confidence signal existed" apart
|
|
77
|
+
* from "nothing matched at all".
|
|
78
|
+
*/
|
|
79
|
+
retrievedChunks: string[];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Runs only when retrieval produced no chunks for a turn (after
|
|
83
|
+
* `rerankContext`, if configured), the deterministic, testable alternative
|
|
84
|
+
* to baking "what if there's nothing to retrieve" judgment calls into
|
|
85
|
+
* freeform system-prompt text. Return a string to inject as an extra system
|
|
86
|
+
* prompt layer scoped to this turn only (e.g. "no matching context was
|
|
87
|
+
* found; offer a clearly-labelled guess or decline"); return `undefined` to
|
|
88
|
+
* leave the prompt exactly as it would be otherwise.
|
|
89
|
+
*
|
|
90
|
+
* A throw/rejection is caught by `prepareChat`, which proceeds without
|
|
91
|
+
* fallback guidance: a broken hook must never break the chat path.
|
|
92
|
+
*/
|
|
93
|
+
export type FallbackFn = (ctx: FallbackContext) => string | undefined | Promise<string | undefined>;
|
|
63
94
|
/**
|
|
64
95
|
* Run retrieval for the latest user message and assemble the system prompt.
|
|
65
96
|
*
|
|
66
97
|
* The assembled system prompt is layered, in order:
|
|
67
|
-
* base rules → persona → channel hint (optional) →
|
|
98
|
+
* base rules → persona → channel hint (optional) → fallback guidance
|
|
99
|
+
* (optional, only when retrieval came back empty) → retrieved context.
|
|
68
100
|
*
|
|
69
101
|
* `personaLayer` and `channelHint` let a caller shape those middle layers
|
|
70
102
|
* without hand-rolling its own sandwich around `store`/`prompts`. Both are
|
|
@@ -83,10 +115,13 @@ export type RerankContext = (ctx: RerankContextArgs) => string[] | Promise<strin
|
|
|
83
115
|
* value falls back to what retrieval would have done unmodified, so a buggy
|
|
84
116
|
* hook degrades relevance rather than breaking the chat path.
|
|
85
117
|
*
|
|
118
|
+
* `fallbackFn` runs after both, only when the chunks folded into the prompt
|
|
119
|
+
* would otherwise be empty, see {@link FallbackFn}.
|
|
120
|
+
*
|
|
86
121
|
* @throws if the conversation contains no user message
|
|
87
122
|
*/
|
|
88
|
-
export declare function prepareChat({ store, prompts, mode, messages, personaLayer, channelHint, buckets, sender, rewriteQuery, rerankContext, logger, }: {
|
|
89
|
-
store:
|
|
123
|
+
export declare function prepareChat({ store, prompts, mode, messages, personaLayer, channelHint, buckets, sender, rewriteQuery, rerankContext, fallbackFn, logger, }: {
|
|
124
|
+
store: Retriever;
|
|
90
125
|
prompts: PromptLoader;
|
|
91
126
|
mode: PipelineMode;
|
|
92
127
|
messages: PipelineMessage[];
|
|
@@ -105,7 +140,9 @@ export declare function prepareChat({ store, prompts, mode, messages, personaLay
|
|
|
105
140
|
rewriteQuery?: RewriteQuery;
|
|
106
141
|
/** Post-processes retrieved chunks before they're folded into the prompt — see {@link RerankContext}. */
|
|
107
142
|
rerankContext?: RerankContext;
|
|
108
|
-
/**
|
|
143
|
+
/** Injects fallback guidance when retrieval comes back empty, see {@link FallbackFn}. */
|
|
144
|
+
fallbackFn?: FallbackFn;
|
|
145
|
+
/** Logs a `rewriteQuery`/`rerankContext`/`fallbackFn` throw before falling back. Unset: the failure is silent. */
|
|
109
146
|
logger?: Pick<Logger, "error">;
|
|
110
147
|
}): Promise<PreparedChat>;
|
|
111
148
|
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"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"}
|
package/dist/core/prompts.d.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Loads prompt templates and interpolates bot configuration
|
|
4
4
|
*/
|
|
5
5
|
import type { BotIdentity } from "../types";
|
|
6
|
+
/** Default prompts directory when a caller's `config.promptsDir` is unset. */
|
|
7
|
+
export declare const DEFAULT_PROMPTS_DIR = "./config/prompts";
|
|
6
8
|
/**
|
|
7
9
|
* Prompt loader class that loads and interpolates prompt templates
|
|
8
10
|
* with bot identity information
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/core/prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;GAGG;AACH,qBAAa,YAAY;IAErB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,GAAG;IAFb,YACU,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,WAAW,EACtB;IAEJ;;OAEG;IACH,OAAO,CAAC,IAAI;IAcZ,+BAA+B;IAC/B,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,4BAA4B;IAC5B,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,6BAA6B;IAC7B,IAAI,cAAc,IAAI,MAAM,CAE3B;CACF"}
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/core/prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,8EAA8E;AAC9E,eAAO,MAAM,mBAAmB,qBAAqB,CAAC;AAEtD;;;GAGG;AACH,qBAAa,YAAY;IAErB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,GAAG;IAFb,YACU,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,WAAW,EACtB;IAEJ;;OAEG;IACH,OAAO,CAAC,IAAI;IAcZ,+BAA+B;IAC/B,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,4BAA4B;IAC5B,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,6BAA6B;IAC7B,IAAI,cAAc,IAAI,MAAM,CAE3B;CACF"}
|