echotools 2.3.97__tar.gz → 2.3.99__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 (249) hide show
  1. {echotools-2.3.97 → echotools-2.3.99}/PKG-INFO +1 -1
  2. {echotools-2.3.97 → echotools-2.3.99}/pyproject.toml +1 -1
  3. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml.py +5 -0
  4. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_fake_structure_markup.py +26 -0
  5. {echotools-2.3.97 → echotools-2.3.99}/src/echotools.egg-info/PKG-INFO +1 -1
  6. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_fake_structure_markup.py +104 -0
  7. {echotools-2.3.97 → echotools-2.3.99}/README.md +0 -0
  8. {echotools-2.3.97 → echotools-2.3.99}/setup.cfg +0 -0
  9. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/__init__.py +0 -0
  10. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/cache/__init__.py +0 -0
  11. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/cache/list_cache.py +0 -0
  12. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/cache/memory_cache.py +0 -0
  13. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/config/__init__.py +0 -0
  14. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/config/base.py +0 -0
  15. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/config/center.py +0 -0
  16. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/config/center_notify.py +0 -0
  17. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/config/center_template.py +0 -0
  18. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/config/loader.py +0 -0
  19. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/config/merge.py +0 -0
  20. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/errors/__init__.py +0 -0
  21. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/errors/base.py +0 -0
  22. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/errors/classify.py +0 -0
  23. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/errors/common.py +0 -0
  24. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/errors/http.py +0 -0
  25. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/ids/__init__.py +0 -0
  26. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/ids/generator.py +0 -0
  27. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/io/__init__.py +0 -0
  28. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/io/io_utils.py +0 -0
  29. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/io/printstream.py +0 -0
  30. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/logger/__init__.py +0 -0
  31. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/logger/manager.py +0 -0
  32. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/retry/__init__.py +0 -0
  33. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/base/retry/retry.py +0 -0
  34. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/compat.py +0 -0
  35. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/dispatch/__init__.py +0 -0
  36. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/dispatch/candidate.py +0 -0
  37. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/dispatch/dispatcher.py +0 -0
  38. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/dispatch/proxy_selector.py +0 -0
  39. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/dispatch/race.py +0 -0
  40. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/dispatch/selector.py +0 -0
  41. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/dispatch/usage.py +0 -0
  42. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/__init__.py +0 -0
  43. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/parsers/__init__.py +0 -0
  44. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/parsers/stream.py +0 -0
  45. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/parsers/stream_delta.py +0 -0
  46. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/parsers/stream_feed.py +0 -0
  47. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/parsers/stream_final.py +0 -0
  48. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/parsers/xml_params.py +0 -0
  49. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/parsers/xml_parser.py +0 -0
  50. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/prompt/__init__.py +0 -0
  51. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/prompt/behavior_blocks.py +0 -0
  52. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/prompt/history.py +0 -0
  53. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/prompt/history_format.py +0 -0
  54. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/prompt/inject.py +0 -0
  55. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/prompt/prompt_helpers.py +0 -0
  56. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/prompt/templates.py +0 -0
  57. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/__init__.py +0 -0
  58. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_invoke.py +0 -0
  59. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_patterns.py +0 -0
  60. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_schema.py +0 -0
  61. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_stream/__init__.py +0 -0
  62. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_stream/body.py +0 -0
  63. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_stream/snap.py +0 -0
  64. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_think/__init__.py +0 -0
  65. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_think/blocks.py +0 -0
  66. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_think/core.py +0 -0
  67. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_think/filter.py +0 -0
  68. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_think/hist.py +0 -0
  69. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_think/hold.py +0 -0
  70. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_think/parse.py +0 -0
  71. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/protocols/entml_tool_result_comment.py +0 -0
  72. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/registry.py +0 -0
  73. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/shared/__init__.py +0 -0
  74. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/shared/coercion.py +0 -0
  75. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/shared/history_markup.py +0 -0
  76. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/shared/loop_detect.py +0 -0
  77. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/shared/normalization.py +0 -0
  78. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/shared/schema_render.py +0 -0
  79. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/fncall/shared/xml_helpers.py +0 -0
  80. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/keys.py +0 -0
  81. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/lifecycle/__init__.py +0 -0
  82. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/lifecycle/manager.py +0 -0
  83. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/lifecycle/updater.py +0 -0
  84. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/lifecycle/updater_pull.py +0 -0
  85. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/process/__init__.py +0 -0
  86. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/process/port.py +0 -0
  87. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/protocol/__init__.py +0 -0
  88. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/protocol/base.py +0 -0
  89. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/__init__.py +0 -0
  90. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/conpty.py +0 -0
  91. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/local/__init__.py +0 -0
  92. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/local/core.py +0 -0
  93. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/local/proc.py +0 -0
  94. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/local/unix.py +0 -0
  95. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/local/win.py +0 -0
  96. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/sanitize.py +0 -0
  97. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/session/__init__.py +0 -0
  98. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/session/base.py +0 -0
  99. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/session/client.py +0 -0
  100. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/ssh.py +0 -0
  101. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/exec/terminal/tmux.py +0 -0
  102. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/__init__.py +0 -0
  103. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/charmap.py +0 -0
  104. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/spinner.py +0 -0
  105. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/ui.py +0 -0
  106. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/mixins/__init__.py +0 -0
  107. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/mixins/uibase.py +0 -0
  108. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/mixins/uicmds.py +0 -0
  109. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/mixins/uiinteract.py +0 -0
  110. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/mixins/uioutput.py +0 -0
  111. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/mixins/uistream.py +0 -0
  112. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/ui_console.py +0 -0
  113. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/ui_io.py +0 -0
  114. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/ui_log.py +0 -0
  115. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/ui_platform.py +0 -0
  116. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/ui_text.py +0 -0
  117. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uicore/ui_types.py +0 -0
  118. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uilayout/ui_countdown.py +0 -0
  119. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uilayout/ui_layout.py +0 -0
  120. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uilayout/ui_misc.py +0 -0
  121. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uilayout/ui_panel.py +0 -0
  122. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uilayout/ui_table.py +0 -0
  123. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uilayout/ui_tree.py +0 -0
  124. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uiwidgets/ui_box.py +0 -0
  125. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uiwidgets/ui_editor.py +0 -0
  126. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uiwidgets/ui_progress.py +0 -0
  127. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uiwidgets/ui_select.py +0 -0
  128. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/console/uiwidgets/ui_stream.py +0 -0
  129. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/events/__init__.py +0 -0
  130. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/events/bus.py +0 -0
  131. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/events/event.py +0 -0
  132. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/spinner/__init__.py +0 -0
  133. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/spinner/spinner.py +0 -0
  134. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/spinner/spinner_color.py +0 -0
  135. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/tracing/__init__.py +0 -0
  136. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/tracing/context.py +0 -0
  137. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/tracing/span.py +0 -0
  138. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/tracing/tracer.py +0 -0
  139. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/translate.py +0 -0
  140. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/watcher/__init__.py +0 -0
  141. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/watcher/file_watcher.py +0 -0
  142. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/__init__.py +0 -0
  143. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/application.py +0 -0
  144. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/broker.py +0 -0
  145. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/app.js +0 -0
  146. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/components/filezone.js +0 -0
  147. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/components/motionkit.js +0 -0
  148. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/components/sendbutton.js +0 -0
  149. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/components/sortablelist.css +0 -0
  150. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/components/sortablelist.js +0 -0
  151. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/components/textinput.js +0 -0
  152. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/components/voiceinput.js +0 -0
  153. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/fonts/inter-500.woff2 +0 -0
  154. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/fonts/inter-600.woff2 +0 -0
  155. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/fonts/inter400.woff2 +0 -0
  156. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/inputbox.css +0 -0
  157. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/inputbox.js +0 -0
  158. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/style.css +0 -0
  159. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/input_box/voicegif.js +0 -0
  160. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/middleware.py +0 -0
  161. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/stats.py +0 -0
  162. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/media/web/utils.py +0 -0
  163. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/files/__init__.py +0 -0
  164. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/files/file_util.py +0 -0
  165. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/network/__init__.py +0 -0
  166. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/network/http_utils.py +0 -0
  167. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/plugin/__init__.py +0 -0
  168. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/plugin/base.py +0 -0
  169. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/plugin/discovery.py +0 -0
  170. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/plugin/registry.py +0 -0
  171. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/plugin/registry_ops.py +0 -0
  172. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/proxy/__init__.py +0 -0
  173. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/proxy/manager.py +0 -0
  174. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/runtime/__init__.py +0 -0
  175. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/runtime/collector.py +0 -0
  176. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/scheduler/__init__.py +0 -0
  177. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/scheduler/scheduler.py +0 -0
  178. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/sdk/__init__.py +0 -0
  179. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/plat/sdk/facade.py +0 -0
  180. {echotools-2.3.97 → echotools-2.3.99}/src/echotools/version.py +0 -0
  181. {echotools-2.3.97 → echotools-2.3.99}/src/echotools.egg-info/SOURCES.txt +0 -0
  182. {echotools-2.3.97 → echotools-2.3.99}/src/echotools.egg-info/dependency_links.txt +0 -0
  183. {echotools-2.3.97 → echotools-2.3.99}/src/echotools.egg-info/requires.txt +0 -0
  184. {echotools-2.3.97 → echotools-2.3.99}/src/echotools.egg-info/top_level.txt +0 -0
  185. {echotools-2.3.97 → echotools-2.3.99}/src/tests/bench_import.py +0 -0
  186. {echotools-2.3.97 → echotools-2.3.99}/src/tests/conftest.py +0 -0
  187. {echotools-2.3.97 → echotools-2.3.99}/src/tests/fixtures/__init__.py +0 -0
  188. {echotools-2.3.97 → echotools-2.3.99}/src/tests/fixtures/simulated_fake_history_markup_responses.py +0 -0
  189. {echotools-2.3.97 → echotools-2.3.99}/src/tests/fixtures/simulated_fault_thinking_responses.py +0 -0
  190. {echotools-2.3.97 → echotools-2.3.99}/src/tests/fixtures/simulated_llm_tool_responses.py +0 -0
  191. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_adversarial_stream_splits.py +0 -0
  192. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_cache_retry.py +0 -0
  193. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_completion.py +0 -0
  194. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_config.py +0 -0
  195. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_config_extended.py +0 -0
  196. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_console.py +0 -0
  197. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_coverage_core.py +0 -0
  198. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_dispatch.py +0 -0
  199. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_dispatch_extended.py +0 -0
  200. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_dispatch_race.py +0 -0
  201. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_agent_output_formats.py +0 -0
  202. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_bare_invoke_format.py +0 -0
  203. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_batch_stream_comprehensive.py +0 -0
  204. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_invoke_known_tool_gate.py +0 -0
  205. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_parser_comprehensive.py +0 -0
  206. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_protocol.py +0 -0
  207. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_stream_json.py +0 -0
  208. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_stream_json_exhaustive.py +0 -0
  209. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_thinking_history.py +0 -0
  210. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_thinking_parse.py +0 -0
  211. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_tool_parse_leak.py +0 -0
  212. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_tool_pipeline.py +0 -0
  213. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_entml_tools.py +0 -0
  214. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_errors.py +0 -0
  215. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_errors_common.py +0 -0
  216. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_events.py +0 -0
  217. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_events_event.py +0 -0
  218. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_facade.py +0 -0
  219. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_fake_history_markup_batch.py +0 -0
  220. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_fake_history_markup_invoke_preserve.py +0 -0
  221. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_fake_history_markup_reply_protect.py +0 -0
  222. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_fake_history_markup_stream.py +0 -0
  223. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_fault_thinking_close_batch.py +0 -0
  224. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_fault_thinking_close_stream.py +0 -0
  225. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_fncall.py +0 -0
  226. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_fncall_stream_thinking.py +0 -0
  227. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_history_markup_filter.py +0 -0
  228. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_ids.py +0 -0
  229. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_imports.py +0 -0
  230. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_io.py +0 -0
  231. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_keys.py +0 -0
  232. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_lifecycle.py +0 -0
  233. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_logger.py +0 -0
  234. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_merge.py +0 -0
  235. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_model_branch_matrix.py +0 -0
  236. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_plugin.py +0 -0
  237. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_printstream.py +0 -0
  238. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_protocols.py +0 -0
  239. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_proxy.py +0 -0
  240. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_proxy_selector.py +0 -0
  241. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_runtime.py +0 -0
  242. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_scheduler.py +0 -0
  243. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_simulated_llm_tool_parse.py +0 -0
  244. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_stream_partial_json_parity.py +0 -0
  245. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_stream_realtime_parse.py +0 -0
  246. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_tracing.py +0 -0
  247. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_usage.py +0 -0
  248. {echotools-2.3.97 → echotools-2.3.99}/src/tests/test_web.py +0 -0
  249. {echotools-2.3.97 → echotools-2.3.99}/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.97
3
+ Version: 2.3.99
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.97"
7
+ version = "2.3.99"
8
8
  description = "通用基础设施 SDK:配置、日志、事件、调度、插件、协议、调用链"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -349,6 +349,11 @@ class EntmlProtocol(ToolProtocol):
349
349
  if tool_calls:
350
350
  clean = strip_actionable_entml_invoke_blocks(clean, known_names=known)
351
351
  clean = strip_tool_entml_residue(clean, known_names=known)
352
+ from echotools.exec.fncall.protocols.entml_fake_structure_markup import (
353
+ strip_orphan_entml_close_tags,
354
+ )
355
+
356
+ clean, _ = strip_orphan_entml_close_tags(clean)
352
357
  return (clean, normalize_tool_calls(tool_calls, tools))
353
358
 
354
359
  def parse_fragment(
@@ -26,17 +26,21 @@ _TAG_ONLY_OPEN_RES = (
26
26
  re.compile(r"<entml:funtions_results\b[^>]*>", re.IGNORECASE),
27
27
  re.compile(r"<entml:conversation_history\b[^>]*>", re.IGNORECASE),
28
28
  re.compile(r"<entml:calls\b[^>]*>", re.IGNORECASE),
29
+ re.compile(r"<entml:call\b[^>]*>", re.IGNORECASE),
29
30
  re.compile(r"<function_calling_behavior\b[^>]*>", re.IGNORECASE),
30
31
  re.compile(r"<thinking_behavior\b[^>]*>", re.IGNORECASE),
31
32
  re.compile(r"<entml:result\b[^>]*>", re.IGNORECASE),
33
+ re.compile(r"<entml:todo\b[^>]*>", re.IGNORECASE),
32
34
  )
33
35
  _TAG_ONLY_CLOSE_RES = (
34
36
  re.compile(r"</entml:funtions_results\s*>", re.IGNORECASE),
35
37
  re.compile(r"</entml:conversation_history\s*>", re.IGNORECASE),
36
38
  re.compile(r"</entml:calls\s*>", re.IGNORECASE),
39
+ re.compile(r"</entml:call\s*>", re.IGNORECASE),
37
40
  re.compile(r"</function_calling_behavior\s*>", re.IGNORECASE),
38
41
  re.compile(r"</thinking_behavior\s*>", re.IGNORECASE),
39
42
  re.compile(r"</entml:result\s*>", re.IGNORECASE),
43
+ re.compile(r"</entml:todo\s*>", re.IGNORECASE),
40
44
  )
41
45
 
42
46
  _FAKE_ENTML_TAG_PREFIXES: Tuple[str, ...] = (
@@ -48,10 +52,14 @@ _FAKE_ENTML_TAG_PREFIXES: Tuple[str, ...] = (
48
52
  "</entml:conversation_history",
49
53
  "<entml:calls",
50
54
  "</entml:calls",
55
+ "<entml:call",
56
+ "</entml:call",
51
57
  "<function_calling_behavior",
52
58
  "</function_calling_behavior",
53
59
  "<thinking_behavior",
54
60
  "</thinking_behavior",
61
+ "<entml:todo",
62
+ "</entml:todo",
55
63
  "</entml:invoke",
56
64
  "</entml:parameter",
57
65
  "</entml:thinking",
@@ -66,6 +74,15 @@ _TRAILING_INCOMPLETE_ENTML_CLOSE_RE = re.compile(
66
74
  r"</entml:?[a-z0-9_-]*\s*$",
67
75
  re.IGNORECASE,
68
76
  )
77
+ # 完整闭标签泄漏:须在 invoke 块移除之后剥离(独立行或文末)。
78
+ _ORPHAN_ENTML_CLOSE_LINE_COMPLETE_RE = re.compile(
79
+ r"(?m)^\s*(?:●\s*)?</entml:?[a-z0-9_-]*>\s*(?:\n|$)",
80
+ re.IGNORECASE,
81
+ )
82
+ _TRAILING_ORPHAN_ENTML_CLOSE_RE = re.compile(
83
+ r"(?:\n|\A)\s*</entml:?[a-z0-9_-]*>\s*$",
84
+ re.IGNORECASE,
85
+ )
69
86
 
70
87
 
71
88
  def _strip_fake_entml_result_id_blocks(text: str) -> Tuple[str, bool]:
@@ -88,6 +105,15 @@ def _strip_orphan_entml_close_leaks(text: str) -> Tuple[str, bool]:
88
105
  return text, (n1 + n2) > 0
89
106
 
90
107
 
108
+ def strip_orphan_entml_close_tags(content: str) -> Tuple[str, bool]:
109
+ """剥离独立行或文末的完整 ``</entml:…>`` 泄漏(invoke 块已移除后调用)。"""
110
+ if not content:
111
+ return content, False
112
+ text, n1 = _ORPHAN_ENTML_CLOSE_LINE_COMPLETE_RE.subn("", content)
113
+ text, n2 = _TRAILING_ORPHAN_ENTML_CLOSE_RE.subn("", text)
114
+ return text, (n1 + n2) > 0
115
+
116
+
91
117
  def _could_be_fake_entml_tag_prefix(fragment: str) -> bool:
92
118
  frag = fragment.lower()
93
119
  if not frag.startswith("<"):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: echotools
3
- Version: 2.3.97
3
+ Version: 2.3.99
4
4
  Summary: 通用基础设施 SDK:配置、日志、事件、调度、插件、协议、调用链
5
5
  Home-page: https://github.com/nichengfuben/echotools
6
6
  Author: nichengfuben
@@ -7,6 +7,7 @@ from echotools.exec.fncall.parsers.stream import FncallStreamParser
7
7
  from echotools.exec.fncall.protocols.entml_fake_structure_markup import (
8
8
  strip_fake_entml_structure_markup,
9
9
  strip_fake_entml_structure_markup_for_display,
10
+ strip_orphan_entml_close_tags,
10
11
  )
11
12
  from echotools.exec.fncall.protocols.entml_tool_result_comment import (
12
13
  trailing_partial_tool_result_id_comment_len,
@@ -52,6 +53,12 @@ READ_TOOL = {
52
53
  "conversation_history",
53
54
  "完",
54
55
  ),
56
+ (
57
+ "前\n<entml:call>\n调用块正文\n</entml:call>\n后",
58
+ "调用块正文",
59
+ "entml:call",
60
+ "后",
61
+ ),
55
62
  (
56
63
  "前\n<entml:calls>\n调用块正文\n</entml:calls>\n后",
57
64
  "调用块正文",
@@ -76,6 +83,18 @@ READ_TOOL = {
76
83
  "entml:result",
77
84
  "ok",
78
85
  ),
86
+ (
87
+ "除此之外</entml:todo>,<entml:todo>只过滤标签",
88
+ "只过滤标签",
89
+ "entml:todo",
90
+ "除此之外",
91
+ ),
92
+ (
93
+ "前\n<entml:todo>\n正文保留\n</entml:todo>\n后",
94
+ "正文保留",
95
+ "entml:todo",
96
+ "后",
97
+ ),
79
98
  ],
80
99
  )
81
100
  def test_strip_fake_entml_structure_batch(
@@ -135,6 +154,16 @@ def test_bare_result_tags_only_not_body() -> None:
135
154
  assert "尾" in cleaned
136
155
 
137
156
 
157
+ def test_orphan_complete_entml_close_after_invoke_strip() -> None:
158
+ cleaned, found = strip_orphan_entml_close_tags("完成编辑\n</entml:invoke>")
159
+ assert found
160
+ assert cleaned.strip() == "完成编辑"
161
+ rest, found2 = strip_orphan_entml_close_tags("前\n后\n</entml:invoke>")
162
+ assert found2
163
+ assert "前" in rest and "后" in rest
164
+ assert "entml" not in rest.lower()
165
+
166
+
138
167
  def test_orphan_incomplete_entml_close_leak() -> None:
139
168
  raw = (
140
169
  "说明正文\n"
@@ -188,6 +217,81 @@ def test_batch_parse_strips_fake_structure() -> None:
188
217
  assert "funtions_results" not in clean
189
218
 
190
219
 
220
+ EDIT_TOOL = {
221
+ "type": "function",
222
+ "function": {
223
+ "name": "Edit",
224
+ "parameters": {
225
+ "type": "object",
226
+ "properties": {
227
+ "path": {"type": "string"},
228
+ "old_string": {"type": "string"},
229
+ "new_string": {"type": "string"},
230
+ "replace_all": {"type": "boolean"},
231
+ },
232
+ "required": ["path", "old_string", "new_string"],
233
+ },
234
+ },
235
+ }
236
+
237
+
238
+ def test_rogator_edit_triple_invoke_corpus_batch() -> None:
239
+ from pathlib import Path
240
+
241
+ log = (
242
+ Path(__file__).resolve().parent
243
+ / "fixtures"
244
+ / "rogator_edit_triple_orphan_close.txt"
245
+ )
246
+ raw = log.read_text(encoding="utf-8")
247
+ proto = get_protocol("entml")
248
+ clean, calls = proto.parse(raw, [EDIT_TOOL])
249
+ assert len(calls) == 3
250
+ assert all(c["function"]["name"] == "Edit" for c in calls)
251
+ assert "entml" not in clean.lower()
252
+ assert "main.py" in clean
253
+
254
+
255
+ @pytest.mark.parametrize("chunk", [1, 4, 8, 17, 32])
256
+ def test_rogator_edit_triple_invoke_corpus_stream(chunk: int) -> None:
257
+ from pathlib import Path
258
+
259
+ log = (
260
+ Path(__file__).resolve().parent
261
+ / "fixtures"
262
+ / "rogator_edit_triple_orphan_close.txt"
263
+ )
264
+ raw = log.read_text(encoding="utf-8")
265
+ parser = FncallStreamParser(protocol=get_protocol("entml"), tools=[EDIT_TOOL])
266
+ for i in range(0, len(raw), chunk):
267
+ parser.feed(raw[i : i + chunk])
268
+ pt = parser.partial_text.lower()
269
+ assert "entml:invoke" not in pt
270
+ assert "entml:parameter" not in pt
271
+ assert "</entml:invoke" not in pt
272
+ assert "entml:todo" not in pt
273
+ clean, calls = parser.finalize()
274
+ assert len(calls) == 3
275
+ assert "entml" not in clean.lower()
276
+
277
+
278
+ def test_corpus_with_inline_todo_tags_strips_tags_only() -> None:
279
+ from pathlib import Path
280
+
281
+ log = (
282
+ Path(__file__).resolve().parent
283
+ / "fixtures"
284
+ / "rogator_edit_triple_orphan_close.txt"
285
+ )
286
+ raw = log.read_text(encoding="utf-8") + "\n除此之外</entml:todo>,<entml:todo>只过滤标签"
287
+ proto = get_protocol("entml")
288
+ clean, calls = proto.parse(raw, [EDIT_TOOL])
289
+ assert len(calls) == 3
290
+ assert "entml" not in clean.lower()
291
+ assert "除此之外" in clean
292
+ assert "只过滤标签" in clean
293
+
294
+
191
295
  @pytest.mark.parametrize("chunk", [1, 4, 17, 32])
192
296
  def test_stream_partial_no_fake_structure_leak(chunk: int) -> None:
193
297
  text = (
File without changes
File without changes