Skip to content

Commit

Permalink
feat: Implement dynamic file-based context addition
Browse files Browse the repository at this point in the history
This commit implements the functionality to dynamically add context from a file. The system now allows users to click the "Add context from File" button and have any changes made to the file thereafter automatically reflected in the context. Please note that currently, only plaintext files  are supported for dynamic context addition. Support for other file formats such as PDF or Word documents is planned for future updates. The README.md file has also been updated to include instructions and information regarding the file format support.
  • Loading branch information
leonid20000 committed Jan 8, 2024
1 parent bac1ce4 commit 011c694
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 15 deletions.
18 changes: 12 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Experience the power of OdinRunes in action with an engaging demo. Click the pla
- [1.1. Capture context from Clipboard](#11-capture-context-from-clipboard)
- [1.2. Capture context from Region](#12-capture-context-from-region)
- [1.3. Capture context from Scrollable Region](#13-capture-context-from-scrollable-region)
- [1.4. Capture context from File](#14-capture-context-from-file)
- [2. Initiating a Chat](#2-initiating-a-chat)
- [3. Appending Prompts](#3-appending-prompts)
- [4. Saving Context](#4-saving-context)
Expand All @@ -40,19 +41,19 @@ Odin Runes offers a range of powerful features that enhance your interaction wit
- Interact with your desired GPT right through your favorite text editor
- Avoid vendor lock-in with a multi-cloud approach
- Switch to the GPT provider of your choice seamlessly
- Capture context from various sources such as clipboard, OCR from a region on the screen, and OCR from an entire scrollable region on the screen
- Capture context from various sources such as clipboard, OCR from a region on the screen, OCR from an entire scrollable region on the screen, and dynamically from a file
- Save context and load it in different conversations
- Save chats independently from their context for greater flexibility

## Advantages of Using Odin Runes

Odin Runes offers several advantages over traditional GPT integration methods:
Odin Runes offers several advantages over traditional GPT clients:

- **Avoid Vendor Lock-in**: By embracing a multi-cloud approach, Odin Runes liberates you from vendor lock-in. You are no longer constrained to a single GPT provider, giving you the freedom to choose the provider that offers the best performance, cost-effectiveness, or features for your specific application. This flexibility ensures you can adapt to changing requirements and leverage the advancements of different GPT providers.
- **Avoid Vendor Lock-in**: By embracing a multi-cloud approach, Odin Runes liberates you from vendor lock-in. You are no longer constrained to a single GPT provider, giving you the freedom to choose the provider that offers the best performance, cost-effectiveness, or features for your specific application. This flexibility ensures you can adapt to changing requirements and leverage the advancements of different GPT providers. Odin Runes currently integrates with several GPT providers, including OpenAI's gpt-3.5-turbo, as well as Google's gemini-pro, and chat-bison via GCP's VertexAI. Stay tuned for future integrations with additional GPT providers. Additionally, Odin Runes offers the flexibility to integrate your own GPT providers by implementing the WellsOfWisdom Interface. This allows you to expand the platform's capabilities and incorporate your preferred GPT provider seamlessly. For more information on how to integrate your own provider, please watch the demo provided.

- **Enhanced User Experience**: By seamlessly integrating GPT models with your favorite text editor through Odin Runes, you can unlock a host of benefits. You'll have the power to leverage the extensive features of your trusted text editor, making your interactions with GPT models more versatile and efficient. Imagine being able to utilize powerful text editing capabilities such as syntax highlighting, code folding, and search-and-replace functionality while conversing with GPT models. This integration allows you to harness the full potential of GPT models within the familiar environment of your text editor. Moreover, because chat sessions are stored as files on your file system, you can take advantage of existing operating system features like grep to easily search and manage your past conversations with GPT models.

- **Improved Contextual Understanding**: Odin Runes allows you to provide context to GPT models through various sources such as clipboard, OCR-based screen region capture, and OCR-based scrollable region capture. By enriching conversations with relevant information, the GPT models possess a better understanding of the context, leading to more accurate and meaningful responses. This contextual understanding enables applications like document summarization, content generation, and more.
- **Improved Contextual Understanding**: Odin Runes allows you to provide context to GPT models through various sources such as clipboard, OCR-based screen region capture, OCR-based scrollable region capture, and dynamically from a file. By enriching conversations with relevant information, the GPT models possess a better understanding of the context, leading to more accurate and meaningful responses. This contextual understanding enables applications like document summarization, content generation, and more.

- **Effortless Context and Chat Management**: With Odin Runes, managing context and chats becomes seamless. You can save and load context independently, facilitating the reuse of previously saved context across multiple conversations. Furthermore, saving and loading chats independently allows for greater flexibility and control over the conversations. This effortless context and chat management streamlines your workflow and enables efficient interaction with GPT models.

Expand Down Expand Up @@ -95,10 +96,10 @@ To install and set up Odin Runes, follow these steps:

- `VERTEXAI_PROJECT_ID`: Set this environment variable to the project ID for your Google Cloud project. It is required to make API requests to the Vertex AI service. (*Required for using Google's GPT APIs.*)

6. Once the installation and setup are complete, you can run Odin Runes. You can run Odin Runes by double-clicking on the JAR file `target/OdinRunes-1.0-SNAPSHOT-jar-with-dependencies.jar` or alternatively by using the following command:
6. Once the installation and setup are complete, you can run Odin Runes. You can run Odin Runes by double-clicking on the JAR file `target/OdinRunes-1.1-SNAPSHOT-jar-with-dependencies.jar` or alternatively by using the following command:

```
java -jar target/OdinRunes-1.0-SNAPSHOT-jar-with-dependencies.jar
java -jar target/OdinRunes-1.1-SNAPSHOT-jar-with-dependencies.jar
```

This will start the Odin Runes application.
Expand Down Expand Up @@ -136,6 +137,11 @@ Click the "Add context from Regionshot" button to capture text from a specific r

Click the "Add context from Scrollshot" button to capture text from a scrollable region on the screen using OCR. This captures the entire content visible within the scrollable region, virtually enabling you to capture context from anywhere.

#### 1.4. Capture context from File

Click the "Add context from File" button to dynamically add context from a file. Any changes made to the file thereafter will be automatically reflected in the context. Please be aware that currently, only plaintext files are supported. Support for other file formats such as PDF or Word documents is under development, so please stay tuned for updates regarding these file types.


### 2. Initiating a Chat

To start a chat session, click on the "Chat" button, which will open your favorite text editor. You can now initiate a conversation with the GPT model.
Expand Down
12 changes: 6 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<groupId>com.odinware</groupId>
<artifactId>OdinRunes</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.1-SNAPSHOT</version>


<dependencies>
Expand All @@ -20,12 +20,12 @@
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>5.9.0</version> <!-- Replace with the latest version -->
<version>5.10.0</version> <!-- Replace with the latest version -->
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version> <!-- Use the latest version -->
<version>2.1.0-alpha1</version> <!-- Use the latest version -->
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
Expand All @@ -50,20 +50,20 @@
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>5.0.0-alpha.11</version> <!-- Use the latest version available -->
<version>5.0.0-alpha.12</version> <!-- Use the latest version available -->
</dependency>

<!-- Jackson for JSON parsing -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.16.0</version> <!-- Use the latest version available -->
<version>2.16.1</version> <!-- Use the latest version available -->
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.0</version> <!-- Replace with the latest version -->
<version>2.16.1</version> <!-- Replace with the latest version -->
</dependency>


Expand Down
8 changes: 7 additions & 1 deletion src/main/java/org/odinware/odinrunes/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,13 @@ public CapturedData(String capturedText, String captureMethod) {
}

public String getCapturedText() {
return capturedText;
if(getCaptureMethod().equals("File (Live)")){
String fileContent=TextHelper.readIntoString(capturedText);
if(fileContent == null){
return "ERROR READING FROM FILE";
} else return fileContent;
} else return capturedText;

}

public void setCapturedText(String capturedText) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,20 @@ public Request buildRequest(Context context, JSONArray odinMessages, JSONObject
contents.put(new JSONObject()
.put("role", "MODEL")
.put("parts", new JSONObject().put("text", "Ok. got it.")));
} else if (captureMethod.equals("File (Live)")) {
contents.put(new JSONObject()
.put("role", "USER")
.put("parts", new JSONObject().put("text", "The content of a file is included below: \n" + capturedText)));
contents.put(new JSONObject()
.put("role", "MODEL")
.put("parts", new JSONObject().put("text", "Ok. got it.")));
} else {
contents.put(new JSONObject()
.put("role", "USER")
.put("parts", new JSONObject().put("text", "Some additional information labeled as "+captureMethod+" is included below: \n" + capturedText)));
contents.put(new JSONObject()
.put("role", "MODEL")
.put("parts", new JSONObject().put("text", "Ok. got it.")));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ public Request buildRequest(Context context, JSONArray odinMessages, JSONObject
contextInfo.put(new JSONObject().put("role", "system").put("content", "The text content captured by OCR from a portion of the user's screen is as follows: " + capturedText));
} else if (captureMethod.equals("Scrollshot (OCR)")) {
contextInfo.put(new JSONObject().put("role", "system").put("content", "The text content captured by OCR from a portion of the user's screen is included below. It might have some redundant lines. \n" + capturedText));
} else if (captureMethod.equals("File (Live)")) {
contextInfo.put(new JSONObject().put("role", "system").put("content", "The content of a file is included below: \n" + capturedText));
} else {
contextInfo.put(new JSONObject().put("role", "system").put("content", "Some additional information labeled as "+captureMethod+" is included below: \n" + capturedText));
}
}

Expand Down
18 changes: 16 additions & 2 deletions src/main/java/org/odinware/odinrunes/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private static void createAndShowGUI() {
mainComponentsPanel.setLayout(new FlowLayout());

// Create the first dropdown menu
String[] options = {"Clipboard", "Regionshot (OCR)", "Scrollshot (OCR)", "Photo (Coming Soon)"};
String[] options = {"Clipboard", "Regionshot (OCR)", "Scrollshot (OCR)", "File (Live)","Photo (Coming Soon)"};
final JComboBox<String> firstDropdown = new JComboBox<>(options);
firstDropdown.setBackground(new Color(189, 219, 225)); // RGB values for a blue-grey shade

Expand Down Expand Up @@ -156,6 +156,19 @@ public void run() {
logger.info(selectedArgument);
toggleSettingsPanelVisibility();
if(!settingsVisible) toggleSettingsPanelVisibility();
} else if (selectedFunction.equals("File (Live)")) {
JFileChooser fileChooser = new JFileChooser();
int returnValue = fileChooser.showOpenDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File tempFile = fileChooser.getSelectedFile();
if(TextHelper.readIntoString(tempFile.getAbsolutePath())==null) {
// Do something with the selected file, e.g., display its path
JOptionPane.showMessageDialog(frame, "ERROR: Something is wrong with the selected file: " + tempFile.getAbsolutePath());
}else{
JOptionPane.showMessageDialog(frame, "OK: I will pass the latest content of the selected file as part of the context to your specified GPT provider. \nThis means that any changes to the file will also be automatically reflected in the context. \nThe selected file: " + tempFile.getAbsolutePath());
context.addCapturedData(tempFile.getAbsolutePath(), "File (Live)");
}
}
}

// Add logic to handle the result or display a message.
Expand Down Expand Up @@ -207,7 +220,7 @@ public void actionPerformed(ActionEvent e) {
try {
boolean fileCreated = selectedFile.createNewFile();
if (fileCreated) {
JOptionPane.showMessageDialog(frame, "File created: " + selectedFile.getAbsolutePath());
JOptionPane.showMessageDialog(frame, "File created: " + selectedFile.getAbsolutePath()+"\nOdinRunes will use this file every time you click the chat button from now on.");
} else {
JOptionPane.showMessageDialog(frame, "File already exists.");
}
Expand All @@ -232,6 +245,7 @@ public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "Something is wrong with the selected output file: " + selectedFile.getAbsolutePath());
}else{
selectedFile=tempFile;
JOptionPane.showMessageDialog(frame, "Output file set successfully to: " + selectedFile.getAbsolutePath()+"\nOdinRunes will use this file every time you click the chat button from now on.");
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/odinware/odinrunes/OpenAIWellsOfWisdom.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ public Request buildRequest(Context context, JSONArray odinMessages, JSONObject
messages.put(new JSONObject().put("role", "system").put("content", "The text content captured by OCR from a portion of the user's screen is as follows: " + capturedText));
} else if (captureMethod.equals("Scrollshot (OCR)")) {
messages.put(new JSONObject().put("role", "system").put("content", "The text content captured by OCR from a portion of the user's screen is included below. It might have some redundant lines. \n" + capturedText));
} else if (captureMethod.equals("File (Live)")) {
messages.put(new JSONObject().put("role", "system").put("content", "The content of a file is included below: \n" + capturedText));
} else {
messages.put(new JSONObject().put("role", "system").put("content", "Some additional information labeled as "+captureMethod+" is included below: \n" + capturedText));
}
}

Expand Down
20 changes: 20 additions & 0 deletions src/main/java/org/odinware/odinrunes/TextHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,24 @@ public static boolean isFirstLineValid(File file) {
return false; // Handle the exception as needed
}
}

public static String readIntoString(String filePath) {
try {
File file = new File(filePath);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;

while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append("\n");
}

reader.close();
return stringBuilder.toString();
} catch (IOException e) {
logger.log(Level.SEVERE, "An error occurred in readIntoString: ", e);
return null;
}
}
}

0 comments on commit 011c694

Please sign in to comment.