echotools 2.3.55__tar.gz → 2.3.56__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 (227) hide show
  1. {echotools-2.3.55 → echotools-2.3.56}/PKG-INFO +1 -1
  2. {echotools-2.3.55 → echotools-2.3.56}/pyproject.toml +1 -1
  3. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/protocols/entml_tools.py +29 -3
  4. {echotools-2.3.55 → echotools-2.3.56}/src/echotools.egg-info/PKG-INFO +1 -1
  5. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_entml_protocol.py +1 -1
  6. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_entml_tool_pipeline.py +3 -1
  7. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_entml_tools.py +32 -5
  8. {echotools-2.3.55 → echotools-2.3.56}/README.md +0 -0
  9. {echotools-2.3.55 → echotools-2.3.56}/docs/README.md +0 -0
  10. {echotools-2.3.55 → echotools-2.3.56}/setup.cfg +0 -0
  11. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/__init__.py +0 -0
  12. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/cache/__init__.py +0 -0
  13. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/cache/list_cache.py +0 -0
  14. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/cache/memory_cache.py +0 -0
  15. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/config/__init__.py +0 -0
  16. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/config/base.py +0 -0
  17. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/config/center.py +0 -0
  18. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/config/center_notify.py +0 -0
  19. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/config/center_template.py +0 -0
  20. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/config/loader.py +0 -0
  21. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/config/merge.py +0 -0
  22. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/errors/__init__.py +0 -0
  23. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/errors/base.py +0 -0
  24. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/errors/classify.py +0 -0
  25. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/errors/common.py +0 -0
  26. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/errors/http.py +0 -0
  27. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/ids/__init__.py +0 -0
  28. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/ids/generator.py +0 -0
  29. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/io/__init__.py +0 -0
  30. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/io/io_utils.py +0 -0
  31. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/io/printstream.py +0 -0
  32. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/logger/__init__.py +0 -0
  33. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/logger/manager.py +0 -0
  34. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/retry/__init__.py +0 -0
  35. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/base/retry/retry.py +0 -0
  36. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/compat.py +0 -0
  37. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/dispatch/__init__.py +0 -0
  38. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/dispatch/candidate.py +0 -0
  39. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/dispatch/dispatcher.py +0 -0
  40. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/dispatch/proxy_selector.py +0 -0
  41. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/dispatch/race.py +0 -0
  42. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/dispatch/selector.py +0 -0
  43. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/dispatch/usage.py +0 -0
  44. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/__init__.py +0 -0
  45. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/parsers/__init__.py +0 -0
  46. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/parsers/stream.py +0 -0
  47. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/parsers/xml_params.py +0 -0
  48. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/parsers/xml_parser.py +0 -0
  49. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/prompt/__init__.py +0 -0
  50. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/prompt/history.py +0 -0
  51. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/prompt/history_format.py +0 -0
  52. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/prompt/inject.py +0 -0
  53. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/prompt/prompt_helpers.py +0 -0
  54. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/prompt/templates.py +0 -0
  55. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/protocols/__init__.py +0 -0
  56. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/protocols/entml.py +0 -0
  57. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/protocols/entml_invoke.py +0 -0
  58. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/protocols/entml_patterns.py +0 -0
  59. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/protocols/entml_stream_json.py +0 -0
  60. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/protocols/entml_think/__init__.py +0 -0
  61. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/protocols/entml_think/core.py +0 -0
  62. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/protocols/entml_think/hist.py +0 -0
  63. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/protocols/entml_think/parse.py +0 -0
  64. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/protocols/entml_values.py +0 -0
  65. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/registry.py +0 -0
  66. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/shared/__init__.py +0 -0
  67. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/shared/coercion.py +0 -0
  68. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/shared/loop_detect.py +0 -0
  69. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/shared/normalization.py +0 -0
  70. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/shared/schema_render.py +0 -0
  71. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/fncall/shared/xml_helpers.py +0 -0
  72. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/keys.py +0 -0
  73. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/lifecycle/__init__.py +0 -0
  74. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/lifecycle/manager.py +0 -0
  75. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/lifecycle/updater.py +0 -0
  76. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/lifecycle/updater_pull.py +0 -0
  77. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/process/__init__.py +0 -0
  78. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/process/port.py +0 -0
  79. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/protocol/__init__.py +0 -0
  80. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/protocol/base.py +0 -0
  81. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/__init__.py +0 -0
  82. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/conpty.py +0 -0
  83. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/local/__init__.py +0 -0
  84. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/local/core.py +0 -0
  85. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/local/proc.py +0 -0
  86. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/local/unix.py +0 -0
  87. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/local/win.py +0 -0
  88. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/sanitize.py +0 -0
  89. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/session/__init__.py +0 -0
  90. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/session/base.py +0 -0
  91. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/session/client.py +0 -0
  92. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/ssh.py +0 -0
  93. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/exec/terminal/tmux.py +0 -0
  94. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/__init__.py +0 -0
  95. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/charmap.py +0 -0
  96. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/spinner.py +0 -0
  97. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/ui.py +0 -0
  98. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/mixins/__init__.py +0 -0
  99. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/mixins/uibase.py +0 -0
  100. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/mixins/uicmds.py +0 -0
  101. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/mixins/uiinteract.py +0 -0
  102. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/mixins/uioutput.py +0 -0
  103. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/mixins/uistream.py +0 -0
  104. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/ui_console.py +0 -0
  105. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/ui_io.py +0 -0
  106. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/ui_log.py +0 -0
  107. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/ui_platform.py +0 -0
  108. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/ui_text.py +0 -0
  109. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uicore/ui_types.py +0 -0
  110. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uilayout/ui_countdown.py +0 -0
  111. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uilayout/ui_layout.py +0 -0
  112. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uilayout/ui_misc.py +0 -0
  113. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uilayout/ui_panel.py +0 -0
  114. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uilayout/ui_table.py +0 -0
  115. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uilayout/ui_tree.py +0 -0
  116. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uiwidgets/ui_box.py +0 -0
  117. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uiwidgets/ui_editor.py +0 -0
  118. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uiwidgets/ui_progress.py +0 -0
  119. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uiwidgets/ui_select.py +0 -0
  120. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/console/uiwidgets/ui_stream.py +0 -0
  121. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/events/__init__.py +0 -0
  122. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/events/bus.py +0 -0
  123. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/events/event.py +0 -0
  124. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/spinner/__init__.py +0 -0
  125. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/spinner/spinner.py +0 -0
  126. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/spinner/spinner_color.py +0 -0
  127. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/tracing/__init__.py +0 -0
  128. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/tracing/context.py +0 -0
  129. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/tracing/span.py +0 -0
  130. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/tracing/tracer.py +0 -0
  131. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/translate.py +0 -0
  132. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/watcher/__init__.py +0 -0
  133. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/watcher/file_watcher.py +0 -0
  134. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/__init__.py +0 -0
  135. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/application.py +0 -0
  136. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/broker.py +0 -0
  137. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/app.js +0 -0
  138. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/components/filezone.js +0 -0
  139. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/components/motionkit.js +0 -0
  140. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/components/sendbutton.js +0 -0
  141. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/components/sortablelist.css +0 -0
  142. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/components/sortablelist.js +0 -0
  143. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/components/textinput.js +0 -0
  144. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/components/voiceinput.js +0 -0
  145. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/fonts/inter-500.woff2 +0 -0
  146. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/fonts/inter-600.woff2 +0 -0
  147. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/fonts/inter400.woff2 +0 -0
  148. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/inputbox.css +0 -0
  149. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/inputbox.js +0 -0
  150. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/style.css +0 -0
  151. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/input_box/voicegif.js +0 -0
  152. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/middleware.py +0 -0
  153. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/stats.py +0 -0
  154. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/media/web/utils.py +0 -0
  155. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/files/__init__.py +0 -0
  156. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/files/file_util.py +0 -0
  157. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/network/__init__.py +0 -0
  158. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/network/http_utils.py +0 -0
  159. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/plugin/__init__.py +0 -0
  160. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/plugin/base.py +0 -0
  161. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/plugin/discovery.py +0 -0
  162. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/plugin/registry.py +0 -0
  163. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/plugin/registry_ops.py +0 -0
  164. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/proxy/__init__.py +0 -0
  165. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/proxy/manager.py +0 -0
  166. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/runtime/__init__.py +0 -0
  167. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/runtime/collector.py +0 -0
  168. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/scheduler/__init__.py +0 -0
  169. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/scheduler/scheduler.py +0 -0
  170. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/sdk/__init__.py +0 -0
  171. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/plat/sdk/facade.py +0 -0
  172. {echotools-2.3.55 → echotools-2.3.56}/src/echotools/version.py +0 -0
  173. {echotools-2.3.55 → echotools-2.3.56}/src/echotools.egg-info/SOURCES.txt +0 -0
  174. {echotools-2.3.55 → echotools-2.3.56}/src/echotools.egg-info/dependency_links.txt +0 -0
  175. {echotools-2.3.55 → echotools-2.3.56}/src/echotools.egg-info/requires.txt +0 -0
  176. {echotools-2.3.55 → echotools-2.3.56}/src/echotools.egg-info/top_level.txt +0 -0
  177. {echotools-2.3.55 → echotools-2.3.56}/src/tests/bench_import.py +0 -0
  178. {echotools-2.3.55 → echotools-2.3.56}/src/tests/conftest.py +0 -0
  179. {echotools-2.3.55 → echotools-2.3.56}/src/tests/fixtures/__init__.py +0 -0
  180. {echotools-2.3.55 → echotools-2.3.56}/src/tests/fixtures/simulated_llm_tool_responses.py +0 -0
  181. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_adversarial_stream_splits.py +0 -0
  182. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_cache_retry.py +0 -0
  183. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_completion.py +0 -0
  184. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_config.py +0 -0
  185. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_config_extended.py +0 -0
  186. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_console.py +0 -0
  187. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_coverage_core.py +0 -0
  188. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_dispatch.py +0 -0
  189. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_dispatch_extended.py +0 -0
  190. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_dispatch_race.py +0 -0
  191. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_entml_agent_output_formats.py +0 -0
  192. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_entml_bare_invoke_format.py +0 -0
  193. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_entml_parser_comprehensive.py +0 -0
  194. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_entml_stream_json.py +0 -0
  195. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_entml_stream_json_exhaustive.py +0 -0
  196. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_entml_thinking_history.py +0 -0
  197. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_entml_thinking_parse.py +0 -0
  198. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_entml_tool_parse_leak.py +0 -0
  199. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_errors.py +0 -0
  200. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_errors_common.py +0 -0
  201. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_events.py +0 -0
  202. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_events_event.py +0 -0
  203. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_facade.py +0 -0
  204. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_fncall.py +0 -0
  205. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_fncall_stream_thinking.py +0 -0
  206. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_ids.py +0 -0
  207. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_imports.py +0 -0
  208. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_io.py +0 -0
  209. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_keys.py +0 -0
  210. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_lifecycle.py +0 -0
  211. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_logger.py +0 -0
  212. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_merge.py +0 -0
  213. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_model_branch_matrix.py +0 -0
  214. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_plugin.py +0 -0
  215. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_printstream.py +0 -0
  216. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_protocols.py +0 -0
  217. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_proxy.py +0 -0
  218. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_proxy_selector.py +0 -0
  219. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_runtime.py +0 -0
  220. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_scheduler.py +0 -0
  221. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_simulated_llm_tool_parse.py +0 -0
  222. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_stream_partial_json_parity.py +0 -0
  223. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_stream_realtime_parse.py +0 -0
  224. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_tracing.py +0 -0
  225. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_usage.py +0 -0
  226. {echotools-2.3.55 → echotools-2.3.56}/src/tests/test_web.py +0 -0
  227. {echotools-2.3.55 → echotools-2.3.56}/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.55
3
+ Version: 2.3.56
4
4
  Summary: 通用基础设施 SDK:配置、日志、事件、调度、插件、协议、调用链
5
5
  Home-page: https://github.com/nichengfuben/echotools
6
6
  Author: nichengfuben
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "echotools"
7
- version = "2.3.55"
7
+ version = "2.3.56"
8
8
  description = "通用基础设施 SDK:配置、日志、事件、调度、插件、协议、调用链"
9
9
  readme = "docs/README.md"
10
10
  requires-python = ">=3.8"
@@ -87,6 +87,33 @@ def _expand_description_multiline(json_text: str) -> str:
87
87
  return _DESC_LINE_RE.sub(_repl, json_text)
88
88
 
89
89
 
90
+ def _normalize_tool_description(description: Any) -> str:
91
+ """将上游字面量 \\n / \\_ / \\* 等还原为可读文本。"""
92
+ if not description:
93
+ return ""
94
+ text = str(description)
95
+ while "\\n" in text or "\\r" in text or "\\t" in text:
96
+ prev = text
97
+ text = (
98
+ text.replace("\\r\\n", "\n")
99
+ .replace("\\n", "\n")
100
+ .replace("\\t", "\t")
101
+ )
102
+ if text == prev:
103
+ break
104
+ for old, new in (("\\_", "_"), ("\\*", "*")):
105
+ text = text.replace(old, new)
106
+ return text
107
+
108
+
109
+ def _format_top_level_description(description: Any) -> str:
110
+ """顶层 Description:真换行排版,不再包 JSON 字符串引号。"""
111
+ text = _normalize_tool_description(description)
112
+ if not text:
113
+ return "Description:"
114
+ return f"Description:\n{text}"
115
+
116
+
90
117
  def _format_parameters_json(params: Mapping[str, Any]) -> str:
91
118
  sorted_params = _sort_schema_keys(dict(params))
92
119
  body = json.dumps(sorted_params, ensure_ascii=False, indent=2)
@@ -103,12 +130,11 @@ def format_entml_tool_descs(tools: List[Dict[str, Any]]) -> str:
103
130
  fn = tool.get("function", tool)
104
131
  name = str(fn.get("name") or "unknown")
105
132
  description = fn.get("description") or ""
106
- # Description 外置为 JSON 字符串字面量(含转义),与示范一致
107
- desc_literal = json.dumps(description, ensure_ascii=False)
133
+ desc_block = _format_top_level_description(description)
108
134
  params_body = _format_parameters_json(_normalize_parameters(fn.get("parameters")))
109
135
  blocks.append(
110
136
  f"### {name}\n\n"
111
- f"Description: {desc_literal}\n\n"
137
+ f"{desc_block}\n\n"
112
138
  f"```json\n{params_body}\n```"
113
139
  )
114
140
  return "\n\n".join(blocks)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: echotools
3
- Version: 2.3.55
3
+ Version: 2.3.56
4
4
  Summary: 通用基础设施 SDK:配置、日志、事件、调度、插件、协议、调用链
5
5
  Home-page: https://github.com/nichengfuben/echotools
6
6
  Author: nichengfuben
@@ -572,7 +572,7 @@ def test_entml_instruction_matches_spec_format() -> None:
572
572
  assert "```text" not in prompt
573
573
  assert "### ask_user_input_v0" in prompt
574
574
  assert "**ask_user_input_v0**" not in prompt
575
- assert 'Description: "Ask user"' in prompt
575
+ assert "Description:\nAsk user" in prompt
576
576
  assert '"name": "ask_user_input_v0"' not in prompt
577
577
  assert "<entml:function_calls>" not in prompt
578
578
  assert '<entml:invoke name="$FUNCTION_NAME">' in prompt
@@ -670,7 +670,9 @@ class TestBuildMechanisms:
670
670
  def test_format_tool_descs_structure(self) -> None:
671
671
  out = format_entml_tool_descs(RICH_TOOLS)
672
672
  assert "### rich_tool" in out
673
- assert 'Description: "All scalar and container types.\\nLine two."' in out
673
+ assert (
674
+ "Description:\nAll scalar and container types.\nLine two."
675
+ ) in out
674
676
  assert '"properties"' in out
675
677
  assert out.index('"properties"') < out.index('"type"')
676
678
  assert "```json" in out
@@ -51,7 +51,7 @@ def test_entml_tool_descs_heading_and_description_outside_json() -> None:
51
51
  out = format_entml_tool_descs([ASK_USER_TOOL])
52
52
  assert "### ask_user_input_v0" in out
53
53
  assert "**ask_user_input_v0**" not in out
54
- assert 'Description: "USE THIS TOOL WHENEVER YOU HAVE A QUESTION FOR THE USER.' in out
54
+ assert "Description:\nUSE THIS TOOL WHENEVER YOU HAVE A QUESTION FOR THE USER." in out
55
55
  # name / top-level description 不再塞进 parameters JSON
56
56
  assert '"name": "ask_user_input_v0"' not in out
57
57
  assert out.count("```json") == 1
@@ -71,12 +71,39 @@ def test_entml_tool_descs_include_schema_types_and_required() -> None:
71
71
 
72
72
  def test_entml_tool_descs_expand_multiline_description() -> None:
73
73
  out = format_entml_tool_descs([ASK_USER_TOOL])
74
- # 外置 Description 为 JSON 字符串字面量,换行以 \n 转义
75
- assert "USE THIS TOOL WHENEVER YOU HAVE A QUESTION FOR THE USER.\\n\\nUSE THIS TOOL WHEN:\\n" in out
76
- # parameters 内嵌 description 仍可展开多行
74
+ # 外置 Description 展开为物理换行,不再堆在一行的 \\n 转义里
75
+ assert (
76
+ "Description:\nUSE THIS TOOL WHENEVER YOU HAVE A QUESTION FOR THE USER.\n\n"
77
+ "USE THIS TOOL WHEN:\n"
78
+ ) in out
79
+ assert "\\n" not in out.split("```json")[0]
77
80
  assert "1-3 questions to ask the user" in out
78
81
 
79
82
 
83
+ def test_entml_tool_descs_unescape_api_markdown_escapes() -> None:
84
+ desc = (
85
+ r"Launch agent.\n\n"
86
+ r'Use `subagent\_type: "fork"` for forks.\n'
87
+ r"**Don't peek.**"
88
+ )
89
+ tool = {
90
+ "type": "function",
91
+ "function": {
92
+ "name": "Agent",
93
+ "description": desc,
94
+ "parameters": {"type": "object", "properties": {}},
95
+ },
96
+ }
97
+ out = format_entml_tool_descs([tool])
98
+ head = out.split("```json")[0]
99
+ assert "subagent_type:" in head
100
+ assert "fork" in head
101
+ assert "\\_" not in head
102
+ assert "**Don't peek.**" in head
103
+ assert "\\n\\n" not in head
104
+ assert "Launch agent.\n\n" in out
105
+
106
+
80
107
  def test_entml_tool_descs_schema_key_order() -> None:
81
108
  out = format_entml_tool_descs([ASK_USER_TOOL])
82
109
  # parameters 块内:properties 先于 type
@@ -114,6 +141,6 @@ def test_entml_tool_descs_matches_design_shape() -> None:
114
141
  }
115
142
  ]
116
143
  out = format_entml_tool_descs(tools)
117
- assert out.startswith("### bash_tool\n\nDescription: \"Run a bash command")
144
+ assert out.startswith("### bash_tool\n\nDescription:\nRun a bash command")
118
145
  assert '"title": "BashInput"' in out
119
146
  assert '"name":' not in out
File without changes
File without changes
File without changes