feat: add gpt command
This commit is contained in:
11 files changed
+154
-25
No files matched your search
@@ -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
|
||||
}
|
||||
@@ -9,5 +9,8 @@
|
||||
1919810
|
||||
],
|
||||
"qweatherKey": "114514",
|
||||
"githubKey": "1919810"
|
||||
"githubKey": "1919810",
|
||||
"imageType": "PNG",
|
||||
"openAIAPIHost": "https://api.moonshot.cn",
|
||||
"openAIAPIKey": "114514"
|
||||
}
|
||||
Reference in New Issue
Block a user