feat: add gpt command

This commit is contained in:
2024-09-15 13:27:14 +08:00
parent c23a8211f2
commit cd7cc341ab
11 files changed
+154 -25

No files matched your search

+3 -1
View File
@@ -29,7 +29,9 @@ val DEFAULT_CONFIG = Config(
listeningGroups = listOf(114514, 1919810), listeningGroups = listOf(114514, 1919810),
qweatherKey = "114514", qweatherKey = "114514",
githubKey = "1919810", githubKey = "1919810",
imageType = ImageType.PNG imageType = ImageType.PNG,
openAIAPIHost = "https://api.moonshot.cn",
openAIAPIKey = "114514"
) )
val ADMINS = listOf( val ADMINS = listOf(
@@ -10,6 +10,7 @@ package cn.rtast.fancybot
import cn.rtast.fancybot.commands.* import cn.rtast.fancybot.commands.*
import cn.rtast.fancybot.commands.CompilerCommand import cn.rtast.fancybot.commands.CompilerCommand
import cn.rtast.fancybot.commands.lookup.CigaretteCommand import cn.rtast.fancybot.commands.lookup.CigaretteCommand
import cn.rtast.fancybot.commands.lookup.GPTCommand
import cn.rtast.fancybot.commands.lookup.MCPingCommand import cn.rtast.fancybot.commands.lookup.MCPingCommand
import cn.rtast.fancybot.commands.lookup.MusicCommand import cn.rtast.fancybot.commands.lookup.MusicCommand
import cn.rtast.fancybot.commands.lookup.NslookupCommand import cn.rtast.fancybot.commands.lookup.NslookupCommand
@@ -147,7 +148,7 @@ val commands = listOf(
RUACommand(), NslookupCommand(), RUACommand(), NslookupCommand(),
NiuziSignCommand(), MyNiuziCommand(), NiuziSignCommand(), MyNiuziCommand(),
JiJianCommand(), LikeMeCommand(), JiJianCommand(), LikeMeCommand(),
CompilerCommand() CompilerCommand(), GPTCommand()
) )
suspend fun main() { suspend fun main() {
@@ -0,0 +1,69 @@
/*
* Copyright © 2024 RTAkland
* Author: RTAkland
* Date: 2024/9/15
*/
package cn.rtast.fancybot.commands.lookup
import cn.rtast.fancybot.configManager
import cn.rtast.fancybot.entity.gpt.ChatCompletionsPayload
import cn.rtast.fancybot.entity.gpt.ChatCompletionsResponse
import cn.rtast.fancybot.entity.gpt.ModelList
import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.str.toJson
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OBMessage
class GPTCommand : BaseCommand() {
override val commandNames = listOf("/gpt")
override suspend fun executeGroup(listener: OBMessage, message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addAt(message.sender.userId)
.addText("发送`/gpt [模型] <问题>`即可询问AI哦~")
.addNewLine()
.addText("不指定模型默认为`moonshot-v1-8k`")
.addNewLine()
.addText("发送`/gpt list`可以获取可用的模型列表~")
.build()
listener.sendGroupMessage(message.groupId, msg)
return
}
if (args.first() == "列表" || args.first() == "list") {
val models = Http.get<ModelList>(
"${configManager.openAIAPIHost}/v1/models",
headers = mapOf("Authorization" to "Bearer ${configManager.openAIAPIKey}")
)
val modelsString = models.data.joinToString(", ") { it.id }
val msg = MessageChain.Builder()
.addReply(message.messageId)
.addText("可用的模型列表如下: ")
.addNewLine()
.addText(modelsString)
.build()
listener.sendGroupMessage(message.groupId, msg)
return
}
val model = if (args.size == 1) "moonshot-v1-8k" else args.first()
val content = if (args.size == 1) args.joinToString(" ") else args.drop(1).joinToString(" ")
val messages = ChatCompletionsPayload(model, listOf(ChatCompletionsPayload.Message(content)))
val response = Http.post<ChatCompletionsResponse>(
"${configManager.openAIAPIHost}/v1/chat/completions",
messages.toJson(),
mapOf("Authorization" to "Bearer ${configManager.openAIAPIKey}")
)
val msg = MessageChain.Builder()
.addReply(message.messageId)
.addNewLine()
.addText(response.choices.first().message.content)
.build()
listener.sendGroupMessage(message.groupId, msg)
}
}
@@ -20,4 +20,6 @@ data class Config(
val qweatherKey: String, val qweatherKey: String,
val githubKey: String, val githubKey: String,
val imageType: ImageType, val imageType: ImageType,
val openAIAPIHost: String,
val openAIAPIKey: String
) )
@@ -0,0 +1,12 @@
/*
* Copyright © 2024 RTAkland
* Author: RTAkland
* Date: 2024/9/15
*/
package cn.rtast.fancybot.entity.enums
enum class GPTUserRole {
user, system, assistant
}
@@ -0,0 +1,21 @@
/*
* Copyright © 2024 RTAkland
* Author: RTAkland
* Date: 2024/9/15
*/
package cn.rtast.fancybot.entity.gpt
import cn.rtast.fancybot.entity.enums.GPTUserRole
data class ChatCompletionsPayload(
val model: String,
val messages: List<Message>
) {
data class Message(
val content: String,
val role: GPTUserRole = GPTUserRole.user,
val temperature: Float = 0.3f
)
}
@@ -0,0 +1,23 @@
/*
* Copyright © 2024 RTAkland
* Author: RTAkland
* Date: 2024/9/15
*/
package cn.rtast.fancybot.entity.gpt
import cn.rtast.fancybot.entity.enums.GPTUserRole
data class ChatCompletionsResponse(
val choices: List<Choice>
) {
data class Choice(
val message: Message
)
data class Message(
val role: GPTUserRole,
val content: String,
)
}
@@ -0,0 +1,16 @@
/*
* Copyright © 2024 RTAkland
* Author: RTAkland
* Date: 2024/9/15
*/
package cn.rtast.fancybot.entity.gpt
data class ModelList(
val data: List<Data>
) {
data class Data(
val id: String,
)
}
@@ -8,15 +8,11 @@
package cn.rtast.fancybot.util package cn.rtast.fancybot.util
import cn.rtast.fancybot.util.str.fromJson import cn.rtast.fancybot.util.str.fromJson
import okhttp3.Call
import okhttp3.Callback
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import java.io.IOException
object Http { object Http {
@@ -56,24 +52,6 @@ object Http {
return okHttpClient.newCall(request).execute().body.string() return okHttpClient.newCall(request).execute().body.string()
} }
fun executeRequestAsync(
requestBuilder: Request.Builder,
headers: Map<String, String>?,
callback: (String) -> Unit
) {
this.addHeaders(requestBuilder, headers)
okHttpClient.newCall(requestBuilder.build()).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val responseBody = response.body.string()
callback(responseBody)
}
override fun onFailure(call: Call, e: IOException) {
callback(e.toString())
}
})
}
@JvmOverloads @JvmOverloads
fun get( fun get(
url: String, url: String,
@@ -20,4 +20,6 @@ class ConfigManager : JsonFileHandler<Config>("config.json") {
val qweatherKey get() = this.read<Config>().qweatherKey val qweatherKey get() = this.read<Config>().qweatherKey
val githubKey get() = this.read<Config>().githubKey val githubKey get() = this.read<Config>().githubKey
val imageType get() = this.read<Config>().imageType val imageType get() = this.read<Config>().imageType
val openAIAPIHost get() = this.read<Config>().openAIAPIHost
val openAIAPIKey get() = this.read<Config>().openAIAPIKey
} }
+4 -1
View File
@@ -9,5 +9,8 @@
1919810 1919810
], ],
"qweatherKey": "114514", "qweatherKey": "114514",
"githubKey": "1919810" "githubKey": "1919810",
"imageType": "PNG",
"openAIAPIHost": "https://api.moonshot.cn",
"openAIAPIKey": "114514"
} }