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 }