| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- /** Verify that the committed translation prompt renders and parses as documented. */
- import { readFileSync } from 'node:fs'
- import { join, resolve } from 'node:path'
- import {
- consumeTranslationResponse,
- documentedTranslationPromptPlaceholders,
- parseTranslationResponse,
- renderTranslationPrompt,
- renderTranslationRequest,
- renderTranslationResponse,
- TRANSLATION_PROMPT_PLACEHOLDERS,
- type TranslationExample,
- } from './translation-prompt.ts'
- const root = resolve(import.meta.dirname, '..')
- function read(path: string): string {
- return readFileSync(join(root, path), 'utf8')
- }
- try {
- const mode = process.argv[2]
- if (mode !== undefined && mode !== '--snapshot') throw new Error(`unsupported argument ${JSON.stringify(mode)}`)
- const document = read('docs/i18n/translation-prompt.md')
- const terminology = read('docs/i18n/terminology.md')
- // Synthetic reviewed examples, not live documents: editing a paired document must not
- // churn the prompt snapshot. Each pair mirrors the other side's structure and uses
- // terminology-table forms.
- const examplePaths = [
- ['scripts/fixtures/translation-prompt/examples/product.md', 'scripts/fixtures/translation-prompt/examples/product.zh.md'],
- ['scripts/fixtures/translation-prompt/examples/rules.md', 'scripts/fixtures/translation-prompt/examples/rules.zh.md'],
- [
- 'scripts/fixtures/translation-prompt/examples/agent-note.md',
- 'scripts/fixtures/translation-prompt/examples/agent-note.zh.md',
- ],
- ] as const
- const examples: TranslationExample[] = examplePaths.map(([english, chinese]) => ({
- english: read(english),
- chinese: read(chinese),
- }))
- const sourceDocument = read('scripts/fixtures/translation-prompt/snapshot-note.md')
- const recordedResponse = read('scripts/fixtures/translation-prompt/response.txt')
- const documented = documentedTranslationPromptPlaceholders(document)
- if (documented.join('\n') !== TRANSLATION_PROMPT_PLACEHOLDERS.join('\n')) {
- throw new Error(`placeholder table must list exactly: ${TRANSLATION_PROMPT_PLACEHOLDERS.join(', ')}`)
- }
- const englishInput = { sourceLanguage: 'English' as const, sourceFilename: 'snapshot-note.md', terminology }
- const englishSource = renderTranslationPrompt(document, englishInput)
- const chineseSource = renderTranslationPrompt(document, {
- sourceLanguage: 'Chinese',
- sourceFilename: 'snapshot-note.zh.md',
- terminology,
- })
- if (englishSource.includes('{{') || chineseSource.includes('{{')) throw new Error('rendered prompt contains an unresolved placeholder')
- if (!englishSource.includes('from English to Chinese')) throw new Error('English-source render does not translate into Chinese')
- if (!chineseSource.includes('from Chinese to English')) throw new Error('Chinese-source render does not translate into English')
- const example = /```xml\n([\s\S]*?)\n```/.exec(englishSource)?.[1]
- if (example === undefined) throw new Error('rendered prompt has no three-section response example')
- parseTranslationResponse(example)
- const roundTrip = { translation: 'first pass\n\nwith **markdown**', review: '- 无修正', final: 'final text' }
- const parsed = parseTranslationResponse(renderTranslationResponse(roundTrip))
- if (JSON.stringify(parsed) !== JSON.stringify(roundTrip)) throw new Error('three-section response does not round-trip')
- const request = renderTranslationRequest(document, { ...englishInput, sourceDocument, examples })
- if (request.targetFilename !== 'snapshot-note.zh.md') throw new Error('English request resolves the wrong target filename')
- const expectedRoles = ['system', ...examples.flatMap(() => ['user', 'assistant']), 'user']
- if (request.messages.map(message => message.role).join('\n') !== expectedRoles.join('\n')) {
- throw new Error('reviewed examples are not assembled as system, example pairs, then source')
- }
- const consumed = consumeTranslationResponse(recordedResponse, englishInput)
- const expectedFinalPrefix = [
- '---',
- 'layout: doc',
- '---',
- '',
- '# 快照说明',
- '',
- '[English](snapshot-note.md) | 中文',
- '',
- ].join('\n')
- if (!consumed.final.startsWith(expectedFinalPrefix)) {
- throw new Error('recorded frontmatter response does not preserve metadata and receive the canonical target switcher')
- }
- if (mode === '--snapshot') {
- process.stdout.write(`${JSON.stringify({ request, response: consumed }, null, 2)}\n`)
- } else {
- console.log('verify-translation-prompt: both directions render, reviewed examples assemble, and the consumed response is target-path correct.')
- }
- } catch (error) {
- const message = error instanceof Error ? error.message : String(error)
- console.error(`verify-translation-prompt: ${message}`)
- process.exit(1)
- }
|