locai 2.1.2 → 2.2.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 (80) hide show
  1. package/dist/cli.d.ts +2 -0
  2. package/dist/commands/review.d.ts +109 -0
  3. package/dist/commands/translator.d.ts +23 -0
  4. package/dist/config/index.d.ts +145 -0
  5. package/dist/core/adapters/base-adapter.d.ts +20 -0
  6. package/dist/core/adapters/factory.d.ts +16 -0
  7. package/dist/core/adapters/json-adapter.d.ts +9 -0
  8. package/dist/core/adapters/po-adapter.d.ts +9 -0
  9. package/dist/core/adapters/properties-adapter.d.ts +9 -0
  10. package/dist/core/adapters/yaml-adapter.d.ts +9 -0
  11. package/dist/core/context-processor.d.ts +81 -0
  12. package/dist/core/detection/framework-detector.d.ts +9 -0
  13. package/dist/core/detection/structure-detector.d.ts +9 -0
  14. package/dist/core/fallback-provider.d.ts +54 -0
  15. package/dist/core/orchestrator.d.ts +101 -0
  16. package/dist/core/pipeline/Pipeline.d.ts +23 -0
  17. package/dist/core/pipeline/PipelineStep.d.ts +18 -0
  18. package/dist/core/pipeline/context.d.ts +29 -0
  19. package/dist/core/pipeline/steps/CacheReadStep.d.ts +25 -0
  20. package/dist/core/pipeline/steps/CacheWriteStep.d.ts +11 -0
  21. package/dist/core/pipeline/steps/ConfidenceCheckStep.d.ts +10 -0
  22. package/dist/core/pipeline/steps/GlossaryPostStep.d.ts +9 -0
  23. package/dist/core/pipeline/steps/GlossaryPreStep.d.ts +9 -0
  24. package/dist/core/pipeline/steps/InputValidationStep.d.ts +8 -0
  25. package/dist/core/pipeline/steps/QualityCheckStep.d.ts +10 -0
  26. package/dist/core/pipeline/steps/ToneCheckStep.d.ts +13 -0
  27. package/dist/core/pipeline/steps/TranslationStep.d.ts +22 -0
  28. package/dist/core/pipeline/steps/VectorCacheReadStep.d.ts +17 -0
  29. package/dist/core/pipeline/steps/VectorCacheWriteStep.d.ts +11 -0
  30. package/dist/core/pipeline/steps/__tests__/ToneCheckStep.test.d.ts +1 -0
  31. package/dist/core/provider-factory.d.ts +41 -0
  32. package/dist/core/provider-factory.js +4 -0
  33. package/dist/providers/anthropic.d.ts +25 -0
  34. package/dist/providers/anthropic.js +178 -0
  35. package/dist/providers/base-provider.d.ts +66 -0
  36. package/dist/providers/dashscope.d.ts +24 -0
  37. package/dist/providers/deepseek.d.ts +22 -0
  38. package/dist/providers/gemini.d.ts +22 -0
  39. package/dist/providers/gemini.js +3 -3
  40. package/dist/providers/openai.d.ts +28 -0
  41. package/dist/providers/openai.js +3 -3
  42. package/dist/providers/xai.d.ts +22 -0
  43. package/dist/services/embedding-provider.d.ts +26 -0
  44. package/dist/services/translation-service.d.ts +138 -0
  45. package/dist/services/vector-store.d.ts +26 -0
  46. package/dist/utils/ai-context-analyzer.d.ts +73 -0
  47. package/dist/utils/confidence-scorer.d.ts +77 -0
  48. package/dist/utils/error-helper.d.ts +87 -0
  49. package/dist/utils/error-helper.js +3 -1
  50. package/dist/utils/file-manager.d.ts +129 -0
  51. package/dist/utils/glossary-manager.d.ts +69 -0
  52. package/dist/utils/graceful-shutdown.d.ts +22 -0
  53. package/dist/utils/input-validator.d.ts +227 -0
  54. package/dist/utils/input-validator.js +8 -1
  55. package/dist/utils/logger.d.ts +134 -0
  56. package/dist/utils/object-transformer.d.ts +38 -0
  57. package/dist/utils/progress-tracker.d.ts +63 -0
  58. package/dist/utils/prompt-templates.d.ts +37 -0
  59. package/dist/utils/prompt-templates.js +18 -0
  60. package/dist/utils/quality/__tests__/tone-verifier.test.d.ts +1 -0
  61. package/dist/utils/quality/base-checker.d.ts +79 -0
  62. package/dist/utils/quality/code-block-checker.d.ts +64 -0
  63. package/dist/utils/quality/html-tag-checker.d.ts +33 -0
  64. package/dist/utils/quality/index.d.ts +39 -0
  65. package/dist/utils/quality/length-checker.d.ts +70 -0
  66. package/dist/utils/quality/markdown-checker.d.ts +63 -0
  67. package/dist/utils/quality/placeholder-checker.d.ts +42 -0
  68. package/dist/utils/quality/punctuation-checker.d.ts +31 -0
  69. package/dist/utils/quality/quote-balance-checker.d.ts +37 -0
  70. package/dist/utils/quality/special-characters-checker.d.ts +66 -0
  71. package/dist/utils/quality/style-guide-checker.d.ts +71 -0
  72. package/dist/utils/quality/text-sanitizer.d.ts +51 -0
  73. package/dist/utils/quality/tone-verifier.d.ts +14 -0
  74. package/dist/utils/rate-limiter.d.ts +73 -0
  75. package/dist/utils/rate-limiter.js +6 -0
  76. package/dist/utils/retry-helper.d.ts +49 -0
  77. package/dist/utils/state-manager.d.ts +62 -0
  78. package/dist/utils/statistics-manager.d.ts +47 -0
  79. package/dist/utils/ui-manager.d.ts +21 -0
  80. package/package.json +13 -5
@@ -0,0 +1,29 @@
1
+ export interface TranslationResult {
2
+ key: string;
3
+ translated: string | null;
4
+ success: boolean;
5
+ context: Record<string, any>;
6
+ error?: string;
7
+ fromCache?: boolean;
8
+ qualityChecks?: any;
9
+ meta?: Record<string, any>;
10
+ }
11
+ export interface TranslationContext {
12
+ key: string;
13
+ sourceText: string;
14
+ sourceLang: string;
15
+ targetLang: string;
16
+ options: any;
17
+ meta: Record<string, any>;
18
+ existingTranslation: any;
19
+ result: TranslationResult;
20
+ protectedText?: string;
21
+ termMap?: Map<string, any>;
22
+ translatedText?: string;
23
+ success?: boolean;
24
+ error?: string;
25
+ fromCache?: boolean;
26
+ qualityChecks?: any;
27
+ [key: string]: any;
28
+ }
29
+ export declare const createTranslationContext: (key: string, sourceText: string, sourceLang: string, targetLang: string, options: any, meta?: Record<string, any>, existingTranslation?: any) => TranslationContext;
@@ -0,0 +1,25 @@
1
+ import PipelineStep from "../PipelineStep.js";
2
+ import { TranslationContext } from "../context.js";
3
+ export interface CacheStats {
4
+ hits: number;
5
+ staleHits: number;
6
+ misses: number;
7
+ stored: number;
8
+ [key: string]: any;
9
+ }
10
+ export interface Cache {
11
+ has(key: string): boolean;
12
+ get(key: string): any;
13
+ set(key: string, value: any, options?: any): void;
14
+ delete(key: string): void;
15
+ getRemainingTTL?(key: string): number;
16
+ }
17
+ declare class CacheReadStep extends PipelineStep {
18
+ private cache;
19
+ private stats;
20
+ private options;
21
+ constructor(cache: Cache, cacheStats: CacheStats, options?: any);
22
+ execute(context: TranslationContext, next: () => Promise<void>): Promise<void>;
23
+ _generateCacheKey(text: string, targetLang: string, category?: string): string;
24
+ }
25
+ export default CacheReadStep;
@@ -0,0 +1,11 @@
1
+ import PipelineStep from "../PipelineStep.js";
2
+ import { TranslationContext } from "../context.js";
3
+ import { Cache, CacheStats } from "./CacheReadStep.js";
4
+ declare class CacheWriteStep extends PipelineStep {
5
+ private cache;
6
+ private stats;
7
+ private options;
8
+ constructor(cache: Cache, cacheStats: CacheStats, options?: any);
9
+ execute(context: TranslationContext, next: () => Promise<void>): Promise<void>;
10
+ }
11
+ export default CacheWriteStep;
@@ -0,0 +1,10 @@
1
+ import PipelineStep from "../PipelineStep.js";
2
+ import { TranslationContext } from "../context.js";
3
+ import { ConfidenceSettings } from "./TranslationStep.js";
4
+ declare class ConfidenceCheckStep extends PipelineStep {
5
+ private confidenceSettings;
6
+ private debug;
7
+ constructor(confidenceSettings: Partial<ConfidenceSettings>, debug?: boolean);
8
+ execute(context: TranslationContext, next: () => Promise<void>): Promise<void>;
9
+ }
10
+ export default ConfidenceCheckStep;
@@ -0,0 +1,9 @@
1
+ import PipelineStep from "../PipelineStep.js";
2
+ import GlossaryManager from "../../../utils/glossary-manager.js";
3
+ import { TranslationContext } from "../context.js";
4
+ declare class GlossaryPostStep extends PipelineStep {
5
+ private glossaryManager?;
6
+ constructor(glossaryManager?: GlossaryManager | null);
7
+ execute(context: TranslationContext, next: () => Promise<void>): Promise<void>;
8
+ }
9
+ export default GlossaryPostStep;
@@ -0,0 +1,9 @@
1
+ import PipelineStep from "../PipelineStep.js";
2
+ import GlossaryManager from "../../../utils/glossary-manager.js";
3
+ import { TranslationContext } from "../context.js";
4
+ declare class GlossaryPreStep extends PipelineStep {
5
+ private glossaryManager?;
6
+ constructor(glossaryManager?: GlossaryManager | null);
7
+ execute(context: TranslationContext, next: () => Promise<void>): Promise<void>;
8
+ }
9
+ export default GlossaryPreStep;
@@ -0,0 +1,8 @@
1
+ import PipelineStep from "../PipelineStep.js";
2
+ import { TranslationContext } from "../context.js";
3
+ declare class InputValidationStep extends PipelineStep {
4
+ private maxKeyLength;
5
+ constructor(maxKeyLength?: number);
6
+ execute(context: TranslationContext, next: () => Promise<void>): Promise<void>;
7
+ }
8
+ export default InputValidationStep;
@@ -0,0 +1,10 @@
1
+ import PipelineStep from "../PipelineStep.js";
2
+ import { TranslationContext } from "../context.js";
3
+ import QualityChecker from "../../../utils/quality/index.js";
4
+ declare class QualityCheckStep extends PipelineStep {
5
+ private qualityChecker;
6
+ private debug;
7
+ constructor(qualityChecker: QualityChecker | any, debug?: boolean);
8
+ execute(context: TranslationContext, next: () => Promise<void>): Promise<void>;
9
+ }
10
+ export default QualityCheckStep;
@@ -0,0 +1,13 @@
1
+ import PipelineStep from "../PipelineStep.js";
2
+ import { TranslationContext } from "../context.js";
3
+ export declare class ToneCheckStep extends PipelineStep {
4
+ private verifier;
5
+ private enabled;
6
+ private debug;
7
+ constructor(config?: {
8
+ enabled?: boolean;
9
+ debug?: boolean;
10
+ });
11
+ execute(context: TranslationContext, next: () => Promise<void>): Promise<void>;
12
+ }
13
+ export default ToneCheckStep;
@@ -0,0 +1,22 @@
1
+ import PipelineStep from "../PipelineStep.js";
2
+ import { AIProvider } from "../../provider-factory.js";
3
+ import { TranslationContext } from "../context.js";
4
+ export interface ConfidenceSettings {
5
+ enabled: boolean;
6
+ autoApproveThreshold: number;
7
+ rejectThreshold: number;
8
+ reviewThreshold: number;
9
+ saveReviewQueue: boolean;
10
+ reviewQueue: any[];
11
+ autoApprovedCount: number;
12
+ rejectedCount: number;
13
+ [key: string]: any;
14
+ }
15
+ declare class TranslationStep extends PipelineStep {
16
+ private options;
17
+ private confidenceSettings;
18
+ constructor(options?: any, confidenceSettings?: Partial<ConfidenceSettings>);
19
+ execute(context: TranslationContext, next: () => Promise<void>): Promise<void>;
20
+ _getProvider(): AIProvider;
21
+ }
22
+ export default TranslationStep;
@@ -0,0 +1,17 @@
1
+ import PipelineStep from "../PipelineStep.js";
2
+ import { TranslationContext } from "../context.js";
3
+ import { VectorStore } from "../../../services/vector-store.js";
4
+ import { EmbeddingProvider } from "../../../services/embedding-provider.js";
5
+ export interface VectorMemoryStats {
6
+ hits: number;
7
+ contextUsed: number;
8
+ misses: number;
9
+ }
10
+ export declare class VectorCacheReadStep extends PipelineStep {
11
+ private vectorStore;
12
+ private embeddingProvider;
13
+ private stats;
14
+ private options;
15
+ constructor(vectorStore: VectorStore, embeddingProvider: EmbeddingProvider, stats: VectorMemoryStats, options?: any);
16
+ execute(context: TranslationContext, next: () => Promise<void>): Promise<void>;
17
+ }
@@ -0,0 +1,11 @@
1
+ import PipelineStep from "../PipelineStep.js";
2
+ import { TranslationContext } from "../context.js";
3
+ import { VectorStore } from "../../../services/vector-store.js";
4
+ import { EmbeddingProvider } from "../../../services/embedding-provider.js";
5
+ export declare class VectorCacheWriteStep extends PipelineStep {
6
+ private vectorStore;
7
+ private embeddingProvider;
8
+ private options;
9
+ constructor(vectorStore: VectorStore, embeddingProvider: EmbeddingProvider, options?: any);
10
+ execute(context: TranslationContext, next: () => Promise<void>): Promise<void>;
11
+ }
@@ -0,0 +1,41 @@
1
+ import { ProviderConfig, TranslateOptions } from "../providers/base-provider.js";
2
+ export interface AIProvider {
3
+ translate(text: string, sourceLang: string, targetLang: string, options?: TranslateOptions): Promise<string>;
4
+ analyze?(prompt: string, options?: ProviderConfig): Promise<string>;
5
+ chat?(messages: any[], options?: ProviderConfig): Promise<string>;
6
+ }
7
+ /**
8
+ * Factory for creating and managing AI providers.
9
+ * Handles provider instantiation, configuration, and fallback chains.
10
+ */
11
+ declare class ProviderFactory {
12
+ /**
13
+ * Get provider instance with intelligent fallback support.
14
+ * @param {string} providerName - Name of the primary provider.
15
+ * @param {boolean} [useFallback=true] - Whether to use fallback chain on failure.
16
+ * @param {Object} [config=null] - Optional configuration overrides.
17
+ * @returns {AIProvider} - Provider instance or wrapped FallbackProvider.
18
+ * @throws {Error} If provider is not found or configured.
19
+ */
20
+ static getProvider(providerName: string, useFallback?: boolean, config?: {
21
+ fallbackOrder?: string[];
22
+ } | null): AIProvider;
23
+ /**
24
+ * Get list of available (configured) providers.
25
+ * @returns {string[]} - Array of provider names with valid API keys.
26
+ */
27
+ static getAvailableProviders(): string[];
28
+ /**
29
+ * Validate that at least one provider is configured.
30
+ * @returns {string[]} - Array of available providers.
31
+ * @throws {Error} If no providers are configured.
32
+ */
33
+ static validateProviders(): string[];
34
+ /**
35
+ * Check if a specific provider is configured.
36
+ * @param {string} providerName - Name of the provider.
37
+ * @returns {boolean} - True if provider has an API key configured.
38
+ */
39
+ static isProviderConfigured(providerName: string): boolean;
40
+ }
41
+ export default ProviderFactory;
@@ -1,6 +1,7 @@
1
1
  import * as deepseekProvider from "../providers/deepseek.js";
2
2
  import * as geminiProvider from "../providers/gemini.js";
3
3
  import * as openaiProvider from "../providers/openai.js";
4
+ import * as anthropicProvider from "../providers/anthropic.js";
4
5
  import * as dashscopeProvider from "../providers/dashscope.js";
5
6
  import * as xaiProvider from "../providers/xai.js";
6
7
  import FallbackProvider from "./fallback-provider.js";
@@ -23,6 +24,7 @@ class ProviderFactory {
23
24
  dashscope: dashscopeProvider,
24
25
  xai: xaiProvider,
25
26
  openai: openaiProvider,
27
+ anthropic: anthropicProvider,
26
28
  deepseek: deepseekProvider,
27
29
  gemini: geminiProvider,
28
30
  };
@@ -100,6 +102,7 @@ class ProviderFactory {
100
102
  dashscope: process.env.DASHSCOPE_API_KEY,
101
103
  xai: process.env.XAI_API_KEY,
102
104
  openai: process.env.OPENAI_API_KEY,
105
+ anthropic: process.env.ANTHROPIC_API_KEY,
103
106
  deepseek: process.env.DEEPSEEK_API_KEY,
104
107
  gemini: process.env.GEMINI_API_KEY,
105
108
  };
@@ -129,6 +132,7 @@ class ProviderFactory {
129
132
  dashscope: "DASHSCOPE_API_KEY",
130
133
  xai: "XAI_API_KEY",
131
134
  openai: "OPENAI_API_KEY",
135
+ anthropic: "ANTHROPIC_API_KEY",
132
136
  deepseek: "DEEPSEEK_API_KEY",
133
137
  gemini: "GEMINI_API_KEY",
134
138
  };
@@ -0,0 +1,25 @@
1
+ import BaseProvider, { ProviderConfig, TranslateOptions } from "./base-provider.js";
2
+ /**
3
+ * Provider implementation for Anthropic (Claude) models.
4
+ */
5
+ declare class AnthropicProvider extends BaseProvider {
6
+ private client;
7
+ /**
8
+ * Create a new AnthropicProvider instance.
9
+ * @param {ProviderConfig} config - Provider configuration.
10
+ */
11
+ constructor(config?: ProviderConfig);
12
+ getApiKey(): string | undefined;
13
+ getEndpoint(): string;
14
+ /**
15
+ * Translate text using Anthropic.
16
+ */
17
+ translate(text: string, sourceLang: string, targetLang: string, options?: TranslateOptions): Promise<string>;
18
+ analyze(prompt: string, options?: ProviderConfig): Promise<string>;
19
+ chat(messages: any[], options?: ProviderConfig): Promise<string>;
20
+ extractTranslation(response: any, providerName: string): string;
21
+ }
22
+ declare function translate(text: string, sourceLang: string, targetLang: string, options?: TranslateOptions): Promise<string>;
23
+ declare function analyze(prompt: string, options?: ProviderConfig): Promise<string>;
24
+ declare function chat(messages: any[], options?: ProviderConfig): Promise<string>;
25
+ export { translate, analyze, chat, AnthropicProvider };
@@ -0,0 +1,178 @@
1
+ import axios from "axios";
2
+ import BaseProvider from "./base-provider.js";
3
+ import { getPrompt, getAnalysisPrompt } from "../utils/prompt-templates.js";
4
+ import RetryHelper from "../utils/retry-helper.js";
5
+ /**
6
+ * Provider implementation for Anthropic (Claude) models.
7
+ */
8
+ class AnthropicProvider extends BaseProvider {
9
+ client;
10
+ /**
11
+ * Create a new AnthropicProvider instance.
12
+ * @param {ProviderConfig} config - Provider configuration.
13
+ */
14
+ constructor(config = {}) {
15
+ super("anthropic", config);
16
+ this.client = axios.create({
17
+ baseURL: "https://api.anthropic.com/v1",
18
+ headers: {
19
+ ...this.commonHeaders,
20
+ "x-api-key": this.getApiKey(),
21
+ "anthropic-version": "2023-06-01",
22
+ },
23
+ timeout: 30000,
24
+ maxRedirects: 0,
25
+ validateStatus: (status) => status < 500,
26
+ });
27
+ }
28
+ getApiKey() {
29
+ return process.env.ANTHROPIC_API_KEY;
30
+ }
31
+ getEndpoint() {
32
+ return "/messages";
33
+ }
34
+ /**
35
+ * Translate text using Anthropic.
36
+ */
37
+ async translate(text, sourceLang, targetLang, options = {}) {
38
+ this.validateRequest(text, sourceLang, targetLang);
39
+ // Prioritize user config > options config > default model
40
+ // Anthropic models: claude-3-5-sonnet-latest, claude-3-5-haiku-latest, claude-3-opus-latest
41
+ const config = this.getConfig(options.apiConfig?.anthropic);
42
+ const model = config.model || "claude-haiku-4-5-20251001";
43
+ const promptData = getPrompt("anthropic", sourceLang, targetLang, text, options);
44
+ return RetryHelper.withRetry(async () => {
45
+ try {
46
+ const response = await this.client.post(this.getEndpoint(), {
47
+ model: model,
48
+ ...promptData, // Contains { system: "...", messages: [...] }
49
+ max_tokens: config.maxTokens || 4096,
50
+ temperature: config.temperature,
51
+ });
52
+ this.validateResponse(response, this.name);
53
+ const translation = this.extractTranslation(response.data, this.name);
54
+ return this.sanitizeTranslation(translation);
55
+ }
56
+ catch (error) {
57
+ this.handleApiError(error, this.name);
58
+ throw error;
59
+ }
60
+ }, {
61
+ maxRetries: options.retryOptions?.maxRetries || 2,
62
+ initialDelay: options.retryOptions?.initialDelay || 1000,
63
+ context: "Anthropic Provider",
64
+ logContext: {
65
+ source: sourceLang,
66
+ target: targetLang,
67
+ },
68
+ });
69
+ }
70
+ async analyze(prompt, options = {}) {
71
+ const config = this.getConfig({
72
+ model: options.model || "claude-3-5-sonnet-latest",
73
+ temperature: options.temperature || 0.2,
74
+ maxTokens: options.maxTokens || 1000,
75
+ });
76
+ const promptData = getAnalysisPrompt("anthropic", prompt, options);
77
+ return RetryHelper.withRetry(async () => {
78
+ try {
79
+ const response = await this.client.post(this.getEndpoint(), {
80
+ model: config.model,
81
+ ...promptData,
82
+ max_tokens: config.maxTokens,
83
+ temperature: config.temperature,
84
+ });
85
+ this.validateResponse(response, this.name);
86
+ const result = this.extractTranslation(response.data, this.name);
87
+ return this.sanitizeTranslation(result);
88
+ }
89
+ catch (error) {
90
+ this.handleApiError(error, this.name);
91
+ throw error;
92
+ }
93
+ }, {
94
+ maxRetries: options.maxRetries || 2,
95
+ initialDelay: options.initialDelay || 1000,
96
+ context: "Anthropic Provider Analysis",
97
+ });
98
+ }
99
+ async chat(messages, options = {}) {
100
+ const config = this.getConfig({
101
+ model: options.model || "claude-3-5-sonnet-latest",
102
+ temperature: options.temperature || 0.3,
103
+ maxTokens: options.maxTokens || 4096,
104
+ });
105
+ // Anthropic requires system prompt to be top-level, separate from messages array
106
+ // Note: This simple implementation assumes messages passed in might be mixed.
107
+ // Ideally, the caller should separate system prompt, but we can do a quick check here.
108
+ let systemPrompt = undefined;
109
+ const cleanMessages = messages.filter((msg) => {
110
+ if (msg.role === "system") {
111
+ systemPrompt = msg.content;
112
+ return false;
113
+ }
114
+ return true;
115
+ });
116
+ return RetryHelper.withRetry(async () => {
117
+ try {
118
+ const payload = {
119
+ model: config.model,
120
+ messages: cleanMessages,
121
+ max_tokens: config.maxTokens,
122
+ temperature: config.temperature,
123
+ };
124
+ if (systemPrompt) {
125
+ payload.system = systemPrompt;
126
+ }
127
+ const response = await this.client.post(this.getEndpoint(), payload);
128
+ this.validateResponse(response, this.name);
129
+ const result = this.extractTranslation(response.data, this.name);
130
+ return this.sanitizeTranslation(result);
131
+ }
132
+ catch (error) {
133
+ this.handleApiError(error, this.name);
134
+ throw error;
135
+ }
136
+ }, {
137
+ maxRetries: options.maxRetries || 2,
138
+ initialDelay: options.initialDelay || 1000,
139
+ context: "Anthropic Provider Chat",
140
+ });
141
+ }
142
+ // Override extractTranslation to handle Anthropic's specific response structure
143
+ extractTranslation(response, providerName) {
144
+ // Check for error response first
145
+ if (response.error) {
146
+ const errorMsg = response.error.message || response.error.error || JSON.stringify(response.error);
147
+ throw new Error(`api: ${providerName} - ${errorMsg}`);
148
+ }
149
+ // Anthropic format: { content: [{ type: 'text', text: '...' }] }
150
+ if (response.content && Array.isArray(response.content) && response.content.length > 0) {
151
+ const textBlock = response.content.find((block) => block.type === "text");
152
+ if (textBlock && textBlock.text) {
153
+ return textBlock.text.trim();
154
+ }
155
+ }
156
+ // Fallback to base implementation for other structures (though unlikely for Anthropic)
157
+ return super.extractTranslation(response, providerName);
158
+ }
159
+ }
160
+ // Lazy singleton - created on first use
161
+ let anthropicProvider = null;
162
+ function getProvider() {
163
+ if (!anthropicProvider) {
164
+ anthropicProvider = new AnthropicProvider();
165
+ }
166
+ return anthropicProvider;
167
+ }
168
+ // Export both class and legacy functions
169
+ async function translate(text, sourceLang, targetLang, options = {}) {
170
+ return getProvider().translate(text, sourceLang, targetLang, options);
171
+ }
172
+ async function analyze(prompt, options = {}) {
173
+ return getProvider().analyze(prompt, options);
174
+ }
175
+ async function chat(messages, options = {}) {
176
+ return getProvider().chat(messages, options);
177
+ }
178
+ export { translate, analyze, chat, AnthropicProvider };
@@ -0,0 +1,66 @@
1
+ export interface ProviderConfig {
2
+ model?: string;
3
+ temperature?: number;
4
+ maxTokens?: number;
5
+ [key: string]: any;
6
+ }
7
+ export interface TranslateOptions {
8
+ detectedContext?: {
9
+ category?: string;
10
+ [key: string]: any;
11
+ };
12
+ lengthControl?: {
13
+ mode?: string;
14
+ [key: string]: any;
15
+ };
16
+ apiConfig?: Record<string, any>;
17
+ retryOptions?: {
18
+ maxRetries?: number;
19
+ initialDelay?: number;
20
+ [key: string]: any;
21
+ };
22
+ [key: string]: any;
23
+ }
24
+ export interface ConfidenceResult {
25
+ score: number;
26
+ metrics?: any;
27
+ [key: string]: any;
28
+ }
29
+ export interface TranslationResult {
30
+ translation: string;
31
+ confidence: ConfidenceResult;
32
+ rawResponse: any;
33
+ }
34
+ declare class BaseProvider {
35
+ name: string;
36
+ config: ProviderConfig;
37
+ defaultModel?: string;
38
+ defaultTemperature: number;
39
+ defaultMaxTokens: number;
40
+ commonHeaders: Record<string, string>;
41
+ constructor(name: string, config?: ProviderConfig);
42
+ translate(text: string, sourceLang: string, targetLang: string, _options?: TranslateOptions): Promise<string>;
43
+ analyze(prompt: string, options?: any): Promise<string>;
44
+ chat(messages: any[], options?: any): Promise<string>;
45
+ getApiKey(): string | undefined;
46
+ getEndpoint(): string;
47
+ validateRequest(text: string, sourceLang: string, targetLang: string): void;
48
+ validateResponse(response: any, providerName: string): boolean;
49
+ handleApiError(error: any, providerName: string): never;
50
+ generatePrompt(text: string, sourceLang: string, targetLang: string, options?: TranslateOptions): string;
51
+ getConfig(options?: ProviderConfig): {
52
+ model: string | undefined;
53
+ temperature: number;
54
+ maxTokens: number;
55
+ max_tokens: number;
56
+ apiKey: string;
57
+ endpoint: string;
58
+ };
59
+ extractTranslation(response: any, providerName: string): string;
60
+ /**
61
+ * Extract translation with confidence score
62
+ */
63
+ extractTranslationWithConfidence(response: any, providerName: string, sourceText: string, sourceLang: string, targetLang: string, category?: string): TranslationResult;
64
+ sanitizeTranslation(translation: string): string;
65
+ }
66
+ export default BaseProvider;
@@ -0,0 +1,24 @@
1
+ import BaseProvider, { ProviderConfig, TranslateOptions } from "./base-provider.js";
2
+ /**
3
+ * Provider implementation for Alibaba DashScope (Qwen) models.
4
+ */
5
+ declare class DashScopeProvider extends BaseProvider {
6
+ private client;
7
+ private generationClient;
8
+ /**
9
+ * Create a new DashScopeProvider instance.
10
+ * @param {ProviderConfig} config - Provider configuration.
11
+ */
12
+ constructor(config?: ProviderConfig);
13
+ getApiKey(): string | undefined;
14
+ getEndpoint(): string;
15
+ getGenerationEndpoint(): string;
16
+ /**
17
+ * Translate text using DashScope.
18
+ */
19
+ translate(text: string, sourceLang: string, targetLang: string, options?: TranslateOptions): Promise<string>;
20
+ analyze(prompt: string, options?: ProviderConfig): Promise<string>;
21
+ }
22
+ declare function translate(text: string, sourceLang: string, targetLang: string, options?: TranslateOptions): Promise<string>;
23
+ declare function analyze(prompt: string, options?: ProviderConfig): Promise<string>;
24
+ export { translate, analyze, DashScopeProvider };
@@ -0,0 +1,22 @@
1
+ import BaseProvider, { ProviderConfig, TranslateOptions } from "./base-provider.js";
2
+ /**
3
+ * Provider implementation for DeepSeek API.
4
+ */
5
+ declare class DeepSeekProvider extends BaseProvider {
6
+ private client;
7
+ /**
8
+ * Create a new DeepSeekProvider instance.
9
+ * @param {ProviderConfig} config - Provider configuration.
10
+ */
11
+ constructor(config?: ProviderConfig);
12
+ getApiKey(): string | undefined;
13
+ getEndpoint(): string;
14
+ /**
15
+ * Translate text using DeepSeek.
16
+ */
17
+ translate(text: string, sourceLang: string, targetLang: string, options?: TranslateOptions): Promise<string>;
18
+ analyze(prompt: string, options?: ProviderConfig): Promise<string>;
19
+ }
20
+ declare function translate(text: string, sourceLang: string, targetLang: string, options?: TranslateOptions): Promise<string>;
21
+ declare function analyze(prompt: string, options?: ProviderConfig): Promise<string>;
22
+ export { translate, analyze, DeepSeekProvider };
@@ -0,0 +1,22 @@
1
+ import BaseProvider, { ProviderConfig, TranslateOptions } from "./base-provider.js";
2
+ /**
3
+ * Provider implementation for Google Gemini models.
4
+ */
5
+ declare class GeminiProvider extends BaseProvider {
6
+ private client;
7
+ /**
8
+ * Create a new GeminiProvider instance.
9
+ * @param {ProviderConfig} config - Provider configuration.
10
+ */
11
+ constructor(config?: ProviderConfig);
12
+ getApiKey(): string | undefined;
13
+ getEndpoint(model?: string): string;
14
+ /**
15
+ * Translate text using Gemini.
16
+ */
17
+ translate(text: string, sourceLang: string, targetLang: string, options?: TranslateOptions): Promise<string>;
18
+ analyze(prompt: string, options?: ProviderConfig): Promise<string>;
19
+ }
20
+ declare function translate(text: string, sourceLang: string, targetLang: string, options?: TranslateOptions): Promise<string>;
21
+ declare function analyze(prompt: string, options?: ProviderConfig): Promise<string>;
22
+ export { translate, analyze, GeminiProvider };
@@ -27,7 +27,7 @@ class GeminiProvider extends BaseProvider {
27
27
  return process.env.GEMINI_API_KEY;
28
28
  }
29
29
  getEndpoint(model) {
30
- return `/models/${model || "gemini-2.0-flash-exp"}:generateContent`;
30
+ return `/models/${model || "gemini-3-flash"}:generateContent`;
31
31
  }
32
32
  /**
33
33
  * Translate text using Gemini.
@@ -35,7 +35,7 @@ class GeminiProvider extends BaseProvider {
35
35
  async translate(text, sourceLang, targetLang, options = {}) {
36
36
  this.validateRequest(text, sourceLang, targetLang);
37
37
  const config = this.getConfig(options.apiConfig?.gemini);
38
- const model = config.model || "gemini-2.0-flash-exp";
38
+ const model = config.model || "gemini-3-flash";
39
39
  const apiKey = this.getApiKey();
40
40
  if (!apiKey) {
41
41
  throw new Error("GEMINI_API_KEY environment variable not found");
@@ -77,7 +77,7 @@ class GeminiProvider extends BaseProvider {
77
77
  }
78
78
  async analyze(prompt, options = {}) {
79
79
  const config = this.getConfig({
80
- model: options.model || "gemini-2.0-flash-exp",
80
+ model: options.model || "gemini-3-flash",
81
81
  temperature: options.temperature || 0.2,
82
82
  maxTokens: options.maxTokens || 1000,
83
83
  });