amrita 0.7.3.2__tar.gz → 1.0.0.dev2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {amrita-0.7.3.2/amrita.egg-info → amrita-1.0.0.dev2}/PKG-INFO +8 -5
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/README.md +4 -3
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/cache.py +4 -4
- amrita-1.0.0.dev2/amrita/config_manager.py +25 -0
- amrita-1.0.0.dev2/amrita/dirty.py +265 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/__init__.py +0 -2
- amrita-1.0.0.dev2/amrita/plugins/chat/builtin_hook.py +122 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/check_rule.py +33 -30
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/config.py +89 -89
- amrita-1.0.0.dev2/amrita/plugins/chat/exception.py +20 -0
- amrita-1.0.0.dev2/amrita/plugins/chat/handlers/chat.py +398 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/chatobj.py +23 -15
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/choose_prompt.py +2 -4
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/debug_switchs.py +1 -2
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/del_memory.py +7 -5
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/disable.py +6 -6
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/enable.py +8 -6
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/fakepeople_switch.py +8 -8
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/insights.py +11 -10
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/mcp.py +9 -12
- amrita-1.0.0.dev2/amrita/plugins/chat/handlers/poke_event.py +221 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/preset_test.py +3 -5
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/prompt.py +7 -6
- amrita-1.0.0.dev2/amrita/plugins/chat/handlers/sessions.py +214 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/set_preset.py +2 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/show_abstract.py +6 -3
- amrita-1.0.0.dev2/amrita/plugins/chat/matcher.py +15 -0
- amrita-1.0.0.dev2/amrita/plugins/chat/migrations/702651e6e3d8_refactor_by_core.py +251 -0
- amrita-1.0.0.dev2/amrita/plugins/chat/on_event.py +15 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/page.py +11 -11
- amrita-1.0.0.dev2/amrita/plugins/chat/preprocess.py +24 -0
- amrita-1.0.0.dev2/amrita/plugins/chat/runtime.py +288 -0
- amrita-1.0.0.dev2/amrita/plugins/chat/utils/__init__.py +3 -0
- amrita-1.0.0.dev2/amrita/plugins/chat/utils/app.py +182 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/utils/functions.py +5 -35
- amrita-1.0.0.dev2/amrita/plugins/chat/utils/libchat.py +91 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/utils/llm_tools/builtin_tools.py +14 -51
- amrita-1.0.0.dev2/amrita/plugins/chat/utils/llm_tools/manager.py +3 -0
- amrita-1.0.0.dev2/amrita/plugins/chat/utils/llm_tools/mcp_client.py +19 -0
- amrita-1.0.0.dev2/amrita/plugins/chat/utils/llm_tools/models.py +43 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/utils/lock.py +0 -5
- amrita-1.0.0.dev2/amrita/plugins/chat/utils/protocol.py +30 -0
- amrita-1.0.0.dev2/amrita/plugins/chat/utils/sql.py +489 -0
- amrita-1.0.0.dev2/amrita/plugins/chat/utils/tokenizer.py +10 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/nodelib.py +0 -11
- {amrita-0.7.3.2 → amrita-1.0.0.dev2/amrita.egg-info}/PKG-INFO +8 -5
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita.egg-info/SOURCES.txt +6 -7
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita.egg-info/requires.txt +3 -1
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/pyproject.toml +5 -2
- amrita-0.7.3.2/amrita/config_manager.py +0 -640
- amrita-0.7.3.2/amrita/plugins/chat/API.py +0 -159
- amrita-0.7.3.2/amrita/plugins/chat/builtin_hook.py +0 -465
- amrita-0.7.3.2/amrita/plugins/chat/chatmanager.py +0 -1089
- amrita-0.7.3.2/amrita/plugins/chat/event.py +0 -219
- amrita-0.7.3.2/amrita/plugins/chat/exception.py +0 -14
- amrita-0.7.3.2/amrita/plugins/chat/handlers/chat.py +0 -36
- amrita-0.7.3.2/amrita/plugins/chat/handlers/poke_event.py +0 -224
- amrita-0.7.3.2/amrita/plugins/chat/handlers/sessions.py +0 -154
- amrita-0.7.3.2/amrita/plugins/chat/matcher.py +0 -237
- amrita-0.7.3.2/amrita/plugins/chat/on_event.py +0 -22
- amrita-0.7.3.2/amrita/plugins/chat/preprocess.py +0 -31
- amrita-0.7.3.2/amrita/plugins/chat/utils/event.py +0 -25
- amrita-0.7.3.2/amrita/plugins/chat/utils/libchat.py +0 -546
- amrita-0.7.3.2/amrita/plugins/chat/utils/llm_tools/manager.py +0 -165
- amrita-0.7.3.2/amrita/plugins/chat/utils/llm_tools/mcp_client.py +0 -326
- amrita-0.7.3.2/amrita/plugins/chat/utils/llm_tools/models.py +0 -345
- amrita-0.7.3.2/amrita/plugins/chat/utils/logging.py +0 -15
- amrita-0.7.3.2/amrita/plugins/chat/utils/memory.py +0 -293
- amrita-0.7.3.2/amrita/plugins/chat/utils/models.py +0 -637
- amrita-0.7.3.2/amrita/plugins/chat/utils/protocol.py +0 -96
- amrita-0.7.3.2/amrita/plugins/chat/utils/tokenizer.py +0 -117
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/LICENSE +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/MANIFEST.in +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/API.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/__init__.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/__main__.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/bot.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/cli.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/cmds/main.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/cmds/plugin.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/cmds/wrapper.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/config.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/load_test.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/on.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/add_notices.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/presets.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/handlers/recall.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/hook_manager.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/matcher_manager.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/migrations/1d99948099bb_fix_memory.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/migrations/1e67057a1646_memory_abstract.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/migrations/25b14ed0ad3c_insights.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/migrations/3537b7cb6a29_init.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/migrations/5740c5aae763_json.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/migrations/74381965bbe2_abs_move.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/migrations/b54b093a9ce3_sessions.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/migrations/ec1f1e46989b_usage.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/templates/function.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/templates/mcp.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/templates/models.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/templates/prompts.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/chat/utils/admin.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/__init__.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/add.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/amrita.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/apicall_insight.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/auto_clean.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/ban.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/black.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/blacklist/black.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/blacklist/models.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/checker.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/event.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/leave.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/list_black.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/migrations/5d80e832962b_webui.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/migrations/9c25f4ea773e_manager.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/migrations/a61ec0d70761_type.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/migrations/a62db4039f17_blacklist.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/models.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/pardon.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/send.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/status.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/status_manager.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/manager/utils.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/menu/__init__.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/menu/commands.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/menu/manager.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/menu/models.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/menu/utils.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/API/admin.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/API/config.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/API/node.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/API/rules.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/__init__.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/command_manager.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/commands/lp_chat_group.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/commands/lp_perm_group.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/commands/lp_user.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/commands/main.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/config.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/legacy.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/migrations/8b619d7fca40_refactor.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/models.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/on_init.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/perm/utils.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/API.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/__init__.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/authlib.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/config.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/main.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/route/api.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/route/bot.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/route/confedit.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/route/config.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/route/dbmeta.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/route/index.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/route/user.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/sidebar.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/static/css/base.css +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/static/css/dash.css +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/static/images/Amrita.png +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/static/images/github-mark-white.svg +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/static/images/github-mark.svg +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/base.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/blacklist.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/confedit_edit.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/config.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/create_perm_group.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/dashboard.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/dbmetadata.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/error.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/group_permissions.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/index.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/password-help.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/perm_group_permissions.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/permissions.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/plugins.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/status.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/system_confedit.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/plugins/webui/service/templates/user_permissions.html +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/resource.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/utils/admin.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/utils/bot_utils.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/utils/dbmetadata.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/utils/dependencies.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/utils/logging.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/utils/plugins.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/utils/rate.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/utils/send.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/utils/system_health.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita/utils/utils.py +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita.egg-info/dependency_links.txt +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita.egg-info/entry_points.txt +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/amrita.egg-info/top_level.txt +0 -0
- {amrita-0.7.3.2 → amrita-1.0.0.dev2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: amrita
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0.dev2
|
|
4
4
|
Summary: A powerful AI bot framework powered by NoneBot2
|
|
5
5
|
License-Expression: GPL-3.0-or-later
|
|
6
6
|
Project-URL: Homepage, https://github.com/LiteSuggarDEV/Amrita
|
|
@@ -29,6 +29,8 @@ Requires-Dist: nonebot-plugin-orm>=0.8.3
|
|
|
29
29
|
Requires-Dist: nb-cli==1.6.0
|
|
30
30
|
Requires-Dist: watchfiles>=1.1.1
|
|
31
31
|
Provides-Extra: full
|
|
32
|
+
Requires-Dist: amrita-core==0.4.3.2; extra == "full"
|
|
33
|
+
Requires-Dist: nonebot-plugin-uniconf>=0.1.3; extra == "full"
|
|
32
34
|
Requires-Dist: aiomysql>=0.3.2; extra == "full"
|
|
33
35
|
Requires-Dist: aiopg>=1.4.0; extra == "full"
|
|
34
36
|
Requires-Dist: aiosqlite>=0.21.0; extra == "full"
|
|
@@ -46,7 +48,7 @@ Requires-Dist: pytz>=2025.1; extra == "full"
|
|
|
46
48
|
Requires-Dist: stubs>=1.0.0; extra == "full"
|
|
47
49
|
Requires-Dist: dotenv>=0.9.9; extra == "full"
|
|
48
50
|
Requires-Dist: importlib>=1.0.4; extra == "full"
|
|
49
|
-
Requires-Dist: openai
|
|
51
|
+
Requires-Dist: openai>=2.16.0; extra == "full"
|
|
50
52
|
Requires-Dist: pydantic>=2.4.2; extra == "full"
|
|
51
53
|
Requires-Dist: jieba>=0.42.1; extra == "full"
|
|
52
54
|
Requires-Dist: nonebot-plugin-orm>=0.8.2; extra == "full"
|
|
@@ -54,7 +56,7 @@ Requires-Dist: nonebot-adapter-onebot>=2.4.6; extra == "full"
|
|
|
54
56
|
Requires-Dist: nonebot2[fastapi]>=2.4.3; extra == "full"
|
|
55
57
|
Dynamic: license-file
|
|
56
58
|
|
|
57
|
-
# PROJ.Amrita 🌸 - 基于 NoneBot 的
|
|
59
|
+
# PROJ.Amrita 🌸 - 基于 NoneBot 与 AmritaCore 的 Agent Bot
|
|
58
60
|
|
|
59
61
|
<p align= "center">
|
|
60
62
|
<img src="./logo/Amrita-nobg.png" width=400 height=400>
|
|
@@ -65,7 +67,7 @@ Dynamic: license-file
|
|
|
65
67
|
<img src="https://img.shields.io/badge/NoneBot-2.0+-red?logo=nonebot" alt="NoneBot">
|
|
66
68
|
</p>
|
|
67
69
|
|
|
68
|
-
Amrita 是一个基于[NoneBot2](https://nonebot.dev/)的强大聊天机器人框架,专为快速构建和部署智能聊天机器人而设计。它是一个完整的 LLM 聊天机器人解决方案,具有强大的功能和灵活性。
|
|
70
|
+
Amrita 是一个基于[NoneBot2](https://nonebot.dev/)与[AmritaCore](https://amrita-core.suggar.top)的强大聊天机器人框架,专为快速构建和部署智能聊天机器人而设计。它是一个完整的 LLM 聊天机器人解决方案,具有强大的功能和灵活性。
|
|
69
71
|
|
|
70
72
|
## 🌟 特性亮点
|
|
71
73
|
|
|
@@ -76,7 +78,7 @@ Amrita 是一个基于[NoneBot2](https://nonebot.dev/)的强大聊天机器人
|
|
|
76
78
|
- **插件化架构**: 模块化设计,易于扩展和定制
|
|
77
79
|
- **开箱即用**: 预设丰富的回复模板和功能配置
|
|
78
80
|
- **强大 CLI 工具**: 一体化命令行管理工具,简化开发和部署流程
|
|
79
|
-
- **Agent
|
|
81
|
+
- **Agent**: 支持智能对话管理,自动生成回复
|
|
80
82
|
- **智能上下文管理**: 支持智能上下文管理
|
|
81
83
|
- **Web UI**: 集成 Web UI,提供可视化管理界面
|
|
82
84
|
- **MCP**: 支持Model Context Protocol
|
|
@@ -84,6 +86,7 @@ Amrita 是一个基于[NoneBot2](https://nonebot.dev/)的强大聊天机器人
|
|
|
84
86
|
## 📚 文档和资源
|
|
85
87
|
|
|
86
88
|
- [官方文档](https://amrita.suggar.top)
|
|
89
|
+
- [Core开发文档](https://amrita-core.suggar.top)
|
|
87
90
|
- [问题反馈](https://github.com/LiteSuggarDEV/Amrita/issues)
|
|
88
91
|
|
|
89
92
|
## 🤝 贡献
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# PROJ.Amrita 🌸 - 基于 NoneBot 的
|
|
1
|
+
# PROJ.Amrita 🌸 - 基于 NoneBot 与 AmritaCore 的 Agent Bot
|
|
2
2
|
|
|
3
3
|
<p align= "center">
|
|
4
4
|
<img src="./logo/Amrita-nobg.png" width=400 height=400>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<img src="https://img.shields.io/badge/NoneBot-2.0+-red?logo=nonebot" alt="NoneBot">
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
Amrita 是一个基于[NoneBot2](https://nonebot.dev/)的强大聊天机器人框架,专为快速构建和部署智能聊天机器人而设计。它是一个完整的 LLM 聊天机器人解决方案,具有强大的功能和灵活性。
|
|
12
|
+
Amrita 是一个基于[NoneBot2](https://nonebot.dev/)与[AmritaCore](https://amrita-core.suggar.top)的强大聊天机器人框架,专为快速构建和部署智能聊天机器人而设计。它是一个完整的 LLM 聊天机器人解决方案,具有强大的功能和灵活性。
|
|
13
13
|
|
|
14
14
|
## 🌟 特性亮点
|
|
15
15
|
|
|
@@ -20,7 +20,7 @@ Amrita 是一个基于[NoneBot2](https://nonebot.dev/)的强大聊天机器人
|
|
|
20
20
|
- **插件化架构**: 模块化设计,易于扩展和定制
|
|
21
21
|
- **开箱即用**: 预设丰富的回复模板和功能配置
|
|
22
22
|
- **强大 CLI 工具**: 一体化命令行管理工具,简化开发和部署流程
|
|
23
|
-
- **Agent
|
|
23
|
+
- **Agent**: 支持智能对话管理,自动生成回复
|
|
24
24
|
- **智能上下文管理**: 支持智能上下文管理
|
|
25
25
|
- **Web UI**: 集成 Web UI,提供可视化管理界面
|
|
26
26
|
- **MCP**: 支持Model Context Protocol
|
|
@@ -28,6 +28,7 @@ Amrita 是一个基于[NoneBot2](https://nonebot.dev/)的强大聊天机器人
|
|
|
28
28
|
## 📚 文档和资源
|
|
29
29
|
|
|
30
30
|
- [官方文档](https://amrita.suggar.top)
|
|
31
|
+
- [Core开发文档](https://amrita-core.suggar.top)
|
|
31
32
|
- [问题反馈](https://github.com/LiteSuggarDEV/Amrita/issues)
|
|
32
33
|
|
|
33
34
|
## 🤝 贡献
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
该模块实现了基于OrderedDict的LRU(Least Recently Used)缓存,
|
|
4
4
|
支持字典-like的操作接口,并在缓存满时自动淘汰最久未使用的条目。
|
|
5
|
-
同时实现了TTL(Time To Live)和
|
|
5
|
+
同时实现了TTL(Time To Live)和LFU(Least Frequently Used)缓存策略。
|
|
6
6
|
|
|
7
7
|
目前这个模块看起来并没有使用,但是在Amrita的未来的重构计划中将作为重要的一环。
|
|
8
8
|
"""
|
|
@@ -445,14 +445,14 @@ class TTLCache(Generic[K, V]):
|
|
|
445
445
|
return f"{self.__class__.__name__}(capacity={self._capacity}, ttl={self._ttl}, items={{{', '.join(items)}}})"
|
|
446
446
|
|
|
447
447
|
|
|
448
|
-
class
|
|
449
|
-
"""
|
|
448
|
+
class LFUCache(Generic[K, V]):
|
|
449
|
+
"""LFU缓存实现(Least Frequently Used)
|
|
450
450
|
|
|
451
451
|
该缓存根据访问频率淘汰条目,保留访问频率最高的条目。
|
|
452
452
|
"""
|
|
453
453
|
|
|
454
454
|
def __init__(self, capacity: int):
|
|
455
|
-
"""初始化
|
|
455
|
+
"""初始化LFU缓存
|
|
456
456
|
|
|
457
457
|
Args:
|
|
458
458
|
capacity: 缓存的最大容量
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""为了兼容,这里保留了import"""
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
4
|
+
|
|
5
|
+
warnings.warn(
|
|
6
|
+
"This module is deprecated and will be removed in a future version(1.2.0).Please import from `nonebot_plugin_uniconf` instead.",
|
|
7
|
+
DeprecationWarning,
|
|
8
|
+
stacklevel=2,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from nonebot_plugin_uniconf import (
|
|
12
|
+
CALLBACK_TYPE,
|
|
13
|
+
FILTER_TYPE,
|
|
14
|
+
BaseDataManager,
|
|
15
|
+
EnvfulConfigManager,
|
|
16
|
+
UniConfigManager,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"CALLBACK_TYPE",
|
|
21
|
+
"FILTER_TYPE",
|
|
22
|
+
"BaseDataManager",
|
|
23
|
+
"EnvfulConfigManager",
|
|
24
|
+
"UniConfigManager",
|
|
25
|
+
]
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"""脏标记Pydantic模型,用于数据库ORM等场景,自动跟踪属性的修改状态。"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, SupportsIndex, TypeVar
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
|
|
9
|
+
T = TypeVar("T")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DirtyList(list):
|
|
13
|
+
def __init__(self, *args, parent: DirtyAwareModel, attr: str, **kwargs):
|
|
14
|
+
super().__init__(*args, **kwargs)
|
|
15
|
+
self._parent = parent
|
|
16
|
+
self._attr = attr
|
|
17
|
+
|
|
18
|
+
def _mark_dirty(self):
|
|
19
|
+
self._parent._mark_dirty(self._attr)
|
|
20
|
+
|
|
21
|
+
def _wrap_value(self, value: Any) -> Any:
|
|
22
|
+
if isinstance(value, (list, dict, set)) and not hasattr(value, "_parent"):
|
|
23
|
+
return _wrap_container(value, self._parent, self._attr)
|
|
24
|
+
return value
|
|
25
|
+
|
|
26
|
+
def append(self, item):
|
|
27
|
+
item = self._wrap_value(item)
|
|
28
|
+
super().append(item)
|
|
29
|
+
self._mark_dirty()
|
|
30
|
+
|
|
31
|
+
def extend(self, iterable):
|
|
32
|
+
iterable = [self._wrap_value(i) for i in iterable]
|
|
33
|
+
super().extend(iterable)
|
|
34
|
+
self._mark_dirty()
|
|
35
|
+
|
|
36
|
+
def insert(self, index, item):
|
|
37
|
+
item = self._wrap_value(item)
|
|
38
|
+
super().insert(index, item)
|
|
39
|
+
self._mark_dirty()
|
|
40
|
+
|
|
41
|
+
def remove(self, item):
|
|
42
|
+
super().remove(item)
|
|
43
|
+
self._mark_dirty()
|
|
44
|
+
|
|
45
|
+
def pop(self, index: SupportsIndex = -1):
|
|
46
|
+
result = super().pop(index)
|
|
47
|
+
self._mark_dirty()
|
|
48
|
+
return result
|
|
49
|
+
|
|
50
|
+
def clear(self):
|
|
51
|
+
super().clear()
|
|
52
|
+
self._mark_dirty()
|
|
53
|
+
|
|
54
|
+
def __setitem__(self, index, item):
|
|
55
|
+
if isinstance(index, slice):
|
|
56
|
+
item = [self._wrap_value(i) for i in item]
|
|
57
|
+
else:
|
|
58
|
+
item = self._wrap_value(item)
|
|
59
|
+
super().__setitem__(index, item)
|
|
60
|
+
self._mark_dirty()
|
|
61
|
+
|
|
62
|
+
def __delitem__(self, index):
|
|
63
|
+
super().__delitem__(index)
|
|
64
|
+
self._mark_dirty()
|
|
65
|
+
|
|
66
|
+
def __iadd__(self, other):
|
|
67
|
+
other = [self._wrap_value(i) for i in other]
|
|
68
|
+
super().__iadd__(other)
|
|
69
|
+
self._mark_dirty()
|
|
70
|
+
return self
|
|
71
|
+
|
|
72
|
+
def __imul__(self, other):
|
|
73
|
+
super().__imul__(other)
|
|
74
|
+
self._mark_dirty()
|
|
75
|
+
return self
|
|
76
|
+
|
|
77
|
+
def __getitem__(self, index):
|
|
78
|
+
value = super().__getitem__(index)
|
|
79
|
+
if isinstance(index, slice):
|
|
80
|
+
return value
|
|
81
|
+
return self._wrap_value(value)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class DirtyDict(dict):
|
|
85
|
+
def __init__(self, *args, parent: DirtyAwareModel, attr: str, **kwargs):
|
|
86
|
+
super().__init__(*args, **kwargs)
|
|
87
|
+
self._parent = parent
|
|
88
|
+
self._attr = attr
|
|
89
|
+
|
|
90
|
+
def _mark_dirty(self):
|
|
91
|
+
self._parent._mark_dirty(self._attr)
|
|
92
|
+
|
|
93
|
+
def _wrap_value(self, value: Any) -> Any:
|
|
94
|
+
if isinstance(value, (list, dict, set)) and not hasattr(value, "_parent"):
|
|
95
|
+
return _wrap_container(value, self._parent, self._attr)
|
|
96
|
+
return value
|
|
97
|
+
|
|
98
|
+
def __setitem__(self, key, value):
|
|
99
|
+
value = self._wrap_value(value)
|
|
100
|
+
super().__setitem__(key, value)
|
|
101
|
+
self._mark_dirty()
|
|
102
|
+
|
|
103
|
+
def __delitem__(self, key):
|
|
104
|
+
super().__delitem__(key)
|
|
105
|
+
self._mark_dirty()
|
|
106
|
+
|
|
107
|
+
def pop(self, key, default=None):
|
|
108
|
+
result = super().pop(key, default)
|
|
109
|
+
self._mark_dirty()
|
|
110
|
+
return result
|
|
111
|
+
|
|
112
|
+
def popitem(self):
|
|
113
|
+
result = super().popitem()
|
|
114
|
+
self._mark_dirty()
|
|
115
|
+
return result
|
|
116
|
+
|
|
117
|
+
def clear(self):
|
|
118
|
+
super().clear()
|
|
119
|
+
self._mark_dirty()
|
|
120
|
+
|
|
121
|
+
def update(self, *args, **kwargs):
|
|
122
|
+
other = dict(*args, **kwargs)
|
|
123
|
+
for k, v in other.items():
|
|
124
|
+
other[k] = self._wrap_value(v)
|
|
125
|
+
super().update(other)
|
|
126
|
+
self._mark_dirty()
|
|
127
|
+
|
|
128
|
+
def setdefault(self, key, default=None):
|
|
129
|
+
default = self._wrap_value(default)
|
|
130
|
+
result = super().setdefault(key, default)
|
|
131
|
+
if key not in self:
|
|
132
|
+
self._mark_dirty()
|
|
133
|
+
return self._wrap_value(result)
|
|
134
|
+
|
|
135
|
+
def __getitem__(self, key):
|
|
136
|
+
value = super().__getitem__(key)
|
|
137
|
+
return self._wrap_value(value)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class DirtySet(set):
|
|
141
|
+
def __init__(self, *args, parent: DirtyAwareModel, attr: str, **kwargs):
|
|
142
|
+
super().__init__(*args, **kwargs)
|
|
143
|
+
self._parent = parent
|
|
144
|
+
self._attr = attr
|
|
145
|
+
|
|
146
|
+
def _mark_dirty(self):
|
|
147
|
+
self._parent._mark_dirty(self._attr)
|
|
148
|
+
|
|
149
|
+
def add(self, element):
|
|
150
|
+
super().add(element)
|
|
151
|
+
self._mark_dirty()
|
|
152
|
+
|
|
153
|
+
def remove(self, element):
|
|
154
|
+
super().remove(element)
|
|
155
|
+
self._mark_dirty()
|
|
156
|
+
|
|
157
|
+
def discard(self, element):
|
|
158
|
+
super().discard(element)
|
|
159
|
+
self._mark_dirty()
|
|
160
|
+
|
|
161
|
+
def pop(self):
|
|
162
|
+
result = super().pop()
|
|
163
|
+
self._mark_dirty()
|
|
164
|
+
return result
|
|
165
|
+
|
|
166
|
+
def clear(self):
|
|
167
|
+
super().clear()
|
|
168
|
+
self._mark_dirty()
|
|
169
|
+
|
|
170
|
+
def __ior__(self, other):
|
|
171
|
+
super().__ior__(other)
|
|
172
|
+
self._mark_dirty()
|
|
173
|
+
return self
|
|
174
|
+
|
|
175
|
+
def __iand__(self, other):
|
|
176
|
+
super().__iand__(other)
|
|
177
|
+
self._mark_dirty()
|
|
178
|
+
return self
|
|
179
|
+
|
|
180
|
+
def __isub__(self, other):
|
|
181
|
+
super().__isub__(other)
|
|
182
|
+
self._mark_dirty()
|
|
183
|
+
return self
|
|
184
|
+
|
|
185
|
+
def __ixor__(self, other):
|
|
186
|
+
super().__ixor__(other)
|
|
187
|
+
self._mark_dirty()
|
|
188
|
+
return self
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _wrap_container(obj: list | dict | set, parent: DirtyAwareModel, attr: str):
|
|
192
|
+
if isinstance(obj, list):
|
|
193
|
+
return DirtyList(obj, parent=parent, attr=attr)
|
|
194
|
+
if isinstance(obj, dict):
|
|
195
|
+
return DirtyDict(obj, parent=parent, attr=attr)
|
|
196
|
+
if isinstance(obj, set):
|
|
197
|
+
return DirtySet(obj, parent=parent, attr=attr)
|
|
198
|
+
return obj
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class DirtyAwareModel(BaseModel):
|
|
202
|
+
dirtyvars__: set[str] = Field(default_factory=set, init=False, exclude=True)
|
|
203
|
+
|
|
204
|
+
def model_post_init(self, __context, /):
|
|
205
|
+
del __context
|
|
206
|
+
for name, value in self.__dict__.items():
|
|
207
|
+
if name.startswith("__") or name == "dirtyvars__":
|
|
208
|
+
continue
|
|
209
|
+
wrapped = self._wrap_if_needed(name, value)
|
|
210
|
+
if wrapped is not value:
|
|
211
|
+
object.__setattr__(self, name, wrapped)
|
|
212
|
+
|
|
213
|
+
def __setattr__(self, name, value):
|
|
214
|
+
if name in ("dirtyvars__",):
|
|
215
|
+
object.__setattr__(self, name, value)
|
|
216
|
+
return
|
|
217
|
+
|
|
218
|
+
wrapped = self._wrap_if_needed(name, value)
|
|
219
|
+
super().__setattr__(name, wrapped)
|
|
220
|
+
self._mark_dirty(name)
|
|
221
|
+
|
|
222
|
+
def __getattribute__(self, name: str) -> Any:
|
|
223
|
+
value = super().__getattribute__(name)
|
|
224
|
+
if name.startswith("__") or name == "dirtyvars__" or name.endswith("__"):
|
|
225
|
+
return value
|
|
226
|
+
|
|
227
|
+
if hasattr(value, "_parent"):
|
|
228
|
+
return value
|
|
229
|
+
|
|
230
|
+
if isinstance(value, (list, dict, set)):
|
|
231
|
+
wrapped = _wrap_container(value, self, name)
|
|
232
|
+
object.__setattr__(self, name, wrapped)
|
|
233
|
+
return wrapped
|
|
234
|
+
elif isinstance(
|
|
235
|
+
value, BaseModel
|
|
236
|
+
): # 也不会有人在ORM模型里嵌套好几层吧,就简单地处理一下吧
|
|
237
|
+
self._mark_dirty(name)
|
|
238
|
+
|
|
239
|
+
return value
|
|
240
|
+
|
|
241
|
+
def _wrap_if_needed(self, name: str, value: Any) -> Any:
|
|
242
|
+
if isinstance(value, (list, dict, set)) and not hasattr(value, "_parent"):
|
|
243
|
+
return _wrap_container(value, self, name)
|
|
244
|
+
return value
|
|
245
|
+
|
|
246
|
+
def _mark_dirty(self, name: str):
|
|
247
|
+
exclue: tuple[str, ...] | None
|
|
248
|
+
if exclue := getattr(self, "dirty_excluede__", None):
|
|
249
|
+
if name in exclue:
|
|
250
|
+
return
|
|
251
|
+
dirty_vars: set[str] | None = getattr(self, "dirtyvars__", None)
|
|
252
|
+
if dirty_vars is None:
|
|
253
|
+
return
|
|
254
|
+
dirty_vars.add(name)
|
|
255
|
+
|
|
256
|
+
def is_dirty(self, name: str | None = None) -> bool:
|
|
257
|
+
if name:
|
|
258
|
+
return name in self.dirtyvars__
|
|
259
|
+
return len(self.dirtyvars__) > 0
|
|
260
|
+
|
|
261
|
+
def get_dirty_vars(self) -> set[str]:
|
|
262
|
+
return set(self.dirtyvars__)
|
|
263
|
+
|
|
264
|
+
def clean(self):
|
|
265
|
+
self.dirtyvars__.clear()
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import random
|
|
3
|
+
import typing
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from amrita_core import (
|
|
7
|
+
ChatObject,
|
|
8
|
+
PreCompletionEvent,
|
|
9
|
+
ToolContext,
|
|
10
|
+
on_precompletion,
|
|
11
|
+
on_tools,
|
|
12
|
+
)
|
|
13
|
+
from amrita_core.builtins import agent
|
|
14
|
+
from amrita_core.protocol import StringMessageContent
|
|
15
|
+
from nonebot import get_bot
|
|
16
|
+
from nonebot.adapters.onebot.v11 import Bot, MessageEvent
|
|
17
|
+
from nonebot.log import logger
|
|
18
|
+
from nonebot.matcher import Matcher
|
|
19
|
+
|
|
20
|
+
from amrita.plugins.chat.utils.app import CachedUserDataRepository
|
|
21
|
+
from amrita.plugins.chat.utils.sql import (
|
|
22
|
+
SEND_MESSAGES,
|
|
23
|
+
ToolCall,
|
|
24
|
+
UniResponse,
|
|
25
|
+
get_any_id,
|
|
26
|
+
)
|
|
27
|
+
from amrita.utils.admin import send_to_admin
|
|
28
|
+
|
|
29
|
+
from .config import Config, config_manager
|
|
30
|
+
from .utils.libchat import (
|
|
31
|
+
tools_caller,
|
|
32
|
+
)
|
|
33
|
+
from .utils.llm_tools.builtin_tools import (
|
|
34
|
+
PROCESS_MESSAGE_TOOL,
|
|
35
|
+
REPORT_TOOL_HIGH,
|
|
36
|
+
REPORT_TOOL_LOW,
|
|
37
|
+
REPORT_TOOL_MEDIUM,
|
|
38
|
+
report,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
checkhook = on_precompletion(1, False)
|
|
42
|
+
|
|
43
|
+
agent.BUILTIN_TOOLS_NAME.add(REPORT_TOOL_MEDIUM.function.name)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@on_tools(
|
|
47
|
+
data=PROCESS_MESSAGE_TOOL,
|
|
48
|
+
custom_run=True,
|
|
49
|
+
enable_if=lambda: config_manager.config.llm.tools.agent_middle_message,
|
|
50
|
+
)
|
|
51
|
+
async def _(ctx: ToolContext) -> str | None:
|
|
52
|
+
msg: str = ctx.data["content"]
|
|
53
|
+
logger.debug(f"[LLM-ProcessMessage] {msg}")
|
|
54
|
+
chatobj: ChatObject = ctx.event.chat_object
|
|
55
|
+
await chatobj.yield_response(StringMessageContent(msg))
|
|
56
|
+
return f"Sent a message to user:\n\n```text\n{msg}\n```\n"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@checkhook.handle()
|
|
60
|
+
async def text_check(
|
|
61
|
+
event: PreCompletionEvent, nonebot_event: MessageEvent, nonebot_matcher: Matcher
|
|
62
|
+
) -> None:
|
|
63
|
+
config: Config = config_manager.config
|
|
64
|
+
if not config.llm.tools.enable_report:
|
|
65
|
+
checkhook.pass_event()
|
|
66
|
+
logger.info("Content checking in progress......")
|
|
67
|
+
bot = get_bot()
|
|
68
|
+
match config.llm.tools.report_invoke_level:
|
|
69
|
+
case "low":
|
|
70
|
+
tool_list = [REPORT_TOOL_LOW]
|
|
71
|
+
case "medium":
|
|
72
|
+
tool_list = [REPORT_TOOL_MEDIUM]
|
|
73
|
+
case "high":
|
|
74
|
+
tool_list = [REPORT_TOOL_HIGH]
|
|
75
|
+
case _:
|
|
76
|
+
raise ValueError("Invalid report_invoke_level")
|
|
77
|
+
msg: SEND_MESSAGES = event.get_context_messages().unwrap()
|
|
78
|
+
dm = CachedUserDataRepository()
|
|
79
|
+
if (
|
|
80
|
+
config.llm.tools.report_exclude_context
|
|
81
|
+
and config.llm.tools.report_exclude_system_prompt
|
|
82
|
+
):
|
|
83
|
+
msg = [event.get_context_messages().get_user_query()]
|
|
84
|
+
elif config.llm.tools.report_exclude_system_prompt:
|
|
85
|
+
msg = event.get_context_messages().get_memory()
|
|
86
|
+
elif config.llm.tools.report_exclude_context:
|
|
87
|
+
msg = [
|
|
88
|
+
event.get_context_messages().get_train(),
|
|
89
|
+
event.get_context_messages().get_user_query(),
|
|
90
|
+
]
|
|
91
|
+
if not msg:
|
|
92
|
+
logger.warning("Message list is empty, skipping content check")
|
|
93
|
+
return
|
|
94
|
+
response: UniResponse[None, list[ToolCall] | None] = await tools_caller(
|
|
95
|
+
msg, tool_list
|
|
96
|
+
)
|
|
97
|
+
if tool_calls := response.tool_calls:
|
|
98
|
+
for tool_call in tool_calls:
|
|
99
|
+
function_name = tool_call.function.name
|
|
100
|
+
function_args: dict[str, Any] = json.loads(tool_call.function.arguments)
|
|
101
|
+
if function_name == REPORT_TOOL_MEDIUM.function.name:
|
|
102
|
+
if not function_args.get("invoke"):
|
|
103
|
+
return
|
|
104
|
+
await report(
|
|
105
|
+
event,
|
|
106
|
+
nonebot_event,
|
|
107
|
+
function_args,
|
|
108
|
+
typing.cast(Bot, bot),
|
|
109
|
+
)
|
|
110
|
+
if config_manager.config.llm.tools.report_then_block:
|
|
111
|
+
data = await dm.get_memory(*get_any_id(nonebot_event))
|
|
112
|
+
data.memory_json.messages = []
|
|
113
|
+
await dm.update_memory_data(data)
|
|
114
|
+
await bot.send(
|
|
115
|
+
nonebot_event,
|
|
116
|
+
random.choice(config_manager.config.llm.block_msg),
|
|
117
|
+
)
|
|
118
|
+
await nonebot_matcher.finish()
|
|
119
|
+
else:
|
|
120
|
+
await send_to_admin(
|
|
121
|
+
f"[LLM-Report] Detected non-passed tool call: {function_name}, please feedback this issue to the model provider."
|
|
122
|
+
)
|
|
@@ -3,6 +3,7 @@ import random
|
|
|
3
3
|
import time
|
|
4
4
|
|
|
5
5
|
import nonebot
|
|
6
|
+
from amrita_core.types import Message
|
|
6
7
|
from nonebot import get_driver, logger
|
|
7
8
|
from nonebot.adapters.onebot.v11 import Bot
|
|
8
9
|
from nonebot.adapters.onebot.v11.event import (
|
|
@@ -10,12 +11,12 @@ from nonebot.adapters.onebot.v11.event import (
|
|
|
10
11
|
GroupMessageEvent,
|
|
11
12
|
MessageEvent,
|
|
12
13
|
)
|
|
13
|
-
from nonebot_plugin_orm import get_session
|
|
14
14
|
from typing_extensions import override
|
|
15
15
|
|
|
16
|
+
from amrita.plugins.chat.utils.app import CachedUserDataRepository, MemorySchema
|
|
16
17
|
from amrita.plugins.chat.utils.libchat import usage_enough
|
|
17
18
|
from amrita.plugins.chat.utils.lock import get_group_lock, get_private_lock
|
|
18
|
-
from amrita.plugins.chat.utils.
|
|
19
|
+
from amrita.plugins.chat.utils.sql import TextContent
|
|
19
20
|
from amrita.plugins.perm.API.admin import is_lp_admin
|
|
20
21
|
|
|
21
22
|
from .config import config_manager
|
|
@@ -23,14 +24,12 @@ from .utils.functions import (
|
|
|
23
24
|
get_current_datetime_timestamp,
|
|
24
25
|
synthesize_message,
|
|
25
26
|
)
|
|
26
|
-
from .utils.memory import get_memory_data
|
|
27
|
-
from .utils.models import Message, get_or_create_data
|
|
28
27
|
|
|
29
28
|
nb_config = get_driver().config
|
|
30
29
|
|
|
31
30
|
|
|
32
31
|
class FakeEvent(Event):
|
|
33
|
-
"""
|
|
32
|
+
"""伪事件类,用于模拟用户事件"""
|
|
34
33
|
|
|
35
34
|
user_id: int
|
|
36
35
|
|
|
@@ -54,12 +53,11 @@ async def is_bot_enabled(event: Event) -> bool:
|
|
|
54
53
|
bots = set(nonebot.get_bots().keys())
|
|
55
54
|
if event.get_user_id() in bots: # 多实例下防止冲突
|
|
56
55
|
return False
|
|
57
|
-
if getattr(event, "group_id", None) is not None:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return data.enable
|
|
56
|
+
if (group_id := getattr(event, "group_id", None)) is not None:
|
|
57
|
+
data = await CachedUserDataRepository().get_group_config(
|
|
58
|
+
group_id,
|
|
59
|
+
)
|
|
60
|
+
return data.enable
|
|
63
61
|
return True
|
|
64
62
|
|
|
65
63
|
|
|
@@ -100,6 +98,7 @@ async def should_respond_to_message(event: MessageEvent, bot: Bot) -> bool:
|
|
|
100
98
|
if isinstance(event, GroupMessageEvent)
|
|
101
99
|
else get_private_lock(event.user_id)
|
|
102
100
|
)
|
|
101
|
+
dm = CachedUserDataRepository()
|
|
103
102
|
async with lock:
|
|
104
103
|
message = event.get_message()
|
|
105
104
|
message_text = message.extract_plain_text().strip()
|
|
@@ -130,12 +129,14 @@ async def should_respond_to_message(event: MessageEvent, bot: Bot) -> bool:
|
|
|
130
129
|
rate = config_manager.config.autoreply.probability
|
|
131
130
|
|
|
132
131
|
# 获取记忆数据
|
|
133
|
-
|
|
132
|
+
is_group = bool(getattr(event, "group_id", None))
|
|
133
|
+
ins_id: int = getattr(event, "group_id", event.user_id)
|
|
134
|
+
memory_data: MemorySchema = await dm.get_memory(ins_id, is_group)
|
|
134
135
|
if rand <= rate and (
|
|
135
136
|
config_manager.config.autoreply.global_enable or memory_data.fake_people
|
|
136
137
|
):
|
|
137
|
-
memory_data.
|
|
138
|
-
await
|
|
138
|
+
memory_data.memory_json.time = time.time()
|
|
139
|
+
await dm.update_memory_data(memory_data)
|
|
139
140
|
return True
|
|
140
141
|
# 合成消息内容
|
|
141
142
|
content = await synthesize_message(message, bot)
|
|
@@ -175,35 +176,34 @@ async def should_respond_to_message(event: MessageEvent, bot: Bot) -> bool:
|
|
|
175
176
|
# 生成消息内容并记录到记忆
|
|
176
177
|
content_message = f"[{role}][{Date}][{user_name}({user_id})]说:{content}"
|
|
177
178
|
if (
|
|
178
|
-
not len(memory_data.
|
|
179
|
-
or memory_data.
|
|
180
|
-
or (not memory_data.
|
|
179
|
+
not len(memory_data.memory_json.messages) > 1
|
|
180
|
+
or memory_data.memory_json.messages[-1].role != "user"
|
|
181
|
+
or (not memory_data.memory_json.messages[-1].content)
|
|
181
182
|
):
|
|
182
|
-
memory_data.
|
|
183
|
+
memory_data.memory_json.messages.append(
|
|
183
184
|
Message(
|
|
184
185
|
role="user",
|
|
185
186
|
content=[TextContent(type="text", text=content_message)],
|
|
186
187
|
)
|
|
187
188
|
)
|
|
188
|
-
elif isinstance(memory_data.
|
|
189
|
-
memory_data.
|
|
189
|
+
elif isinstance(memory_data.memory_json.messages[-1].content, str):
|
|
190
|
+
memory_data.memory_json.messages[-1].content = [
|
|
190
191
|
TextContent(
|
|
191
|
-
type="text",
|
|
192
|
+
type="text",
|
|
193
|
+
text=str(memory_data.memory_json.messages[-1].content),
|
|
192
194
|
),
|
|
193
195
|
TextContent(type="text", text=content_message),
|
|
194
196
|
]
|
|
195
197
|
else:
|
|
196
|
-
assert isinstance(memory_data.
|
|
197
|
-
if len(memory_data.
|
|
198
|
-
memory_data.
|
|
198
|
+
assert isinstance(memory_data.memory_json.messages[-1].content, list)
|
|
199
|
+
if len(memory_data.memory_json.messages[-1].content) >= 100:
|
|
200
|
+
memory_data.memory_json.messages[
|
|
199
201
|
-1
|
|
200
|
-
].content = memory_data.
|
|
201
|
-
memory_data.
|
|
202
|
+
].content = memory_data.memory_json.messages[-1].content[-100:]
|
|
203
|
+
memory_data.memory_json.messages[-1].content.append(
|
|
202
204
|
TextContent(type="text", text=content_message)
|
|
203
205
|
)
|
|
204
|
-
|
|
205
|
-
await memory_data.save(event)
|
|
206
|
-
|
|
206
|
+
await dm.update_memory_data(memory_data)
|
|
207
207
|
# 默认返回 False
|
|
208
208
|
return False
|
|
209
209
|
|
|
@@ -219,7 +219,10 @@ async def should_respond_with_usage_check(event: MessageEvent, bot: Bot) -> bool
|
|
|
219
219
|
):
|
|
220
220
|
if event.is_tome():
|
|
221
221
|
with contextlib.suppress(Exception):
|
|
222
|
-
await bot.send(
|
|
222
|
+
await bot.send(
|
|
223
|
+
event,
|
|
224
|
+
random.choice(config_manager.config.usage_limit.limit_msg),
|
|
225
|
+
)
|
|
223
226
|
return False
|
|
224
227
|
return False
|
|
225
228
|
return True
|