perf:优化识图,缓解重复回复,使用原始插件manifest_id避免不一致情况
This commit is contained in:
@@ -18,7 +18,7 @@ const PLUGIN_DETAILS_FILE = 'plugin_details.json'
|
||||
* 插件列表 API 响应类型(只包含我们需要的字段)
|
||||
*/
|
||||
interface PluginApiResponse {
|
||||
id: string
|
||||
id?: string
|
||||
manifest: {
|
||||
manifest_version: number
|
||||
id?: string
|
||||
@@ -110,7 +110,7 @@ export async function fetchPluginList(): Promise<ApiResponse<PluginInfo[]>> {
|
||||
console.warn('跳过无效插件数据:', item)
|
||||
return false
|
||||
}
|
||||
const pluginId = item.manifest.id || item.id
|
||||
const pluginId = item.manifest.id
|
||||
if (!pluginId) {
|
||||
console.warn('跳过缺少 ID 的插件:', item)
|
||||
return false
|
||||
@@ -122,7 +122,7 @@ export async function fetchPluginList(): Promise<ApiResponse<PluginInfo[]>> {
|
||||
return true
|
||||
})
|
||||
.map((item) => ({
|
||||
id: item.manifest.id || item.id,
|
||||
id: item.manifest.id!,
|
||||
manifest: normalizePluginManifest(item.manifest),
|
||||
downloads: 0,
|
||||
rating: 0,
|
||||
|
||||
@@ -1 +1 @@
|
||||
请用中文描述这张图片的内容。如果有文字,请把文字描述概括出来,请留意其主题、直观感受,输出为一段平文本,最多30字,请注意不要分点,就输出一段文本
|
||||
请用中文详细描述这张图片的内容。如果有文字,请把文字描述概括出来,请留意其主题、直观感受,输出为一段平文本,最多100字,请注意不要分点,就输出一段文本
|
||||
|
||||
@@ -61,3 +61,76 @@ def test_resolve_installed_plugin_path_accepts_manifest_id_case_mismatch(client:
|
||||
|
||||
assert plugin_path is not None
|
||||
assert plugin_path.name == "demo_plugin"
|
||||
|
||||
|
||||
def test_install_plugin_preserves_manifest_declared_id(client: TestClient, monkeypatch):
|
||||
class FakeGitMirrorService:
|
||||
async def clone_repository(self, **kwargs):
|
||||
target_path = kwargs["target_path"]
|
||||
target_path.mkdir(parents=True, exist_ok=True)
|
||||
(target_path / "_manifest.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"id": "author.declared",
|
||||
"name": "Declared Plugin",
|
||||
"version": "1.0.0",
|
||||
"author": {"name": "author"},
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
return {"success": True}
|
||||
|
||||
monkeypatch.setattr(management_module, "get_git_mirror_service", lambda: FakeGitMirrorService())
|
||||
|
||||
response = client.post(
|
||||
"/api/webui/plugins/install",
|
||||
json={
|
||||
"plugin_id": "market.plugin",
|
||||
"repository_url": "https://github.com/author/declared",
|
||||
"branch": "main",
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
plugin_path = support_module.resolve_installed_plugin_path("author.declared")
|
||||
assert plugin_path is not None
|
||||
manifest = json.loads((plugin_path / "_manifest.json").read_text(encoding="utf-8"))
|
||||
assert manifest["id"] == "author.declared"
|
||||
|
||||
|
||||
def test_install_plugin_backfills_missing_manifest_id(client: TestClient, monkeypatch):
|
||||
class FakeGitMirrorService:
|
||||
async def clone_repository(self, **kwargs):
|
||||
target_path = kwargs["target_path"]
|
||||
target_path.mkdir(parents=True, exist_ok=True)
|
||||
(target_path / "_manifest.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Legacy Plugin",
|
||||
"version": "1.0.0",
|
||||
"author": {"name": "author"},
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
return {"success": True}
|
||||
|
||||
monkeypatch.setattr(management_module, "get_git_mirror_service", lambda: FakeGitMirrorService())
|
||||
|
||||
response = client.post(
|
||||
"/api/webui/plugins/install",
|
||||
json={
|
||||
"plugin_id": "market.legacy",
|
||||
"repository_url": "https://github.com/author/legacy",
|
||||
"branch": "main",
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
plugin_path = support_module.resolve_installed_plugin_path("market.legacy")
|
||||
assert plugin_path is not None
|
||||
manifest = json.loads((plugin_path / "_manifest.json").read_text(encoding="utf-8"))
|
||||
assert manifest["id"] == "market.legacy"
|
||||
|
||||
@@ -263,6 +263,7 @@ async def handle_tool(
|
||||
|
||||
target_user_info = target_message.message_info.user_info
|
||||
target_user_name = target_user_info.user_cardname or target_user_info.user_nickname or target_user_info.user_id
|
||||
bot_name = config_module.global_config.bot.nickname.strip() or "MaiSaka"
|
||||
|
||||
if tool_ctx.runtime.chat_stream.platform == CLI_PLATFORM_NAME:
|
||||
tool_ctx.append_guided_reply_to_chat_history(combined_reply_text)
|
||||
@@ -291,7 +292,7 @@ async def handle_tool(
|
||||
)
|
||||
return tool_ctx.build_success_result(
|
||||
invocation.tool_name,
|
||||
f'已生成并发送回复"{combined_reply_text}"\n发送对象:{target_user_name}',
|
||||
f'"{bot_name}"已生成并向"{target_user_name}"发送了回复"{combined_reply_text}"',
|
||||
structured_content={
|
||||
"msg_id": target_message_id,
|
||||
"set_quote": set_quote,
|
||||
|
||||
@@ -187,6 +187,7 @@ async def install_plugin(request: InstallPluginRequest, maibot_session: Optional
|
||||
for field in ["manifest_version", "name", "version", "author"]:
|
||||
if field not in manifest:
|
||||
raise ValueError(f"缺少必需字段: {field}")
|
||||
if not str(manifest.get("id", "")).strip():
|
||||
manifest["id"] = plugin_id
|
||||
with open(manifest_path, "w", encoding="utf-8") as file_obj:
|
||||
json.dump(manifest, file_obj, ensure_ascii=False, indent=2)
|
||||
|
||||
8
uv.lock
generated
8
uv.lock
generated
@@ -1511,7 +1511,7 @@ requires-dist = [
|
||||
{ name = "httpx", extras = ["socks"] },
|
||||
{ name = "jieba", specifier = ">=0.42.1" },
|
||||
{ name = "json-repair", specifier = ">=0.47.6" },
|
||||
{ name = "maibot-dashboard", specifier = ">=1.0.9" },
|
||||
{ name = "maibot-dashboard", specifier = ">=1.0.10" },
|
||||
{ name = "maibot-plugin-sdk", specifier = ">=2.4.0" },
|
||||
{ name = "maim-message", specifier = ">=0.6.2" },
|
||||
{ name = "matplotlib", specifier = ">=3.10.5" },
|
||||
@@ -1549,11 +1549,11 @@ dev = [
|
||||
|
||||
[[package]]
|
||||
name = "maibot-dashboard"
|
||||
version = "1.0.9"
|
||||
version = "1.0.10"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ac/5b/e90896cbdddc89ec5586873de07a3d70c0107e4dc76db8666a0c0fde6ae8/maibot_dashboard-1.0.9.tar.gz", hash = "sha256:0e5c00be021419686105238cded501024f0383a3815bd85f9a1e747f3f04d0cd", size = 2496957, upload-time = "2026-05-07T18:37:51.291Z" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9a/b7/3301c49d96bbfde0c61405b7e5afe1c75d625420fdd83d1f4814b9f09eec/maibot_dashboard-1.0.10.tar.gz", hash = "sha256:38be2833f6a17c1f347262eccf5967813327948ad29900b955bb91631844a27c", size = 2496436, upload-time = "2026-05-08T13:15:48.204Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/27/ab227a84e55356039004a375e78031e5e8aaf4192e11908a568498816d5e/maibot_dashboard-1.0.9-py3-none-any.whl", hash = "sha256:197b26c5c3d0e6ba1238b91d12c88e57db71c65303cc602fcccdca84ce4db582", size = 2563281, upload-time = "2026-05-07T18:37:49.648Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/ab/1e/c86f8a98c9de4eef831f855994744ec0512ccfb9322aaef385ca0919f950/maibot_dashboard-1.0.10-py3-none-any.whl", hash = "sha256:749390d6e4c340598e048d72f4c733558163153c0ad4443ff81b5a1c28799629", size = 2563613, upload-time = "2026-05-08T13:15:46.562Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in New Issue
Block a user