diff --git a/pom.xml b/pom.xml
index 41a47ff9..815167e9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -553,14 +553,14 @@
4.4.4
2.1.5
5.1.0
- 2.14.2
+ 2.17.0
0.8.5
2.3.1
1.15.4
- 1.9.22
+ 1.9.23
1.5.3
2.3.9
- 4.10.0
+ 4.12.0
2.0.12
0.25
1.0.1
diff --git a/src/main/kotlin/javabot/Javabot.kt b/src/main/kotlin/javabot/Javabot.kt
index 935fabc6..b2af8e9e 100644
--- a/src/main/kotlin/javabot/Javabot.kt
+++ b/src/main/kotlin/javabot/Javabot.kt
@@ -93,8 +93,7 @@ constructor(
val activeOperations = sortedSetOf(OperationComparator())
- @Volatile
- private var running = true
+ @Volatile private var running = true
init {
val hook = Thread { this.shutdown() }
@@ -263,8 +262,8 @@ constructor(
if (
!ignores.contains(sender.nick) &&
- !shunDao.isShunned(sender.nick) &&
- (message.channel != null || isOnCommonChannel(message.user))
+ !shunDao.isShunned(sender.nick) &&
+ (message.channel != null || isOnCommonChannel(message.user))
) {
try {
if (message.triggered) {
@@ -339,9 +338,9 @@ constructor(
if (
responses.isEmpty() &&
- (!message.value
- .lowercase(Locale.getDefault())
- .startsWith("${nick}'s".lowercase(Locale.getDefault())))
+ (!message.value
+ .lowercase(Locale.getDefault())
+ .startsWith("${nick}'s".lowercase(Locale.getDefault())))
) {
responses.add(
Message(message.channel, message.user, Sofia.unhandledMessage(message.user.nick))
diff --git a/src/main/kotlin/javabot/Message.kt b/src/main/kotlin/javabot/Message.kt
index d634de5d..e44fb7f5 100644
--- a/src/main/kotlin/javabot/Message.kt
+++ b/src/main/kotlin/javabot/Message.kt
@@ -138,9 +138,7 @@ open class Message(
}
}
-/**
- * This is a standard message type whose content is NOT output to a user.
- */
+/** This is a standard message type whose content is NOT output to a user. */
class NoOperationMessage(
channel: Channel? = null,
user: JavabotUser,
@@ -148,14 +146,7 @@ class NoOperationMessage(
target: JavabotUser? = null,
triggered: Boolean = true,
addressed: Boolean = false
-) : Message(
- channel,
- user,
- value,
- target,
- triggered,
- addressed
-) {
+) : Message(channel, user, value, target, triggered, addressed) {
constructor(
message: Message,
value: String
diff --git a/src/main/kotlin/javabot/dao/ChatGPTDao.kt b/src/main/kotlin/javabot/dao/ChatGPTDao.kt
index 8ab7b615..857da9bf 100644
--- a/src/main/kotlin/javabot/dao/ChatGPTDao.kt
+++ b/src/main/kotlin/javabot/dao/ChatGPTDao.kt
@@ -3,18 +3,13 @@ package javabot.dao
import com.enigmastation.kgpt.GPT
import com.enigmastation.kgpt.model.BaseGPTResponse
import com.enigmastation.kgpt.model.GPTMessage
-import com.enigmastation.kgpt.model.GPTResponse
-import com.fasterxml.jackson.annotation.JsonProperty
-import com.fasterxml.jackson.databind.DeserializationFeature
-import com.fasterxml.jackson.databind.ObjectMapper
import com.google.common.cache.CacheBuilder
import com.google.inject.Inject
import com.google.inject.Singleton
import io.dropwizard.util.Duration
+import java.util.concurrent.TimeUnit
import javabot.JavabotConfig
import javabot.operations.throttle.BotRateLimiter
-import javabot.service.HttpService
-import java.util.concurrent.TimeUnit
@Singleton
class ChatGPTDao
@@ -22,18 +17,19 @@ class ChatGPTDao
constructor(
private val javabotConfig: JavabotConfig,
) {
- private val gpt= GPT(javabotConfig.chatGptKey())
+ private val gpt = GPT(javabotConfig.chatGptKey())
private val limiter: BotRateLimiter =
BotRateLimiter(javabotConfig.chatGptLimit(), Duration.days(1).toMilliseconds())
- private val queryCache = CacheBuilder.newBuilder()
- .maximumSize(100)
- .expireAfterWrite(1, TimeUnit.DAYS)
- .build();
+ private val queryCache =
+ CacheBuilder.newBuilder()
+ .maximumSize(100)
+ .expireAfterWrite(1, TimeUnit.DAYS)
+ .build()
- private fun getGPTResponse(prompts:List): BaseGPTResponse = gpt.query(prompts)
+ private fun getGPTResponse(prompts: List): BaseGPTResponse = gpt.query(prompts)
- fun sendPromptToChatGPT(key: String, prompts:List): String? {
+ fun sendPromptToChatGPT(key: String, prompts: List): String? {
return if (limiter.tryAcquire()) {
val response = queryCache.get(key) { getGPTResponse(prompts) }
return response.first()
diff --git a/src/main/kotlin/javabot/model/Factoid.kt b/src/main/kotlin/javabot/model/Factoid.kt
index 576b79f4..5713040a 100644
--- a/src/main/kotlin/javabot/model/Factoid.kt
+++ b/src/main/kotlin/javabot/model/Factoid.kt
@@ -41,6 +41,7 @@ class Factoid() : Serializable, Persistent {
var lastUsed: LocalDateTime? = null
var locked = false
+ var usage = 0
@Indexed lateinit var upperName: String
@@ -94,7 +95,7 @@ class Factoid() : Serializable, Persistent {
private fun camelcase(`in`: String): String {
val sb = StringBuilder(`in`.replace("\\s".toRegex(), " "))
- if (!`in`.isEmpty()) {
+ if (`in`.isNotEmpty()) {
var idx = sb.indexOf(" ")
sb.setCharAt(0, Character.toUpperCase(sb[0]))
while (idx > -1) {
@@ -141,14 +142,15 @@ class Factoid() : Serializable, Persistent {
override fun toString(): String {
return format(
- "Factoid{id=%s, name='%s', value='%s', userName='%s', updated=%s, lastUsed=%s, locked=%s}",
+ "Factoid{id=%s, name='%s', value='%s', userName='%s', updated=%s, lastUsed=%s, locked=%s, usage=%d}",
id,
name,
value,
userName,
updated,
lastUsed,
- locked
+ locked,
+ usage
)
}
diff --git a/src/main/kotlin/javabot/operations/ChatGPTOperation.kt b/src/main/kotlin/javabot/operations/ChatGPTOperation.kt
index 14e8f082..890551da 100644
--- a/src/main/kotlin/javabot/operations/ChatGPTOperation.kt
+++ b/src/main/kotlin/javabot/operations/ChatGPTOperation.kt
@@ -8,7 +8,6 @@ import javabot.Message
import javabot.NoOperationMessage
import javabot.dao.AdminDao
import javabot.dao.ChatGPTDao
-import javabot.dao.FactoidDao
import javax.inject.Inject
/** Gets current weather conditions for a place given as a parameter. */
@@ -19,7 +18,6 @@ constructor(
adminDao: AdminDao,
private var chatGPTDao: ChatGPTDao,
private var getFactoidOperation: GetFactoidOperation
-
) : BotOperation(bot, adminDao) {
override fun handleMessage(event: Message): List {
val message = event.value
@@ -30,7 +28,8 @@ constructor(
query.equals("help", true) ->
responses.add(
Message(
- event, """
+ event,
+ """
Simply use '~gpt query' to generate a Java-focused query.
Note that GPT is not exceptionally reliable: the data is based
on content from April 2023, and should be considered as if the
@@ -40,36 +39,48 @@ constructor(
.cleanForIRC()
)
)
-
else -> {
- val factoid = getFactoidOperation.handleMessage(Message(event.user, query)).firstOrNull()?.value
- val seed = when {
- factoid != null ->
- "Frame the response in the context of the query having a potential answer of '${factoid}'."
- else -> null
- }
+ val factoid =
+ getFactoidOperation
+ .handleMessage(Message(event.user, query))
+ .firstOrNull()
+ ?.value
+ val seed =
+ when {
+ factoid != null ->
+ "Frame the response in the context of the query having a potential answer of '${factoid}'."
+ else -> null
+ }
val uuid = UUID.randomUUID()
try {
- val result = chatGPTDao.sendPromptToChatGPT(
- query,
- listOfNotNull(
- "Someone is asking '$query', in the context of the Java Virtual Machine.".asUser(),
- """
+ val result =
+ chatGPTDao.sendPromptToChatGPT(
+ query,
+ listOfNotNull(
+ "Someone is asking '$query', in the context of the Java Virtual Machine."
+ .asUser(),
+ """
If the answer does not contain constructive information for Java programmers,
respond **ONLY** with \"$uuid-not applicable\" and no other text.
Restrict your answer to being applicable to the Java Virtual Machine, and
limit the response's length to under 500 characters, formatted as simple text,
no markdown or other markup, but urls are acceptable.
- """.trimIndent().asSystem(),
- seed?.asSystem()
+ """
+ .trimIndent()
+ .asSystem(),
+ seed?.asSystem()
+ )
)
- )
- if (!result.isNullOrEmpty() && !result.lowercase().contains(uuid.toString())) {
+ if (
+ !result.isNullOrEmpty() && !result.lowercase().contains(uuid.toString())
+ ) {
val response = result.cleanForIRC()
responses.add(Message(event, response))
} else {
- responses.add(NoOperationMessage(event, "no appropriate response from ChatGPT"))
+ responses.add(
+ NoOperationMessage(event, "no appropriate response from ChatGPT")
+ )
}
} catch (e: Throwable) {
Javabot.LOG.info("exception", e)
@@ -82,9 +93,5 @@ constructor(
}
fun String.cleanForIRC(): String {
- return this.trimIndent()
- .trim()
- .replace("\n ", " ")
- .replace(" \n", " ")
- .replace("\n", " ")
+ return this.trimIndent().trim().replace("\n ", " ").replace(" \n", " ").replace("\n", " ")
}
diff --git a/src/main/kotlin/javabot/operations/GetFactoidOperation.kt b/src/main/kotlin/javabot/operations/GetFactoidOperation.kt
index df964de6..7d836b13 100644
--- a/src/main/kotlin/javabot/operations/GetFactoidOperation.kt
+++ b/src/main/kotlin/javabot/operations/GetFactoidOperation.kt
@@ -53,6 +53,7 @@ constructor(bot: Javabot, adminDao: AdminDao, var factoidDao: FactoidDao) :
if (factoid != null) {
getResponse(responses, event, backtrack, params, factoid)
factoid.lastUsed = LocalDateTime.now()
+ factoid.usage += 1
factoidDao.save(factoid)
}
}
diff --git a/src/main/kotlin/javabot/operations/urlcontent/URLFromMessageParser.kt b/src/main/kotlin/javabot/operations/urlcontent/URLFromMessageParser.kt
index 7a59fb7b..f654a737 100644
--- a/src/main/kotlin/javabot/operations/urlcontent/URLFromMessageParser.kt
+++ b/src/main/kotlin/javabot/operations/urlcontent/URLFromMessageParser.kt
@@ -36,20 +36,22 @@ class URLFromMessageParser {
val idxPunc = ArrayUtils.indexOf(CLOSE_PUNCTUATION, last)
if (idxPunc == -1) {
return url
+ } else {
+ return url.substring(0,url.indexOf(CLOSE_PUNCTUATION[idxPunc]))
}
// Walk backwards in message from urlStart, and strip the punctuation if an open
// brace/bracket is seen
// before another close. Otherwise, return the url as is.
- for (c in StringUtils.reverse(message.substring(0, idxUrlStart)).toCharArray()) {
- if (c == OPEN_PUNCTUATION[idxPunc]) {
- return url.substring(0, url.length - 1)
- }
- if (c == CLOSE_PUNCTUATION[idxPunc]) {
- return url
- }
- }
- return url
+// for (c in StringUtils.reverse(message.substring(0, idxUrlStart)).toCharArray()) {
+// if (c == OPEN_PUNCTUATION[idxPunc]) {
+// return url.substring(0, url.length - 1)
+// }
+// if (c == CLOSE_PUNCTUATION[idxPunc]) {
+// return url
+// }
+// }
+// return url
}
private fun urlFromToken(token: String): URL? {
@@ -64,7 +66,7 @@ class URLFromMessageParser {
companion object {
private val OPEN_PUNCTUATION = charArrayOf('{', '(', '[')
private val CLOSE_PUNCTUATION = charArrayOf('}', ')', ']')
- val blacklistHosts =
+ val blacklistHosts: List =
try {
this::class
.java
@@ -72,7 +74,7 @@ class URLFromMessageParser {
.bufferedReader(Charsets.UTF_8)
.use { it.lines().collect(Collectors.toList()) }
} catch (ignored: Exception) {
- emptyList()
+ emptyList()
}
}
}
diff --git a/src/main/kotlin/javabot/service/HttpService.kt b/src/main/kotlin/javabot/service/HttpService.kt
index f219d753..63f14684 100644
--- a/src/main/kotlin/javabot/service/HttpService.kt
+++ b/src/main/kotlin/javabot/service/HttpService.kt
@@ -97,7 +97,6 @@ class HttpService {
bodyContent.toRequestBody("application/json; chartset=utf-8".toMediaType())
)
}
-
else ->
throw IllegalArgumentException("method type $method not supported by HttpService")
}
@@ -105,14 +104,14 @@ class HttpService {
// if options aren't empty, build a local copy of the request.
// otherwise, use the global client options as is.
if (options.isNotEmpty()) {
- val localRequest = client.newBuilder()
+ val localRequest = client.newBuilder()
- options.forEach { action -> action.key.apply(localRequest, action.value) }
+ options.forEach { action -> action.key.apply(localRequest, action.value) }
- localRequest.build()
- } else {
- client
- }
+ localRequest.build()
+ } else {
+ client
+ }
.newCall(request)
.execute()
.use { response ->
diff --git a/src/test/kotlin/javabot/operations/ChatGPTOperationTest.kt b/src/test/kotlin/javabot/operations/ChatGPTOperationTest.kt
index 914cb62b..deb3b6b6 100644
--- a/src/test/kotlin/javabot/operations/ChatGPTOperationTest.kt
+++ b/src/test/kotlin/javabot/operations/ChatGPTOperationTest.kt
@@ -11,40 +11,42 @@ import org.testng.annotations.DataProvider
import org.testng.annotations.Test
class ChatGPTOperationTest : BaseTest() {
- @Inject
- protected lateinit var operation: ChatGPTOperation
- @Inject
- protected lateinit var addFactoidOperation: AddFactoidOperation
+ @Inject protected lateinit var operation: ChatGPTOperation
+ @Inject protected lateinit var addFactoidOperation: AddFactoidOperation
- @Inject
- protected lateinit var config: JavabotConfig
+ @Inject protected lateinit var config: JavabotConfig
@BeforeClass
fun prepFactoids() {
- addFactoidOperation.handleMessage(message("""
+ addFactoidOperation.handleMessage(
+ message(
+ """
~suffering-oriented programming is
Suffering-oriented programming:
make it work, make it pretty, make it fast
- in that order.
http://nathanmarz.com/blog/suffering-oriented-programming.html"""
- .cleanForIRC()))
+ .cleanForIRC()
+ )
+ )
}
+
@DataProvider
- fun queries() = arrayOf(
- arrayOf("help", false, "query. Note that GPT"),
- arrayOf("speed of an african laden swallow", true, ""),
- arrayOf("what is the maven directory structure", false, "Maven directory structure"),
- arrayOf("suffering-oriented programming", false, "Suffering-oriented programming"),
- arrayOf("list of DI frameworks", false, "Spring"),
- arrayOf("list of DI frameworks", false, "Spring"),
- arrayOf("how do I declare a new variable in Javascript", true, "")
- )
+ fun queries() =
+ arrayOf(
+ arrayOf("help", false, "query. Note that GPT"),
+ arrayOf("speed of an african laden swallow", true, ""),
+ arrayOf("what is the maven directory structure", false, "Maven directory structure"),
+ arrayOf("suffering-oriented programming", false, "Suffering-oriented programming"),
+ arrayOf("list of DI frameworks", false, "Spring"),
+ arrayOf("list of DI frameworks", false, "Spring"),
+ arrayOf("how do I declare a new variable in Javascript", true, "")
+ )
@Test(dataProvider = "queries")
fun runTestQuery(prompt: String, empty: Boolean, match: String) {
if (config.chatGptKey().isNotEmpty()) {
- val response =
- operation.handleMessage(message("~gpt $prompt"))
+ val response = operation.handleMessage(message("~gpt $prompt"))
println(response)
if (empty) {
assertTrue(response.isNotEmpty())
@@ -58,7 +60,6 @@ class ChatGPTOperationTest : BaseTest() {
}
}
-
fun testNonJavaQuestion() {
if (config.chatGptKey().isNotEmpty()) {
val response =
diff --git a/src/test/kotlin/javabot/operations/GetFactoidOperationTest.kt b/src/test/kotlin/javabot/operations/GetFactoidOperationTest.kt
index f13f342c..950479f8 100644
--- a/src/test/kotlin/javabot/operations/GetFactoidOperationTest.kt
+++ b/src/test/kotlin/javabot/operations/GetFactoidOperationTest.kt
@@ -102,12 +102,14 @@ class GetFactoidOperationTest : BaseTest() {
}
fun straightGets() {
+ Assert.assertEquals(factoidDao.getFactoid("api")?.usage, 0)
val response = operation.handleMessage(message("~api"))
Assert.assertEquals(
response[0].value,
getFoundMessage("api", "http://java.sun.com/javase/current/docs/api/index.html")
)
Assert.assertNotNull(factoidDao.getFactoid("api")?.lastUsed)
+ Assert.assertEquals(factoidDao.getFactoid("api")?.usage, 1)
}
fun dates() {
diff --git a/src/test/kotlin/javabot/operations/urlcontent/URLFromMessageParserTest.kt b/src/test/kotlin/javabot/operations/urlcontent/URLFromMessageParserTest.kt
index 31540ab8..cc28d4e0 100644
--- a/src/test/kotlin/javabot/operations/urlcontent/URLFromMessageParserTest.kt
+++ b/src/test/kotlin/javabot/operations/urlcontent/URLFromMessageParserTest.kt
@@ -32,19 +32,19 @@ class URLFromMessageParserTest {
),
arrayOf(
"Don't fix mismatched punctuation {http://sample.com)",
- expectedUrls("http://sample.com)")
+ expectedUrls("http://sample.com")
),
arrayOf(
"Don't fix mismatched punctuation (http://sample.com]",
- expectedUrls("http://sample.com]")
+ expectedUrls("http://sample.com")
),
arrayOf(
"Don't fix mismatched punctuation [http://sample.com}",
- expectedUrls("http://sample.com}")
+ expectedUrls("http://sample.com")
),
arrayOf(
"Message has parens (like this) before http://sample.com)",
- expectedUrls("http://sample.com)")
+ expectedUrls("http://sample.com")
)
)
}