@mulingai-npm/redis 3.38.0 → 3.38.2

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.
@@ -20,6 +20,11 @@ export type StreamingChunkData = {
20
20
  model?: string;
21
21
  words?: TranscriptionWord[];
22
22
  };
23
+ export type SttHistoryEntry = {
24
+ chunkNumber: number;
25
+ source: 'stt' | 'llm';
26
+ provider: string;
27
+ };
23
28
  export type MulingstreamChunkData = {
24
29
  chunkId: string;
25
30
  roomId: string;
@@ -48,6 +53,11 @@ export type MulingstreamChunkData = {
48
53
  };
49
54
  isComplete: boolean;
50
55
  isSaved: boolean;
56
+ llmTranscription?: string;
57
+ llmWords?: TranscriptionWord[];
58
+ transcriptionSource: 'stt' | 'llm';
59
+ routeUsed?: 'LLM' | 'AZURE' | 'AZURE_FALLBACK';
60
+ sttHistory?: SttHistoryEntry[];
51
61
  };
52
62
  export declare class MulingstreamChunkManager {
53
63
  private redisClient;
@@ -91,6 +101,21 @@ export declare class MulingstreamChunkManager {
91
101
  getMulingstreamChunkById(roomId: string, n: number): Promise<MulingstreamChunkData>;
92
102
  private withChunk;
93
103
  updateFinalTranscription(roomId: string, n: number, transcription: string): Promise<MulingstreamChunkData | null>;
104
+ /**
105
+ * Update chunk with LLM-sanitized transcription from SmartTranslate.
106
+ * If the sanitized text differs from the original, sets transcriptionSource to 'llm'
107
+ * and updates finalTranscription to the sanitized version.
108
+ * Returns the chunk (caller can compare original vs sanitized to decide on TRANSCRIPTION_CORRECTED).
109
+ */
110
+ updateLlmTranscription(roomId: string, n: number, opts: {
111
+ llmTranscription: string;
112
+ llmWords?: TranscriptionWord[];
113
+ routeUsed: 'LLM' | 'AZURE' | 'AZURE_FALLBACK';
114
+ sttHistoryEntry?: SttHistoryEntry;
115
+ }): Promise<{
116
+ chunk: MulingstreamChunkData | null;
117
+ wasChanged: boolean;
118
+ }>;
94
119
  discardLanguage(roomId: string, n: number, lang: string): Promise<MulingstreamChunkData | null>;
95
120
  discardLanguages(roomId: string, n: number, opt: {
96
121
  translation?: string[];
@@ -39,7 +39,13 @@ class MulingstreamChunkManager {
39
39
  translation: this.deserialize(h.translation),
40
40
  tts: this.deserialize(h.tts),
41
41
  isComplete: h.isComplete === 'true',
42
- isSaved: h.isSaved === 'true'
42
+ isSaved: h.isSaved === 'true',
43
+ // SmartTranslate fields
44
+ llmTranscription: h.llmTranscription || undefined,
45
+ llmWords: h.llmWords ? this.deserialize(h.llmWords) : undefined,
46
+ transcriptionSource: h.transcriptionSource || 'stt',
47
+ routeUsed: h.routeUsed || undefined,
48
+ sttHistory: h.sttHistory ? this.deserialize(h.sttHistory) : undefined
43
49
  };
44
50
  }
45
51
  getTimeout() {
@@ -133,7 +139,9 @@ class MulingstreamChunkManager {
133
139
  translation,
134
140
  tts,
135
141
  isComplete: false,
136
- isSaved: false
142
+ isSaved: false,
143
+ // SmartTranslate defaults
144
+ transcriptionSource: 'stt'
137
145
  };
138
146
  const hash = {
139
147
  chunkId,
@@ -150,7 +158,8 @@ class MulingstreamChunkManager {
150
158
  translation: this.serialize(translation),
151
159
  tts: this.serialize(tts),
152
160
  isComplete: 'false',
153
- isSaved: 'false'
161
+ isSaved: 'false',
162
+ transcriptionSource: 'stt'
154
163
  };
155
164
  const pipe = this.redisClient.pipeline();
156
165
  pipe.hset(this.chunkHashKey(chunkId), hash);
@@ -194,14 +203,25 @@ class MulingstreamChunkManager {
194
203
  const chunk = this.hashToChunk(raw);
195
204
  await fn(chunk);
196
205
  const p = this.redisClient.pipeline();
197
- p.hset(key, {
206
+ const updateHash = {
198
207
  finalTranscription: chunk.finalTranscription,
199
208
  translation: this.serialize(chunk.translation),
200
209
  tts: this.serialize(chunk.tts),
201
210
  streamingChunk: this.serialize(chunk.streamingChunk),
202
211
  isComplete: String(chunk.isComplete),
203
- isSaved: String(chunk.isSaved)
204
- });
212
+ isSaved: String(chunk.isSaved),
213
+ transcriptionSource: chunk.transcriptionSource || 'stt'
214
+ };
215
+ // SmartTranslate fields (only set if populated)
216
+ if (chunk.llmTranscription !== undefined)
217
+ updateHash.llmTranscription = chunk.llmTranscription;
218
+ if (chunk.llmWords !== undefined)
219
+ updateHash.llmWords = this.serialize(chunk.llmWords);
220
+ if (chunk.routeUsed !== undefined)
221
+ updateHash.routeUsed = chunk.routeUsed;
222
+ if (chunk.sttHistory !== undefined)
223
+ updateHash.sttHistory = this.serialize(chunk.sttHistory);
224
+ p.hset(key, updateHash);
205
225
  p.expire(key, EXPIRATION);
206
226
  await p.exec();
207
227
  return chunk;
@@ -211,6 +231,36 @@ class MulingstreamChunkManager {
211
231
  c.finalTranscription = transcription;
212
232
  });
213
233
  }
234
+ /**
235
+ * Update chunk with LLM-sanitized transcription from SmartTranslate.
236
+ * If the sanitized text differs from the original, sets transcriptionSource to 'llm'
237
+ * and updates finalTranscription to the sanitized version.
238
+ * Returns the chunk (caller can compare original vs sanitized to decide on TRANSCRIPTION_CORRECTED).
239
+ */
240
+ async updateLlmTranscription(roomId, n, opts) {
241
+ let wasChanged = false;
242
+ const chunk = await this.withChunk(roomId, n, (c) => {
243
+ const originalText = c.finalTranscription;
244
+ c.llmTranscription = opts.llmTranscription;
245
+ c.llmWords = opts.llmWords;
246
+ c.routeUsed = opts.routeUsed;
247
+ // If LLM produced a different transcription, update the active text
248
+ if (opts.routeUsed === 'LLM' && opts.llmTranscription !== originalText) {
249
+ c.finalTranscription = opts.llmTranscription;
250
+ c.transcriptionSource = 'llm';
251
+ wasChanged = true;
252
+ }
253
+ // Append to STT history (keep last 3)
254
+ if (opts.sttHistoryEntry) {
255
+ if (!c.sttHistory)
256
+ c.sttHistory = [];
257
+ c.sttHistory.push(opts.sttHistoryEntry);
258
+ if (c.sttHistory.length > 3)
259
+ c.sttHistory = c.sttHistory.slice(-3);
260
+ }
261
+ });
262
+ return { chunk, wasChanged };
263
+ }
214
264
  async discardLanguage(roomId, n, lang) {
215
265
  return this.withChunk(roomId, n, (c) => {
216
266
  if (c.translation[lang])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mulingai-npm/redis",
3
- "version": "3.38.0",
3
+ "version": "3.38.2",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": {