diff --git a/.gitignore b/.gitignore
index d2daf1c..6c5fc87 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,4 +60,3 @@ local.properties
logs
mobibot.properties
out
-/target/
diff --git a/.idea/libraries/bld.xml b/.idea/libraries/bld.xml
index 5c4010c..4dd96bf 100644
--- a/.idea/libraries/bld.xml
+++ b/.idea/libraries/bld.xml
@@ -2,12 +2,12 @@
-
+
-
+
diff --git a/.idea/libraries/compile.xml b/.idea/libraries/compile.xml
index 99cc0c0..9bd86aa 100644
--- a/.idea/libraries/compile.xml
+++ b/.idea/libraries/compile.xml
@@ -7,7 +7,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/.idea/libraries/runtime.xml b/.idea/libraries/runtime.xml
index d4069f2..2ae5c4b 100644
--- a/.idea/libraries/runtime.xml
+++ b/.idea/libraries/runtime.xml
@@ -8,7 +8,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/.idea/libraries/test.xml b/.idea/libraries/test.xml
index 57ed5ef..b80486a 100644
--- a/.idea/libraries/test.xml
+++ b/.idea/libraries/test.xml
@@ -8,7 +8,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index e438c94..a4db76e 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
# mobibot
[](https://opensource.org/licenses/BSD-3-Clause)
-[](https://kotlinlang.org)
-[](https://rife2.com/bld)
+[](https://kotlinlang.org)
+[](https://rife2.com/bld)
[](https://sonarcloud.io/summary/new_code?id=ethauvin_mobibot)
[](https://github.com/ethauvin/mobibot/actions/workflows/bld.yml)
[](https://circleci.com/gh/ethauvin/mobibot/tree/master)
diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml
index 719ca4e..b20abc9 100644
--- a/config/detekt/baseline.xml
+++ b/config/detekt/baseline.xml
@@ -71,6 +71,9 @@
ReturnCount:Addons.kt$Addons$fun help(channel: String, topic: String, event: GenericMessageEvent): Boolean
ReturnCount:ExceptionSanitizer.kt$ExceptionSanitizer$fun ModuleException.sanitize(vararg sanitize: String): ModuleException
ReturnCount:Seen.kt$Seen$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent)
+ SwallowedException:GoogleSearchTest.kt$GoogleSearchTest$e: ModuleException
+ SwallowedException:StockQuoteTest.kt$StockQuoteTest$e: ModuleException
+ SwallowedException:WolframAlphaTest.kt$WolframAlphaTest$e: ModuleException
ThrowsCount:ChatGpt.kt$ChatGpt.Companion$@JvmStatic @Throws(ModuleException::class) fun chat(query: String, apiKey: String?, maxTokens: Int): String
ThrowsCount:GoogleSearch.kt$GoogleSearch.Companion$@JvmStatic @Throws(ModuleException::class) fun searchGoogle( query: String, apiKey: String?, cseKey: String?, quotaUser: String = ReleaseInfo.PROJECT ): List<Message>
ThrowsCount:Joke.kt$Joke.Companion$@JvmStatic @Throws(ModuleException::class) fun randomJoke(): List<Message>
@@ -79,9 +82,7 @@
ThrowsCount:StockQuote.kt$StockQuote.Companion$@Throws(ModuleException::class) private fun getJsonResponse(response: String, debugMessage: String): JSONObject
ThrowsCount:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List<Message>
ThrowsCount:WolframAlpha.kt$WolframAlpha.Companion$@JvmStatic @Throws(ModuleException::class) fun queryWolfram(query: String, units: String = IMPERIAL, appId: String?): String
- TooGenericExceptionCaught:ChatGpt2.kt$ChatGpt2.Companion$e: Exception
TooGenericExceptionCaught:Gemini.kt$Gemini.Companion$e: Exception
- TooGenericExceptionCaught:Gemini2.kt$Gemini2.Companion$e: Exception
TooGenericExceptionCaught:StockQuote.kt$StockQuote.Companion$e: NullPointerException
TooGenericExceptionCaught:Weather2.kt$Weather2.Companion$e: NullPointerException
TooManyFunctions:EntryLink.kt$EntryLink : Serializable
@@ -93,7 +94,6 @@
WildcardImport:FeedMgrTest.kt$import assertk.assertions.*
WildcardImport:FeedReaderTest.kt$import assertk.assertions.*
WildcardImport:FeedsManager.kt$import com.rometools.rome.feed.synd.*
- WildcardImport:Gemini2Test.kt$import assertk.assertions.*
WildcardImport:GeminiTest.kt$import assertk.assertions.*
WildcardImport:GoogleSearchTest.kt$import assertk.assertions.*
WildcardImport:JokeTest.kt$import assertk.assertions.*
diff --git a/lib/bld/bld-wrapper.jar b/lib/bld/bld-wrapper.jar
index 5425f1c..1d2b318 100644
Binary files a/lib/bld/bld-wrapper.jar and b/lib/bld/bld-wrapper.jar differ
diff --git a/lib/bld/bld-wrapper.properties b/lib/bld/bld-wrapper.properties
index ed0fdb7..26eaf6a 100644
--- a/lib/bld/bld-wrapper.properties
+++ b/lib/bld/bld-wrapper.properties
@@ -1,10 +1,10 @@
bld.downloadExtensionJavadoc=false
bld.downloadExtensionSources=true
bld.downloadLocation=
-bld.extension-detekt=com.uwyn.rife2:bld-detekt:0.9.7
-bld.extension-gv=com.uwyn.rife2:bld-generated-version:0.9.9
-bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.8
-bld.extension-kotlin=com.uwyn.rife2:bld-kotlin:1.0.1
+bld.extension-detekt=com.uwyn.rife2:bld-detekt:0.9.5
+bld.extension-gv=com.uwyn.rife2:bld-generated-version:0.9.8
+bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.7
+bld.extension-kotlin=com.uwyn.rife2:bld-kotlin:1.0.0
bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES
bld.sourceDirectories=
-bld.version=2.1.0
+bld.version=2.0.1
diff --git a/pom.xml b/pom.xml
index 5d1b89a..7996b05 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
net.thauvin.erik.mobibot
mobibot
- 0.8.0-rc+20240908192921
+ 0.8.0-rc+20240809180718
mobibot
@@ -18,7 +18,7 @@
org.apache.commons
commons-lang3
- 3.17.0
+ 3.16.0
compile
@@ -51,28 +51,34 @@
33.2.1-jre
compile
+
+ com.google.cloud
+ google-cloud-vertexai
+ 1.7.0
+ compile
+
org.jetbrains.kotlin
kotlin-stdlib
- 2.0.20
+ 2.0.10
compile
org.jetbrains.kotlin
kotlin-stdlib-common
- 2.0.20
+ 2.0.10
compile
org.jetbrains.kotlin
kotlin-stdlib-jdk7
- 2.0.20
+ 2.0.10
compile
org.jetbrains.kotlin
kotlin-stdlib-jdk8
- 2.0.20
+ 2.0.10
compile
@@ -90,49 +96,25 @@
org.slf4j
slf4j-api
- 2.0.16
+ 2.0.15
compile
org.apache.logging.log4j
log4j-api
- 2.24.0
+ 2.23.1
compile
org.apache.logging.log4j
log4j-core
- 2.24.0
+ 2.23.1
compile
org.apache.logging.log4j
log4j-slf4j2-impl
- 2.24.0
- compile
-
-
- dev.langchain4j
- langchain4j-open-ai
- 0.34.0
- compile
-
-
- dev.langchain4j
- langchain4j-google-ai-gemini
- 0.34.0
- compile
-
-
- dev.langchain4j
- langchain4j-core
- 0.34.0
- compile
-
-
- dev.langchain4j
- langchain4j
- 0.34.0
+ 2.23.1
compile
diff --git a/properties/mobibot.properties b/properties/mobibot.properties
index fd7b104..a7526cc 100644
--- a/properties/mobibot.properties
+++ b/properties/mobibot.properties
@@ -45,6 +45,7 @@ disabled-modules=mastodon
# Automatically post links to Mastodon
#mastodon-auto-post=true
+
#
# Get Exchange Rate API key from: https://www.exchangerate-api.com/
#
@@ -74,13 +75,19 @@ disabled-modules=mastodon
#wolfram-units=imperial
#
-# Get ChatGPT/OpenAI API key from: https://platform.openai.com/api-keys
+# ChatGPT/OpenAI API key from: https://beta.openai.com/account/api-keys
#
#chatgpt-api-key=
#chatgpt-max-tokens=1024
#
-# Get Google Gemini API key from https://ai.google.dev/gemini-api/docs/api-key
+# Set a Vertex AI Gemini API project in Google Cloud:
+# https://cloud.google.com/vertex-ai/docs/generative-ai/start/quickstarts/quickstart-multimodal
+# Don't forget to:
+# gcloud config set project PROJECT_ID
+# gcloud auth login LOGIN
+# gcloud auth application-default login
#
-#gemini-api-key=
+#gemini-project-id=
+#gemini-location=us-west1
#gemini-max-tokens=1024
diff --git a/src/bld/java/net/thauvin/erik/MobibotBuild.java b/src/bld/java/net/thauvin/erik/MobibotBuild.java
index 980f2a6..1e6649b 100644
--- a/src/bld/java/net/thauvin/erik/MobibotBuild.java
+++ b/src/bld/java/net/thauvin/erik/MobibotBuild.java
@@ -77,20 +77,20 @@ public class MobibotBuild extends Project {
new Repository("https://jitpack.io"),
SONATYPE_SNAPSHOTS_LEGACY);
- var log4j = version(2, 24, 0);
- var kotlin = version(2, 0, 20);
- var langchain = version(0, 34, 0);
+ var log4j = version(2, 23, 1);
+ var kotlin = version(2, 0, 10);
scope(compile)
// PircBotX
.include(dependency("com.github.pircbotx", "pircbotx", "2.3.1"))
// Commons (mostly for PircBotX)
- .include(dependency("org.apache.commons", "commons-lang3", "3.17.0"))
+ .include(dependency("org.apache.commons", "commons-lang3", "3.16.0"))
.include(dependency("org.apache.commons", "commons-text", "1.12.0"))
.include(dependency("commons-codec", "commons-codec", "1.17.1"))
.include(dependency("commons-net", "commons-net", "3.11.1"))
// Google
.include(dependency("com.google.code.gson", "gson", "2.11.0"))
.include(dependency("com.google.guava", "guava", "33.2.1-jre"))
+ .include(dependency("com.google.cloud", "google-cloud-vertexai", "1.7.0"))
// Kotlin
.include(dependency("org.jetbrains.kotlin", "kotlin-stdlib", kotlin))
.include(dependency("org.jetbrains.kotlin", "kotlin-stdlib-common", kotlin))
@@ -99,15 +99,10 @@ public class MobibotBuild extends Project {
.include(dependency("org.jetbrains.kotlinx", "kotlinx-coroutines-core", "1.8.1"))
.include(dependency("org.jetbrains.kotlinx", "kotlinx-cli-jvm", "0.3.6"))
// Logging
- .include(dependency("org.slf4j", "slf4j-api", "2.0.16"))
+ .include(dependency("org.slf4j", "slf4j-api", "2.0.15"))
.include(dependency("org.apache.logging.log4j", "log4j-api", log4j))
.include(dependency("org.apache.logging.log4j", "log4j-core", log4j))
.include(dependency("org.apache.logging.log4j", "log4j-slf4j2-impl", log4j))
- // LangChain4J
- .include(dependency("dev.langchain4j", "langchain4j-open-ai", langchain))
- .include(dependency("dev.langchain4j", "langchain4j-google-ai-gemini", langchain))
- .include(dependency("dev.langchain4j", "langchain4j-core", langchain))
- .include(dependency("dev.langchain4j", "langchain4j", langchain))
// Misc.
.include(dependency("com.rometools", "rome", "2.1.0"))
.include(dependency("com.squareup.okhttp3", "okhttp", "4.12.0"))
@@ -123,8 +118,8 @@ public class MobibotBuild extends Project {
scope(test)
.include(dependency("com.willowtreeapps.assertk", "assertk-jvm", version(0, 28, 1)))
.include(dependency("org.jetbrains.kotlin", "kotlin-test-junit5", kotlin))
- .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 11, 0)))
- .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 11, 0)));
+ .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 3)))
+ .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 3)));
List jars = new ArrayList<>();
runtimeClasspathJars().forEach(f -> jars.add("./lib/" + f.getName()));
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt b/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt
index 1e49a88..88bed54 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt
@@ -396,11 +396,11 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro
// Load the modules
addons.add(Calc())
- addons.add(ChatGpt2())
+ addons.add(ChatGpt())
addons.add(CryptoPrices())
addons.add(CurrencyConverter())
addons.add(Dice())
- addons.add(Gemini2())
+ addons.add(Gemini())
addons.add(GoogleSearch())
addons.add(Info(tell, seen))
addons.add(Joke())
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/ReleaseInfo.kt b/src/main/kotlin/net/thauvin/erik/mobibot/ReleaseInfo.kt
index 5b5e5d2..3abf162 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/ReleaseInfo.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/ReleaseInfo.kt
@@ -14,12 +14,12 @@ import java.time.ZoneId
*/
object ReleaseInfo {
const val PROJECT = "mobibot"
- const val VERSION = "0.8.0-rc+20240908190240"
+ const val VERSION = "0.8.0-rc+20240712110931"
@JvmField
@Suppress("MagicNumber")
val BUILD_DATE: LocalDateTime = LocalDateTime.ofInstant(
- Instant.ofEpochMilli(1725847361020L), ZoneId.systemDefault()
+ Instant.ofEpochMilli(1720807771484L), ZoneId.systemDefault()
)
const val WEBSITE = "https://mobitopia.org/mobibot/"
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt.kt
similarity index 62%
rename from src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2.kt
rename to src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt.kt
index 854bb9f..c7ba4ba 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt.kt
@@ -31,16 +31,23 @@
package net.thauvin.erik.mobibot.modules
-import dev.langchain4j.model.openai.OpenAiChatModel
-import dev.langchain4j.model.openai.OpenAiChatModelName
+import net.thauvin.erik.mobibot.Constants
import net.thauvin.erik.mobibot.Utils
import net.thauvin.erik.mobibot.Utils.sendMessage
+import org.json.JSONArray
+import org.json.JSONException
+import org.json.JSONObject
import org.pircbotx.hooks.types.GenericMessageEvent
import org.slf4j.Logger
import org.slf4j.LoggerFactory
+import java.io.IOException
+import java.net.URI
+import java.net.http.HttpClient
+import java.net.http.HttpRequest
+import java.net.http.HttpResponse
-class ChatGpt2 : AbstractModule() {
- val logger: Logger = LoggerFactory.getLogger(ChatGpt2::class.java)
+class ChatGpt : AbstractModule() {
+ val logger: Logger = LoggerFactory.getLogger(ChatGpt::class.java)
override val name = CHATGPT_NAME
@@ -86,6 +93,9 @@ class ChatGpt2 : AbstractModule() {
*/
const val MAX_TOKENS_PROP = "chatgpt-max-tokens"
+ // ChatGPT API URL
+ private const val API_URL = "https://api.openai.com/v1/chat/completions"
+
// ChatGPT command
private const val CHATGPT_CMD = "chatgpt"
@@ -93,15 +103,48 @@ class ChatGpt2 : AbstractModule() {
@Throws(ModuleException::class)
fun chat(query: String, apiKey: String?, maxTokens: Int): String {
if (!apiKey.isNullOrEmpty()) {
- try {
- val model = OpenAiChatModel.builder()
- .apiKey(apiKey)
- .modelName(OpenAiChatModelName.GPT_4_O)
- .maxTokens(maxTokens)
- .build()
+ val jsonObject = JSONObject()
+ jsonObject.put("model", "gpt-3.5-turbo-1106")
+ jsonObject.put("max_tokens", maxTokens)
+ val message = JSONObject()
+ message.put("role", "user")
+ message.put("content", query)
+ val messages = JSONArray()
+ messages.put(message)
+ jsonObject.put("messages", messages)
- return model.generate(query)
- } catch (e: Exception) {
+ val request = HttpRequest.newBuilder()
+ .uri(URI.create(API_URL))
+ .header("Content-Type", "application/json")
+ .header("Authorization", "Bearer $apiKey")
+ .header("User-Agent", Constants.USER_AGENT)
+ .POST(HttpRequest.BodyPublishers.ofString(jsonObject.toString()))
+ .build()
+ try {
+ val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
+ if (response.statusCode() == 200) {
+ try {
+ val jsonResponse = JSONObject(response.body())
+ val choices = jsonResponse.getJSONArray("choices")
+ return choices.getJSONObject(0).getJSONObject("message").getString("content").trim()
+ } catch (e: JSONException) {
+ throw ModuleException(
+ "$CHATGPT_CMD($query): JSON",
+ "A JSON error has occurred while conversing with $CHATGPT_NAME.",
+ e
+ )
+ }
+ } else {
+ if (response.statusCode() == 429) {
+ throw ModuleException(
+ "$CHATGPT_CMD($query): Rate limit reached",
+ "Rate limit reached. Please try again later."
+ )
+ } else {
+ throw IOException("HTTP Status Code: " + response.statusCode())
+ }
+ }
+ } catch (e: IOException) {
throw ModuleException(
"$CHATGPT_CMD($query): IO",
"An IO error has occurred while conversing with $CHATGPT_NAME.",
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt
index 3c8ea92..4fb7555 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt
@@ -217,6 +217,6 @@ class CurrencyConverter : AbstractModule() {
init {
commands.add(CURRENCY_CMD)
initProperties(API_KEY_PROP)
- loadSymbols(properties[ChatGpt2.API_KEY_PROP])
+ loadSymbols(properties[ChatGpt.API_KEY_PROP])
}
}
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini2.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini.kt
similarity index 58%
rename from src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini2.kt
rename to src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini.kt
index 812aed3..2e4ed91 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini2.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini.kt
@@ -31,7 +31,12 @@
package net.thauvin.erik.mobibot.modules
-import dev.langchain4j.model.googleai.GoogleAiGeminiChatModel
+import com.google.cloud.vertexai.VertexAI
+import com.google.cloud.vertexai.api.GenerationConfig
+import com.google.cloud.vertexai.api.HarmCategory
+import com.google.cloud.vertexai.api.SafetySetting
+import com.google.cloud.vertexai.generativeai.GenerativeModel
+import com.google.cloud.vertexai.generativeai.ResponseHandler
import net.thauvin.erik.mobibot.Utils
import net.thauvin.erik.mobibot.Utils.sendMessage
import org.pircbotx.hooks.types.GenericMessageEvent
@@ -40,8 +45,8 @@ import org.slf4j.LoggerFactory
import java.util.*
-class Gemini2 : AbstractModule() {
- private val logger: Logger = LoggerFactory.getLogger(Gemini2::class.java)
+class Gemini : AbstractModule() {
+ private val logger: Logger = LoggerFactory.getLogger(Gemini::class.java)
override val name = GEMINI_NAME
@@ -50,7 +55,8 @@ class Gemini2 : AbstractModule() {
try {
val answer = chat(
args.trim(),
- properties[GEMINI_API_KEY],
+ properties[PROJECT_ID_PROP],
+ properties[LOCATION_PROP],
properties.getOrDefault(MAX_TOKENS_PROP, "1024").toInt()
)
if (!answer.isNullOrEmpty()) {
@@ -76,12 +82,17 @@ class Gemini2 : AbstractModule() {
const val GEMINI_NAME = "Gemini"
/**
- * The API key
+ * The Google cloud project ID property.
*/
- const val GEMINI_API_KEY = "gemini-api-key"
+ const val PROJECT_ID_PROP = "gemini-project-id"
/**
- * The max number of output tokens property.
+ * The Vertex AI location property.
+ */
+ const val LOCATION_PROP = "gemini-location"
+
+ /**
+ * The max number of tokens property.
*/
const val MAX_TOKENS_PROP = "gemini-max-tokens"
@@ -92,18 +103,40 @@ class Gemini2 : AbstractModule() {
@Throws(ModuleException::class)
fun chat(
query: String,
- apiKey: String?,
- maxTokens: Int
+ projectId: String?,
+ location: String?,
+ maxToken: Int
): String? {
- if (!apiKey.isNullOrEmpty()) {
+ if (!projectId.isNullOrEmpty() && !location.isNullOrEmpty()) {
try {
- val gemini = GoogleAiGeminiChatModel.builder()
- .apiKey(apiKey)
- .modelName("gemini-1.5-flash")
- .maxOutputTokens(maxTokens)
- .build()
+ VertexAI(projectId, location).use { vertexAI ->
+ val generationConfig = GenerationConfig.newBuilder().setMaxOutputTokens(maxToken).build()
+ val safetySettings = listOf(
+ SafetySetting.newBuilder()
+ .setCategory(HarmCategory.HARM_CATEGORY_HATE_SPEECH)
+ .setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_LOW_AND_ABOVE)
+ .build(),
+ SafetySetting.newBuilder()
+ .setCategory(HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT)
+ .setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_LOW_AND_ABOVE)
+ .build(),
+ SafetySetting.newBuilder()
+ .setCategory(HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT)
+ .setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_LOW_AND_ABOVE)
+ .build(),
+ SafetySetting.newBuilder()
+ .setCategory(HarmCategory.HARM_CATEGORY_HARASSMENT)
+ .setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_LOW_AND_ABOVE)
+ .build()
+ )
+ val model = GenerativeModel.Builder().setModelName("gemini-1.5-flash-001")
+ .setGenerationConfig(generationConfig)
+ .setVertexAi(vertexAI).build()
+ .withSafetySettings(safetySettings)
- return gemini.generate(query)
+ val response = model.generateContent(query)
+ return ResponseHandler.getText(response)
+ }
} catch (e: Exception) {
throw ModuleException(
"$GEMINI_CMD($query): IO",
@@ -126,6 +159,7 @@ class Gemini2 : AbstractModule() {
add(Utils.helpFormat("%c $GEMINI_CMD explain quantum computing in simple terms"))
add(Utils.helpFormat("%c $GEMINI_CMD how do I make an HTTP request in Javascript?"))
}
- initProperties(GEMINI_API_KEY, MAX_TOKENS_PROP)
+ initProperties(PROJECT_ID_PROP, LOCATION_PROP, MAX_TOKENS_PROP)
}
+
}
diff --git a/src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2Test.kt b/src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGptTest.kt
similarity index 84%
rename from src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2Test.kt
rename to src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGptTest.kt
index 4332a52..1809a9f 100644
--- a/src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2Test.kt
+++ b/src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGptTest.kt
@@ -39,10 +39,10 @@ import net.thauvin.erik.mobibot.DisableOnCi
import net.thauvin.erik.mobibot.LocalProperties
import kotlin.test.Test
-class ChatGpt2Test : LocalProperties() {
+class ChatGptTest : LocalProperties() {
@Test
fun testApiKey() {
- assertFailure { ChatGpt2.chat("1 gallon to liter", "", 0) }
+ assertFailure { ChatGpt.chat("1 gallon to liter", "", 0) }
.isInstanceOf(ModuleException::class.java)
.hasNoCause()
}
@@ -51,7 +51,7 @@ class ChatGpt2Test : LocalProperties() {
fun testChatOnCoverage() {
if (System.getenv("CI") == null || System.getenv("COVERAGE_JDK") != null) {
assertThat(
- ChatGpt2.chat("how do I encode a URL in java?", getProperty(ChatGpt2.API_KEY_PROP), 60)
+ ChatGpt.chat("how do I encode a URL in java?", getProperty(ChatGpt.API_KEY_PROP), 60)
).contains("URLEncoder")
}
}
@@ -59,12 +59,12 @@ class ChatGpt2Test : LocalProperties() {
@Test
@DisableOnCi
fun testChat() {
- val apiKey = getProperty(ChatGpt2.API_KEY_PROP)
+ val apiKey = getProperty(ChatGpt.API_KEY_PROP)
assertThat(
- ChatGpt2.chat("how do I make an HTTP request in Javascript?", apiKey, 200)
+ ChatGpt.chat("how do I make an HTTP request in Javascript?", apiKey, 100)
).contains("XMLHttpRequest")
- assertFailure { ChatGpt2.chat("1 liter to gallon", apiKey, -1) }
+ assertFailure { ChatGpt.chat("1 liter to gallon", apiKey, -1) }
.isInstanceOf(ModuleException::class.java)
}
}
diff --git a/src/test/kotlin/net/thauvin/erik/mobibot/modules/Gemini2Test.kt b/src/test/kotlin/net/thauvin/erik/mobibot/modules/GeminiTest.kt
similarity index 79%
rename from src/test/kotlin/net/thauvin/erik/mobibot/modules/Gemini2Test.kt
rename to src/test/kotlin/net/thauvin/erik/mobibot/modules/GeminiTest.kt
index 226ff6a..1f0202f 100644
--- a/src/test/kotlin/net/thauvin/erik/mobibot/modules/Gemini2Test.kt
+++ b/src/test/kotlin/net/thauvin/erik/mobibot/modules/GeminiTest.kt
@@ -37,10 +37,10 @@ import net.thauvin.erik.mobibot.DisableOnCi
import net.thauvin.erik.mobibot.LocalProperties
import kotlin.test.Test
-class Gemini2Test : LocalProperties() {
+class GeminiTest : LocalProperties() {
@Test
fun testApiKey() {
- assertFailure { Gemini2.chat("1 gallon to liter", "", 0) }
+ assertFailure { Gemini.chat("1 gallon to liter", "", "", 1024) }
.isInstanceOf(ModuleException::class.java)
.hasNoCause()
}
@@ -48,18 +48,19 @@ class Gemini2Test : LocalProperties() {
@Test
@DisableOnCi
fun chatPrompt() {
- val apiKey = getProperty(Gemini2.GEMINI_API_KEY)
- val maxTokens = getProperty(Gemini2.MAX_TOKENS_PROP).toInt()
+ val projectId = getProperty(Gemini.PROJECT_ID_PROP)
+ val location = getProperty(Gemini.LOCATION_PROP)
+ val maxTokens = getProperty(Gemini.MAX_TOKENS_PROP).toInt()
assertThat(
- Gemini2.chat("how do I make an HTTP request in Javascript?", apiKey, maxTokens)
+ Gemini.chat("how do I make an HTTP request in Javascript?", projectId, location, maxTokens)
).isNotNull().contains("XMLHttpRequest")
assertThat(
- Gemini2.chat("how do I encode a URL in java?", apiKey, 60)
+ Gemini.chat("how do I encode a URL in java?", projectId, location, 60)
).isNotNull().contains("URLEncoder")
- assertFailure { Gemini2.chat("1 liter to gallon", "foo", 40) }
+ assertFailure { Gemini.chat("1 liter to gallon", projectId, "blah", 40) }
.isInstanceOf(ModuleException::class.java)
}
}
diff --git a/website/index.html b/website/index.html
index 370c3cf..fffe650 100644
--- a/website/index.html
+++ b/website/index.html
@@ -38,10 +38,10 @@
Apache Commons Net
CryptoPrice
exp4j
+ Google Vertex AI
JokeAPI
jsoup
kotlinx-cli
- LangChain4J
OkHttp
OWM JAPIs
Pinboard Poster