@runnerpro/backend 1.21.8 → 1.21.10
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/lib/cjs/chat/api/conversation.js +27 -5
- package/lib/cjs/chat/exposed/conversation.js +7 -0
- package/lib/cjs/chat/index.js +7 -0
- package/lib/cjs/locale/en.js +4 -0
- package/lib/cjs/locale/es.js +4 -0
- package/lib/cjs/locale/fr.js +4 -0
- package/lib/cjs/locale/it.js +4 -0
- package/lib/cjs/prompt/ai.js +14 -0
- package/lib/cjs/prompt/constants.js +12 -21
- package/lib/cjs/prompt/llmCacheStore.js +102 -0
- package/lib/cjs/sendNotification/index.js +70 -4
- package/lib/cjs/types/chat/api/conversation.d.ts.map +1 -1
- package/lib/cjs/types/chat/exposed/conversation.d.ts.map +1 -1
- package/lib/cjs/types/chat/index.d.ts.map +1 -1
- package/lib/cjs/types/locale/en.d.ts +4 -0
- package/lib/cjs/types/locale/en.d.ts.map +1 -1
- package/lib/cjs/types/locale/es.d.ts +4 -0
- package/lib/cjs/types/locale/es.d.ts.map +1 -1
- package/lib/cjs/types/locale/fr.d.ts +4 -0
- package/lib/cjs/types/locale/fr.d.ts.map +1 -1
- package/lib/cjs/types/locale/it.d.ts +4 -0
- package/lib/cjs/types/locale/it.d.ts.map +1 -1
- package/lib/cjs/types/prompt/ai.d.ts.map +1 -1
- package/lib/cjs/types/prompt/constants.d.ts.map +1 -1
- package/lib/cjs/types/prompt/llmCacheStore.d.ts +26 -0
- package/lib/cjs/types/prompt/llmCacheStore.d.ts.map +1 -0
- package/lib/cjs/types/sendNotification/index.d.ts +20 -1
- package/lib/cjs/types/sendNotification/index.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -370,12 +370,16 @@ const sendMessage = (req, res, { sendNotification, firebaseMessaging, isClient }
|
|
|
370
370
|
const [message] = yield (0, index_1.query)('INSERT INTO [CHAT MESSAGE] ([ID CLIENTE], [ID SENDER], [TEXT], [TEXT PREFERRED LANGUAGE], [PREFERRED LANGUAGE], [REPLY MESSAGE ID], [ID WORKOUT], [TYPE]) VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING [ID]', [isClient ? userid : idCliente, userid, textSpanish, textPreferredLanguage, preferredLanguage, replyMessageId, idWorkout, type]);
|
|
371
371
|
res.send({ idMessage: message.id, text: textSpanish });
|
|
372
372
|
if (!isClient) {
|
|
373
|
+
// Recuperamos el nombre del entrenador para firmar el push con su nombre real (no genérico).
|
|
374
|
+
const [entrenadorRow] = yield (0, index_1.query)('SELECT [NAME] FROM [ENTRENADOR] WHERE [ID] = ?', [userid]);
|
|
375
|
+
const entrenador = ((entrenadorRow === null || entrenadorRow === void 0 ? void 0 : entrenadorRow.name) || 'Tu entrenador').split(' ')[0];
|
|
373
376
|
sendNotification({
|
|
374
377
|
firebaseMessaging,
|
|
375
378
|
idCliente,
|
|
376
|
-
title: '💬
|
|
379
|
+
title: (0, index_2.t)('{{ entrenador }} 💬', preferredLanguage || common_1.LANGUAGES.ES).replace('{{ entrenador }}', entrenador),
|
|
377
380
|
body: textPreferredLanguage || textSpanish,
|
|
378
381
|
screen: common_1.NOTIFICATION_SCREEN_TYPES.CHAT,
|
|
382
|
+
channelId: common_1.NOTIFICATION_CHANNELS.COACH,
|
|
379
383
|
});
|
|
380
384
|
// Enviar a N8N lo que ha escrito el entrenador
|
|
381
385
|
// const [lastSuggestionMsg] = await query(
|
|
@@ -427,11 +431,20 @@ const sendEmoji = (req, res, { sendNotification, firebaseMessaging, isClient })
|
|
|
427
431
|
]);
|
|
428
432
|
res.send({ idReaction: reaction.id });
|
|
429
433
|
if (!isClient) {
|
|
434
|
+
const [[entrenadorRow], [clienteRow]] = yield Promise.all([
|
|
435
|
+
(0, index_1.query)('SELECT [NAME] FROM [ENTRENADOR] WHERE [ID] = ?', [userid]),
|
|
436
|
+
(0, index_1.query)('SELECT [PREFERRED LANGUAGE] FROM [CLIENTE] WHERE [ID] = ?', [idCliente]),
|
|
437
|
+
]);
|
|
438
|
+
const entrenador = ((entrenadorRow === null || entrenadorRow === void 0 ? void 0 : entrenadorRow.name) || 'Tu entrenador').split(' ')[0];
|
|
439
|
+
const lang = (clienteRow === null || clienteRow === void 0 ? void 0 : clienteRow.preferredLanguage) || common_1.LANGUAGES.ES;
|
|
430
440
|
sendNotification({
|
|
431
441
|
firebaseMessaging,
|
|
432
442
|
idCliente,
|
|
433
|
-
body:
|
|
443
|
+
body: (0, index_2.t)('{{ entrenador }} reaccionó {{ emoji }} a tu mensaje', lang)
|
|
444
|
+
.replace('{{ entrenador }}', entrenador)
|
|
445
|
+
.replace('{{ emoji }}', emoji),
|
|
434
446
|
screen: common_1.NOTIFICATION_SCREEN_TYPES.CHAT,
|
|
447
|
+
channelId: common_1.NOTIFICATION_CHANNELS.COACH,
|
|
435
448
|
});
|
|
436
449
|
}
|
|
437
450
|
});
|
|
@@ -506,13 +519,22 @@ const sendFile = (req, res, { sendNotification, firebaseMessaging, isClient, buc
|
|
|
506
519
|
textFile = 'Vídeo';
|
|
507
520
|
if (req.file.mimetype.includes('image'))
|
|
508
521
|
textFile = 'Imagen';
|
|
509
|
-
const [
|
|
522
|
+
const [[entrenadorRow], [clienteRow]] = yield Promise.all([
|
|
523
|
+
(0, index_1.query)('SELECT [NAME] FROM [ENTRENADOR] WHERE [ID] = ?', [userid]),
|
|
524
|
+
(0, index_1.query)('SELECT [PREFERRED LANGUAGE] FROM [CLIENTE] WHERE [ID] = ?', [idCliente]),
|
|
525
|
+
]);
|
|
526
|
+
const entrenador = ((entrenadorRow === null || entrenadorRow === void 0 ? void 0 : entrenadorRow.name) || 'Tu entrenador').split(' ')[0];
|
|
527
|
+
const lang = (clienteRow === null || clienteRow === void 0 ? void 0 : clienteRow.preferredLanguage) || common_1.LANGUAGES.ES;
|
|
528
|
+
const tipoArchivo = (0, index_2.t)(textFile, lang);
|
|
510
529
|
sendNotification({
|
|
511
530
|
firebaseMessaging,
|
|
512
531
|
idCliente,
|
|
513
|
-
title: (0, index_2.t)('
|
|
514
|
-
|
|
532
|
+
title: (0, index_2.t)('{{ entrenador }} te ha enviado {{ tipoArchivo }} 📎', lang)
|
|
533
|
+
.replace('{{ entrenador }}', entrenador)
|
|
534
|
+
.replace('{{ tipoArchivo }}', tipoArchivo),
|
|
535
|
+
body: (0, index_2.t)('Ábrelo en el chat.', lang),
|
|
515
536
|
screen: common_1.NOTIFICATION_SCREEN_TYPES.CHAT,
|
|
537
|
+
channelId: common_1.NOTIFICATION_CHANNELS.COACH,
|
|
516
538
|
});
|
|
517
539
|
yield updateSenderView({ userid, idCliente, idMessage: idFile });
|
|
518
540
|
}
|
|
@@ -30,6 +30,13 @@ exports.conversationRoute = conversationRoute;
|
|
|
30
30
|
const socketConversation = (req, res, { isClient }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
31
|
const { idCliente } = req.body;
|
|
32
32
|
const ioEmitter = req.app.get('socketIo');
|
|
33
|
+
// El backend de la app ya no monta socket.io (la app recibe por push + recarga HTTP, no por
|
|
34
|
+
// websocket). Sin emisor no hay a quién emitir: respondemos ok y salimos. Antes esto caía al
|
|
35
|
+
// vacío igualmente porque la app no escuchaba el socket; ahora evitamos el 500 por undefined.
|
|
36
|
+
if (!ioEmitter) {
|
|
37
|
+
res.send({ status: 'ok' });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
33
40
|
const room = (0, getRoom_1.getRoom)(isClient, idCliente);
|
|
34
41
|
ioEmitter.sockets.in(room).emit('message', req.body);
|
|
35
42
|
res.send({ status: 'ok' });
|
package/lib/cjs/chat/index.js
CHANGED
|
@@ -15,6 +15,13 @@ Object.defineProperty(exports, "chatExposed", { enumerable: true, get: function
|
|
|
15
15
|
const getCountNotificaciones_1 = require("./utils/getCountNotificaciones");
|
|
16
16
|
Object.defineProperty(exports, "getCountNotificaciones", { enumerable: true, get: function () { return getCountNotificaciones_1.getCountNotificaciones; } });
|
|
17
17
|
const chat = ({ server, app, verify_access_token, tokenExposed, backendExtremeUrl, frontendUrl, isClient }) => {
|
|
18
|
+
// El backend de la APP (isClient) NO usa websockets: la app recibe los mensajes por avisos
|
|
19
|
+
// push (FCM) + recarga HTTP de la conversación, nunca por socket.io (no tiene cliente de
|
|
20
|
+
// websocket). Montarlo aquí era código muerto — el emit caía al vacío — y además inflaba la
|
|
21
|
+
// latencia p95 del servicio con conexiones de larga duración. El dashboard de coaches
|
|
22
|
+
// (isClient=false) sí consume el socket, así que ahí se mantiene intacto.
|
|
23
|
+
if (isClient)
|
|
24
|
+
return;
|
|
18
25
|
// @ts-ignore
|
|
19
26
|
const io = (0, socket_io_1.default)(server, {
|
|
20
27
|
cors: {
|
package/lib/cjs/locale/en.js
CHANGED
|
@@ -7,5 +7,9 @@ const en = {
|
|
|
7
7
|
Vídeo: 'Video',
|
|
8
8
|
Imagen: 'Image',
|
|
9
9
|
'💬 Nuevo mensaje de tu entrenador': '💬 New message from your trainer',
|
|
10
|
+
'{{ entrenador }} 💬': '{{ entrenador }} 💬',
|
|
11
|
+
'{{ entrenador }} te ha enviado {{ tipoArchivo }} 📎': '{{ entrenador }} sent you {{ tipoArchivo }} 📎',
|
|
12
|
+
'Ábrelo en el chat.': 'Open it in the chat.',
|
|
13
|
+
'{{ entrenador }} reaccionó {{ emoji }} a tu mensaje': '{{ entrenador }} reacted {{ emoji }} to your message',
|
|
10
14
|
};
|
|
11
15
|
exports.en = en;
|
package/lib/cjs/locale/es.js
CHANGED
|
@@ -7,5 +7,9 @@ const es = {
|
|
|
7
7
|
Vídeo: 'Vídeo',
|
|
8
8
|
Imagen: 'Imagen',
|
|
9
9
|
'💬 Nuevo mensaje de tu entrenador': '💬 Nuevo mensaje de tu entrenador',
|
|
10
|
+
'{{ entrenador }} 💬': '{{ entrenador }} 💬',
|
|
11
|
+
'{{ entrenador }} te ha enviado {{ tipoArchivo }} 📎': '{{ entrenador }} te ha enviado {{ tipoArchivo }} 📎',
|
|
12
|
+
'Ábrelo en el chat.': 'Ábrelo en el chat.',
|
|
13
|
+
'{{ entrenador }} reaccionó {{ emoji }} a tu mensaje': '{{ entrenador }} reaccionó {{ emoji }} a tu mensaje',
|
|
10
14
|
};
|
|
11
15
|
exports.es = es;
|
package/lib/cjs/locale/fr.js
CHANGED
|
@@ -7,5 +7,9 @@ const fr = {
|
|
|
7
7
|
Vídeo: 'Vidéo',
|
|
8
8
|
Imagen: 'Image',
|
|
9
9
|
'💬 Nuevo mensaje de tu entrenador': '💬 Nouveau message de votre entraîneur',
|
|
10
|
+
'{{ entrenador }} 💬': '{{ entrenador }} 💬',
|
|
11
|
+
'{{ entrenador }} te ha enviado {{ tipoArchivo }} 📎': '{{ entrenador }} t’a envoyé {{ tipoArchivo }} 📎',
|
|
12
|
+
'Ábrelo en el chat.': 'Ouvre-le dans le chat.',
|
|
13
|
+
'{{ entrenador }} reaccionó {{ emoji }} a tu mensaje': '{{ entrenador }} a réagi {{ emoji }} à ton message',
|
|
10
14
|
};
|
|
11
15
|
exports.fr = fr;
|
package/lib/cjs/locale/it.js
CHANGED
|
@@ -7,5 +7,9 @@ const it = {
|
|
|
7
7
|
Vídeo: 'Video',
|
|
8
8
|
Imagen: 'Immagine',
|
|
9
9
|
'💬 Nuevo mensaje de tu entrenador': '💬 Nuovo messaggio da tuo allenatore',
|
|
10
|
+
'{{ entrenador }} 💬': '{{ entrenador }} 💬',
|
|
11
|
+
'{{ entrenador }} te ha enviado {{ tipoArchivo }} 📎': '{{ entrenador }} ti ha inviato {{ tipoArchivo }} 📎',
|
|
12
|
+
'Ábrelo en el chat.': 'Aprilo nella chat.',
|
|
13
|
+
'{{ entrenador }} reaccionó {{ emoji }} a tu mensaje': '{{ entrenador }} ha reagito {{ emoji }} al tuo messaggio',
|
|
10
14
|
};
|
|
11
15
|
exports.it = it;
|
package/lib/cjs/prompt/ai.js
CHANGED
|
@@ -16,6 +16,7 @@ const modelPricing_1 = require("./modelPricing");
|
|
|
16
16
|
const constants_1 = require("./constants");
|
|
17
17
|
const googleModel_1 = require("./googleModel");
|
|
18
18
|
const slack_1 = require("../slack");
|
|
19
|
+
const llmCacheStore_1 = require("./llmCacheStore");
|
|
19
20
|
const MIN_RETRIES = 1;
|
|
20
21
|
// ✅ Detección de Chain-of-Thought (CoT) que se cuela en la respuesta final del modelo
|
|
21
22
|
const COT_HTML_TAG = /<\/?(thinking|thought|reasoning)\b/i;
|
|
@@ -204,6 +205,17 @@ function generateObject(options) {
|
|
|
204
205
|
return __awaiter(this, void 0, void 0, function* () {
|
|
205
206
|
let lastError;
|
|
206
207
|
let currentOptions = options;
|
|
208
|
+
// [llm-cache] cache-aside: HIT → output guardado sin llamar al modelo (opt-out con options.cache === false)
|
|
209
|
+
const co = currentOptions;
|
|
210
|
+
const useCache = co.cache !== false;
|
|
211
|
+
const schemaSig = useCache ? (0, llmCacheStore_1.schemaSignature)(co.schema) : null;
|
|
212
|
+
let cacheKey = null;
|
|
213
|
+
if (useCache) {
|
|
214
|
+
cacheKey = (0, llmCacheStore_1.llmCacheKey)({ system: co.system, prompt: co.prompt, schemaSig, temperature: co.temperature });
|
|
215
|
+
const hit = yield (0, llmCacheStore_1.lookup)(cacheKey);
|
|
216
|
+
if (hit !== null && hit !== undefined)
|
|
217
|
+
return { object: hit, cost: { inputTokens: 0, outputTokens: 0, cost: 0 } };
|
|
218
|
+
}
|
|
207
219
|
const fallbackNames = ((_a = currentOptions.model) === null || _a === void 0 ? void 0 : _a._fallbackModelNames) || [];
|
|
208
220
|
const maxAttempts = (1 + fallbackNames.length) * (1 + MIN_RETRIES);
|
|
209
221
|
let transientRetries = 0;
|
|
@@ -216,6 +228,8 @@ function generateObject(options) {
|
|
|
216
228
|
const tracker = costTrackingStorage.getStore();
|
|
217
229
|
if (tracker)
|
|
218
230
|
tracker.push(cost);
|
|
231
|
+
if (useCache && cacheKey)
|
|
232
|
+
(0, llmCacheStore_1.store)(cacheKey, { modelName, system: co.system, prompt: co.prompt, schemaSig, temperature: co.temperature, output: object });
|
|
219
233
|
return { object, cost };
|
|
220
234
|
}
|
|
221
235
|
catch (error) {
|
|
@@ -17,9 +17,6 @@ const BEDROCK_CLAUDE_SONNET_4 = 'us.anthropic.claude-sonnet-4-20250514-v1:0';
|
|
|
17
17
|
exports.BEDROCK_CLAUDE_SONNET_4 = BEDROCK_CLAUDE_SONNET_4;
|
|
18
18
|
const BEDROCK_CLAUDE_HAIKU = 'us.anthropic.claude-haiku-4-5-20251001-v1:0';
|
|
19
19
|
exports.BEDROCK_CLAUDE_HAIKU = BEDROCK_CLAUDE_HAIKU;
|
|
20
|
-
const BEDROCK_NOVA_PREMIER = 'amazon.nova-premier-v1:0';
|
|
21
|
-
const BEDROCK_NOVA_PRO = 'amazon.nova-pro-v1:0';
|
|
22
|
-
const BEDROCK_NOVA_LITE = 'amazon.nova-2-lite-v1:0';
|
|
23
20
|
const GOOGLE_MODELS = {
|
|
24
21
|
FLASH: 'gemini-3-flash-preview',
|
|
25
22
|
PRO: 'gemini-3.1-pro-preview',
|
|
@@ -44,8 +41,8 @@ const AZURE_GPT_5_4_MINI = `${AZURE_PREFIX}${AZURE_GPT_5_4_MINI_DEPLOYMENT}`;
|
|
|
44
41
|
exports.AZURE_GPT_5_4_MINI = AZURE_GPT_5_4_MINI;
|
|
45
42
|
const AZURE_GPT_5_4_NANO = `${AZURE_PREFIX}${AZURE_GPT_5_4_NANO_DEPLOYMENT}`;
|
|
46
43
|
exports.AZURE_GPT_5_4_NANO = AZURE_GPT_5_4_NANO;
|
|
47
|
-
// Primario Azure por tier (antes que
|
|
48
|
-
// El modelo
|
|
44
|
+
// Primario Azure por tier (antes que Gemini en todos los tiers → Azure > Gemini).
|
|
45
|
+
// El modelo Gemini que el tier resuelve (PRODUCTION_MODELS/FAST_MODELS/... vía AI_MODELS)
|
|
49
46
|
// se conserva como PRIMER fallback.
|
|
50
47
|
//
|
|
51
48
|
// ⚠️ TEMPORAL: la cuenta de Azure solo tiene cuota para gpt-5.4-mini de momento,
|
|
@@ -59,16 +56,19 @@ const AZURE_PRIMARY_MODELS = {
|
|
|
59
56
|
LITE: AZURE_GPT_5_4_MINI,
|
|
60
57
|
};
|
|
61
58
|
exports.AZURE_PRIMARY_MODELS = AZURE_PRIMARY_MODELS;
|
|
59
|
+
// ⚠️ Bedrock/Claude retirado del enrutado: el provider, las constantes BEDROCK_CLAUDE_*
|
|
60
|
+
// y su pricing siguen disponibles (compat de exports), pero ningún tier ni fallback los
|
|
61
|
+
// referencia, así que Bedrock nunca se selecciona. Cascada efectiva: Azure → Gemini.
|
|
62
62
|
const PRODUCTION_MODELS = {
|
|
63
|
-
FLASH:
|
|
64
|
-
PRO:
|
|
65
|
-
LITE:
|
|
63
|
+
FLASH: GOOGLE_MODELS.FLASH,
|
|
64
|
+
PRO: GOOGLE_MODELS.PRO,
|
|
65
|
+
LITE: GOOGLE_MODELS.LITE,
|
|
66
66
|
};
|
|
67
67
|
exports.PRODUCTION_MODELS = PRODUCTION_MODELS;
|
|
68
68
|
const SEMI_MODELS = {
|
|
69
|
-
FLASH:
|
|
70
|
-
PRO:
|
|
71
|
-
LITE:
|
|
69
|
+
FLASH: GOOGLE_MODELS.FLASH,
|
|
70
|
+
PRO: GOOGLE_MODELS.FLASH,
|
|
71
|
+
LITE: GOOGLE_MODELS.FLASH,
|
|
72
72
|
};
|
|
73
73
|
exports.SEMI_MODELS = SEMI_MODELS;
|
|
74
74
|
const FAST_MODELS = {
|
|
@@ -88,21 +88,12 @@ const AISTUDIO_PREFIX = 'aistudio:';
|
|
|
88
88
|
exports.AISTUDIO_PREFIX = AISTUDIO_PREFIX;
|
|
89
89
|
const FALLBACK_MODELS = {
|
|
90
90
|
FLASH: [
|
|
91
|
-
BEDROCK_CLAUDE_SONNET_4_5,
|
|
92
|
-
BEDROCK_CLAUDE_SONNET_4,
|
|
93
|
-
BEDROCK_NOVA_PRO,
|
|
94
91
|
`${AISTUDIO_PREFIX}${GOOGLE_MODELS.FLASH}`,
|
|
95
92
|
'gemini-2.5-flash',
|
|
96
93
|
`${AISTUDIO_PREFIX}gemini-2.5-flash`,
|
|
97
94
|
GOOGLE_MODELS.LITE,
|
|
98
95
|
],
|
|
99
96
|
PRO: [
|
|
100
|
-
BEDROCK_CLAUDE_OPUS_4_5,
|
|
101
|
-
BEDROCK_CLAUDE_OPUS_4_1,
|
|
102
|
-
BEDROCK_CLAUDE_SONNET,
|
|
103
|
-
BEDROCK_CLAUDE_SONNET_4_5,
|
|
104
|
-
BEDROCK_NOVA_PREMIER,
|
|
105
|
-
BEDROCK_NOVA_PRO,
|
|
106
97
|
`${AISTUDIO_PREFIX}${GOOGLE_MODELS.PRO}`,
|
|
107
98
|
'gemini-2.5-pro',
|
|
108
99
|
`${AISTUDIO_PREFIX}gemini-2.5-pro`,
|
|
@@ -112,7 +103,7 @@ const FALLBACK_MODELS = {
|
|
|
112
103
|
`${AISTUDIO_PREFIX}gemini-2.5-flash`,
|
|
113
104
|
GOOGLE_MODELS.LITE,
|
|
114
105
|
],
|
|
115
|
-
LITE: [
|
|
106
|
+
LITE: [`${AISTUDIO_PREFIX}${GOOGLE_MODELS.LITE}`, 'gemini-2.5-flash-lite', `${AISTUDIO_PREFIX}gemini-2.5-flash-lite`],
|
|
116
107
|
};
|
|
117
108
|
exports.FALLBACK_MODELS = FALLBACK_MODELS;
|
|
118
109
|
const MODEL_TIER = {
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.store = exports.lookup = exports.llmCacheKey = exports.schemaSignature = void 0;
|
|
13
|
+
/**
|
|
14
|
+
* Caché LLM (cache-aside) para `generateObject`.
|
|
15
|
+
*
|
|
16
|
+
* Antes de cada llamada se busca por (modelo + system + input + schema + temperatura); si existe se
|
|
17
|
+
* devuelve el output guardado SIN llamar al modelo; si no, se llama y se guarda. Una poda periódica
|
|
18
|
+
* (Cron-backend /cron/operations/llmCacheEvict) elimina las entradas de un solo uso rancias.
|
|
19
|
+
*
|
|
20
|
+
* Fail-safe: un único chequeo `to_regclass` desactiva la caché en silencio si la tabla "LLM CACHE" no
|
|
21
|
+
* existe (migración no aplicada) o la BBDD falla. Así nunca rompe ni hace spam de errores.
|
|
22
|
+
*
|
|
23
|
+
* Tabla: ver migración en IA-backend docs/llm-cache-prod/001-llm-cache-table.sql.
|
|
24
|
+
*/
|
|
25
|
+
const node_crypto_1 = require("node:crypto");
|
|
26
|
+
const db_1 = require("../db");
|
|
27
|
+
let _ready = null; // null=sin comprobar, true=tabla disponible, false=desactivada
|
|
28
|
+
function ensureReady() {
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
if (_ready !== null)
|
|
31
|
+
return _ready;
|
|
32
|
+
try {
|
|
33
|
+
const rows = yield (0, db_1.query)('SELECT to_regclass(?) AS t', ['"LLM CACHE"']);
|
|
34
|
+
_ready = !!(rows && rows[0] && rows[0].t);
|
|
35
|
+
}
|
|
36
|
+
catch (_a) {
|
|
37
|
+
_ready = false;
|
|
38
|
+
}
|
|
39
|
+
return _ready;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/** Firma ligera del schema (zod) para distinguir llamadas con el mismo prompt pero distinta forma. */
|
|
43
|
+
function schemaSignature(schema) {
|
|
44
|
+
var _a, _b;
|
|
45
|
+
try {
|
|
46
|
+
if (!schema)
|
|
47
|
+
return 'noschema';
|
|
48
|
+
const tn = ((_a = schema === null || schema === void 0 ? void 0 : schema._def) === null || _a === void 0 ? void 0 : _a.typeName) || ((_b = schema === null || schema === void 0 ? void 0 : schema.constructor) === null || _b === void 0 ? void 0 : _b.name) || 'schema';
|
|
49
|
+
let shape = schema === null || schema === void 0 ? void 0 : schema.shape;
|
|
50
|
+
if (!shape && (schema === null || schema === void 0 ? void 0 : schema._def))
|
|
51
|
+
shape = typeof schema._def.shape === 'function' ? schema._def.shape() : schema._def.shape;
|
|
52
|
+
const keys = shape ? Object.keys(shape).sort().join(',') : '';
|
|
53
|
+
return `${tn}:${keys}`;
|
|
54
|
+
}
|
|
55
|
+
catch (_c) {
|
|
56
|
+
return 'schema';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.schemaSignature = schemaSignature;
|
|
60
|
+
/**
|
|
61
|
+
* Clave determinista de una llamada: SYSTEM + INPUT + SCHEMA + TEMPERATURE.
|
|
62
|
+
* NO incluye el modelo a propósito: si esos 4 coinciden, se reutiliza el output guardado (lo haya
|
|
63
|
+
* generado el modelo que sea). Implica que cambiar de modelo NO invalida la caché.
|
|
64
|
+
*/
|
|
65
|
+
function llmCacheKey(opts) {
|
|
66
|
+
var _a;
|
|
67
|
+
const payload = JSON.stringify({
|
|
68
|
+
system: opts.system || '',
|
|
69
|
+
prompt: opts.prompt || '',
|
|
70
|
+
schema: opts.schemaSig || 'noschema',
|
|
71
|
+
temperature: (_a = opts.temperature) !== null && _a !== void 0 ? _a : null,
|
|
72
|
+
});
|
|
73
|
+
return (0, node_crypto_1.createHash)('sha256').update(payload).digest('hex');
|
|
74
|
+
}
|
|
75
|
+
exports.llmCacheKey = llmCacheKey;
|
|
76
|
+
/** HIT: incrementa USE COUNT + LAST USED y devuelve OUTPUT (atómico). null en MISS o ante error. */
|
|
77
|
+
function lookup(key) {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
if (!(yield ensureReady()))
|
|
80
|
+
return null;
|
|
81
|
+
try {
|
|
82
|
+
const rows = yield (0, db_1.query)('UPDATE "LLM CACHE" SET "USE COUNT" = "USE COUNT" + 1, "LAST USED AT" = now() WHERE "KEY" = ? RETURNING "OUTPUT"', [key]);
|
|
83
|
+
return rows && rows[0] ? rows[0].output : null;
|
|
84
|
+
}
|
|
85
|
+
catch (_a) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
exports.lookup = lookup;
|
|
91
|
+
/** MISS: inserta (ON CONFLICT cubre la carrera). Fire-and-forget, nunca lanza. */
|
|
92
|
+
function store(key, data) {
|
|
93
|
+
void ensureReady()
|
|
94
|
+
.then((ok) => {
|
|
95
|
+
var _a, _b;
|
|
96
|
+
if (!ok)
|
|
97
|
+
return undefined;
|
|
98
|
+
return (0, db_1.query)('INSERT INTO "LLM CACHE" ("KEY","MODEL","SYSTEM PROMPT","INPUT PROMPT","SCHEMA SIG","TEMPERATURE","OUTPUT") VALUES (?,?,?,?,?,?,?::jsonb) ON CONFLICT ("KEY") DO UPDATE SET "USE COUNT" = "LLM CACHE"."USE COUNT" + 1, "LAST USED AT" = now()', [key, data.modelName || null, data.system || null, data.prompt || null, data.schemaSig || null, (_a = data.temperature) !== null && _a !== void 0 ? _a : null, JSON.stringify((_b = data.output) !== null && _b !== void 0 ? _b : null)]);
|
|
99
|
+
})
|
|
100
|
+
.catch(() => { });
|
|
101
|
+
}
|
|
102
|
+
exports.store = store;
|
|
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.sendNotification = void 0;
|
|
13
13
|
const index_1 = require("../db/index");
|
|
14
14
|
const common_1 = require("@runnerpro/common");
|
|
15
|
-
const sendNotification = ({ firebaseMessaging, idCliente, title, body, screen = common_1.NOTIFICATION_SCREEN_TYPES.HOME, screenParams = {}, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
const sendNotification = ({ firebaseMessaging, idCliente, title, body, screen = common_1.NOTIFICATION_SCREEN_TYPES.HOME, screenParams = {}, imageUrl, channelId, largeIcon, bigText, actions, progress, sound, coachNombre, category, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
16
|
const devices = yield (0, index_1.query)('SELECT [SUBSCRIPTION], [TYPE] FROM [PUSH MANAGER] WHERE [ID CLIENTE] = ?', [idCliente]);
|
|
17
17
|
const [{ id: idNotification }] = yield (0, index_1.query)('INSERT INTO "CLIENTE NOTIFICACION" ("ID CLIENTE", "TIMESTAMP", "TITLE", "BODY", "PARAMS") VALUES (?, NOW(), ?, ?, ?) RETURNING "ID"', [
|
|
18
18
|
idCliente,
|
|
@@ -31,23 +31,89 @@ const sendNotification = ({ firebaseMessaging, idCliente, title, body, screen =
|
|
|
31
31
|
idNotification: (idNotification || '0').toString(),
|
|
32
32
|
screen,
|
|
33
33
|
screenParams: screenParamsString,
|
|
34
|
+
imageUrl,
|
|
35
|
+
channelId,
|
|
36
|
+
largeIcon,
|
|
37
|
+
bigText,
|
|
38
|
+
actions,
|
|
39
|
+
progress,
|
|
40
|
+
sound,
|
|
41
|
+
coachNombre,
|
|
42
|
+
category,
|
|
34
43
|
}, device.subscription);
|
|
35
44
|
}
|
|
36
45
|
});
|
|
37
46
|
exports.sendNotification = sendNotification;
|
|
38
47
|
function notificationWEB(firebaseMessaging, msg, token) {
|
|
48
|
+
var _a, _b;
|
|
39
49
|
return __awaiter(this, void 0, void 0, function* () {
|
|
40
50
|
if (!msg.title)
|
|
41
51
|
msg.title = '';
|
|
42
52
|
try {
|
|
43
|
-
|
|
53
|
+
// FCM `data` solo acepta strings; serializamos los campos ricos para que la
|
|
54
|
+
// app los reconstruya con Notifee al recibir el push.
|
|
55
|
+
const data = {
|
|
56
|
+
title: msg.title,
|
|
57
|
+
body: msg.body,
|
|
58
|
+
screen: msg.screen,
|
|
59
|
+
screenParams: msg.screenParams,
|
|
60
|
+
idNotification: String((_a = msg.idNotification) !== null && _a !== void 0 ? _a : ''),
|
|
61
|
+
};
|
|
62
|
+
if (msg.imageUrl)
|
|
63
|
+
data.imageUrl = msg.imageUrl;
|
|
64
|
+
if (msg.channelId)
|
|
65
|
+
data.channelId = msg.channelId;
|
|
66
|
+
if (msg.largeIcon)
|
|
67
|
+
data.largeIcon = msg.largeIcon;
|
|
68
|
+
if (msg.bigText)
|
|
69
|
+
data.bigText = msg.bigText;
|
|
70
|
+
if (msg.actions && msg.actions.length > 0)
|
|
71
|
+
data.actions = JSON.stringify(msg.actions);
|
|
72
|
+
if (msg.progress)
|
|
73
|
+
data.progress = JSON.stringify(msg.progress);
|
|
74
|
+
if (msg.sound)
|
|
75
|
+
data.sound = msg.sound;
|
|
76
|
+
if (msg.coachNombre)
|
|
77
|
+
data.coachNombre = msg.coachNombre;
|
|
78
|
+
const message = {
|
|
44
79
|
token,
|
|
45
80
|
notification: {
|
|
46
81
|
title: msg.title,
|
|
47
82
|
body: msg.body,
|
|
48
83
|
},
|
|
49
|
-
data
|
|
50
|
-
}
|
|
84
|
+
data,
|
|
85
|
+
};
|
|
86
|
+
// Bloques nativos solo cuando aportan, para no inflar el payload ni romper
|
|
87
|
+
// pushes existentes que no usan estos campos.
|
|
88
|
+
const channelIdResolved = (_b = msg.channelId) !== null && _b !== void 0 ? _b : common_1.NOTIFICATION_CHANNELS.DEFAULT;
|
|
89
|
+
const androidNotification = {
|
|
90
|
+
channelId: channelIdResolved,
|
|
91
|
+
};
|
|
92
|
+
if (msg.imageUrl)
|
|
93
|
+
androidNotification.imageUrl = msg.imageUrl;
|
|
94
|
+
if (msg.sound)
|
|
95
|
+
androidNotification.sound = msg.sound;
|
|
96
|
+
message.android = {
|
|
97
|
+
priority: 'high',
|
|
98
|
+
notification: androidNotification,
|
|
99
|
+
};
|
|
100
|
+
// iOS (APNs). mutable-content activa el Notification Service Extension, que
|
|
101
|
+
// necesitamos cuando hay imagen rica O avatar del coach (para pintarlo como
|
|
102
|
+
// communication notification con la cara del entrenador). category habilita
|
|
103
|
+
// los botones de acción (UNNotificationCategory registrada en la app).
|
|
104
|
+
const aps = {};
|
|
105
|
+
if (msg.imageUrl || msg.largeIcon)
|
|
106
|
+
aps['mutable-content'] = 1;
|
|
107
|
+
if (msg.sound)
|
|
108
|
+
aps.sound = msg.sound;
|
|
109
|
+
if (msg.category)
|
|
110
|
+
aps.category = msg.category;
|
|
111
|
+
if (Object.keys(aps).length > 0) {
|
|
112
|
+
message.apns = { payload: { aps } };
|
|
113
|
+
if (msg.imageUrl)
|
|
114
|
+
message.apns.fcm_options = { image: msg.imageUrl };
|
|
115
|
+
}
|
|
116
|
+
yield firebaseMessaging.send(message);
|
|
51
117
|
}
|
|
52
118
|
catch (error) {
|
|
53
119
|
return error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../../../src/chat/api/conversation.ts"],"names":[],"mappings":"AAmBA,QAAA,MAAM,iBAAiB,0BAA2B,GAAG,SA0BpD,CAAC;AAoGF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,QAAA,MAAM,uBAAuB,qCAAkC,GAAG,iBAwCjE,CAAC;AAmGF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,QAAA,MAAM,WAAW,0EAAuE,GAAG,
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../../../src/chat/api/conversation.ts"],"names":[],"mappings":"AAmBA,QAAA,MAAM,iBAAiB,0BAA2B,GAAG,SA0BpD,CAAC;AAoGF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,QAAA,MAAM,uBAAuB,qCAAkC,GAAG,iBAwCjE,CAAC;AAmGF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,QAAA,MAAM,WAAW,0EAAuE,GAAG,kBAsE1F,CAAC;AAEF,QAAA,MAAM,gBAAgB;;;;mBAqBrB,CAAC;AAqUF,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,WAAW,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../../../src/chat/exposed/conversation.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,iBAAiB;;;;UAEtB,CAAC;
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../../../src/chat/exposed/conversation.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,iBAAiB;;;;UAEtB,CAAC;AAiBF,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/chat/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAExE,QAAA,MAAM,IAAI;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/chat/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAExE,QAAA,MAAM,IAAI;;;;;;;;UAqCT,CAAC;AAEF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC"}
|
|
@@ -4,6 +4,10 @@ declare const en: {
|
|
|
4
4
|
Vídeo: string;
|
|
5
5
|
Imagen: string;
|
|
6
6
|
'\uD83D\uDCAC Nuevo mensaje de tu entrenador': string;
|
|
7
|
+
'{{ entrenador }} \uD83D\uDCAC': string;
|
|
8
|
+
'{{ entrenador }} te ha enviado {{ tipoArchivo }} \uD83D\uDCCE': string;
|
|
9
|
+
'\u00C1brelo en el chat.': string;
|
|
10
|
+
'{{ entrenador }} reaccion\u00F3 {{ emoji }} a tu mensaje': string;
|
|
7
11
|
};
|
|
8
12
|
export { en };
|
|
9
13
|
//# sourceMappingURL=en.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../../src/locale/en.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../../src/locale/en.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,EAAE;;;;;;;;;;CAUP,CAAC;AAEF,OAAO,EAAE,EAAE,EAAE,CAAC"}
|
|
@@ -4,6 +4,10 @@ declare const es: {
|
|
|
4
4
|
Vídeo: string;
|
|
5
5
|
Imagen: string;
|
|
6
6
|
'\uD83D\uDCAC Nuevo mensaje de tu entrenador': string;
|
|
7
|
+
'{{ entrenador }} \uD83D\uDCAC': string;
|
|
8
|
+
'{{ entrenador }} te ha enviado {{ tipoArchivo }} \uD83D\uDCCE': string;
|
|
9
|
+
'\u00C1brelo en el chat.': string;
|
|
10
|
+
'{{ entrenador }} reaccion\u00F3 {{ emoji }} a tu mensaje': string;
|
|
7
11
|
};
|
|
8
12
|
export { es };
|
|
9
13
|
//# sourceMappingURL=es.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"es.d.ts","sourceRoot":"","sources":["../../../../src/locale/es.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"es.d.ts","sourceRoot":"","sources":["../../../../src/locale/es.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,EAAE;;;;;;;;;;CAUP,CAAC;AAEF,OAAO,EAAE,EAAE,EAAE,CAAC"}
|
|
@@ -4,6 +4,10 @@ declare const fr: {
|
|
|
4
4
|
Vídeo: string;
|
|
5
5
|
Imagen: string;
|
|
6
6
|
'\uD83D\uDCAC Nuevo mensaje de tu entrenador': string;
|
|
7
|
+
'{{ entrenador }} \uD83D\uDCAC': string;
|
|
8
|
+
'{{ entrenador }} te ha enviado {{ tipoArchivo }} \uD83D\uDCCE': string;
|
|
9
|
+
'\u00C1brelo en el chat.': string;
|
|
10
|
+
'{{ entrenador }} reaccion\u00F3 {{ emoji }} a tu mensaje': string;
|
|
7
11
|
};
|
|
8
12
|
export { fr };
|
|
9
13
|
//# sourceMappingURL=fr.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fr.d.ts","sourceRoot":"","sources":["../../../../src/locale/fr.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"fr.d.ts","sourceRoot":"","sources":["../../../../src/locale/fr.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,EAAE;;;;;;;;;;CAUP,CAAC;AAEF,OAAO,EAAE,EAAE,EAAE,CAAC"}
|
|
@@ -4,6 +4,10 @@ declare const it: {
|
|
|
4
4
|
Vídeo: string;
|
|
5
5
|
Imagen: string;
|
|
6
6
|
'\uD83D\uDCAC Nuevo mensaje de tu entrenador': string;
|
|
7
|
+
'{{ entrenador }} \uD83D\uDCAC': string;
|
|
8
|
+
'{{ entrenador }} te ha enviado {{ tipoArchivo }} \uD83D\uDCCE': string;
|
|
9
|
+
'\u00C1brelo en el chat.': string;
|
|
10
|
+
'{{ entrenador }} reaccion\u00F3 {{ emoji }} a tu mensaje': string;
|
|
7
11
|
};
|
|
8
12
|
export { it };
|
|
9
13
|
//# sourceMappingURL=it.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"it.d.ts","sourceRoot":"","sources":["../../../../src/locale/it.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"it.d.ts","sourceRoot":"","sources":["../../../../src/locale/it.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,EAAE;;;;;;;;;;CAUP,CAAC;AAEF,OAAO,EAAE,EAAE,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../../../src/prompt/ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,IAAI,sBAAsB,EAAE,YAAY,IAAI,oBAAoB,EAAE,MAAM,IAAI,CAAC;AAEpG,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../../../src/prompt/ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,IAAI,sBAAsB,EAAE,YAAY,IAAI,oBAAoB,EAAE,MAAM,IAAI,CAAC;AAEpG,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAwKhE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,iBAAe,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAoD/H;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,iBAAe,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CA0C5H;AA2ED;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAe,mBAAmB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,SAAS,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAc5H;AAED,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/prompt/constants.ts"],"names":[],"mappings":"AAEA,KAAK,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAIzC,QAAA,MAAM,mBAAmB,oCAAoC,CAAC;AAC9D,QAAA,MAAM,qBAAqB,mCAAmC,CAAC;AAC/D,QAAA,MAAM,uBAAuB,+CAA+C,CAAC;AAC7E,QAAA,MAAM,uBAAuB,+CAA+C,CAAC;AAC7E,QAAA,MAAM,yBAAyB,iDAAiD,CAAC;AACjF,QAAA,MAAM,uBAAuB,+CAA+C,CAAC;AAC7E,QAAA,MAAM,oBAAoB,gDAAgD,CAAC;
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/prompt/constants.ts"],"names":[],"mappings":"AAEA,KAAK,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAIzC,QAAA,MAAM,mBAAmB,oCAAoC,CAAC;AAC9D,QAAA,MAAM,qBAAqB,mCAAmC,CAAC;AAC/D,QAAA,MAAM,uBAAuB,+CAA+C,CAAC;AAC7E,QAAA,MAAM,uBAAuB,+CAA+C,CAAC;AAC7E,QAAA,MAAM,yBAAyB,iDAAiD,CAAC;AACjF,QAAA,MAAM,uBAAuB,+CAA+C,CAAC;AAC7E,QAAA,MAAM,oBAAoB,gDAAgD,CAAC;AAE3E,QAAA,MAAM,aAAa,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAI3C,CAAC;AAMF,QAAA,MAAM,YAAY,WAAW,CAAC;AAC9B,QAAA,MAAM,wBAAwB,QAAoD,CAAC;AACnF,QAAA,MAAM,6BAA6B,QAA8D,CAAC;AAClG,QAAA,MAAM,6BAA6B,QAA8D,CAAC;AAElG,QAAA,MAAM,aAAa,QAA+C,CAAC;AACnE,QAAA,MAAM,kBAAkB,QAAoD,CAAC;AAC7E,QAAA,MAAM,kBAAkB,QAAoD,CAAC;AAW7E,QAAA,MAAM,oBAAoB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAIlD,CAAC;AAKF,QAAA,MAAM,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAI/C,CAAC;AAEF,QAAA,MAAM,WAAW,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAIzC,CAAC;AAEF,QAAA,MAAM,WAAW,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAIzC,CAAC;AAGF,QAAA,MAAM,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAI1C,CAAC;AAEF,QAAA,MAAM,eAAe,cAAc,CAAC;AAEpC,QAAA,MAAM,eAAe,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,CAkB/C,CAAC;AAEF,QAAA,MAAM,UAAU;;;;;CAKN,CAAC;AAEX,KAAK,cAAc,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AASnE;;;;;;;;GAQG;AACH,QAAA,MAAM,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAQtC,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,iBAAS,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAErF;AAED,OAAO,EACL,QAAQ,EACR,cAAc,EACd,SAAS,EACT,aAAa,EACb,YAAY,EACZ,wBAAwB,EACxB,6BAA6B,EAC7B,6BAA6B,EAC7B,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,aAAa,GACd,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Firma ligera del schema (zod) para distinguir llamadas con el mismo prompt pero distinta forma. */
|
|
2
|
+
declare function schemaSignature(schema: any): string;
|
|
3
|
+
/**
|
|
4
|
+
* Clave determinista de una llamada: SYSTEM + INPUT + SCHEMA + TEMPERATURE.
|
|
5
|
+
* NO incluye el modelo a propósito: si esos 4 coinciden, se reutiliza el output guardado (lo haya
|
|
6
|
+
* generado el modelo que sea). Implica que cambiar de modelo NO invalida la caché.
|
|
7
|
+
*/
|
|
8
|
+
declare function llmCacheKey(opts: {
|
|
9
|
+
system?: string;
|
|
10
|
+
prompt?: string;
|
|
11
|
+
schemaSig?: string | null;
|
|
12
|
+
temperature?: number | null;
|
|
13
|
+
}): string;
|
|
14
|
+
/** HIT: incrementa USE COUNT + LAST USED y devuelve OUTPUT (atómico). null en MISS o ante error. */
|
|
15
|
+
declare function lookup(key: string): Promise<any | null>;
|
|
16
|
+
/** MISS: inserta (ON CONFLICT cubre la carrera). Fire-and-forget, nunca lanza. */
|
|
17
|
+
declare function store(key: string, data: {
|
|
18
|
+
modelName?: string;
|
|
19
|
+
system?: string;
|
|
20
|
+
prompt?: string;
|
|
21
|
+
schemaSig?: string | null;
|
|
22
|
+
temperature?: number | null;
|
|
23
|
+
output: any;
|
|
24
|
+
}): void;
|
|
25
|
+
export { schemaSignature, llmCacheKey, lookup, store };
|
|
26
|
+
//# sourceMappingURL=llmCacheStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llmCacheStore.d.ts","sourceRoot":"","sources":["../../../../src/prompt/llmCacheStore.ts"],"names":[],"mappings":"AA4BA,sGAAsG;AACtG,iBAAS,eAAe,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CAW5C;AAED;;;;GAIG;AACH,iBAAS,WAAW,CAAC,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,MAAM,CAQ/H;AAED,oGAAoG;AACpG,iBAAe,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAQtD;AAED,kFAAkF;AAClF,iBAAS,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GAAG,IAAI,CAUrK;AAED,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC"}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
interface NotificationAction {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
input?: boolean;
|
|
5
|
+
}
|
|
6
|
+
interface NotificationProgress {
|
|
7
|
+
max: number;
|
|
8
|
+
current: number;
|
|
9
|
+
indeterminate?: boolean;
|
|
10
|
+
}
|
|
1
11
|
interface Notification {
|
|
2
12
|
firebaseMessaging: any;
|
|
3
13
|
idCliente: number;
|
|
@@ -6,7 +16,16 @@ interface Notification {
|
|
|
6
16
|
idNotification?: number;
|
|
7
17
|
screen?: string;
|
|
8
18
|
screenParams?: any;
|
|
19
|
+
imageUrl?: string;
|
|
20
|
+
channelId?: string;
|
|
21
|
+
largeIcon?: string;
|
|
22
|
+
bigText?: string;
|
|
23
|
+
actions?: NotificationAction[];
|
|
24
|
+
progress?: NotificationProgress;
|
|
25
|
+
sound?: string;
|
|
26
|
+
coachNombre?: string;
|
|
27
|
+
category?: string;
|
|
9
28
|
}
|
|
10
|
-
declare const sendNotification: ({ firebaseMessaging, idCliente, title, body, screen, screenParams, }: Notification) => Promise<void>;
|
|
29
|
+
declare const sendNotification: ({ firebaseMessaging, idCliente, title, body, screen, screenParams, imageUrl, channelId, largeIcon, bigText, actions, progress, sound, coachNombre, category, }: Notification) => Promise<void>;
|
|
11
30
|
export { sendNotification };
|
|
12
31
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/sendNotification/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/sendNotification/index.ts"],"names":[],"mappings":"AAGA,UAAU,kBAAkB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,UAAU,oBAAoB;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,YAAY;IACpB,iBAAiB,EAAE,GAAG,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,GAAG,CAAC;IAEnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,QAAA,MAAM,gBAAgB,mKAgBnB,YAAY,kBAuCd,CAAC;AAkFF,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runnerpro/backend",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.10",
|
|
4
4
|
"description": "A collection of common backend functions",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./lib/cjs/index.js"
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@ai-sdk/amazon-bedrock": "^4.0.89",
|
|
66
|
+
"@ai-sdk/azure": "^3.0.74",
|
|
66
67
|
"@ai-sdk/google": "^3.0.43",
|
|
67
68
|
"@ai-sdk/google-vertex": "^4.0.102",
|
|
68
69
|
"@google-cloud/speech": "^7.2.1",
|