mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-10-29 03:18:14 +08:00
refactor(agent): unify tools behind API gateway and provider skills
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
"""插件持久化数据查询与写用例。"""
|
||||
"""插件持久化数据查询、投影与写用例。"""
|
||||
|
||||
from typing import Protocol
|
||||
import json
|
||||
from collections.abc import Callable
|
||||
from typing import Any, Optional, Protocol
|
||||
|
||||
from app.schemas.common import JsonData
|
||||
|
||||
@@ -57,3 +59,89 @@ class DeletePluginDataCommand:
|
||||
except Exception:
|
||||
self._unit_of_work.rollback()
|
||||
raise
|
||||
|
||||
|
||||
DEFAULT_PLUGIN_DATA_PREVIEW_CHARS = 12_000
|
||||
MAX_PLUGIN_DATA_PREVIEW_CHARS = 50_000
|
||||
PLUGIN_DATA_KEY_PREVIEW_LIMIT = 50
|
||||
PLUGIN_DATA_TRUNCATION_SUFFIX = "\n...(插件数据内容过长,已截断)"
|
||||
|
||||
|
||||
def clamp_preview_chars(max_chars: Optional[int]) -> int:
|
||||
"""约束插件数据预览长度,避免结果无限膨胀。"""
|
||||
if max_chars is None:
|
||||
return DEFAULT_PLUGIN_DATA_PREVIEW_CHARS
|
||||
return max(512, min(int(max_chars), MAX_PLUGIN_DATA_PREVIEW_CHARS))
|
||||
|
||||
|
||||
def build_preview_payload(value: Any, max_chars: Optional[int]) -> tuple[bool, int, int, str]:
|
||||
"""稳定序列化插件数据并生成有界预览。"""
|
||||
serialized = json.dumps(value, ensure_ascii=False, indent=2, default=str)
|
||||
preview_limit = clamp_preview_chars(max_chars)
|
||||
if len(serialized) <= preview_limit:
|
||||
return False, len(serialized), len(serialized), serialized
|
||||
preview = serialized[:preview_limit] + PLUGIN_DATA_TRUNCATION_SUFFIX
|
||||
return True, len(serialized), len(preview), preview
|
||||
|
||||
|
||||
class PluginDataQueryService:
|
||||
"""查询已安装插件数据并对大结果执行稳定裁剪。"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
repository: PluginDataQueryRepository,
|
||||
snapshot: Callable[[str], Optional[dict[str, Any]]],
|
||||
) -> None:
|
||||
"""注入插件数据仓储和安装态快照查询函数。"""
|
||||
self._repository = repository
|
||||
self._snapshot = snapshot
|
||||
|
||||
async def query(
|
||||
self,
|
||||
plugin_id: str,
|
||||
*,
|
||||
key: Optional[str] = None,
|
||||
max_chars: Optional[int] = None,
|
||||
) -> dict[str, Any]:
|
||||
"""读取单键或全部数据,并返回上下文安全的投影。"""
|
||||
plugin = self._snapshot(plugin_id)
|
||||
if plugin is None:
|
||||
raise ValueError(f"插件 {plugin_id} 不存在")
|
||||
if key:
|
||||
value = await self._repository.get(plugin_id, key)
|
||||
if value is None:
|
||||
return {
|
||||
**plugin,
|
||||
"key": key,
|
||||
"found": False,
|
||||
"message": f"插件 {plugin_id} 没有数据项 {key}",
|
||||
}
|
||||
truncated, total_chars, returned_chars, preview = build_preview_payload(value, max_chars)
|
||||
result = {
|
||||
**plugin,
|
||||
"key": key,
|
||||
"found": True,
|
||||
"truncated": truncated,
|
||||
"total_chars": total_chars,
|
||||
"returned_chars": returned_chars,
|
||||
}
|
||||
result["value_preview" if truncated else "value"] = preview if truncated else value
|
||||
return result
|
||||
data = await self._repository.list(plugin_id)
|
||||
keys = list(data)
|
||||
result = {
|
||||
**plugin,
|
||||
"count": len(data),
|
||||
"keys": keys[:PLUGIN_DATA_KEY_PREVIEW_LIMIT],
|
||||
"keys_truncated": len(keys) > PLUGIN_DATA_KEY_PREVIEW_LIMIT,
|
||||
}
|
||||
truncated, total_chars, returned_chars, preview = build_preview_payload(data, max_chars)
|
||||
result.update(
|
||||
{
|
||||
"truncated": truncated,
|
||||
"total_chars": total_chars,
|
||||
"returned_chars": returned_chars,
|
||||
"data_preview" if truncated else "data": (preview if truncated else data),
|
||||
}
|
||||
)
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user