From cc55925e6e287585cc5dcce78d977202d7bd03d8 Mon Sep 17 00:00:00 2001 From: Manu K Date: Tue, 3 Oct 2023 03:14:54 +0530 Subject: [PATCH] Add proxy url functionality --- package.json | 43 +++++++++++++++---------- src/Diffy.ts | 20 +++++++----- src/service/OpenAiService.ts | 39 ++++++++++++++--------- src/service/WorkspaceService.ts | 56 ++++++++++++++++++++++++++------- 4 files changed, 109 insertions(+), 49 deletions(-) diff --git a/package.json b/package.json index 8f1a387..f3c5b8d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "diffy-explain-ai", "displayName": "DIFFY - Generate Your Commit Message", "description": "Generate Commit Message for You or Explains The Changed Code Using Git Diff And OpenAi In Natural Language", - "version": "1.0.0", + "version": "1.0.2", "publisher": "hitclaw", "engines": { "vscode": "^1.72.0" @@ -91,6 +91,11 @@ "configuration": { "type": "object", "properties": { + "diffy-explain-ai.proxyUrl": { + "type": "string", + "default": "", + "description": "Provide a user-defined URL for the OpenAI API proxy server. Please ensure the server's availability is confirmed. The default value is: https://api.openai.com/v1." + }, "diffy-explain-ai.openAiKey": { "type": "string", "markdownDescription": "Enter your api key from openai.com [Go to API Key Page](https://beta.openai.com/account/api-keys)" @@ -99,25 +104,31 @@ "type": "string", "enum": [ "gpt-4", + "gpt-4-0613", "gpt-4-32k", + "gpt-4-32k-0613", "gpt-3.5-turbo", - "gpt-3.5-turbo-0301" + "gpt-3.5-turbo-0613", + "gpt-3.5-turbo-16k", + "gpt-3.5-turbo-16k-0613" ], "default": "gpt-3.5-turbo", - "markdownDescription": "OpenAI models to use for your prompts. [Documentation](https://beta.openai.com/docs/models/models). \n\n**If you face 400 Bad Request please make sure you are using the right model for your integration method.**", - "order": 36, - "enumItemLabels": [ - "gpt-4", - "gpt-4-32k", - "gpt-3.5-turbo", - "gpt-3.5-turbo-0301" - ], - "markdownEnumDescriptions": [ - "GPT-4, the latest and greatest model from OpenAI. 2x longer inputs than GPT-3.", - "Not yet available? - GPT-4-32k, the latest and greatest model from OpenAI, with 32k tokens. This is 4x GPT-4 max length and 8x GPT-3 max length.", - "Most capable GPT-3.5 model and optimized for chat at 1/10th the cost of `text-davinci-003`. Will be updated with our latest model iteration.", - "Snapshot of `gpt-3.5-turbo` from March 1st 2023. Unlike gpt-3.5-turbo, this model will not receive updates, and will only be supported for a three month period ending on June 1st 2023." - ] + "markdownDescription": "OpenAI models to use for your prompts. [Documentation](https://beta.openai.com/docs/models/models). \n\n**If you face 400 Bad Request please make sure you are using the right model for your integration method.**" + }, + "diffy-explain-ai.temperature": { + "type": "number", + "default": 0.2, + "description": "Temperature is a parameter used in OpenAI's language models to control the level of randomness and creativity in generated text, with higher values making the output more random and lower values making it more deterministic." + }, + "diffy-explain-ai.maxTokens": { + "type": "number", + "default": 196, + "description": "Parameter in OpenAI's language models that limits the maximum length of the generated text output to a specified number of tokens, helping control the length of the response." + }, + "diffy-explain-ai.aiInstructions": { + "type": "string", + "default": "You are to act as the author of a commit message in git. Your mission is to create clean and comprehensive commit messages as per the conventional commit convention and explain WHAT were the changes and mainly WHY the changes were done. I'll send you an output of 'git diff --staged' command, and you are to convert it into a commit message and first line of commit doesn't exceeds '50' characters and Other lines is a short description of why the changes are done after the commit message. Don't start it with 'This commit', just describe the changes. Don't each line above exceeds '50' characters", + "description": "Instruction for AI to following for generation of commit" } } } diff --git a/src/Diffy.ts b/src/Diffy.ts index 984faf4..9324051 100644 --- a/src/Diffy.ts +++ b/src/Diffy.ts @@ -1,5 +1,5 @@ import * as vscode from "vscode"; -import { ExtensionContext, env } from "vscode"; +import { env, ExtensionContext } from "vscode"; import { EventType } from "./@types/EventType"; import BaseDiffy from "./BaseDiffy"; import GitService from "./service/GitService"; @@ -71,9 +71,9 @@ class Diffy extends BaseDiffy { } /* Checking if the api key is defined. */ const apiKey = this.workspaceService?.getOpenAIKey(); - // if (!apiKey) { - // return; - // } + if (!apiKey) { + return; + } /* Getting the current repo. */ const repo = this.gitService?.getCurrentRepo(); if (!repo) { @@ -117,9 +117,9 @@ class Diffy extends BaseDiffy { } /* Checking if the api key is defined. */ const apiKey = this.workspaceService?.getOpenAIKey(); - // if (!apiKey) { - // return; - // } + if (!apiKey) { + return; + } /* Getting the current repo. */ const repo = this.gitService?.getCurrentRepo(); if (!repo) { @@ -164,6 +164,9 @@ class Diffy extends BaseDiffy { } /* Checking if the api key is defined. */ const apiKey = this.workspaceService?.getOpenAIKey(); + if (!apiKey) { + return; + } /* Getting the current repo. */ const repo = this.gitService?.getCurrentRepo(); @@ -214,6 +217,9 @@ class Diffy extends BaseDiffy { } /* Checking if the api key is defined. */ const apiKey = this.workspaceService?.getOpenAIKey(); + if (!apiKey) { + return; + } /* Getting the current repo. */ const repo = this.gitService?.getCurrentRepo(); diff --git a/src/service/OpenAiService.ts b/src/service/OpenAiService.ts index 06d6f3b..cea6626 100644 --- a/src/service/OpenAiService.ts +++ b/src/service/OpenAiService.ts @@ -1,13 +1,10 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import * as vscode from "vscode"; +import { AxiosError } from "axios"; import OpenAI from "openai"; +import * as vscode from "vscode"; +import { window } from "vscode"; import { CacheService } from "./CacheService"; -import { window, workspace } from "vscode"; -import { resolveNaptr } from "dns"; -import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios"; import WorkspaceService from "./WorkspaceService"; -import axiosRetry from "axios-retry"; -import { CONSTANTS } from "../Constants"; export interface OpenAIErrorResponse { status?: boolean; @@ -60,11 +57,16 @@ class OpenAiService implements AIService { if (nameOnly) { gitCmd = "git diff --cached --name-status"; } - const instructions = - "You are a bot generate 'conventional commit' message from the result of '" + - gitCmd + - "' that user given. commit message should be a multiple lines where first line doesn't exceeds '50' characters by following commit message guidelines based on the given git diff changes without mentioning itself"; - let response = await this.getFromOpenApi(instructions, code, openAIKey); + const instructions = WorkspaceService.getInstance().getAIInstructions(); + if (!instructions) { + return null; + } + let response = await this.getFromOpenApi( + instructions, + code, + openAIKey, + progress + ); if ( response && response.choices.length > 0 && @@ -138,11 +140,15 @@ class OpenAiService implements AIService { ); } if (!openAIKey) { - openAiClient.apiKey = "mk-R4d04fe2a29e703da6ZC9Ub0wnz4XsNiRVBChTYbJcE3F"; - openAiClient.baseURL = "https://gpt.pinocks.com/user/v1"; + return undefined; } else { openAiClient.apiKey = openAIKey; - openAiClient.baseURL = "https://api.openai.com/v1"; + const proxyUrl = WorkspaceService.getInstance().getProxyUrl(); + if (proxyUrl) { + openAiClient.baseURL = proxyUrl; + } else { + openAiClient.baseURL = "https://api.openai.com/v1"; + } } progress?.report({ increment: 50 }); const params: OpenAI.Chat.ChatCompletionCreateParams = { @@ -156,11 +162,14 @@ class OpenAiService implements AIService { content: prompt, }, ], - model: "gpt-3.5-turbo", + model: model, + temperature: WorkspaceService.getInstance().getTemp(), + max_tokens: WorkspaceService.getInstance().getMaxTokens(), }; const response = await openAiClient.chat.completions .create(params) .then((value) => { + progress?.report({ increment: 49 }); return value; }) .catch(async (reason: AxiosError) => { diff --git a/src/service/WorkspaceService.ts b/src/service/WorkspaceService.ts index 4d70b1c..7e63a33 100644 --- a/src/service/WorkspaceService.ts +++ b/src/service/WorkspaceService.ts @@ -1,5 +1,5 @@ -import { WorkspaceFolder, window, workspace } from "vscode"; import { EventEmitter } from "events"; +import { window, workspace, WorkspaceFolder } from "vscode"; import { EventType } from "../@types/EventType"; import { CONSTANTS } from "../Constants"; @@ -91,19 +91,53 @@ export default class WorkspaceService extends EventEmitter { } getOpenAIKey() { - const openAiKey: string = String(this.getConfiguration().get("openAiKey")); - // if (!openAiKey) { - // this.showErrorMessage( - // "Please Enter Your OpenAi Api Key in Settings.\nVisit The Openai Website to Generate Key" - // ); - // return null; - // } - return openAiKey; + const value = String(this.getConfiguration().get("openAiKey")); + if (!value) { + this.showErrorMessage( + "Your OpenAI API Key is missing; kindly input it within the Diffy Settings section. You can generate a key by visiting the OpenAI website." + ); + return null; + } + return value; } getGptModel() { - const openAiKey: string = String(this.getConfiguration().get("model")); - return openAiKey; + const value = String(this.getConfiguration().get("model")); + return value; + } + + getProxyUrl() { + const value = this.getConfiguration().get("proxyUrl") + ? String(this.getConfiguration().get("proxyUrl")) + : undefined; + return value; + } + + getAIInstructions() { + const value = this.getConfiguration().get("aiInstructions") + ? String(this.getConfiguration().get("aiInstructions")) + : undefined; + if (!value) { + this.showErrorMessage( + "Instructions for AI are absent; please provide them within the Diffy Settings section." + ); + return null; + } + return value; + } + + getTemp() { + const value = this.getConfiguration().get("temperature") + ? Number(this.getConfiguration().get("temperature")) + : undefined; + return value; + } + + getMaxTokens() { + const value = this.getConfiguration().get("maxTokens") + ? Number(this.getConfiguration().get("maxTokens")) + : undefined; + return value; } /**