@thor123141245r/ai-translate 0.0.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 (57) hide show
  1. package/.agentdocs/code-changes/2026-01-22/AI/347/277/273/350/257/221/345/231/250TS/345/256/236/347/216/260-/345/256/236/347/216/260.md +22 -0
  2. package/.agentdocs/code-changes/2026-01-23/CLI/345/210/206/345/217/221-npx/345/256/236/347/216/260.md +18 -0
  3. package/.agentdocs/code-changes/2026-01-23/sora-watermask-remover-/345/233/275/351/231/205/345/214/226/347/277/273/350/257/221-/345/256/236/347/216/260.md +37 -0
  4. package/.agentdocs/code-changes/2026-01-23//351/205/215/347/275/256/350/257/273/345/217/226-/347/216/257/345/242/203/345/217/230/351/207/217/344/274/230/345/205/210-/345/256/236/347/216/260.md +22 -0
  5. package/.agentdocs/plans/2026-01-22/AI/347/277/273/350/257/221/345/231/250TS/345/256/236/347/216/260-/344/274/230/345/214/226/346/226/271/346/241/210.md +67 -0
  6. package/.agentdocs/plans/2026-01-23/CLI/345/210/206/345/217/221-npx/346/226/271/346/241/210.md +60 -0
  7. package/.agentdocs/plans/2026-01-23/sora-watermask-remover-/345/233/275/351/231/205/345/214/226/347/277/273/350/257/221-/344/274/230/345/214/226/346/226/271/346/241/210.md +51 -0
  8. package/.agentdocs/plans/2026-01-23//351/205/215/347/275/256/350/257/273/345/217/226-/347/216/257/345/242/203/345/217/230/351/207/217/344/274/230/345/205/210-/344/274/230/345/214/226/346/226/271/346/241/210.md +80 -0
  9. package/README.md +120 -0
  10. package/SKILL.md +103 -0
  11. package/dist/asyncTransform.d.ts +7 -0
  12. package/dist/asyncTransform.d.ts.map +1 -0
  13. package/dist/asyncTransform.js +23 -0
  14. package/dist/asyncTransform.js.map +1 -0
  15. package/dist/bin/ai-translate.d.ts +3 -0
  16. package/dist/bin/ai-translate.d.ts.map +1 -0
  17. package/dist/bin/ai-translate.js +4 -0
  18. package/dist/bin/ai-translate.js.map +1 -0
  19. package/dist/cli.d.ts +7 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +259 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +4 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/logger.d.ts +3 -0
  28. package/dist/logger.d.ts.map +1 -0
  29. package/dist/logger.js +3 -0
  30. package/dist/logger.js.map +1 -0
  31. package/dist/model.d.ts +29 -0
  32. package/dist/model.d.ts.map +1 -0
  33. package/dist/model.js +103 -0
  34. package/dist/model.js.map +1 -0
  35. package/dist/prompt.d.ts +12 -0
  36. package/dist/prompt.d.ts.map +1 -0
  37. package/dist/prompt.js +51 -0
  38. package/dist/prompt.js.map +1 -0
  39. package/dist/split.d.ts +27 -0
  40. package/dist/split.d.ts.map +1 -0
  41. package/dist/split.js +87 -0
  42. package/dist/split.js.map +1 -0
  43. package/dist/utils.d.ts +7 -0
  44. package/dist/utils.d.ts.map +1 -0
  45. package/dist/utils.js +14 -0
  46. package/dist/utils.js.map +1 -0
  47. package/package.json +42 -0
  48. package/src/asyncTransform.ts +31 -0
  49. package/src/bin/ai-translate.ts +5 -0
  50. package/src/cli.ts +313 -0
  51. package/src/index.ts +9 -0
  52. package/src/logger.ts +3 -0
  53. package/src/model.ts +139 -0
  54. package/src/prompt.ts +71 -0
  55. package/src/split.ts +111 -0
  56. package/src/utils.ts +15 -0
  57. package/tsconfig.json +19 -0
package/dist/cli.js ADDED
@@ -0,0 +1,259 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { pipeline } from 'node:stream/promises';
4
+ import { initProcLog } from 'debug-level';
5
+ import { AppConfig, StringSchema, v } from '@commenthol/app-config';
6
+ import { logger } from './logger.js';
7
+ import { modelFactory, AiTranslateTransform } from './model.js';
8
+ import { TextSplitterStream, recursiveChunkTextSplitter, getFormatByExtension } from './split.js';
9
+ const log = logger('cli');
10
+ const help = {};
11
+ help._ = `
12
+ AI Translator
13
+
14
+ Usage:
15
+ ai-translate [flags]
16
+ ai-translate [command] [flags]
17
+
18
+ Commands:
19
+ set set config value
20
+
21
+ Flags:
22
+ -h, --help Help for ai-translate
23
+ -v, --version Show version information
24
+ -c, --config DIR Use config file .ai-translate.json in DIR
25
+ -f, --from LANG Source language
26
+ -t, --to LANG Target language; LANG is English language name or
27
+ supported BCP47 codes (ar, de, en, es, fr, ja, pt, ru,
28
+ vi, zh-CN, zh-TW)
29
+ -i, --input FILE input file
30
+ -o, --output FILE output file
31
+ --format FORMAT specify input format (cpp, go, java, js, php, proto,
32
+ python, rst, ruby, rust, scala, swift, markdown, latex,
33
+ html, sol)
34
+ Examples:
35
+ Translate input.md from Spanish to output.md in English
36
+ ai-translate -f Spanish -t English -i input.md -o output.md
37
+
38
+ Pipe from stdin to stdout using the config in the local folder
39
+ echo "translate" | ai-translate -f en -t en -c .
40
+
41
+ Use "ai-translate [command] --help" for more information about a command.
42
+ `;
43
+ help.set = `
44
+ Set ai-translate configuration
45
+
46
+ Writes config to \`.ai-translate.json\`
47
+ If --config flag is omitted then global config is used.
48
+
49
+ Usage:
50
+ ai-translate [flags] set KEY VALUE
51
+
52
+ Flags:
53
+ -c, --config DIR Use config file .ai-translate.json in DIR
54
+
55
+ Available KEYs:
56
+ provider set provider (ollama, mistral, anthropic, openai, deepseek);
57
+ default="ollama"
58
+ model set model from provider; default="qwen2.5:7b"
59
+ apiKey set api key
60
+ baseUrl baseUrl for model
61
+ temperature model temperature; default=0.1
62
+ maxRetries max. number of retries; default=10
63
+ chunkSize number of chunks used in text-splitter; default=1000
64
+ `;
65
+ const PACKAGE_JSON = '../package.json';
66
+ const APP = 'ai-translate';
67
+ const CONF_FILE = `.${APP}.json`;
68
+ const DEFAULT_LANG = 'en';
69
+ const commands = {
70
+ set: (c, argv) => {
71
+ const key = nextArg(argv);
72
+ const value = nextArg(argv);
73
+ c.set = [key, value];
74
+ }
75
+ };
76
+ const flags = {
77
+ '--help': (f) => (f.help = true),
78
+ '--version': (f) => (f.version = true),
79
+ '--config': (f, argv) => {
80
+ const dir = nextArg(argv);
81
+ if (dir)
82
+ f.config = path.resolve(process.cwd(), dir);
83
+ },
84
+ '--from': (f, argv) => {
85
+ const lang = nextArg(argv);
86
+ f.sourceLanguage = lang || DEFAULT_LANG;
87
+ },
88
+ '--to': (f, argv) => {
89
+ const lang = nextArg(argv);
90
+ f.targetLanguage = lang || DEFAULT_LANG;
91
+ },
92
+ '--input': (f, argv) => {
93
+ const filename = nextArg(argv);
94
+ if (filename)
95
+ f.input = path.resolve(process.cwd(), filename);
96
+ },
97
+ '--output': (f, argv) => {
98
+ const filename = nextArg(argv);
99
+ if (filename)
100
+ f.output = path.resolve(process.cwd(), filename);
101
+ },
102
+ '--format': (f, argv) => {
103
+ const format = nextArg(argv);
104
+ if (format)
105
+ f.format = format;
106
+ }
107
+ };
108
+ flags['-h'] = flags['--help'];
109
+ flags['-v'] = flags['--version'];
110
+ flags['-c'] = flags['--config'];
111
+ flags['-f'] = flags['--from'];
112
+ flags['-t'] = flags['--to'];
113
+ flags['-i'] = flags['--input'];
114
+ flags['-o'] = flags['--output'];
115
+ export const argvParse = (args) => {
116
+ initProcLog();
117
+ const argv = args || process.argv.slice(2);
118
+ log.debug(argv);
119
+ const opts = {
120
+ sourceLanguage: 'en',
121
+ targetLanguage: 'en'
122
+ };
123
+ const cmd = {};
124
+ while (argv.length) {
125
+ const arg = argv.shift();
126
+ if (!arg)
127
+ continue;
128
+ if (commands[arg]) {
129
+ commands[arg](cmd, argv);
130
+ }
131
+ else if (flags[arg]) {
132
+ flags[arg](opts, argv);
133
+ }
134
+ }
135
+ return { cmd, opts };
136
+ };
137
+ const nextArg = (argv) => {
138
+ const next = argv[0] || '';
139
+ if (next.indexOf('-') === 0) {
140
+ return;
141
+ }
142
+ return argv.shift();
143
+ };
144
+ let _console = console;
145
+ export const _injectConsole = (obj) => {
146
+ _console = obj;
147
+ };
148
+ const displayError = (msg) => {
149
+ _console.error(`ERROR: ${msg}`);
150
+ };
151
+ const display = (msg) => _console.log(msg);
152
+ const version = () => {
153
+ const packageJson = new URL(PACKAGE_JSON, import.meta.url);
154
+ const { version: pkgVersion } = JSON.parse(fs.readFileSync(packageJson, 'utf-8'));
155
+ display(pkgVersion);
156
+ };
157
+ const schema = {
158
+ provider: StringSchema,
159
+ model: StringSchema,
160
+ apiKey: StringSchema,
161
+ baseUrl: StringSchema,
162
+ temperature: v.pipe(v.string(), v.transform(Number), v.minValue(0), v.maxValue(2)),
163
+ maxRetries: v.pipe(v.string(), v.transform(Number), v.integer(), v.minValue(0), v.maxValue(99)),
164
+ chunkSize: v.pipe(v.string(), v.transform(Number), v.integer(), v.minValue(100), v.maxValue(200e3))
165
+ };
166
+ const PROVIDER_API_KEY_ENV = {
167
+ openai: 'OPENAI_API_KEY',
168
+ anthropic: 'ANTHROPIC_API_KEY',
169
+ mistral: 'MISTRAL_API_KEY',
170
+ deepseek: 'DEEPSEEK_API_KEY'
171
+ };
172
+ const PROVIDER_BASE_URL_ENV = {
173
+ openai: 'OPENAI_BASE_URL',
174
+ anthropic: 'ANTHROPIC_BASE_URL',
175
+ mistral: 'MISTRAL_BASE_URL',
176
+ deepseek: 'DEEPSEEK_BASE_URL',
177
+ ollama: 'OLLAMA_BASE_URL'
178
+ };
179
+ const readEnv = (key) => {
180
+ if (!key)
181
+ return;
182
+ const value = process.env[key];
183
+ if (!value)
184
+ return;
185
+ const trimmed = value.trim();
186
+ return trimmed ? trimmed : undefined;
187
+ };
188
+ const pickFirst = (...values) => values.find((value) => value && value.length > 0);
189
+ const resolveRuntimeConfig = (config) => {
190
+ const provider = String(config.provider || 'ollama');
191
+ const envApiKey = pickFirst(readEnv('AI_TRANSLATE_API_KEY'), readEnv(PROVIDER_API_KEY_ENV[provider]));
192
+ const envBaseUrl = pickFirst(readEnv('AI_TRANSLATE_BASE_URL'), readEnv(PROVIDER_BASE_URL_ENV[provider]));
193
+ return {
194
+ ...config,
195
+ ...(envApiKey ? { apiKey: envApiKey } : {}),
196
+ ...(envBaseUrl ? { baseUrl: envBaseUrl } : {})
197
+ };
198
+ };
199
+ export const cli = async (args) => {
200
+ const { cmd, opts } = argvParse(args);
201
+ const command = Object.keys(cmd)[0];
202
+ log.debug({ cmd, opts });
203
+ const filename = !opts.config
204
+ ? CONF_FILE
205
+ : fs.lstatSync(String(opts.config)).isDirectory()
206
+ ? path.resolve(String(opts.config), CONF_FILE)
207
+ : String(opts.config);
208
+ const appConf = new AppConfig({ appName: APP, schema, filename });
209
+ await appConf.read().catch(() => null);
210
+ try {
211
+ if (opts.version) {
212
+ version();
213
+ return;
214
+ }
215
+ if (opts.help) {
216
+ const helpText = help[command || ''] || help._;
217
+ display(helpText);
218
+ return;
219
+ }
220
+ if (cmd.set) {
221
+ const [key, value] = cmd.set;
222
+ if (key) {
223
+ appConf.set(key, value);
224
+ await appConf.write();
225
+ }
226
+ else {
227
+ display(JSON.stringify(appConf.config, null, 2));
228
+ }
229
+ return;
230
+ }
231
+ const sourceLanguage = String(opts.sourceLanguage || DEFAULT_LANG);
232
+ const targetLanguage = String(opts.targetLanguage || DEFAULT_LANG);
233
+ const reader = opts.input ? fs.createReadStream(String(opts.input)) : process.stdin;
234
+ const writer = opts.output ? fs.createWriteStream(String(opts.output)) : process.stdout;
235
+ const runtimeConfig = resolveRuntimeConfig(appConf.config);
236
+ const model = modelFactory(runtimeConfig);
237
+ const lcNamespace = model.lc_namespace || {};
238
+ const lcKwargs = model.lc_kwargs || {};
239
+ const { apiKey: _apiKey, ...modelParams } = { ...lcNamespace, ...lcKwargs };
240
+ log.debug(modelParams);
241
+ const format = opts.format ||
242
+ getFormatByExtension(path.extname(String(opts.input || '_.md')));
243
+ const chunkSize = runtimeConfig.chunkSize || 1000;
244
+ const textSplitter = recursiveChunkTextSplitter({ chunkSize, format });
245
+ const splitter = new TextSplitterStream({ textSplitter });
246
+ const translator = new AiTranslateTransform({
247
+ ...opts,
248
+ sourceLanguage,
249
+ targetLanguage,
250
+ model
251
+ });
252
+ await pipeline(reader, splitter, translator, writer);
253
+ }
254
+ catch (err) {
255
+ log.debug(err);
256
+ displayError(err.message);
257
+ }
258
+ };
259
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { AiTranslateTransform, modelFactory } from './model.js';
2
+ export { promptInvoke, languages } from './prompt.js';
3
+ export { TextSplitterStream, recursiveChunkTextSplitter, getFormatByExtension } from './split.js';
4
+ export type { Metadata, ModelFactoryOptions } from './model.js';
5
+ export type { TextSplitterParams, Separator } from './split.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,oBAAoB,EACrB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAC/D,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { AiTranslateTransform, modelFactory } from './model.js';
2
+ export { promptInvoke, languages } from './prompt.js';
3
+ export { TextSplitterStream, recursiveChunkTextSplitter, getFormatByExtension } from './split.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,oBAAoB,EACrB,MAAM,YAAY,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { ProcLog } from 'debug-level';
2
+ export declare const logger: (namespace: string) => ProcLog;
3
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAErC,eAAO,MAAM,MAAM,GAAI,WAAW,MAAM,YAA6C,CAAA"}
package/dist/logger.js ADDED
@@ -0,0 +1,3 @@
1
+ import { ProcLog } from 'debug-level';
2
+ export const logger = (namespace) => new ProcLog(`ai-translate:${namespace}`);
3
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAErC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,SAAiB,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,gBAAgB,SAAS,EAAE,CAAC,CAAA"}
@@ -0,0 +1,29 @@
1
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import { AsyncTransform } from './asyncTransform.js';
3
+ export type Metadata = {
4
+ inputTokens: number;
5
+ outputTokens: number;
6
+ };
7
+ export type ModelFactoryOptions = {
8
+ provider?: 'ollama' | 'mistral' | 'anthropic' | 'openai' | 'deepseek';
9
+ [key: string]: unknown;
10
+ };
11
+ export declare const modelFactory: (modelOpts?: ModelFactoryOptions) => BaseChatModel;
12
+ export declare class AiTranslateTransform extends AsyncTransform {
13
+ private readonly _model;
14
+ private readonly _promptOpts;
15
+ private _metadata;
16
+ constructor(options: {
17
+ model: BaseChatModel;
18
+ format?: string;
19
+ sourceLanguage: string;
20
+ targetLanguage: string;
21
+ [key: string]: unknown;
22
+ });
23
+ getMetadata(): {
24
+ inputTokens: number;
25
+ outputTokens: number;
26
+ };
27
+ protected _asyncTransform(chunk: Buffer | object, encoding: BufferEncoding | 'buffer'): Promise<boolean>;
28
+ }
29
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAA;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAapD,MAAM,MAAM,QAAQ,GAAG;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAA;IACrE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,YAAY,mBAAmB,KAAG,aAuD9D,CAAA;AAED,qBAAa,oBAAqB,SAAQ,cAAc;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAI3B;IACD,OAAO,CAAC,SAAS,CAAgD;gBAErD,OAAO,EAAE;QACnB,KAAK,EAAE,aAAa,CAAA;QACpB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,cAAc,EAAE,MAAM,CAAA;QACtB,cAAc,EAAE,MAAM,CAAA;QACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KACvB;IAOD,WAAW;qBAxFE,MAAM;sBACL,MAAM;;cA2FJ,eAAe,CAC7B,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,QAAQ,EAAE,cAAc,GAAG,QAAQ;CAwBtC"}
package/dist/model.js ADDED
@@ -0,0 +1,103 @@
1
+ import { ChatOllama } from '@langchain/ollama';
2
+ import { ChatMistralAI } from '@langchain/mistralai';
3
+ import { ChatAnthropic } from '@langchain/anthropic';
4
+ import { ChatOpenAI } from '@langchain/openai';
5
+ import { ChatDeepSeek } from '@langchain/deepseek';
6
+ import { AsyncTransform } from './asyncTransform.js';
7
+ import { promptInvoke, replaceMarkerSymbol } from './prompt.js';
8
+ import { logger } from './logger.js';
9
+ import { isWhiteSpace, preserveWhiteSpace } from './utils.js';
10
+ const log = logger('model');
11
+ const DEFAULT = {
12
+ temperature: 0.1,
13
+ maxRetries: 10,
14
+ maxConcurrency: 1
15
+ };
16
+ export const modelFactory = (modelOpts) => {
17
+ const { provider = 'ollama', ...other } = modelOpts || {};
18
+ const apiKeyValue = typeof other.apiKey === 'string' ? other.apiKey.trim() : '';
19
+ const baseUrlValue = typeof other.baseUrl === 'string' ? other.baseUrl.trim() : '';
20
+ const apiKey = apiKeyValue ? apiKeyValue : undefined;
21
+ const baseUrl = baseUrlValue ? baseUrlValue : undefined;
22
+ const filtered = { ...other };
23
+ if ('apiKey' in filtered) {
24
+ delete filtered.apiKey;
25
+ }
26
+ if ('baseUrl' in filtered) {
27
+ delete filtered.baseUrl;
28
+ }
29
+ switch (provider) {
30
+ case 'ollama':
31
+ return new ChatOllama({
32
+ ...DEFAULT,
33
+ model: 'qwen2.5:7b',
34
+ ...(baseUrl ? { baseUrl } : {}),
35
+ ...filtered
36
+ });
37
+ case 'mistral':
38
+ return new ChatMistralAI({
39
+ ...DEFAULT,
40
+ model: 'ministral-8b',
41
+ ...(apiKey ? { apiKey } : {}),
42
+ ...filtered
43
+ });
44
+ case 'anthropic':
45
+ return new ChatAnthropic({
46
+ ...DEFAULT,
47
+ model: 'claude-3-5-haiku-20241022',
48
+ ...(apiKey ? { apiKey } : {}),
49
+ ...filtered
50
+ });
51
+ case 'openai':
52
+ return new ChatOpenAI({
53
+ ...DEFAULT,
54
+ model: 'gpt-4o-mini',
55
+ ...(apiKey ? { apiKey } : {}),
56
+ ...(baseUrl ? { configuration: { baseURL: baseUrl } } : {}),
57
+ ...filtered
58
+ });
59
+ case 'deepseek':
60
+ return new ChatDeepSeek({
61
+ ...DEFAULT,
62
+ model: 'deepseek-reasoner',
63
+ ...(apiKey ? { apiKey } : {}),
64
+ ...(baseUrl ? { configuration: { baseURL: baseUrl } } : {}),
65
+ ...filtered
66
+ });
67
+ default:
68
+ throw new Error(`unsupported provider=${provider}`);
69
+ }
70
+ };
71
+ export class AiTranslateTransform extends AsyncTransform {
72
+ _model;
73
+ _promptOpts;
74
+ _metadata = { inputTokens: 0, outputTokens: 0 };
75
+ constructor(options) {
76
+ const { model, format, sourceLanguage, targetLanguage, ...rest } = options;
77
+ super(rest);
78
+ this._model = model;
79
+ this._promptOpts = { format, sourceLanguage, targetLanguage };
80
+ }
81
+ getMetadata() {
82
+ return { ...this._metadata };
83
+ }
84
+ async _asyncTransform(chunk, encoding) {
85
+ const text = AsyncTransform.toString(chunk, encoding);
86
+ if (isWhiteSpace(text)) {
87
+ return !this.push(text);
88
+ }
89
+ log.debug('inp=%j', text);
90
+ const messages = await promptInvoke({ ...this._promptOpts, text });
91
+ const result = await this._model.invoke(messages);
92
+ log.debug('out=%j', result.content);
93
+ const usage = result
94
+ .usage_metadata;
95
+ const inputTokens = usage?.input_tokens ?? 0;
96
+ const outputTokens = usage?.output_tokens ?? 0;
97
+ this.emit('metadata', { inputTokens, outputTokens });
98
+ this._metadata.inputTokens += inputTokens;
99
+ this._metadata.outputTokens += outputTokens;
100
+ return !this.push(preserveWhiteSpace(text, replaceMarkerSymbol(result.content)));
101
+ }
102
+ }
103
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ChatPromptValueInterface } from '@langchain/core/prompt_values';
2
+ import type { MessageContent } from '@langchain/core/messages';
3
+ export declare const languages: Record<string, string>;
4
+ export declare const getLanguageName: (lang: string) => string;
5
+ export declare const promptInvoke: ({ format, sourceLanguage, targetLanguage, text }: {
6
+ format?: string;
7
+ sourceLanguage: string;
8
+ targetLanguage: string;
9
+ text: string;
10
+ }) => Promise<ChatPromptValueInterface>;
11
+ export declare const replaceMarkerSymbol: (text: MessageContent) => string;
12
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAC7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAK9D,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAY5C,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,WAA4B,CAAA;AAyBxE,eAAO,MAAM,YAAY,GAAI,kDAK1B;IACD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;CACb,KAAG,OAAO,CAAC,wBAAwB,CAMhC,CAAA;AAEJ,eAAO,MAAM,mBAAmB,GAAI,MAAM,cAAc,WAMvD,CAAA"}
package/dist/prompt.js ADDED
@@ -0,0 +1,51 @@
1
+ import { ChatPromptTemplate } from '@langchain/core/prompts';
2
+ import { logger } from './logger.js';
3
+ const log = logger('prompt');
4
+ export const languages = {
5
+ ar: 'Arabic',
6
+ de: 'German',
7
+ en: 'English',
8
+ es: 'Spanish',
9
+ fr: 'French',
10
+ ja: 'Japanese',
11
+ pt: 'Portuguese',
12
+ ru: 'Russian',
13
+ vi: 'Vietnamese',
14
+ 'zh-CN': 'Chinese-simplified',
15
+ 'zh-TW': 'Chinese-traditional'
16
+ };
17
+ export const getLanguageName = (lang) => languages[lang] || lang;
18
+ const systemPrompt = 'You are an AI-driven advanced translation system, specifically designed to ' +
19
+ 'translate structured and technical documents. ' +
20
+ 'You will receive a text snippet from a file formatted as "{format}"\n\n' +
21
+ 'Your task is to **accurately translate** the text enclosed between the 🔤 ' +
22
+ 'symbols from "{sourceLanguage}" to "{targetLanguage}". ' +
23
+ 'Preserve the original formatting, sentence structure, and terminology. ' +
24
+ 'Ensure that every word and sentence is translated as closely as possible to ' +
25
+ 'the original meaning, without summarizing or omitting any part of the content. ' +
26
+ 'The translation must be faithful, detailed, and maintain the original length ' +
27
+ 'and complexity. ' +
28
+ 'Deliver the translation exactly as required, without any additional ' +
29
+ 'commentary or explanation, and ensure the 🔤 symbols are removed in the final output.\n\n' +
30
+ 'Remember: your job is to **translate** the text exactly as it is, without ' +
31
+ 'adding summaries or changing the content in any way. ' +
32
+ 'Do not skip or modify any part of the text. Ensure that the output is a ' +
33
+ 'direct translation, and that the original structure and meaning are preserved.';
34
+ const promptTemplate = ChatPromptTemplate.fromMessages([
35
+ ['system', systemPrompt],
36
+ ['user', '🔤{text}🔤']
37
+ ]);
38
+ export const promptInvoke = ({ format = 'markdown', sourceLanguage, targetLanguage, text = '' }) => promptTemplate.invoke({
39
+ format,
40
+ sourceLanguage: getLanguageName(sourceLanguage),
41
+ targetLanguage: getLanguageName(targetLanguage),
42
+ text
43
+ });
44
+ export const replaceMarkerSymbol = (text) => {
45
+ if (typeof text === 'string') {
46
+ return text.replace(/^\s*🔤/, '').replace(/🔤\s*$/, '');
47
+ }
48
+ log.error(text);
49
+ return '';
50
+ };
51
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAG5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;AAE5B,MAAM,CAAC,MAAM,SAAS,GAA2B;IAC/C,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,UAAU;IACd,EAAE,EAAE,YAAY;IAChB,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,YAAY;IAChB,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,qBAAqB;CAC/B,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,CAAA;AAExE,MAAM,YAAY,GAChB,6EAA6E;IAC7E,gDAAgD;IAChD,yEAAyE;IACzE,4EAA4E;IAC5E,yDAAyD;IACzD,yEAAyE;IACzE,8EAA8E;IAC9E,iFAAiF;IACjF,+EAA+E;IAC/E,kBAAkB;IAClB,sEAAsE;IACtE,2FAA2F;IAC3F,4EAA4E;IAC5E,uDAAuD;IACvD,0EAA0E;IAC1E,gFAAgF,CAAA;AAElF,MAAM,cAAc,GAAG,kBAAkB,CAAC,YAAY,CAAC;IACrD,CAAC,QAAQ,EAAE,YAAY,CAAC;IACxB,CAAC,MAAM,EAAE,YAAY,CAAC;CACvB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,MAAM,GAAG,UAAU,EACnB,cAAc,EACd,cAAc,EACd,IAAI,GAAG,EAAE,EAMV,EAAqC,EAAE,CACtC,cAAc,CAAC,MAAM,CAAC;IACpB,MAAM;IACN,cAAc,EAAE,eAAe,CAAC,cAAc,CAAC;IAC/C,cAAc,EAAE,eAAe,CAAC,cAAc,CAAC;IAC/C,IAAI;CACL,CAAC,CAAA;AAEJ,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAoB,EAAE,EAAE;IAC1D,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IACzD,CAAC;IACD,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACf,OAAO,EAAE,CAAA;AACX,CAAC,CAAA"}
@@ -0,0 +1,27 @@
1
+ import { RecursiveCharacterTextSplitter } from '@langchain/textsplitters';
2
+ import type { RecursiveCharacterTextSplitterParams, SupportedTextSplitterLanguage } from '@langchain/textsplitters';
3
+ import { AsyncTransform } from './asyncTransform.js';
4
+ export type TextSplitterFormat = {
5
+ format?: SupportedTextSplitterLanguage;
6
+ };
7
+ export type TextSplitterParams = Partial<RecursiveCharacterTextSplitterParams> & TextSplitterFormat;
8
+ export type Separator = string | RegExp;
9
+ export type TextSplitterLike = {
10
+ splitText(text: string): Promise<string[]>;
11
+ };
12
+ export declare const getFormatByExtension: (extname: string) => SupportedTextSplitterLanguage | undefined;
13
+ export declare const recursiveChunkTextSplitter: (options?: TextSplitterParams) => RecursiveChunkTextSplitter;
14
+ export declare class RecursiveChunkTextSplitter extends RecursiveCharacterTextSplitter {
15
+ protected joinDocs(docs: string[], separator: string): string | null;
16
+ }
17
+ export declare class TextSplitterStream extends AsyncTransform {
18
+ private readonly _textSplitter;
19
+ private _documents;
20
+ private _buffer;
21
+ constructor(options?: {
22
+ textSplitter?: TextSplitterLike;
23
+ });
24
+ protected _asyncTransform(chunk: Buffer | object, encoding: BufferEncoding | 'buffer'): Promise<boolean>;
25
+ _flush(done: (error?: Error | null) => void): void;
26
+ }
27
+ //# sourceMappingURL=split.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../src/split.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAA;AACzE,OAAO,KAAK,EACV,oCAAoC,EACpC,6BAA6B,EAC9B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,MAAM,MAAM,kBAAkB,GAAG;IAAE,MAAM,CAAC,EAAE,6BAA6B,CAAA;CAAE,CAAA;AAC3E,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,oCAAoC,CAAC,GAC5E,kBAAkB,CAAA;AACpB,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAA;AACvC,MAAM,MAAM,gBAAgB,GAAG;IAAE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;CAAE,CAAA;AAsB7E,eAAO,MAAM,oBAAoB,GAC/B,SAAS,MAAM,KACd,6BAA6B,GAAG,SAUlC,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,UAAU,kBAAkB,+BAWtE,CAAA;AAGD,qBAAa,0BAA2B,SAAQ,8BAA8B;cACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAI9E;AAED,qBAAa,kBAAmB,SAAQ,cAAc;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkB;IAChD,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,OAAO,CAAQ;gBAEX,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,gBAAgB,CAAA;KAAE;cAQzC,eAAe,CAC7B,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,QAAQ,EAAE,cAAc,GAAG,QAAQ;IAoBrC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI;CAO5C"}
package/dist/split.js ADDED
@@ -0,0 +1,87 @@
1
+ import { RecursiveCharacterTextSplitter } from '@langchain/textsplitters';
2
+ import { AsyncTransform } from './asyncTransform.js';
3
+ const extensionsByFormat = {
4
+ cpp: ['.h', '.c', '.cpp'],
5
+ go: ['.go'],
6
+ java: ['.java'],
7
+ js: ['.js', '.cjs', '.mjs', '.jsx', '.ts', '.tsx'],
8
+ php: ['.php', '.inc'],
9
+ proto: ['.proto'],
10
+ python: ['.py'],
11
+ rst: ['.rst'],
12
+ ruby: ['.rb', '.gem'],
13
+ rust: ['.rs'],
14
+ scala: ['.scala', '.sc'],
15
+ swift: ['.swift'],
16
+ markdown: ['.md', '.markdown', '.mkdn'],
17
+ latex: ['.tex', '.latex', '.ltx'],
18
+ html: ['.html', '.htm', '.xhtml', '.shtml', '.asp', '.aspx', '.jsp']
19
+ };
20
+ let formatByExtension;
21
+ export const getFormatByExtension = (extname) => {
22
+ if (!formatByExtension) {
23
+ formatByExtension = {};
24
+ for (const [key, values] of Object.entries(extensionsByFormat)) {
25
+ for (const ext of values) {
26
+ formatByExtension[ext] = key;
27
+ }
28
+ }
29
+ }
30
+ return formatByExtension[extname];
31
+ };
32
+ export const recursiveChunkTextSplitter = (options) => {
33
+ const { format = 'markdown', ...rest } = options || {};
34
+ const separators = extensionsByFormat[format]
35
+ ? RecursiveCharacterTextSplitter.getSeparatorsForLanguage(format)
36
+ : ['\n\n', '\n', '.', ''];
37
+ return new RecursiveChunkTextSplitter({
38
+ chunkSize: 1000,
39
+ chunkOverlap: 0,
40
+ separators,
41
+ ...rest
42
+ });
43
+ };
44
+ // @ts-expect-error override joinDocs to preserve whitespace; upstream marks it private
45
+ export class RecursiveChunkTextSplitter extends RecursiveCharacterTextSplitter {
46
+ joinDocs(docs, separator) {
47
+ const text = docs.join(separator);
48
+ return text === '' ? null : text;
49
+ }
50
+ }
51
+ export class TextSplitterStream extends AsyncTransform {
52
+ _textSplitter;
53
+ _documents;
54
+ _buffer;
55
+ constructor(options) {
56
+ const { textSplitter } = options || {};
57
+ super();
58
+ this._textSplitter = textSplitter || recursiveChunkTextSplitter();
59
+ this._documents = [];
60
+ this._buffer = '';
61
+ }
62
+ async _asyncTransform(chunk, encoding) {
63
+ const text = AsyncTransform.toString(chunk, encoding);
64
+ this._buffer += text;
65
+ const documents = await this._textSplitter.splitText(this._buffer);
66
+ this._buffer = documents.pop() ?? '';
67
+ this._documents = this._documents.concat(documents);
68
+ while (this._documents.length) {
69
+ const document = this._documents.shift();
70
+ if (document === undefined)
71
+ break;
72
+ const wait = !this.push(document);
73
+ if (wait) {
74
+ return true;
75
+ }
76
+ }
77
+ return false;
78
+ }
79
+ _flush(done) {
80
+ for (const document of this._documents) {
81
+ this.push(document);
82
+ }
83
+ this.push(this._buffer);
84
+ done();
85
+ }
86
+ }
87
+ //# sourceMappingURL=split.js.map