@jungjaehoon/mama-os 0.64.0 → 0.66.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/CHANGELOG.md +65 -0
- package/README.md +14 -13
- package/dist/api/help-actions.js +1 -1
- package/dist/api/help-actions.js.map +1 -1
- package/dist/api/owner-message-actions.d.ts +1 -3
- package/dist/api/owner-message-actions.d.ts.map +1 -1
- package/dist/api/owner-message-actions.js +1 -6
- package/dist/api/owner-message-actions.js.map +1 -1
- package/dist/api/owner-policy-actions.d.ts +8 -0
- package/dist/api/owner-policy-actions.d.ts.map +1 -0
- package/dist/api/owner-policy-actions.js +160 -0
- package/dist/api/owner-policy-actions.js.map +1 -0
- package/dist/api/report-source-actions.d.ts.map +1 -1
- package/dist/api/report-source-actions.js +3 -1
- package/dist/api/report-source-actions.js.map +1 -1
- package/dist/api/wiki-actions.js +3 -3
- package/dist/api/wiki-actions.js.map +1 -1
- package/dist/api/work-actions.d.ts.map +1 -1
- package/dist/api/work-actions.js +9 -2
- package/dist/api/work-actions.js.map +1 -1
- package/dist/backfill/format.d.ts +2 -0
- package/dist/backfill/format.d.ts.map +1 -1
- package/dist/backfill/format.js +8 -3
- package/dist/backfill/format.js.map +1 -1
- package/dist/backfill/push.d.ts.map +1 -1
- package/dist/backfill/push.js +1 -0
- package/dist/backfill/push.js.map +1 -1
- package/dist/cli/commands/daemon.d.ts +0 -1
- package/dist/cli/commands/daemon.d.ts.map +1 -1
- package/dist/cli/commands/daemon.js +1 -1
- package/dist/cli/commands/daemon.js.map +1 -1
- package/dist/gateways/discord.d.ts +0 -1
- package/dist/gateways/discord.d.ts.map +1 -1
- package/dist/gateways/discord.js +23 -4
- package/dist/gateways/discord.js.map +1 -1
- package/dist/gateways/slack.d.ts +0 -1
- package/dist/gateways/slack.d.ts.map +1 -1
- package/dist/gateways/slack.js +23 -4
- package/dist/gateways/slack.js.map +1 -1
- package/dist/gateways/telegram-format.d.ts +0 -13
- package/dist/gateways/telegram-format.d.ts.map +1 -1
- package/dist/gateways/telegram-format.js +1 -42
- package/dist/gateways/telegram-format.js.map +1 -1
- package/dist/gateways/telegram-message-ledger.d.ts +3 -2
- package/dist/gateways/telegram-message-ledger.d.ts.map +1 -1
- package/dist/gateways/telegram-message-ledger.js +10 -9
- package/dist/gateways/telegram-message-ledger.js.map +1 -1
- package/dist/gateways/telegram-response-presenter.d.ts +6 -14
- package/dist/gateways/telegram-response-presenter.d.ts.map +1 -1
- package/dist/gateways/telegram-response-presenter.js +13 -98
- package/dist/gateways/telegram-response-presenter.js.map +1 -1
- package/dist/gateways/telegram.d.ts +0 -1
- package/dist/gateways/telegram.d.ts.map +1 -1
- package/dist/gateways/telegram.js +17 -5
- package/dist/gateways/telegram.js.map +1 -1
- package/dist/gateways/turn-contract.d.ts +8 -0
- package/dist/gateways/turn-contract.d.ts.map +1 -1
- package/dist/replay/import-manifest.d.ts +2 -2
- package/dist/replay/import-manifest.d.ts.map +1 -1
- package/dist/replay/import-manifest.js.map +1 -1
- package/dist/replay/replay-source-catalog.d.ts.map +1 -1
- package/dist/replay/replay-source-catalog.js +1 -0
- package/dist/replay/replay-source-catalog.js.map +1 -1
- package/dist/runtime/action-surface.d.ts +2 -1
- package/dist/runtime/action-surface.d.ts.map +1 -1
- package/dist/runtime/action-surface.js +32 -3
- package/dist/runtime/action-surface.js.map +1 -1
- package/dist/runtime/native-session.d.ts +1 -0
- package/dist/runtime/native-session.d.ts.map +1 -1
- package/dist/runtime/native-session.js +3 -0
- package/dist/runtime/native-session.js.map +1 -1
- package/dist/runtime/owner-authority.d.ts +4 -2
- package/dist/runtime/owner-authority.d.ts.map +1 -1
- package/dist/runtime/owner-authority.js +23 -3
- package/dist/runtime/owner-authority.js.map +1 -1
- package/dist/runtime/owner-policy.d.ts +3 -0
- package/dist/runtime/owner-policy.d.ts.map +1 -1
- package/dist/runtime/owner-policy.js +16 -3
- package/dist/runtime/owner-policy.js.map +1 -1
- package/dist/runtime/owner-runtime.d.ts +2 -3
- package/dist/runtime/owner-runtime.d.ts.map +1 -1
- package/dist/runtime/owner-runtime.js +15 -23
- package/dist/runtime/owner-runtime.js.map +1 -1
- package/dist/runtime/owner-system-prompt.d.ts.map +1 -1
- package/dist/runtime/owner-system-prompt.js +6 -5
- package/dist/runtime/owner-system-prompt.js.map +1 -1
- package/dist/runtime/session-start-context.d.ts +3 -22
- package/dist/runtime/session-start-context.d.ts.map +1 -1
- package/dist/runtime/session-start-context.js +1 -58
- package/dist/runtime/session-start-context.js.map +1 -1
- package/dist/runtime/stimulus-delivery.d.ts +4 -1
- package/dist/runtime/stimulus-delivery.d.ts.map +1 -1
- package/dist/runtime/stimulus-delivery.js +18 -10
- package/dist/runtime/stimulus-delivery.js.map +1 -1
- package/dist/runtime/timezone.d.ts +6 -0
- package/dist/runtime/timezone.d.ts.map +1 -1
- package/dist/runtime/timezone.js +11 -0
- package/dist/runtime/timezone.js.map +1 -1
- package/dist/runtime/turn-orders.d.ts +5 -0
- package/dist/runtime/turn-orders.d.ts.map +1 -1
- package/dist/runtime/turn-orders.js +12 -9
- package/dist/runtime/turn-orders.js.map +1 -1
- package/dist/storage/chat-sources.d.ts +21 -0
- package/dist/storage/chat-sources.d.ts.map +1 -0
- package/dist/storage/chat-sources.js +119 -0
- package/dist/storage/chat-sources.js.map +1 -0
- package/dist/wiki-artifacts/normalization.d.ts +1 -1
- package/dist/wiki-artifacts/normalization.d.ts.map +1 -1
- package/dist/wiki-artifacts/normalization.js +1 -4
- package/dist/wiki-artifacts/normalization.js.map +1 -1
- package/package.json +2 -2
- package/dist/gateways/conversation-record.d.ts +0 -52
- package/dist/gateways/conversation-record.d.ts.map +0 -1
- package/dist/gateways/conversation-record.js +0 -220
- package/dist/gateways/conversation-record.js.map +0 -1
- package/dist/gateways/session-store.d.ts +0 -120
- package/dist/gateways/session-store.d.ts.map +0 -1
- package/dist/gateways/session-store.js +0 -581
- package/dist/gateways/session-store.js.map +0 -1
|
@@ -1,581 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Session store for messenger conversations
|
|
4
|
-
*
|
|
5
|
-
* Manages conversation sessions with rolling context (history)
|
|
6
|
-
* for cross-platform messenger integration.
|
|
7
|
-
*/
|
|
8
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
-
if (k2 === undefined) k2 = k;
|
|
10
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
-
}
|
|
14
|
-
Object.defineProperty(o, k2, desc);
|
|
15
|
-
}) : (function(o, m, k, k2) {
|
|
16
|
-
if (k2 === undefined) k2 = k;
|
|
17
|
-
o[k2] = m[k];
|
|
18
|
-
}));
|
|
19
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
-
}) : function(o, v) {
|
|
22
|
-
o["default"] = v;
|
|
23
|
-
});
|
|
24
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
-
var ownKeys = function(o) {
|
|
26
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
-
var ar = [];
|
|
28
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
-
return ar;
|
|
30
|
-
};
|
|
31
|
-
return ownKeys(o);
|
|
32
|
-
};
|
|
33
|
-
return function (mod) {
|
|
34
|
-
if (mod && mod.__esModule) return mod;
|
|
35
|
-
var result = {};
|
|
36
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
-
__setModuleDefault(result, mod);
|
|
38
|
-
return result;
|
|
39
|
-
};
|
|
40
|
-
})();
|
|
41
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.SessionStore = void 0;
|
|
43
|
-
const crypto_1 = require("crypto");
|
|
44
|
-
const debugLogger = __importStar(require("@jungjaehoon/mama-core/debug-logger"));
|
|
45
|
-
const { DebugLogger } = debugLogger;
|
|
46
|
-
const logger = new DebugLogger('SessionStore');
|
|
47
|
-
// ============================================================================
|
|
48
|
-
// SessionStore Class
|
|
49
|
-
// ============================================================================
|
|
50
|
-
/**
|
|
51
|
-
* SQLite-backed session store for messenger conversations
|
|
52
|
-
*/
|
|
53
|
-
class SessionStore {
|
|
54
|
-
db;
|
|
55
|
-
maxTurns;
|
|
56
|
-
constructor(db, options = {}) {
|
|
57
|
-
this.db = db;
|
|
58
|
-
this.maxTurns = options.maxTurns ?? 1000; // Store unlimited turns in DB
|
|
59
|
-
this.runMigration();
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Run database migration
|
|
63
|
-
*/
|
|
64
|
-
runMigration() {
|
|
65
|
-
// Create table if not exists
|
|
66
|
-
this.db.exec(`
|
|
67
|
-
CREATE TABLE IF NOT EXISTS messenger_sessions (
|
|
68
|
-
id TEXT PRIMARY KEY,
|
|
69
|
-
source TEXT NOT NULL,
|
|
70
|
-
channel_id TEXT NOT NULL,
|
|
71
|
-
channel_name TEXT,
|
|
72
|
-
user_id TEXT,
|
|
73
|
-
context TEXT,
|
|
74
|
-
created_at INTEGER,
|
|
75
|
-
last_active INTEGER,
|
|
76
|
-
UNIQUE(source, channel_id)
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
CREATE INDEX IF NOT EXISTS idx_messenger_source_channel
|
|
80
|
-
ON messenger_sessions(source, channel_id);
|
|
81
|
-
`);
|
|
82
|
-
// Add missing columns for older databases
|
|
83
|
-
try {
|
|
84
|
-
const tableInfo = this.db.prepare('PRAGMA table_info(messenger_sessions)').all();
|
|
85
|
-
const columns = tableInfo.map((col) => col.name);
|
|
86
|
-
if (!columns.includes('created_at')) {
|
|
87
|
-
this.db.exec('ALTER TABLE messenger_sessions ADD COLUMN created_at INTEGER');
|
|
88
|
-
}
|
|
89
|
-
if (!columns.includes('last_active')) {
|
|
90
|
-
this.db.exec('ALTER TABLE messenger_sessions ADD COLUMN last_active INTEGER');
|
|
91
|
-
}
|
|
92
|
-
if (!columns.includes('channel_name')) {
|
|
93
|
-
this.db.exec('ALTER TABLE messenger_sessions ADD COLUMN channel_name TEXT');
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
catch {
|
|
97
|
-
// Ignore errors - columns might already exist
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Get existing session or create new one
|
|
102
|
-
*/
|
|
103
|
-
getOrCreate(source, channelId, userId, channelName) {
|
|
104
|
-
const existing = this.db
|
|
105
|
-
.prepare(`
|
|
106
|
-
SELECT * FROM messenger_sessions
|
|
107
|
-
WHERE source = ? AND channel_id = ?
|
|
108
|
-
`)
|
|
109
|
-
.get(source, channelId);
|
|
110
|
-
if (existing) {
|
|
111
|
-
// Update channel name if provided and different
|
|
112
|
-
if (channelName && existing.channel_name !== channelName) {
|
|
113
|
-
this.db
|
|
114
|
-
.prepare('UPDATE messenger_sessions SET channel_name = ? WHERE id = ?')
|
|
115
|
-
.run(channelName, existing.id);
|
|
116
|
-
existing.channel_name = channelName;
|
|
117
|
-
}
|
|
118
|
-
return this.rowToSession(existing);
|
|
119
|
-
}
|
|
120
|
-
// Create new session
|
|
121
|
-
const id = (0, crypto_1.randomUUID)();
|
|
122
|
-
const now = Date.now();
|
|
123
|
-
this.db
|
|
124
|
-
.prepare(`
|
|
125
|
-
INSERT INTO messenger_sessions (id, source, channel_id, channel_name, user_id, context, created_at, last_active)
|
|
126
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
127
|
-
`)
|
|
128
|
-
.run(id, source, channelId, channelName || null, userId || null, '[]', now, now);
|
|
129
|
-
return {
|
|
130
|
-
id,
|
|
131
|
-
source,
|
|
132
|
-
channelId,
|
|
133
|
-
channelName,
|
|
134
|
-
userId,
|
|
135
|
-
context: '[]',
|
|
136
|
-
createdAt: now,
|
|
137
|
-
lastActive: now,
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Get session by ID
|
|
142
|
-
*/
|
|
143
|
-
getById(sessionId) {
|
|
144
|
-
const row = this.db.prepare('SELECT * FROM messenger_sessions WHERE id = ?').get(sessionId);
|
|
145
|
-
return row ? this.rowToSession(row) : null;
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Update session with new conversation turn
|
|
149
|
-
*/
|
|
150
|
-
updateSession(sessionId, userMessage, botResponse) {
|
|
151
|
-
const session = this.getById(sessionId);
|
|
152
|
-
if (!session)
|
|
153
|
-
return false;
|
|
154
|
-
// Parse existing context
|
|
155
|
-
let history;
|
|
156
|
-
try {
|
|
157
|
-
history = JSON.parse(session.context || '[]');
|
|
158
|
-
}
|
|
159
|
-
catch {
|
|
160
|
-
history = [];
|
|
161
|
-
}
|
|
162
|
-
// Add new turn (store full response, truncation only at prompt injection)
|
|
163
|
-
history.push({
|
|
164
|
-
user: userMessage,
|
|
165
|
-
bot: botResponse,
|
|
166
|
-
timestamp: Date.now(),
|
|
167
|
-
});
|
|
168
|
-
// Keep only recent turns
|
|
169
|
-
const recentHistory = history.slice(-this.maxTurns);
|
|
170
|
-
// Update database
|
|
171
|
-
const result = this.db
|
|
172
|
-
.prepare(`
|
|
173
|
-
UPDATE messenger_sessions
|
|
174
|
-
SET context = ?, last_active = ?
|
|
175
|
-
WHERE id = ?
|
|
176
|
-
`)
|
|
177
|
-
.run(JSON.stringify(recentHistory), Date.now(), sessionId);
|
|
178
|
-
return result.changes > 0;
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Append a single message (user or assistant) to session history.
|
|
182
|
-
* - role='user': creates a new turn with empty bot
|
|
183
|
-
* - role='assistant': fills bot field of last incomplete turn, or creates new turn
|
|
184
|
-
*/
|
|
185
|
-
appendMessage(sessionId, msg, opts = {}) {
|
|
186
|
-
const session = this.getById(sessionId);
|
|
187
|
-
if (!session) {
|
|
188
|
-
return false;
|
|
189
|
-
}
|
|
190
|
-
let history;
|
|
191
|
-
try {
|
|
192
|
-
history = JSON.parse(session.context || '[]');
|
|
193
|
-
}
|
|
194
|
-
catch {
|
|
195
|
-
history = [];
|
|
196
|
-
}
|
|
197
|
-
if (msg.role === 'user') {
|
|
198
|
-
if (opts.sourceMessageRef) {
|
|
199
|
-
const matches = history.filter((turn) => turn.sourceMessageRef === opts.sourceMessageRef);
|
|
200
|
-
if (matches.length > 1) {
|
|
201
|
-
throw new Error('Session contains duplicate source message references');
|
|
202
|
-
}
|
|
203
|
-
const existing = matches[0];
|
|
204
|
-
if (existing) {
|
|
205
|
-
if (existing.user !== msg.content ||
|
|
206
|
-
existing.sourceObservationRef !== opts.sourceObservationRef) {
|
|
207
|
-
throw new Error('Source message replay conflicts with the persisted turn');
|
|
208
|
-
}
|
|
209
|
-
return true;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
history.push({
|
|
213
|
-
user: msg.content,
|
|
214
|
-
bot: '',
|
|
215
|
-
timestamp: msg.timestamp,
|
|
216
|
-
// TG-05: a source-ref-bound turn stays provisional until the atomic
|
|
217
|
-
// turn/receipt commit; fresh-session formatting excludes it.
|
|
218
|
-
...(opts.sourceMessageRef
|
|
219
|
-
? { sourceMessageRef: opts.sourceMessageRef, state: 'provisional' }
|
|
220
|
-
: {}),
|
|
221
|
-
...(opts.sourceObservationRef ? { sourceObservationRef: opts.sourceObservationRef } : {}),
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
const lastTurn = history[history.length - 1];
|
|
226
|
-
if (lastTurn && lastTurn.bot === '') {
|
|
227
|
-
lastTurn.bot = msg.content;
|
|
228
|
-
lastTurn.timestamp = msg.timestamp;
|
|
229
|
-
if (opts.resultObservationRef) {
|
|
230
|
-
lastTurn.resultObservationRef = opts.resultObservationRef;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
logger.warn(`Creating orphan assistant message for session ${sessionId}`);
|
|
235
|
-
history.push({
|
|
236
|
-
user: '',
|
|
237
|
-
bot: msg.content,
|
|
238
|
-
timestamp: msg.timestamp,
|
|
239
|
-
...(opts.resultObservationRef ? { resultObservationRef: opts.resultObservationRef } : {}),
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
const recentHistory = history.slice(-this.maxTurns);
|
|
244
|
-
const result = this.db
|
|
245
|
-
.prepare('UPDATE messenger_sessions SET context = ?, last_active = ? WHERE id = ?')
|
|
246
|
-
.run(JSON.stringify(recentHistory), Date.now(), sessionId);
|
|
247
|
-
return result.changes > 0;
|
|
248
|
-
}
|
|
249
|
-
findTurnBySourceMessageRef(sessionId, sourceMessageRef) {
|
|
250
|
-
const session = this.getById(sessionId);
|
|
251
|
-
if (!session) {
|
|
252
|
-
return null;
|
|
253
|
-
}
|
|
254
|
-
let history;
|
|
255
|
-
try {
|
|
256
|
-
history = JSON.parse(session.context);
|
|
257
|
-
}
|
|
258
|
-
catch (error) {
|
|
259
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
260
|
-
throw new Error(`Session context is malformed JSON: ${message}`);
|
|
261
|
-
}
|
|
262
|
-
const matches = history.filter((turn) => turn.sourceMessageRef === sourceMessageRef);
|
|
263
|
-
if (matches.length > 1) {
|
|
264
|
-
throw new Error('Session contains duplicate source message references');
|
|
265
|
-
}
|
|
266
|
-
return matches[0] ?? null;
|
|
267
|
-
}
|
|
268
|
-
finalizeTurn(sessionId, sourceMessageRef, response, resultObservationRef) {
|
|
269
|
-
const session = this.getById(sessionId);
|
|
270
|
-
if (!session) {
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
let history;
|
|
274
|
-
try {
|
|
275
|
-
history = JSON.parse(session.context);
|
|
276
|
-
}
|
|
277
|
-
catch (error) {
|
|
278
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
279
|
-
throw new Error(`Session context is malformed JSON: ${message}`);
|
|
280
|
-
}
|
|
281
|
-
const matches = history.filter((turn) => turn.sourceMessageRef === sourceMessageRef);
|
|
282
|
-
if (matches.length !== 1) {
|
|
283
|
-
throw new Error('Session turn cannot be finalized without one exact source reference');
|
|
284
|
-
}
|
|
285
|
-
const turn = matches[0];
|
|
286
|
-
if (turn.state === 'shared') {
|
|
287
|
-
throw new Error('Shared source message cannot acquire a second final response');
|
|
288
|
-
}
|
|
289
|
-
const responseHash = (0, crypto_1.createHash)('sha256').update(response, 'utf8').digest('hex');
|
|
290
|
-
if (turn.state === 'final') {
|
|
291
|
-
if (turn.bot !== response ||
|
|
292
|
-
turn.finalResponseSha256 !== responseHash ||
|
|
293
|
-
turn.resultObservationRef !== resultObservationRef) {
|
|
294
|
-
throw new Error('Final source message replay conflicts with the persisted turn');
|
|
295
|
-
}
|
|
296
|
-
return true;
|
|
297
|
-
}
|
|
298
|
-
turn.bot = response;
|
|
299
|
-
turn.timestamp = Date.now();
|
|
300
|
-
turn.state = 'final';
|
|
301
|
-
turn.finalResponseSha256 = responseHash;
|
|
302
|
-
if (resultObservationRef) {
|
|
303
|
-
turn.resultObservationRef = resultObservationRef;
|
|
304
|
-
}
|
|
305
|
-
const result = this.db
|
|
306
|
-
.prepare('UPDATE messenger_sessions SET context = ?, last_active = ? WHERE id = ?')
|
|
307
|
-
.run(JSON.stringify(history), Date.now(), sessionId);
|
|
308
|
-
return result.changes > 0;
|
|
309
|
-
}
|
|
310
|
-
/** Preserve a later user input while linking it to the one reply owner. */
|
|
311
|
-
finalizeSharedTurn(sessionId, sourceMessageRef, replySourceMessageRef) {
|
|
312
|
-
const session = this.getById(sessionId);
|
|
313
|
-
if (!session)
|
|
314
|
-
return false;
|
|
315
|
-
if (!replySourceMessageRef || replySourceMessageRef === sourceMessageRef) {
|
|
316
|
-
throw new Error('Shared source message needs another reply owner');
|
|
317
|
-
}
|
|
318
|
-
let history;
|
|
319
|
-
try {
|
|
320
|
-
history = JSON.parse(session.context);
|
|
321
|
-
}
|
|
322
|
-
catch (error) {
|
|
323
|
-
throw new Error('Session context is malformed JSON', { cause: error });
|
|
324
|
-
}
|
|
325
|
-
const matches = history.filter((turn) => turn.sourceMessageRef === sourceMessageRef);
|
|
326
|
-
if (matches.length !== 1)
|
|
327
|
-
throw new Error('Shared source message requires one exact input');
|
|
328
|
-
const turn = matches[0];
|
|
329
|
-
if (turn.state === 'shared') {
|
|
330
|
-
if (turn.sharedReplyRef !== replySourceMessageRef) {
|
|
331
|
-
throw new Error('Shared source message replay conflicts with its reply owner');
|
|
332
|
-
}
|
|
333
|
-
return true;
|
|
334
|
-
}
|
|
335
|
-
const targets = history.filter((candidate) => candidate.sourceMessageRef === replySourceMessageRef);
|
|
336
|
-
if (targets.length !== 1) {
|
|
337
|
-
throw new Error('Shared source message requires one exact reply owner in this session');
|
|
338
|
-
}
|
|
339
|
-
if (turn.state === 'final' || turn.bot !== '' || turn.resultObservationRef) {
|
|
340
|
-
throw new Error('Shared source message conflicts with a prepared response');
|
|
341
|
-
}
|
|
342
|
-
turn.state = 'shared';
|
|
343
|
-
turn.sharedReplyRef = replySourceMessageRef;
|
|
344
|
-
turn.timestamp = Date.now();
|
|
345
|
-
const result = this.db
|
|
346
|
-
.prepare('UPDATE messenger_sessions SET context = ?, last_active = ? WHERE id = ?')
|
|
347
|
-
.run(JSON.stringify(history), Date.now(), sessionId);
|
|
348
|
-
return result.changes > 0;
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Flush streaming response to the last incomplete turn.
|
|
352
|
-
* Called periodically during streaming to persist partial assistant responses.
|
|
353
|
-
*/
|
|
354
|
-
flushStreamingResponse(sessionId, accumulatedText, resultObservationRef, sourceMessageRef) {
|
|
355
|
-
const session = this.getById(sessionId);
|
|
356
|
-
if (!session) {
|
|
357
|
-
return false;
|
|
358
|
-
}
|
|
359
|
-
let history;
|
|
360
|
-
try {
|
|
361
|
-
history = JSON.parse(session.context || '[]');
|
|
362
|
-
}
|
|
363
|
-
catch {
|
|
364
|
-
history = [];
|
|
365
|
-
}
|
|
366
|
-
const matches = sourceMessageRef
|
|
367
|
-
? history.filter((turn) => turn.sourceMessageRef === sourceMessageRef)
|
|
368
|
-
: [];
|
|
369
|
-
if (sourceMessageRef && matches.length !== 1) {
|
|
370
|
-
throw new Error('Stream response requires one exact source message reference');
|
|
371
|
-
}
|
|
372
|
-
const targetTurn = sourceMessageRef ? matches[0] : history[history.length - 1];
|
|
373
|
-
if (!targetTurn) {
|
|
374
|
-
return false;
|
|
375
|
-
}
|
|
376
|
-
if (targetTurn.state === 'final' || targetTurn.state === 'shared') {
|
|
377
|
-
throw new Error('Final source message cannot be changed by a stream response');
|
|
378
|
-
}
|
|
379
|
-
targetTurn.bot = accumulatedText;
|
|
380
|
-
targetTurn.timestamp = Date.now();
|
|
381
|
-
if (resultObservationRef) {
|
|
382
|
-
targetTurn.resultObservationRef = resultObservationRef;
|
|
383
|
-
}
|
|
384
|
-
const result = this.db
|
|
385
|
-
.prepare('UPDATE messenger_sessions SET context = ?, last_active = ? WHERE id = ?')
|
|
386
|
-
.run(JSON.stringify(history), Date.now(), sessionId);
|
|
387
|
-
return result.changes > 0;
|
|
388
|
-
}
|
|
389
|
-
/** Remove only the failed turn; legacy callers without a source ref use the last turn. */
|
|
390
|
-
discardIncompleteTurn(sessionId, sourceMessageRef) {
|
|
391
|
-
const session = this.getById(sessionId);
|
|
392
|
-
if (!session) {
|
|
393
|
-
return false;
|
|
394
|
-
}
|
|
395
|
-
let history;
|
|
396
|
-
try {
|
|
397
|
-
history = JSON.parse(session.context || '[]');
|
|
398
|
-
}
|
|
399
|
-
catch {
|
|
400
|
-
history = [];
|
|
401
|
-
}
|
|
402
|
-
if (history.length === 0) {
|
|
403
|
-
return false;
|
|
404
|
-
}
|
|
405
|
-
const matchingIndices = sourceMessageRef
|
|
406
|
-
? history.flatMap((turn, index) => turn.sourceMessageRef === sourceMessageRef ? [index] : [])
|
|
407
|
-
: [history.length - 1];
|
|
408
|
-
if (sourceMessageRef && matchingIndices.length !== 1) {
|
|
409
|
-
throw new Error('Discard requires one exact source message reference');
|
|
410
|
-
}
|
|
411
|
-
const index = matchingIndices[0];
|
|
412
|
-
if (history[index]?.state === 'final' || history[index]?.state === 'shared') {
|
|
413
|
-
throw new Error('Final source message cannot be discarded');
|
|
414
|
-
}
|
|
415
|
-
history.splice(index, 1);
|
|
416
|
-
const result = this.db
|
|
417
|
-
.prepare('UPDATE messenger_sessions SET context = ?, last_active = ? WHERE id = ?')
|
|
418
|
-
.run(JSON.stringify(history), Date.now(), sessionId);
|
|
419
|
-
return result.changes > 0;
|
|
420
|
-
}
|
|
421
|
-
/**
|
|
422
|
-
* Get conversation history for a session by ID
|
|
423
|
-
*/
|
|
424
|
-
getHistory(sessionId) {
|
|
425
|
-
const session = this.getById(sessionId);
|
|
426
|
-
if (!session)
|
|
427
|
-
return [];
|
|
428
|
-
try {
|
|
429
|
-
return JSON.parse(session.context || '[]');
|
|
430
|
-
}
|
|
431
|
-
catch {
|
|
432
|
-
return [];
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* Get conversation history by source and channel
|
|
437
|
-
* Used by messenger and runtime session consumers
|
|
438
|
-
*/
|
|
439
|
-
getHistoryByChannel(source, channelId) {
|
|
440
|
-
const session = this.db
|
|
441
|
-
.prepare('SELECT context FROM messenger_sessions WHERE source = ? AND channel_id = ?')
|
|
442
|
-
.get(source, channelId);
|
|
443
|
-
if (!session)
|
|
444
|
-
return [];
|
|
445
|
-
try {
|
|
446
|
-
return JSON.parse(session.context || '[]');
|
|
447
|
-
}
|
|
448
|
-
catch {
|
|
449
|
-
return [];
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Clear session context (start fresh)
|
|
454
|
-
*/
|
|
455
|
-
clearContext(sessionId) {
|
|
456
|
-
const result = this.db
|
|
457
|
-
.prepare(`
|
|
458
|
-
UPDATE messenger_sessions
|
|
459
|
-
SET context = ?, last_active = ?
|
|
460
|
-
WHERE id = ?
|
|
461
|
-
`)
|
|
462
|
-
.run('[]', Date.now(), sessionId);
|
|
463
|
-
return result.changes > 0;
|
|
464
|
-
}
|
|
465
|
-
/**
|
|
466
|
-
* Delete a session
|
|
467
|
-
*/
|
|
468
|
-
deleteSession(sessionId) {
|
|
469
|
-
const result = this.db.prepare('DELETE FROM messenger_sessions WHERE id = ?').run(sessionId);
|
|
470
|
-
return result.changes > 0;
|
|
471
|
-
}
|
|
472
|
-
/**
|
|
473
|
-
* List all sessions for a source
|
|
474
|
-
*/
|
|
475
|
-
/**
|
|
476
|
-
* What this store holds, as the dashboard asks it: how many sessions per
|
|
477
|
-
* source, and the ten most recently active channels.
|
|
478
|
-
*
|
|
479
|
-
* The viewer used to open a second connection to this database by path and
|
|
480
|
-
* run these two queries itself. The store that owns the table answers them.
|
|
481
|
-
*/
|
|
482
|
-
stats() {
|
|
483
|
-
const bySourceRows = this.db
|
|
484
|
-
.prepare('SELECT source, COUNT(*) as count FROM messenger_sessions GROUP BY source')
|
|
485
|
-
.all();
|
|
486
|
-
const bySource = {};
|
|
487
|
-
let total = 0;
|
|
488
|
-
for (const row of bySourceRows) {
|
|
489
|
-
bySource[row.source] = row.count;
|
|
490
|
-
total += row.count;
|
|
491
|
-
}
|
|
492
|
-
const channelRows = this.db
|
|
493
|
-
.prepare(`SELECT source, channel_id, channel_name, last_active,
|
|
494
|
-
json_array_length(context) as message_count
|
|
495
|
-
FROM messenger_sessions
|
|
496
|
-
ORDER BY last_active DESC
|
|
497
|
-
LIMIT 10`)
|
|
498
|
-
.all();
|
|
499
|
-
return {
|
|
500
|
-
total,
|
|
501
|
-
bySource,
|
|
502
|
-
channels: channelRows.map((row) => ({
|
|
503
|
-
source: row.source,
|
|
504
|
-
channelId: row.channel_id,
|
|
505
|
-
channelName: row.channel_name || null,
|
|
506
|
-
lastActive: row.last_active,
|
|
507
|
-
messageCount: row.message_count || 0,
|
|
508
|
-
})),
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
listSessions(source) {
|
|
512
|
-
let stmt;
|
|
513
|
-
if (source) {
|
|
514
|
-
stmt = this.db.prepare('SELECT * FROM messenger_sessions WHERE source = ? ORDER BY last_active DESC');
|
|
515
|
-
return stmt.all(source).map((row) => this.rowToSession(row));
|
|
516
|
-
}
|
|
517
|
-
else {
|
|
518
|
-
stmt = this.db.prepare('SELECT * FROM messenger_sessions ORDER BY last_active DESC');
|
|
519
|
-
return stmt.all().map((row) => this.rowToSession(row));
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* Update channel name for a session by source and channel ID
|
|
524
|
-
* Used to backfill channel names when gateway connects
|
|
525
|
-
*/
|
|
526
|
-
updateChannelName(source, channelId, channelName) {
|
|
527
|
-
const result = this.db
|
|
528
|
-
.prepare(`UPDATE messenger_sessions SET channel_name = ? WHERE source = ? AND channel_id = ? AND (channel_name IS NULL OR channel_name = '')`)
|
|
529
|
-
.run(channelName, source, channelId);
|
|
530
|
-
return result.changes > 0;
|
|
531
|
-
}
|
|
532
|
-
/**
|
|
533
|
-
* Delete inactive sessions older than specified age
|
|
534
|
-
*/
|
|
535
|
-
cleanupInactiveSessions(maxAgeMs) {
|
|
536
|
-
const cutoff = Date.now() - maxAgeMs;
|
|
537
|
-
const result = this.db
|
|
538
|
-
.prepare('DELETE FROM messenger_sessions WHERE last_active < ?')
|
|
539
|
-
.run(cutoff);
|
|
540
|
-
return result.changes;
|
|
541
|
-
}
|
|
542
|
-
/**
|
|
543
|
-
* Get the most recently active session for a specific source
|
|
544
|
-
*/
|
|
545
|
-
getLastActiveSession(source) {
|
|
546
|
-
let stmt;
|
|
547
|
-
let row;
|
|
548
|
-
if (source) {
|
|
549
|
-
stmt = this.db.prepare('SELECT * FROM messenger_sessions WHERE source = ? ORDER BY last_active DESC LIMIT 1');
|
|
550
|
-
row = stmt.get(source);
|
|
551
|
-
}
|
|
552
|
-
else {
|
|
553
|
-
stmt = this.db.prepare('SELECT * FROM messenger_sessions ORDER BY last_active DESC LIMIT 1');
|
|
554
|
-
row = stmt.get();
|
|
555
|
-
}
|
|
556
|
-
return row ? this.rowToSession(row) : null;
|
|
557
|
-
}
|
|
558
|
-
/**
|
|
559
|
-
* Convert database row to Session object
|
|
560
|
-
*/
|
|
561
|
-
rowToSession(row) {
|
|
562
|
-
return {
|
|
563
|
-
id: row.id,
|
|
564
|
-
source: row.source,
|
|
565
|
-
channelId: row.channel_id,
|
|
566
|
-
channelName: row.channel_name || undefined,
|
|
567
|
-
userId: row.user_id || undefined,
|
|
568
|
-
context: row.context || '[]',
|
|
569
|
-
createdAt: row.created_at,
|
|
570
|
-
lastActive: row.last_active,
|
|
571
|
-
};
|
|
572
|
-
}
|
|
573
|
-
/**
|
|
574
|
-
* Close database connection
|
|
575
|
-
*/
|
|
576
|
-
close() {
|
|
577
|
-
this.db.close();
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
exports.SessionStore = SessionStore;
|
|
581
|
-
//# sourceMappingURL=session-store.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-store.js","sourceRoot":"","sources":["../../src/gateways/session-store.ts"],"names":[],"mappings":"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"}
|