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),
|
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
|
||||||
}
|
}
|
||||||
@@ -9,5 +9,8 @@
|
|||||||
1919810
|
1919810
|
||||||
],
|
],
|
||||||
"qweatherKey": "114514",
|
"qweatherKey": "114514",
|
||||||
"githubKey": "1919810"
|
"githubKey": "1919810",
|
||||||
|
"imageType": "PNG",
|
||||||
|
"openAIAPIHost": "https://api.moonshot.cn",
|
||||||
|
"openAIAPIKey": "114514"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user