Skip to content

Commit 2c07bfe

Browse files
WIP
1 parent b6f8bec commit 2c07bfe

File tree

3 files changed

+174
-2
lines changed

3 files changed

+174
-2
lines changed

hasheous-taskrunner/Classes/Tasks/AITask.cs renamed to hasheous-taskrunner/Classes/Tasks/AIDescriptionAndTaggingTask.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace hasheous_taskrunner.Classes.Tasks
66
/// <summary>
77
/// Represents an AI task that can be executed by the task runner.
88
/// </summary>
9-
public class AITask : ITask
9+
public class AIDescriptionAndTaggingTask : ITask
1010
{
1111
private const int MaxSourceCount = 25;
1212
private const int MaxSourceItemChars = 100_000;
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
using hasheous_taskrunner.Classes.Capabilities;
2+
using hasheous_taskrunner.Classes.Helpers;
3+
4+
namespace hasheous_taskrunner.Classes.Tasks
5+
{
6+
public class AILanguageFileTranslationTask : ITask
7+
{
8+
public TaskType TaskType => TaskType.AILanguageFileTranslation;
9+
10+
/// <inheritdoc />
11+
public async Task<TaskVerificationResult> VerifyAsync(Dictionary<string, string>? parameters, CancellationToken cancellationToken)
12+
{
13+
// check for required parameters - model and prompt
14+
TaskVerificationResult verificationResults = new TaskVerificationResult();
15+
16+
if (parameters == null)
17+
{
18+
verificationResults.Status = TaskVerificationResult.VerificationStatus.Failure;
19+
verificationResults.Details["parameters"] = "Parameters cannot be null.";
20+
return await Task.FromResult(verificationResults);
21+
}
22+
23+
if (!parameters.ContainsKey("model"))
24+
{
25+
verificationResults.Details["model"] = "Missing required parameter: model";
26+
}
27+
28+
if (!parameters.ContainsKey("prompt"))
29+
{
30+
verificationResults.Details["prompt"] = "Missing required parameter: prompt";
31+
}
32+
33+
if (!parameters.ContainsKey("language_name_in_english"))
34+
{
35+
verificationResults.Details["language_name_in_english"] = "Missing required parameter: language_name_in_english";
36+
}
37+
38+
if (verificationResults.Details.Count > 0)
39+
{
40+
verificationResults.Status = TaskVerificationResult.VerificationStatus.Failure;
41+
}
42+
else
43+
{
44+
verificationResults.Status = TaskVerificationResult.VerificationStatus.Success;
45+
}
46+
47+
return await Task.FromResult(verificationResults);
48+
49+
}
50+
51+
/// <inheritdoc />
52+
public async Task<Dictionary<string, object>> ExecuteAsync(Dictionary<string, string>? parameters, StatusUpdate statusUpdate, CancellationToken cancellationToken)
53+
{
54+
if (parameters == null)
55+
{
56+
return new Dictionary<string, object>
57+
{
58+
{ "result", false },
59+
{ "error", "Parameters cannot be null." }
60+
};
61+
}
62+
63+
var verification = await VerifyAsync(parameters, cancellationToken);
64+
if (verification.Status != TaskVerificationResult.VerificationStatus.Success)
65+
{
66+
string verificationError = string.Join("; ", verification.Details.Select(d => $"{d.Key}: {d.Value}"));
67+
statusUpdate.AddStatus(StatusUpdate.StatusItem.StatusType.Error, "AITask verification failed before execution: " + verificationError);
68+
return new Dictionary<string, object>
69+
{
70+
{ "result", false },
71+
{ "error", "Verification failed: " + verificationError }
72+
};
73+
}
74+
75+
// use the model and prompt parameters to call Ollama API
76+
var ai = Classes.Capabilities.Capabilities.GetCapabilityById<ICapability>(20); // AI capability
77+
if (ai == null)
78+
{
79+
throw new InvalidOperationException("AI capability is not available.");
80+
}
81+
82+
// get english language file from host
83+
string enuri = new Uri(new Uri(Config.BaseUriPath), "/localisation/en.json").ToString();
84+
string? englishLanguageFileContent = await TaskRunner.Classes.HttpHelper.Get<string>(enuri);
85+
if (englishLanguageFileContent == null)
86+
{
87+
return new Dictionary<string, object>
88+
{
89+
{ "result", false },
90+
{ "error", "Failed to retrieve English language file from host." }
91+
};
92+
}
93+
94+
// deserialise the english language file into a Dictionary<string, string>
95+
Dictionary<string, string>? englishLanguageFile = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(englishLanguageFileContent);
96+
if (englishLanguageFile == null)
97+
{
98+
return new Dictionary<string, object>
99+
{
100+
{ "result", false },
101+
{ "error", "Failed to deserialise English language file." }
102+
};
103+
}
104+
105+
Dictionary<string, string> translatedLanguageFile = new Dictionary<string, string>();
106+
foreach (var kvp in englishLanguageFile)
107+
{
108+
string prompt = parameters["prompt"].Replace("<TEXT_TO_TRANSLATE>", kvp.Key);
109+
110+
// call the AI capability to translate the text
111+
var translationResult = await ai.ExecuteAsync(new Dictionary<string, object>
112+
{
113+
{ "model", parameters["model"] },
114+
{ "prompt", prompt }
115+
}, statusUpdate);
116+
117+
Dictionary<string, object> response = new Dictionary<string, object>();
118+
if (translationResult == null)
119+
{
120+
response = new Dictionary<string, object>
121+
{
122+
{ "result", false },
123+
{ "error", $"Translation failed for key: {kvp.Key}" }
124+
};
125+
}
126+
127+
if (translationResult != null && translationResult.ContainsKey("result") && !(bool)translationResult["result"])
128+
{
129+
response = new Dictionary<string, object>
130+
{
131+
{ "result", true },
132+
{ "error", translationResult.ContainsKey("error") ? translationResult["error"] : "Unknown error from AI capability." }
133+
};
134+
135+
statusUpdate.AddStatus(StatusUpdate.StatusItem.StatusType.Error, "AITask: AI capability returned an error: " + (response.ContainsKey("error") ? response["error"] : "Unknown error."));
136+
}
137+
else if (translationResult != null && translationResult.ContainsKey("result") && (bool)translationResult["result"] && translationResult.ContainsKey("response"))
138+
{
139+
translatedLanguageFile[kvp.Key] = translationResult["response"].ToString() ?? "";
140+
}
141+
else
142+
{
143+
response = new Dictionary<string, object>
144+
{
145+
{ "result", false },
146+
{ "error", $"Unexpected response from AI capability for key: {kvp.Key}" }
147+
};
148+
149+
statusUpdate.AddStatus(StatusUpdate.StatusItem.StatusType.Error, "AITask: Unexpected response from AI capability for key: " + kvp.Key);
150+
}
151+
}
152+
153+
// return the translated language file as a JSON string in the "response" key
154+
string translatedLanguageFileJson = System.Text.Json.JsonSerializer.Serialize(translatedLanguageFile);
155+
return new Dictionary<string, object>
156+
{
157+
{ "result", true },
158+
{ "response", translatedLanguageFileJson }
159+
};
160+
}
161+
}
162+
}

hasheous-taskrunner/Classes/Tasks/ITask.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,17 @@ public enum TaskType
164164
/// <summary>
165165
/// Task for AI description generation and tagging.
166166
/// </summary>
167-
AIDescriptionAndTagging = 0
167+
AIDescriptionAndTagging = 0,
168+
169+
/// <summary>
170+
/// Task for AI language file translation.
171+
/// </summary>
172+
AILanguageFileTranslation = 10,
173+
174+
/// <summary>
175+
/// Task for AI language key translation.
176+
/// </summary>
177+
AILanguageKeyTranslation = 11
168178
}
169179

170180
/// <summary>

0 commit comments

Comments
 (0)