mirror of
https://github.com/jie65535/JChatGPT.git
synced 2026-06-23 00:49:31 +08:00
Optimize search results
Add Weather Service Agent Add Crazy Thursday Agent
This commit is contained in:
@@ -1,14 +1,28 @@
|
||||
package top.jie65535.mirai.tools
|
||||
|
||||
import com.aallam.openai.api.chat.Tool
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.okhttp.*
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
|
||||
abstract class BaseAgent(
|
||||
val tool: Tool
|
||||
) {
|
||||
/**
|
||||
* 是否启用该工具
|
||||
*/
|
||||
open val isEnabled: Boolean = true
|
||||
|
||||
abstract suspend fun execute(args: JsonObject): String
|
||||
/**
|
||||
* 加载时消息 可用于提示用户正在执行
|
||||
*/
|
||||
open val loadingMessage: String = ""
|
||||
|
||||
protected val httpClient by lazy {
|
||||
HttpClient(OkHttp)
|
||||
}
|
||||
|
||||
abstract suspend fun execute(args: JsonObject?): String
|
||||
|
||||
override fun toString(): String {
|
||||
return "${tool.function.name}: ${tool.function.description}"
|
||||
|
||||
20
src/main/kotlin/tools/CrazyKfc.kt
Normal file
20
src/main/kotlin/tools/CrazyKfc.kt
Normal file
@@ -0,0 +1,20 @@
|
||||
package top.jie65535.mirai.tools
|
||||
|
||||
import com.aallam.openai.api.chat.Tool
|
||||
import com.aallam.openai.api.core.Parameters
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.*
|
||||
import kotlinx.serialization.json.*
|
||||
|
||||
class CrazyKfc : BaseAgent(
|
||||
tool = Tool.function(
|
||||
name = "crazyThursday",
|
||||
description = "获取一条KFC疯狂星期四文案",
|
||||
parameters = Parameters.Empty
|
||||
)
|
||||
) {
|
||||
override suspend fun execute(args: JsonObject?): String {
|
||||
val response = httpClient.get("https://api.52vmy.cn/api/wl/yan/kfc")
|
||||
return response.bodyAsText()
|
||||
}
|
||||
}
|
||||
56
src/main/kotlin/tools/WeatherService.kt
Normal file
56
src/main/kotlin/tools/WeatherService.kt
Normal file
@@ -0,0 +1,56 @@
|
||||
package top.jie65535.mirai.tools
|
||||
|
||||
import com.aallam.openai.api.chat.Tool
|
||||
import com.aallam.openai.api.core.Parameters
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.*
|
||||
import kotlinx.serialization.json.*
|
||||
|
||||
class WeatherService : BaseAgent(
|
||||
tool = Tool.function(
|
||||
name = "queryWeather",
|
||||
description = "可用于查询某城市地区天气.",
|
||||
parameters = Parameters.buildJsonObject {
|
||||
put("type", "object")
|
||||
putJsonObject("properties") {
|
||||
putJsonObject("city") {
|
||||
put("type", "string")
|
||||
put("description", "城市地区,如\"深圳市\"")
|
||||
}
|
||||
putJsonObject("time_range") {
|
||||
put("type", "string")
|
||||
putJsonArray("enum") {
|
||||
add("day")
|
||||
add("three")
|
||||
add("many")
|
||||
}
|
||||
put("description", "时间范围,仅当天天气可获得最详细信息,三天和更多只能获得简单信息。")
|
||||
}
|
||||
}
|
||||
putJsonArray("required") {
|
||||
add("city")
|
||||
}
|
||||
}
|
||||
)
|
||||
) {
|
||||
override val loadingMessage: String
|
||||
get() = "查询天气中..."
|
||||
|
||||
override suspend fun execute(args: JsonObject?): String {
|
||||
requireNotNull(args)
|
||||
val city = args.getValue("city").jsonPrimitive.content
|
||||
val timeRange = args["time_range"]?.jsonPrimitive?.contentOrNull
|
||||
val response = httpClient.get(
|
||||
buildString {
|
||||
append(when (timeRange) {
|
||||
"many" -> "https://api.52vmy.cn/api/query/tian/many"
|
||||
"three" -> "https://api.52vmy.cn/api/query/tian/three"
|
||||
else -> "https://api.52vmy.cn/api/query/tian"
|
||||
})
|
||||
append("?city=")
|
||||
append(city)
|
||||
}
|
||||
)
|
||||
return response.bodyAsText()
|
||||
}
|
||||
}
|
||||
@@ -2,25 +2,51 @@ package top.jie65535.mirai.tools
|
||||
|
||||
import com.aallam.openai.api.chat.Tool
|
||||
import com.aallam.openai.api.core.Parameters
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.okhttp.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.*
|
||||
import io.ktor.http.*
|
||||
import kotlinx.serialization.json.*
|
||||
import top.jie65535.mirai.PluginConfig
|
||||
import org.apache.commons.text.StringEscapeUtils
|
||||
import top.jie65535.mirai.PluginConfig
|
||||
|
||||
class WebSearch : BaseAgent(
|
||||
tool = Tool.function(
|
||||
name = "search",
|
||||
description = "通过互联网搜索一切",
|
||||
description = "Provides meta-search functionality through SearXNG," +
|
||||
" aggregating results from multiple search engines.",
|
||||
parameters = Parameters.buildJsonObject {
|
||||
put("type", "object")
|
||||
putJsonObject("properties") {
|
||||
putJsonObject("q") {
|
||||
put("type", "string")
|
||||
put("description", "The search query")
|
||||
put("description", "查询内容关键字")
|
||||
}
|
||||
putJsonObject("categories") {
|
||||
put("type", "array")
|
||||
putJsonObject("items") {
|
||||
put("type", "string")
|
||||
putJsonArray("enum") {
|
||||
add("general")
|
||||
add("images")
|
||||
add("videos")
|
||||
add("news")
|
||||
add("music")
|
||||
add("it")
|
||||
add("science")
|
||||
add("files")
|
||||
add("social_media")
|
||||
}
|
||||
}
|
||||
put("description", "可选择多项查询分类,通常情况下不传或用general即可。")
|
||||
}
|
||||
putJsonObject("time_range") {
|
||||
put("type", "string")
|
||||
putJsonArray("enum") {
|
||||
add("day")
|
||||
add("month")
|
||||
add("year")
|
||||
}
|
||||
put("description", "可选择获取最新消息,例如day表示只查询最近一天相关信息,以此类推。")
|
||||
}
|
||||
}
|
||||
putJsonArray("required") {
|
||||
@@ -35,16 +61,66 @@ class WebSearch : BaseAgent(
|
||||
override val isEnabled: Boolean
|
||||
get() = PluginConfig.searXngUrl.isNotEmpty()
|
||||
|
||||
private val httpClient by lazy {
|
||||
HttpClient(OkHttp)
|
||||
}
|
||||
override val loadingMessage: String
|
||||
get() = "联网搜索中..."
|
||||
|
||||
override suspend fun execute(args: JsonObject): String {
|
||||
override suspend fun execute(args: JsonObject?): String {
|
||||
requireNotNull(args)
|
||||
val q = args.getValue("q").jsonPrimitive.content
|
||||
val categories = args["categories"]?.jsonArray
|
||||
val timeRange = args["time_range"]?.jsonPrimitive?.contentOrNull
|
||||
val response = httpClient.get(
|
||||
"${PluginConfig.searXngUrl}?q=${q.encodeURLParameter(true)}&format=json"
|
||||
buildString {
|
||||
append(PluginConfig.searXngUrl)
|
||||
append("?q=")
|
||||
append(q.encodeURLParameter())
|
||||
append("&format=json")
|
||||
if (categories != null) {
|
||||
append("&")
|
||||
append(categories.joinToString { it.jsonPrimitive.content })
|
||||
}
|
||||
if (timeRange != null) {
|
||||
append("&")
|
||||
append(timeRange)
|
||||
}
|
||||
}
|
||||
)
|
||||
val body = response.bodyAsText()
|
||||
return StringEscapeUtils.unescapeJava(body)
|
||||
val unescapedBody = StringEscapeUtils.unescapeJava(body)
|
||||
val responseJsonElement = Json.parseToJsonElement(unescapedBody)
|
||||
return buildJsonObject {
|
||||
val root = responseJsonElement.jsonObject
|
||||
// 查询内容原样转发
|
||||
root["query"]?.let { put("query", it) }
|
||||
|
||||
// 过滤搜索结果
|
||||
val results = root["results"]?.jsonArray
|
||||
if (results != null) {
|
||||
val filteredResults = results
|
||||
.filter {
|
||||
// 去掉所有内容为空的结果
|
||||
!it.jsonObject.getValue("content").jsonPrimitive.contentOrNull.isNullOrEmpty()
|
||||
}.sortedByDescending {
|
||||
it.jsonObject.getValue("score").jsonPrimitive.double
|
||||
}.take(5) // 只取得分最高的前5条结果
|
||||
.map {
|
||||
// 移除掉我不想要的字段
|
||||
val item = it.jsonObject.toMutableMap()
|
||||
item.remove("engine")
|
||||
item.remove("parsed_url")
|
||||
item.remove("template")
|
||||
item.remove("engines")
|
||||
item.remove("positions")
|
||||
item.remove("metadata")
|
||||
item.remove("thumbnail")
|
||||
JsonObject(item)
|
||||
}
|
||||
put("results", JsonArray(filteredResults))
|
||||
}
|
||||
|
||||
// 答案和信息盒子原样转发
|
||||
root["answers"]?.let { put("answers", it) }
|
||||
root["infoboxes"]?.let { put("infoboxes", it) }
|
||||
}.toString()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user