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+ }
0 commit comments