echotools 2.3.87__tar.gz → 2.3.88__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.
- {echotools-2.3.87 → echotools-2.3.88}/PKG-INFO +1 -1
- {echotools-2.3.87 → echotools-2.3.88}/pyproject.toml +1 -1
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_invoke.py +6 -3
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_patterns.py +81 -5
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_stream/body.py +4 -31
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools.egg-info/PKG-INFO +1 -1
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_protocol.py +104 -0
- {echotools-2.3.87 → echotools-2.3.88}/README.md +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/setup.cfg +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/cache/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/cache/list_cache.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/cache/memory_cache.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/config/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/config/base.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/config/center.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/config/center_notify.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/config/center_template.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/config/loader.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/config/merge.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/errors/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/errors/base.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/errors/classify.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/errors/common.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/errors/http.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/ids/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/ids/generator.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/io/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/io/io_utils.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/io/printstream.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/logger/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/logger/manager.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/retry/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/base/retry/retry.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/compat.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/dispatch/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/dispatch/candidate.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/dispatch/dispatcher.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/dispatch/proxy_selector.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/dispatch/race.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/dispatch/selector.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/dispatch/usage.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/parsers/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/parsers/stream.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/parsers/stream_delta.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/parsers/stream_feed.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/parsers/stream_final.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/parsers/xml_params.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/parsers/xml_parser.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/prompt/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/prompt/history.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/prompt/history_format.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/prompt/inject.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/prompt/prompt_helpers.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/prompt/templates.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_schema.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_stream/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_stream/snap.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/blocks.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/core.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/filter.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/hist.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/hold.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/parse.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/registry.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/shared/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/shared/coercion.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/shared/history_markup.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/shared/loop_detect.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/shared/normalization.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/shared/schema_render.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/shared/xml_helpers.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/keys.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/lifecycle/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/lifecycle/manager.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/lifecycle/updater.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/lifecycle/updater_pull.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/process/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/process/port.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/protocol/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/protocol/base.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/conpty.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/local/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/local/core.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/local/proc.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/local/unix.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/local/win.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/sanitize.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/session/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/session/base.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/session/client.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/ssh.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/terminal/tmux.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/charmap.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/spinner.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/ui.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/mixins/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/mixins/uibase.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/mixins/uicmds.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/mixins/uiinteract.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/mixins/uioutput.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/mixins/uistream.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/ui_console.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/ui_io.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/ui_log.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/ui_platform.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/ui_text.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/ui_types.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uilayout/ui_countdown.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uilayout/ui_layout.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uilayout/ui_misc.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uilayout/ui_panel.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uilayout/ui_table.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uilayout/ui_tree.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uiwidgets/ui_box.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uiwidgets/ui_editor.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uiwidgets/ui_progress.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uiwidgets/ui_select.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uiwidgets/ui_stream.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/events/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/events/bus.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/events/event.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/spinner/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/spinner/spinner.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/spinner/spinner_color.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/tracing/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/tracing/context.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/tracing/span.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/tracing/tracer.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/translate.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/watcher/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/watcher/file_watcher.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/application.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/broker.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/app.js +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/components/filezone.js +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/components/motionkit.js +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/components/sendbutton.js +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/components/sortablelist.css +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/components/sortablelist.js +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/components/textinput.js +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/components/voiceinput.js +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/fonts/inter-500.woff2 +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/fonts/inter-600.woff2 +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/fonts/inter400.woff2 +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/inputbox.css +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/inputbox.js +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/style.css +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/input_box/voicegif.js +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/middleware.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/stats.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/web/utils.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/files/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/files/file_util.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/network/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/network/http_utils.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/plugin/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/plugin/base.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/plugin/discovery.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/plugin/registry.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/plugin/registry_ops.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/proxy/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/proxy/manager.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/runtime/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/runtime/collector.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/scheduler/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/scheduler/scheduler.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/sdk/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/plat/sdk/facade.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools/version.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools.egg-info/SOURCES.txt +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools.egg-info/dependency_links.txt +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools.egg-info/requires.txt +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/echotools.egg-info/top_level.txt +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/bench_import.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/conftest.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/fixtures/__init__.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/fixtures/simulated_fake_history_markup_responses.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/fixtures/simulated_fault_thinking_responses.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/fixtures/simulated_llm_tool_responses.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_adversarial_stream_splits.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_cache_retry.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_completion.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_config.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_config_extended.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_console.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_coverage_core.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_dispatch.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_dispatch_extended.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_dispatch_race.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_agent_output_formats.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_bare_invoke_format.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_batch_stream_comprehensive.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_parser_comprehensive.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_stream_json.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_stream_json_exhaustive.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_thinking_history.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_thinking_parse.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_tool_parse_leak.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_tool_pipeline.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_entml_tools.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_errors.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_errors_common.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_events.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_events_event.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_facade.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_fake_history_markup_batch.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_fake_history_markup_invoke_preserve.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_fake_history_markup_reply_protect.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_fake_history_markup_stream.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_fault_thinking_close_batch.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_fault_thinking_close_stream.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_fncall.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_fncall_stream_thinking.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_history_markup_filter.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_ids.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_imports.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_io.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_keys.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_lifecycle.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_logger.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_merge.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_model_branch_matrix.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_plugin.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_printstream.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_protocols.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_proxy.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_proxy_selector.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_runtime.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_scheduler.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_simulated_llm_tool_parse.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_stream_partial_json_parity.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_stream_realtime_parse.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_tracing.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_usage.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_web.py +0 -0
- {echotools-2.3.87 → echotools-2.3.88}/src/tests/test_web_broker.py +0 -0
|
@@ -11,6 +11,7 @@ from .entml_patterns import (
|
|
|
11
11
|
PARAMETERS_RE,
|
|
12
12
|
extract_attr_value,
|
|
13
13
|
extract_parameter_type_attr,
|
|
14
|
+
invoke_structural_gap_text,
|
|
14
15
|
iter_actionable_entml_invoke_blocks,
|
|
15
16
|
normalize_entml_name,
|
|
16
17
|
parse_sub_tags,
|
|
@@ -25,8 +26,9 @@ def _parse_direct_child_tags(
|
|
|
25
26
|
args: Dict[str, Any],
|
|
26
27
|
func_props: Dict[str, Dict[str, Any]],
|
|
27
28
|
) -> None:
|
|
28
|
-
"""模型用 ``<key>value</key>`` 代替 ``<parameter name=\"key\"
|
|
29
|
-
|
|
29
|
+
"""模型用 ``<key>value</key>`` 代替 ``<parameter name=\"key\">``(仅 structural gap)。"""
|
|
30
|
+
gap_text = invoke_structural_gap_text(body)
|
|
31
|
+
for match in INVOKE_DIRECT_CHILD_RE.finditer(gap_text):
|
|
30
32
|
key = normalize_entml_name(match.group(1))
|
|
31
33
|
if not key or key.lower() in INVOKE_DIRECT_CHILD_SKIP or key in args:
|
|
32
34
|
continue
|
|
@@ -42,7 +44,8 @@ def _parse_bare_invoke_children(
|
|
|
42
44
|
args: Dict[str, Any],
|
|
43
45
|
func_props: Dict[str, Dict[str, Any]],
|
|
44
46
|
) -> None:
|
|
45
|
-
|
|
47
|
+
gap_text = invoke_structural_gap_text(body)
|
|
48
|
+
for match in BARE_INVOKE_CHILD_RE.finditer(gap_text):
|
|
46
49
|
key = normalize_entml_name(match.group(1))
|
|
47
50
|
if not key or key in args:
|
|
48
51
|
continue
|
|
@@ -15,17 +15,22 @@ INVOKE_RE = re.compile(
|
|
|
15
15
|
r"<entml:invoke\b([^>]*)>([\s\S]*?)</entml:invoke>",
|
|
16
16
|
re.DOTALL,
|
|
17
17
|
)
|
|
18
|
+
# invoke 内直接子元素:<pattern>v</pattern>、<-n>true</-n>(标签名即参数名)
|
|
19
|
+
_INVOKE_DIRECT_TAG_NAME = r"(?:-\w+|[a-zA-Z_][\w.-]*)"
|
|
18
20
|
# 允许 name / type 等属性任意顺序;单/双引号均可。
|
|
19
|
-
#
|
|
21
|
+
# 闭合标签后必须是 invoke 内合法兄弟节点(parameter / entml 子标签 / 直接子元素 / invoke 结束)。
|
|
20
22
|
# 批量解析允许参数块在 body 末尾($);流式未闭合 invoke 不允许 $,避免 chunk 落在假闭合上误判。
|
|
21
23
|
# 模型偶发省略 entml: 前缀:<parameter name="...">...</parameter>
|
|
22
24
|
_BARE_PARAM_OPEN_TAG = r"<parameter\b(?![s>])"
|
|
23
25
|
PARAM_OPEN_PATTERN = rf"(?:<entml:parameter\b|{_BARE_PARAM_OPEN_TAG})"
|
|
24
26
|
PARAM_CLOSE_ENTML = "</entml:parameter>"
|
|
25
27
|
PARAM_CLOSE_BARE = "</parameter>"
|
|
26
|
-
# 闭合标签后必须是 invoke 内合法兄弟节点(含裸 description/timeout 等)。
|
|
27
28
|
_INVOKE_SIBLING_OPEN = r"<entml:(?!parameter\b|parameters\b|invoke\b)\w+\b"
|
|
28
|
-
|
|
29
|
+
_INVOKE_DIRECT_CHILD_OPEN = rf"<(?!entml:)({_INVOKE_DIRECT_TAG_NAME})\b"
|
|
30
|
+
_PARAM_CLOSE_FOLLOWERS = (
|
|
31
|
+
rf"(?:{PARAM_OPEN_PATTERN}|{_INVOKE_SIBLING_OPEN}|{_INVOKE_DIRECT_CHILD_OPEN}"
|
|
32
|
+
rf"|</entml:invoke>|</entml:parameters>|{re.escape(PARAM_CLOSE_BARE)})"
|
|
33
|
+
)
|
|
29
34
|
_PARAM_CLOSE_LOOKAHEAD = rf"(?=\s*{_PARAM_CLOSE_FOLLOWERS})"
|
|
30
35
|
_PARAM_CLOSE_LOOKAHEAD_EOL = rf"(?=\s*(?:{_PARAM_CLOSE_FOLLOWERS}|$))"
|
|
31
36
|
PARAM_RE = re.compile(
|
|
@@ -60,8 +65,7 @@ BARE_INVOKE_CHILD_OPEN_RE = re.compile(
|
|
|
60
65
|
r"<entml:(description|timeout)>([\s\S]*)",
|
|
61
66
|
re.DOTALL | re.IGNORECASE,
|
|
62
67
|
)
|
|
63
|
-
# invoke
|
|
64
|
-
_INVOKE_DIRECT_TAG_NAME = r"(?:-\w+|[a-zA-Z_][\w.-]*)"
|
|
68
|
+
# invoke 内直接子元素(完整/未闭合 regex 见下)
|
|
65
69
|
INVOKE_DIRECT_CHILD_RE = re.compile(
|
|
66
70
|
rf"<(?!entml:)({_INVOKE_DIRECT_TAG_NAME})>([\s\S]*?)</\1>",
|
|
67
71
|
re.DOTALL,
|
|
@@ -243,6 +247,7 @@ _FOLLOWER_PREFIXES = (
|
|
|
243
247
|
"</parameter",
|
|
244
248
|
"<entml:description",
|
|
245
249
|
"<entml:timeout",
|
|
250
|
+
"<",
|
|
246
251
|
)
|
|
247
252
|
|
|
248
253
|
|
|
@@ -270,6 +275,8 @@ def _parameter_close_follower_ok(after: str, *, allow_end: bool) -> bool:
|
|
|
270
275
|
|
|
271
276
|
|
|
272
277
|
_PARAM_OPEN_TAG_RE = re.compile(rf"{PARAM_OPEN_PATTERN}([^>]*)>", re.IGNORECASE)
|
|
278
|
+
|
|
279
|
+
|
|
273
280
|
def synthetic_close_invoke_body(inner: str) -> str:
|
|
274
281
|
"""为 force_close / invoke 已闭合但未闭合的 parameter 补齐结构闭合标签。"""
|
|
275
282
|
if not inner:
|
|
@@ -316,6 +323,75 @@ def find_valid_parameter_close(body: str, search_from: int = 0, *, allow_end: bo
|
|
|
316
323
|
return -1
|
|
317
324
|
|
|
318
325
|
|
|
326
|
+
def parameter_value_spans(body: str) -> List[Tuple[int, int]]:
|
|
327
|
+
"""``<entml:parameter>`` 值区间(含未闭合 parameter 的 growing tail)。"""
|
|
328
|
+
if not body:
|
|
329
|
+
return []
|
|
330
|
+
spans: List[Tuple[int, int]] = []
|
|
331
|
+
i = 0
|
|
332
|
+
while i < len(body):
|
|
333
|
+
match = _PARAM_OPEN_TAG_RE.search(body, i)
|
|
334
|
+
if not match:
|
|
335
|
+
break
|
|
336
|
+
val_start = match.end()
|
|
337
|
+
close = find_valid_parameter_close(body, val_start, allow_end=True)
|
|
338
|
+
if close < 0:
|
|
339
|
+
spans.append((val_start, len(body)))
|
|
340
|
+
break
|
|
341
|
+
spans.append((val_start, close))
|
|
342
|
+
i = close + parameter_close_at(body, close)
|
|
343
|
+
return spans
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def parameter_block_spans(body: str) -> List[Tuple[int, int]]:
|
|
347
|
+
"""完整 ``<entml:parameter …>…</entml:parameter>`` 块(含开闭标签)。"""
|
|
348
|
+
if not body:
|
|
349
|
+
return []
|
|
350
|
+
spans: List[Tuple[int, int]] = []
|
|
351
|
+
i = 0
|
|
352
|
+
while i < len(body):
|
|
353
|
+
match = _PARAM_OPEN_TAG_RE.search(body, i)
|
|
354
|
+
if not match:
|
|
355
|
+
break
|
|
356
|
+
block_start = match.start()
|
|
357
|
+
val_start = match.end()
|
|
358
|
+
close = find_valid_parameter_close(body, val_start, allow_end=True)
|
|
359
|
+
if close < 0:
|
|
360
|
+
spans.append((block_start, len(body)))
|
|
361
|
+
break
|
|
362
|
+
block_end = close + parameter_close_at(body, close)
|
|
363
|
+
spans.append((block_start, block_end))
|
|
364
|
+
i = block_end
|
|
365
|
+
return spans
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def invoke_structural_gaps(body: str) -> List[Tuple[int, int]]:
|
|
369
|
+
"""invoke 体内可承载备用参数语法的区间(parameter 块之外)。"""
|
|
370
|
+
if not body:
|
|
371
|
+
return []
|
|
372
|
+
blocks = parameter_block_spans(body)
|
|
373
|
+
if not blocks:
|
|
374
|
+
return [(0, len(body))]
|
|
375
|
+
gaps: List[Tuple[int, int]] = []
|
|
376
|
+
pos = 0
|
|
377
|
+
for start, end in blocks:
|
|
378
|
+
if pos < start:
|
|
379
|
+
gaps.append((pos, start))
|
|
380
|
+
pos = end
|
|
381
|
+
if pos < len(body):
|
|
382
|
+
gaps.append((pos, len(body)))
|
|
383
|
+
return gaps
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
def invoke_structural_gap_text(body: str) -> str:
|
|
387
|
+
"""parameter 块视为不透明 payload 后,invoke 体剩余可解析文本。"""
|
|
388
|
+
return "".join(body[s:e] for s, e in invoke_structural_gaps(body))
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def inside_parameter_value(pos: int, spans: List[Tuple[int, int]]) -> bool:
|
|
392
|
+
return any(start <= pos < end for start, end in spans)
|
|
393
|
+
|
|
394
|
+
|
|
319
395
|
def extract_attr_value(attrs: str, attr_name: str = "name") -> Optional[str]:
|
|
320
396
|
"""从标签属性串中提取 name/type 等(支持单双引号)。"""
|
|
321
397
|
if not attrs:
|
{echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_stream/body.py
RENAMED
|
@@ -16,6 +16,7 @@ from echotools.exec.fncall.protocols.entml_patterns import (
|
|
|
16
16
|
extract_attr_value,
|
|
17
17
|
extract_parameter_type_attr,
|
|
18
18
|
find_valid_parameter_close,
|
|
19
|
+
invoke_structural_gap_text,
|
|
19
20
|
normalize_entml_name,
|
|
20
21
|
parameter_close_at,
|
|
21
22
|
split_mangled_json_param_tail,
|
|
@@ -206,46 +207,18 @@ def _parse_bare_invoke_entries(body: str) -> List[Tuple[str, str, bool, Optional
|
|
|
206
207
|
return entries
|
|
207
208
|
|
|
208
209
|
|
|
209
|
-
def _parameter_value_spans(body: str) -> List[Tuple[int, int]]:
|
|
210
|
-
"""``<entml:parameter>`` 值区间(含流式未闭合 parameter 的 growing tail)。"""
|
|
211
|
-
if not body:
|
|
212
|
-
return []
|
|
213
|
-
spans: List[Tuple[int, int]] = []
|
|
214
|
-
i = 0
|
|
215
|
-
while i < len(body):
|
|
216
|
-
match = _PARAM_OPEN_RE.search(body, i)
|
|
217
|
-
if not match:
|
|
218
|
-
break
|
|
219
|
-
val_start = match.end()
|
|
220
|
-
close = find_valid_parameter_close(body, val_start, allow_end=True)
|
|
221
|
-
if close < 0:
|
|
222
|
-
spans.append((val_start, len(body)))
|
|
223
|
-
break
|
|
224
|
-
spans.append((val_start, close))
|
|
225
|
-
i = close + parameter_close_at(body, close)
|
|
226
|
-
return spans
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
def _inside_parameter_value(pos: int, spans: List[Tuple[int, int]]) -> bool:
|
|
230
|
-
return any(start <= pos < end for start, end in spans)
|
|
231
|
-
|
|
232
|
-
|
|
233
210
|
def _parse_direct_child_entries(body: str) -> List[Tuple[str, str, bool, Optional[str]]]:
|
|
234
211
|
"""返回 [(key, value, is_complete, type_hint), ...](直接子元素标签)。"""
|
|
235
212
|
if not body:
|
|
236
213
|
return []
|
|
237
|
-
|
|
214
|
+
gap_text = invoke_structural_gap_text(body)
|
|
238
215
|
tagged: List[Tuple[int, str, str, bool, Optional[str]]] = []
|
|
239
|
-
for match in INVOKE_DIRECT_CHILD_RE.finditer(
|
|
240
|
-
if _inside_parameter_value(match.start(), param_spans):
|
|
241
|
-
continue
|
|
216
|
+
for match in INVOKE_DIRECT_CHILD_RE.finditer(gap_text):
|
|
242
217
|
key = normalize_entml_name(match.group(1))
|
|
243
218
|
if not key or key.lower() in INVOKE_DIRECT_CHILD_SKIP:
|
|
244
219
|
continue
|
|
245
220
|
tagged.append((match.start(), key, (match.group(2) or "").strip(), True, None))
|
|
246
|
-
for match in INVOKE_DIRECT_CHILD_OPEN_RE.finditer(
|
|
247
|
-
if _inside_parameter_value(match.start(), param_spans):
|
|
248
|
-
continue
|
|
221
|
+
for match in INVOKE_DIRECT_CHILD_OPEN_RE.finditer(gap_text):
|
|
249
222
|
key = normalize_entml_name(match.group(1))
|
|
250
223
|
if not key or key.lower() in INVOKE_DIRECT_CHILD_SKIP:
|
|
251
224
|
continue
|
|
@@ -6,6 +6,11 @@ import pytest
|
|
|
6
6
|
|
|
7
7
|
from echotools.exec.fncall import get_protocol, inject_fncall
|
|
8
8
|
from echotools.exec.fncall.protocols.entml_invoke import parse_entml_tool_calls
|
|
9
|
+
from echotools.exec.fncall.protocols.entml_patterns import (
|
|
10
|
+
invoke_structural_gap_text,
|
|
11
|
+
invoke_structural_gaps,
|
|
12
|
+
parameter_block_spans,
|
|
13
|
+
)
|
|
9
14
|
from echotools.exec.fncall.protocols.entml_think.core import (
|
|
10
15
|
build_entml_thinking_section,
|
|
11
16
|
default_max_thinking_length_for_level,
|
|
@@ -1700,3 +1705,102 @@ def test_write_path_content_hybrid_tool_block() -> None:
|
|
|
1700
1705
|
assert "Agent WebUI" in args["content"]
|
|
1701
1706
|
assert "Phase 1" in args["content"]
|
|
1702
1707
|
|
|
1708
|
+
|
|
1709
|
+
def test_invoke_structural_gaps_exclude_parameter_blocks() -> None:
|
|
1710
|
+
body = (
|
|
1711
|
+
"pre\n"
|
|
1712
|
+
'<entml:parameter name="content"><span>x</span></entml:parameter>\n'
|
|
1713
|
+
"<path>src/a.py</path>\n"
|
|
1714
|
+
"post"
|
|
1715
|
+
)
|
|
1716
|
+
blocks = parameter_block_spans(body)
|
|
1717
|
+
assert len(blocks) == 1
|
|
1718
|
+
assert body[blocks[0][0] : blocks[0][1]].startswith("<entml:parameter")
|
|
1719
|
+
gaps = invoke_structural_gaps(body)
|
|
1720
|
+
gap_text = invoke_structural_gap_text(body)
|
|
1721
|
+
assert "<span>" not in gap_text
|
|
1722
|
+
assert "<path>src/a.py</path>" in gap_text
|
|
1723
|
+
assert "pre" in gap_text
|
|
1724
|
+
assert "post" in gap_text
|
|
1725
|
+
assert sum(e - s for s, e in gaps) == len(gap_text)
|
|
1726
|
+
|
|
1727
|
+
|
|
1728
|
+
def test_write_parameter_payload_opaque_to_alternate_syntax() -> None:
|
|
1729
|
+
"""parameter 块内任意类 XML/HTML 标签不得被 invoke 备用语法解析为参数。"""
|
|
1730
|
+
schema_index = _build_param_schema_index(WRITE_TOOLS)
|
|
1731
|
+
sample = (
|
|
1732
|
+
'<entml:invoke name="Write">\n'
|
|
1733
|
+
'<entml:parameter name="path">src/select.js</entml:parameter>\n'
|
|
1734
|
+
'<entml:parameter name="content">'
|
|
1735
|
+
"app.component('core-collapsible', {\n"
|
|
1736
|
+
" template: [\n"
|
|
1737
|
+
" '<span class=\"collapsible-arrow\"></span>',\n"
|
|
1738
|
+
" '<span>{{ title }}</span>',\n"
|
|
1739
|
+
" '<slot></slot>',\n"
|
|
1740
|
+
" '<div v-if=\"open\"></div>',\n"
|
|
1741
|
+
" ].join('\\n')\n"
|
|
1742
|
+
"});\n"
|
|
1743
|
+
"</entml:parameter>\n"
|
|
1744
|
+
"</entml:invoke>"
|
|
1745
|
+
)
|
|
1746
|
+
calls = parse_entml_tool_calls(sample, WRITE_TOOLS, schema_index)
|
|
1747
|
+
assert len(calls) == 1
|
|
1748
|
+
args = json.loads(calls[0]["function"]["arguments"])
|
|
1749
|
+
assert set(args.keys()) == {"file_path", "content"}
|
|
1750
|
+
assert "<slot></slot>" in args["content"]
|
|
1751
|
+
assert "{{ title }}" in args["content"]
|
|
1752
|
+
|
|
1753
|
+
|
|
1754
|
+
def test_invoke_mixed_parameter_and_direct_child_syntax() -> None:
|
|
1755
|
+
"""structural gap:parameter 与直接子标签可并存,互不污染。"""
|
|
1756
|
+
tools = [
|
|
1757
|
+
{
|
|
1758
|
+
"type": "function",
|
|
1759
|
+
"function": {
|
|
1760
|
+
"name": "Grep",
|
|
1761
|
+
"parameters": {
|
|
1762
|
+
"type": "object",
|
|
1763
|
+
"properties": {
|
|
1764
|
+
"pattern": {"type": "string"},
|
|
1765
|
+
"path": {"type": "string"},
|
|
1766
|
+
"-n": {"type": "boolean"},
|
|
1767
|
+
},
|
|
1768
|
+
"required": ["pattern"],
|
|
1769
|
+
},
|
|
1770
|
+
},
|
|
1771
|
+
}
|
|
1772
|
+
]
|
|
1773
|
+
schema_index = _build_param_schema_index(tools)
|
|
1774
|
+
sample = (
|
|
1775
|
+
'<entml:invoke name="Grep">\n'
|
|
1776
|
+
'<entml:parameter name="pattern">foo|bar</entml:parameter>\n'
|
|
1777
|
+
"<path>src/main.py</path>\n"
|
|
1778
|
+
"<-n>true</-n>\n"
|
|
1779
|
+
"</entml:invoke>"
|
|
1780
|
+
)
|
|
1781
|
+
calls = parse_entml_tool_calls(sample, tools, schema_index)
|
|
1782
|
+
args = json.loads(calls[0]["function"]["arguments"])
|
|
1783
|
+
assert args == {"pattern": "foo|bar", "path": "src/main.py", "-n": True}
|
|
1784
|
+
|
|
1785
|
+
|
|
1786
|
+
def test_write_parameter_payload_corpus_req_1785323083() -> None:
|
|
1787
|
+
"""回归 req-1785323083:parameter payload 内 markup 不得泄漏为额外参数。"""
|
|
1788
|
+
from pathlib import Path
|
|
1789
|
+
|
|
1790
|
+
sample_path = Path(
|
|
1791
|
+
r"X:/Project/Public/Qwen/logs/responses/req-1785323083-f6847d18c1f9.txt"
|
|
1792
|
+
)
|
|
1793
|
+
if not sample_path.is_file():
|
|
1794
|
+
pytest.skip("corpus file not available")
|
|
1795
|
+
text = sample_path.read_text(encoding="utf-8")
|
|
1796
|
+
proto = get_protocol("entml")
|
|
1797
|
+
_, batch_calls = proto.parse(text, WRITE_TOOLS)
|
|
1798
|
+
write_calls = [c for c in batch_calls if c["function"]["name"] == "Write"]
|
|
1799
|
+
assert len(write_calls) == 1
|
|
1800
|
+
args = json.loads(write_calls[0]["function"]["arguments"])
|
|
1801
|
+
assert "span" not in args
|
|
1802
|
+
assert "slot" not in args
|
|
1803
|
+
assert args["file_path"].endswith("select.js")
|
|
1804
|
+
assert "core-select" in args["content"]
|
|
1805
|
+
assert "<slot></slot>" in args["content"]
|
|
1806
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_stream/__init__.py
RENAMED
|
File without changes
|
{echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_stream/snap.py
RENAMED
|
File without changes
|
{echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/__init__.py
RENAMED
|
File without changes
|
{echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/blocks.py
RENAMED
|
File without changes
|
{echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/core.py
RENAMED
|
File without changes
|
{echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/filter.py
RENAMED
|
File without changes
|
{echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/hist.py
RENAMED
|
File without changes
|
{echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/hold.py
RENAMED
|
File without changes
|
{echotools-2.3.87 → echotools-2.3.88}/src/echotools/exec/fncall/protocols/entml_think/parse.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{echotools-2.3.87 → echotools-2.3.88}/src/echotools/media/console/uicore/mixins/uiinteract.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|