Skip to content
Merged
8 changes: 8 additions & 0 deletions core/amber/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,11 @@ region-plan-generator {
enable-cost-based-region-plan-generator = false
use-global-search = false
}

ai-assistant-server{
assistant = "none"
# Put your Ai Service authentication key here
ai-service-key = ""
# Put your Ai service url here (If you are using OpenAI, then the url should be "https://api.openai.com/v1")
ai-service-url = ""
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,9 @@ object AmberConfig {
// JDBC configuration
val jdbcConfig: Config = getConfSource.getConfig("jdbc")

// Python language server configuration
var aiAssistantConfig: Option[Config] = None
if (getConfSource.hasPath("ai-assistant-server")) {
aiAssistantConfig = Some(getConfSource.getConfig("ai-assistant-server"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ class TexeraWebApplication
environment.jersey.register(classOf[AdminExecutionResource])
environment.jersey.register(classOf[UserQuotaResource])
environment.jersey.register(classOf[UserDiscussionResource])
environment.jersey.register(classOf[AiAssistantResource])
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package edu.uci.ics.texera.web.resource.aiassistant
import edu.uci.ics.amber.engine.common.AmberConfig
import java.net.{HttpURLConnection, URL}

object AiAssistantManager {
private val aiAssistantConfig = AmberConfig.aiAssistantConfig.getOrElse(
throw new Exception("ai-assistant-server configuration is missing in application.conf")
)
val assistantType: String = aiAssistantConfig.getString("assistant")
// The accountKey is the OpenAI authentication key used to authenticate API requests and obtain responses from the OpenAI service.

val accountKey: String = aiAssistantConfig.getString("ai-service-key")
val sharedUrl: String = aiAssistantConfig.getString("ai-service-url")

private def initOpenAI(): String = {
var connection: HttpURLConnection = null
try {
val url = new URL(s"${sharedUrl}/models")
connection = url.openConnection().asInstanceOf[HttpURLConnection]
connection.setRequestMethod("GET")
connection.setRequestProperty(
"Authorization",
s"Bearer ${accountKey.trim.replaceAll("^\"|\"$", "")}"
)
val responseCode = connection.getResponseCode
if (responseCode == 200) {
"OpenAI"
} else {
"NoAiAssistant"
}
} catch {
case e: Exception =>
"NoAiAssistant"
} finally {
if (connection != null) {
connection.disconnect()
}
}
}

val validAIAssistant: String = assistantType match {
case "none" =>
"NoAiAssistant"

case "openai" =>
initOpenAI()

case _ =>
"NoAiAssistant"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package edu.uci.ics.texera.web.resource
import edu.uci.ics.texera.web.resource.aiassistant.AiAssistantManager
import javax.annotation.security.RolesAllowed
import javax.ws.rs._

@Path("/aiassistant")
class AiAssistantResource {
final private lazy val isEnabled = AiAssistantManager.validAIAssistant
@GET
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/isenabled")
def isAiAssistantEnable: String = isEnabled
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Injectable } from "@angular/core";
import { firstValueFrom } from "rxjs";
import { AppSettings } from "../../../../common/app-setting";
import { HttpClient } from "@angular/common/http";

export const AI_ASSISTANT_API_BASE_URL = `${AppSettings.getApiEndpoint()}/aiassistant`;

@Injectable({
providedIn: "root",
})
export class AiAssistantService {
constructor(private http: HttpClient) {}

public checkAiAssistantEnabled(): Promise<string> {
const apiUrl = `${AI_ASSISTANT_API_BASE_URL}/isenabled`;
return firstValueFrom(this.http.get(apiUrl, { responseType: "text" }))
.then(response => {
const isEnabled = response !== undefined ? response : "NoAiAssistant";
console.log(
isEnabled === "OpenAI"
? "AI Assistant successfully started"
: "No AI Assistant or OpenAI authentication key error"
);
return isEnabled;
})
.catch(() => {
return "NoAiAssistant";
});
}
}