gptrans 1.4.8 → 1.5.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.
package/README.md CHANGED
@@ -65,11 +65,12 @@ When creating a new instance of GPTrans, you can customize:
65
65
 
66
66
  | Option | Description | Default |
67
67
  |--------|-------------|---------|
68
- | `from` | Source language locale (BCP 47) | `es-AR` |
69
- | `target` | Target language locale (BCP 47) | `en-US` |
68
+ | `from` | Source language locale (BCP 47) | `en-US` |
69
+ | `target` | Target language locale (BCP 47) | `es` |
70
70
  | `model` | Translation model key | `claude-3-7-sonnet` |
71
- | `batchThreshold` | Maximum number of characters to accumulate before triggering batch processing | `1000` |
71
+ | `batchThreshold` | Maximum number of characters to accumulate before triggering batch processing | `1500` |
72
72
  | `debounceTimeout` | Time in milliseconds to wait before processing translations | `500` |
73
+ | `freeze` | Freeze mode to prevent translations from being queued | `false` |
73
74
 
74
75
  ### BCP 47 Language Tags
75
76
 
@@ -0,0 +1,9 @@
1
+ {
2
+ "45h": {
3
+ "eres_muy_bueno_26czme": "You're very good",
4
+ "tienes_fuego_1i2o3ok": "Do you have a light?"
5
+ },
6
+ "1sfvxng": {
7
+ "eres_muy_bueno_26czme": "You are very good"
8
+ }
9
+ }
package/demo/case_4.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import GPTrans from '../index.js';
2
2
 
3
3
 
4
- // Case 2: Translate from Spanish Spain to Spanish Argentina
4
+ // Case 2: Translate from Spanish to English
5
5
  const model = new GPTrans({
6
6
  from: 'es',
7
- target: 'es',
7
+ target: 'en',
8
8
  });
9
9
 
10
10
  await model.preload();
package/index.js CHANGED
@@ -9,7 +9,16 @@ class GPTrans {
9
9
 
10
10
  static get mmix() {
11
11
  if (!this.#mmixInstance) {
12
- const mmix = new ModelMix();
12
+ const mmix = new ModelMix({
13
+ config: {
14
+ max_history: 1,
15
+ debug: false,
16
+ bottleneck: {
17
+ minTime: 15000,
18
+ maxConcurrent: 1
19
+ }
20
+ }
21
+ });
13
22
 
14
23
  mmix.attach(new MixOpenAI());
15
24
  mmix.attach(new MixAnthropic());
@@ -23,7 +32,7 @@ class GPTrans {
23
32
  return isLanguageAvailable(langCode);
24
33
  }
25
34
 
26
- constructor({ from = 'en-US', target = 'es-AR', model = 'claude-3-7-sonnet-20250219', batchThreshold = 1000, debounceTimeout = 500, promptFile = null, context = '' }) {
35
+ constructor({ from = 'en-US', target = 'es', model = 'claude-3-7-sonnet-20250219', batchThreshold = 1500, debounceTimeout = 500, promptFile = null, context = '', freeze = false }) {
27
36
 
28
37
  try {
29
38
  dotenv.config();
@@ -49,14 +58,8 @@ class GPTrans {
49
58
  this.modelKey = model;
50
59
  this.promptFile = promptFile ?? new URL('./prompt/translate.md', import.meta.url).pathname;
51
60
  this.context = context;
61
+ this.freeze = freeze;
52
62
  this.modelConfig = {
53
- config: {
54
- max_history: 1,
55
- debug: false,
56
- bottleneck: {
57
- maxConcurrent: 2,
58
- }
59
- },
60
63
  options: {
61
64
  max_tokens: batchThreshold,
62
65
  temperature: 0
@@ -85,14 +88,25 @@ class GPTrans {
85
88
  }
86
89
 
87
90
  get(key, text) {
91
+
92
+ if (!text || !text.trim()) {
93
+ return text;
94
+ }
95
+
88
96
  const contextHash = this._hash(this.context);
89
97
  const translation = this.dbTarget.get(contextHash, key);
90
98
 
91
99
  if (!translation) {
100
+
92
101
  if (!this.dbFrom.get(this.context, key)) {
93
102
  this.dbFrom.set(this.context, key, text);
94
103
  }
95
104
 
105
+ if (this.freeze) {
106
+ console.log(`Freeze mode: [${key}] ${text}`);
107
+ return text;
108
+ }
109
+
96
110
  // Skip translation if context is empty and languages are the same
97
111
  if (!this.context && this.replaceFrom.FROM_ISO === this.replaceTarget.TARGET_ISO) {
98
112
  return text;
@@ -129,7 +143,11 @@ class GPTrans {
129
143
 
130
144
  // Clear pending translations and character count before awaiting translation
131
145
  this.pendingTranslations.clear();
146
+
132
147
  this.modelConfig.options.max_tokens = this.pendingCharCount + 1000;
148
+ const minTime = Math.floor((60000 / (8000 / this.pendingCharCount)) * 1.4);
149
+ GPTrans.mmix.limiter.updateSettings({ minTime });
150
+
133
151
  this.pendingCharCount = 0;
134
152
 
135
153
  const textsToTranslate = batch.map(([_, text]) => text).join('\n---\n');
@@ -139,6 +157,14 @@ class GPTrans {
139
157
 
140
158
  const contextHash = this._hash(context);
141
159
  batch.forEach(([key], index) => {
160
+
161
+ if (!translatedTexts[index]) {
162
+ console.log(translations);
163
+ console.error(`No translation found for ${key}`);
164
+
165
+ return;
166
+ }
167
+
142
168
  this.dbTarget.set(contextHash, key, translatedTexts[index].trim());
143
169
  });
144
170
 
@@ -188,38 +214,30 @@ class GPTrans {
188
214
  return stringHash(input).toString(36);
189
215
  }
190
216
 
191
- async preload({ target = this.replaceTarget.TARGET_ISO, model = this.modelKey, from = this.replaceFrom.FROM_ISO, batchThreshold = this.batchThreshold, debounceTimeout = this.debounceTimeout } = {}) {
192
-
193
- // Create new GPTrans instance for the target language
194
- const translator = new GPTrans({
195
- from,
196
- target,
197
- model,
198
- batchThreshold,
199
- debounceTimeout,
200
- });
201
-
202
- // Process all entries in batches
217
+ async preload() {
203
218
  for (const [context, pairs] of this.dbFrom.entries()) {
204
- translator.setContext(context);
219
+ this.setContext(context);
205
220
  for (const [key, text] of Object.entries(pairs)) {
206
- translator.get(key, text);
221
+ this.get(key, text);
207
222
  }
208
223
  }
209
224
 
210
225
  // Wait for any pending translations to complete
211
- if (translator.pendingTranslations.size > 0) {
212
- await new Promise(resolve => {
213
- const checkInterval = setInterval(() => {
214
- if (translator.processing === false && translator.pendingTranslations.size === 0) {
215
- clearInterval(checkInterval);
216
- resolve();
217
- }
218
- }, 1000);
219
- });
220
- }
226
+ await new Promise(resolve => {
227
+ const checkInterval = setInterval(() => {
228
+ if (this.dbFrom.keys().length === this.dbTarget.keys().length) {
229
+ clearInterval(checkInterval);
230
+ resolve();
231
+ }
232
+ }, 100);
233
+ });
221
234
 
222
- return translator;
235
+ return this;
236
+ }
237
+
238
+ setFreeze(freeze = true) {
239
+ this.freeze = freeze;
240
+ return this;
223
241
  }
224
242
  }
225
243
 
package/isoAssoc.js CHANGED
@@ -180,10 +180,14 @@ export function isoAssoc(iso, prefix = '') {
180
180
 
181
181
  const parts = iso.toLowerCase().split('-');
182
182
  const lang = parts[0];
183
- const country = parts.length > 1 ? parts[1] : null;
183
+ let country = parts.length > 1 ? parts[1] : null;
184
184
 
185
- let denonym = country ? countryDenonym[country] : 'Neutral';
185
+ if (lang === 'en' && !country) {
186
+ country = 'us';
187
+ }
186
188
 
189
+ let denonym = country ? countryDenonym[country] : 'Neutral';
190
+
187
191
  if (lang === 'zh' && !country) {
188
192
  denonym = 'Simplified';
189
193
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gptrans",
3
3
  "type": "module",
4
- "version": "1.4.8",
4
+ "version": "1.5.2",
5
5
  "description": "🚆 GPTrans - The smarter AI-powered way to translate.",
6
6
  "keywords": [
7
7
  "translate",
@@ -2,7 +2,9 @@
2
2
  Translation from FROM_ISO to TARGET_ISO (TARGET_DENONYM TARGET_LANG) with cultural adaptations.
3
3
 
4
4
  ## Text to translate
5
+ ```
5
6
  INPUT
7
+ ```
6
8
 
7
9
  # Return Format
8
10
  - Provide the final translation within a code block using ```.