@diegoaltoworks/chatter 0.57.0 → 0.59.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 +18 -3
- package/dist/channels/index.mjs +18 -3
- package/dist/channels/pipeline.d.ts +8 -0
- package/dist/channels/pipeline.d.ts.map +1 -1
- package/dist/channels/telegram/api.d.ts +17 -0
- package/dist/channels/telegram/api.d.ts.map +1 -1
- package/dist/channels/telegram/channel.d.ts +11 -1
- package/dist/channels/telegram/channel.d.ts.map +1 -1
- package/dist/channels/telegram/handler.d.ts +31 -0
- package/dist/channels/telegram/handler.d.ts.map +1 -0
- package/dist/channels/telegram/index.d.ts +7 -0
- package/dist/channels/telegram/index.d.ts.map +1 -1
- package/dist/channels/telegram/index.js +319 -82
- package/dist/channels/telegram/index.mjs +316 -82
- package/dist/channels/telegram/webhook.d.ts +95 -0
- package/dist/channels/telegram/webhook.d.ts.map +1 -0
- package/dist/channels/whatsapp/inbound.d.ts +6 -0
- package/dist/channels/whatsapp/inbound.d.ts.map +1 -1
- package/dist/channels/whatsapp/index.js +18 -3
- package/dist/channels/whatsapp/index.mjs +18 -3
- 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/package.json +1 -1
|
@@ -790,6 +790,16 @@ async function resolvePersonaLayer(config, ctx) {
|
|
|
790
790
|
return void 0;
|
|
791
791
|
}
|
|
792
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
|
+
}
|
|
793
803
|
function createInboundPipeline(deps, config) {
|
|
794
804
|
const mutedChats = /* @__PURE__ */ new Set();
|
|
795
805
|
const now = config.now ?? Date.now;
|
|
@@ -829,12 +839,15 @@ function createInboundPipeline(deps, config) {
|
|
|
829
839
|
}
|
|
830
840
|
const personaLayer = await resolvePersonaLayer(config, { sender, text: msg.text });
|
|
831
841
|
const buckets = await resolveBuckets({ mode, sender, bucketsFor: config.bucketsFor });
|
|
832
|
-
const
|
|
842
|
+
const historyEnabled = config.history ? await isHistoryEnabled(config, sender) : false;
|
|
843
|
+
const priorTurns = config.history && historyEnabled ? await config.history.store.load(
|
|
833
844
|
conversationId,
|
|
834
845
|
config.history.limit ?? DEFAULT_HISTORY_LIMIT
|
|
835
846
|
) : [];
|
|
836
847
|
const messages = [...priorTurns, { role: "user", content: msg.text }];
|
|
837
|
-
|
|
848
|
+
if (historyEnabled) {
|
|
849
|
+
await config.history?.store.append(conversationId, { role: "user", content: msg.text });
|
|
850
|
+
}
|
|
838
851
|
const { system } = await prepareChat({
|
|
839
852
|
store: deps.store,
|
|
840
853
|
prompts: deps.prompts,
|
|
@@ -866,7 +879,9 @@ function createInboundPipeline(deps, config) {
|
|
|
866
879
|
if (!content) {
|
|
867
880
|
return { action: "ignore" };
|
|
868
881
|
}
|
|
869
|
-
|
|
882
|
+
if (historyEnabled) {
|
|
883
|
+
await config.history?.store.append(conversationId, { role: "assistant", content });
|
|
884
|
+
}
|
|
870
885
|
await turn.reply.sendAnswer(msg.chatId, content);
|
|
871
886
|
return { action: "reply", content };
|
|
872
887
|
};
|
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/package.json
CHANGED