@diegoaltoworks/chatter 0.56.0 → 0.58.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/dist/channels/index.js +46 -6
- package/dist/channels/index.mjs +46 -6
- package/dist/channels/pipeline.d.ts +13 -0
- package/dist/channels/pipeline.d.ts.map +1 -1
- package/dist/channels/telegram/channel.d.ts +12 -0
- package/dist/channels/telegram/channel.d.ts.map +1 -1
- package/dist/channels/telegram/index.js +48 -6
- package/dist/channels/telegram/index.mjs +48 -6
- package/dist/channels/whatsapp/inbound.d.ts +13 -0
- package/dist/channels/whatsapp/inbound.d.ts.map +1 -1
- package/dist/channels/whatsapp/index.js +48 -6
- package/dist/channels/whatsapp/index.mjs +48 -6
- package/dist/core/pipeline.d.ts +52 -1
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/history/index.d.ts +1 -0
- package/dist/history/index.d.ts.map +1 -1
- package/dist/history/index.js +23 -2
- package/dist/history/index.mjs +23 -2
- package/dist/history/tursoStore.d.ts +13 -1
- package/dist/history/tursoStore.d.ts.map +1 -1
- package/dist/history/types.d.ts +2 -0
- package/dist/history/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +74 -9
- package/dist/index.mjs +74 -9
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +31 -4
- package/dist/mcp-server.mjs +31 -4
- 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/server.js +66 -7
- package/dist/server.mjs +66 -7
- package/dist/types.d.ts +25 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -737,14 +737,35 @@ async function prepareChat({
|
|
|
737
737
|
messages,
|
|
738
738
|
personaLayer,
|
|
739
739
|
channelHint,
|
|
740
|
-
buckets
|
|
740
|
+
buckets,
|
|
741
|
+
sender,
|
|
742
|
+
rewriteQuery,
|
|
743
|
+
rerankContext,
|
|
744
|
+
logger
|
|
741
745
|
}) {
|
|
742
746
|
const lastUserMsg = lastUserMessage(messages);
|
|
743
747
|
if (!lastUserMsg) {
|
|
744
748
|
throw new Error("no user message found in conversation");
|
|
745
749
|
}
|
|
746
750
|
const { topK, label } = MODE_SETTINGS[mode];
|
|
747
|
-
|
|
751
|
+
let query = lastUserMsg.content;
|
|
752
|
+
if (rewriteQuery) {
|
|
753
|
+
try {
|
|
754
|
+
const rewritten = await rewriteQuery({ query, mode, sender });
|
|
755
|
+
if (typeof rewritten === "string" && rewritten.trim()) query = rewritten;
|
|
756
|
+
} catch (error) {
|
|
757
|
+
logger?.error("rewriteQuery threw; falling back to the original query", error);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
let ctx = await store.query(query, topK, buckets ?? defaultBuckets(mode));
|
|
761
|
+
if (rerankContext) {
|
|
762
|
+
try {
|
|
763
|
+
const reranked = await rerankContext({ query, chunks: ctx });
|
|
764
|
+
if (Array.isArray(reranked) && reranked.every((c) => typeof c === "string")) ctx = reranked;
|
|
765
|
+
} catch (error) {
|
|
766
|
+
logger?.error("rerankContext threw; falling back to the original chunks", error);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
748
769
|
const persona = personaLayer?.trim() || (mode === "private" ? prompts.privatePersona : prompts.publicPersona);
|
|
749
770
|
const hint = channelHint?.trim();
|
|
750
771
|
const system = [
|
|
@@ -769,6 +790,16 @@ async function resolvePersonaLayer(config, ctx) {
|
|
|
769
790
|
return void 0;
|
|
770
791
|
}
|
|
771
792
|
}
|
|
793
|
+
async function isHistoryEnabled(config, sender) {
|
|
794
|
+
const predicate = config.history?.historyEnabledFor;
|
|
795
|
+
if (!predicate) return true;
|
|
796
|
+
try {
|
|
797
|
+
return await predicate(sender);
|
|
798
|
+
} catch (error) {
|
|
799
|
+
config.logger?.error("historyEnabledFor threw; disabling history for this turn", error);
|
|
800
|
+
return false;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
772
803
|
function createInboundPipeline(deps, config) {
|
|
773
804
|
const mutedChats = /* @__PURE__ */ new Set();
|
|
774
805
|
const now = config.now ?? Date.now;
|
|
@@ -808,12 +839,15 @@ function createInboundPipeline(deps, config) {
|
|
|
808
839
|
}
|
|
809
840
|
const personaLayer = await resolvePersonaLayer(config, { sender, text: msg.text });
|
|
810
841
|
const buckets = await resolveBuckets({ mode, sender, bucketsFor: config.bucketsFor });
|
|
811
|
-
const
|
|
842
|
+
const historyEnabled = config.history ? await isHistoryEnabled(config, sender) : false;
|
|
843
|
+
const priorTurns = config.history && historyEnabled ? await config.history.store.load(
|
|
812
844
|
conversationId,
|
|
813
845
|
config.history.limit ?? DEFAULT_HISTORY_LIMIT
|
|
814
846
|
) : [];
|
|
815
847
|
const messages = [...priorTurns, { role: "user", content: msg.text }];
|
|
816
|
-
|
|
848
|
+
if (historyEnabled) {
|
|
849
|
+
await config.history?.store.append(conversationId, { role: "user", content: msg.text });
|
|
850
|
+
}
|
|
817
851
|
const { system } = await prepareChat({
|
|
818
852
|
store: deps.store,
|
|
819
853
|
prompts: deps.prompts,
|
|
@@ -821,7 +855,11 @@ function createInboundPipeline(deps, config) {
|
|
|
821
855
|
messages,
|
|
822
856
|
personaLayer,
|
|
823
857
|
channelHint: config.channelHint,
|
|
824
|
-
buckets
|
|
858
|
+
buckets,
|
|
859
|
+
sender,
|
|
860
|
+
rewriteQuery: config.rewriteQuery,
|
|
861
|
+
rerankContext: config.rerankContext,
|
|
862
|
+
logger: config.logger
|
|
825
863
|
});
|
|
826
864
|
const { content: produced } = await answerOnce({
|
|
827
865
|
answerFn: config.answerFn,
|
|
@@ -841,7 +879,9 @@ function createInboundPipeline(deps, config) {
|
|
|
841
879
|
if (!content) {
|
|
842
880
|
return { action: "ignore" };
|
|
843
881
|
}
|
|
844
|
-
|
|
882
|
+
if (historyEnabled) {
|
|
883
|
+
await config.history?.store.append(conversationId, { role: "assistant", content });
|
|
884
|
+
}
|
|
845
885
|
await turn.reply.sendAnswer(msg.chatId, content);
|
|
846
886
|
return { action: "reply", content };
|
|
847
887
|
};
|
|
@@ -948,6 +988,8 @@ function createWhatsAppInboundHandler(config) {
|
|
|
948
988
|
channel: "whatsapp",
|
|
949
989
|
answerFn: config.answerFn,
|
|
950
990
|
bucketsFor: config.bucketsFor,
|
|
991
|
+
rewriteQuery: config.rewriteQuery,
|
|
992
|
+
rerankContext: config.rerankContext,
|
|
951
993
|
transformReply: config.transformReply,
|
|
952
994
|
model: config.model,
|
|
953
995
|
channelHint: config.channelHint,
|
package/dist/core/pipeline.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* then ask for the answer via `answerOnce`/`answerStream` (see ./answer.ts)
|
|
9
9
|
* so a caller-supplied brain is honoured.
|
|
10
10
|
*/
|
|
11
|
+
import type { Logger } from "./logger";
|
|
11
12
|
import type { PromptLoader } from "./prompts";
|
|
12
13
|
import type { VectorStore } from "./retrieval";
|
|
13
14
|
export type PipelineMode = "public" | "private";
|
|
@@ -23,6 +24,42 @@ export interface PreparedChat {
|
|
|
23
24
|
/** Raw retrieved chunks, before being folded into `system` — for callers that log or display RAG context alongside the answer */
|
|
24
25
|
context: string[];
|
|
25
26
|
}
|
|
27
|
+
/** What `rewriteQuery` sees for a turn. */
|
|
28
|
+
export interface RewriteQueryArgs {
|
|
29
|
+
/** The latest user message's content — what retrieval would search on unmodified. */
|
|
30
|
+
query: string;
|
|
31
|
+
mode: PipelineMode;
|
|
32
|
+
/** Caller identity, where the surface has one. Absent on anonymous surfaces. */
|
|
33
|
+
sender?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Rewrites the retrieval query before it reaches the vector store — e.g.
|
|
37
|
+
* expanding an ambiguous follow-up ("what about the second one?") into
|
|
38
|
+
* something embeddable on its own. Return the query unchanged to opt out for
|
|
39
|
+
* a given turn. A throw/rejection is caught by `prepareChat`, which falls
|
|
40
|
+
* back to the original query — a broken rewrite must never break retrieval.
|
|
41
|
+
*/
|
|
42
|
+
export type RewriteQuery = (ctx: RewriteQueryArgs) => string | Promise<string>;
|
|
43
|
+
/** What `rerankContext` sees for a turn. */
|
|
44
|
+
export interface RerankContextArgs {
|
|
45
|
+
/** The query retrieval actually ran with — post-`rewriteQuery`, if configured. */
|
|
46
|
+
query: string;
|
|
47
|
+
/** Chunks `store.query` returned, in its own order. */
|
|
48
|
+
chunks: string[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reorders, filters, or otherwise post-processes the chunks retrieval
|
|
52
|
+
* returned before they're folded into the system prompt. A throw/rejection
|
|
53
|
+
* is caught by `prepareChat`, which falls back to the original chunks in
|
|
54
|
+
* their original order — a broken reranker must never break retrieval.
|
|
55
|
+
*
|
|
56
|
+
* This is NOT the seam for access control. Because a failure falls back to
|
|
57
|
+
* the unfiltered chunks, a hook that drops chunks a sender shouldn't see
|
|
58
|
+
* would silently un-drop them on its own error — the opposite of safe
|
|
59
|
+
* failure. Scope decisions belong in `bucketsFor` (see ./buckets), which
|
|
60
|
+
* fails closed by design; use this hook for relevance/ordering only.
|
|
61
|
+
*/
|
|
62
|
+
export type RerankContext = (ctx: RerankContextArgs) => string[] | Promise<string[]>;
|
|
26
63
|
/**
|
|
27
64
|
* Run retrieval for the latest user message and assemble the system prompt.
|
|
28
65
|
*
|
|
@@ -40,9 +77,15 @@ export interface PreparedChat {
|
|
|
40
77
|
* `resolveBuckets` (see ./buckets) first, which is where the anonymous
|
|
41
78
|
* ceiling is enforced.
|
|
42
79
|
*
|
|
80
|
+
* `rewriteQuery` and `rerankContext` shape retrieval itself rather than the
|
|
81
|
+
* prompt around it: the former runs before `store.query`, the latter after.
|
|
82
|
+
* Both are optional and fail open — a throw, rejection, or malformed return
|
|
83
|
+
* value falls back to what retrieval would have done unmodified, so a buggy
|
|
84
|
+
* hook degrades relevance rather than breaking the chat path.
|
|
85
|
+
*
|
|
43
86
|
* @throws if the conversation contains no user message
|
|
44
87
|
*/
|
|
45
|
-
export declare function prepareChat({ store, prompts, mode, messages, personaLayer, channelHint, buckets, }: {
|
|
88
|
+
export declare function prepareChat({ store, prompts, mode, messages, personaLayer, channelHint, buckets, sender, rewriteQuery, rerankContext, logger, }: {
|
|
46
89
|
store: VectorStore;
|
|
47
90
|
prompts: PromptLoader;
|
|
48
91
|
mode: PipelineMode;
|
|
@@ -56,5 +99,13 @@ export declare function prepareChat({ store, prompts, mode, messages, personaLay
|
|
|
56
99
|
* `["base", mode]`. An empty array retrieves nothing.
|
|
57
100
|
*/
|
|
58
101
|
buckets?: string[];
|
|
102
|
+
/** Caller identity, passed through to `rewriteQuery`. Absent on anonymous surfaces. */
|
|
103
|
+
sender?: string;
|
|
104
|
+
/** Rewrites the retrieval query before `store.query` runs — see {@link RewriteQuery}. */
|
|
105
|
+
rewriteQuery?: RewriteQuery;
|
|
106
|
+
/** Post-processes retrieved chunks before they're folded into the prompt — see {@link RerankContext}. */
|
|
107
|
+
rerankContext?: RerankContext;
|
|
108
|
+
/** Logs a `rewriteQuery`/`rerankContext` throw before falling back. Unset: the failure is silent. */
|
|
109
|
+
logger?: Pick<Logger, "error">;
|
|
59
110
|
}): Promise<PreparedChat>;
|
|
60
111
|
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
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,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,iIAAiI;IACjI,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,gBAAgB,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAE/E,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAOrF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,WAAW,CAAC,EAChC,KAAK,EACL,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,OAAO,EACP,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,GACP,EAAE;IACD,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yFAAyF;IACzF,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,yGAAyG;IACzG,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,qGAAqG;IACrG,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,GAAG,OAAO,CAAC,YAAY,CAAC,CAuCxB"}
|
package/dist/history/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @packageDocumentation
|
|
14
14
|
*/
|
|
15
|
+
export type { TursoHistoryStoreOptions } from "./tursoStore";
|
|
15
16
|
export { createTursoHistoryStore } from "./tursoStore";
|
|
16
17
|
export type { HistoryMessage, HistoryStore } from "./types";
|
|
17
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/history/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/history/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,YAAY,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/history/index.js
CHANGED
|
@@ -58,19 +58,32 @@ function ensureHistorySchema(client, tableName) {
|
|
|
58
58
|
var VALID_TABLE_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
59
59
|
var VALID_ROLES = /* @__PURE__ */ new Set(["user", "assistant"]);
|
|
60
60
|
var DEFAULT_MAX_PER_CONVERSATION = 200;
|
|
61
|
-
function createTursoHistoryStore(client, tableName = "chat_history", maxPerConversation = DEFAULT_MAX_PER_CONVERSATION) {
|
|
61
|
+
function createTursoHistoryStore(client, tableName = "chat_history", maxPerConversation = DEFAULT_MAX_PER_CONVERSATION, options) {
|
|
62
62
|
if (!VALID_TABLE_NAME.test(tableName)) {
|
|
63
63
|
throw new Error(`Invalid history store table name: ${tableName}`);
|
|
64
64
|
}
|
|
65
65
|
if (!Number.isInteger(maxPerConversation) || maxPerConversation < 1) {
|
|
66
66
|
throw new Error(`Invalid history store maxPerConversation: ${maxPerConversation}`);
|
|
67
67
|
}
|
|
68
|
+
if (options?.ttlMs !== void 0 && (!Number.isInteger(options.ttlMs) || options.ttlMs < 1)) {
|
|
69
|
+
throw new Error(`Invalid history store ttlMs: ${options.ttlMs}`);
|
|
70
|
+
}
|
|
71
|
+
const ttlMs = options?.ttlMs;
|
|
72
|
+
const now = options?.now ?? Date.now;
|
|
73
|
+
async function pruneExpired(conversationId) {
|
|
74
|
+
if (ttlMs === void 0) return;
|
|
75
|
+
await client.execute({
|
|
76
|
+
sql: `DELETE FROM ${tableName} WHERE conversation_id = ? AND created_at < ?`,
|
|
77
|
+
args: [conversationId, now() - ttlMs]
|
|
78
|
+
});
|
|
79
|
+
}
|
|
68
80
|
return {
|
|
69
81
|
async append(conversationId, message) {
|
|
70
82
|
await ensureHistorySchema(client, tableName);
|
|
83
|
+
await pruneExpired(conversationId);
|
|
71
84
|
await client.execute({
|
|
72
85
|
sql: `INSERT INTO ${tableName} (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)`,
|
|
73
|
-
args: [conversationId, message.role, message.content,
|
|
86
|
+
args: [conversationId, message.role, message.content, now()]
|
|
74
87
|
});
|
|
75
88
|
await client.execute({
|
|
76
89
|
sql: `DELETE FROM ${tableName} WHERE conversation_id = ? AND id NOT IN (
|
|
@@ -83,6 +96,7 @@ function createTursoHistoryStore(client, tableName = "chat_history", maxPerConve
|
|
|
83
96
|
const boundedLimit = Math.max(0, Math.trunc(limit));
|
|
84
97
|
if (boundedLimit === 0) return [];
|
|
85
98
|
await ensureHistorySchema(client, tableName);
|
|
99
|
+
await pruneExpired(conversationId);
|
|
86
100
|
const result = await client.execute({
|
|
87
101
|
sql: `SELECT role, content FROM ${tableName} WHERE conversation_id = ? ORDER BY id DESC LIMIT ?`,
|
|
88
102
|
args: [conversationId, boundedLimit]
|
|
@@ -91,6 +105,13 @@ function createTursoHistoryStore(client, tableName = "chat_history", maxPerConve
|
|
|
91
105
|
role: String(row.role),
|
|
92
106
|
content: String(row.content)
|
|
93
107
|
})).filter((row) => VALID_ROLES.has(row.role)).reverse();
|
|
108
|
+
},
|
|
109
|
+
async clear(conversationId) {
|
|
110
|
+
await ensureHistorySchema(client, tableName);
|
|
111
|
+
await client.execute({
|
|
112
|
+
sql: `DELETE FROM ${tableName} WHERE conversation_id = ?`,
|
|
113
|
+
args: [conversationId]
|
|
114
|
+
});
|
|
94
115
|
}
|
|
95
116
|
};
|
|
96
117
|
}
|
package/dist/history/index.mjs
CHANGED
|
@@ -32,19 +32,32 @@ function ensureHistorySchema(client, tableName) {
|
|
|
32
32
|
var VALID_TABLE_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
33
33
|
var VALID_ROLES = /* @__PURE__ */ new Set(["user", "assistant"]);
|
|
34
34
|
var DEFAULT_MAX_PER_CONVERSATION = 200;
|
|
35
|
-
function createTursoHistoryStore(client, tableName = "chat_history", maxPerConversation = DEFAULT_MAX_PER_CONVERSATION) {
|
|
35
|
+
function createTursoHistoryStore(client, tableName = "chat_history", maxPerConversation = DEFAULT_MAX_PER_CONVERSATION, options) {
|
|
36
36
|
if (!VALID_TABLE_NAME.test(tableName)) {
|
|
37
37
|
throw new Error(`Invalid history store table name: ${tableName}`);
|
|
38
38
|
}
|
|
39
39
|
if (!Number.isInteger(maxPerConversation) || maxPerConversation < 1) {
|
|
40
40
|
throw new Error(`Invalid history store maxPerConversation: ${maxPerConversation}`);
|
|
41
41
|
}
|
|
42
|
+
if (options?.ttlMs !== void 0 && (!Number.isInteger(options.ttlMs) || options.ttlMs < 1)) {
|
|
43
|
+
throw new Error(`Invalid history store ttlMs: ${options.ttlMs}`);
|
|
44
|
+
}
|
|
45
|
+
const ttlMs = options?.ttlMs;
|
|
46
|
+
const now = options?.now ?? Date.now;
|
|
47
|
+
async function pruneExpired(conversationId) {
|
|
48
|
+
if (ttlMs === void 0) return;
|
|
49
|
+
await client.execute({
|
|
50
|
+
sql: `DELETE FROM ${tableName} WHERE conversation_id = ? AND created_at < ?`,
|
|
51
|
+
args: [conversationId, now() - ttlMs]
|
|
52
|
+
});
|
|
53
|
+
}
|
|
42
54
|
return {
|
|
43
55
|
async append(conversationId, message) {
|
|
44
56
|
await ensureHistorySchema(client, tableName);
|
|
57
|
+
await pruneExpired(conversationId);
|
|
45
58
|
await client.execute({
|
|
46
59
|
sql: `INSERT INTO ${tableName} (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)`,
|
|
47
|
-
args: [conversationId, message.role, message.content,
|
|
60
|
+
args: [conversationId, message.role, message.content, now()]
|
|
48
61
|
});
|
|
49
62
|
await client.execute({
|
|
50
63
|
sql: `DELETE FROM ${tableName} WHERE conversation_id = ? AND id NOT IN (
|
|
@@ -57,6 +70,7 @@ function createTursoHistoryStore(client, tableName = "chat_history", maxPerConve
|
|
|
57
70
|
const boundedLimit = Math.max(0, Math.trunc(limit));
|
|
58
71
|
if (boundedLimit === 0) return [];
|
|
59
72
|
await ensureHistorySchema(client, tableName);
|
|
73
|
+
await pruneExpired(conversationId);
|
|
60
74
|
const result = await client.execute({
|
|
61
75
|
sql: `SELECT role, content FROM ${tableName} WHERE conversation_id = ? ORDER BY id DESC LIMIT ?`,
|
|
62
76
|
args: [conversationId, boundedLimit]
|
|
@@ -65,6 +79,13 @@ function createTursoHistoryStore(client, tableName = "chat_history", maxPerConve
|
|
|
65
79
|
role: String(row.role),
|
|
66
80
|
content: String(row.content)
|
|
67
81
|
})).filter((row) => VALID_ROLES.has(row.role)).reverse();
|
|
82
|
+
},
|
|
83
|
+
async clear(conversationId) {
|
|
84
|
+
await ensureHistorySchema(client, tableName);
|
|
85
|
+
await client.execute({
|
|
86
|
+
sql: `DELETE FROM ${tableName} WHERE conversation_id = ?`,
|
|
87
|
+
args: [conversationId]
|
|
88
|
+
});
|
|
68
89
|
}
|
|
69
90
|
};
|
|
70
91
|
}
|
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { Client } from "@libsql/client";
|
|
12
12
|
import type { HistoryStore } from "./types";
|
|
13
|
+
export interface TursoHistoryStoreOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Retention window: rows older than this are pruned whenever the
|
|
16
|
+
* conversation they belong to is accessed (`append` or `load`) — there is
|
|
17
|
+
* no background sweep. Unset: rows never expire on their own (only the
|
|
18
|
+
* `maxPerConversation` count cap and explicit `clear` remove them). Must be
|
|
19
|
+
* a positive integer, validated at construction like `maxPerConversation`.
|
|
20
|
+
*/
|
|
21
|
+
ttlMs?: number;
|
|
22
|
+
/** Injectable clock for tests. @default Date.now */
|
|
23
|
+
now?: () => number;
|
|
24
|
+
}
|
|
13
25
|
/**
|
|
14
26
|
* Creates a history store keyed by an arbitrary conversation id (a WhatsApp
|
|
15
27
|
* chat jid, a phone call sid, a web session id) on `tableName`.
|
|
@@ -22,5 +34,5 @@ import type { HistoryStore } from "./types";
|
|
|
22
34
|
* or disable pruning entirely (SQLite reads a negative `LIMIT` as
|
|
23
35
|
* unlimited), so it is validated at construction the same way `tableName` is.
|
|
24
36
|
*/
|
|
25
|
-
export declare function createTursoHistoryStore(client: Client, tableName?: string, maxPerConversation?: number): HistoryStore;
|
|
37
|
+
export declare function createTursoHistoryStore(client: Client, tableName?: string, maxPerConversation?: number, options?: TursoHistoryStoreOptions): HistoryStore;
|
|
26
38
|
//# sourceMappingURL=tursoStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tursoStore.d.ts","sourceRoot":"","sources":["../../src/history/tursoStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,SAAS,CAAC;AAkD5D;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,SAAS,SAAiB,EAC1B,kBAAkB,SAA+B,
|
|
1
|
+
{"version":3,"file":"tursoStore.d.ts","sourceRoot":"","sources":["../../src/history/tursoStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,SAAS,CAAC;AAkD5D,MAAM,WAAW,wBAAwB;IACvC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,SAAS,SAAiB,EAC1B,kBAAkB,SAA+B,EACjD,OAAO,CAAC,EAAE,wBAAwB,GACjC,YAAY,CAyEd"}
|
package/dist/history/types.d.ts
CHANGED
|
@@ -14,5 +14,7 @@ export interface HistoryStore {
|
|
|
14
14
|
append(conversationId: string, message: HistoryMessage): Promise<void>;
|
|
15
15
|
/** Load up to `limit` most recent turns for `conversationId`, oldest first. */
|
|
16
16
|
load(conversationId: string, limit: number): Promise<HistoryMessage[]>;
|
|
17
|
+
/** Reset primitive: erases all of `conversationId`'s history. Other conversations are untouched. */
|
|
18
|
+
clear(conversationId: string): Promise<void>;
|
|
17
19
|
}
|
|
18
20
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/history/types.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,+EAA+E;IAC/E,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/history/types.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,+EAA+E;IAC/E,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACvE,oGAAoG;IACpG,KAAK,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C"}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export type { Logger, LogLevel } from "./core/logger";
|
|
|
25
25
|
export { createConsoleLogger } from "./core/logger";
|
|
26
26
|
export type { NormalizedChatBody } from "./core/messages";
|
|
27
27
|
export { normalizeChatBody, normalizeMessages } from "./core/messages";
|
|
28
|
-
export type { PipelineMessage, PipelineMode, PreparedChat } from "./core/pipeline";
|
|
28
|
+
export type { PipelineMessage, PipelineMode, PreparedChat, RerankContext, RerankContextArgs, RewriteQuery, RewriteQueryArgs, } from "./core/pipeline";
|
|
29
29
|
export { prepareChat } from "./core/pipeline";
|
|
30
30
|
export { PromptLoader } from "./core/prompts";
|
|
31
31
|
export type { VectorStoreOptions } from "./core/retrieval";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEzE,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAIvC,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,eAAe,GAChB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,QAAQ,EACR,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,EACX,cAAc,EACd,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC9E,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG1D,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -458,14 +458,35 @@ async function prepareChat({
|
|
|
458
458
|
messages,
|
|
459
459
|
personaLayer,
|
|
460
460
|
channelHint,
|
|
461
|
-
buckets
|
|
461
|
+
buckets,
|
|
462
|
+
sender,
|
|
463
|
+
rewriteQuery,
|
|
464
|
+
rerankContext,
|
|
465
|
+
logger
|
|
462
466
|
}) {
|
|
463
467
|
const lastUserMsg = lastUserMessage(messages);
|
|
464
468
|
if (!lastUserMsg) {
|
|
465
469
|
throw new Error("no user message found in conversation");
|
|
466
470
|
}
|
|
467
471
|
const { topK, label } = MODE_SETTINGS[mode];
|
|
468
|
-
|
|
472
|
+
let query = lastUserMsg.content;
|
|
473
|
+
if (rewriteQuery) {
|
|
474
|
+
try {
|
|
475
|
+
const rewritten = await rewriteQuery({ query, mode, sender });
|
|
476
|
+
if (typeof rewritten === "string" && rewritten.trim()) query = rewritten;
|
|
477
|
+
} catch (error) {
|
|
478
|
+
logger?.error("rewriteQuery threw; falling back to the original query", error);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
let ctx = await store.query(query, topK, buckets ?? defaultBuckets(mode));
|
|
482
|
+
if (rerankContext) {
|
|
483
|
+
try {
|
|
484
|
+
const reranked = await rerankContext({ query, chunks: ctx });
|
|
485
|
+
if (Array.isArray(reranked) && reranked.every((c) => typeof c === "string")) ctx = reranked;
|
|
486
|
+
} catch (error) {
|
|
487
|
+
logger?.error("rerankContext threw; falling back to the original chunks", error);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
469
490
|
const persona = personaLayer?.trim() || (mode === "private" ? prompts.privatePersona : prompts.publicPersona);
|
|
470
491
|
const hint = channelHint?.trim();
|
|
471
492
|
const system = [
|
|
@@ -1004,7 +1025,10 @@ async function createMCPServer(config) {
|
|
|
1004
1025
|
prompts,
|
|
1005
1026
|
mode: "public",
|
|
1006
1027
|
messages: conversationMessages,
|
|
1007
|
-
buckets
|
|
1028
|
+
buckets,
|
|
1029
|
+
rewriteQuery: config.rewriteQuery,
|
|
1030
|
+
rerankContext: config.rerankContext,
|
|
1031
|
+
logger: log
|
|
1008
1032
|
});
|
|
1009
1033
|
const result = await answerOnce({
|
|
1010
1034
|
answerFn: config.answerFn,
|
|
@@ -1090,7 +1114,10 @@ async function createMCPServer(config) {
|
|
|
1090
1114
|
prompts,
|
|
1091
1115
|
mode: "private",
|
|
1092
1116
|
messages: conversationMessages,
|
|
1093
|
-
buckets
|
|
1117
|
+
buckets,
|
|
1118
|
+
rewriteQuery: config.rewriteQuery,
|
|
1119
|
+
rerankContext: config.rerankContext,
|
|
1120
|
+
logger: log
|
|
1094
1121
|
});
|
|
1095
1122
|
const result = await answerOnce({
|
|
1096
1123
|
answerFn: config.answerFn,
|
|
@@ -1565,7 +1592,16 @@ function demoRoutes(deps) {
|
|
|
1565
1592
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
1566
1593
|
}
|
|
1567
1594
|
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config.bucketsFor });
|
|
1568
|
-
const { system } = await prepareChat({
|
|
1595
|
+
const { system } = await prepareChat({
|
|
1596
|
+
store,
|
|
1597
|
+
prompts,
|
|
1598
|
+
mode: "public",
|
|
1599
|
+
messages,
|
|
1600
|
+
buckets,
|
|
1601
|
+
rewriteQuery: config.rewriteQuery,
|
|
1602
|
+
rerankContext: config.rerankContext,
|
|
1603
|
+
logger
|
|
1604
|
+
});
|
|
1569
1605
|
const model = config.openai.model || DEFAULT_MODEL;
|
|
1570
1606
|
const url = new URL(c.req.url);
|
|
1571
1607
|
const wantsStream3 = url.searchParams.get("stream") === "1";
|
|
@@ -1684,13 +1720,23 @@ function openaiRoutes(deps) {
|
|
|
1684
1720
|
sender: jwtSubject(c),
|
|
1685
1721
|
bucketsFor: config.bucketsFor
|
|
1686
1722
|
});
|
|
1723
|
+
const sender = jwtSubject(c) ?? apiKeySubject(c);
|
|
1687
1724
|
let system;
|
|
1688
1725
|
try {
|
|
1689
|
-
({ system } = await prepareChat({
|
|
1726
|
+
({ system } = await prepareChat({
|
|
1727
|
+
store,
|
|
1728
|
+
prompts,
|
|
1729
|
+
mode,
|
|
1730
|
+
messages,
|
|
1731
|
+
buckets,
|
|
1732
|
+
sender,
|
|
1733
|
+
rewriteQuery: config.rewriteQuery,
|
|
1734
|
+
rerankContext: config.rerankContext,
|
|
1735
|
+
logger
|
|
1736
|
+
}));
|
|
1690
1737
|
} catch {
|
|
1691
1738
|
return errorJson(c, 400, "Conversation must contain at least one user message");
|
|
1692
1739
|
}
|
|
1693
|
-
const sender = jwtSubject(c) ?? apiKeySubject(c);
|
|
1694
1740
|
const conversationId = clientConversationId(c, body) ?? crypto.randomUUID();
|
|
1695
1741
|
c.header("x-conversation-id", conversationId);
|
|
1696
1742
|
const id = `chatcmpl-${crypto.randomUUID()}`;
|
|
@@ -1800,7 +1846,17 @@ function privateRoutes(deps) {
|
|
|
1800
1846
|
});
|
|
1801
1847
|
let system;
|
|
1802
1848
|
try {
|
|
1803
|
-
({ system } = await prepareChat({
|
|
1849
|
+
({ system } = await prepareChat({
|
|
1850
|
+
store,
|
|
1851
|
+
prompts,
|
|
1852
|
+
mode: "private",
|
|
1853
|
+
messages,
|
|
1854
|
+
buckets,
|
|
1855
|
+
sender,
|
|
1856
|
+
rewriteQuery: config.rewriteQuery,
|
|
1857
|
+
rerankContext: config.rerankContext,
|
|
1858
|
+
logger
|
|
1859
|
+
}));
|
|
1804
1860
|
} catch {
|
|
1805
1861
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
1806
1862
|
}
|
|
@@ -1876,7 +1932,16 @@ function publicRoutes(deps) {
|
|
|
1876
1932
|
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config.bucketsFor });
|
|
1877
1933
|
let system;
|
|
1878
1934
|
try {
|
|
1879
|
-
({ system } = await prepareChat({
|
|
1935
|
+
({ system } = await prepareChat({
|
|
1936
|
+
store,
|
|
1937
|
+
prompts,
|
|
1938
|
+
mode: "public",
|
|
1939
|
+
messages,
|
|
1940
|
+
buckets,
|
|
1941
|
+
rewriteQuery: config.rewriteQuery,
|
|
1942
|
+
rerankContext: config.rerankContext,
|
|
1943
|
+
logger
|
|
1944
|
+
}));
|
|
1880
1945
|
} catch {
|
|
1881
1946
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
1882
1947
|
}
|