From 2968b82fd1a7a9479986f4584be6ee12b495799a Mon Sep 17 00:00:00 2001 From: Drew Baumann Date: Mon, 12 Aug 2024 22:14:32 -0700 Subject: [PATCH] feat: Allows for expanded configuration * Adds the ability to use your model of preference * Adds the ability to use custom base URLS. * This is helpful for running local LLMs or using Azure based openAI calls * Adds the ability to add additional parameters to the API call for increased customization * Adds a sample file * Backwards compatible with old api_key.lua configuration * Updates README with new documentation and use cases --- .gitignore | 3 +- README.md | 29 ++++++++++++++++---- configuration.lua.sample | 8 ++++++ gpt_query.lua | 59 ++++++++++++++++++++++++++++++++-------- 4 files changed, 82 insertions(+), 17 deletions(-) create mode 100644 configuration.lua.sample diff --git a/.gitignore b/.gitignore index a951c51..5fb062f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -/api_key.lua \ No newline at end of file +/api_key.lua +/configuration.lua \ No newline at end of file diff --git a/README.md b/README.md index 99f691e..e1c6d9b 100644 --- a/README.md +++ b/README.md @@ -10,17 +10,36 @@ Get [KoReader](https://github.com/koreader/koreader) installed on your e-reader. If you want to do this on a Kindle, you are going to have to jailbreak it. I recommend following [this guide](https://www.mobileread.com/forums/showthread.php?t=320564) to jailbreak your Kindle. -An API key from OpenAI. Once you have your API key, create a `api_key.lua` file in the following structure: +Acquire an API key from an API account on OpenAI (with credits). Once you have your API key, create a `configuration.lua` file in the following structure or modify and rename the `configuration.lua.sample` file: + +> **Note:** The prior `api_key.lua` style configuration is deprecated. Please use the new `configuration.lua` style configuration. + +```lua +local CONFIGURATION = { + api_key = "YOUR_API_KEY", + model = "gpt-4o-mini", + base_url = "https://api.openai.com/v1/chat/completions", +} + +return CONFIGURATION +``` + +In this new format you can specify the model you want to use, the API key, and the base URL for the API. The model is optional and defaults to `gpt-4o-mini`. The base URL is also optional and defaults to `https://api.openai.com/v1/chat/completions`. This is useful if you want to use a different model or a different API endpoint (such as via Azure or another LLM that uses the same API style as OpenAI). + +For example, you could use a local API via a tool like (Ollama)[https://ollama.com/blog/openai-compatibility] and set the base url to point to your computers IP address and port. ```lua -local API_KEY = { - key = "your_api_key", +local CONFIGURATION = { + api_key = "ollama", + model = "zephyr", + base_url = "http://192.168.1.87:11434/v1/chat/completions", + additional_parameters = {}, } -return API_KEY +return CONFIGURATION ``` -If you clone this project, you should be able to put the directory, `askgpt.koplugin`, in the `koreader/plugins` directory and it should work. If you want to use the plugin without cloning the project, you can download the zip file from the releases page and extract the `askgpt.koplugin` directory to the `koreader/plugins` directory. +If you clone this project, you should be able to put the directory, `askgpt.koplugin`, in the `koreader/plugins` directory and it should work. If you want to use the plugin without cloning the project, you can download the zip file from the releases page and extract the `askgpt.koplugin` directory to the `koreader/plugins` directory. If for some reason you extract the files of this repository in another directory, rename it before moving it to the `koreader/plugins` directory. ## How To Use diff --git a/configuration.lua.sample b/configuration.lua.sample new file mode 100644 index 0000000..542f52d --- /dev/null +++ b/configuration.lua.sample @@ -0,0 +1,8 @@ +local CONFIGURATION = { + api_key = "YOUR_API_KEY", + model = "gpt-4o-mini", + base_url = "https://api.openai.com/v1/chat/completions", + additional_parameters = {}, +} + +return CONFIGURATION \ No newline at end of file diff --git a/gpt_query.lua b/gpt_query.lua index becf321..52b1b71 100644 --- a/gpt_query.lua +++ b/gpt_query.lua @@ -1,25 +1,62 @@ -local API_KEY = require("api_key") +local api_key = nil +local CONFIGURATION = nil + +-- Attempt to load the api_key module. IN A LATER VERSION, THIS WILL BE REMOVED +local success, result = pcall(function() return require("api_key") end) +if success then + api_key = result.key +else + print("api_key.lua not found, skipping...") +end + +-- Attempt to load the configuration module +success, result = pcall(function() return require("configuration") end) +if success then + CONFIGURATION = result +else + print("configuration.lua not found, skipping...") +end + +-- Define your queryChatGPT function local https = require("ssl.https") +local http = require("socket.http") local ltn12 = require("ltn12") local json = require("json") local function queryChatGPT(message_history) - local api_key = API_KEY.key - local api_url = "https://api.openai.com/v1/chat/completions" + -- Use api_key from CONFIGURATION or fallback to the api_key module + local api_key_value = CONFIGURATION and CONFIGURATION.api_key or api_key + local api_url = CONFIGURATION and CONFIGURATION.base_url or "https://api.openai.com/v1/chat/completions" + local model = CONFIGURATION and CONFIGURATION.model or "gpt-4o-mini" + + -- Determine whether to use http or https + local request_library = api_url:match("^https://") and https or http + + -- Start building the request body + local requestBodyTable = { + model = model, + messages = message_history, + } + + -- Add additional parameters if they exist + if CONFIGURATION and CONFIGURATION.additional_parameters then + for key, value in pairs(CONFIGURATION.additional_parameters) do + requestBodyTable[key] = value + end + end + + -- Encode the request body as JSON + local requestBody = json.encode(requestBodyTable) local headers = { ["Content-Type"] = "application/json", - ["Authorization"] = "Bearer " .. api_key, + ["Authorization"] = "Bearer " .. api_key_value, } - local requestBody = json.encode({ - model = "gpt-4o", - messages = message_history, - }) - local responseBody = {} - local res, code, responseHeaders = https.request { + -- Make the HTTP/HTTPS request + local res, code, responseHeaders = request_library.request { url = api_url, method = "POST", headers = headers, @@ -35,4 +72,4 @@ local function queryChatGPT(message_history) return response.choices[1].message.content end -return queryChatGPT +return queryChatGPT \ No newline at end of file