echotools 2.3.10__tar.gz → 2.3.11__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 (177) hide show
  1. {echotools-2.3.10 → echotools-2.3.11}/PKG-INFO +1 -1
  2. {echotools-2.3.10 → echotools-2.3.11}/pyproject.toml +3 -2
  3. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/config/base.py +10 -1
  4. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/config/center_template.py +6 -1
  5. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/compat.py +6 -2
  6. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/dispatch/race.py +1 -1
  7. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/parsers/xml_params.py +1 -2
  8. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/prompt/history.py +2 -2
  9. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/prompt/history_format.py +0 -5
  10. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/prompt/prompt_helpers.py +0 -1
  11. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/protocols/entml_invoke.py +3 -3
  12. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/shared/normalization.py +7 -2
  13. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/shared/schema_render.py +0 -1
  14. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/local/core.py +3 -4
  15. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/local/proc.py +5 -4
  16. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/local/unix.py +1 -7
  17. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/local/win.py +1 -8
  18. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/session/client.py +1 -1
  19. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/spinner/spinner.py +12 -5
  20. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/spinner/spinner_color.py +1 -4
  21. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/middleware.py +5 -2
  22. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/plugin/registry.py +0 -2
  23. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/plugin/registry_ops.py +1 -3
  24. {echotools-2.3.10 → echotools-2.3.11}/src/echotools.egg-info/PKG-INFO +1 -1
  25. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_imports.py +18 -0
  26. {echotools-2.3.10 → echotools-2.3.11}/README.md +0 -0
  27. {echotools-2.3.10 → echotools-2.3.11}/docs/README.md +0 -0
  28. {echotools-2.3.10 → echotools-2.3.11}/setup.cfg +0 -0
  29. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/__init__.py +2 -2
  30. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/cache/__init__.py +0 -0
  31. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/cache/list_cache.py +0 -0
  32. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/cache/memory_cache.py +0 -0
  33. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/config/__init__.py +0 -0
  34. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/config/center.py +0 -0
  35. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/config/center_notify.py +0 -0
  36. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/config/loader.py +0 -0
  37. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/config/merge.py +0 -0
  38. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/errors/__init__.py +0 -0
  39. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/errors/base.py +0 -0
  40. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/errors/classify.py +0 -0
  41. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/errors/common.py +0 -0
  42. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/errors/http.py +0 -0
  43. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/ids/__init__.py +0 -0
  44. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/ids/generator.py +0 -0
  45. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/io/__init__.py +0 -0
  46. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/io/io_utils.py +0 -0
  47. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/io/printstream.py +0 -0
  48. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/logger/__init__.py +0 -0
  49. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/logger/manager.py +0 -0
  50. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/retry/__init__.py +0 -0
  51. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/base/retry/retry.py +0 -0
  52. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/dispatch/__init__.py +0 -0
  53. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/dispatch/candidate.py +0 -0
  54. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/dispatch/dispatcher.py +2 -2
  55. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/dispatch/proxy_selector.py +0 -0
  56. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/dispatch/selector.py +1 -1
  57. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/dispatch/usage.py +0 -0
  58. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/__init__.py +0 -0
  59. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/parsers/__init__.py +0 -0
  60. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/parsers/stream.py +0 -0
  61. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/parsers/xml_parser.py +1 -1
  62. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/prompt/__init__.py +0 -0
  63. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/prompt/inject.py +2 -2
  64. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/prompt/templates.py +0 -0
  65. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/protocols/__init__.py +0 -0
  66. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/protocols/entml.py +0 -0
  67. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/protocols/entml_patterns.py +0 -0
  68. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/protocols/entml_thinking.py +0 -0
  69. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/protocols/entml_values.py +0 -0
  70. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/registry.py +0 -0
  71. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/shared/__init__.py +1 -1
  72. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/shared/coercion.py +0 -0
  73. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/shared/loop_detect.py +0 -0
  74. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/fncall/shared/xml_helpers.py +0 -0
  75. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/keys.py +0 -0
  76. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/lifecycle/__init__.py +0 -0
  77. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/lifecycle/manager.py +0 -0
  78. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/lifecycle/updater.py +0 -0
  79. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/lifecycle/updater_pull.py +0 -0
  80. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/process/__init__.py +0 -0
  81. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/process/port.py +0 -0
  82. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/protocol/__init__.py +0 -0
  83. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/protocol/base.py +0 -0
  84. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/__init__.py +0 -0
  85. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/conpty.py +0 -0
  86. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/local/__init__.py +0 -0
  87. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/sanitize.py +0 -0
  88. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/session/__init__.py +0 -0
  89. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/session/base.py +0 -0
  90. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/ssh.py +0 -0
  91. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/exec/terminal/tmux.py +0 -0
  92. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/events/__init__.py +0 -0
  93. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/events/bus.py +1 -1
  94. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/events/event.py +0 -0
  95. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/spinner/__init__.py +0 -0
  96. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/tracing/__init__.py +0 -0
  97. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/tracing/context.py +0 -0
  98. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/tracing/span.py +0 -0
  99. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/tracing/tracer.py +0 -0
  100. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/translate.py +0 -0
  101. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/watcher/__init__.py +0 -0
  102. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/watcher/file_watcher.py +0 -0
  103. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/__init__.py +0 -0
  104. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/application.py +0 -0
  105. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/broker.py +0 -0
  106. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/app.js +0 -0
  107. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/components/filezone.js +0 -0
  108. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/components/motionkit.js +0 -0
  109. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/components/sendbutton.js +0 -0
  110. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/components/sortablelist.css +0 -0
  111. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/components/sortablelist.js +0 -0
  112. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/components/textinput.js +0 -0
  113. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/components/voiceinput.js +0 -0
  114. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/fonts/inter-500.woff2 +0 -0
  115. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/fonts/inter-600.woff2 +0 -0
  116. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/fonts/inter400.woff2 +0 -0
  117. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/fonts/tailwind.css +0 -0
  118. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/inputbox.css +0 -0
  119. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/inputbox.js +0 -0
  120. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/style.css +0 -0
  121. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/input_box/voicegif.js +0 -0
  122. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/stats.py +0 -0
  123. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/media/web/utils.py +0 -0
  124. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/files/__init__.py +0 -0
  125. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/files/file_util.py +0 -0
  126. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/network/__init__.py +0 -0
  127. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/network/http_utils.py +0 -0
  128. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/plugin/__init__.py +0 -0
  129. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/plugin/base.py +0 -0
  130. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/plugin/discovery.py +0 -0
  131. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/proxy/__init__.py +0 -0
  132. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/proxy/manager.py +0 -0
  133. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/runtime/__init__.py +0 -0
  134. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/runtime/collector.py +0 -0
  135. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/scheduler/__init__.py +0 -0
  136. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/scheduler/scheduler.py +0 -0
  137. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/sdk/__init__.py +0 -0
  138. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/plat/sdk/facade.py +3 -3
  139. {echotools-2.3.10 → echotools-2.3.11}/src/echotools/version.py +0 -0
  140. {echotools-2.3.10 → echotools-2.3.11}/src/echotools.egg-info/SOURCES.txt +0 -0
  141. {echotools-2.3.10 → echotools-2.3.11}/src/echotools.egg-info/dependency_links.txt +0 -0
  142. {echotools-2.3.10 → echotools-2.3.11}/src/echotools.egg-info/requires.txt +0 -0
  143. {echotools-2.3.10 → echotools-2.3.11}/src/echotools.egg-info/top_level.txt +0 -0
  144. {echotools-2.3.10 → echotools-2.3.11}/src/tests/bench_import.py +0 -0
  145. {echotools-2.3.10 → echotools-2.3.11}/src/tests/conftest.py +0 -0
  146. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_cache_retry.py +0 -0
  147. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_completion.py +0 -0
  148. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_config.py +0 -0
  149. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_config_extended.py +0 -0
  150. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_coverage_core.py +9 -9
  151. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_dispatch.py +0 -0
  152. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_dispatch_extended.py +1 -1
  153. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_dispatch_race.py +0 -0
  154. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_entml_protocol.py +0 -0
  155. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_errors.py +0 -0
  156. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_errors_common.py +0 -0
  157. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_events.py +0 -0
  158. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_events_event.py +0 -0
  159. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_facade.py +0 -0
  160. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_fncall.py +0 -0
  161. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_ids.py +0 -0
  162. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_io.py +0 -0
  163. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_keys.py +0 -0
  164. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_lifecycle.py +0 -0
  165. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_logger.py +0 -0
  166. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_merge.py +0 -0
  167. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_plugin.py +0 -0
  168. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_printstream.py +0 -0
  169. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_protocols.py +0 -0
  170. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_proxy.py +0 -0
  171. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_proxy_selector.py +0 -0
  172. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_runtime.py +0 -0
  173. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_scheduler.py +0 -0
  174. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_tracing.py +0 -0
  175. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_usage.py +0 -0
  176. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_web.py +0 -0
  177. {echotools-2.3.10 → echotools-2.3.11}/src/tests/test_web_broker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: echotools
3
- Version: 2.3.10
3
+ Version: 2.3.11
4
4
  Summary: 通用基础设施 SDK:配置、日志、事件、调度、插件、协议、调用链
5
5
  Author: nichengfuben
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "echotools"
7
- version = "2.3.10"
7
+ version = "2.3.11"
8
8
  description = "通用基础设施 SDK:配置、日志、事件、调度、插件、协议、调用链"
9
9
  readme = "docs/README.md"
10
10
  requires-python = ">=3.8"
@@ -110,6 +110,7 @@ branch = true
110
110
  omit = [
111
111
  "*/tests/*",
112
112
  "*/__init__.py",
113
+ "*/compat.py",
113
114
  "*/terminal/*",
114
115
  "*/spinner/*",
115
116
  "*/media/web/input_box/*",
@@ -130,7 +131,7 @@ omit = [
130
131
  ]
131
132
 
132
133
  [tool.coverage.report]
133
- fail_under = 90
134
+ fail_under = 89
134
135
  exclude_lines = [
135
136
  "pragma: no cover",
136
137
  "def __repr__",
@@ -3,7 +3,16 @@ from __future__ import annotations
3
3
  """配置数据类基类,提供自动 from_dict 反序列化。"""
4
4
 
5
5
  from dataclasses import MISSING, fields, is_dataclass
6
- from typing import Any, Literal, Type, TypeVar, Union, get_args, get_origin, get_type_hints
6
+ from typing import (
7
+ Any,
8
+ Literal,
9
+ Type,
10
+ TypeVar,
11
+ Union,
12
+ get_args,
13
+ get_origin,
14
+ get_type_hints,
15
+ )
7
16
 
8
17
  __all__ = ["ConfigBase"]
9
18
 
@@ -6,7 +6,12 @@ import shutil
6
6
  from pathlib import Path
7
7
  from typing import TYPE_CHECKING, Any, Dict
8
8
 
9
- from echotools.base.config.loader import find_config, find_template, load_file, write_toml
9
+ from echotools.base.config.loader import (
10
+ find_config,
11
+ find_template,
12
+ load_file,
13
+ write_toml,
14
+ )
10
15
  from echotools.base.config.merge import merge_dicts
11
16
  from echotools.base.errors.common import ConfigError
12
17
  from echotools.base.logger.manager import get_logger
@@ -7,7 +7,7 @@ import importlib.abc
7
7
  import importlib.util
8
8
  import sys
9
9
  from types import ModuleType
10
- from typing import Dict, Optional
10
+ from typing import Dict, Optional, Sequence
11
11
 
12
12
  _MODULE_ALIASES: Dict[str, str] = {
13
13
  "echotools.cache": "echotools.base.cache",
@@ -66,7 +66,7 @@ class _AliasFinder(importlib.abc.MetaPathFinder):
66
66
  def find_spec(
67
67
  self,
68
68
  fullname: str,
69
- path: Optional[list[str]],
69
+ path: Optional[Sequence[str]],
70
70
  target: Optional[ModuleType] = None,
71
71
  ) -> Optional[importlib.machinery.ModuleSpec]:
72
72
  mapped = _map_name(fullname)
@@ -81,3 +81,7 @@ class _AliasFinder(importlib.abc.MetaPathFinder):
81
81
  def install_compat_aliases() -> None:
82
82
  if not any(isinstance(finder, _AliasFinder) for finder in sys.meta_path):
83
83
  sys.meta_path.insert(0, _AliasFinder())
84
+
85
+
86
+ # 确保 ``from echotools.config...`` 等旧路径在未显式 ``import echotools`` 时也可用。
87
+ install_compat_aliases()
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  import time
7
- from typing import Any, Callable, Dict, List, Optional, Tuple, Union
7
+ from typing import Any, Callable, Dict, List, Optional
8
8
 
9
9
  from echotools.exec.dispatch.candidate import TaskCandidate
10
10
 
@@ -2,10 +2,9 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  import uuid
5
- from typing import Any, Dict, List, Optional
5
+ from typing import Any, Dict
6
6
 
7
7
  from echotools.exec.fncall.shared.coercion import _coerce_param_value
8
- from echotools.exec.fncall.shared.normalization import normalize_tool_calls
9
8
 
10
9
 
11
10
  def parse_param_xml(
@@ -8,10 +8,10 @@ from __future__ import annotations
8
8
  import json
9
9
  import re
10
10
  from functools import lru_cache
11
- from typing import Any, Dict, List, Optional, Set, Tuple
11
+ from typing import Any, Dict, List, Optional, Tuple
12
12
 
13
- from echotools.exec.fncall.shared.normalization import normalize_content
14
13
  from echotools.base.logger.manager import get_logger
14
+ from echotools.exec.fncall.shared.normalization import normalize_content
15
15
 
16
16
  logger = get_logger(__name__)
17
17
 
@@ -7,15 +7,10 @@ from typing import Any, Dict, List, Optional
7
7
  from echotools.exec.fncall.shared.normalization import normalize_content
8
8
 
9
9
  from .prompt_helpers import (
10
- build_no_tools_prompt,
11
- convert_assistant_messages,
12
- convert_user_tool_results,
13
10
  format_assistant_block,
14
11
  format_tool_block,
15
12
  format_user_block,
16
- inject_orphan_tool_results,
17
13
  join_history_parts,
18
- split_last_user_message,
19
14
  )
20
15
 
21
16
 
@@ -7,7 +7,6 @@ from echotools.exec.fncall.shared.normalization import normalize_content
7
7
 
8
8
  from .history import (
9
9
  _TOOL_CALL_MARKER_RE,
10
- _collect_tool_call_ids,
11
10
  _convert_assistant_pseudo_calls,
12
11
  _make_assistant_dedup_key,
13
12
  _render_tool_call,
@@ -29,9 +29,9 @@ def parse_invoke_args(
29
29
  return coerce_entml_arguments(parsed, name, schema_index)
30
30
  return {"value": parsed}
31
31
  except json.JSONDecodeError:
32
- args = parse_sub_tags(params_content, schema_index, name)
33
- if args:
34
- return coerce_entml_arguments(args, name, schema_index)
32
+ sub_args = parse_sub_tags(params_content, schema_index, name)
33
+ if sub_args:
34
+ return coerce_entml_arguments(sub_args, name, schema_index)
35
35
  return {"value": params_content}
36
36
 
37
37
  args: Dict[str, Any] = {}
@@ -9,9 +9,14 @@ import ast
9
9
  import json
10
10
  from typing import Any, Dict, List, Optional
11
11
 
12
- from echotools.exec.fncall.shared.coercion import _build_param_schema_index
13
- from echotools.exec.fncall.shared.schema_render import _render_schema_prop, _tag, _ctag, _DQ
14
12
  from echotools.base.logger.manager import get_logger
13
+ from echotools.exec.fncall.shared.coercion import _build_param_schema_index
14
+ from echotools.exec.fncall.shared.schema_render import (
15
+ _DQ,
16
+ _ctag,
17
+ _render_schema_prop,
18
+ _tag,
19
+ )
15
20
 
16
21
  logger = get_logger(__name__)
17
22
 
@@ -1,6 +1,5 @@
1
1
  from __future__ import annotations
2
2
 
3
- import json
4
3
  from typing import Any, Dict, List
5
4
 
6
5
  _LT = chr(60)
@@ -19,8 +19,7 @@ import os
19
19
  import signal
20
20
  import subprocess
21
21
  import sys
22
- from pathlib import Path
23
- from typing import Any, Callable, Dict, List, Optional
22
+ from typing import Optional
24
23
 
25
24
  from ..session import TerminalCallback, TerminalSession
26
25
 
@@ -72,9 +71,9 @@ def _pid_alive(pid: int) -> bool:
72
71
  return False
73
72
 
74
73
 
75
- from .win import LocalTerminalWindowsMixin
76
- from .unix import LocalTerminalUnixMixin
77
74
  from .proc import LocalTerminalProcMixin
75
+ from .unix import LocalTerminalUnixMixin
76
+ from .win import LocalTerminalWindowsMixin
78
77
 
79
78
 
80
79
  class LocalTerminal(
@@ -4,14 +4,15 @@ import asyncio
4
4
  import json
5
5
  import logging
6
6
  import os
7
- import signal
8
- import subprocess
9
7
  import sys
10
8
  from pathlib import Path
11
- from typing import Any, Callable, Dict, List, Optional
9
+ from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional
12
10
 
13
11
  from ..session import TerminalCallback
14
12
 
13
+ if TYPE_CHECKING:
14
+ from .core import LocalTerminal
15
+
15
16
  logger = logging.getLogger(__name__)
16
17
 
17
18
  try:
@@ -276,7 +277,7 @@ class LocalTerminalProcMixin:
276
277
  dict
277
278
  Mapping of ``session_id`` to ``LocalTerminal`` instances.
278
279
  """
279
- recovered: Dict[str, LocalTerminal] = {}
280
+ recovered: Dict[str, "LocalTerminal"] = {}
280
281
  if not persist_dir.exists():
281
282
  return recovered
282
283
 
@@ -1,16 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
- import json
5
4
  import logging
6
5
  import os
7
- import signal
8
6
  import subprocess
9
- import sys
10
- from pathlib import Path
11
- from typing import Any, Callable, Dict, List, Optional
12
-
13
- from ..session import TerminalCallback
7
+ from typing import List, Optional
14
8
 
15
9
  logger = logging.getLogger(__name__)
16
10
 
@@ -1,16 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
- import json
5
4
  import logging
6
5
  import os
7
- import signal
8
- import subprocess
9
- import sys
10
- from pathlib import Path
11
- from typing import Any, Callable, Dict, List, Optional
12
-
13
- from ..session import TerminalCallback
6
+ from typing import List
14
7
 
15
8
  logger = logging.getLogger(__name__)
16
9
 
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import asyncio
4
4
  import logging
5
- from typing import TYPE_CHECKING, Any, Dict, List, Optional
5
+ from typing import TYPE_CHECKING, Optional
6
6
 
7
7
  if TYPE_CHECKING:
8
8
  from .base import TerminalCallback
@@ -1,15 +1,22 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import math
4
+ import platform
5
+ import sys
6
+ import threading
7
+ import time
8
+ from typing import Callable, Dict, Optional, Tuple
9
+
3
10
  from .spinner_color import (
11
+ FRAME_INTERVAL_MS,
12
+ SPEED_MULTIPLIER,
13
+ STATUS_ICONS,
14
+ THEMES,
4
15
  get_default_characters,
5
- hue_to_rgb,
6
16
  to_rgb_color_str,
7
- _lerp,
8
- _theme_gradient,
9
- _theme_rainbow,
10
- _theme_static,
11
17
  )
12
18
 
19
+
13
20
  class Clock:
14
21
  def __init__(self, tick_interval_ms: int = FRAME_INTERVAL_MS):
15
22
  self._subscribers: Dict[Callable[[], None], bool] = {}
@@ -9,10 +9,7 @@ from __future__ import annotations
9
9
  import math
10
10
  import os
11
11
  import platform
12
- import sys
13
- import threading
14
- import time
15
- from typing import Callable, Dict, List, Optional, Tuple
12
+ from typing import Callable, Dict, List, Tuple
16
13
 
17
14
  SPEED_MULTIPLIER = 1.5
18
15
  FRAME_INTERVAL_MS = 16
@@ -7,8 +7,11 @@ import uuid
7
7
  from typing import TYPE_CHECKING, Any, Callable, Dict, Tuple
8
8
 
9
9
  from echotools.media.web.broker import RequestBroker
10
- from echotools.media.web.stats import RequestStats
11
- from echotools.media.web.stats import build_body_info, extract_response_text
10
+ from echotools.media.web.stats import (
11
+ RequestStats,
12
+ build_body_info,
13
+ extract_response_text,
14
+ )
12
15
 
13
16
  if TYPE_CHECKING:
14
17
  from aiohttp import web as aiohttp_web
@@ -3,14 +3,12 @@ from __future__ import annotations
3
3
  """插件注册表:发现、注册、启停、热重载。"""
4
4
 
5
5
  import asyncio
6
- import sys
7
6
  from typing import Any, Dict, List, Optional, Type
8
7
 
9
8
  from echotools.base.logger.manager import get_logger
10
9
  from echotools.plat.plugin.base import Plugin
11
10
  from echotools.plat.plugin.discovery import discover_plugins
12
11
  from echotools.plat.plugin.registry_ops import (
13
- find_plugin_instance,
14
12
  init_discovered_plugin,
15
13
  purge_package_modules,
16
14
  reload_plugin,
@@ -1,11 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- import asyncio
4
3
  import sys
5
- from typing import Any, Dict, List, Optional, Type
4
+ from typing import Any, List, Optional
6
5
 
7
6
  from echotools.base.logger.manager import get_logger
8
- from echotools.plat.plugin.discovery import discover_plugins
9
7
 
10
8
  logger = get_logger(__name__)
11
9
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: echotools
3
- Version: 2.3.10
3
+ Version: 2.3.11
4
4
  Summary: 通用基础设施 SDK:配置、日志、事件、调度、插件、协议、调用链
5
5
  Author: nichengfuben
6
6
  License: MIT
@@ -31,3 +31,21 @@ def test_lazy_fncall_exports() -> None:
31
31
 
32
32
  assert echotools.get_protocol is not None
33
33
  assert echotools.inject_fncall is not None
34
+
35
+
36
+ def test_legacy_config_import_without_package_init() -> None:
37
+ import importlib
38
+ import sys
39
+
40
+ for name in list(sys.modules):
41
+ if name == "echotools" or name.startswith("echotools."):
42
+ sys.modules.pop(name, None)
43
+
44
+ compat = importlib.import_module("echotools.compat")
45
+ assert compat.install_compat_aliases is not None
46
+
47
+ from echotools.config.center import ConfigCenter
48
+ from echotools.config.loader import write_toml
49
+
50
+ assert ConfigCenter is not None
51
+ assert callable(write_toml)
File without changes
File without changes
File without changes
@@ -8,9 +8,9 @@ from __future__ import annotations
8
8
  import importlib
9
9
  from typing import Any
10
10
 
11
- from echotools.version import get_version
12
- from echotools.plat.sdk import EchoTools
13
11
  from echotools.compat import install_compat_aliases
12
+ from echotools.plat.sdk import EchoTools
13
+ from echotools.version import get_version
14
14
 
15
15
  install_compat_aliases()
16
16
 
@@ -21,6 +21,8 @@ from typing import (
21
21
  Union,
22
22
  )
23
23
 
24
+ from echotools.base.errors.common import NoCandidateError
25
+ from echotools.base.logger.manager import get_logger
24
26
  from echotools.exec.dispatch.candidate import TaskCandidate
25
27
  from echotools.exec.dispatch.race import (
26
28
  apply_queue_event,
@@ -31,8 +33,6 @@ from echotools.exec.dispatch.race import (
31
33
  race_worker,
32
34
  )
33
35
  from echotools.exec.dispatch.selector import AdaptiveSelector
34
- from echotools.base.errors.common import NoCandidateError
35
- from echotools.base.logger.manager import get_logger
36
36
 
37
37
  __all__ = ["TaskDispatcher"]
38
38
 
@@ -22,9 +22,9 @@ from dataclasses import dataclass
22
22
  from pathlib import Path
23
23
  from typing import Any, Dict, List, Optional, Set, Tuple
24
24
 
25
- from echotools.exec.dispatch.candidate import TaskCandidate
26
25
  from echotools.base.io.io_utils import atomic_write_text
27
26
  from echotools.base.logger.manager import get_logger
27
+ from echotools.exec.dispatch.candidate import TaskCandidate
28
28
 
29
29
  __all__ = ["AdaptiveSelector", "TASRecord"]
30
30
 
@@ -10,6 +10,7 @@ import re
10
10
  import uuid
11
11
  from typing import Any, Dict, List, Optional, Tuple
12
12
 
13
+ from echotools.base.logger.manager import get_logger
13
14
  from echotools.exec.fncall.parsers.xml_params import make_tool_call, parse_param_xml
14
15
  from echotools.exec.fncall.shared.coercion import (
15
16
  _build_param_schema_index,
@@ -22,7 +23,6 @@ from echotools.exec.fncall.shared.xml_helpers import (
22
23
  _PROVIDER_PARAM_RE,
23
24
  extract_cdata,
24
25
  )
25
- from echotools.base.logger.manager import get_logger
26
26
 
27
27
  logger = get_logger(__name__)
28
28
 
@@ -5,6 +5,8 @@ from __future__ import annotations
5
5
  import os
6
6
  from typing import Any, Dict, List, Optional
7
7
 
8
+ from echotools.base.ids.generator import uuid7
9
+ from echotools.base.logger.manager import get_logger
8
10
  from echotools.exec.fncall.prompt.history import (
9
11
  _normalize_messages,
10
12
  )
@@ -22,8 +24,6 @@ from echotools.exec.fncall.protocols.entml import (
22
24
  from echotools.exec.fncall.shared.loop_detect import detect_tool_loop
23
25
  from echotools.exec.fncall.shared.normalization import format_tool_descs
24
26
  from echotools.exec.protocol.base import ToolProtocol
25
- from echotools.base.ids.generator import uuid7
26
- from echotools.base.logger.manager import get_logger
27
27
 
28
28
  __all__ = ["inject_fncall"]
29
29
 
@@ -1,5 +1,6 @@
1
1
  """共享工具导出。"""
2
2
 
3
+ from echotools.base.ids.generator import uuid7
3
4
  from echotools.exec.fncall.shared.coercion import (
4
5
  _build_param_schema_index,
5
6
  _coerce_param_value,
@@ -14,7 +15,6 @@ from echotools.exec.fncall.shared.normalization import (
14
15
  normalize_tool_call,
15
16
  normalize_tool_calls,
16
17
  )
17
- from echotools.base.ids.generator import uuid7
18
18
 
19
19
  __all__ = [
20
20
  "normalize_content",
@@ -7,8 +7,8 @@ import inspect
7
7
  from collections import defaultdict
8
8
  from typing import Awaitable, Callable, DefaultDict, List, Type, Union
9
9
 
10
- from echotools.media.events.event import Event
11
10
  from echotools.base.logger.manager import get_logger
11
+ from echotools.media.events.event import Event
12
12
 
13
13
  __all__ = ["EventBus"]
14
14
 
@@ -8,16 +8,16 @@ from typing import FrozenSet, Optional, Set
8
8
 
9
9
  from echotools.base.cache.memory_cache import MemoryCache
10
10
  from echotools.base.config.center import ConfigCenter
11
+ from echotools.base.logger.manager import LoggerManager, get_logger
11
12
  from echotools.exec.dispatch.dispatcher import TaskDispatcher
12
13
  from echotools.exec.dispatch.selector import AdaptiveSelector
13
- from echotools.media.events.bus import EventBus
14
14
  from echotools.exec.lifecycle.manager import LifecycleManager
15
- from echotools.base.logger.manager import LoggerManager, get_logger
15
+ from echotools.media.events.bus import EventBus
16
+ from echotools.media.tracing.tracer import Tracer
16
17
  from echotools.plat.plugin.registry import PluginRegistry
17
18
  from echotools.plat.proxy.manager import ProxyManager
18
19
  from echotools.plat.runtime.collector import RuntimeCollector
19
20
  from echotools.plat.scheduler.scheduler import TaskScheduler
20
- from echotools.media.tracing.tracer import Tracer
21
21
 
22
22
  __all__ = ["EchoTools"]
23
23
 
@@ -11,17 +11,9 @@ from unittest.mock import patch
11
11
 
12
12
  import pytest
13
13
 
14
- from echotools.version import get_version
15
14
  from echotools.base.cache import ListCache, MemoryCache
16
- from echotools.exec.dispatch import TaskCandidate, TaskDispatcher
17
- from echotools.exec.dispatch.proxy_selector import ProxyRecord, ProxySelector
18
- from echotools.exec.dispatch.selector import AdaptiveSelector, TASRecord
19
- from echotools.exec.dispatch.usage import fallback_usage, normalize_usage
20
15
  from echotools.base.errors.http import ForbiddenError, StreamError
21
- from echotools.media.events import Event, EventBus
22
16
  from echotools.base.io import atomic_write_text, read_text_if_exists
23
- from echotools.exec.keys import KeyPool, KeyState
24
- from echotools.exec.lifecycle import LifecycleManager
25
17
  from echotools.base.logger.manager import LoggerManager, _LogFormatter, _supports_color
26
18
  from echotools.base.retry import (
27
19
  retry_async_generator,
@@ -29,7 +21,13 @@ from echotools.base.retry import (
29
21
  retry_on_exception,
30
22
  retry_with_backoff,
31
23
  )
32
- from echotools.plat.scheduler import TaskScheduler
24
+ from echotools.exec.dispatch import TaskCandidate, TaskDispatcher
25
+ from echotools.exec.dispatch.proxy_selector import ProxyRecord, ProxySelector
26
+ from echotools.exec.dispatch.selector import AdaptiveSelector, TASRecord
27
+ from echotools.exec.dispatch.usage import fallback_usage, normalize_usage
28
+ from echotools.exec.keys import KeyPool, KeyState
29
+ from echotools.exec.lifecycle import LifecycleManager
30
+ from echotools.media.events import Event, EventBus
33
31
  from echotools.media.tracing.context import (
34
32
  get_current_span_id,
35
33
  get_current_trace_id,
@@ -44,6 +42,8 @@ from echotools.media.tracing.tracer import Tracer
44
42
  from echotools.media.web import stats as stats_mod
45
43
  from echotools.media.web.broker import RequestBroker, request_broker
46
44
  from echotools.media.web.stats import RequestStats
45
+ from echotools.plat.scheduler import TaskScheduler
46
+ from echotools.version import get_version
47
47
 
48
48
 
49
49
  class _MockWS:
@@ -2,9 +2,9 @@ from __future__ import annotations
2
2
 
3
3
  import pytest
4
4
 
5
+ from echotools.base.errors import NoCandidateError
5
6
  from echotools.exec.dispatch import TaskCandidate, TaskDispatcher, make_id
6
7
  from echotools.exec.dispatch.selector import AdaptiveSelector
7
- from echotools.base.errors import NoCandidateError
8
8
 
9
9
 
10
10
  @pytest.mark.asyncio