@mulingai-npm/redis 3.40.3 → 3.40.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.
|
@@ -6,18 +6,34 @@
|
|
|
6
6
|
* to improve translation quality and transcription correction.
|
|
7
7
|
*
|
|
8
8
|
* Redis key: smarttranslate:context-enhancer:{roomId}
|
|
9
|
-
* Type: String (
|
|
10
|
-
* TTL:
|
|
9
|
+
* Type: String (JSON: { text, savedAt })
|
|
10
|
+
* TTL: environment-dependent (15min localhost, 30min development, 36h production)
|
|
11
11
|
*/
|
|
12
12
|
import { RedisClient } from '../redis-client';
|
|
13
|
+
export interface ContextEnhancerResult {
|
|
14
|
+
text: string;
|
|
15
|
+
savedAt: number;
|
|
16
|
+
expiresAt: number;
|
|
17
|
+
ttlSeconds: number;
|
|
18
|
+
}
|
|
13
19
|
export declare class ContextEnhancerManager {
|
|
14
20
|
private redisClient;
|
|
15
|
-
|
|
21
|
+
private ttlSeconds;
|
|
22
|
+
constructor(redisClient: RedisClient, environment?: string);
|
|
16
23
|
private key;
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
|
|
24
|
+
/** Get TTL configured for this environment (in seconds) */
|
|
25
|
+
getTtlSeconds(): number;
|
|
26
|
+
/** Save context text for a room. Truncates to MAX_CHARS. Returns false if cooldown active. */
|
|
27
|
+
saveContext(roomId: string | number, text: string): Promise<{
|
|
28
|
+
saved: boolean;
|
|
29
|
+
cooldownRemaining?: number;
|
|
30
|
+
}>;
|
|
31
|
+
/** Get raw context data (internal). */
|
|
32
|
+
private getContextData;
|
|
33
|
+
/** Get context with metadata (text, savedAt, expiresAt, ttlSeconds). */
|
|
34
|
+
getContext(roomId: string | number): Promise<ContextEnhancerResult | null>;
|
|
35
|
+
/** Get just the text (for pipeline injection, no metadata overhead). */
|
|
36
|
+
getContextText(roomId: string | number): Promise<string | null>;
|
|
21
37
|
/** Delete context text for a room. */
|
|
22
38
|
deleteContext(roomId: string | number): Promise<void>;
|
|
23
39
|
/** Check if context text exists for a room (not expired). */
|
|
@@ -7,30 +7,83 @@
|
|
|
7
7
|
* to improve translation quality and transcription correction.
|
|
8
8
|
*
|
|
9
9
|
* Redis key: smarttranslate:context-enhancer:{roomId}
|
|
10
|
-
* Type: String (
|
|
11
|
-
* TTL:
|
|
10
|
+
* Type: String (JSON: { text, savedAt })
|
|
11
|
+
* TTL: environment-dependent (15min localhost, 30min development, 36h production)
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.ContextEnhancerManager = void 0;
|
|
15
|
-
const CONTEXT_ENHANCER_TTL = 36 * 60 * 60; // 36 hours
|
|
16
15
|
const MAX_CHARS = 15000;
|
|
16
|
+
const COOLDOWN_SECONDS = 60; // 1 minute cooldown between saves
|
|
17
|
+
// TTL by environment (seconds)
|
|
18
|
+
const TTL_BY_ENV = {
|
|
19
|
+
localhost: 15 * 60,
|
|
20
|
+
development: 30 * 60,
|
|
21
|
+
production: 36 * 60 * 60 // 36 hours
|
|
22
|
+
};
|
|
17
23
|
class ContextEnhancerManager {
|
|
18
|
-
constructor(redisClient) {
|
|
24
|
+
constructor(redisClient, environment) {
|
|
19
25
|
this.redisClient = redisClient;
|
|
26
|
+
this.ttlSeconds = TTL_BY_ENV[environment || 'production'] || TTL_BY_ENV.production;
|
|
20
27
|
}
|
|
21
28
|
key(roomId) {
|
|
22
29
|
return `smarttranslate:context-enhancer:${roomId}`;
|
|
23
30
|
}
|
|
24
|
-
/**
|
|
31
|
+
/** Get TTL configured for this environment (in seconds) */
|
|
32
|
+
getTtlSeconds() {
|
|
33
|
+
return this.ttlSeconds;
|
|
34
|
+
}
|
|
35
|
+
/** Save context text for a room. Truncates to MAX_CHARS. Returns false if cooldown active. */
|
|
25
36
|
async saveContext(roomId, text) {
|
|
26
|
-
const truncated = text.slice(0, MAX_CHARS);
|
|
27
37
|
const key = this.key(roomId);
|
|
28
|
-
|
|
29
|
-
await this.
|
|
38
|
+
// Check cooldown
|
|
39
|
+
const existing = await this.getContextData(roomId);
|
|
40
|
+
if (existing) {
|
|
41
|
+
const elapsedSeconds = (Date.now() - existing.savedAt) / 1000;
|
|
42
|
+
if (elapsedSeconds < COOLDOWN_SECONDS) {
|
|
43
|
+
return { saved: false, cooldownRemaining: Math.ceil(COOLDOWN_SECONDS - elapsedSeconds) };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const truncated = text.slice(0, MAX_CHARS);
|
|
47
|
+
const data = {
|
|
48
|
+
text: truncated,
|
|
49
|
+
savedAt: Date.now()
|
|
50
|
+
};
|
|
51
|
+
await this.redisClient.set(key, JSON.stringify(data));
|
|
52
|
+
await this.redisClient.expire(key, this.ttlSeconds);
|
|
53
|
+
return { saved: true };
|
|
30
54
|
}
|
|
31
|
-
/** Get context
|
|
55
|
+
/** Get raw context data (internal). */
|
|
56
|
+
async getContextData(roomId) {
|
|
57
|
+
const raw = await this.redisClient.get(this.key(roomId));
|
|
58
|
+
if (!raw)
|
|
59
|
+
return null;
|
|
60
|
+
try {
|
|
61
|
+
return JSON.parse(raw);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Legacy plain text format (before JSON migration)
|
|
65
|
+
return { text: raw, savedAt: Date.now() };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Get context with metadata (text, savedAt, expiresAt, ttlSeconds). */
|
|
32
69
|
async getContext(roomId) {
|
|
33
|
-
|
|
70
|
+
const data = await this.getContextData(roomId);
|
|
71
|
+
if (!data)
|
|
72
|
+
return null;
|
|
73
|
+
const remainingTtl = await this.redisClient.ttl(this.key(roomId));
|
|
74
|
+
if (remainingTtl < 0)
|
|
75
|
+
return null; // expired or no TTL
|
|
76
|
+
return {
|
|
77
|
+
text: data.text,
|
|
78
|
+
savedAt: data.savedAt,
|
|
79
|
+
expiresAt: Date.now() + (remainingTtl * 1000),
|
|
80
|
+
ttlSeconds: remainingTtl
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/** Get just the text (for pipeline injection, no metadata overhead). */
|
|
84
|
+
async getContextText(roomId) {
|
|
85
|
+
const data = await this.getContextData(roomId);
|
|
86
|
+
return (data === null || data === void 0 ? void 0 : data.text) || null;
|
|
34
87
|
}
|
|
35
88
|
/** Delete context text for a room. */
|
|
36
89
|
async deleteContext(roomId) {
|
package/dist/redis-client.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export declare class RedisClient {
|
|
|
14
14
|
del(key: string): Promise<number>;
|
|
15
15
|
exists(key: string): Promise<number>;
|
|
16
16
|
expire(key: string, seconds: number): Promise<number>;
|
|
17
|
+
/** Get remaining TTL in seconds (-1 = no expiry, -2 = key doesn't exist) */
|
|
18
|
+
ttl(key: string): Promise<number>;
|
|
17
19
|
sadd(key: string, ...values: string[]): Promise<number>;
|
|
18
20
|
srem(key: string, ...values: string[]): Promise<number>;
|
|
19
21
|
smembers(key: string): Promise<string[]>;
|
package/dist/redis-client.js
CHANGED
|
@@ -37,6 +37,10 @@ class RedisClient {
|
|
|
37
37
|
async expire(key, seconds) {
|
|
38
38
|
return this.client.expire(key, seconds);
|
|
39
39
|
}
|
|
40
|
+
/** Get remaining TTL in seconds (-1 = no expiry, -2 = key doesn't exist) */
|
|
41
|
+
async ttl(key) {
|
|
42
|
+
return this.client.ttl(key);
|
|
43
|
+
}
|
|
40
44
|
async sadd(key, ...values) {
|
|
41
45
|
return this.client.sadd(key, values);
|
|
42
46
|
}
|