View Javadoc
1   package io.github.magwas.coder.command;
2   
3   import java.io.IOException;
4   import java.net.http.HttpResponse;
5   import java.util.HashMap;
6   import java.util.List;
7   import java.util.Map;
8   
9   import org.springframework.beans.factory.annotation.Autowired;
10  import org.springframework.stereotype.Service;
11  
12  import com.fasterxml.jackson.databind.ObjectMapper;
13  
14  import io.github.magwas.coder.*;
15  import io.github.magwas.coder.config.ApiKeyConfigService;
16  import io.github.magwas.coder.conversation.ConversationState;
17  import io.github.magwas.coder.dependencies.ObjectMapperWrapper;
18  import io.github.magwas.coder.dependencies.SystemWrapper;
19  import io.github.magwas.coder.dependencies.TimeWrapper;
20  import io.github.magwas.coder.file.FileConstants;
21  import io.github.magwas.coder.file.FileWriterService;
22  import io.github.magwas.coder.openrouter.*;
23  
24  @Service
25  public class AskAICommandService implements ProcessingStepService {
26  
27  	@Autowired
28  	SystemWrapper systemDependency;
29  
30  	@Autowired
31  	OpenRouterClientService openRouterClientService;
32  
33  	@Autowired
34  	ConversationState conversationState;
35  
36  	@Autowired
37  	OpenRouterRequestService requestService;
38  
39  	@Autowired
40  	FileWriterService fileWriterService;
41  
42  	@Autowired
43  	ApiKeyConfigService apiKeyConfigService;
44  
45  	@Autowired
46  	TimeWrapper timeDependency;
47  
48  	@Autowired
49  	ObjectMapperWrapper objectMapperWrapper;
50  
51  	@Override
52  	public ProcessingContextData apply(ProcessingContextData context, List<String> args) {
53  		if (args.size() < 3) return new ProcessingContextData(500, "usage: askAi modelId doReasoning", context.meta());
54  		String modelId = args.get(1);
55  		Boolean doReasoning = Boolean.getBoolean(args.get(2));
56  
57  		Map<String, String> meta = new HashMap<>();
58  
59  		try {
60  			systemDependency.println(UIConstants.GOT_INPUT);
61  			conversationState.history.add(new RequestMessageData("user", context.content()));
62  			String requestBody = requestService.apply(conversationState.history, modelId, doReasoning);
63  			fileWriterService.apply(FileConstants.REQUEST_DUMP_PATH, requestBody);
64  
65  			String authHeader = apiKeyConfigService.apply();
66  
67  			long startTime = timeDependency.currentTimeMillis();
68  			HttpResponse<String> response1 = openRouterClientService.apply(requestBody, authHeader);
69  			long endTime = timeDependency.currentTimeMillis();
70  			long duration = endTime - startTime;
71  
72  			meta.put("duration", Long.toString(duration));
73  
74  			if (response1.statusCode() == 200) {
75  				String responseBody = response1.body();
76  				fileWriterService.apply(FileConstants.RESPONSE_DUMP_PATH, responseBody);
77  				ObjectMapper mapper = objectMapperWrapper.objectMapper;
78  				OpenRouterResponseData aiResponse = mapper.readValue(responseBody, OpenRouterResponseData.class);
79  				ChoiceData choice = aiResponse.choices()[0];
80  				MessageData message = choice.message();
81  				meta.put("reasoning", message.reasoning());
82  				return new ProcessingContextData(200, message.content(), meta);
83  			} else {
84  				return new ProcessingContextData(response1.statusCode(), response1.body(), meta);
85  			}
86  		} catch (IOException | InterruptedException e) {
87  			return new ProcessingContextData(500, e.getMessage(), meta);
88  		}
89  	}
90  }