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),
qweatherKey = "114514",
githubKey = "1919810",
imageType = ImageType.PNG
imageType = ImageType.PNG,
openAIAPIHost = "https://api.moonshot.cn",
openAIAPIKey = "114514"
)
val ADMINS = listOf(
@@ -10,6 +10,7 @@ package cn.rtast.fancybot
import cn.rtast.fancybot.commands.*
import cn.rtast.fancybot.commands.CompilerCommand
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.MusicCommand
import cn.rtast.fancybot.commands.lookup.NslookupCommand
@@ -147,7 +148,7 @@ val commands = listOf(
RUACommand(), NslookupCommand(),
NiuziSignCommand(), MyNiuziCommand(),
JiJianCommand(), LikeMeCommand(),
CompilerCommand()
CompilerCommand(), GPTCommand()
)
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 githubKey: String,
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
import cn.rtast.fancybot.util.str.fromJson
import okhttp3.Call
import okhttp3.Callback
import okhttp3.FormBody
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import java.io.IOException
object Http {
@@ -56,24 +52,6 @@ object Http {
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
fun get(
url: String,
@@ -20,4 +20,6 @@ class ConfigManager : JsonFileHandler<Config>("config.json") {
val qweatherKey get() = this.read<Config>().qweatherKey
val githubKey get() = this.read<Config>().githubKey
val imageType get() = this.read<Config>().imageType
val openAIAPIHost get() = this.read<Config>().openAIAPIHost
val openAIAPIKey get() = this.read<Config>().openAIAPIKey
}