-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathDeepSeekTranslate.cs
More file actions
136 lines (116 loc) · 5.41 KB
/
Copy pathDeepSeekTranslate.cs
File metadata and controls
136 lines (116 loc) · 5.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using Nikse.SubtitleEdit.Core.Common;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
using Nikse.SubtitleEdit.Core.Translate;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Nikse.SubtitleEdit.Core.Settings;
namespace Nikse.SubtitleEdit.Core.AutoTranslate
{
public class DeepSeekTranslate : IAutoTranslator, IAutoTranslatorWithContext, IDisposable
{
private HttpClient _httpClient;
public static string StaticName { get; set; } = "DeepSeek";
public override string ToString() => StaticName;
public string Name => StaticName;
public string Url => "https://api.deepseek.com";
public string Error { get; set; }
public int MaxCharacters => 1500;
/// <summary>
/// See https://api-docs.deepseek.com/
/// </summary>
public static string[] Models => new[]
{
"deepseek-v4-flash",
"deepseek-v4-pro",
};
public void Initialize()
{
_httpClient?.Dispose();
_httpClient = HttpClientFactoryWithProxy.CreateHttpClientWithProxy();
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("accept", "application/json");
_httpClient.BaseAddress = new Uri(Configuration.Settings.Tools.DeepSeekUrl.TrimEnd('/'));
_httpClient.Timeout = TimeSpan.FromMinutes(15);
if (!string.IsNullOrEmpty(Configuration.Settings.Tools.DeepSeekApiKey))
{
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Bearer " + Configuration.Settings.Tools.DeepSeekApiKey);
}
}
public List<TranslationPair> GetSupportedSourceLanguages()
{
return ListLanguages();
}
public List<TranslationPair> GetSupportedTargetLanguages()
{
return ListLanguages();
}
public async Task<string> Translate(string text, string sourceLanguageCode, string targetLanguageCode, CancellationToken cancellationToken)
{
return await Translate(text, sourceLanguageCode, targetLanguageCode, string.Empty, string.Empty, cancellationToken);
}
public async Task<string> Translate(string text, string sourceLanguageCode, string targetLanguageCode, string previousLineText, string nextLineText, CancellationToken cancellationToken)
{
var model = Configuration.Settings.Tools.DeepSeekModel;
if (string.IsNullOrEmpty(model))
{
model = Models[0];
Configuration.Settings.Tools.DeepSeekModel = model;
}
if (string.IsNullOrEmpty(Configuration.Settings.Tools.DeepSeekPrompt))
{
Configuration.Settings.Tools.DeepSeekPrompt = new ToolsSettings().DeepSeekPrompt;
}
var prompt = string.Format(Configuration.Settings.Tools.DeepSeekPrompt, sourceLanguageCode, targetLanguageCode, previousLineText, nextLineText);
var input = "{\"model\": \"" + model + "\",\"messages\": [{ \"role\": \"user\", \"content\": \"" + Json.EncodeJsonText(prompt) + "\\n\\n" + Json.EncodeJsonText(text.Trim()) + "\" }]}";
int[] retryDelays = { 2555, 5007, 9013 };
HttpResponseMessage result = null;
string resultContent = null;
for (var attempt = 0; attempt <= retryDelays.Length; attempt++)
{
var content = new StringContent(input, Encoding.UTF8);
content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
result = await _httpClient.PostAsync(string.Empty, content, cancellationToken);
resultContent = await result.Content.ReadAsStringAsync();
if (!DeepLTranslate.ShouldRetry(result, resultContent) || attempt == retryDelays.Length)
{
break;
}
await Task.Delay(retryDelays[attempt], cancellationToken);
}
if (!result.IsSuccessStatusCode)
{
Error = resultContent;
SeLogger.Error("DeepSeek Translate failed calling API: Status code=" + result.StatusCode + Environment.NewLine + resultContent);
}
result.EnsureSuccessStatusCode();
var parser = new SeJsonParser();
var resultText = parser.GetFirstObject(resultContent, "content");
if (resultText == null)
{
return string.Empty;
}
var outputText = Json.DecodeJsonText(resultText).Trim();
if (outputText.StartsWith('"') && outputText.EndsWith('"') && !text.StartsWith('"'))
{
outputText = outputText.Trim('"').Trim();
}
outputText = ChatGptTranslate.FixNewLines(outputText);
outputText = ChatGptTranslate.RemovePreamble(text, outputText);
outputText = ChatGptTranslate.DecodeUnicodeEscapes(outputText);
return outputText.Trim();
}
public static List<TranslationPair> ListLanguages()
{
return ChatGptTranslate.ListLanguages();
}
public void Dispose()
{
_httpClient?.Dispose();
}
}
}