Skip to content

Commit 52a5b51

Browse files
authored
Merge pull request #19 from profiq/azure-support
Azure support
2 parents e0f6ba0 + c8db465 commit 52a5b51

11 files changed

Lines changed: 276 additions & 116 deletions

File tree

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44
}
55

66
group = "com.profiq"
7-
version = "0.1.6"
7+
version = "0.1.7"
88

99
repositories {
1010
mavenCentral()
@@ -18,7 +18,8 @@ dependencies {
1818
// Configure Gradle IntelliJ Plugin
1919
// Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html
2020
intellij {
21-
version.set("2024.1")
21+
version.set("PY-2024.1")
22+
type.set("PY")
2223
plugins.set(listOf())
2324
}
2425

gradlew

100755100644
File mode changed.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.profiq.codexor;
2+
3+
import java.util.regex.Matcher;
4+
import java.util.regex.Pattern;
5+
6+
/**
7+
* Takes in a response from OpenAI API and formats it into a proper Python docstring.
8+
*/
9+
public class DocstringFormatter {
10+
11+
private final String openaiResponse;
12+
private String[] docstringLines = null;
13+
14+
public DocstringFormatter(String openaiResponse) {
15+
this.openaiResponse = openaiResponse;
16+
}
17+
18+
public String docstringWithIndentation(String indentation) {
19+
String[] docstringLines = getDocstringLines();
20+
21+
StringBuilder docstring = new StringBuilder();
22+
for (String line : docstringLines) {
23+
docstring.append(indentation).append(line).append("\n");
24+
}
25+
26+
return docstring.toString();
27+
}
28+
29+
private String[] getDocstringLines() {
30+
if (docstringLines == null) {
31+
Pattern docstringRegex = Pattern.compile("(([ \t]*)\"\"\".*\"\"\")", Pattern.DOTALL);
32+
Matcher docstringMatcher = docstringRegex.matcher(openaiResponse);
33+
34+
if (!docstringMatcher.find()) {
35+
throw new IllegalArgumentException("No docstring found in the OpenAI response.");
36+
}
37+
38+
String docstring = docstringMatcher.group(1);
39+
String indentation = docstringMatcher.group(2);
40+
String[] docstringLinesRaw = docstring.split("\n");
41+
42+
docstringLines = new String[docstringLinesRaw.length];
43+
int substringIdx = 0;
44+
45+
for (int i = 0; i < docstringLinesRaw.length; i++) {
46+
substringIdx = Math.min(docstringLinesRaw[i].length(), indentation.length());
47+
docstringLines[i] = docstringLinesRaw[i].substring(substringIdx);
48+
}
49+
}
50+
51+
return docstringLines;
52+
}
53+
}

src/main/java/com/profiq/codexor/GenerateDocumentationAction.java

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,8 @@ public void run(@NotNull ProgressIndicator indicator) {
7575
if (response.statusCode() == 200) {
7676
var responseParsed = (new Gson()).fromJson(response.body(), Response.class);
7777
var responseText = responseParsed.getChoices()[0].getMessage().getContent();
78-
String docstring = parseDocstring(responseText);
7978
var app = ApplicationManager.getApplication();
80-
app.invokeLater(() -> showEditor(e, docstring));
79+
app.invokeLater(() -> showEditor(e, responseText));
8180
} else {
8281
indicator.cancel();
8382
showError(response.body());
@@ -111,35 +110,45 @@ public void run(@NotNull ProgressIndicator indicator) {
111110
}
112111
}
113112

114-
private static HttpRequest buildRequest(String apiKey, String model, String prompt, String code) {
115-
var messages = new Message[]{new Message("user", prompt + "```" + code + "```")};
113+
private HttpRequest buildRequest(String apiKey, String model, String prompt, String code) {
114+
var endpointURL = getEndpointURL();
115+
var isAzure = endpointURL.contains("azure");
116+
117+
if (isAzure) {
118+
endpointURL = endpointURL + "openai/deployments/" + model + "/chat/completions?api-version=2024-02-01";
119+
}
120+
121+
var messages = new Message[]{new Message(prompt + "```" + code + "```")};
116122
var requestBody = new Request(model, messages, 0);
117123
var requestJson = new Gson().toJson(requestBody);
118124

119-
return HttpRequest.newBuilder(URI.create("https://api.openai.com/v1/chat/completions"))
120-
.header("Authorization", "Bearer " + apiKey)
121-
.header("Content-Type", "application/json")
125+
var requestBuilder = HttpRequest.newBuilder(URI.create(endpointURL));
126+
127+
if (isAzure) {
128+
requestBuilder.header("api-key", apiKey);
129+
} else {
130+
requestBuilder.header("Authorization", "Bearer " + apiKey);
131+
}
132+
133+
return requestBuilder.header("Content-Type", "application/json")
122134
.POST(HttpRequest.BodyPublishers.ofString(requestJson))
123135
.build();
124136
}
125137

126-
private String parseDocstring(String responseText) {
127-
Pattern pattern = Pattern.compile(":\n(\\s*\"\"\".*\"\"\")", Pattern.DOTALL);
128-
Matcher matcher = pattern.matcher(responseText);
129-
if (matcher.find()) {
130-
String docstring = matcher.group(1);
131-
String[] docstringSplit = docstring.split("\"\"\"");
132-
docstring = docstringSplit[0] + "\"\"\"" + docstringSplit[1] + "\"\"\"";
133-
return docstring;
138+
private String getEndpointURL() {
139+
String endpointInput = PropertiesComponent.getInstance().getValue(SettingsConfigurable.ENDPOINT_SETTINGS_KEY);
140+
141+
if (endpointInput == null || endpointInput.isEmpty()) {
142+
return "https://api.openai.com/v1/chat/completions";
134143
} else {
135-
return "";
144+
return endpointInput;
136145
}
137146
}
138147

139148
private String getApiKey() throws IOException {
140149
String apiKeyInput = PropertiesComponent.getInstance().getValue(SettingsConfigurable.API_KEY_SETTING_KEY);
141150

142-
if (apiKeyInput == null || apiKeyInput.length() == 0) {
151+
if (apiKeyInput == null || apiKeyInput.isEmpty()) {
143152
apiKeyInput = JOptionPane.showInputDialog("Enter your Open AI API key:");
144153
PropertiesComponent.getInstance().setValue(SettingsConfigurable.API_KEY_SETTING_KEY, apiKeyInput);
145154
}
@@ -175,7 +184,7 @@ private void showError(String text) {
175184
JOptionPane.showMessageDialog(null, text, "Error", JOptionPane.ERROR_MESSAGE);
176185
}
177186

178-
private void showEditor(AnActionEvent e, String docstring) {
187+
private void showEditor(AnActionEvent e, String responseText) {
179188
var resultWindow = new JFrame();
180189
var virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE);
181190
var fileType = FileTypeManager.getInstance().getFileTypeByFile(virtualFile);
@@ -185,7 +194,8 @@ private void showEditor(AnActionEvent e, String docstring) {
185194
return;
186195
}
187196

188-
var newDocument = EditorFactory.getInstance().createDocument(applyIndentation(docstring, ""));
197+
DocstringFormatter docstringFormatter = new DocstringFormatter(responseText);
198+
var newDocument = EditorFactory.getInstance().createDocument(docstringFormatter.docstringWithIndentation(""));
189199
var editor = EditorFactory.getInstance().createEditor(newDocument, null, fileType, false);
190200
editor.getContentComponent().setPreferredSize(new Dimension(1000, 800));
191201
var confirmBtn = new JButton("Insert");
@@ -196,7 +206,7 @@ private void showEditor(AnActionEvent e, String docstring) {
196206
int lineEndOffset = mainDocument.getLineEndOffset(caretPosition.line);
197207
int nextLineStartOffset = mainDocument.getLineStartOffset(caretPosition.line + 1);
198208
int offset = Math.min(lineEndOffset + 1, nextLineStartOffset);
199-
String formattedDocstring = applyIndentation(docstring, correctIndentation);
209+
String formattedDocstring = docstringFormatter.docstringWithIndentation(correctIndentation);
200210

201211
confirmBtn.addActionListener(actionEvent -> {
202212
var app = ApplicationManager.getApplication();
@@ -215,31 +225,6 @@ private void showEditor(AnActionEvent e, String docstring) {
215225
resultWindow.setLocationRelativeTo(null);
216226
}
217227

218-
private String applyIndentation(String docstring, String indentation) {
219-
Pattern pattern = Pattern.compile("^(\\s+)");
220-
Matcher matcher = pattern.matcher(docstring);
221-
222-
if (matcher.find()) {
223-
String leadingWhitespace = matcher.group(1);
224-
int minIndent = leadingWhitespace.length();
225-
String[] lines = docstring.split("\n");
226-
StringBuilder unindented = new StringBuilder();
227-
228-
for (String line : lines) {
229-
unindented.append(indentation);
230-
231-
if (line.length() >= minIndent) {
232-
unindented.append(line.substring(minIndent));
233-
}
234-
unindented.append("\n");
235-
}
236-
237-
return unindented.toString();
238-
}
239-
240-
return docstring;
241-
}
242-
243228
private String determineCorrectIndentation(String code) {
244229
Pattern pattern = Pattern.compile("\n(\\s+)");
245230
Matcher matcher = pattern.matcher(code);
@@ -250,4 +235,4 @@ private String determineCorrectIndentation(String code) {
250235

251236
return "";
252237
}
253-
}
238+
}

src/main/java/com/profiq/codexor/Message.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22

33
public class Message {
44

5-
private String role;
5+
public String role = "user";
66
private String content;
77

8-
public Message(String role, String content) {
9-
this.role = role;
8+
public Message(String content) {
109
this.content = content;
1110
}
1211

src/main/java/com/profiq/codexor/Response.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,4 @@ public class Response {
77
Choice[] getChoices() {
88
return choices;
99
}
10-
1110
}

0 commit comments

Comments
 (0)