glotto 2.9.0 → 3.1.0

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 (151) hide show
  1. package/README.md +150 -54
  2. package/esm/cli.js +155 -43
  3. package/esm/deno.d.ts +5 -1
  4. package/esm/deno.js +18 -7
  5. package/esm/src/config.d.ts +4 -0
  6. package/esm/src/config.d.ts.map +1 -0
  7. package/esm/src/config.js +95 -0
  8. package/esm/src/contants.d.ts +6 -2
  9. package/esm/src/contants.d.ts.map +1 -1
  10. package/esm/src/contants.js +34 -15
  11. package/esm/src/diff.d.ts +4 -0
  12. package/esm/src/diff.d.ts.map +1 -0
  13. package/esm/src/diff.js +53 -0
  14. package/esm/src/file.d.ts +5 -9
  15. package/esm/src/file.d.ts.map +1 -1
  16. package/esm/src/file.js +14 -103
  17. package/esm/src/providers/anthropic.d.ts +6 -11
  18. package/esm/src/providers/anthropic.d.ts.map +1 -1
  19. package/esm/src/providers/anthropic.js +21 -107
  20. package/esm/src/providers/gemini.d.ts +6 -11
  21. package/esm/src/providers/gemini.d.ts.map +1 -1
  22. package/esm/src/providers/gemini.js +20 -113
  23. package/esm/src/providers/openai.d.ts +6 -11
  24. package/esm/src/providers/openai.d.ts.map +1 -1
  25. package/esm/src/providers/openai.js +17 -108
  26. package/esm/src/translator.d.ts +15 -0
  27. package/esm/src/translator.d.ts.map +1 -0
  28. package/esm/src/translator.js +284 -0
  29. package/esm/src/types.d.ts +58 -13
  30. package/esm/src/types.d.ts.map +1 -1
  31. package/esm/src/utilites.d.ts +3 -10
  32. package/esm/src/utilites.d.ts.map +1 -1
  33. package/esm/src/utilites.js +41 -131
  34. package/package.json +20 -6
  35. package/schema/glotto.schema.json +87 -0
  36. package/script/cli.js +153 -41
  37. package/script/deno.d.ts +5 -1
  38. package/script/deno.js +18 -7
  39. package/script/src/config.d.ts +4 -0
  40. package/script/src/config.d.ts.map +1 -0
  41. package/script/src/config.js +132 -0
  42. package/script/src/contants.d.ts +6 -2
  43. package/script/src/contants.d.ts.map +1 -1
  44. package/script/src/contants.js +35 -16
  45. package/script/src/diff.d.ts +4 -0
  46. package/script/src/diff.d.ts.map +1 -0
  47. package/script/src/diff.js +57 -0
  48. package/script/src/file.d.ts +5 -9
  49. package/script/src/file.d.ts.map +1 -1
  50. package/script/src/file.js +19 -113
  51. package/script/src/providers/anthropic.d.ts +6 -11
  52. package/script/src/providers/anthropic.d.ts.map +1 -1
  53. package/script/src/providers/anthropic.js +20 -106
  54. package/script/src/providers/gemini.d.ts +6 -11
  55. package/script/src/providers/gemini.d.ts.map +1 -1
  56. package/script/src/providers/gemini.js +19 -112
  57. package/script/src/providers/openai.d.ts +6 -11
  58. package/script/src/providers/openai.d.ts.map +1 -1
  59. package/script/src/providers/openai.js +16 -107
  60. package/script/src/translator.d.ts +15 -0
  61. package/script/src/translator.d.ts.map +1 -0
  62. package/script/src/translator.js +294 -0
  63. package/script/src/types.d.ts +58 -13
  64. package/script/src/types.d.ts.map +1 -1
  65. package/script/src/utilites.d.ts +3 -10
  66. package/script/src/utilites.d.ts.map +1 -1
  67. package/script/src/utilites.js +44 -138
  68. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts +0 -23
  69. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts.map +0 -1
  70. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.js +0 -51
  71. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common32.d.ts +0 -35
  72. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common32.d.ts.map +0 -1
  73. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common32.js +0 -192
  74. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common64.d.ts +0 -35
  75. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common64.d.ts.map +0 -1
  76. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common64.js +0 -113
  77. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts +0 -4
  78. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts.map +0 -1
  79. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.js +0 -13
  80. package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts +0 -9
  81. package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts.map +0 -1
  82. package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.js +0 -2
  83. package/esm/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.d.ts +0 -2
  84. package/esm/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.d.ts.map +0 -1
  85. package/esm/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.js +0 -26
  86. package/esm/deps/jsr.io/@std/encoding/1.0.10/ascii85.d.ts +0 -61
  87. package/esm/deps/jsr.io/@std/encoding/1.0.10/ascii85.d.ts.map +0 -1
  88. package/esm/deps/jsr.io/@std/encoding/1.0.10/ascii85.js +0 -152
  89. package/esm/deps/jsr.io/@std/encoding/1.0.10/base32.d.ts +0 -40
  90. package/esm/deps/jsr.io/@std/encoding/1.0.10/base32.d.ts.map +0 -1
  91. package/esm/deps/jsr.io/@std/encoding/1.0.10/base32.js +0 -87
  92. package/esm/deps/jsr.io/@std/encoding/1.0.10/base58.d.ts +0 -40
  93. package/esm/deps/jsr.io/@std/encoding/1.0.10/base58.d.ts.map +0 -1
  94. package/esm/deps/jsr.io/@std/encoding/1.0.10/base58.js +0 -131
  95. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64.d.ts +0 -40
  96. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64.d.ts.map +0 -1
  97. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64.js +0 -82
  98. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64url.d.ts +0 -40
  99. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64url.d.ts.map +0 -1
  100. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64url.js +0 -72
  101. package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts +0 -39
  102. package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts.map +0 -1
  103. package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.js +0 -87
  104. package/esm/deps/jsr.io/@std/encoding/1.0.10/mod.d.ts +0 -98
  105. package/esm/deps/jsr.io/@std/encoding/1.0.10/mod.d.ts.map +0 -1
  106. package/esm/deps/jsr.io/@std/encoding/1.0.10/mod.js +0 -99
  107. package/esm/deps/jsr.io/@std/encoding/1.0.10/varint.d.ts +0 -120
  108. package/esm/deps/jsr.io/@std/encoding/1.0.10/varint.d.ts.map +0 -1
  109. package/esm/deps/jsr.io/@std/encoding/1.0.10/varint.js +0 -205
  110. package/script/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts +0 -23
  111. package/script/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts.map +0 -1
  112. package/script/deps/jsr.io/@std/encoding/1.0.10/_common16.js +0 -57
  113. package/script/deps/jsr.io/@std/encoding/1.0.10/_common32.d.ts +0 -35
  114. package/script/deps/jsr.io/@std/encoding/1.0.10/_common32.d.ts.map +0 -1
  115. package/script/deps/jsr.io/@std/encoding/1.0.10/_common32.js +0 -198
  116. package/script/deps/jsr.io/@std/encoding/1.0.10/_common64.d.ts +0 -35
  117. package/script/deps/jsr.io/@std/encoding/1.0.10/_common64.d.ts.map +0 -1
  118. package/script/deps/jsr.io/@std/encoding/1.0.10/_common64.js +0 -119
  119. package/script/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts +0 -4
  120. package/script/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts.map +0 -1
  121. package/script/deps/jsr.io/@std/encoding/1.0.10/_common_detach.js +0 -16
  122. package/script/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts +0 -9
  123. package/script/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts.map +0 -1
  124. package/script/deps/jsr.io/@std/encoding/1.0.10/_types.js +0 -3
  125. package/script/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.d.ts +0 -2
  126. package/script/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.d.ts.map +0 -1
  127. package/script/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.js +0 -29
  128. package/script/deps/jsr.io/@std/encoding/1.0.10/ascii85.d.ts +0 -61
  129. package/script/deps/jsr.io/@std/encoding/1.0.10/ascii85.d.ts.map +0 -1
  130. package/script/deps/jsr.io/@std/encoding/1.0.10/ascii85.js +0 -156
  131. package/script/deps/jsr.io/@std/encoding/1.0.10/base32.d.ts +0 -40
  132. package/script/deps/jsr.io/@std/encoding/1.0.10/base32.d.ts.map +0 -1
  133. package/script/deps/jsr.io/@std/encoding/1.0.10/base32.js +0 -91
  134. package/script/deps/jsr.io/@std/encoding/1.0.10/base58.d.ts +0 -40
  135. package/script/deps/jsr.io/@std/encoding/1.0.10/base58.d.ts.map +0 -1
  136. package/script/deps/jsr.io/@std/encoding/1.0.10/base58.js +0 -135
  137. package/script/deps/jsr.io/@std/encoding/1.0.10/base64.d.ts +0 -40
  138. package/script/deps/jsr.io/@std/encoding/1.0.10/base64.d.ts.map +0 -1
  139. package/script/deps/jsr.io/@std/encoding/1.0.10/base64.js +0 -86
  140. package/script/deps/jsr.io/@std/encoding/1.0.10/base64url.d.ts +0 -40
  141. package/script/deps/jsr.io/@std/encoding/1.0.10/base64url.d.ts.map +0 -1
  142. package/script/deps/jsr.io/@std/encoding/1.0.10/base64url.js +0 -76
  143. package/script/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts +0 -39
  144. package/script/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts.map +0 -1
  145. package/script/deps/jsr.io/@std/encoding/1.0.10/hex.js +0 -91
  146. package/script/deps/jsr.io/@std/encoding/1.0.10/mod.d.ts +0 -98
  147. package/script/deps/jsr.io/@std/encoding/1.0.10/mod.d.ts.map +0 -1
  148. package/script/deps/jsr.io/@std/encoding/1.0.10/mod.js +0 -115
  149. package/script/deps/jsr.io/@std/encoding/1.0.10/varint.d.ts +0 -120
  150. package/script/deps/jsr.io/@std/encoding/1.0.10/varint.d.ts.map +0 -1
  151. package/script/deps/jsr.io/@std/encoding/1.0.10/varint.js +0 -211
@@ -4,31 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const openai_1 = __importDefault(require("openai"));
7
- const utilites_js_1 = require("../utilites.js");
8
- const logger_js_1 = require("../logger.js");
9
- const file_js_1 = require("../file.js");
10
7
  const contants_js_1 = require("../contants.js");
11
- const decoder = new TextDecoder();
12
8
  class OpenAIModel {
13
- constructor(key, chunks, from, to, baseUrl, modelName) {
14
- Object.defineProperty(this, "chunks", {
15
- enumerable: true,
16
- configurable: true,
17
- writable: true,
18
- value: void 0
19
- });
20
- Object.defineProperty(this, "from", {
21
- enumerable: true,
22
- configurable: true,
23
- writable: true,
24
- value: void 0
25
- });
26
- Object.defineProperty(this, "to", {
27
- enumerable: true,
28
- configurable: true,
29
- writable: true,
30
- value: void 0
31
- });
9
+ constructor(key, baseUrl, modelName, options = { noLimit: false, noTimeout: false }) {
32
10
  Object.defineProperty(this, "client", {
33
11
  enumerable: true,
34
12
  configurable: true,
@@ -41,97 +19,28 @@ class OpenAIModel {
41
19
  writable: true,
42
20
  value: void 0
43
21
  });
44
- this.chunks = chunks;
45
- this.from = from;
46
- this.to = to;
47
22
  this.model = modelName ?? contants_js_1.DEFAULT_MODELS.openai;
48
23
  this.client = new openai_1.default({
49
24
  apiKey: key,
50
25
  baseURL: baseUrl,
26
+ timeout: options.noTimeout ? 2_147_483_647 : undefined,
51
27
  });
52
28
  }
53
- async translateChunk(chunk, systemPrompt, userPrompt) {
54
- const chunkLabel = `[Chunk ${chunk.index + 1}/${this.chunks.length}]`;
55
- const sourceJson = decoder.decode(chunk.data);
56
- for (let attempt = 0; attempt <= contants_js_1.MAX_RETRIES; attempt++) {
57
- try {
58
- if (attempt > 0) {
59
- const backoffMs = contants_js_1.BASE_RETRY_DELAY_MS * Math.pow(2, attempt - 1);
60
- logger_js_1.logger.warn(`${chunkLabel} Retry ${attempt}/${contants_js_1.MAX_RETRIES} after ${backoffMs}ms backoff...`);
61
- await (0, utilites_js_1.delay)(backoffMs);
62
- }
63
- const response = await this.client.responses.create({
64
- model: this.model,
65
- input: [
66
- {
67
- role: 'user',
68
- content: [
69
- {
70
- type: 'input_text',
71
- text: `${systemPrompt}\n\n${userPrompt}\n\nSOURCE_JSON:\n${sourceJson}`,
72
- },
73
- ],
74
- },
75
- ],
76
- });
77
- const text = response.output_text;
78
- if (!text) {
79
- logger_js_1.logger.error(`${chunkLabel} Empty response from OpenAI`);
80
- continue;
81
- }
82
- const cleanedText = (0, utilites_js_1.stripJsonMarkdown)(text);
83
- const tempJsonFileName = `chunk_${chunk.index + 1}.json`;
84
- await (0, file_js_1.writeTemp)(this.to, tempJsonFileName, cleanedText);
85
- if (!(0, utilites_js_1.isValidJson)(cleanedText)) {
86
- if (attempt === contants_js_1.MAX_RETRIES) {
87
- logger_js_1.logger.error(`${chunkLabel} Failed after ${contants_js_1.MAX_RETRIES + 1} attempts: Invalid JSON response`);
88
- return null;
89
- }
90
- logger_js_1.logger.error(`${chunkLabel} Invalid JSON response, saved to ${tempJsonFileName}`);
91
- continue;
92
- }
93
- logger_js_1.logger.info(`${chunkLabel} Translated successfully (${(0, utilites_js_1.formatBytes)(chunk.byteSize)}, ${chunk.keyCount} keys)`);
94
- return cleanedText;
95
- }
96
- catch (error) {
97
- const isLastAttempt = attempt === contants_js_1.MAX_RETRIES;
98
- const errorMessage = error instanceof Error ? error.message : String(error);
99
- if (isLastAttempt) {
100
- logger_js_1.logger.error(`${chunkLabel} Failed after ${contants_js_1.MAX_RETRIES + 1} attempts: ${errorMessage}`);
101
- return null;
102
- }
103
- logger_js_1.logger.warn(`${chunkLabel} Attempt ${attempt + 1} failed: ${errorMessage}`);
104
- }
105
- }
106
- return null;
107
- }
108
- async translate() {
109
- const { systemPrompt, userPrompt } = (0, utilites_js_1.generatePrompts)(this.from, this.to);
110
- const totalChunks = this.chunks.length;
111
- logger_js_1.logger.info(`Starting translation: ${totalChunks} chunk(s) to process`);
112
- const results = [];
113
- const failedChunks = [];
114
- for (let i = 0; i < totalChunks; i++) {
115
- const chunk = this.chunks[i];
116
- if (i > 0) {
117
- logger_js_1.logger.info(`Waiting ${contants_js_1.INTER_CHUNK_DELAY_MS}ms before next chunk (rate limit protection)...`);
118
- await (0, utilites_js_1.delay)(contants_js_1.INTER_CHUNK_DELAY_MS);
119
- }
120
- const result = await this.translateChunk(chunk, systemPrompt, userPrompt);
121
- if (result) {
122
- results.push(result);
123
- }
124
- else {
125
- failedChunks.push(chunk.index + 1);
126
- }
127
- }
128
- if (failedChunks.length > 0) {
129
- throw new Error(`Translation failed for chunk(s): ${failedChunks.join(', ')}. Check temp files for partial results.`);
29
+ async translate(prompt) {
30
+ const completion = await this.client.chat.completions.create({
31
+ model: this.model,
32
+ messages: [{ role: 'user', content: prompt }],
33
+ temperature: 0.2,
34
+ });
35
+ const text = completion.choices[0]?.message?.content ?? '';
36
+ let usage;
37
+ if (completion.usage) {
38
+ usage = {
39
+ inputTokens: completion.usage.prompt_tokens ?? 0,
40
+ outputTokens: completion.usage.completion_tokens ?? 0,
41
+ };
130
42
  }
131
- logger_js_1.logger.info(`All ${totalChunks} chunk(s) translated successfully, merging results...`);
132
- const jsonInputs = results.map((r) => JSON.parse(r));
133
- const mergedContent = (0, file_js_1.mergeInputs)(jsonInputs);
134
- return JSON.stringify(mergedContent, null, 2);
43
+ return { text, usage };
135
44
  }
136
45
  }
137
46
  exports.default = OpenAIModel;
@@ -0,0 +1,15 @@
1
+ import type { Batch, JsonValue, Leaf, Path, TextTranslator, TranslateOptions, TranslateUsage } from './types.js';
2
+ export declare function extractLeaves(data: JsonValue): Leaf[];
3
+ export declare function groupIntoBatches(leaves: Leaf[], maxBytes: number): Batch[];
4
+ export declare function buildBatchPrompt(from: string, to: string, leaves: Leaf[]): string;
5
+ export declare function buildSinglePrompt(from: string, to: string, value: string): string;
6
+ export declare function decodeResponse(text: string): Map<number, string>;
7
+ export declare function setPath(root: JsonValue, path: Path, value: JsonValue): void;
8
+ export declare function reconstruct(allLeaves: Leaf[], translations: Map<number, string>): JsonValue;
9
+ export type RunBatchesResult = {
10
+ translations: Map<number, string>;
11
+ usage: TranslateUsage;
12
+ calls: number;
13
+ };
14
+ export declare function runBatches(batches: Batch[], translator: TextTranslator, from: string, to: string, options: TranslateOptions): Promise<RunBatchesResult>;
15
+ //# sourceMappingURL=translator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translator.d.ts","sourceRoot":"","sources":["../../src/src/translator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAWjH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,EAAE,CAmCrD;AAgBD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,EAAE,CA0B1E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAkBjF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjF;AAQD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAWhE;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAY3E;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAe3F;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AA6IF,wBAAsB,UAAU,CAC9B,OAAO,EAAE,KAAK,EAAE,EAChB,UAAU,EAAE,cAAc,EAC1B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAwC3B"}
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractLeaves = extractLeaves;
4
+ exports.groupIntoBatches = groupIntoBatches;
5
+ exports.buildBatchPrompt = buildBatchPrompt;
6
+ exports.buildSinglePrompt = buildSinglePrompt;
7
+ exports.decodeResponse = decodeResponse;
8
+ exports.setPath = setPath;
9
+ exports.reconstruct = reconstruct;
10
+ exports.runBatches = runBatches;
11
+ const logger_js_1 = require("./logger.js");
12
+ const utilites_js_1 = require("./utilites.js");
13
+ const contants_js_1 = require("./contants.js");
14
+ const encoder = new TextEncoder();
15
+ function byteSize(s) {
16
+ return encoder.encode(s).byteLength;
17
+ }
18
+ function extractLeaves(data) {
19
+ const out = [];
20
+ let nextId = 0;
21
+ function walk(node, path) {
22
+ if (node === null || typeof node !== 'object') {
23
+ const isString = typeof node === 'string';
24
+ out.push({
25
+ id: ++nextId,
26
+ path,
27
+ value: node,
28
+ translatable: isString && node.trim().length > 0,
29
+ });
30
+ return;
31
+ }
32
+ if (Array.isArray(node)) {
33
+ if (node.length === 0) {
34
+ out.push({ id: ++nextId, path, value: node, translatable: false });
35
+ return;
36
+ }
37
+ node.forEach((item, i) => walk(item, [...path, i]));
38
+ return;
39
+ }
40
+ const entries = Object.entries(node);
41
+ if (entries.length === 0) {
42
+ out.push({ id: ++nextId, path, value: node, translatable: false });
43
+ return;
44
+ }
45
+ for (const [k, v] of entries) {
46
+ walk(v, [...path, k]);
47
+ }
48
+ }
49
+ walk(data, []);
50
+ return out;
51
+ }
52
+ function tagOpen(id) {
53
+ return `≪${id}≫`;
54
+ }
55
+ function tagClose(id) {
56
+ return `≪/${id}≫`;
57
+ }
58
+ const TAG_OVERHEAD_CHARS = 8;
59
+ function wrapEntry(leaf) {
60
+ return `${tagOpen(leaf.id)}${String(leaf.value)}${tagClose(leaf.id)}`;
61
+ }
62
+ function groupIntoBatches(leaves, maxBytes) {
63
+ const translatable = leaves.filter((l) => l.translatable);
64
+ const batches = [];
65
+ let current = [];
66
+ let currentSize = 0;
67
+ for (const leaf of translatable) {
68
+ const valueBytes = byteSize(String(leaf.value));
69
+ const idChars = String(leaf.id).length;
70
+ const overhead = TAG_OVERHEAD_CHARS + idChars * 2 + 1;
71
+ const itemSize = valueBytes + overhead;
72
+ if (current.length > 0 && currentSize + itemSize > maxBytes) {
73
+ batches.push({ index: batches.length, leaves: current, byteSize: currentSize });
74
+ current = [];
75
+ currentSize = 0;
76
+ }
77
+ current.push(leaf);
78
+ currentSize += itemSize;
79
+ }
80
+ if (current.length > 0) {
81
+ batches.push({ index: batches.length, leaves: current, byteSize: currentSize });
82
+ }
83
+ return batches;
84
+ }
85
+ function buildBatchPrompt(from, to, leaves) {
86
+ const entries = leaves.map(wrapEntry).join('\n');
87
+ return `Translate each tagged entry below from ${from} to ${to}.
88
+
89
+ Tag format:
90
+ - Every entry is wrapped exactly as ≪N≫value≪/N≫, where N is the entry id (a positive integer).
91
+ - The opening marker is the character ≪ (U+226A), then the id, then ≫ (U+226B). The closing marker is ≪, /, the same id, then ≫.
92
+ - Copy these markers verbatim. Do not put spaces inside them. Do not change them to <<>>, «», <tag>, [n], or any other notation.
93
+ - The id must match the input id of the same entry — never renumber, merge, split, or reorder entries.
94
+
95
+ What to write back:
96
+ - One ≪N≫translated_value≪/N≫ block per input entry, in the same order, separated by single newlines.
97
+ - Translate only the text that sits between ≪N≫ and ≪/N≫.
98
+ - Preserve every variable ({{name}}, {name}, __VAR__, $t(...), %s, %d), HTML tag, markdown token, escape sequence, and special character inside the value.
99
+ - Output nothing else: no headings, no prose, no commentary, no code fences, no language labels.
100
+
101
+ Now translate the following entries:
102
+ ${entries}`;
103
+ }
104
+ function buildSinglePrompt(from, to, value) {
105
+ return `You are a professional ${from} to ${to} translator. Your goal is to accurately convey the meaning and nuances of the original ${from} text while adhering to ${to} grammar, vocabulary, and cultural sensitivities. Preserve every variable ({{name}}, {name}, __VAR__, $t(...), %s, %d), HTML tag, markdown token, escape sequence, and special character exactly as given.
106
+ Produce only the ${to} translation, without any additional explanations, quotes, labels, or commentary. Please translate the following ${from} text into ${to}:
107
+
108
+
109
+ ${value}`;
110
+ }
111
+ const TAG_PATTERNS = [
112
+ /≪\s*(\d+)\s*≫([\s\S]*?)≪\s*\/\s*\1\s*≫/g,
113
+ /<<\s*(\d+)\s*>>([\s\S]*?)<<\s*\/\s*\1\s*>>/g,
114
+ /«\s*(\d+)\s*»([\s\S]*?)«\s*\/\s*\1\s*»/g,
115
+ ];
116
+ function decodeResponse(text) {
117
+ const map = new Map();
118
+ for (const pattern of TAG_PATTERNS) {
119
+ for (const match of text.matchAll(pattern)) {
120
+ const id = parseInt(match[1], 10);
121
+ if (!map.has(id)) {
122
+ map.set(id, match[2].trim());
123
+ }
124
+ }
125
+ }
126
+ return map;
127
+ }
128
+ function setPath(root, path, value) {
129
+ let node = root;
130
+ for (let i = 0; i < path.length - 1; i++) {
131
+ const key = path[i];
132
+ const nextKey = path[i + 1];
133
+ const container = node;
134
+ if (container[key] === undefined) {
135
+ container[key] = typeof nextKey === 'number' ? [] : {};
136
+ }
137
+ node = container[key];
138
+ }
139
+ node[path[path.length - 1]] = value;
140
+ }
141
+ function reconstruct(allLeaves, translations) {
142
+ if (allLeaves.length === 0) {
143
+ return {};
144
+ }
145
+ const firstStep = allLeaves[0].path[0];
146
+ if (firstStep === undefined) {
147
+ const only = allLeaves[0];
148
+ return only.translatable ? translations.get(only.id) ?? only.value : only.value;
149
+ }
150
+ const root = typeof firstStep === 'number' ? [] : {};
151
+ for (const leaf of allLeaves) {
152
+ const value = leaf.translatable && translations.has(leaf.id) ? translations.get(leaf.id) : leaf.value;
153
+ setPath(root, leaf.path, value);
154
+ }
155
+ return root;
156
+ }
157
+ function accumulateUsage(target, source) {
158
+ if (!source) {
159
+ return;
160
+ }
161
+ target.inputTokens += source.inputTokens;
162
+ target.outputTokens += source.outputTokens;
163
+ }
164
+ async function translateOne(translator, from, to, value, usage, callCounter) {
165
+ for (let attempt = 0; attempt <= contants_js_1.MAX_RETRIES; attempt++) {
166
+ if (attempt > 0) {
167
+ await (0, utilites_js_1.delay)(contants_js_1.BASE_RETRY_DELAY_MS * Math.pow(2, attempt - 1));
168
+ }
169
+ try {
170
+ callCounter.count += 1;
171
+ const response = await translator.translate(buildSinglePrompt(from, to, value));
172
+ accumulateUsage(usage, response.usage);
173
+ const trimmed = response.text.trim();
174
+ if (trimmed.length > 0) {
175
+ return trimmed;
176
+ }
177
+ }
178
+ catch {
179
+ if (attempt === contants_js_1.MAX_RETRIES) {
180
+ return null;
181
+ }
182
+ }
183
+ }
184
+ return null;
185
+ }
186
+ async function runBatchAttempts(batchLeaves, translator, from, to, label, translations, usage, callCounter) {
187
+ let remaining = [...batchLeaves];
188
+ let firstAttempt = true;
189
+ for (let attempt = 0; attempt <= contants_js_1.MAX_RETRIES; attempt++) {
190
+ if (attempt > 0) {
191
+ const backoffMs = contants_js_1.BASE_RETRY_DELAY_MS * Math.pow(2, attempt - 1);
192
+ logger_js_1.logger.warn(`${label} Retry ${attempt}/${contants_js_1.MAX_RETRIES} after ${backoffMs}ms backoff (${remaining.length} entries)...`);
193
+ await (0, utilites_js_1.delay)(backoffMs);
194
+ }
195
+ try {
196
+ const prompt = buildBatchPrompt(from, to, remaining);
197
+ callCounter.count += 1;
198
+ const response = await translator.translate(prompt);
199
+ accumulateUsage(usage, response.usage);
200
+ const text = response.text;
201
+ if (!text || text.trim().length === 0) {
202
+ if (attempt === contants_js_1.MAX_RETRIES) {
203
+ return remaining;
204
+ }
205
+ logger_js_1.logger.warn(`${label} Attempt ${attempt + 1} returned empty response`);
206
+ continue;
207
+ }
208
+ const decoded = decodeResponse(text);
209
+ const stillMissing = [];
210
+ for (const leaf of remaining) {
211
+ const value = decoded.get(leaf.id);
212
+ if (!value || value.trim().length === 0) {
213
+ stillMissing.push(leaf);
214
+ }
215
+ else {
216
+ translations.set(leaf.id, value);
217
+ }
218
+ }
219
+ if (stillMissing.length === 0) {
220
+ return [];
221
+ }
222
+ if (firstAttempt && stillMissing.length >= remaining.length * contants_js_1.PER_LEAF_FALLBACK_RATIO) {
223
+ logger_js_1.logger.warn(`${label} Batch mode unreliable for this model (${stillMissing.length}/${remaining.length} missing on first attempt), switching to per-entry mode`);
224
+ return stillMissing;
225
+ }
226
+ logger_js_1.logger.warn(`${label} ${stillMissing.length}/${remaining.length} entries missing, will retry`);
227
+ firstAttempt = false;
228
+ remaining = stillMissing;
229
+ }
230
+ catch (error) {
231
+ const message = error instanceof Error ? error.message : String(error);
232
+ if (attempt === contants_js_1.MAX_RETRIES) {
233
+ logger_js_1.logger.warn(`${label} Batch attempt failed after retries: ${message}`);
234
+ return remaining;
235
+ }
236
+ logger_js_1.logger.warn(`${label} Attempt ${attempt + 1} failed: ${message}`);
237
+ }
238
+ }
239
+ return remaining;
240
+ }
241
+ async function runPerLeafFallback(leaves, translator, from, to, options, label, translations, usage, callCounter) {
242
+ logger_js_1.logger.info(`${label} Per-entry fallback for ${leaves.length} entries`);
243
+ const failed = [];
244
+ for (let i = 0; i < leaves.length; i++) {
245
+ if (i > 0 && !options.noLimit) {
246
+ await (0, utilites_js_1.delay)(contants_js_1.INTER_LEAF_DELAY_MS);
247
+ }
248
+ const leaf = leaves[i];
249
+ const result = await translateOne(translator, from, to, String(leaf.value), usage, callCounter);
250
+ if (result) {
251
+ translations.set(leaf.id, result);
252
+ }
253
+ else {
254
+ logger_js_1.logger.warn(`${label} Per-entry failed for id=${leaf.id}`);
255
+ failed.push(leaf);
256
+ }
257
+ }
258
+ return failed;
259
+ }
260
+ async function runBatches(batches, translator, from, to, options) {
261
+ const translations = new Map();
262
+ const failedIds = [];
263
+ const usage = { inputTokens: 0, outputTokens: 0 };
264
+ const callCounter = { count: 0 };
265
+ for (let i = 0; i < batches.length; i++) {
266
+ const batch = batches[i];
267
+ const label = `[Batch ${batch.index + 1}/${batches.length}]`;
268
+ if (i > 0 && !options.noLimit) {
269
+ logger_js_1.logger.info(`Waiting ${contants_js_1.INTER_BATCH_DELAY_MS}ms before next batch (rate limit protection)...`);
270
+ await (0, utilites_js_1.delay)(contants_js_1.INTER_BATCH_DELAY_MS);
271
+ }
272
+ const missingAfterBatch = await runBatchAttempts(batch.leaves, translator, from, to, label, translations, usage, callCounter);
273
+ let stillFailed = [];
274
+ if (missingAfterBatch.length > 0) {
275
+ stillFailed = await runPerLeafFallback(missingAfterBatch, translator, from, to, options, label, translations, usage, callCounter);
276
+ }
277
+ const succeeded = batch.leaves.length - stillFailed.length;
278
+ if (stillFailed.length === 0) {
279
+ logger_js_1.logger.info(`${label} Translated successfully (${(0, utilites_js_1.formatBytes)(batch.byteSize)}, ${succeeded} entries)`);
280
+ }
281
+ else {
282
+ logger_js_1.logger.error(`${label} ${stillFailed.length}/${batch.leaves.length} entries failed permanently`);
283
+ for (const leaf of stillFailed) {
284
+ failedIds.push(leaf.id);
285
+ }
286
+ }
287
+ }
288
+ if (failedIds.length > 0) {
289
+ const preview = failedIds.slice(0, 20).join(', ');
290
+ const more = failedIds.length > 20 ? `, …(+${failedIds.length - 20})` : '';
291
+ throw new Error(`Translation failed for ${failedIds.length} entry/entries (ids: ${preview}${more})`);
292
+ }
293
+ return { translations, usage, calls: callCounter.count };
294
+ }
@@ -1,4 +1,8 @@
1
1
  export type Provider = 'gemini' | 'openai' | 'anthropic';
2
+ export type TranslateOptions = {
3
+ noLimit: boolean;
4
+ noTimeout: boolean;
5
+ };
2
6
  export type TranslateArgs = {
3
7
  key?: string;
4
8
  provider?: string;
@@ -8,29 +12,70 @@ export type TranslateArgs = {
8
12
  from?: string;
9
13
  to?: string;
10
14
  url?: string;
15
+ config?: string;
16
+ stats?: boolean;
17
+ incremental?: boolean;
18
+ 'no-limit'?: boolean;
19
+ 'no-timeout'?: boolean;
20
+ 'max-batch-size'?: string;
11
21
  };
12
22
  export type ValidatedTranslateArgs = {
13
23
  key: string;
14
24
  provider: Provider;
15
25
  model?: string;
16
26
  input: string;
17
- output: string;
27
+ output: string[];
18
28
  from: string;
19
- to: string;
29
+ to: string[];
20
30
  url?: string;
31
+ noLimit: boolean;
32
+ noTimeout: boolean;
33
+ maxBatchBytes: number;
34
+ stats: boolean;
35
+ incremental: boolean;
21
36
  };
22
- export interface Translatable {
23
- chunks: ChunkInfo[];
24
- from: string;
25
- to: string;
26
- translate(): Promise<string>;
37
+ export type GlottoConfig = {
38
+ key?: string;
39
+ provider?: Provider;
40
+ model?: string;
41
+ input?: string;
42
+ output?: string | string[];
43
+ from?: string;
44
+ to?: string | string[];
45
+ url?: string;
46
+ noLimit?: boolean;
47
+ noTimeout?: boolean;
48
+ maxBatchSize?: number;
49
+ stats?: boolean;
50
+ incremental?: boolean;
51
+ };
52
+ export type JsonValue = string | number | boolean | null | JsonObject | JsonArray;
53
+ export interface JsonObject {
54
+ [key: string]: JsonValue;
27
55
  }
28
- export type JsonObject = Record<string, any>;
29
- export type Chunk = Uint8Array;
30
- export type ChunkInfo = {
31
- data: Uint8Array;
32
- keyCount: number;
33
- byteSize: number;
56
+ export type JsonArray = JsonValue[];
57
+ export type PathSegment = string | number;
58
+ export type Path = PathSegment[];
59
+ export type Leaf = {
60
+ id: number;
61
+ path: Path;
62
+ value: JsonValue;
63
+ translatable: boolean;
64
+ };
65
+ export type Batch = {
34
66
  index: number;
67
+ leaves: Leaf[];
68
+ byteSize: number;
35
69
  };
70
+ export type TranslateUsage = {
71
+ inputTokens: number;
72
+ outputTokens: number;
73
+ };
74
+ export type TranslateResult = {
75
+ text: string;
76
+ usage?: TranslateUsage;
77
+ };
78
+ export interface TextTranslator {
79
+ translate(prompt: string): Promise<TranslateResult>;
80
+ }
36
81
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEzD,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE7C,MAAM,MAAM,KAAK,GAAG,UAAU,CAAC;AAE/B,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,UAAU,CAAC;IAEjB,QAAQ,EAAE,MAAM,CAAC;IAEjB,QAAQ,EAAE,MAAM,CAAC;IAEjB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/src/types.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,5 @@
1
1
  import type { TranslateArgs, ValidatedTranslateArgs } from './types.js';
2
- import type { Args } from '../deps/jsr.io/@std/cli/1.0.29/mod.js';
3
- export declare const validateArgs: (args: Args<TranslateArgs>) => ValidatedTranslateArgs;
4
- export declare const generatePrompts: (from: string, to: string) => {
5
- systemPrompt: string;
6
- userPrompt: string;
7
- };
8
- export declare const stripJsonMarkdown: (text: string) => string;
9
- export declare const isValidJson: (value: string) => boolean;
10
- export declare const formatBytes: (bytes: number) => string;
11
- export declare const delay: (ms: number) => Promise<void>;
2
+ export declare function validateArgs(args: TranslateArgs): ValidatedTranslateArgs;
3
+ export declare function formatBytes(bytes: number): string;
4
+ export declare function delay(ms: number): Promise<void>;
12
5
  //# sourceMappingURL=utilites.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utilites.d.ts","sourceRoot":"","sources":["../../src/src/utilites.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,aAAa,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uCAAuC,CAAC;AAElE,eAAO,MAAM,YAAY,GAAI,MAAM,IAAI,CAAC,aAAa,CAAC,KAAG,sBAmCxD,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,IAAI,MAAM;;;CA2DvD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,MAyDhD,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,KAAG,OAO3C,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,KAAG,MAI3C,CAAC;AAEF,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,KAAG,OAAO,CAAC,IAAI,CAE9C,CAAC"}
1
+ {"version":3,"file":"utilites.d.ts","sourceRoot":"","sources":["../../src/src/utilites.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,aAAa,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAOlF,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,sBAAsB,CA0DxE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQjD;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}