Skip to content

Commit

Permalink
refactor + frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
ecostanzi committed May 20, 2024
1 parent 94fbef7 commit 56bcf4a
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 40 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@
<artifactId>json-path</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit5</artifactId>
Expand Down
21 changes: 6 additions & 15 deletions src/main/kotlin/ChatGPTChatClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ChatGPTChatClient(private val apiKey: String, private val model: String) :

private val client = OkHttpClient()

override fun chat(prompt: String): String {
override fun chat(prompt: String) : String {
val url = "https://api.openai.com/v1/chat/completions"

val requestBody = """
Expand All @@ -40,21 +40,12 @@ class ChatGPTChatClient(private val apiKey: String, private val model: String) :
.post(requestBody.toRequestBody("application/json".toMediaType()))
.build()

try {
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")

val responseBody = response.body?.string()
if (responseBody != null) {
return JsonPath.read(responseBody, "$.choices[0].message.content")
}
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
logger.error("Unexpected response")
throw RuntimeException("Unexpected code $response")
}
} catch (e: Exception) {
logger.error("ChatGPT error", e)
return "Error querying ChatGPT: ${e.message}"
return JsonPath.read(response.body?.string(), "$.choices[0].message.content")
}

logger.warn("No response from ChatGPT")
return "Error: No response from the server."
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/Configs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class Configs {
}

fun getProperty(propertyName: String): String {
return properties.getProperty(propertyName);
return properties.getProperty(propertyName, "NONE");
}

fun getIntegerProperty(propertyName: String): Int {
Expand Down
16 changes: 9 additions & 7 deletions src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.example

import com.jayway.jsonpath.JsonPath
import io.javalin.Javalin
import org.slf4j.LoggerFactory

Expand All @@ -9,20 +10,21 @@ fun main() {

val config = Configs();

val app = Javalin.create(/*config*/)
.get("/") { ctx -> ctx.result(config.getProperty("CUSTOM_MESSAGE")) }
val app = Javalin.create { config ->
config.staticFiles.add("/public")
}
.start(config.getIntegerProperty("SERVER_PORT"))

app.get("/chat") { ctx ->
val prompt = ctx.queryParam("prompt")
app.post("/chat") { ctx ->
val prompt = JsonPath.read<String>(ctx.body(), "$.prompt")
logger.info("Querying chat proxy with promt '$prompt'")
var chat = ChatProxy()
val resultString = prompt?.let { chat.chat(it) }
val resultString = prompt?.let { chat.chat(prompt) }
logger.info("Received results from chat client")
if (resultString != null) {
ctx.result(resultString)
ctx.json(mapOf("result" to resultString))
} else {
ctx.result("no result")
ctx.json(mapOf("result" to "no result"))
}
}

Expand Down
19 changes: 6 additions & 13 deletions src/main/kotlin/OpenllamaChatClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.slf4j.LoggerFactory
import java.io.IOException
import java.time.Duration

class OpenllamaChatClient(private val baseUrl: String, private val model: String) : ChatClient {
Expand Down Expand Up @@ -36,20 +35,14 @@ class OpenllamaChatClient(private val baseUrl: String, private val model: String
.post(requestBody.toRequestBody("application/json".toMediaType()))
.build()

try {
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
client.newCall(request).execute().use { response ->

val responseBody = response.body?.string()
if (responseBody != null) {
return JsonPath.read(responseBody, "$.response")
}
if (!response.isSuccessful) {
logger.error("Error while fetching response: " + response.body?.string())
throw RuntimeException("Unexpected code $response")
}
} catch (e: Exception) {
logger.error("Error querying openllama: ${e.message}", e)
return "Error querying openllama: ${e.message}"

return JsonPath.read(response.body?.string(), "$.response")
}
logger.warn("No response from the server.")
return "Error: No response from the server."
}
}
8 changes: 4 additions & 4 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
SERVER_PORT=8080
CUSTOM_MESSAGE="Hello World From Configs"

#CHAT_CLIENT=CHATGPT
#MODEL=gpt-3.5-turbo
CHAT_CLIENT=CHATGPT
MODEL=gpt-3.5-turbo
CHATGPT_API_KEY=NOT HERE!

CHAT_CLIENT=OPENLLAMA
#CHAT_CLIENT=OPENLLAMA
OPENLLAMA_URL=http://127.0.0.1:11434
MODEL=llama3
#MODEL=llama3
77 changes: 77 additions & 0 deletions src/main/resources/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Proxy</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body, html {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.form-control-lg {
font-size: 1.25rem;
height: calc(1.5em + 1rem + 2px);
padding: .5rem 1rem;
line-height: 1.5;
}
.hidden {
display: none;
}
</style>
</head>
<body>
<div class="container">
<h1 class="text-center mb-4">AI Proxy</h1>
<form id="proxyForm">
<input class="form-control form-control-lg" type="text" id="inputData" placeholder="Your AI prompt">
</form>
<div id="spinner" class="hidden text-center mt-3">
<div class="spinner-border" role="status">
<span class="sr-only"></span>
</div>
</div>
<div id="responseArea" class="mt-3"></div>
</div>

<!-- Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<!-- jQuery (Optional) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
const form = document.getElementById('proxyForm');
const spinner = document.getElementById('spinner');
const responseArea = document.getElementById('responseArea');

form.addEventListener('submit', function(event) {
event.preventDefault();
const inputData = document.getElementById('inputData').value;
spinner.classList.remove('hidden'); // Show spinner
responseArea.textContent = ''; // Clear previous response

fetch('/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ prompt: inputData })
})
.then(response => response.json())
.then(data => {
spinner.classList.add('hidden'); // Hide spinner
responseArea.innerText = 'Response: ' + data['result'];
})
.catch(error => {
console.error('Error:', error);
spinner.classList.add('hidden'); // Ensure spinner is hidden on error
responseArea.innerText = 'Error: ' + error.toString();
});
});
</script>
</body>
</html>

0 comments on commit 56bcf4a

Please sign in to comment.