refactor: formalize deprecation markings with @deprecated decorators (#9468)

* refactor: formalize deprecation markings with @deprecated decorators

Add @deprecated decorators (from the `deprecated` package, following
the existing BaseDatabase precedent) to callables that were previously
marked as deprecated only in comments or docstrings:

- SharedPreferences sync methods (get/range_get/put/remove/clear),
  deprecated since the v4.0.0 DB refactor (#2482)
- SQLiteDatabase deprecated stats methods, matching the decorated
  abstract declarations in BaseDatabase
- po.Platform / po.Stats legacy dataclasses
- ProviderManager.selected_default_persona property
- FuncToolManager.mcp_server_runtime property
- ProviderResult.to_openai_tool_calls
- ConversationManager.update_conversation_title /
  update_conversation_persona_id
- Nodes.toDict
- AstrMessageEvent._pre_send / _post_send (deprecated since v3.5.18)
- misskey resolve_visibility_from_raw_message compat alias
- Context.register_llm_tool / unregister_llm_tool /
  register_commands / register_task

No behavior change beyond emitting DeprecationWarning at call sites.

* refactor: point Context deprecations to their replacement APIs

Address review feedback:

- Context.unregister_llm_tool: point to deactivate_llm_tool() as the
  migration path instead of a generic removal notice
- Context.register_task: point to starting background tasks in the
  plugin's initialize() lifecycle method

Note: the ProviderResult.to_openai_tool_calls reason was checked and
left unchanged -- to_openai_to_calls_model is the actual method name
(entities.py:424, used by tool_loop_agent_runner.py:953), not a typo.
This commit is contained in:
Ruochen Pan
2026-07-30 22:18:13 +08:00
committed by GitHub
parent e80e01c776
commit d8d8a7ad51
11 changed files with 51 additions and 0 deletions
+6
View File
@@ -7,6 +7,8 @@
import json
from collections.abc import Awaitable, Callable
from deprecated import deprecated
from astrbot.core import sp
from astrbot.core.agent.message import AssistantMessageSegment, UserMessageSegment
from astrbot.core.db import BaseDatabase
@@ -304,6 +306,7 @@ class ConversationManager:
token_usage=token_usage,
)
@deprecated(reason="Use update_conversation() with the title parameter instead.")
async def update_conversation_title(
self,
unified_msg_origin: str,
@@ -326,6 +329,9 @@ class ConversationManager:
title=title,
)
@deprecated(
reason="Use update_conversation() with the persona_id parameter instead."
)
async def update_conversation_persona_id(
self,
unified_msg_origin: str,
+3
View File
@@ -3,6 +3,7 @@ from dataclasses import dataclass, field
from datetime import datetime, timezone
from typing import TypedDict
from deprecated import deprecated
from sqlalchemy import Index, desc
from sqlmodel import JSON, Field, SQLModel, Text, UniqueConstraint
@@ -605,6 +606,7 @@ class Personality(TypedDict):
# ====
@deprecated(version="4.0.0", reason="Use PlatformStat instead.")
@dataclass
class Platform:
"""平台使用统计数据"""
@@ -614,6 +616,7 @@ class Platform:
timestamp: int
@deprecated(version="4.0.0", reason="Use get_platform_stats() instead.")
@dataclass
class Stats:
platform: list[Platform] = field(default_factory=list)
+4
View File
@@ -5,6 +5,7 @@ import typing as T
from collections.abc import Awaitable, Callable
from datetime import datetime, timedelta, timezone
from deprecated import deprecated
from sqlalchemy import CursorResult, Row, not_
from sqlalchemy.dialects.sqlite import dialect as sqlite_dialect
from sqlalchemy.ext.asyncio import AsyncSession
@@ -1646,6 +1647,7 @@ class SQLiteDatabase(BaseDatabase):
# Deprecated Methods
# ====
@deprecated(version="4.0.0", reason="Use get_platform_stats instead")
def get_base_stats(self, offset_sec=86400):
"""Get base statistics within the specified offset in seconds."""
@@ -1680,6 +1682,7 @@ class SQLiteDatabase(BaseDatabase):
t.join()
return result
@deprecated(version="4.0.0", reason="Use get_platform_stats instead")
def get_total_message_count(self):
"""Get the total message count from platform statistics."""
@@ -1703,6 +1706,7 @@ class SQLiteDatabase(BaseDatabase):
t.join()
return result
@deprecated(version="4.0.0", reason="Use get_platform_stats instead")
def get_grouped_base_stats(self, offset_sec=86400):
# group by platform_id
async def _inner():
+3
View File
@@ -30,6 +30,8 @@ import uuid
from enum import Enum
from pathlib import Path, PurePosixPath
from deprecated import deprecated
if sys.version_info >= (3, 14):
from pydantic import BaseModel
else:
@@ -711,6 +713,7 @@ class Nodes(BaseMessageComponent):
def __init__(self, nodes: list[Node], **_) -> None:
super().__init__(nodes=nodes, **_)
@deprecated(reason="Use to_dict instead.")
def toDict(self):
"""Deprecated. Use to_dict instead"""
ret = {
@@ -8,6 +8,8 @@ from collections.abc import AsyncGenerator
from time import time
from typing import Any
from deprecated import deprecated
from astrbot import logger
from astrbot.core.agent.tool import ToolSet
from astrbot.core.db.po import Conversation
@@ -301,9 +303,11 @@ class AstrMessageEvent(abc.ABC):
默认实现为空,由具体平台按需重写。
"""
@deprecated(version="3.5.18", reason="No longer invoked by the message scheduler.")
async def _pre_send(self) -> None:
"""调度器会在执行 send() 前调用该方法 deprecated in v3.5.18"""
@deprecated(version="3.5.18", reason="No longer invoked by the message scheduler.")
async def _post_send(self) -> None:
"""调度器会在执行 send() 后调用该方法 deprecated in v3.5.18"""
@@ -2,6 +2,8 @@
from typing import Any
from deprecated import deprecated
import astrbot.api.message_components as Comp
from astrbot.api.platform import AstrBotMessage, MessageMember, MessageType
from astrbot.core.utils.media_utils import MediaResolver
@@ -174,6 +176,7 @@ def resolve_message_visibility(
# 保留旧函数名作为向后兼容的别名
@deprecated(reason="Use resolve_message_visibility instead.")
def resolve_visibility_from_raw_message(
raw_message: dict[str, Any],
self_id: str | None = None,
+2
View File
@@ -6,6 +6,7 @@ from dataclasses import dataclass, field
from typing import Any
from anthropic.types import Message as AnthropicMessage
from deprecated import deprecated
from google.genai.types import GenerateContentResponse
from openai.types.chat.chat_completion import ChatCompletion
@@ -400,6 +401,7 @@ class LLMResponse:
else:
self._completion_text = value
@deprecated(reason="Use to_openai_to_calls_model instead.")
def to_openai_tool_calls(self) -> list[dict]:
"""Convert to OpenAI tool calls format. Deprecated, use to_openai_to_calls_model instead."""
ret = []
@@ -12,6 +12,7 @@ from types import MappingProxyType
from typing import Any
import aiohttp
from deprecated import deprecated
from astrbot import logger
from astrbot.core import sp
@@ -328,6 +329,7 @@ class FunctionToolManager:
return self._mcp_server_runtime_view
@property
@deprecated(reason="Use mcp_server_runtime_view instead.")
def mcp_server_runtime(self) -> Mapping[str, _MCPServerRuntime]:
"""Backward-compatible read-only view (deprecated). Do not mutate.
+3
View File
@@ -5,6 +5,8 @@ import traceback
from collections.abc import Callable
from typing import Protocol, runtime_checkable
from deprecated import deprecated
from astrbot.core import astrbot_config, logger, sp
from astrbot.core.astrbot_config_mgr import AstrBotConfigManager
from astrbot.core.db import BaseDatabase
@@ -136,6 +138,7 @@ class ProviderManager:
return self.persona_mgr.personas_v3
@property
@deprecated(reason="Use persona_mgr.get_default_persona_v3() instead.")
def selected_default_persona(self):
"""动态获取最新的默认选中 persona。已弃用,请使用 context.persona_mgr.get_default_persona_v3()"""
return self.persona_mgr.selected_default_persona_v3
+6
View File
@@ -684,6 +684,7 @@ class Context:
"""
self.provider_manager.provider_insts.append(provider)
@deprecated(reason="Use decorator-based tool registration instead.")
def register_llm_tool(
self,
name: str,
@@ -716,6 +717,7 @@ class Context:
star_handlers_registry.append(md)
self.provider_manager.llm_tools.add_func(name, func_args, desc, func_obj)
@deprecated(reason="Use deactivate_llm_tool() to disable a tool instead.")
def unregister_llm_tool(self, name: str) -> None:
"""[DEPRECATED]删除一个函数调用工具。
@@ -728,6 +730,7 @@ class Context:
"""
self.provider_manager.llm_tools.remove_func(name)
@deprecated(reason="Use the command decorator (@filter.command) instead.")
def register_commands(
self,
star_name: str,
@@ -769,6 +772,9 @@ class Context:
)
star_handlers_registry.append(md)
@deprecated(
reason="Start background tasks in the plugin's initialize() method instead."
)
def register_task(self, task: Awaitable, desc: str) -> None:
"""[DEPRECATED]注册一个异步任务。
+15
View File
@@ -5,6 +5,7 @@ from collections import defaultdict
from typing import Any, TypeVar, overload
from apscheduler.schedulers.background import BackgroundScheduler
from deprecated import deprecated
from astrbot.core.db import BaseDatabase
from astrbot.core.db.po import Preference
@@ -166,6 +167,10 @@ class SharedPreferences:
# DEPRECATED METHODS
# ====
@deprecated(
version="4.0.0",
reason="Use get_async() instead. Plugins: use PluginKVStoreMixin.get_kv_data().",
)
def get(
self,
key: str,
@@ -188,6 +193,7 @@ class SharedPreferences:
return result if result is not None else default
@deprecated(version="4.0.0", reason="Use range_get_async() instead.")
def range_get(
self,
scope: str,
@@ -202,6 +208,10 @@ class SharedPreferences:
return result
@deprecated(
version="4.0.0",
reason="Use put_async() instead. Plugins: use PluginKVStoreMixin.put_kv_data().",
)
def put(
self, key, value, scope: str | None = None, scope_id: str | None = None
) -> None:
@@ -211,6 +221,10 @@ class SharedPreferences:
self._sync_loop,
).result()
@deprecated(
version="4.0.0",
reason="Use remove_async() instead. Plugins: use PluginKVStoreMixin.delete_kv_data().",
)
def remove(
self, key, scope: str | None = None, scope_id: str | None = None
) -> None:
@@ -220,6 +234,7 @@ class SharedPreferences:
self._sync_loop,
).result()
@deprecated(version="4.0.0", reason="Use clear_async() instead.")
def clear(self, scope: str | None = None, scope_id: str | None = None) -> None:
"""清空偏好设置(已弃用)"""
asyncio.run_coroutine_threadsafe(