@memberjunction/livekit-room-server 6.2.0-edge.2 → 6.2.0-edge.4

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.
Files changed (82) hide show
  1. package/README.md +85 -0
  2. package/dist/index.d.ts +18 -2
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +18 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/livekit-agent-room-coordinator.d.ts +220 -13
  7. package/dist/livekit-agent-room-coordinator.d.ts.map +1 -1
  8. package/dist/livekit-agent-room-coordinator.js +409 -65
  9. package/dist/livekit-agent-room-coordinator.js.map +1 -1
  10. package/dist/livekit-egress-service.d.ts +7 -0
  11. package/dist/livekit-egress-service.d.ts.map +1 -1
  12. package/dist/livekit-egress-service.js +11 -0
  13. package/dist/livekit-egress-service.js.map +1 -1
  14. package/dist/livekit-native-module.d.ts +18 -0
  15. package/dist/livekit-native-module.d.ts.map +1 -0
  16. package/dist/livekit-native-module.js +27 -0
  17. package/dist/livekit-native-module.js.map +1 -0
  18. package/dist/livekit-participant-service.d.ts +47 -0
  19. package/dist/livekit-participant-service.d.ts.map +1 -0
  20. package/dist/livekit-participant-service.js +64 -0
  21. package/dist/livekit-participant-service.js.map +1 -0
  22. package/dist/livekit-sip-service.d.ts +141 -0
  23. package/dist/livekit-sip-service.d.ts.map +1 -0
  24. package/dist/livekit-sip-service.js +169 -0
  25. package/dist/livekit-sip-service.js.map +1 -0
  26. package/dist/livekit-token-service.d.ts +26 -5
  27. package/dist/livekit-token-service.d.ts.map +1 -1
  28. package/dist/livekit-token-service.js +22 -7
  29. package/dist/livekit-token-service.js.map +1 -1
  30. package/dist/livekit-webhook.d.ts +65 -0
  31. package/dist/livekit-webhook.d.ts.map +1 -0
  32. package/dist/livekit-webhook.js +65 -0
  33. package/dist/livekit-webhook.js.map +1 -0
  34. package/dist/meeting-dial-in-service.d.ts +83 -0
  35. package/dist/meeting-dial-in-service.d.ts.map +1 -0
  36. package/dist/meeting-dial-in-service.js +202 -0
  37. package/dist/meeting-dial-in-service.js.map +1 -0
  38. package/dist/room-audio/audio-decoder.d.ts +40 -0
  39. package/dist/room-audio/audio-decoder.d.ts.map +1 -0
  40. package/dist/room-audio/audio-decoder.js +205 -0
  41. package/dist/room-audio/audio-decoder.js.map +1 -0
  42. package/dist/room-audio/comfort-tone.d.ts +23 -0
  43. package/dist/room-audio/comfort-tone.d.ts.map +1 -0
  44. package/dist/room-audio/comfort-tone.js +70 -0
  45. package/dist/room-audio/comfort-tone.js.map +1 -0
  46. package/dist/room-audio/pcm-frame-pump.d.ts +134 -0
  47. package/dist/room-audio/pcm-frame-pump.d.ts.map +1 -0
  48. package/dist/room-audio/pcm-frame-pump.js +253 -0
  49. package/dist/room-audio/pcm-frame-pump.js.map +1 -0
  50. package/dist/room-audio/room-audio-decode-cache.d.ts +37 -0
  51. package/dist/room-audio/room-audio-decode-cache.d.ts.map +1 -0
  52. package/dist/room-audio/room-audio-decode-cache.js +75 -0
  53. package/dist/room-audio/room-audio-decode-cache.js.map +1 -0
  54. package/dist/room-audio/room-audio-player.d.ts +178 -0
  55. package/dist/room-audio/room-audio-player.d.ts.map +1 -0
  56. package/dist/room-audio/room-audio-player.js +404 -0
  57. package/dist/room-audio/room-audio-player.js.map +1 -0
  58. package/dist/room-audio/room-audio-sources.d.ts +47 -0
  59. package/dist/room-audio/room-audio-sources.d.ts.map +1 -0
  60. package/dist/room-audio/room-audio-sources.js +116 -0
  61. package/dist/room-audio/room-audio-sources.js.map +1 -0
  62. package/dist/room-audio/room-speech-synthesizer.d.ts +55 -0
  63. package/dist/room-audio/room-speech-synthesizer.d.ts.map +1 -0
  64. package/dist/room-audio/room-speech-synthesizer.js +56 -0
  65. package/dist/room-audio/room-speech-synthesizer.js.map +1 -0
  66. package/dist/room-authorization.d.ts +58 -0
  67. package/dist/room-authorization.d.ts.map +1 -0
  68. package/dist/room-authorization.js +212 -0
  69. package/dist/room-authorization.js.map +1 -0
  70. package/dist/room-handoff/handoff-offer-registry.d.ts +147 -0
  71. package/dist/room-handoff/handoff-offer-registry.d.ts.map +1 -0
  72. package/dist/room-handoff/handoff-offer-registry.js +548 -0
  73. package/dist/room-handoff/handoff-offer-registry.js.map +1 -0
  74. package/dist/room-handoff/handoff-types.d.ts +172 -0
  75. package/dist/room-handoff/handoff-types.d.ts.map +1 -0
  76. package/dist/room-handoff/handoff-types.js +16 -0
  77. package/dist/room-handoff/handoff-types.js.map +1 -0
  78. package/dist/room-handoff/room-handoff-engine.d.ts +149 -0
  79. package/dist/room-handoff/room-handoff-engine.d.ts.map +1 -0
  80. package/dist/room-handoff/room-handoff-engine.js +563 -0
  81. package/dist/room-handoff/room-handoff-engine.js.map +1 -0
  82. package/package.json +15 -9
@@ -0,0 +1,548 @@
1
+ /**
2
+ * @fileoverview Durable registry of handoff offers backed by `MJ: Interaction Offers`.
3
+ *
4
+ * An offer is a short-lived question put to one person: "a caller is waiting, will you take the conversation?".
5
+ * It lives in `MJ: Interaction Offers` from the moment the AI asks until it is accepted, declined, expired or cancelled,
6
+ * and is kept so a console that was open when it resolved can still show what happened.
7
+ *
8
+ * **Durable and cluster-safe.** Offers are stored in the database (`MJ: Interaction Offers`). Accept and decline
9
+ * execute a compare-and-set on `Status = 'Pending'` inside `RunInEntityTransaction` so multiple server instances
10
+ * cannot both accept or race. Expired offers are updated on read and through a periodic sweep. Live changes are
11
+ * published locally and across instances via cluster pub/sub.
12
+ *
13
+ * An accept or decline is authorised by comparing the offer's target user with the caller, and a mismatch answers
14
+ * exactly as a missing offer does: someone who does not own an offer cannot learn that it exists.
15
+ *
16
+ * @module @memberjunction/livekit-room-server
17
+ */
18
+ import { randomUUID } from 'node:crypto';
19
+ import { LogError, LogStatusEx, Metadata, RunInEntityTransaction, RunView } from '@memberjunction/core';
20
+ import { BaseSingleton, EscapeSQLString, UUIDsEqual } from '@memberjunction/global';
21
+ /** How long a person has to accept an offer before it expires. */
22
+ export const HANDOFF_OFFER_TIMEOUT_MS = 45_000;
23
+ /** How long a resolved offer stays listed (so a console that was open still sees what happened). */
24
+ export const HANDOFF_OFFER_RETENTION_MS = 5 * 60_000;
25
+ /** The most pending offers one person can have at once; a flood of offers is refused rather than queued. */
26
+ export const MAX_PENDING_OFFERS_PER_USER = 10;
27
+ /** The one answer for "no such offer", "not yours" and "too late", so an offer's existence is not leaked. */
28
+ export const OFFER_UNAVAILABLE = 'This conversation offer is no longer available.';
29
+ /** Converts a stored offer to what a console may see. */
30
+ export function ToOfferView(offer) {
31
+ return {
32
+ OfferID: offer.OfferID,
33
+ RoomName: offer.RoomName,
34
+ Mode: offer.Mode,
35
+ Summary: offer.Summary,
36
+ CallerLabel: offer.CallerLabel,
37
+ AgentName: offer.AgentName,
38
+ Status: offer.Status,
39
+ CreatedAt: new Date(offer.CreatedAtMs).toISOString(),
40
+ ExpiresAt: new Date(offer.ExpiresAtMs).toISOString(),
41
+ InteractionID: offer.InteractionID ?? null,
42
+ };
43
+ }
44
+ function asTransactionCapable(provider) {
45
+ if (!provider)
46
+ return undefined;
47
+ const candidate = provider;
48
+ return candidate.SupportsEntityTransactions === true && typeof candidate.BeginEntityTransaction === 'function'
49
+ ? candidate
50
+ : undefined;
51
+ }
52
+ /** Holds handoff offers in `MJ: Interaction Offers` with in-memory caching and compare-and-set concurrency guards. */
53
+ export class HandoffOfferRegistry extends BaseSingleton {
54
+ constructor() {
55
+ super();
56
+ this.deps = {};
57
+ this.offers = new Map();
58
+ this.now = Date.now;
59
+ this.warnedNoUser = false;
60
+ this.sweepTimer = setInterval(() => {
61
+ void this.Sweep().catch((e) => {
62
+ LogError(`[HandoffOfferRegistry] periodic sweep failed: ${e instanceof Error ? e.message : String(e)}`);
63
+ });
64
+ }, 15_000);
65
+ this.sweepTimer.unref?.();
66
+ }
67
+ /** The process-wide registry. */
68
+ static get Instance() {
69
+ return super.getInstance();
70
+ }
71
+ /** Configures collaborator dependencies. */
72
+ Configure(deps) {
73
+ this.deps = { ...this.deps, ...deps };
74
+ }
75
+ /** Stops the periodic background sweep timer (shutdown, tests). */
76
+ StopPeriodicSweep() {
77
+ if (this.sweepTimer) {
78
+ clearInterval(this.sweepTimer);
79
+ this.sweepTimer = undefined;
80
+ }
81
+ }
82
+ /** Replaces the clock (tests). */
83
+ SetClock(now) {
84
+ this.now = now;
85
+ }
86
+ /** Forgets every cached offer (tests, shutdown). */
87
+ Clear() {
88
+ this.offers.clear();
89
+ }
90
+ /**
91
+ * Creates a pending offer. Refuses when the person already has {@link MAX_PENDING_OFFERS_PER_USER} pending.
92
+ *
93
+ * @returns The new offer, or `undefined` when the person's pending-offer cap is reached.
94
+ */
95
+ async Create(input, timeoutMs = HANDOFF_OFFER_TIMEOUT_MS) {
96
+ await this.sweep(input.ContextUser, input.Provider);
97
+ const pending = await this.PendingForUser(input.TargetUserID, input.ContextUser, input.Provider);
98
+ if (pending.length >= MAX_PENDING_OFFERS_PER_USER) {
99
+ return undefined;
100
+ }
101
+ const createdAt = this.now();
102
+ const expiresAt = createdAt + timeoutMs;
103
+ const p = this.getProvider(input.Provider);
104
+ if (p && typeof p.GetEntityObject === 'function') {
105
+ const user = this.resolveUser(input.ContextUser);
106
+ try {
107
+ let interactionID = input.InteractionID;
108
+ if (!interactionID) {
109
+ const rv = this.getRunView(p);
110
+ const existing = await rv.RunView({
111
+ EntityName: 'MJ: Interactions',
112
+ ExtraFilter: `RoomName = '${EscapeSQLString(input.RoomName.trim())}' AND Status = 'Active'`,
113
+ ResultType: 'entity_object',
114
+ }, user);
115
+ if (existing.Success && existing.Results && existing.Results.length > 0) {
116
+ interactionID = existing.Results[0].ID;
117
+ }
118
+ else {
119
+ const interaction = await p.GetEntityObject('MJ: Interactions', user);
120
+ interaction.Channel = 'Web';
121
+ interaction.Direction = 'Inbound';
122
+ interaction.RoomName = input.RoomName;
123
+ interaction.Status = 'Active';
124
+ interaction.StartedAt = new Date(createdAt);
125
+ const savedInteraction = await interaction.Save();
126
+ if (savedInteraction) {
127
+ interactionID = interaction.ID;
128
+ }
129
+ }
130
+ }
131
+ if (interactionID) {
132
+ const entity = await p.GetEntityObject('MJ: Interaction Offers', user);
133
+ entity.InteractionID = interactionID;
134
+ entity.TargetUserID = input.TargetUserID;
135
+ entity.OfferedByAgentID = input.OfferedByAgentID ?? null;
136
+ entity.Mode = input.Mode.toLowerCase() === 'warm' ? 'Warm' : 'Blind';
137
+ entity.Status = 'Pending';
138
+ entity.RoomName = input.RoomName;
139
+ entity.CallerLabel = input.CallerLabel;
140
+ entity.Summary = input.Summary;
141
+ entity.OfferedAt = new Date(createdAt);
142
+ entity.ExpiresAt = new Date(expiresAt);
143
+ const saved = await entity.Save();
144
+ if (saved) {
145
+ const record = this.entityToRecord(entity, input.AgentName);
146
+ this.offers.set(record.OfferID, record);
147
+ return record;
148
+ }
149
+ LogError(`[HandoffOfferRegistry] Failed to save offer entity: ${entity.LatestResult?.CompleteMessage ?? 'unknown'}`);
150
+ }
151
+ }
152
+ catch (err) {
153
+ LogError(`[HandoffOfferRegistry] Failed to create database offer: ${err instanceof Error ? err.message : String(err)}`);
154
+ }
155
+ }
156
+ // In-memory fallback
157
+ const offer = {
158
+ OfferID: randomUUID(),
159
+ RoomName: input.RoomName,
160
+ TargetUserID: input.TargetUserID,
161
+ Mode: input.Mode,
162
+ Summary: input.Summary,
163
+ CallerLabel: input.CallerLabel,
164
+ AgentName: input.AgentName,
165
+ Status: 'Pending',
166
+ CreatedAtMs: createdAt,
167
+ ExpiresAtMs: expiresAt,
168
+ InteractionID: input.InteractionID,
169
+ OfferedByAgentID: input.OfferedByAgentID ?? null,
170
+ };
171
+ this.offers.set(offer.OfferID, offer);
172
+ return offer;
173
+ }
174
+ /** The offer with this id, or `undefined`. */
175
+ async Get(offerID, contextUser, provider) {
176
+ const p = this.getProvider(provider);
177
+ const now = this.now();
178
+ if (p && typeof p.GetEntityObject === 'function') {
179
+ try {
180
+ const user = this.resolveUser(contextUser);
181
+ const entity = await p.GetEntityObject('MJ: Interaction Offers', user);
182
+ const loaded = await entity.Load(offerID);
183
+ if (loaded) {
184
+ const expiresAtMs = entity.ExpiresAt ? new Date(entity.ExpiresAt).getTime() : 0;
185
+ if (entity.Status === 'Pending' && expiresAtMs <= now) {
186
+ entity.Status = 'Expired';
187
+ entity.RespondedAt = new Date(now);
188
+ await entity.Save();
189
+ const record = this.entityToRecord(entity);
190
+ this.offers.set(record.OfferID, record);
191
+ this.notifyPublisher(record);
192
+ return record;
193
+ }
194
+ const record = this.entityToRecord(entity);
195
+ this.offers.set(record.OfferID, record);
196
+ return record;
197
+ }
198
+ }
199
+ catch (err) {
200
+ LogError(`[HandoffOfferRegistry] Get(${offerID}) failed: ${err instanceof Error ? err.message : String(err)}`);
201
+ }
202
+ }
203
+ const cached = this.offers.get(offerID);
204
+ if (cached && cached.Status === 'Pending' && cached.ExpiresAtMs <= now) {
205
+ this.finish(cached, 'Expired');
206
+ this.notifyPublisher(cached);
207
+ }
208
+ return cached;
209
+ }
210
+ /** The person's offers that can still be accepted, soonest to expire first. */
211
+ async PendingForUser(userID, contextUser, provider) {
212
+ const p = this.getProvider(provider);
213
+ const now = this.now();
214
+ const user = this.resolveUser(contextUser);
215
+ if (!user) {
216
+ this.noteNoUser();
217
+ }
218
+ if (p && user && typeof p.GetEntityObject === 'function') {
219
+ try {
220
+ const rv = this.getRunView(p);
221
+ const result = await rv.RunView({
222
+ EntityName: 'MJ: Interaction Offers',
223
+ ExtraFilter: `TargetUserID = '${EscapeSQLString(userID)}' AND Status = 'Pending'`,
224
+ OrderBy: 'ExpiresAt ASC',
225
+ ResultType: 'entity_object',
226
+ }, user);
227
+ if (result.Success && result.Results) {
228
+ const records = [];
229
+ for (const entity of result.Results) {
230
+ const expiresAtMs = entity.ExpiresAt ? new Date(entity.ExpiresAt).getTime() : 0;
231
+ if (expiresAtMs <= now) {
232
+ entity.Status = 'Expired';
233
+ entity.RespondedAt = new Date(now);
234
+ await entity.Save();
235
+ const rec = this.entityToRecord(entity);
236
+ this.offers.set(rec.OfferID, rec);
237
+ this.notifyPublisher(rec);
238
+ }
239
+ else {
240
+ const rec = this.entityToRecord(entity);
241
+ this.offers.set(rec.OfferID, rec);
242
+ records.push(rec);
243
+ }
244
+ }
245
+ return records.sort((a, b) => a.ExpiresAtMs - b.ExpiresAtMs);
246
+ }
247
+ }
248
+ catch (err) {
249
+ LogError(`[HandoffOfferRegistry] PendingForUser query failed: ${err instanceof Error ? err.message : String(err)}`);
250
+ }
251
+ }
252
+ // In-memory fallback
253
+ return [...this.offers.values()]
254
+ .filter((o) => o.Status === 'Pending' && o.ExpiresAtMs > now && UUIDsEqual(o.TargetUserID, userID))
255
+ .sort((a, b) => a.ExpiresAtMs - b.ExpiresAtMs);
256
+ }
257
+ /** The person's offers to show: pending ones, plus ones resolved recently enough to still be retained. */
258
+ async ListForUser(userID, contextUser, provider) {
259
+ await this.sweep(contextUser, provider);
260
+ const p = this.getProvider(provider);
261
+ const now = this.now();
262
+ const user = this.resolveUser(contextUser);
263
+ if (!user) {
264
+ this.noteNoUser();
265
+ }
266
+ if (p && user && typeof p.GetEntityObject === 'function') {
267
+ try {
268
+ const cutoff = new Date(now - HANDOFF_OFFER_RETENTION_MS).toISOString();
269
+ const rv = this.getRunView(p);
270
+ const result = await rv.RunView({
271
+ EntityName: 'MJ: Interaction Offers',
272
+ ExtraFilter: `TargetUserID = '${EscapeSQLString(userID)}' AND (Status = 'Pending' OR RespondedAt >= '${cutoff}')`,
273
+ OrderBy: 'OfferedAt DESC',
274
+ ResultType: 'entity_object',
275
+ }, user);
276
+ if (result.Success && result.Results) {
277
+ const records = result.Results.map((e) => {
278
+ const rec = this.entityToRecord(e);
279
+ this.offers.set(rec.OfferID, rec);
280
+ return rec;
281
+ });
282
+ return records.sort((a, b) => b.CreatedAtMs - a.CreatedAtMs);
283
+ }
284
+ }
285
+ catch (err) {
286
+ LogError(`[HandoffOfferRegistry] ListForUser query failed: ${err instanceof Error ? err.message : String(err)}`);
287
+ }
288
+ }
289
+ // In-memory fallback
290
+ return [...this.offers.values()]
291
+ .filter((o) => UUIDsEqual(o.TargetUserID, userID))
292
+ .sort((a, b) => b.CreatedAtMs - a.CreatedAtMs);
293
+ }
294
+ /** The offers made from one room, any status. */
295
+ async ForRoom(roomName, contextUser, provider) {
296
+ const key = roomName.trim().toLowerCase();
297
+ const p = this.getProvider(provider);
298
+ const user = this.resolveUser(contextUser);
299
+ if (!user) {
300
+ this.noteNoUser();
301
+ }
302
+ if (p && user && typeof p.GetEntityObject === 'function') {
303
+ try {
304
+ const rv = this.getRunView(p);
305
+ const result = await rv.RunView({
306
+ EntityName: 'MJ: Interaction Offers',
307
+ ExtraFilter: `RoomName = '${EscapeSQLString(roomName.trim())}'`,
308
+ OrderBy: 'OfferedAt DESC',
309
+ ResultType: 'entity_object',
310
+ }, user);
311
+ if (result.Success && result.Results) {
312
+ return result.Results.map((e) => this.entityToRecord(e));
313
+ }
314
+ }
315
+ catch (err) {
316
+ LogError(`[HandoffOfferRegistry] ForRoom query failed: ${err instanceof Error ? err.message : String(err)}`);
317
+ }
318
+ }
319
+ // In-memory fallback
320
+ return [...this.offers.values()].filter((o) => o.RoomName.trim().toLowerCase() === key);
321
+ }
322
+ /**
323
+ * Moves a pending offer to a terminal status on behalf of the person it was made to. The caller must be the
324
+ * offer's target and the offer must still be pending and unexpired; anything else answers the same way.
325
+ *
326
+ * Compares and sets atomically in a transaction on `Status = 'Pending'` so concurrent requests across
327
+ * multiple instances cannot both succeed.
328
+ */
329
+ async ResolveForUser(offerID, userID, status, contextUser, provider) {
330
+ const p = this.getProvider(provider);
331
+ if (p && typeof p.GetEntityObject === 'function') {
332
+ const user = this.resolveUser(contextUser);
333
+ try {
334
+ return await RunInEntityTransaction(asTransactionCapable(p), async () => {
335
+ const entity = await p.GetEntityObject('MJ: Interaction Offers', user);
336
+ const loaded = await entity.Load(offerID);
337
+ if (!loaded) {
338
+ return { Ok: false, Reason: OFFER_UNAVAILABLE };
339
+ }
340
+ if (!UUIDsEqual(entity.TargetUserID, userID)) {
341
+ return { Ok: false, Reason: OFFER_UNAVAILABLE };
342
+ }
343
+ const now = this.now();
344
+ const expiresAtMs = entity.ExpiresAt ? new Date(entity.ExpiresAt).getTime() : 0;
345
+ if (entity.Status !== 'Pending' || expiresAtMs <= now) {
346
+ if (entity.Status === 'Pending' && expiresAtMs <= now) {
347
+ entity.Status = 'Expired';
348
+ entity.RespondedAt = new Date(now);
349
+ await entity.Save();
350
+ const rec = this.entityToRecord(entity);
351
+ this.offers.set(rec.OfferID, rec);
352
+ this.notifyPublisher(rec);
353
+ }
354
+ return { Ok: false, Reason: OFFER_UNAVAILABLE };
355
+ }
356
+ entity.Status = status;
357
+ entity.RespondedAt = new Date(now);
358
+ const saved = await entity.Save();
359
+ if (!saved) {
360
+ return { Ok: false, Reason: OFFER_UNAVAILABLE };
361
+ }
362
+ const record = this.entityToRecord(entity);
363
+ this.offers.set(record.OfferID, record);
364
+ this.notifyPublisher(record);
365
+ return { Ok: true, Offer: record };
366
+ });
367
+ }
368
+ catch (err) {
369
+ LogError(`[HandoffOfferRegistry] ResolveForUser transaction failed: ${err instanceof Error ? err.message : String(err)}`);
370
+ return { Ok: false, Reason: OFFER_UNAVAILABLE };
371
+ }
372
+ }
373
+ // In-memory fallback
374
+ const offer = this.offers.get(offerID);
375
+ if (!offer || !UUIDsEqual(offer.TargetUserID, userID)) {
376
+ return { Ok: false, Reason: OFFER_UNAVAILABLE };
377
+ }
378
+ if (offer.Status !== 'Pending' || offer.ExpiresAtMs <= this.now()) {
379
+ return { Ok: false, Reason: OFFER_UNAVAILABLE };
380
+ }
381
+ this.finish(offer, status);
382
+ this.notifyPublisher(offer);
383
+ return { Ok: true, Offer: offer };
384
+ }
385
+ /**
386
+ * Moves a pending offer to `Expired` or `Cancelled` (a system decision, not the person's).
387
+ *
388
+ * @returns The offer when it was pending and has now changed; `undefined` when it was already resolved or unknown.
389
+ */
390
+ async Close(offerID, status, contextUser, provider) {
391
+ const p = this.getProvider(provider);
392
+ if (p && typeof p.GetEntityObject === 'function') {
393
+ const user = this.resolveUser(contextUser);
394
+ try {
395
+ return await RunInEntityTransaction(asTransactionCapable(p), async () => {
396
+ const entity = await p.GetEntityObject('MJ: Interaction Offers', user);
397
+ const loaded = await entity.Load(offerID);
398
+ if (!loaded || entity.Status !== 'Pending') {
399
+ return undefined;
400
+ }
401
+ entity.Status = status;
402
+ entity.RespondedAt = new Date(this.now());
403
+ const saved = await entity.Save();
404
+ if (!saved) {
405
+ return undefined;
406
+ }
407
+ const record = this.entityToRecord(entity);
408
+ this.offers.set(record.OfferID, record);
409
+ this.notifyPublisher(record);
410
+ return record;
411
+ });
412
+ }
413
+ catch (err) {
414
+ LogError(`[HandoffOfferRegistry] Close transaction failed: ${err instanceof Error ? err.message : String(err)}`);
415
+ return undefined;
416
+ }
417
+ }
418
+ // In-memory fallback
419
+ const offer = this.offers.get(offerID);
420
+ if (!offer || offer.Status !== 'Pending') {
421
+ return undefined;
422
+ }
423
+ this.finish(offer, status);
424
+ this.notifyPublisher(offer);
425
+ return offer;
426
+ }
427
+ /**
428
+ * Sweeps expired pending offers and purges retained resolved offers.
429
+ *
430
+ * @returns How many pending offers were expired by this sweep.
431
+ */
432
+ async Sweep(contextUser, provider) {
433
+ return this.sweep(contextUser, provider);
434
+ }
435
+ async sweep(contextUser, provider) {
436
+ const now = this.now();
437
+ let swept = 0;
438
+ const p = this.getProvider(provider);
439
+ const user = this.resolveUser(contextUser);
440
+ if (!user) {
441
+ this.noteNoUser();
442
+ }
443
+ if (p && user && typeof p.GetEntityObject === 'function') {
444
+ try {
445
+ const rv = this.getRunView(p);
446
+ const result = await rv.RunView({
447
+ EntityName: 'MJ: Interaction Offers',
448
+ ExtraFilter: `Status = 'Pending' AND ExpiresAt <= '${new Date(now).toISOString()}'`,
449
+ ResultType: 'entity_object',
450
+ }, user);
451
+ if (result.Success && result.Results) {
452
+ for (const entity of result.Results) {
453
+ entity.Status = 'Expired';
454
+ entity.RespondedAt = new Date(now);
455
+ const saved = await entity.Save();
456
+ if (saved) {
457
+ const record = this.entityToRecord(entity);
458
+ this.offers.set(record.OfferID, record);
459
+ this.notifyPublisher(record);
460
+ swept++;
461
+ }
462
+ }
463
+ }
464
+ }
465
+ catch (e) {
466
+ LogError(`[HandoffOfferRegistry] sweep failed: ${e instanceof Error ? e.message : String(e)}`);
467
+ }
468
+ }
469
+ const cutoff = now - HANDOFF_OFFER_RETENTION_MS;
470
+ for (const [id, offer] of this.offers) {
471
+ if (offer.Status === 'Pending' && offer.ExpiresAtMs <= now) {
472
+ this.finish(offer, 'Expired');
473
+ this.notifyPublisher(offer);
474
+ swept++;
475
+ }
476
+ if (offer.ResolvedAtMs !== undefined && offer.ResolvedAtMs < cutoff) {
477
+ this.offers.delete(id);
478
+ }
479
+ }
480
+ return swept;
481
+ }
482
+ finish(offer, status) {
483
+ offer.Status = status;
484
+ offer.ResolvedAtMs = this.now();
485
+ }
486
+ entityToRecord(entity, agentNameFallback) {
487
+ const createdAtMs = entity.OfferedAt
488
+ ? new Date(entity.OfferedAt).getTime()
489
+ : entity.__mj_CreatedAt
490
+ ? new Date(entity.__mj_CreatedAt).getTime()
491
+ : this.now();
492
+ const expiresAtMs = entity.ExpiresAt ? new Date(entity.ExpiresAt).getTime() : createdAtMs + HANDOFF_OFFER_TIMEOUT_MS;
493
+ const resolvedAtMs = entity.RespondedAt ? new Date(entity.RespondedAt).getTime() : undefined;
494
+ const mode = (entity.Mode?.toLowerCase() === 'warm' ? 'warm' : 'blind');
495
+ const agentName = entity.OfferedByAgent || agentNameFallback || 'AI Agent';
496
+ return {
497
+ OfferID: entity.ID,
498
+ InteractionID: entity.InteractionID,
499
+ OfferedByAgentID: entity.OfferedByAgentID,
500
+ RoomName: entity.RoomName,
501
+ TargetUserID: entity.TargetUserID,
502
+ Mode: mode,
503
+ Summary: entity.Summary ?? '',
504
+ CallerLabel: entity.CallerLabel ?? '',
505
+ AgentName: agentName,
506
+ Status: entity.Status,
507
+ CreatedAtMs: createdAtMs,
508
+ ExpiresAtMs: expiresAtMs,
509
+ ResolvedAtMs: resolvedAtMs,
510
+ };
511
+ }
512
+ notifyPublisher(record) {
513
+ try {
514
+ this.deps.Publisher?.({
515
+ UserID: record.TargetUserID,
516
+ Kind: 'updated',
517
+ Offer: ToOfferView(record),
518
+ });
519
+ }
520
+ catch (e) {
521
+ LogError(`[HandoffOfferRegistry] publish failed: ${e instanceof Error ? e.message : String(e)}`);
522
+ }
523
+ }
524
+ /** The caller's user, else the configured server identity, else the lazily resolved one. */
525
+ resolveUser(contextUser) {
526
+ return contextUser ?? this.deps.ContextUser ?? this.deps.ResolveContextUser?.();
527
+ }
528
+ /** Logs once (not per tick) that database queries are being skipped because no user identity is available yet. */
529
+ noteNoUser() {
530
+ if (!this.warnedNoUser) {
531
+ this.warnedNoUser = true;
532
+ LogStatusEx({
533
+ message: '[HandoffOfferRegistry] no context user configured yet; skipping database queries (in-memory offers still served and expired).',
534
+ verboseOnly: true,
535
+ });
536
+ }
537
+ }
538
+ getProvider(callProvider) {
539
+ return callProvider ?? this.deps.Provider ?? Metadata.Provider;
540
+ }
541
+ getRunView(provider) {
542
+ if (typeof provider.RunView === 'function') {
543
+ return RunView.FromMetadataProvider(provider);
544
+ }
545
+ return new RunView();
546
+ }
547
+ }
548
+ //# sourceMappingURL=handoff-offer-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff-offer-registry.js","sourceRoot":"","sources":["../../src/room-handoff/handoff-offer-registry.ts"],"names":[],"mappings":"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"}