Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
SocketC0nnection committed May 15, 2024
0 parents commit 3037cce
Show file tree
Hide file tree
Showing 14 changed files with 492 additions and 0 deletions.
Empty file added .gitignore
Empty file.
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# SilentGPT

This tool monitors the clipboard for new copy events, sends the content to the ChatGPT API, and replaces the clipboard content with the response.

## Features

- No API key required
- Its running in the background so no one can actually see that you are using SilentGPT
- Copy specific commands to your clipboard for running actions (read below)
- This tool can remember the previous conversation like in the normal ChatGPT interface
- This tool can play a sound (windows sound) for notifying you as soon as the answer is in your clipboard

## Commands

If you want to execute one of the following actions you just have to copy the command into your clipboard
- Close SilentGPT
```
SILENTGPT_CLOSE
```
- Toggle notifications (disabled by default)
```
SILENTGPT_NOTIFY
```
- Toggle remembering conversations (disabled by default)
```
SILENTGPT_REMEMBER_CONVERSATION
```

## Installation

1. **Requirements:**
- Java Development Kit (JDK) 11 or higher

2. **Download:**
- Download the latest release from the [Releases page](https://github.com/SocketC0nnection/SilentGPT/releases).

## Usage

1. **Start:**
- Run the JAR file via command-line or just double click it:

```sh
java -jar SilentGPT.jar
```

2. **Monitor Clipboard:**
- Copy text to the clipboard. The tool will automatically send the text to the ChatGPT API and replace the clipboard content with the response.

## Contributions
Contributions are welcome! If you find a bug or have a feature request, please open an issue or submit a pull request.

## License
This project is licensed under the MIT License. See the LICENSE file for details.

## Acknowledgements
- Gson for JSON processing
- [aiforcause](https://github.com/brahmai-research/aiforcause) for accessing ChatGPT API
12 changes: 12 additions & 0 deletions SilentGPT.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="gson-2.10.1" level="project" />
</component>
</module>
3 changes: 3 additions & 0 deletions src/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: net.socket.silentgpt.SilentGPT

79 changes: 79 additions & 0 deletions src/net/socket/silentgpt/SilentGPT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package net.socket.silentgpt;

import net.socket.silentgpt.client.HttpClient;
import net.socket.silentgpt.commands.CloseCommand;
import net.socket.silentgpt.commands.NotificationCommand;
import net.socket.silentgpt.commands.RememberConversationCommand;
import net.socket.silentgpt.handlers.ClipboardUpdateHandler;
import net.socket.silentgpt.managers.ClipboardManager;
import net.socket.silentgpt.managers.CommandManager;
import net.socket.silentgpt.managers.ConversationManager;

public class SilentGPT {

private static SilentGPT instance;

private final ClipboardManager clipboardManager;
private final CommandManager commandManager;
private final ConversationManager conversationManager;

private final HttpClient httpClient;

private boolean notification;
private boolean rememberConversation;

public SilentGPT() {
instance = this;

clipboardManager = new ClipboardManager();
commandManager = new CommandManager();
conversationManager = new ConversationManager();
httpClient = new HttpClient(this);

commandManager.register(new CloseCommand());
commandManager.register(new NotificationCommand());
commandManager.register(new RememberConversationCommand());

new ClipboardUpdateHandler(this).start();
}

public static void main(String[] args) {
new SilentGPT();
}

public HttpClient getHttpClient() {
return httpClient;
}

public ConversationManager getConversationManager() {
return conversationManager;
}

public CommandManager getCommandManager() {
return commandManager;
}

public ClipboardManager getClipboardManager() {
return clipboardManager;
}

public boolean getRememberConversation() {
return rememberConversation;
}

public void setRememberConversation(boolean rememberConversation) {
this.rememberConversation = rememberConversation;
}

public boolean getNotification() {
return notification;
}

public void setNotification(boolean notification) {
this.notification = notification;
}

public static SilentGPT getInstance() {
return instance;
}
}
90 changes: 90 additions & 0 deletions src/net/socket/silentgpt/client/HttpClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package net.socket.silentgpt.client;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import net.socket.silentgpt.SilentGPT;
import net.socket.silentgpt.managers.ConversationManager;

import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class HttpClient {

private final Gson gson;
private final java.net.http.HttpClient client;

private final SilentGPT silentGPT;

public HttpClient(SilentGPT silentGPT) {
gson = new Gson();
client = java.net.http.HttpClient.newHttpClient();

this.silentGPT = silentGPT;
}

public String send(String question) {
JsonObject object = new JsonObject();

JsonArray messages;

if(silentGPT.getRememberConversation()) {
messages = silentGPT.getConversationManager().getMessages();

silentGPT.getConversationManager().addMessage(ConversationManager.Role.USER, question);
} else {
messages = new JsonArray();

JsonObject message = new JsonObject();

message.addProperty("role", "user");
message.addProperty("content", question);

messages.add(message);
}

object.addProperty("model", "gpt-35-turbo");
object.add("messages", messages);
object.addProperty("stream", false);

String text = "";

try {
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://aiforcause.deepnight.tech/openai/"))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer IDK")
.POST(HttpRequest.BodyPublishers.ofString(gson.toJson(object)))
.build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

JsonObject jsonReponse = gson.fromJson(response.body(), JsonObject.class);

text = jsonReponse
.getAsJsonArray("choices")
.get(0)
.getAsJsonObject()
.getAsJsonObject("message")
.get("content")
.getAsString();

silentGPT.getConversationManager().addMessage(ConversationManager.Role.ASSISTANT, text);
} catch (Exception ignored) {}

return text;
}

public SilentGPT getSilentGPT() {
return silentGPT;
}

public java.net.http.HttpClient getClient() {
return client;
}

public Gson getGson() {
return gson;
}
}
14 changes: 14 additions & 0 deletions src/net/socket/silentgpt/commands/CloseCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package net.socket.silentgpt.commands;

public class CloseCommand extends Command {

public CloseCommand() {
super("SILENTGPT_CLOSE");
}

@Override
public void onExecute() {
System.exit(0);
}

}
16 changes: 16 additions & 0 deletions src/net/socket/silentgpt/commands/Command.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package net.socket.silentgpt.commands;

public abstract class Command {

private final String command;

public Command(String command) {
this.command = command;
}

public abstract void onExecute();

public String getCommand() {
return command;
}
}
16 changes: 16 additions & 0 deletions src/net/socket/silentgpt/commands/NotificationCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package net.socket.silentgpt.commands;

import net.socket.silentgpt.SilentGPT;

public class NotificationCommand extends Command {

public NotificationCommand() {
super("SILENTGPT_NOTIFY");
}

@Override
public void onExecute() {
SilentGPT.getInstance().setNotification(!SilentGPT.getInstance().getNotification());
}

}
19 changes: 19 additions & 0 deletions src/net/socket/silentgpt/commands/RememberConversationCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package net.socket.silentgpt.commands;

import net.socket.silentgpt.SilentGPT;

public class RememberConversationCommand extends Command {

public RememberConversationCommand() {
super("SILENTGPT_REMEMBER_CONVERSATION");
}

@Override
public void onExecute() {
SilentGPT.getInstance().setRememberConversation(!SilentGPT.getInstance().getRememberConversation());

if(SilentGPT.getInstance().getRememberConversation()) {
SilentGPT.getInstance().getConversationManager().reset();
}
}
}
66 changes: 66 additions & 0 deletions src/net/socket/silentgpt/handlers/ClipboardUpdateHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package net.socket.silentgpt.handlers;

import net.socket.silentgpt.SilentGPT;
import net.socket.silentgpt.commands.Command;

import java.awt.*;
import java.util.Timer;
import java.util.TimerTask;

public class ClipboardUpdateHandler {

private final SilentGPT silentGPT;
private String lastClipboardText;

public ClipboardUpdateHandler(SilentGPT silentGPT) {
this.silentGPT = silentGPT;

lastClipboardText = "";

silentGPT.getClipboardManager().setClipboardText(lastClipboardText);
}

public void start() {
new Timer().schedule(new TimerTask() {

@Override
public void run() {
String newClipboardText = silentGPT.getClipboardManager().getClipboardText();

if(lastClipboardText.equals(newClipboardText)) {
return;
}

lastClipboardText = newClipboardText;

Command command = silentGPT.getCommandManager().getCommand(newClipboardText.trim());

if(command != null) {
command.onExecute();

return;
}

String answer = silentGPT.getHttpClient().send(newClipboardText);

lastClipboardText = answer;
silentGPT.getClipboardManager().setClipboardText(answer);

if(!silentGPT.getNotification()) {
return;
}

Toolkit.getDefaultToolkit().beep();
}

}, 0, 1000);
}

public String getLastClipboardText() {
return lastClipboardText;
}

public SilentGPT getSilentGPT() {
return silentGPT;
}
}
Loading

0 comments on commit 3037cce

Please sign in to comment.