Untitled

 avatar
unknown
plain_text
9 months ago
2.8 kB
13
Indexable
exports.translateMenuFileWithGPT5 = async (req, res) => {
  if (!req.file) return res.status(400).json({ error: 'File is required' });

  const text = fs.readFileSync(req.file.path, 'utf-8');
  fs.unlink(req.file.path, () => {});

  if (!text || text.trim() === '') {
    return res.status(400).json({ error: 'File is empty' });
  }

  try {
    const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

    const systemPrompt = require('../utils/menuBridgePrompt');
    const userMessage = `Japanese Text (preserve line breaks):\n${text}`;

    const response = await client.responses.create({
      model: 'gpt-5',
      text: {
        format: {
          type: 'json_schema',
          name: 'JapaneseMenuLineTranslations',
          strict: true,
          schema: {
            type: 'object',
            additionalProperties: false,
            properties: {
              translations: {
                type: 'array',
                description: 'Translations per input line, preserving order and empty lines.',
                items: {
                  type: 'object',
                  additionalProperties: false,
                  properties: {
                    japanese: { type: 'string', description: 'Original line (may be empty).' },
                    english:  { type: 'string', description: 'Translated line (may be empty).' },
                    ingredientsAndPreparations: {
                      type: 'array',
                      description: 'Ingredients & Preparations bullets for menu items; empty array for non-menu items or empty lines.',
                      items: { type: 'string' }
                    }
                  },
                  required: ['japanese', 'english', 'ingredientsAndPreparations']
                }
              }
            },
            required: ['translations']
          }
        }
      },
      input: [
        { role: 'system', content: [{ type: 'input_text', text: systemPrompt }] },
        { role: 'user',   content: [{ type: 'input_text', text: userMessage }] }
      ]
    });

    const responseText = (response.output_text || '').trim();
    const cleaned = responseText
      .replace(/^```json\s*/i, '')
      .replace(/^```\s*/i, '')
      .replace(/```$/i, '')
      .trim();

    let payload;
    try {
      payload = JSON.parse(cleaned);
    } catch {
      return res.status(200).json({ raw: responseText });
    }

    if (payload && Array.isArray(payload.translations)) {
      return res.json({ translations: payload.translations });
    }
    return res.status(200).json({ raw: responseText });
  } catch (error) {
    console.error('GPT-5 translation error:', error);
    return res.status(500).json({ error: 'Translation failed', details: error.message });
  }
};
Editor is loading...
Leave a Comment