-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
616 additions
and
325 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,14 @@ | ||
import { LLMProviderConfig } from '@repo/base/config'; | ||
import { OpenAITranslationProvider } from '@repo/provider/openai'; | ||
import { NextResponse } from 'next/server'; | ||
|
||
export const runtime = 'edge'; | ||
|
||
export async function GET() { | ||
const config: LLMProviderConfig = { | ||
provider: 'openai', | ||
maxOutputTokens: 16383, | ||
buffer: 0.3, | ||
maxRetry: 1, | ||
}; | ||
return NextResponse.json(config); | ||
const apiKey = process.env.OPENAI_API_KEY; | ||
if (!apiKey) { | ||
throw new Error('OPENAI_API_KEY is not set'); | ||
} | ||
const provider = new OpenAITranslationProvider({ apiKey }); | ||
console.log(`provider.config()`, await provider.config()); | ||
return NextResponse.json(await provider.config()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "@repo/provider", | ||
"version": "1.0.0", | ||
"private": true, | ||
"description": "Translation providers", | ||
"type": "module", | ||
"exports": { | ||
".": "./src/index.ts", | ||
"./*": "./src/*.ts" | ||
}, | ||
"scripts": {}, | ||
"dependencies": { | ||
"@repo/base": "workspace:*", | ||
"ai": "^3.3.20", | ||
"openai": "^4.20.0", | ||
"@ai-sdk/openai": "^0.0.54", | ||
"zod": "^3.22.4", | ||
"zod-validation-error": "^2.1.0" | ||
}, | ||
"devDependencies": { | ||
"@repo/typescript-config": "workspace:*", | ||
"@types/node": "^20.5.4" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { LLMTranslatorConfig } from '@repo/base/config'; | ||
import { StreamObjectResult } from 'ai'; | ||
|
||
interface TranslationPayload { | ||
context?: string; | ||
sourceLanguage: string; | ||
targetLanguages: string[]; | ||
contents: { | ||
key: string; | ||
source: string; | ||
notes?: string[]; | ||
}[]; | ||
} | ||
|
||
export interface TranslationProvider { | ||
translate( | ||
payload: TranslationPayload, | ||
): Promise<StreamObjectResult<Record<string, Record<string, string>>>>; | ||
config(): Promise<LLMTranslatorConfig>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { OpenAIProvider, createOpenAI } from '@ai-sdk/openai'; | ||
import { LLMTranslatorConfig } from '@repo/base/config'; | ||
import { logger } from '@repo/base/logger'; | ||
import { LanguageModel, streamObject } from 'ai'; | ||
import { z } from 'zod'; | ||
|
||
import { TranslationProvider } from '.'; | ||
|
||
export class OpenAITranslationProvider implements TranslationProvider { | ||
private openai: OpenAIProvider; | ||
private model: LanguageModel; | ||
|
||
constructor(options: { apiKey: string }) { | ||
this.openai = createOpenAI({ | ||
apiKey: options.apiKey, | ||
compatibility: 'strict', // https://sdk.vercel.ai/providers/ai-sdk-providers/openai#provider-instance | ||
}); | ||
this.model = this.openai('gpt-4o-mini'); | ||
} | ||
|
||
async config() { | ||
const config: LLMTranslatorConfig = { | ||
maxOutputTokens: 16383, | ||
buffer: 0.3, | ||
maxRetry: 1, | ||
tokenizer: 'openai', | ||
tokenizerModel: 'gpt-4', | ||
}; | ||
return config; | ||
} | ||
|
||
async translate(payload: { | ||
context?: string; | ||
sourceLanguage: string; | ||
targetLanguages: string[]; | ||
contents: { | ||
key: string; | ||
source: string; | ||
notes?: string[]; | ||
}[]; | ||
}) { | ||
let instructions = `As an app/website translator, your task is to translate texts to target languages, considering context and developer notes for accuracy and cultural appropriateness. It's essential to preserve original format, including line breaks, separators, escaping characters and localization symbols, otherwise, user interface may break.\nSource texts are in key=value format. Translate only the 'value', keeping the 'key' as is. Lines starting with "//" are developer notes for translation guidance.\nFor example, 'key=Hello "%@"\\nWelcome!' can be translate to 'key=你好 "%@"\\n欢迎!' in Chinese. \nOutput should be in JSON format: each source key links to an object with target languages as keys and translated texts as values. \n`; | ||
if (payload.context) { | ||
instructions += `\nTranslation context: \n${payload.context}\n`; | ||
} | ||
let userContent = `Translate from ${ | ||
payload.sourceLanguage | ||
} to target languages: [${payload.targetLanguages.join(', ')}].\n\n`; | ||
userContent += '=====\n\n'; | ||
for (const content of payload.contents) { | ||
if (content.notes) { | ||
for (const note of content.notes) { | ||
userContent += `// ${note}\n`; | ||
} | ||
} | ||
userContent += `${content.key}=${content.source}\n\n`; | ||
} | ||
const TranslationReponseSchema = z.record( | ||
z.string(), | ||
z.record( | ||
z.enum([ | ||
payload.targetLanguages[0], | ||
...payload.targetLanguages.slice(1), | ||
]), | ||
z.string(), | ||
), | ||
); | ||
const result = await streamObject({ | ||
model: this.model, | ||
mode: 'json', | ||
schema: TranslationReponseSchema, | ||
system: instructions, | ||
prompt: userContent, | ||
onFinish: (e) => { | ||
if (e.error) { | ||
logger.error(`Error translating streaming object error: ${e.error}`); | ||
return; | ||
} | ||
logger.info( | ||
`Finished translating, usage: ${e.usage}, object: ${JSON.stringify(e.object)}`, | ||
); | ||
}, | ||
}); | ||
return result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"extends": "@repo/typescript-config/lib.json", | ||
"compilerOptions": { | ||
"module": "esnext", | ||
"moduleResolution": "bundler" | ||
}, | ||
"include": ["src"], | ||
"exclude": ["dist", "build", "node_modules"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.