ErisPulse 2.5.2.dev0__tar.gz → 2.5.2.dev1__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.
Files changed (179) hide show
  1. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/PKG-INFO +1 -1
  2. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/pyproject.toml +1 -1
  3. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/run.py +24 -20
  4. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/run.pyi +8 -2
  5. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/en.py +1 -0
  6. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/ja.py +1 -0
  7. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/ru.py +1 -0
  8. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/zh_cn.py +1 -0
  9. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/zh_tw.py +1 -0
  10. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/utils/package_manager.py +4 -45
  11. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/utils/package_manager.pyi +0 -3
  12. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/__init__.py +33 -26
  13. erispulse-2.5.2.dev1/src/ErisPulse/Core/Event/__init__.pyi +26 -0
  14. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/command.py +43 -12
  15. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/command.pyi +1 -1
  16. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/constants.py +4 -0
  17. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/en.py +1 -0
  18. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/ja.py +1 -0
  19. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/ru.py +1 -0
  20. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/zh_cn.py +1 -0
  21. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/zh_tw.py +1 -0
  22. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/sdk.py +16 -31
  23. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/sdk.pyi +6 -3
  24. erispulse-2.5.2.dev0/src/ErisPulse/Core/Event/__init__.pyi +0 -26
  25. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/.gitignore +0 -0
  26. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/LICENSE +0 -0
  27. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/README.md +0 -0
  28. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/__init__.py +0 -0
  29. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/__init__.pyi +0 -0
  30. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/base.py +0 -0
  31. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/base.pyi +0 -0
  32. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/cli.py +0 -0
  33. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/cli.pyi +0 -0
  34. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/__init__.py +0 -0
  35. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/__init__.pyi +0 -0
  36. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/create.py +0 -0
  37. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/create.pyi +0 -0
  38. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/init.py +0 -0
  39. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/init.pyi +0 -0
  40. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/install.py +0 -0
  41. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/install.pyi +0 -0
  42. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/language.py +0 -0
  43. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/language.pyi +0 -0
  44. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/list.py +0 -0
  45. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/list.pyi +0 -0
  46. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/list_remote.py +0 -0
  47. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/list_remote.pyi +0 -0
  48. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/self_update.py +0 -0
  49. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/self_update.pyi +0 -0
  50. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/uninstall.py +0 -0
  51. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/uninstall.pyi +0 -0
  52. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/upgrade.py +0 -0
  53. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/commands/upgrade.pyi +0 -0
  54. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/console.py +0 -0
  55. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/console.pyi +0 -0
  56. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/__init__.py +0 -0
  57. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/__init__.pyi +0 -0
  58. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/__init__.py +0 -0
  59. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/__init__.pyi +0 -0
  60. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/en.pyi +0 -0
  61. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/ja.pyi +0 -0
  62. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/ru.pyi +0 -0
  63. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/zh_cn.pyi +0 -0
  64. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/i18n/locales/zh_tw.pyi +0 -0
  65. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/registry.py +0 -0
  66. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/registry.pyi +0 -0
  67. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/utils/__init__.py +0 -0
  68. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/utils/__init__.pyi +0 -0
  69. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/utils/display.py +0 -0
  70. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/utils/display.pyi +0 -0
  71. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/utils/file_watcher.py +0 -0
  72. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/CLI/utils/file_watcher.pyi +0 -0
  73. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/__init__.py +0 -0
  74. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/__init__.pyi +0 -0
  75. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/adapter.py +0 -0
  76. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/adapter.pyi +0 -0
  77. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/client.py +0 -0
  78. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/client.pyi +0 -0
  79. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/errors.py +0 -0
  80. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/errors.pyi +0 -0
  81. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/manager.py +0 -0
  82. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/manager.pyi +0 -0
  83. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/module.py +0 -0
  84. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/module.pyi +0 -0
  85. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/router.py +0 -0
  86. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/router.pyi +0 -0
  87. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/storage.py +0 -0
  88. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/storage.pyi +0 -0
  89. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/websocket.py +0 -0
  90. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Bases/websocket.pyi +0 -0
  91. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/base.py +0 -0
  92. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/base.pyi +0 -0
  93. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/message.py +0 -0
  94. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/message.pyi +0 -0
  95. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/message_builder.py +0 -0
  96. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/message_builder.pyi +0 -0
  97. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/meta.py +0 -0
  98. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/meta.pyi +0 -0
  99. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/notice.py +0 -0
  100. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/notice.pyi +0 -0
  101. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/request.py +0 -0
  102. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/request.pyi +0 -0
  103. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/session_type.py +0 -0
  104. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/session_type.pyi +0 -0
  105. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/wrapper.py +0 -0
  106. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/Event/wrapper.pyi +0 -0
  107. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/__init__.py +0 -0
  108. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/__init__.pyi +0 -0
  109. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/adapter.py +0 -0
  110. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/adapter.pyi +0 -0
  111. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/client.py +0 -0
  112. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/client.pyi +0 -0
  113. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/config.py +0 -0
  114. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/config.pyi +0 -0
  115. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/constants.pyi +0 -0
  116. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/__init__.py +0 -0
  117. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/__init__.pyi +0 -0
  118. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/constants.py +0 -0
  119. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/constants.pyi +0 -0
  120. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/__init__.py +0 -0
  121. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/__init__.pyi +0 -0
  122. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/en.pyi +0 -0
  123. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/ja.pyi +0 -0
  124. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/ru.pyi +0 -0
  125. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/zh_cn.pyi +0 -0
  126. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/i18n/locales/zh_tw.pyi +0 -0
  127. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/lifecycle.py +0 -0
  128. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/lifecycle.pyi +0 -0
  129. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/logger.py +0 -0
  130. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/logger.pyi +0 -0
  131. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/module.py +0 -0
  132. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/module.pyi +0 -0
  133. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/router.py +0 -0
  134. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/router.pyi +0 -0
  135. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/storage.py +0 -0
  136. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/Core/storage.pyi +0 -0
  137. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/__init__.py +0 -0
  138. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/__init__.pyi +0 -0
  139. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/__main__.py +0 -0
  140. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/__main__.pyi +0 -0
  141. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/finders/__init__.py +0 -0
  142. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/finders/__init__.pyi +0 -0
  143. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/finders/adapter.py +0 -0
  144. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/finders/adapter.pyi +0 -0
  145. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/finders/bases/__init__.py +0 -0
  146. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/finders/bases/__init__.pyi +0 -0
  147. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/finders/bases/finder.py +0 -0
  148. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/finders/bases/finder.pyi +0 -0
  149. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/finders/module.py +0 -0
  150. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/finders/module.pyi +0 -0
  151. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/__init__.py +0 -0
  152. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/__init__.pyi +0 -0
  153. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/adapter.py +0 -0
  154. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/adapter.pyi +0 -0
  155. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/bases/__init__.py +0 -0
  156. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/bases/__init__.pyi +0 -0
  157. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/bases/loader.py +0 -0
  158. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/bases/loader.pyi +0 -0
  159. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/module.py +0 -0
  160. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/module.pyi +0 -0
  161. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/strategy.py +0 -0
  162. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/strategy.pyi +0 -0
  163. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/strict.py +0 -0
  164. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/loaders/strict.pyi +0 -0
  165. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/runtime/__init__.py +0 -0
  166. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/runtime/__init__.pyi +0 -0
  167. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/runtime/config_schema.py +0 -0
  168. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/runtime/config_schema.pyi +0 -0
  169. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/runtime/context.py +0 -0
  170. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/runtime/context.pyi +0 -0
  171. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/runtime/exceptions.py +0 -0
  172. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/runtime/exceptions.pyi +0 -0
  173. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/runtime/frame_config.py +0 -0
  174. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/runtime/frame_config.pyi +0 -0
  175. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/web_status/4xx.png +0 -0
  176. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/web_status/5xx.png +0 -0
  177. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/web_status/__init__.py +0 -0
  178. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/web_status/__init__.pyi +0 -0
  179. {erispulse-2.5.2.dev0 → erispulse-2.5.2.dev1}/src/ErisPulse/web_status/unknow.png +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ErisPulse
3
- Version: 2.5.2.dev0
3
+ Version: 2.5.2.dev1
4
4
  Summary: ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。
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.5.2-dev.0"
7
+ version = "2.5.2-dev.1"
8
8
  description = "ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -128,13 +128,20 @@ class RunCommand(Command):
128
128
  self._run_internal(reload_mode)
129
129
 
130
130
  _RESTART_EXIT_CODE = 42
131
+ _MAX_CRASH_BACKOFF = 60.0
131
132
 
132
133
  def _run_internal(self, reload_mode: bool):
133
134
  """
134
135
  直接运行 SDK(不指定脚本时)
135
136
 
136
- 以子进程方式运行 SDK,支持硬重启:当 SDK 进程以特定退出码退出时,
137
- 自动重新启动新进程,确保资源完全释放。
137
+ 以子进程方式运行 SDK,支持硬重启。
138
+
139
+ {!--< tips >!--}
140
+ 重要设计原则:
141
+ 1. 只有硬重启(退出码 42)或 KeyboardInterrupt 才能停止主进程
142
+ 2. 模块/适配器的任何错误都**不会**导致主进程退出
143
+ 3. 子进程异常退出时自动重试,使用递增退避策略避免刷屏
144
+ {!--< /tips >!--}
138
145
  """
139
146
 
140
147
  if reload_mode:
@@ -168,33 +175,30 @@ class RunCommand(Command):
168
175
  "asyncio.run(sdk.run(keep_running=True))",
169
176
  ]
170
177
 
171
- import signal
172
-
178
+ crash_count = 0
173
179
  try:
174
180
  while True:
175
181
  process = subprocess.Popen(cmd)
176
-
177
- # 转发 SIGTERM/SIGINT 到子进程,使 SDK 能优雅关闭
178
- def _forward_signal(signum, frame):
179
- try:
180
- process.send_signal(signum)
181
- except Exception:
182
- pass
183
-
184
- old_term = signal.signal(signal.SIGTERM, _forward_signal)
185
- old_int = signal.signal(signal.SIGINT, _forward_signal)
186
-
187
182
  process.wait()
188
183
 
189
- # 恢复默认信号处理
190
- signal.signal(signal.SIGTERM, old_term)
191
- signal.signal(signal.SIGINT, old_int)
192
-
193
184
  if process.returncode == self._RESTART_EXIT_CODE:
194
185
  console.print(f"[info]{i18n.t('cli.run.restart_request')}[/]")
186
+ crash_count = 0
195
187
  time.sleep(0.5)
196
188
  continue
197
- break
189
+
190
+ # 非硬重启退出码:模块/适配器内部错误导致子进程异常终止
191
+ # 不退出主进程,等待后自动重试
192
+ crash_count += 1
193
+ backoff = min(self._MAX_CRASH_BACKOFF, 3.0 * crash_count)
194
+ console.print(
195
+ f"[warning]{i18n.t('cli.run.process_crashed', code=process.returncode)}[/]"
196
+ )
197
+ console.print(
198
+ f"[info]{i18n.t('cli.run.subprocess_crashed_retry', seconds=backoff)}[/]"
199
+ )
200
+ time.sleep(backoff)
201
+ # 继续循环,重新启动子进程
198
202
  except KeyboardInterrupt:
199
203
  pass
200
204
 
@@ -72,8 +72,14 @@ class RunCommand(Command):
72
72
  """
73
73
  直接运行 SDK(不指定脚本时)
74
74
 
75
- 以子进程方式运行 SDK,支持硬重启:当 SDK 进程以特定退出码退出时,
76
- 自动重新启动新进程,确保资源完全释放。
75
+ 以子进程方式运行 SDK,支持硬重启。
76
+
77
+ {!--< tips >!--}
78
+ 重要设计原则:
79
+ 1. 只有硬重启(退出码 42)或 KeyboardInterrupt 才能停止主进程
80
+ 2. 模块/适配器的任何错误都**不会**导致主进程退出
81
+ 3. 子进程异常退出时自动重试,使用递增退避策略避免刷屏
82
+ {!--< /tips >!--}
77
83
  """
78
84
  ...
79
85
  def _run_script(self: object, script_path: str, reload_mode: bool) -> ...:
@@ -249,6 +249,7 @@ TRANSLATIONS = {
249
249
  "cli.run.file_changed_restart": "File change detected ([cmd]{file}[/]), restarting...",
250
250
  "cli.run.process_exited": "Process exited normally, waiting for file changes to restart",
251
251
  "cli.run.process_crashed": "Process crashed (exit code {code}), fix and save to restart",
252
+ "cli.run.subprocess_crashed_retry": "Subprocess crashed, will auto-retry in {seconds}s...",
252
253
  # ==================== uninstall command ====================
253
254
  "cli.uninstall.description": "Uninstall module/adapter packages",
254
255
  "cli.uninstall.package_help": "Package name(s) to uninstall (multiple allowed)",
@@ -249,6 +249,7 @@ TRANSLATIONS = {
249
249
  "cli.run.file_changed_restart": "ファイル変更を検出 ([cmd]{file}[/])、再起動中...",
250
250
  "cli.run.process_exited": "プロセスが正常に終了しました。ファイルの変更を待機して再起動",
251
251
  "cli.run.process_crashed": "プロセスが異常終了しました(終了コード {code})。修正して保存すると自動再起動",
252
+ "cli.run.subprocess_crashed_retry": "サブプロセスが異常終了しました。{seconds} 秒後に自動再試行します...",
252
253
  # ==================== uninstall コマンド ====================
253
254
  "cli.uninstall.description": "モジュール/アダプターパッケージをアンインストール",
254
255
  "cli.uninstall.package_help": "アンインストールするパッケージ名(複数指定可)",
@@ -249,6 +249,7 @@ TRANSLATIONS = {
249
249
  "cli.run.file_changed_restart": "Обнаружено изменение файла ([cmd]{file}[/]), перезапуск...",
250
250
  "cli.run.process_exited": "Процесс завершен нормально, ожидание изменений файлов для перезапуска",
251
251
  "cli.run.process_crashed": "Процесс аварийно завершен (код {code}), исправьте и сохраните для перезапуска",
252
+ "cli.run.subprocess_crashed_retry": "Подпроцесс аварийно завершен, автоматическая перезагрузка через {seconds}с...",
252
253
  # ==================== команда uninstall ====================
253
254
  "cli.uninstall.description": "Удалить пакеты модулей/адаптеров",
254
255
  "cli.uninstall.package_help": "Имя(ена) пакета(ов) для удаления (можно указать несколько)",
@@ -249,6 +249,7 @@ TRANSLATIONS = {
249
249
  "cli.run.file_changed_restart": "检测到文件变更 ([cmd]{file}[/]),正在重启...",
250
250
  "cli.run.process_exited": "进程已正常退出,等待文件变更后重启",
251
251
  "cli.run.process_crashed": "进程异常退出(退出码 {code}),修复后保存文件将自动重启",
252
+ "cli.run.subprocess_crashed_retry": "子进程异常终止,将在 {seconds} 秒后自动重试...",
252
253
  # ==================== uninstall 命令 ====================
253
254
  "cli.uninstall.description": "卸载模块/适配器包",
254
255
  "cli.uninstall.package_help": "要卸载的包名(可指定多个)",
@@ -249,6 +249,7 @@ TRANSLATIONS = {
249
249
  "cli.run.file_changed_restart": "檢測到檔案變更 ([cmd]{file}[/]),正在重啟...",
250
250
  "cli.run.process_exited": "程式已正常退出,等待檔案變更後重啟",
251
251
  "cli.run.process_crashed": "程式異常退出(退出碼 {code}),修復後儲存檔案將自動重啟",
252
+ "cli.run.subprocess_crashed_retry": "子程序異常終止,將在 {seconds} 秒後自動重試...",
252
253
  # ==================== uninstall 命令 ====================
253
254
  "cli.uninstall.description": "解除安裝模組/適配器包",
254
255
  "cli.uninstall.package_help": "要解除安裝的包名(可指定多個)",
@@ -673,59 +673,18 @@ class PackageManager:
673
673
  并将目标 Python 解析为当前虚拟环境的解释器,
674
674
  避免安装到全局环境。
675
675
 
676
- 操作成功后自动保存包快照到持久化目录,
677
- 供 Docker 容器重建后恢复使用。
678
-
679
676
  :param args: [List[str]] pip 子命令与参数,如 ["install", "--upgrade", pkg]
680
677
  :param description: [str] 展示给用户的操作描述
681
678
  :return: [bool] 执行成功返回 True
682
679
  """
683
680
  uv_cmd = self._get_uv_command()
684
- success = False
685
681
  if uv_cmd:
686
682
  if self._execute_backend(uv_cmd + ["pip"], args, description, "uv"):
687
- success = True
688
- else:
689
- console.print(f"[warning]{i18n.t('cli.package.uv_fallback_to_pip')}[/]")
690
-
691
- if not success:
692
- pip_cmd = [self._get_target_python(), "-m", "pip"]
693
- success = self._execute_backend(pip_cmd, args, description, "pip")
694
-
695
- # 操作成功后保存包快照(非关键,失败不影响主流程)
696
- if success:
697
- self._save_package_snapshot()
698
-
699
- return success
700
-
701
- def _save_package_snapshot(self) -> None:
702
- """
703
- {!--< internal-use >!--}
704
- 将当前已安装的包列表保存到持久化目录。
705
-
706
- 快照文件用于 Docker 容器重建后的包恢复:
707
- entrypoint 创建新 venv 时会读取 .pip-snapshot.txt
708
- 并尝试重新安装这些包。
683
+ return True
684
+ console.print(f"[warning]{i18n.t('cli.package.uv_fallback_to_pip')}[/]")
709
685
 
710
- 仅在 config/ 目录存在时保存(即项目环境或 Docker 环境)。
711
- """
712
- try:
713
- config_dir = os.path.join(os.getcwd(), "config")
714
- if not os.path.isdir(config_dir):
715
- return
716
-
717
- result = subprocess.run(
718
- [sys.executable, "-m", "pip", "freeze"],
719
- capture_output=True,
720
- text=True,
721
- timeout=30,
722
- )
723
- if result.returncode == 0:
724
- snapshot_path = os.path.join(config_dir, ".pip-snapshot.txt")
725
- with open(snapshot_path, "w", encoding="utf-8") as f:
726
- f.write(result.stdout)
727
- except Exception:
728
- pass
686
+ pip_cmd = [self._get_target_python(), "-m", "pip"]
687
+ return self._execute_backend(pip_cmd, args, description, "pip")
729
688
 
730
689
  def _version_key(self, version: str) -> tuple:
731
690
  """
@@ -243,9 +243,6 @@ class PackageManager:
243
243
  并将目标 Python 解析为当前虚拟环境的解释器,
244
244
  避免安装到全局环境。
245
245
 
246
- 操作成功后自动保存包快照到持久化目录,
247
- 供 Docker 容器重建后恢复使用。
248
-
249
246
  :param args: [List[str]] pip 子命令与参数,如 ["install", "--upgrade", pkg]
250
247
  :param description: [str] 展示给用户的操作描述
251
248
  :return: [bool] 执行成功返回 True
@@ -12,48 +12,55 @@ ErisPulse 事件处理模块
12
12
 
13
13
  from .command import command
14
14
  from .message import message
15
+ from .message_builder import MessageBuilder
16
+ from .meta import meta
15
17
  from .notice import notice
16
18
  from .request import request
17
- from .meta import meta
18
- from .wrapper import (
19
- Event,
20
- Conversation,
21
- CONFIRM_YES_WORDS,
22
- CONFIRM_NO_WORDS,
23
- register_event_mixin,
24
- register_event_method,
25
- unregister_event_method,
26
- unregister_platform_event_methods,
27
- get_platform_event_methods,
28
- _builtin_wait_reply,
29
- _builtin_confirm,
30
- _builtin_choose,
31
- _builtin_collect,
32
- )
33
- from .message_builder import MessageBuilder
34
19
  from .session_type import (
35
20
  # 标准类型常量
36
21
  RECEIVE_TYPES,
37
22
  SEND_TYPES,
38
23
  # 自定义类型注册
39
- register_custom_type,
40
- unregister_custom_type,
24
+ clear_custom_types,
25
+ convert_to_receive_type,
26
+ convert_to_send_type,
41
27
  # 类型获取方法
42
28
  get_id_field,
43
29
  get_receive_type,
44
- convert_to_send_type,
45
- convert_to_receive_type,
30
+ get_send_type_and_target_id,
31
+ get_send_types,
32
+ get_standard_types,
33
+ get_target_id,
46
34
  # 自动推断方法
47
35
  infer_receive_type,
48
- get_target_id,
49
- get_send_type_and_target_id,
50
36
  # 工具方法
51
37
  is_standard_type,
52
38
  is_valid_send_type,
53
- get_standard_types,
54
- get_send_types,
55
- clear_custom_types,
39
+ # 自定义类型注册
40
+ register_custom_type,
41
+ unregister_custom_type,
56
42
  )
43
+ from .wrapper import (
44
+ CONFIRM_NO_WORDS,
45
+ CONFIRM_YES_WORDS,
46
+ Conversation,
47
+ Event,
48
+ _builtin_choose,
49
+ _builtin_collect,
50
+ _builtin_confirm,
51
+ _builtin_wait_reply,
52
+ get_platform_event_methods,
53
+ register_event_method,
54
+ register_event_mixin,
55
+ unregister_event_method,
56
+ unregister_platform_event_methods,
57
+ )
58
+
59
+ # 将 command 的命令分发器绑定到 message 的共享 BaseEventHandler,
60
+ # 使命令处理和消息处理共享同一个优先级队列。
61
+ # 命令分发器 _handle_message 以 DEFAULT_COMMAND_DISPATCHER_PRIORITY (100) 注册,
62
+ # 确保命令 /xxx 始终优先于 on_message / on_group_message 等处理器触发。
63
+ command.bind_message_handler(message.handler)
57
64
 
58
65
 
59
66
  def _clear_all_handlers():
@@ -0,0 +1,26 @@
1
+ # type: ignore
2
+ #
3
+ # Auto-generated type stub for __init__.py
4
+ # DO NOT EDIT MANUALLY - Generated by generate-type-stubs.py
5
+ #
6
+
7
+ """
8
+ ErisPulse 事件处理模块
9
+
10
+ 提供统一的事件处理接口,支持命令、消息、通知、请求和元事件处理
11
+
12
+ {!--< tips >!--}
13
+ 1. 所有事件处理都基于OneBot12标准事件格式
14
+ 2. 通过装饰器方式注册事件处理器
15
+ 3. 支持优先级和条件过滤
16
+ {!--< /tips >!--}
17
+ """
18
+
19
+ from .command import command
20
+ from .message import message
21
+ from .message_builder import MessageBuilder
22
+ from .meta import meta
23
+ from .notice import notice
24
+ from .request import request
25
+ from .session_type import RECEIVE_TYPES, SEND_TYPES, clear_custom_types, convert_to_receive_type, convert_to_send_type, get_id_field, get_receive_type, get_send_type_and_target_id, get_send_types, get_standard_types, get_target_id, infer_receive_type, is_standard_type, is_valid_send_type, register_custom_type, unregister_custom_type
26
+ from .wrapper import CONFIRM_NO_WORDS, CONFIRM_YES_WORDS, Conversation, Event, _builtin_choose, _builtin_collect, _builtin_confirm, _builtin_wait_reply, get_platform_event_methods, register_event_method, register_event_mixin, unregister_event_method, unregister_platform_event_methods
@@ -21,6 +21,7 @@ from ...runtime.context import current_owner, handler_waits
21
21
  from .. import adapter, logger
22
22
  from ..constants import (
23
23
  DEFAULT_COMMAND_ALLOW_SPACE_PREFIX,
24
+ DEFAULT_COMMAND_DISPATCHER_PRIORITY,
24
25
  DEFAULT_COMMAND_MUST_AT_BOT,
25
26
  DEFAULT_SEND_METHOD,
26
27
  DEFAULT_WAIT_TIMEOUT_SECS,
@@ -65,12 +66,11 @@ class CommandHandler:
65
66
  # 等待回复相关
66
67
  self._waiting_replies = {} # 存储等待回复的用户信息
67
68
 
68
- # 创建消息事件处理器
69
- self.handler = BaseEventHandler("message", "command")
70
-
71
- # 将命令分发器 _handle_message 挂载到适配器消息事件总线
72
- if not self.handler._linked_to_adapter_bus:
73
- self.handler.register(self._handle_message)
69
+ # 共享的消息事件处理器引用(由 bind_message_handler() 设置)
70
+ # 命令分发器 _handle_message 以高优先级注册在同一个队列中,
71
+ # 确保命令 /xxx 始终优先于 on_message / on_group_message 触发
72
+ self._bound_handler: BaseEventHandler | None = None
73
+ self._dispatcher_registered: bool = False
74
74
 
75
75
  def __call__(
76
76
  self,
@@ -98,8 +98,9 @@ class CommandHandler:
98
98
  """
99
99
 
100
100
  def decorator(func: Callable):
101
- if not self.handler._linked_to_adapter_bus:
102
- self.handler.register(self._handle_message)
101
+ # 确保命令分发器已注册到共享 handler
102
+ if not self._dispatcher_registered:
103
+ self._register_dispatcher()
103
104
 
104
105
  cmd_names = []
105
106
  if isinstance(name, str):
@@ -162,8 +163,10 @@ class CommandHandler:
162
163
  :param handler: 要注销的命令处理器
163
164
  :return: 是否成功注销
164
165
  """
165
- # 从基础处理器中移除
166
- result = self.handler.unregister(handler)
166
+ # 从共享 handler 中注销命令函数(如已注册)
167
+ result = False
168
+ if self._bound_handler is not None:
169
+ result = self._bound_handler.unregister(handler)
167
170
 
168
171
  # 从命令映射中移除
169
172
  commands_to_remove = []
@@ -667,10 +670,35 @@ class CommandHandler:
667
670
  except Exception as e:
668
671
  logger.error(f"发送命令错误消息失败: {e}")
669
672
 
673
+ def bind_message_handler(self, handler: BaseEventHandler) -> None:
674
+ """
675
+ {!--< internal-use >!--}
676
+ 绑定到共享的消息事件处理器
677
+
678
+ 将命令分发器 _handle_message 注册到共享的 BaseEventHandler 中,
679
+ 使命令处理和通用消息处理共享同一个优先级队列。
680
+
681
+ :param handler: MessageHandler 持有的 BaseEventHandler 实例
682
+ """
683
+ self._bound_handler = handler
684
+ self._register_dispatcher()
685
+
686
+ def _register_dispatcher(self) -> None:
687
+ """
688
+ {!--< internal-use >!--}
689
+ 将命令分发器注册到共享 handler(如尚未注册)
690
+ """
691
+ if self._bound_handler is not None and not self._dispatcher_registered:
692
+ self._bound_handler.register(
693
+ self._handle_message,
694
+ priority=DEFAULT_COMMAND_DISPATCHER_PRIORITY,
695
+ )
696
+ self._dispatcher_registered = True
697
+
670
698
  def _clear_commands(self):
671
699
  """
672
700
  {!--< internal-use >!--}
673
- 清除所有已注册的命令,并断开与适配器事件总线的连接
701
+ 清除所有已注册的命令,并从共享 handler 中注销命令分发器
674
702
 
675
703
  :return: 被清除的命令数量
676
704
  """
@@ -680,7 +708,10 @@ class CommandHandler:
680
708
  self.groups.clear()
681
709
  self.permissions.clear()
682
710
  self._waiting_replies.clear()
683
- self.handler._clear_handlers()
711
+ # 从共享 handler 中注销命令分发器(不清除其他 handler 的消息处理器)
712
+ if self._bound_handler is not None and self._dispatcher_registered:
713
+ self._bound_handler.unregister(self._handle_message)
714
+ self._dispatcher_registered = False
684
715
  return count
685
716
 
686
717
  def get_command(self, name: str) -> dict | None:
@@ -24,7 +24,7 @@ from typing import Any
24
24
  from ...runtime import get_event_config
25
25
  from ...runtime.context import current_owner, handler_waits
26
26
  from .. import adapter, logger
27
- from ..constants import DEFAULT_COMMAND_ALLOW_SPACE_PREFIX, DEFAULT_COMMAND_MUST_AT_BOT, DEFAULT_SEND_METHOD, DEFAULT_WAIT_TIMEOUT_SECS, DETAIL_TYPE_PRIVATE, DETAIL_TYPE_USER, UNKNOWN_PLATFORM
27
+ from ..constants import DEFAULT_COMMAND_ALLOW_SPACE_PREFIX, DEFAULT_COMMAND_DISPATCHER_PRIORITY, DEFAULT_COMMAND_MUST_AT_BOT, DEFAULT_SEND_METHOD, DEFAULT_WAIT_TIMEOUT_SECS, DETAIL_TYPE_PRIVATE, DETAIL_TYPE_USER, UNKNOWN_PLATFORM
28
28
  from .base import BaseEventHandler
29
29
  from .session_type import get_send_type_and_target_id, infer_receive_type
30
30
 
@@ -319,6 +319,10 @@ DEFAULT_MESSAGE_IGNORE_SELF = True
319
319
  # 修改影响: 未指定 priority 的处理器的执行顺序。
320
320
  DEFAULT_HANDLER_PRIORITY = 0
321
321
 
322
+ # 命令分发器优先级(远高于默认值,确保命令在消息处理器之前执行)。
323
+ # 修改影响: 命令 /xxx 总是优先于 on_message / on_group_message 等处理器触发。
324
+ DEFAULT_COMMAND_DISPATCHER_PRIORITY = 100
325
+
322
326
  # 等待用户回复的默认超时时间(秒)。
323
327
  # 使用位置: command.wait_reply(), Event.wait_reply(), Event.wait_for() 等 8 处。
324
328
  # 修改影响: 所有等待用户交互的默认超时。设大用户有更多反应时间,设小释放资源更快。
@@ -57,6 +57,7 @@ TRANSLATIONS = {
57
57
  # ==================== SDK Run ====================
58
58
  "core.sdk.run.init_failed": "ErisPulse initialization failed, please check the logs",
59
59
  "core.sdk.run.shutdown_signal": "Shutdown signal received, cleaning up...",
60
+ "core.sdk.run.unexpected_error": "Unexpected termination signal intercepted: {error}, process kept alive",
60
61
  # ==================== SDK Reload ====================
61
62
  "core.sdk.reload.starting": "[Reload] Starting SDK reload...",
62
63
  "core.sdk.reload.collected_top_modules": "[Reload] Collected external package top-level modules: {modules}",
@@ -57,6 +57,7 @@ TRANSLATIONS = {
57
57
  # ==================== SDK 実行 ====================
58
58
  "core.sdk.run.init_failed": "ErisPulse の初期化に失敗しました、ログを確認してください",
59
59
  "core.sdk.run.shutdown_signal": "シャットダウンシグナルを受信しました、クリーンアップ中...",
60
+ "core.sdk.run.unexpected_error": "予期しない終了シグナルを遮断しました: {error}、プロセスは維持されます",
60
61
  # ==================== SDK リロード ====================
61
62
  "core.sdk.reload.starting": "[Reload] SDK の再読み込みを開始しています...",
62
63
  "core.sdk.reload.collected_top_modules": "[Reload] 外部パッケージのトップレベルモジュールを収集しました: {modules}",
@@ -57,6 +57,7 @@ TRANSLATIONS = {
57
57
  # ==================== Запуск SDK ====================
58
58
  "core.sdk.run.init_failed": "Ошибка инициализации ErisPulse, проверьте журналы",
59
59
  "core.sdk.run.shutdown_signal": "Получен сигнал завершения, выполняется очистка...",
60
+ "core.sdk.run.unexpected_error": "Перехвачен неожиданный сигнал завершения: {error}, процесс продолжает работу",
60
61
  # ==================== Перезагрузка SDK ====================
61
62
  "core.sdk.reload.starting": "[Reload] Начинается перезагрузка SDK...",
62
63
  "core.sdk.reload.collected_top_modules": "[Reload] Собраны модули верхнего уровня внешних пакетов: {modules}",
@@ -57,6 +57,7 @@ TRANSLATIONS = {
57
57
  # ==================== SDK 运行 ====================
58
58
  "core.sdk.run.init_failed": "ErisPulse 初始化失败,请检查日志",
59
59
  "core.sdk.run.shutdown_signal": "收到关闭信号,正在清理...",
60
+ "core.sdk.run.unexpected_error": "拦截到意外终止信号: {error},已阻止进程退出",
60
61
  # ==================== SDK 重载 ====================
61
62
  "core.sdk.reload.starting": "[Reload] 开始重新加载SDK...",
62
63
  "core.sdk.reload.collected_top_modules": "[Reload] 收集到外部包顶层模块: {modules}",
@@ -57,6 +57,7 @@ TRANSLATIONS = {
57
57
  # ==================== SDK 執行 ====================
58
58
  "core.sdk.run.init_failed": "ErisPulse 初始化失敗,請檢查日誌",
59
59
  "core.sdk.run.shutdown_signal": "收到關閉訊號,正在清理...",
60
+ "core.sdk.run.unexpected_error": "攔截到意外終止訊號: {error},已阻止程序退出",
60
61
  # ==================== SDK 重新載入 ====================
61
62
  "core.sdk.reload.starting": "[Reload] 開始重新載入SDK...",
62
63
  "core.sdk.reload.collected_top_modules": "[Reload] 收集到外部套件頂層模組: {modules}",
@@ -898,37 +898,19 @@ class SDK:
898
898
  """
899
899
  无头模式运行 ErisPulse
900
900
 
901
- 监听 SIGTERM/SIGINT 信号以实现优雅关闭:
902
- 收到信号后触发 shutdown_event,使 finally 块中的 uninit() 正常执行,
903
- 确保适配器断开、模块卸载、数据落盘等清理工作完成。
901
+ {!--< tips >!--}
902
+ 异常处理原则:
903
+ 1. 模块/适配器的任何错误都会被拦截,不会导致进程退出
904
+ 2. 只有 KeyboardInterrupt(Ctrl+C)会正常向上传播,触发优雅关闭
905
+ 3. 其他 BaseException(如 SystemExit)会被拦截并记录,防止意外终止
906
+ {!--< /tips >!--}
904
907
 
905
908
  :param keep_running: bool 是否保持运行
906
909
 
907
910
  :example:
908
911
  >>> await sdk.run(keep_running=True)
909
912
  """
910
- import signal
911
-
912
- shutdown_event = asyncio.Event()
913
- loop = asyncio.get_running_loop()
914
- _registered_signals: list[int] = []
915
-
916
- def _request_shutdown() -> None:
917
- """信号回调:设置关闭事件,使 run() 退出等待并进入清理流程"""
918
- if not shutdown_event.is_set():
919
- self.logger.info(i18n.t("core.sdk.run.shutdown_signal"))
920
- shutdown_event.set()
921
-
922
913
  try:
923
- # 注册信号处理器,使 Docker SIGTERM / Ctrl+C 能触发优雅关闭
924
- for sig in (signal.SIGTERM, signal.SIGINT):
925
- try:
926
- loop.add_signal_handler(sig, _request_shutdown)
927
- _registered_signals.append(sig)
928
- except (NotImplementedError, RuntimeError):
929
- # Windows 不支持 add_signal_handler,跳过
930
- pass
931
-
932
914
  isInit = await self.init()
933
915
 
934
916
  if not isInit:
@@ -936,19 +918,22 @@ class SDK:
936
918
  return
937
919
 
938
920
  if keep_running:
921
+ shutdown_event = asyncio.Event()
939
922
  await shutdown_event.wait()
940
923
  except asyncio.CancelledError:
941
924
  self.logger.info(i18n.t("core.sdk.run.shutdown_signal"))
925
+ except KeyboardInterrupt:
926
+ # Ctrl+C / SIGINT: 允许正常传播,触发优雅关闭
927
+ self.logger.info(i18n.t("core.sdk.run.shutdown_signal"))
928
+ raise
942
929
  except Exception as e:
930
+ # 常规异常(模块/适配器错误等),记录但不向上传播
943
931
  self.logger.error(e)
932
+ except BaseException as e:
933
+ # 其他 BaseException(SystemExit 等),拦截并记录
934
+ # 模块/适配器不应能终止进程
935
+ self.logger.error(i18n.t("core.sdk.run.unexpected_error", error=repr(e)))
944
936
  finally:
945
- # 清理信号处理器,避免重复触发
946
- for sig in _registered_signals:
947
- try:
948
- loop.remove_signal_handler(sig)
949
- except Exception:
950
- pass
951
-
952
937
  if keep_running:
953
938
  try:
954
939
  await self.uninit()
@@ -142,9 +142,12 @@ class SDK:
142
142
  """
143
143
  无头模式运行 ErisPulse
144
144
 
145
- 监听 SIGTERM/SIGINT 信号以实现优雅关闭:
146
- 收到信号后触发 shutdown_event,使 finally 块中的 uninit() 正常执行,
147
- 确保适配器断开、模块卸载、数据落盘等清理工作完成。
145
+ {!--< tips >!--}
146
+ 异常处理原则:
147
+ 1. 模块/适配器的任何错误都会被拦截,不会导致进程退出
148
+ 2. 只有 KeyboardInterrupt(Ctrl+C)会正常向上传播,触发优雅关闭
149
+ 3. 其他 BaseException(如 SystemExit)会被拦截并记录,防止意外终止
150
+ {!--< /tips >!--}
148
151
 
149
152
  :param keep_running: bool 是否保持运行
150
153
 
@@ -1,26 +0,0 @@
1
- # type: ignore
2
- #
3
- # Auto-generated type stub for __init__.py
4
- # DO NOT EDIT MANUALLY - Generated by generate-type-stubs.py
5
- #
6
-
7
- """
8
- ErisPulse 事件处理模块
9
-
10
- 提供统一的事件处理接口,支持命令、消息、通知、请求和元事件处理
11
-
12
- {!--< tips >!--}
13
- 1. 所有事件处理都基于OneBot12标准事件格式
14
- 2. 通过装饰器方式注册事件处理器
15
- 3. 支持优先级和条件过滤
16
- {!--< /tips >!--}
17
- """
18
-
19
- from .command import command
20
- from .message import message
21
- from .notice import notice
22
- from .request import request
23
- from .meta import meta
24
- from .wrapper import Event, Conversation, CONFIRM_YES_WORDS, CONFIRM_NO_WORDS, register_event_mixin, register_event_method, unregister_event_method, unregister_platform_event_methods, get_platform_event_methods, _builtin_wait_reply, _builtin_confirm, _builtin_choose, _builtin_collect
25
- from .message_builder import MessageBuilder
26
- from .session_type import RECEIVE_TYPES, SEND_TYPES, register_custom_type, unregister_custom_type, get_id_field, get_receive_type, convert_to_send_type, convert_to_receive_type, infer_receive_type, get_target_id, get_send_type_and_target_id, is_standard_type, is_valid_send_type, get_standard_types, get_send_types, clear_custom_types
File without changes
File without changes