From 7df12aeca2cef0979413bb6584cd3e083b48f995 Mon Sep 17 00:00:00 2001 From: Daniel Hu Date: Tue, 21 Nov 2023 11:22:16 +0800 Subject: [PATCH] Feat: new api getSetting/request Signed-off-by: Daniel Hu --- api/setting.md | 93 +++++++++++++++++++ .../java/ai/devchat/cli/DevChatWrapper.java | 4 +- .../devchat/devchat/ActionHandlerFactory.java | 1 + .../ai/devchat/devchat/DevChatActions.java | 2 + .../devchat/handler/GetKeyRequestHandler.java | 5 +- .../handler/GetSettingRequestHandler.java | 56 +++++++++++ .../handler/ListModelsRequestHandler.java | 2 + .../handler/SendMessageRequestHandler.java | 4 +- .../setting/DevChatSettingsComponent.java | 10 ++ .../setting/DevChatSettingsConfigurable.java | 87 ++++++++--------- .../idea/setting/DevChatSettingsState.java | 2 + 11 files changed, 220 insertions(+), 46 deletions(-) create mode 100644 api/setting.md create mode 100644 src/main/java/ai/devchat/devchat/handler/GetSettingRequestHandler.java diff --git a/api/setting.md b/api/setting.md new file mode 100644 index 0000000..af0ad62 --- /dev/null +++ b/api/setting.md @@ -0,0 +1,93 @@ +## Get Setting + +### JS to Java + +```json +{ + "action": "getSetting/request", + "metadata": { + "callback": "responseFunctionName" + }, + "payload": null +} +``` + +### Java to JS + +- success + +```json +{ + "action": "getSetting/response", + "metadata": { + "status": "success", + "error": "" + }, + "payload": { + "setting": { + "apiKey": "DC.abcdef123456", + "apiBase": "https://api.example.com/v1", + "currentModel": "gpt-4" + } + } +} +``` + +- failed + +```json +{ + "action": "getSetting/response", + "metadata": { + "status": "Failed", + "error": "Failed to get setting." + }, + "payload": null +} +``` + +## Set or Update Setting + +### JS to Java + +```json +{ + "action": "updateSetting/request", + "metadata": { + "callback": "responseFunctionName" + }, + "payload": { + "setting": { + "currentModel": "gpt-3.5" + } + } +} +``` + +### Java to JS + +- success + +```json +{ + "action": "updateSetting/response", + "metadata": { + "status": "success", + "error": "" + }, + "payload": null +} +``` + +- failed + +```json +{ + "action": "updateSetting/response", + "metadata": { + "status": "Failed", + "error": "Failed to update setting." + }, + "payload": null +} +``` diff --git a/src/main/java/ai/devchat/cli/DevChatWrapper.java b/src/main/java/ai/devchat/cli/DevChatWrapper.java index e04ff45..62931f0 100644 --- a/src/main/java/ai/devchat/cli/DevChatWrapper.java +++ b/src/main/java/ai/devchat/cli/DevChatWrapper.java @@ -17,6 +17,7 @@ public class DevChatWrapper { private String apiBase; private String apiKey; + private String currentModel; private String command; private final String DEFAULT_LOG_MAX_COUNT = "100"; @@ -24,9 +25,10 @@ public DevChatWrapper(String command) { this.command = command; } - public DevChatWrapper(String apiBase, String apiKey, String command) { + public DevChatWrapper(String apiBase, String apiKey, String currentModel, String command) { this.apiBase = apiBase; this.apiKey = apiKey; + this.currentModel = currentModel; this.command = command; } diff --git a/src/main/java/ai/devchat/devchat/ActionHandlerFactory.java b/src/main/java/ai/devchat/devchat/ActionHandlerFactory.java index 1ca80b7..971c854 100644 --- a/src/main/java/ai/devchat/devchat/ActionHandlerFactory.java +++ b/src/main/java/ai/devchat/devchat/ActionHandlerFactory.java @@ -23,6 +23,7 @@ public class ActionHandlerFactory { put(DevChatActions.ADD_CONTEXT_REQUEST, AddContextRequestHandler.class); put(DevChatActions.GET_KEY_REQUEST, GetKeyRequestHandler.class); put(DevChatActions.COMMIT_CODE_REQUEST, CommitCodeRequestHandler.class); + put(DevChatActions.GET_SETTING_REQUEST, GetSettingRequestHandler.class); } }; diff --git a/src/main/java/ai/devchat/devchat/DevChatActions.java b/src/main/java/ai/devchat/devchat/DevChatActions.java index 40918a4..90ba477 100644 --- a/src/main/java/ai/devchat/devchat/DevChatActions.java +++ b/src/main/java/ai/devchat/devchat/DevChatActions.java @@ -28,4 +28,6 @@ public class DevChatActions { public static final String GET_KEY_RESPONSE = "getKey/response"; public static final String COMMIT_CODE_REQUEST = "commitCode/request"; public static final String COMMIT_CODE_RESPONSE = "commitCode/response"; + public static final String GET_SETTING_REQUEST = "getSetting/request"; + public static final String GET_SETTING_RESPONSE = "getSetting/response"; } diff --git a/src/main/java/ai/devchat/devchat/handler/GetKeyRequestHandler.java b/src/main/java/ai/devchat/devchat/handler/GetKeyRequestHandler.java index 5cb84af..ca13ad8 100644 --- a/src/main/java/ai/devchat/devchat/handler/GetKeyRequestHandler.java +++ b/src/main/java/ai/devchat/devchat/handler/GetKeyRequestHandler.java @@ -2,6 +2,7 @@ import ai.devchat.devchat.ActionHandler; import ai.devchat.devchat.DevChatActionHandler; +import ai.devchat.devchat.DevChatActions; import ai.devchat.idea.storage.SensitiveDataStorage; import com.alibaba.fastjson.JSONObject; @@ -20,13 +21,13 @@ public void executeAction() { String key = SensitiveDataStorage.getKey(); if (key != null && !key.isEmpty()) { - devChatActionHandler.sendResponse("getKey/response", callbackFunc, (metadata, payload) -> { + devChatActionHandler.sendResponse(DevChatActions.GET_KEY_RESPONSE, callbackFunc, (metadata, payload) -> { metadata.put("status", "success"); metadata.put("error", ""); payload.put("key", key); }); } else { - devChatActionHandler.sendResponse("getKey/response", callbackFunc, (metadata, payload) -> { + devChatActionHandler.sendResponse(DevChatActions.GET_KEY_RESPONSE, callbackFunc, (metadata, payload) -> { metadata.put("status", "error"); metadata.put("error", "key is empty"); }); diff --git a/src/main/java/ai/devchat/devchat/handler/GetSettingRequestHandler.java b/src/main/java/ai/devchat/devchat/handler/GetSettingRequestHandler.java new file mode 100644 index 0000000..7282c67 --- /dev/null +++ b/src/main/java/ai/devchat/devchat/handler/GetSettingRequestHandler.java @@ -0,0 +1,56 @@ +package ai.devchat.devchat.handler; + +import ai.devchat.devchat.ActionHandler; +import ai.devchat.devchat.DevChatActionHandler; +import ai.devchat.devchat.DevChatActions; +import ai.devchat.idea.setting.DevChatSettingsState; +import ai.devchat.idea.storage.SensitiveDataStorage; +import com.alibaba.fastjson.JSONObject; + +public class GetSettingRequestHandler implements ActionHandler { + private JSONObject metadata; + private JSONObject payload; + private final DevChatActionHandler devChatActionHandler; + + public GetSettingRequestHandler(DevChatActionHandler devChatActionHandler) { + this.devChatActionHandler = devChatActionHandler; + } + + @Override + public void executeAction() { + String callbackFunc = metadata.getString("callback"); + + DevChatSettingsState settings = DevChatSettingsState.getInstance(); + String apiKey = SensitiveDataStorage.getKey(); + if (settings.apiBase == null || settings.apiBase.isEmpty()) { + if (apiKey.startsWith("sk-")) { + settings.apiBase = "https://api.openai.com/v1"; + } else if (apiKey.startsWith("DC.")) { + settings.apiBase = "https://api.devchat.ai/v1"; + } + } + + String apiBase = settings.apiBase; + String currentModel = settings.defaultModel; + + devChatActionHandler.sendResponse(DevChatActions.GET_SETTING_RESPONSE, callbackFunc, (metadata, payload) -> { + metadata.put("status", "success"); + metadata.put("error", ""); + JSONObject setting = new JSONObject(); + setting.put("apiKey", apiKey); + setting.put("apiBase", apiBase); + setting.put("currentModel", currentModel); + payload.put("setting", setting); + }); + } + + @Override + public void setMetadata(JSONObject metadata) { + this.metadata = metadata; + } + + @Override + public void setPayload(JSONObject payload) { + this.payload = payload; + } +} diff --git a/src/main/java/ai/devchat/devchat/handler/ListModelsRequestHandler.java b/src/main/java/ai/devchat/devchat/handler/ListModelsRequestHandler.java index eecbc23..8ddc518 100644 --- a/src/main/java/ai/devchat/devchat/handler/ListModelsRequestHandler.java +++ b/src/main/java/ai/devchat/devchat/handler/ListModelsRequestHandler.java @@ -28,6 +28,8 @@ public void executeAction() { List modelList = new ArrayList<>(); modelList.add("gpt-3.5-turbo"); modelList.add("gpt-4"); + modelList.add("gpt-3.5-turbo-16k"); + modelList.add("claude-2"); devChatActionHandler.sendResponse(DevChatActions.LIST_MODELS_RESPONSE, callbackFunc, (metadata, payload) -> { metadata.put("status", "success"); diff --git a/src/main/java/ai/devchat/devchat/handler/SendMessageRequestHandler.java b/src/main/java/ai/devchat/devchat/handler/SendMessageRequestHandler.java index b9644cb..bd79f6c 100644 --- a/src/main/java/ai/devchat/devchat/handler/SendMessageRequestHandler.java +++ b/src/main/java/ai/devchat/devchat/handler/SendMessageRequestHandler.java @@ -92,10 +92,12 @@ public void executeAction() { DevChatSettingsState settings = DevChatSettingsState.getInstance(); if (settings.apiBase != null && !settings.apiBase.isEmpty()) { apiBase = settings.apiBase; + } else { + settings.apiBase = apiBase; } DevChatResponseConsumer responseConsumer = getResponseConsumer(callbackFunc); - DevChatWrapper devchatWrapper = new DevChatWrapper(apiBase, apiKey, devchatCommandPath); + DevChatWrapper devchatWrapper = new DevChatWrapper(apiBase, apiKey, settings.defaultModel, devchatCommandPath); devchatWrapper.runPromptCommand(flags, message, responseConsumer); } catch (Exception e) { Log.error("Exception occurred while executing DevChat command. Exception message: " + e.getMessage()); diff --git a/src/main/java/ai/devchat/idea/setting/DevChatSettingsComponent.java b/src/main/java/ai/devchat/idea/setting/DevChatSettingsComponent.java index a7fceb4..b588f1d 100644 --- a/src/main/java/ai/devchat/idea/setting/DevChatSettingsComponent.java +++ b/src/main/java/ai/devchat/idea/setting/DevChatSettingsComponent.java @@ -15,11 +15,13 @@ public class DevChatSettingsComponent { private final JPanel jPanel; private final JBTextField apiBaseText = new JBTextField(); private final JBTextField apiKeyText = new JBTextField(); + private final JBTextField defaultModelText = new JBTextField(); public DevChatSettingsComponent() { jPanel = FormBuilder.createFormBuilder() .addLabeledComponent(new JBLabel("api_base"), apiBaseText, 1, false) .addLabeledComponent(new JBLabel("api_key"), apiKeyText, 2, false) + .addLabeledComponent(new JBLabel("default_model"), defaultModelText, 3, false) .addComponentFillVertically(new JPanel(), 0) .getPanel(); } @@ -41,6 +43,10 @@ public String getApiKey() { return apiKeyText.getText(); } + public String getDefaultModel() { + return defaultModelText.getText(); + } + public void setApiBase(@NotNull String apiBase) { apiBaseText.setText(apiBase); } @@ -48,4 +54,8 @@ public void setApiBase(@NotNull String apiBase) { public void setApiKey(@NotNull String apiKey) { apiKeyText.setText(apiKey); } + + public void setDefaultModel(@NotNull String defaultModel) { + defaultModelText.setText(defaultModel); + } } diff --git a/src/main/java/ai/devchat/idea/setting/DevChatSettingsConfigurable.java b/src/main/java/ai/devchat/idea/setting/DevChatSettingsConfigurable.java index 858bbaf..878a298 100644 --- a/src/main/java/ai/devchat/idea/setting/DevChatSettingsConfigurable.java +++ b/src/main/java/ai/devchat/idea/setting/DevChatSettingsConfigurable.java @@ -12,54 +12,57 @@ */ public class DevChatSettingsConfigurable implements Configurable { - private DevChatSettingsComponent devChatSettingsComponent; + private DevChatSettingsComponent devChatSettingsComponent; - // A default constructor with no arguments is required because this implementation - // is registered in an applicationConfigurable EP + // A default constructor with no arguments is required because this implementation + // is registered in an applicationConfigurable EP - @Nls(capitalization = Nls.Capitalization.Title) - @Override - public String getDisplayName() { - return "DevChat"; - } + @Nls(capitalization = Nls.Capitalization.Title) + @Override + public String getDisplayName() { + return "DevChat"; + } - @Override - public JComponent getPreferredFocusedComponent() { - return devChatSettingsComponent.getPreferredFocusedComponent(); - } + @Override + public JComponent getPreferredFocusedComponent() { + return devChatSettingsComponent.getPreferredFocusedComponent(); + } - @Nullable - @Override - public JComponent createComponent() { - devChatSettingsComponent = new DevChatSettingsComponent(); - return devChatSettingsComponent.getPanel(); - } + @Nullable + @Override + public JComponent createComponent() { + devChatSettingsComponent = new DevChatSettingsComponent(); + return devChatSettingsComponent.getPanel(); + } - @Override - public boolean isModified() { - DevChatSettingsState settings = DevChatSettingsState.getInstance(); - return !devChatSettingsComponent.getApiBase().equals(settings.apiBase) || - !devChatSettingsComponent.getApiKey().equals(settings.apiKey); - } + @Override + public boolean isModified() { + DevChatSettingsState settings = DevChatSettingsState.getInstance(); + return !devChatSettingsComponent.getApiBase().equals(settings.apiBase) || + !devChatSettingsComponent.getApiKey().equals(settings.apiKey) || + !devChatSettingsComponent.getDefaultModel().equals(settings.defaultModel); + } - @Override - public void apply() { - DevChatSettingsState settings = DevChatSettingsState.getInstance(); - settings.apiBase = devChatSettingsComponent.getApiBase(); - settings.apiKey = devChatSettingsComponent.getApiKey(); - SensitiveDataStorage.setKey(settings.apiKey); - } + @Override + public void apply() { + DevChatSettingsState settings = DevChatSettingsState.getInstance(); + settings.apiBase = devChatSettingsComponent.getApiBase(); + settings.apiKey = devChatSettingsComponent.getApiKey(); + settings.defaultModel = devChatSettingsComponent.getDefaultModel(); + SensitiveDataStorage.setKey(settings.apiKey); + } - @Override - public void reset() { - DevChatSettingsState settings = DevChatSettingsState.getInstance(); - devChatSettingsComponent.setApiBase(settings.apiBase); - devChatSettingsComponent.setApiKey(settings.apiKey); - SensitiveDataStorage.setKey(settings.apiKey); - } + @Override + public void reset() { + DevChatSettingsState settings = DevChatSettingsState.getInstance(); + devChatSettingsComponent.setApiBase(settings.apiBase); + devChatSettingsComponent.setApiKey(settings.apiKey); + devChatSettingsComponent.setDefaultModel(settings.defaultModel); + SensitiveDataStorage.setKey(settings.apiKey); + } - @Override - public void disposeUIResources() { - devChatSettingsComponent = null; - } + @Override + public void disposeUIResources() { + devChatSettingsComponent = null; + } } diff --git a/src/main/java/ai/devchat/idea/setting/DevChatSettingsState.java b/src/main/java/ai/devchat/idea/setting/DevChatSettingsState.java index 4c3356e..0f8c653 100644 --- a/src/main/java/ai/devchat/idea/setting/DevChatSettingsState.java +++ b/src/main/java/ai/devchat/idea/setting/DevChatSettingsState.java @@ -23,6 +23,8 @@ public class DevChatSettingsState implements PersistentStateComponent