Files
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
2026-08-07 12:53:47 +08:00

1 line
6.3 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "bniya-cn/jx-team", "files": {"app/services/deepseek_translator.rb": {"8f2d1306c5010eb0cabaa2e9038640497165af2f": {"t": 1785745745.640019, "n": 2600, "h": "1044a4fd047e8308", "c": "require 'net/http'\nrequire 'json'\n\n# DeepSeek 翻译服务:API Key 仅存于服务端环境变量\nclass DeepseekTranslator\n API_URL = URI('https://api.deepseek.com/chat/completions')\n MAX_TEXTS = 50\n MAX_CHARS = 8000\n\n class << self\n def translate(texts:, source_lang:, target_lang:)\n cleaned = Array(texts).map(&:to_s).reject(&:blank?)\n return { translations: [], error: '没有可翻译的文本' } if cleaned.empty?\n\n if cleaned.join.length > MAX_CHARS || cleaned.length > MAX_TEXTS\n return { translations: [], error: \"单次最多 #{MAX_TEXTS} 条或 #{MAX_CHARS} 字符\" }\n end\n\n api_key = ENV['DEEPSEEK_API_KEY']\n if api_key.blank?\n return {\n translations: placeholder_translations(cleaned, target_lang),\n placeholder: true,\n message: '未配置 DEEPSEEK_API_KEY,返回占位译文。请在 .env 中设置密钥后重启服务。',\n }\n end\n\n prompt = build_prompt(cleaned, source_lang, target_lang)\n response_body = call_api(api_key, prompt)\n parsed = JSON.parse(response_body)\n content = parsed.dig('choices', 0, 'message', 'content')\n translations = JSON.parse(content)\n { translations: translations }\n rescue JSON::ParserError\n { translations: [], error: '翻译结果解析失败' }\n rescue StandardError => e\n { translations: [], error: \"翻译服务异常:#{e.message}\" }\n end\n\n private\n\n def build_prompt(texts, source_lang, target_lang)\n from = lang_label(source_lang)\n to = lang_label(target_lang)\n <<~PROMPT\n 将以下 JSON 数组中的每条文本从#{from}翻译为#{to}。\n 只返回 JSON 数组,顺序与输入一致,不要 markdown 代码块。\n 输入:#{texts.to_json}\n PROMPT\n end\n\n LANG_LABELS = {\n 'zh' => '中文',\n 'en' => '英文',\n 'ja' => '日文',\n 'ko' => '韩文',\n }.freeze\n\n def lang_label(code)\n LANG_LABELS[code.to_s] || code.to_s\n end\n\n def call_api(api_key, prompt)\n http = Net::HTTP.new(API_URL.host, API_URL.port)\n http.use_ssl = true\n http.read_timeout = 60\n req = Net::HTTP::Post.new(API_URL)\n req['Authorization'] = \"Bearer #{api_key}\"\n req['Content-Type'] = 'application/json'\n req.body = {\n model: 'deepseek-chat',\n messages: [{ role: 'user', content: prompt }],\n temperature: 0.2,\n }.to_json\n res = http.request(req)\n raise \"DeepSeek HTTP #{res.code}\" unless res.is_a?(Net::HTTPSuccess)\n res.body\n end\n\n # 未配置 API Key 时的占位译文,便于本地演示 UI\n def placeholder_translations(texts, target_lang)\n prefix = { 'en' => '[EN]', 'zh' => '[中文]', 'ja' => '[JA]', 'ko' => '[KO]' }[target_lang] || \"[#{target_lang}]\"\n texts.map { |t| \"#{prefix} #{t}\" }\n end\n end\nend\n"}, "ebc69e3ca7042f4336d17fe7ea35d7ded99eed8a": {"t": 1785756116.0608795, "n": 2600, "h": "1044a4fd047e8308", "c": "require 'net/http'\nrequire 'json'\n\n# DeepSeek 翻译服务:API Key 仅存于服务端环境变量\nclass DeepseekTranslator\n API_URL = URI('https://api.deepseek.com/chat/completions')\n MAX_TEXTS = 50\n MAX_CHARS = 8000\n\n class << self\n def translate(texts:, source_lang:, target_lang:)\n cleaned = Array(texts).map(&:to_s).reject(&:blank?)\n return { translations: [], error: '没有可翻译的文本' } if cleaned.empty?\n\n if cleaned.join.length > MAX_CHARS || cleaned.length > MAX_TEXTS\n return { translations: [], error: \"单次最多 #{MAX_TEXTS} 条或 #{MAX_CHARS} 字符\" }\n end\n\n api_key = ENV['DEEPSEEK_API_KEY']\n if api_key.blank?\n return {\n translations: placeholder_translations(cleaned, target_lang),\n placeholder: true,\n message: '未配置 DEEPSEEK_API_KEY,返回占位译文。请在 .env 中设置密钥后重启服务。',\n }\n end\n\n prompt = build_prompt(cleaned, source_lang, target_lang)\n response_body = call_api(api_key, prompt)\n parsed = JSON.parse(response_body)\n content = parsed.dig('choices', 0, 'message', 'content')\n translations = JSON.parse(content)\n { translations: translations }\n rescue JSON::ParserError\n { translations: [], error: '翻译结果解析失败' }\n rescue StandardError => e\n { translations: [], error: \"翻译服务异常:#{e.message}\" }\n end\n\n private\n\n def build_prompt(texts, source_lang, target_lang)\n from = lang_label(source_lang)\n to = lang_label(target_lang)\n <<~PROMPT\n 将以下 JSON 数组中的每条文本从#{from}翻译为#{to}。\n 只返回 JSON 数组,顺序与输入一致,不要 markdown 代码块。\n 输入:#{texts.to_json}\n PROMPT\n end\n\n LANG_LABELS = {\n 'zh' => '中文',\n 'en' => '英文',\n 'ja' => '日文',\n 'ko' => '韩文',\n }.freeze\n\n def lang_label(code)\n LANG_LABELS[code.to_s] || code.to_s\n end\n\n def call_api(api_key, prompt)\n http = Net::HTTP.new(API_URL.host, API_URL.port)\n http.use_ssl = true\n http.read_timeout = 60\n req = Net::HTTP::Post.new(API_URL)\n req['Authorization'] = \"Bearer #{api_key}\"\n req['Content-Type'] = 'application/json'\n req.body = {\n model: 'deepseek-chat',\n messages: [{ role: 'user', content: prompt }],\n temperature: 0.2,\n }.to_json\n res = http.request(req)\n raise \"DeepSeek HTTP #{res.code}\" unless res.is_a?(Net::HTTPSuccess)\n res.body\n end\n\n # 未配置 API Key 时的占位译文,便于本地演示 UI\n def placeholder_translations(texts, target_lang)\n prefix = { 'en' => '[EN]', 'zh' => '[中文]', 'ja' => '[JA]', 'ko' => '[KO]' }[target_lang] || \"[#{target_lang}]\"\n texts.map { |t| \"#{prefix} #{t}\" }\n end\n end\nend\n"}}, ".env.example": {"8f2d1306c5010eb0cabaa2e9038640497165af2f": {"t": 1786068614.7325876, "n": 85, "h": "0c46fc7b81dbf82e", "c": "# 复制为 .env 并填入你的 DeepSeek API Key(不要提交 .env 到 git)\nDEEPSEEK_API_KEY=sk-your-key-here\n"}}}}