ErisPulse 2.11.0.dev0__tar.gz → 2.11.1.dev0__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.
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/.gitignore +0 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/PKG-INFO +1 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/pyproject.toml +9 -8
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/base.py +3 -3
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/cli.py +22 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/config.py +3 -3
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/create.py +367 -6
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/doctor.py +342 -8
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/init.py +23 -12
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/install.py +19 -7
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/language.py +3 -3
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/list.py +3 -3
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/list_remote.py +3 -3
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/run.py +312 -102
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/runtime.py +4 -4
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/self_update.py +3 -3
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/types.py +10 -6
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/uninstall.py +3 -3
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/upgrade.py +9 -5
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/version.py +3 -2
- erispulse-2.11.1.dev0/src/ErisPulse/CLI/constants.py +159 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/i18n/locales/en.py +50 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/i18n/locales/ja.py +50 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/i18n/locales/ru.py +50 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/i18n/locales/zh_cn.py +50 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/i18n/locales/zh_tw.py +50 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/registry.py +1 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/utils/package_manager.py +300 -36
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/utils/runtime_state.py +46 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/utils/scaffold_text.py +81 -2
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/__init__.py +3 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/adapter.py +156 -18
- erispulse-2.11.1.dev0/src/ErisPulse/Core/Bases/adapter_patterns.py +324 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/client.py +5 -4
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/manager.py +93 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/model.py +7 -2
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/module.py +81 -4
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/router.py +20 -20
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/storage.py +2 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/websocket.py +9 -9
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/base.py +1 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/conversation.py +6 -6
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/governance.py +64 -8
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/interaction.py +1 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/message.py +4 -4
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/meta.py +4 -4
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/notice.py +5 -5
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/request.py +3 -3
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/wrapper.py +9 -6
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/__init__.py +4 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/adapter.py +150 -155
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/client.py +7 -7
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/config.py +49 -10
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/connections.py +4 -2
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/constants.py +122 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/i18n/__init__.py +44 -11
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/i18n/locales/en.py +36 -10
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/i18n/locales/ja.py +115 -89
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/i18n/locales/ru.py +115 -89
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/i18n/locales/zh_cn.py +115 -89
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/i18n/locales/zh_tw.py +115 -89
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/lifecycle.py +3 -3
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/logger.py +245 -64
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/module.py +103 -112
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/router.py +30 -26
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/scope.py +7 -7
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/transcript.py +123 -17
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/__init__.py +4 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/finders/bases/finder.py +7 -4
- erispulse-2.11.1.dev0/src/ErisPulse/loaders/_reload_utils.py +249 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/loaders/adapter.py +109 -118
- erispulse-2.11.1.dev0/src/ErisPulse/loaders/bases/__init__.py +3 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/loaders/bases/loader.py +118 -121
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/loaders/module.py +392 -201
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/loaders/plugin_folder.py +31 -48
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/__init__.py +4 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/example_config.py +15 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/file_watcher.py +97 -25
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/frame_config.py +20 -1
- erispulse-2.11.1.dev0/src/ErisPulse/runtime/kernel.py +110 -0
- erispulse-2.11.1.dev0/src/ErisPulse/runtime/plugin_reload.py +358 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/proactive_gc.py +9 -2
- erispulse-2.11.1.dev0/src/ErisPulse/runtime/process_state.py +91 -0
- erispulse-2.11.1.dev0/src/ErisPulse/runtime/reload_ops.py +197 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/sdk_initializer.py +35 -7
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/troubleshoot.py +71 -1
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/sdk.py +186 -64
- erispulse-2.11.0.dev0/src/ErisPulse/CLI/constants.py +0 -76
- erispulse-2.11.0.dev0/src/ErisPulse/loaders/bases/__init__.py +0 -3
- erispulse-2.11.0.dev0/src/ErisPulse/runtime/plugin_reload.py +0 -186
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/LICENSE +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/README.pypi.md +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/commands/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/console.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/hints.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/i18n/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/i18n/locales/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/utils/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/utils/config_wizard.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/utils/display.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/CLI/utils/interactive.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/api_dsl.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/config_schema.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/converter.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/errors.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/i18n_schema.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/kv_builder.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/send_builder.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/send_rules.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Bases/sql_base.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/command.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/command_args.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/command_flow.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/message_builder.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/overrides.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/session_type.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/throttle.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/Event/trace.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/assets/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/assets/error.css +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/assets/error.html +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/assets/root.css +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/assets/root.html +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/di.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/i18n/constants.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/i18n/locales/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/master.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/ownership.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/shadow.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/storage/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/storage/mysql.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/storage/postgres.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/storage/sqlite.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/Core/text_match.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/__main__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/finders/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/finders/adapter.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/finders/bases/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/finders/module.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/loaders/__init__.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/loaders/strategy.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/loaders/strict.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/py.typed +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/config_schema.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/context.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/diagnostics.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/exceptions.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/hints.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/memory.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/owner_cleanup.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/tasks.py +0 -0
- {erispulse-2.11.0.dev0 → erispulse-2.11.1.dev0}/src/ErisPulse/runtime/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: ErisPulse
|
|
3
|
-
Version: 2.11.
|
|
3
|
+
Version: 2.11.1-dev.0
|
|
4
4
|
Summary: Event-driven modular async bot framework — write once, deploy to any platform | 事件驱动的模块化异步机器人框架,一次编写,多平台部署
|
|
5
5
|
Project-URL: Homepage, https://github.com/ErisPulse/ErisPulse
|
|
6
6
|
Project-URL: Documentation, https://www.erisdev.com#docs
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ErisPulse"
|
|
7
|
-
version = "2.11.
|
|
7
|
+
version = "2.11.1-dev.0"
|
|
8
8
|
description = "Event-driven modular async bot framework — write once, deploy to any platform | 事件驱动的模块化异步机器人框架,一次编写,多平台部署"
|
|
9
9
|
readme = "README.pypi.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -223,13 +223,14 @@ ignore = [
|
|
|
223
223
|
|
|
224
224
|
[tool.ruff.lint.per-file-ignores]
|
|
225
225
|
"__init__.py" = ["F401", "PLC0415", "I001"] # 导出式 __init__ 经常按需导入
|
|
226
|
-
#
|
|
227
|
-
#
|
|
228
|
-
"scripts/tools/translate
|
|
229
|
-
"scripts/tools/
|
|
230
|
-
"scripts/tools/
|
|
231
|
-
"scripts/tools/
|
|
232
|
-
"scripts/tools/
|
|
226
|
+
# 旧版生成/翻译脚本:存量风格债渐进收编。TODO: 逐步修复后移除本段;
|
|
227
|
+
# 2026-10 scripts/tools 包化重组,路径由平铺文件名改为包内模块。
|
|
228
|
+
"scripts/tools/translate.py" = ["PERF401", "PTH", "UP035", "B", "RET505", "FURB", "RUF013", "UP008", "A001", "SIM"]
|
|
229
|
+
"scripts/tools/checks/translation.py" = ["PERF401", "PTH", "UP035", "B", "RET505", "FURB", "RUF013", "SIM"]
|
|
230
|
+
"scripts/tools/generators/api_docs.py" = ["PERF401", "PTH", "UP035", "B", "RET505", "FURB", "RUF013", "A001", "SIM", "W29", "E501"]
|
|
231
|
+
"scripts/tools/generators/docs_index.py" = ["PERF401", "PTH", "UP035", "B", "RET505", "FURB", "RUF013", "RUF015", "SIM"]
|
|
232
|
+
"scripts/tools/generators/type_stubs.py" = ["PERF401", "PTH", "UP035", "B", "RET505", "FURB", "RUF013", "ANN", "A001", "PLW0603", "SIM", "W29"]
|
|
233
|
+
"scripts/tools/generators/skills.py" = ["PERF401", "PTH", "UP035", "B", "RET505", "FURB", "RUF013", "SIM", "E501"]
|
|
233
234
|
"tests/**/*.py" = [
|
|
234
235
|
# 断言/夹具相关(测试代码天然模式)
|
|
235
236
|
"S101", "PLR2004", "SLF001", "ARG", "ANN", "PTH",
|
|
@@ -5,7 +5,7 @@ CLI 命令基类
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from abc import ABC, abstractmethod
|
|
8
|
-
from argparse import ArgumentParser
|
|
8
|
+
from argparse import ArgumentParser, Namespace
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class Command(ABC):
|
|
@@ -29,7 +29,7 @@ class Command(ABC):
|
|
|
29
29
|
category: str = "" # 主帮助分组类别标识(project/components/config/misc;空串归入 misc)
|
|
30
30
|
|
|
31
31
|
@abstractmethod
|
|
32
|
-
def add_arguments(self, parser: ArgumentParser):
|
|
32
|
+
def add_arguments(self, parser: ArgumentParser) -> None:
|
|
33
33
|
"""
|
|
34
34
|
添加命令参数
|
|
35
35
|
|
|
@@ -38,7 +38,7 @@ class Command(ABC):
|
|
|
38
38
|
...
|
|
39
39
|
|
|
40
40
|
@abstractmethod
|
|
41
|
-
def execute(self, args):
|
|
41
|
+
def execute(self, args: Namespace) -> None:
|
|
42
42
|
"""
|
|
43
43
|
执行命令
|
|
44
44
|
|
|
@@ -264,6 +264,24 @@ class CLI:
|
|
|
264
264
|
)
|
|
265
265
|
)
|
|
266
266
|
|
|
267
|
+
@staticmethod
|
|
268
|
+
def _ensure_utf8_stdio() -> None:
|
|
269
|
+
"""
|
|
270
|
+
将标准流重配置为 UTF-8(Windows GBK 代码页兜底)
|
|
271
|
+
|
|
272
|
+
中文 Windows 控制台默认 GBK 编码,非 Rich 的裸 print 与子进程管道
|
|
273
|
+
输出遇到非 GBK 字符会 ``UnicodeEncodeError``——CLI 入口统一兜底,
|
|
274
|
+
一次性消灭该类偶发乱码/崩溃(历史点状爆发:翻译脚本、PowerShell BOM)。
|
|
275
|
+
仅在流支持 reconfigure 时生效(Python 3.7+ 的 io.TextIOWrapper)。
|
|
276
|
+
"""
|
|
277
|
+
for stream_name in ("stdout", "stderr", "stdin"):
|
|
278
|
+
try:
|
|
279
|
+
stream = getattr(sys, stream_name, None)
|
|
280
|
+
if stream is not None and hasattr(stream, "reconfigure"):
|
|
281
|
+
stream.reconfigure(encoding="utf-8")
|
|
282
|
+
except Exception:
|
|
283
|
+
pass
|
|
284
|
+
|
|
267
285
|
def _check_command_typo(self) -> None:
|
|
268
286
|
"""
|
|
269
287
|
在 argparse 解析之前检查命令拼写
|
|
@@ -351,7 +369,7 @@ class CLI:
|
|
|
351
369
|
)
|
|
352
370
|
i18n.increment_lang_hint()
|
|
353
371
|
|
|
354
|
-
def run(self):
|
|
372
|
+
def run(self) -> None:
|
|
355
373
|
"""
|
|
356
374
|
运行 CLI
|
|
357
375
|
|
|
@@ -361,6 +379,9 @@ class CLI:
|
|
|
361
379
|
# 在 argparse 之前检查命令拼写(argparse 的 choices 验证会直接报错退出)
|
|
362
380
|
self._check_command_typo()
|
|
363
381
|
|
|
382
|
+
# Windows GBK 代码页兜底:标准流统一 UTF-8(入口级一次性修复)
|
|
383
|
+
self._ensure_utf8_stdio()
|
|
384
|
+
|
|
364
385
|
args, unknown = self.parser.parse_known_args()
|
|
365
386
|
args._unknown_args = unknown
|
|
366
387
|
|
|
@@ -5,7 +5,7 @@ Config 命令实现
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import json
|
|
8
|
-
from argparse import ArgumentParser
|
|
8
|
+
from argparse import ArgumentParser, Namespace
|
|
9
9
|
|
|
10
10
|
from rich.box import SIMPLE
|
|
11
11
|
from rich.prompt import Prompt
|
|
@@ -36,7 +36,7 @@ class ConfigCommand(Command):
|
|
|
36
36
|
aliases = ["cfg", "conf"]
|
|
37
37
|
category = "config"
|
|
38
38
|
|
|
39
|
-
def add_arguments(self, parser: ArgumentParser):
|
|
39
|
+
def add_arguments(self, parser: ArgumentParser) -> None:
|
|
40
40
|
parser.add_argument(
|
|
41
41
|
"name",
|
|
42
42
|
nargs="?",
|
|
@@ -54,7 +54,7 @@ class ConfigCommand(Command):
|
|
|
54
54
|
help=i18n.t("cli.config.json_help"),
|
|
55
55
|
)
|
|
56
56
|
|
|
57
|
-
def execute(self, args):
|
|
57
|
+
def execute(self, args: Namespace) -> None:
|
|
58
58
|
from ErisPulse import config
|
|
59
59
|
|
|
60
60
|
targets = config_wizard.load_config_targets()
|
|
@@ -7,7 +7,7 @@ Create 命令实现
|
|
|
7
7
|
import datetime
|
|
8
8
|
import shutil
|
|
9
9
|
import sys
|
|
10
|
-
from argparse import ArgumentParser
|
|
10
|
+
from argparse import ArgumentParser, Namespace
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
|
|
13
13
|
from rich.prompt import IntPrompt, Prompt
|
|
@@ -555,7 +555,7 @@ class {name}(BaseAdapter):
|
|
|
555
555
|
raw = json.loads(data)
|
|
556
556
|
event = self.convert(raw)
|
|
557
557
|
if event:
|
|
558
|
-
await self.
|
|
558
|
+
await self.emit_event(event)
|
|
559
559
|
except Exception as e:
|
|
560
560
|
self.logger.warning("{text[adapter.log.connection_lost]}")
|
|
561
561
|
finally:
|
|
@@ -595,6 +595,351 @@ class {name}(BaseAdapter):
|
|
|
595
595
|
"""
|
|
596
596
|
|
|
597
597
|
|
|
598
|
+
_ADAPTER_CORE_POLLING = """import asyncio
|
|
599
|
+
from dataclasses import dataclass, field
|
|
600
|
+
from typing import ClassVar
|
|
601
|
+
from ErisPulse import PollingAdapter, BaseConfig, BaseI18n, I18nKey, client
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
class {name}(PollingAdapter):
|
|
605
|
+
\"\"\"
|
|
606
|
+
{text[adapter.polling.doc]}
|
|
607
|
+
\"\"\"
|
|
608
|
+
|
|
609
|
+
# 依赖声明(可选,ErisPulse 2.9.0+):
|
|
610
|
+
# depends = {{"adapters": [], "modules": []}} # 硬依赖:缺失时跳过启动
|
|
611
|
+
# optional_modules = [] # 软依赖:就绪/丢失时收到
|
|
612
|
+
# # on_dependency_ready/lost 回调
|
|
613
|
+
depends: ClassVar[dict] = {{}}
|
|
614
|
+
optional_modules: ClassVar[list] = []
|
|
615
|
+
|
|
616
|
+
# 声明所需最低 SDK 版本:不满足时框架在加载期明确报错并跳过本适配器(可选)
|
|
617
|
+
min_sdk_version = "{min_sdk}"
|
|
618
|
+
|
|
619
|
+
# 轮询间隔(秒):声明了下方 ConfigClass.poll_interval 字段后以配置值为准
|
|
620
|
+
poll_interval = 5.0
|
|
621
|
+
|
|
622
|
+
# {text[adapter.config_hint]}
|
|
623
|
+
@dataclass
|
|
624
|
+
class ConfigClass(BaseConfig):
|
|
625
|
+
\"\"\"
|
|
626
|
+
{text[adapter.config_doc]}
|
|
627
|
+
|
|
628
|
+
:ivar poll_interval: 轮询间隔秒数(热更新生效)
|
|
629
|
+
\"\"\"
|
|
630
|
+
|
|
631
|
+
endpoint: str = field(
|
|
632
|
+
default="https://api.example.com",
|
|
633
|
+
metadata={{
|
|
634
|
+
"description": {{"i18n": "adapter.{name}.endpoint", "default": "Platform API Endpoint"}},
|
|
635
|
+
"required": False,
|
|
636
|
+
"ui": {{"widget": "text", "group": "connection", "order": 1}},
|
|
637
|
+
}},
|
|
638
|
+
)
|
|
639
|
+
token: str = field(
|
|
640
|
+
default="",
|
|
641
|
+
metadata={{
|
|
642
|
+
"description": {{"i18n": "adapter.{name}.token", "default": "Platform Token"}},
|
|
643
|
+
"required": True,
|
|
644
|
+
"secret": True,
|
|
645
|
+
"ui": {{"widget": "password", "group": "basic", "order": 2}},
|
|
646
|
+
}},
|
|
647
|
+
)
|
|
648
|
+
poll_interval: float = field(
|
|
649
|
+
default=5.0,
|
|
650
|
+
metadata={{
|
|
651
|
+
"description": {{"i18n": "adapter.{name}.poll_interval", "default": "Polling interval (seconds)"}},
|
|
652
|
+
"required": False,
|
|
653
|
+
"min": 0.1,
|
|
654
|
+
"ui": {{"widget": "number", "group": "connection", "order": 3}},
|
|
655
|
+
}},
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
# {text[adapter.i18n_hint]}
|
|
659
|
+
class I18nClass(BaseI18n):
|
|
660
|
+
\"\"\"{name} translation keys\"\"\"
|
|
661
|
+
|
|
662
|
+
endpoint: I18nKey = I18nKey(
|
|
663
|
+
key="adapter.{name}.endpoint",
|
|
664
|
+
default="Platform API Endpoint",
|
|
665
|
+
zh_CN="平台 API 地址",
|
|
666
|
+
en="Platform API Endpoint",
|
|
667
|
+
ja="APIアドレス",
|
|
668
|
+
ru="API адрес",
|
|
669
|
+
zh_TW="API 位址",
|
|
670
|
+
)
|
|
671
|
+
token: I18nKey = I18nKey(
|
|
672
|
+
key="adapter.{name}.token",
|
|
673
|
+
default="Platform Token",
|
|
674
|
+
zh_CN="平台 Token",
|
|
675
|
+
en="Platform Token",
|
|
676
|
+
ja="トークン",
|
|
677
|
+
ru="Токен",
|
|
678
|
+
zh_TW="權杖",
|
|
679
|
+
)
|
|
680
|
+
poll_interval: I18nKey = I18nKey(
|
|
681
|
+
key="adapter.{name}.poll_interval",
|
|
682
|
+
default="Polling interval (seconds)",
|
|
683
|
+
zh_CN="轮询间隔(秒)",
|
|
684
|
+
en="Polling interval (seconds)",
|
|
685
|
+
ja="ポーリング間隔(秒)",
|
|
686
|
+
ru="Интервал опроса (сек)",
|
|
687
|
+
zh_TW="輪詢間隔(秒)",
|
|
688
|
+
)
|
|
689
|
+
|
|
690
|
+
def __init__(self, sdk=None):
|
|
691
|
+
super().__init__(sdk=sdk)
|
|
692
|
+
self.logger = self._get_logger()
|
|
693
|
+
self.converter = self._setup_converter()
|
|
694
|
+
|
|
695
|
+
def on_config_update(self, old_config, new_config):
|
|
696
|
+
\"\"\"Called when adapter config hot-reloads\"\"\"
|
|
697
|
+
self.logger.info("{text[adapter.log.config_updated]}")
|
|
698
|
+
|
|
699
|
+
def _setup_converter(self):
|
|
700
|
+
from .Converter import {converter_name}
|
|
701
|
+
return {converter_name}()
|
|
702
|
+
|
|
703
|
+
# start() / shutdown() 由 PollingAdapter 基类管理:
|
|
704
|
+
# start 拉起带指数退避的轮询循环后立即返回;shutdown 时框架按 owner 自动取消
|
|
705
|
+
|
|
706
|
+
async def fetch_events(self):
|
|
707
|
+
\"\"\"
|
|
708
|
+
{text[adapter.polling.fetch_doc]}
|
|
709
|
+
\"\"\"
|
|
710
|
+
cfg = self.cfg
|
|
711
|
+
# TODO: 替换为平台的增量拉取接口(如 Telegram getUpdates,配合 offset 去重)
|
|
712
|
+
resp = await client.get(
|
|
713
|
+
f"{{cfg.endpoint}}/getUpdates",
|
|
714
|
+
headers={{"Authorization": "Bearer " + cfg.token}},
|
|
715
|
+
)
|
|
716
|
+
data = await resp.json()
|
|
717
|
+
return data.get("events", [])
|
|
718
|
+
|
|
719
|
+
def convert_one(self, raw):
|
|
720
|
+
\"\"\"
|
|
721
|
+
{text[adapter.polling.convert_one_doc]}
|
|
722
|
+
\"\"\"
|
|
723
|
+
# TODO: 按平台事件结构调整(Converter 模板已给出 message 型骨架)
|
|
724
|
+
return self.converter.convert(raw)
|
|
725
|
+
|
|
726
|
+
class Send(PollingAdapter.Send):
|
|
727
|
+
\"\"\"
|
|
728
|
+
{text[adapter.dsl.send_doc]}
|
|
729
|
+
\"\"\"
|
|
730
|
+
|
|
731
|
+
def Raw_ob12(self, message, **kwargs):
|
|
732
|
+
async def _do_send():
|
|
733
|
+
segments = self._apply_modifiers(message)
|
|
734
|
+
return await self._adapter.call_api(
|
|
735
|
+
endpoint="/send_message",
|
|
736
|
+
message=segments,
|
|
737
|
+
**self.send_context,
|
|
738
|
+
**kwargs,
|
|
739
|
+
)
|
|
740
|
+
return asyncio.create_task(_do_send())
|
|
741
|
+
|
|
742
|
+
# {text[adapter.dsl.send_std_methods_hint]}
|
|
743
|
+
# {text[adapter.dsl.send_override_hint]}
|
|
744
|
+
# def Text(self, text: str):
|
|
745
|
+
# return self.Raw_ob12([{{"type": "text", "data": {{"text": text}}}}])
|
|
746
|
+
|
|
747
|
+
# {text[adapter.dsl.send_extra_methods_hint]}
|
|
748
|
+
# def Sticker(self, sticker_id: str):
|
|
749
|
+
# return self.Raw_ob12([{{"type": "sticker", "data": {{"id": sticker_id}}}}])
|
|
750
|
+
|
|
751
|
+
# Request / Api 内部类继承基类默认实现即可;如需平台特定逻辑可按需覆盖
|
|
752
|
+
|
|
753
|
+
async def call_api(self, endpoint: str, **params):
|
|
754
|
+
\"\"\"Call platform API\"\"\"
|
|
755
|
+
cfg = self.cfg
|
|
756
|
+
headers = {{"Authorization": "Bearer " + cfg.token}}
|
|
757
|
+
url = cfg.endpoint + endpoint
|
|
758
|
+
|
|
759
|
+
try:
|
|
760
|
+
resp = await client.post(
|
|
761
|
+
url,
|
|
762
|
+
json=params,
|
|
763
|
+
headers=headers,
|
|
764
|
+
timeout=30,
|
|
765
|
+
max_retries=2,
|
|
766
|
+
)
|
|
767
|
+
result = await resp.json()
|
|
768
|
+
return self.make_response(
|
|
769
|
+
data=result.get("data"),
|
|
770
|
+
message_id=result.get("data", {{}}).get("message_id", ""),
|
|
771
|
+
raw=result,
|
|
772
|
+
)
|
|
773
|
+
except Exception as e:
|
|
774
|
+
self.logger.error(("{text[adapter.log.api_call_failed]}").format(error=e))
|
|
775
|
+
return self.make_error(message=str(e))
|
|
776
|
+
"""
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
_ADAPTER_CORE_WEBHOOK = """import asyncio
|
|
780
|
+
from dataclasses import dataclass, field
|
|
781
|
+
from typing import ClassVar
|
|
782
|
+
from ErisPulse import WebhookAdapter, BaseConfig, BaseI18n, I18nKey, client
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
class {name}(WebhookAdapter):
|
|
786
|
+
\"\"\"
|
|
787
|
+
{text[adapter.webhook.doc]}
|
|
788
|
+
\"\"\"
|
|
789
|
+
|
|
790
|
+
# 依赖声明(可选,ErisPulse 2.9.0+):
|
|
791
|
+
# depends = {{"adapters": [], "modules": []}} # 硬依赖:缺失时跳过启动
|
|
792
|
+
# optional_modules = [] # 软依赖:就绪/丢失时收到
|
|
793
|
+
# # on_dependency_ready/lost 回调
|
|
794
|
+
depends: ClassVar[dict] = {{}}
|
|
795
|
+
optional_modules: ClassVar[list] = []
|
|
796
|
+
|
|
797
|
+
# 声明所需最低 SDK 版本:不满足时框架在加载期明确报错并跳过本适配器(可选)
|
|
798
|
+
min_sdk_version = "{min_sdk}"
|
|
799
|
+
|
|
800
|
+
# {text[adapter.config_hint]}
|
|
801
|
+
@dataclass
|
|
802
|
+
class ConfigClass(BaseConfig):
|
|
803
|
+
\"\"\"
|
|
804
|
+
{text[adapter.config_doc]}
|
|
805
|
+
\"\"\"
|
|
806
|
+
|
|
807
|
+
endpoint: str = field(
|
|
808
|
+
default="https://api.example.com",
|
|
809
|
+
metadata={{
|
|
810
|
+
"description": {{"i18n": "adapter.{name}.endpoint", "default": "Platform API Endpoint"}},
|
|
811
|
+
"required": False,
|
|
812
|
+
"ui": {{"widget": "text", "group": "connection", "order": 1}},
|
|
813
|
+
}},
|
|
814
|
+
)
|
|
815
|
+
token: str = field(
|
|
816
|
+
default="",
|
|
817
|
+
metadata={{
|
|
818
|
+
"description": {{"i18n": "adapter.{name}.token", "default": "Verify Token (empty = accept all)"}},
|
|
819
|
+
"required": False,
|
|
820
|
+
"secret": True,
|
|
821
|
+
"ui": {{"widget": "password", "group": "basic", "order": 2}},
|
|
822
|
+
}},
|
|
823
|
+
)
|
|
824
|
+
|
|
825
|
+
# {text[adapter.i18n_hint]}
|
|
826
|
+
class I18nClass(BaseI18n):
|
|
827
|
+
\"\"\"{name} translation keys\"\"\"
|
|
828
|
+
|
|
829
|
+
endpoint: I18nKey = I18nKey(
|
|
830
|
+
key="adapter.{name}.endpoint",
|
|
831
|
+
default="Platform API Endpoint",
|
|
832
|
+
zh_CN="平台 API 地址",
|
|
833
|
+
en="Platform API Endpoint",
|
|
834
|
+
ja="APIアドレス",
|
|
835
|
+
ru="API адрес",
|
|
836
|
+
zh_TW="API 位址",
|
|
837
|
+
)
|
|
838
|
+
token: I18nKey = I18nKey(
|
|
839
|
+
key="adapter.{name}.token",
|
|
840
|
+
default="Verify Token (empty = accept all)",
|
|
841
|
+
zh_CN="校验 Token(留空放行全部请求)",
|
|
842
|
+
en="Verify Token (empty = accept all)",
|
|
843
|
+
ja="検証トークン(空なら全許可)",
|
|
844
|
+
ru="Токен проверки (пусто = разрешить все)",
|
|
845
|
+
zh_TW="校驗權杖(留空放行全部請求)",
|
|
846
|
+
)
|
|
847
|
+
|
|
848
|
+
def __init__(self, sdk=None):
|
|
849
|
+
super().__init__(sdk=sdk)
|
|
850
|
+
self.logger = self._get_logger()
|
|
851
|
+
self.converter = self._setup_converter()
|
|
852
|
+
|
|
853
|
+
def on_config_update(self, old_config, new_config):
|
|
854
|
+
\"\"\"Called when adapter config hot-reloads\"\"\"
|
|
855
|
+
self.logger.info("{text[adapter.log.config_updated]}")
|
|
856
|
+
|
|
857
|
+
def _setup_converter(self):
|
|
858
|
+
from .Converter import {converter_name}
|
|
859
|
+
return {converter_name}()
|
|
860
|
+
|
|
861
|
+
# start() / shutdown() 由 WebhookAdapter 基类管理:
|
|
862
|
+
# start 在框架 router 上注册 POST /{entry_key}/webhook 接收路由(owner 归属,
|
|
863
|
+
# 卸载自动清理);回调地址经 sdk.adapter.get_connection_info("{entry_key}") 查询
|
|
864
|
+
|
|
865
|
+
def verify_request(self, request) -> bool:
|
|
866
|
+
\"\"\"
|
|
867
|
+
{text[adapter.webhook.verify_doc]}
|
|
868
|
+
\"\"\"
|
|
869
|
+
cfg = self.cfg
|
|
870
|
+
if not cfg.token:
|
|
871
|
+
return True
|
|
872
|
+
# TODO: 按平台校验方式调整(签名头 / query token / 时间戳防重放等)
|
|
873
|
+
auth = request.headers.get("authorization", "")
|
|
874
|
+
return auth == f"Bearer {{cfg.token}}"
|
|
875
|
+
|
|
876
|
+
def convert(self, payload):
|
|
877
|
+
\"\"\"
|
|
878
|
+
{text[adapter.webhook.convert_doc]}
|
|
879
|
+
\"\"\"
|
|
880
|
+
# TODO: 按平台回调载荷结构调整(Converter 模板已给出 message 型骨架)
|
|
881
|
+
return self.converter.convert(payload)
|
|
882
|
+
|
|
883
|
+
class Send(WebhookAdapter.Send):
|
|
884
|
+
\"\"\"
|
|
885
|
+
{text[adapter.dsl.send_doc]}
|
|
886
|
+
\"\"\"
|
|
887
|
+
|
|
888
|
+
def Raw_ob12(self, message, **kwargs):
|
|
889
|
+
async def _do_send():
|
|
890
|
+
segments = self._apply_modifiers(message)
|
|
891
|
+
return await self._adapter.call_api(
|
|
892
|
+
endpoint="/send_message",
|
|
893
|
+
message=segments,
|
|
894
|
+
**self.send_context,
|
|
895
|
+
**kwargs,
|
|
896
|
+
)
|
|
897
|
+
return asyncio.create_task(_do_send())
|
|
898
|
+
|
|
899
|
+
# {text[adapter.dsl.send_std_methods_hint]}
|
|
900
|
+
# {text[adapter.dsl.send_override_hint]}
|
|
901
|
+
# def Text(self, text: str):
|
|
902
|
+
# return self.Raw_ob12([{{"type": "text", "data": {{"text": text}}}}])
|
|
903
|
+
|
|
904
|
+
# {text[adapter.dsl.send_extra_methods_hint]}
|
|
905
|
+
# def Sticker(self, sticker_id: str):
|
|
906
|
+
# return self.Raw_ob12([{{"type": "sticker", "data": {{"id": sticker_id}}}}])
|
|
907
|
+
|
|
908
|
+
# Request / Api 内部类继承基类默认实现即可;如需平台特定逻辑可按需覆盖
|
|
909
|
+
|
|
910
|
+
async def call_api(self, endpoint: str, **params):
|
|
911
|
+
\"\"\"Call platform API\"\"\"
|
|
912
|
+
cfg = self.cfg
|
|
913
|
+
headers = {{"Authorization": "Bearer " + cfg.token}}
|
|
914
|
+
url = cfg.endpoint + endpoint
|
|
915
|
+
|
|
916
|
+
try:
|
|
917
|
+
resp = await client.post(
|
|
918
|
+
url,
|
|
919
|
+
json=params,
|
|
920
|
+
headers=headers,
|
|
921
|
+
timeout=30,
|
|
922
|
+
max_retries=2,
|
|
923
|
+
)
|
|
924
|
+
result = await resp.json()
|
|
925
|
+
return self.make_response(
|
|
926
|
+
data=result.get("data"),
|
|
927
|
+
message_id=result.get("data", {{}}).get("message_id", ""),
|
|
928
|
+
raw=result,
|
|
929
|
+
)
|
|
930
|
+
except Exception as e:
|
|
931
|
+
self.logger.error(("{text[adapter.log.api_call_failed]}").format(error=e))
|
|
932
|
+
return self.make_error(message=str(e))
|
|
933
|
+
"""
|
|
934
|
+
|
|
935
|
+
# 适配器 --template 选项 → 核心模板映射(ws-server 保持既有默认行为)
|
|
936
|
+
_ADAPTER_CORE_TEMPLATES = {
|
|
937
|
+
"ws-server": _ADAPTER_CORE,
|
|
938
|
+
"polling": _ADAPTER_CORE_POLLING,
|
|
939
|
+
"webhook": _ADAPTER_CORE_WEBHOOK,
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
|
|
598
943
|
_ADAPTER_CONVERTER = """\"\"\"
|
|
599
944
|
{text[adapter.converter_doc]}
|
|
600
945
|
\"\"\"
|
|
@@ -796,7 +1141,7 @@ class CreateCommand(Command):
|
|
|
796
1141
|
aliases = ["c", "new"]
|
|
797
1142
|
category = "project"
|
|
798
1143
|
|
|
799
|
-
def add_arguments(self, parser: ArgumentParser):
|
|
1144
|
+
def add_arguments(self, parser: ArgumentParser) -> None:
|
|
800
1145
|
parser.add_argument(
|
|
801
1146
|
"create_type",
|
|
802
1147
|
nargs="?",
|
|
@@ -828,8 +1173,14 @@ class CreateCommand(Command):
|
|
|
828
1173
|
default=False,
|
|
829
1174
|
help=i18n.t("cli.create.local_help"),
|
|
830
1175
|
)
|
|
1176
|
+
parser.add_argument(
|
|
1177
|
+
"--template",
|
|
1178
|
+
choices=list(_ADAPTER_CORE_TEMPLATES),
|
|
1179
|
+
default="ws-server",
|
|
1180
|
+
help=i18n.t("cli.create.adapter_template_help"),
|
|
1181
|
+
)
|
|
831
1182
|
|
|
832
|
-
def execute(self, args):
|
|
1183
|
+
def execute(self, args: Namespace) -> None:
|
|
833
1184
|
create_type = getattr(args, "create_type", None)
|
|
834
1185
|
if not create_type:
|
|
835
1186
|
create_type = self._interactive_select_type()
|
|
@@ -1243,13 +1594,15 @@ class CreateCommand(Command):
|
|
|
1243
1594
|
|
|
1244
1595
|
converter_name = _to_converter_name(name)
|
|
1245
1596
|
entry_key = _camel_to_snake(name)
|
|
1597
|
+
template = getattr(args, "template", None) or "ws-server"
|
|
1598
|
+
core_template = _ADAPTER_CORE_TEMPLATES[template]
|
|
1246
1599
|
|
|
1247
1600
|
(plugin_dir / "__init__.py").write_text(
|
|
1248
1601
|
_ADAPTER_INIT.format(name=name, converter_name=converter_name),
|
|
1249
1602
|
encoding="utf-8",
|
|
1250
1603
|
)
|
|
1251
1604
|
(plugin_dir / "Core.py").write_text(
|
|
1252
|
-
|
|
1605
|
+
core_template.format(
|
|
1253
1606
|
name=name,
|
|
1254
1607
|
converter_name=converter_name,
|
|
1255
1608
|
entry_key=entry_key,
|
|
@@ -1272,6 +1625,9 @@ class CreateCommand(Command):
|
|
|
1272
1625
|
console.print(
|
|
1273
1626
|
f"[success] {i18n.t('cli.create.adapter_created', name=name)}[/]"
|
|
1274
1627
|
)
|
|
1628
|
+
console.print(
|
|
1629
|
+
f"[dim] {i18n.t('cli.create.template_used', template=i18n.t('cli.create.template_' + template.replace('-', '_')))}[/]"
|
|
1630
|
+
)
|
|
1275
1631
|
console.print()
|
|
1276
1632
|
console.print(Text(i18n.t("cli.create.local_structure"), style="bold"))
|
|
1277
1633
|
console.print(" plugins/")
|
|
@@ -1328,6 +1684,8 @@ class CreateCommand(Command):
|
|
|
1328
1684
|
|
|
1329
1685
|
converter_name = _to_converter_name(name)
|
|
1330
1686
|
entry_key = _camel_to_snake(name)
|
|
1687
|
+
template = getattr(args, "template", None) or "ws-server"
|
|
1688
|
+
core_template = _ADAPTER_CORE_TEMPLATES[template]
|
|
1331
1689
|
output = Path(args.output)
|
|
1332
1690
|
project_dir = output / name
|
|
1333
1691
|
|
|
@@ -1347,7 +1705,7 @@ class CreateCommand(Command):
|
|
|
1347
1705
|
encoding="utf-8",
|
|
1348
1706
|
)
|
|
1349
1707
|
(pkg_dir / "Core.py").write_text(
|
|
1350
|
-
|
|
1708
|
+
core_template.format(
|
|
1351
1709
|
name=name,
|
|
1352
1710
|
converter_name=converter_name,
|
|
1353
1711
|
entry_key=entry_key,
|
|
@@ -1393,6 +1751,9 @@ class CreateCommand(Command):
|
|
|
1393
1751
|
console.print(
|
|
1394
1752
|
f"[success] {i18n.t('cli.create.adapter_created', name=name)}[/]"
|
|
1395
1753
|
)
|
|
1754
|
+
console.print(
|
|
1755
|
+
f"[dim] {i18n.t('cli.create.template_used', template=i18n.t('cli.create.template_' + template.replace('-', '_')))}[/]"
|
|
1756
|
+
)
|
|
1396
1757
|
console.print()
|
|
1397
1758
|
console.print(Text(i18n.t("cli.create.project_structure"), style="bold"))
|
|
1398
1759
|
console.print(f" {name}/")
|