Added Google Gemini module
This commit is contained in:
parent
8412a8c26d
commit
4a4e702d9f
10 changed files with 230 additions and 26 deletions
|
@ -1,15 +1,15 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<ManuallySuppressedIssues></ManuallySuppressedIssues>
|
||||
<CurrentIssues>
|
||||
<ID>CyclomaticComplexMethod:FeedsManager.kt$FeedsManager.Companion$@JvmStatic fun saveFeed(entries: Entries, currentFile: String = CURRENT_XML)</ID>
|
||||
<ID>CyclomaticComplexMethod:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List<Message></ID>
|
||||
<ID>CyclomaticComplexMethod:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List<Message></ID>
|
||||
<ID>LongMethod:FeedsManager.kt$FeedsManager.Companion$@JvmStatic fun saveFeed(entries: Entries, currentFile: String = CURRENT_XML)</ID>
|
||||
<ID>LongMethod:Mobibot.kt$Mobibot.Companion$@JvmStatic @Throws(Exception::class) fun main(args: Array<String>)</ID>
|
||||
<ID>LongMethod:StockQuote.kt$StockQuote.Companion$@JvmStatic @Throws(ModuleException::class) fun getQuote(symbol: String, apiKey: String?): List<Message></ID>
|
||||
<ID>LongMethod:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List<Message></ID>
|
||||
<ID>LongMethod:Mobibot.kt$Mobibot.Companion$@JvmStatic @Throws(Exception::class) fun main(args: Array<String>)</ID>
|
||||
<ID>LongMethod:StockQuote.kt$StockQuote.Companion$@JvmStatic @Throws(ModuleException::class) fun getQuote(symbol: String, apiKey: String?): List<Message></ID>
|
||||
<ID>LongMethod:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List<Message></ID>
|
||||
<ID>LongParameterList:Comment.kt$Comment$( channel: String, cmd: String, entry: EntryLink, entryIndex: Int, commentIndex: Int, event: GenericMessageEvent )</ID>
|
||||
<ID>LongParameterList:EntryLink.kt$EntryLink$( // Link's comments val comments: MutableList<EntryComment> = mutableListOf(), // Tags/categories val tags: MutableList<SyndCategory> = mutableListOf(), // Channel var channel: String, // Creation date var date: Date = Calendar.getInstance().time, // Link's URL var link: String, // Author's login var login: String = "", // Author's nickname var nick: String, // Link's title var title: String )</ID>
|
||||
<ID>LongParameterList:EntryLink.kt$EntryLink$( // Link's comments val comments: MutableList<EntryComment> = mutableListOf(), // Tags/categories val tags: MutableList<SyndCategory> = mutableListOf(), // Channel var channel: String, // Creation date var date: Date = Calendar.getInstance().time, // Link's URL var link: String, // Author's login var login: String = "", // Author's nickname var nick: String, // Link's title var title: String )</ID>
|
||||
<ID>MagicNumber:ChatGpt.kt$ChatGpt$400</ID>
|
||||
<ID>MagicNumber:ChatGpt.kt$ChatGpt.Companion$200</ID>
|
||||
<ID>MagicNumber:ChatGpt.kt$ChatGpt.Companion$429</ID>
|
||||
|
@ -20,6 +20,7 @@
|
|||
<ID>MagicNumber:CurrencyConverter.kt$CurrencyConverter.Companion$4</ID>
|
||||
<ID>MagicNumber:Cycle.kt$Cycle$10</ID>
|
||||
<ID>MagicNumber:Cycle.kt$Cycle$1000L</ID>
|
||||
<ID>MagicNumber:Gemini.kt$Gemini$400</ID>
|
||||
<ID>MagicNumber:Ignore.kt$Ignore$8</ID>
|
||||
<ID>MagicNumber:Info.kt$Info.Companion$30</ID>
|
||||
<ID>MagicNumber:Info.kt$Info.Companion$365</ID>
|
||||
|
@ -52,22 +53,22 @@
|
|||
<ID>NestedBlockDepth:Comment.kt$Comment$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent)</ID>
|
||||
<ID>NestedBlockDepth:CurrencyConverter.kt$CurrencyConverter.Companion$@JvmStatic @Throws(ModuleException::class) fun loadSymbols(apiKey: String?)</ID>
|
||||
<ID>NestedBlockDepth:CurrencyConverter.kt$CurrencyConverter.Companion$@JvmStatic fun convertCurrency(apiKey: String?, query: String): Message</ID>
|
||||
<ID>NestedBlockDepth:EntryLink.kt$EntryLink$private fun setTags(tags: List<String?>)</ID>
|
||||
<ID>NestedBlockDepth:EntryLink.kt$EntryLink$private fun setTags(tags: List<String?>)</ID>
|
||||
<ID>NestedBlockDepth:FeedsManager.kt$FeedsManager.Companion$@JvmStatic @Throws(IOException::class, FeedException::class) fun loadFeed(entries: Entries, currentFile: String = CURRENT_XML): String</ID>
|
||||
<ID>NestedBlockDepth:FeedsManager.kt$FeedsManager.Companion$@JvmStatic fun saveFeed(entries: Entries, currentFile: String = CURRENT_XML)</ID>
|
||||
<ID>NestedBlockDepth:GoogleSearch.kt$GoogleSearch$override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent)</ID>
|
||||
<ID>NestedBlockDepth:GoogleSearch.kt$GoogleSearch.Companion$@JvmStatic @Throws(ModuleException::class) fun searchGoogle( query: String, apiKey: String?, cseKey: String?, quotaUser: String = ReleaseInfo.PROJECT ): List<Message></ID>
|
||||
<ID>NestedBlockDepth:GoogleSearch.kt$GoogleSearch.Companion$@JvmStatic @Throws(ModuleException::class) fun searchGoogle( query: String, apiKey: String?, cseKey: String?, quotaUser: String = ReleaseInfo.PROJECT ): List<Message></ID>
|
||||
<ID>NestedBlockDepth:LinksManager.kt$LinksManager$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent)</ID>
|
||||
<ID>NestedBlockDepth:Lookup.kt$Lookup$override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent)</ID>
|
||||
<ID>NestedBlockDepth:Mastodon.kt$Mastodon.Companion$@JvmStatic @Throws(ModuleException::class) fun toot(apiKey: String?, instance: String?, handle: String?, message: String, isDm: Boolean): String</ID>
|
||||
<ID>NestedBlockDepth:Posting.kt$Posting$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent)</ID>
|
||||
<ID>NestedBlockDepth:Seen.kt$Seen$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent)</ID>
|
||||
<ID>NestedBlockDepth:StockQuote.kt$StockQuote.Companion$@JvmStatic @Throws(ModuleException::class) fun getQuote(symbol: String, apiKey: String?): List<Message></ID>
|
||||
<ID>NestedBlockDepth:StockQuote.kt$StockQuote.Companion$@JvmStatic @Throws(ModuleException::class) fun getQuote(symbol: String, apiKey: String?): List<Message></ID>
|
||||
<ID>NestedBlockDepth:Tell.kt$Tell$fun send(event: GenericUserEvent)</ID>
|
||||
<ID>NestedBlockDepth:Utils.kt$Utils$@JvmStatic fun loadSerialData(file: String, default: Any, logger: Logger, description: String): Any</ID>
|
||||
<ID>NestedBlockDepth:Utils.kt$Utils$@JvmStatic fun saveSerialData(file: String, data: Any, logger: Logger, description: String)</ID>
|
||||
<ID>NestedBlockDepth:Weather2.kt$Weather2$override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent)</ID>
|
||||
<ID>NestedBlockDepth:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List<Message></ID>
|
||||
<ID>NestedBlockDepth:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List<Message></ID>
|
||||
<ID>ReturnCount:Addons.kt$Addons$fun exec(channel: String, cmd: String, args: String, event: GenericMessageEvent): Boolean</ID>
|
||||
<ID>ReturnCount:Addons.kt$Addons$fun help(channel: String, topic: String, event: GenericMessageEvent): Boolean</ID>
|
||||
<ID>ReturnCount:ExceptionSanitizer.kt$ExceptionSanitizer$fun ModuleException.sanitize(vararg sanitize: String): ModuleException</ID>
|
||||
|
@ -76,13 +77,14 @@
|
|||
<ID>SwallowedException:StockQuoteTest.kt$StockQuoteTest$e: ModuleException</ID>
|
||||
<ID>SwallowedException:WolframAlphaTest.kt$WolframAlphaTest$e: ModuleException</ID>
|
||||
<ID>ThrowsCount:ChatGpt.kt$ChatGpt.Companion$@JvmStatic @Throws(ModuleException::class) fun chat(query: String, apiKey: String?, maxTokens: Int): String</ID>
|
||||
<ID>ThrowsCount:GoogleSearch.kt$GoogleSearch.Companion$@JvmStatic @Throws(ModuleException::class) fun searchGoogle( query: String, apiKey: String?, cseKey: String?, quotaUser: String = ReleaseInfo.PROJECT ): List<Message></ID>
|
||||
<ID>ThrowsCount:Joke.kt$Joke.Companion$@JvmStatic @Throws(ModuleException::class) fun randomJoke(): List<Message></ID>
|
||||
<ID>ThrowsCount:GoogleSearch.kt$GoogleSearch.Companion$@JvmStatic @Throws(ModuleException::class) fun searchGoogle( query: String, apiKey: String?, cseKey: String?, quotaUser: String = ReleaseInfo.PROJECT ): List<Message></ID>
|
||||
<ID>ThrowsCount:Joke.kt$Joke.Companion$@JvmStatic @Throws(ModuleException::class) fun randomJoke(): List<Message></ID>
|
||||
<ID>ThrowsCount:Mastodon.kt$Mastodon.Companion$@JvmStatic @Throws(ModuleException::class) fun toot(apiKey: String?, instance: String?, handle: String?, message: String, isDm: Boolean): String</ID>
|
||||
<ID>ThrowsCount:StockQuote.kt$StockQuote.Companion$@JvmStatic @Throws(ModuleException::class) fun getQuote(symbol: String, apiKey: String?): List<Message></ID>
|
||||
<ID>ThrowsCount:StockQuote.kt$StockQuote.Companion$@JvmStatic @Throws(ModuleException::class) fun getQuote(symbol: String, apiKey: String?): List<Message></ID>
|
||||
<ID>ThrowsCount:StockQuote.kt$StockQuote.Companion$@Throws(ModuleException::class) private fun getJsonResponse(response: String, debugMessage: String): JSONObject</ID>
|
||||
<ID>ThrowsCount:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List<Message></ID>
|
||||
<ID>ThrowsCount:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List<Message></ID>
|
||||
<ID>ThrowsCount:WolframAlpha.kt$WolframAlpha.Companion$@JvmStatic @Throws(ModuleException::class) fun queryWolfram(query: String, units: String = IMPERIAL, appId: String?): String</ID>
|
||||
<ID>TooGenericExceptionCaught:Gemini.kt$Gemini.Companion$e: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:StockQuote.kt$StockQuote.Companion$e: NullPointerException</ID>
|
||||
<ID>TooGenericExceptionCaught:Weather2.kt$Weather2.Companion$e: NullPointerException</ID>
|
||||
<ID>TooManyFunctions:EntryLink.kt$EntryLink : Serializable</ID>
|
||||
|
@ -94,6 +96,7 @@
|
|||
<ID>WildcardImport:FeedMgrTest.kt$import assertk.assertions.*</ID>
|
||||
<ID>WildcardImport:FeedReaderTest.kt$import assertk.assertions.*</ID>
|
||||
<ID>WildcardImport:FeedsManager.kt$import com.rometools.rome.feed.synd.*</ID>
|
||||
<ID>WildcardImport:GeminiTest.kt$import assertk.assertions.*</ID>
|
||||
<ID>WildcardImport:GoogleSearchTest.kt$import assertk.assertions.*</ID>
|
||||
<ID>WildcardImport:JokeTest.kt$import assertk.assertions.*</ID>
|
||||
<ID>WildcardImport:Mobibot.kt$import java.io.*</ID>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#!/bin/bash
|
||||
|
||||
./bld jar deploy
|
||||
[ $? -eq 0 ] && sftp nix3.thauvin.us <<EOF
|
||||
cd mobitopia/mobibot
|
||||
./bld clean jar deploy
|
||||
[ $? -eq 0 ] && sftp nix4.thauvin.us <<EOF
|
||||
cd /home/mobibot/mobitopia/mobibot
|
||||
lcd deploy
|
||||
put *.jar
|
||||
cd lib
|
||||
|
|
|
@ -79,3 +79,14 @@ disabled-modules=mastodon
|
|||
#
|
||||
#chatgpt-api-key=
|
||||
#chatgpt-max-tokens=1024
|
||||
|
||||
#
|
||||
# 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-project-id=
|
||||
#gemini-location=us-west1
|
||||
#gemini-max-tokens=1024
|
||||
|
|
|
@ -50,7 +50,8 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.jar.Attributes;
|
||||
|
||||
import static rife.bld.dependencies.Repository.*;
|
||||
import static rife.bld.dependencies.Repository.MAVEN_CENTRAL;
|
||||
import static rife.bld.dependencies.Repository.MAVEN_LOCAL;
|
||||
import static rife.bld.dependencies.Scope.compile;
|
||||
import static rife.bld.dependencies.Scope.test;
|
||||
|
||||
|
@ -82,9 +83,9 @@ public class MobibotBuild extends Project {
|
|||
// Google
|
||||
.include(dependency("com.google.code.gson", "gson", "2.10.1"))
|
||||
.include(dependency("com.google.guava", "guava", "32.1.3-jre"))
|
||||
.include(dependency("com.google.cloud", "google-cloud-vertexai", version(0, 1, 0)))
|
||||
// Kotlin
|
||||
.include(dependency("org.jetbrains.kotlin", "kotlin-stdlib", kotlin))
|
||||
.include(dependency("org.jetbrains.kotlin", "kotlin-stdlib-common", kotlin))
|
||||
.include(dependency("org.jetbrains.kotlin", "kotlin-stdlib-jdk7", kotlin))
|
||||
.include(dependency("org.jetbrains.kotlin", "kotlin-stdlib-jdk8", kotlin))
|
||||
.include(dependency("org.jetbrains.kotlinx", "kotlinx-coroutines-core", "1.7.3"))
|
||||
|
@ -100,19 +101,20 @@ public class MobibotBuild extends Project {
|
|||
.include(dependency("net.aksingh", "owm-japis", "2.5.3.0"))
|
||||
.include(dependency("net.objecthunter", "exp4j", "0.4.8"))
|
||||
.include(dependency("org.json", "json", "20231013"))
|
||||
.include(dependency("org.jsoup", "jsoup", "1.16.2"))
|
||||
.include(dependency("org.jsoup", "jsoup", "1.17.1"))
|
||||
// Thauvin
|
||||
.include(dependency("net.thauvin.erik", "cryptoprice", "1.0.2"))
|
||||
.include(dependency("net.thauvin.erik", "jokeapi", "0.9.1"))
|
||||
.include(dependency("net.thauvin.erik", "pinboard-poster", "1.1.1"))
|
||||
.include(dependency("net.thauvin.erik.urlencoder", "urlencoder-lib-jvm", "1.4.0"));
|
||||
scope(test)
|
||||
.include(dependency("com.willowtreeapps.assertk", "assertk-jvm", version(0, 27, 0)))
|
||||
.include(dependency("com.willowtreeapps.assertk", "assertk-jvm", version(0, 28, 0)))
|
||||
.include(dependency("org.jetbrains.kotlin", "kotlin-test-junit5", version(1, 9, 21)))
|
||||
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 1)))
|
||||
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 1)));
|
||||
|
||||
List<String> jars = new ArrayList<>();
|
||||
runtimeClasspathJars().forEach(f -> jars.add("./lib/" + f.getName()));
|
||||
compileClasspathJars().forEach(f -> jars.add("./lib/" + f.getName()));
|
||||
jarOperation()
|
||||
.manifestAttribute(Attributes.Name.MAIN_CLASS, mainClass())
|
||||
|
@ -149,6 +151,9 @@ public class MobibotBuild extends Project {
|
|||
for (var jar : compileClasspathJars()) {
|
||||
FileUtils.copy(jar, new File(lib, jar.getName()));
|
||||
}
|
||||
for (var jar : runtimeClasspathJars()) {
|
||||
FileUtils.copy(jar, new File(lib, jar.getName()));
|
||||
}
|
||||
FileUtils.copy(new File(buildDistDirectory(), jarFileName()), new File(deploy, "mobibot.jar"));
|
||||
}
|
||||
|
||||
|
|
|
@ -400,6 +400,7 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro
|
|||
addons.add(CryptoPrices())
|
||||
addons.add(CurrencyConverter())
|
||||
addons.add(Dice())
|
||||
addons.add(Gemini())
|
||||
addons.add(GoogleSearch())
|
||||
addons.add(Info(tell, seen))
|
||||
addons.add(Joke())
|
||||
|
|
|
@ -14,12 +14,12 @@ import java.time.ZoneId
|
|||
*/
|
||||
object ReleaseInfo {
|
||||
const val PROJECT = "mobibot"
|
||||
const val VERSION = "0.8.0-rc+20231125224843"
|
||||
const val VERSION = "0.8.0-rc+20231217213124"
|
||||
|
||||
@JvmField
|
||||
@Suppress("MagicNumber")
|
||||
val BUILD_DATE: LocalDateTime = LocalDateTime.ofInstant(
|
||||
Instant.ofEpochMilli(1700981323173L), ZoneId.systemDefault()
|
||||
Instant.ofEpochMilli(1702877484912L), ZoneId.systemDefault()
|
||||
)
|
||||
|
||||
const val WEBSITE = "https://www.mobitopia.org/mobibot/"
|
||||
|
|
|
@ -42,7 +42,7 @@ class Versions : AbstractCommand() {
|
|||
private val allVersions = listOf(
|
||||
"Version: ${ReleaseInfo.VERSION} (${ReleaseInfo.BUILD_DATE.toIsoLocalDate()})",
|
||||
"${System.getProperty("os.name")} ${System.getProperty("os.version")} (${System.getProperty("os.arch")})" +
|
||||
", JVM ${System.getProperty("java.runtime.version")}",
|
||||
", JVM ${System.getProperty("java.version")}",
|
||||
"Kotlin ${KotlinVersion.CURRENT}, PircBotX ${PircBotX.VERSION}"
|
||||
)
|
||||
override val name = "versions"
|
||||
|
|
116
src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini.kt
Normal file
116
src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini.kt
Normal file
|
@ -0,0 +1,116 @@
|
|||
package net.thauvin.erik.mobibot.modules
|
||||
|
||||
import com.google.auth.Credentials
|
||||
import com.google.cloud.vertexai.VertexAI
|
||||
import com.google.cloud.vertexai.api.GenerateContentResponse
|
||||
import com.google.cloud.vertexai.api.GenerationConfig
|
||||
import com.google.cloud.vertexai.generativeai.preview.ChatSession
|
||||
import com.google.cloud.vertexai.generativeai.preview.GenerativeModel
|
||||
import com.google.cloud.vertexai.generativeai.preview.ResponseHandler
|
||||
import net.thauvin.erik.mobibot.Utils
|
||||
import net.thauvin.erik.mobibot.Utils.sendMessage
|
||||
import okio.IOException
|
||||
import org.apache.commons.text.WordUtils
|
||||
import org.pircbotx.hooks.types.GenericMessageEvent
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
|
||||
class Gemini : AbstractModule() {
|
||||
private val logger: Logger = LoggerFactory.getLogger(Gemini::class.java)
|
||||
|
||||
override val name = GEMINI_NAME
|
||||
|
||||
override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) {
|
||||
if (args.isNotBlank()) {
|
||||
try {
|
||||
val answer = chat(
|
||||
args.trim(),
|
||||
properties[PROJECT_ID_PROP],
|
||||
properties[LOCATION_PROPR],
|
||||
properties.getOrDefault(MAX_TOKENS_PROP, "1024").toInt()
|
||||
)
|
||||
if (!answer.isNullOrEmpty()) {
|
||||
event.sendMessage(answer)
|
||||
} else {
|
||||
event.respond("$name is stumped.")
|
||||
}
|
||||
} catch (e: ModuleException) {
|
||||
if (logger.isWarnEnabled) logger.warn(e.debugMessage, e)
|
||||
e.message?.let {
|
||||
event.respond(it)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
helpResponse(event)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* The service name.
|
||||
*/
|
||||
const val GEMINI_NAME = "Gemini"
|
||||
|
||||
/**
|
||||
* The Google cloud project ID.
|
||||
*/
|
||||
const val PROJECT_ID_PROP = "gemini-project-id"
|
||||
|
||||
/**
|
||||
* The Vertex AI location.
|
||||
*/
|
||||
const val LOCATION_PROPR = "gemini-location"
|
||||
|
||||
/**
|
||||
* The max tokens property.
|
||||
*/
|
||||
const val MAX_TOKENS_PROP = "gemini-max-tokens"
|
||||
|
||||
// ChatGPT command
|
||||
private const val GEMINI_CMD = "gemini"
|
||||
|
||||
@JvmStatic
|
||||
@Throws(ModuleException::class)
|
||||
fun chat(
|
||||
query: String,
|
||||
projectId: String?,
|
||||
location: String?,
|
||||
maxToken: Int
|
||||
): String? {
|
||||
if (!projectId.isNullOrEmpty() && !location.isNullOrEmpty()) {
|
||||
try {
|
||||
VertexAI(projectId, location).use { vertexAI ->
|
||||
val generationConfig = GenerationConfig.newBuilder().setMaxOutputTokens(maxToken).build()
|
||||
val model = GenerativeModel("gemini-pro-vision", generationConfig, vertexAI)
|
||||
val session = ChatSession(model)
|
||||
val response = session.sendMessage(query)
|
||||
|
||||
return ResponseHandler.getText(response);
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw ModuleException(
|
||||
"$GEMINI_CMD($query): IO",
|
||||
"An IO error has occurred while conversing with ${GEMINI_NAME}.",
|
||||
e
|
||||
)
|
||||
}
|
||||
} else {
|
||||
throw ModuleException("${GEMINI_CMD}($query)", "No ${GEMINI_NAME} Project ID or Location specified.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
commands.add(GEMINI_CMD)
|
||||
with(help) {
|
||||
add("To get answers from $name:")
|
||||
add(Utils.helpFormat("%c ${GEMINI_CMD} <query>"))
|
||||
add("For example:")
|
||||
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(PROJECT_ID_PROP, LOCATION_PROPR, MAX_TOKENS_PROP)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* ChatGptTest.kt
|
||||
*
|
||||
* Copyright 2004-2023 Erik C. Thauvin (erik@thauvin.net)
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of this project nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.thauvin.erik.mobibot.modules
|
||||
|
||||
import assertk.assertFailure
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.*
|
||||
import net.thauvin.erik.mobibot.DisableOnCi
|
||||
import net.thauvin.erik.mobibot.LocalProperties
|
||||
import kotlin.test.Test
|
||||
|
||||
class GeminiTest : LocalProperties() {
|
||||
@Test
|
||||
fun testApiKey() {
|
||||
assertFailure { Gemini.chat("1 gallon to liter", "", "", 1024) }
|
||||
.isInstanceOf(ModuleException::class.java)
|
||||
.hasNoCause()
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisableOnCi
|
||||
fun chatPrompt() {
|
||||
val projectId = getProperty(Gemini.PROJECT_ID_PROP)
|
||||
val location = getProperty(Gemini.LOCATION_PROPR)
|
||||
val maxTokens = getProperty(Gemini.MAX_TOKENS_PROP).toInt()
|
||||
|
||||
assertThat(
|
||||
Gemini.chat("how do I make an HTTP request in Javascript?", projectId, location, maxTokens)
|
||||
).isNotNull().contains("XMLHttpRequest")
|
||||
|
||||
assertThat(
|
||||
Gemini.chat("how do I encode a URL in java?", projectId, location, 60)
|
||||
).isNotNull().contains("URLEncoder")
|
||||
|
||||
assertFailure { Gemini.chat("1 liter to gallon", projectId, "blah", 40) }
|
||||
.isInstanceOf(ModuleException::class.java)
|
||||
}
|
||||
}
|
|
@ -38,6 +38,7 @@
|
|||
<li><a href="https://commons.apache.org/proper/commons-net/">Apache Commons Net</a></li>
|
||||
<li><a href="https://github.com/ethauvin/cryptoprice">CryptoPrice</a></li>
|
||||
<li><a href="https://www.objecthunter.net/exp4j/">exp4j</a></li>
|
||||
<li><a href="https://github.com/googleapis/google-cloud-java/tree/main/java-vertexai">Google Vertex AI</a></li>
|
||||
<li><a href="https://github.com/ethauvin/jokeapi">JokeAPI</a></li>
|
||||
<li><a href="https://jsoup.org/">jsoup</a></li>
|
||||
<li><a href="https://github.com/Kotlin/kotlinx-cli">kotlinx-cli</a></li>
|
||||
|
@ -80,9 +81,10 @@
|
|||
<li>Performing Google searches
|
||||
<div><code>mobibot: google mobitopia on irc</code></div>
|
||||
</li>
|
||||
<li>Getting answers from <a href="https://wolframalpha.com/">Wolfram Alpha</a> and <a href="https://chat.openai.com/chat">ChatGPT</a>
|
||||
<li>Getting answers from <a href="https://wolframalpha.com/">Wolfram Alpha</a>, <a href="https://chat.openai.com/chat">ChatGPT</a> and <a href="https://deepmind.google/technologies/gemini/">Google Gemini</a>
|
||||
<div><code>mobibot: wolfram days until christmas</code></div>
|
||||
<div><code>mobibot: chatgpt explain quantum computing in simple terms</code></div>
|
||||
<div><code>mobibot: gemini what are all the colors in a rainbow?</code></div>
|
||||
</li>
|
||||
<li>Displaying weather information
|
||||
<div><code>mobibot: weather san francisco</code></div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue