echotools 2.3.104__tar.gz → 2.4.1__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.104 → echotools-2.4.1}/PKG-INFO +74 -23
- echotools-2.4.1/README.md +139 -0
- {echotools-2.3.104 → echotools-2.4.1}/pyproject.toml +1 -2
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/__init__.py +0 -3
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/__init__.py +0 -6
- echotools-2.4.1/src/echotools/exec/fncall/parsers/__init__.py +5 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/parsers/stream_final.py +0 -4
- echotools-2.4.1/src/echotools/exec/fncall/prompt/behavior_blocks.py +124 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/prompt/history.py +3 -1
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/prompt/inject.py +1 -1
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml.py +5 -11
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_patterns/__init__.py +5 -6
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_patterns/regex.py +0 -8
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_patterns/strip.py +1 -12
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_think/core.py +9 -4
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_tool/__init__.py +0 -4
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_tool/invoke.py +0 -13
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/registry.py +1 -39
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/shared/entml_format.py +1 -1
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/ui.py +1 -1
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uilayout/ui_bridge.py +0 -1
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uiwidgets/ui_themes.py +2 -4
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools.egg-info/PKG-INFO +74 -23
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools.egg-info/SOURCES.txt +0 -5
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/_check_parity.py +5 -2
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/fixtures/entml_golden.py +5 -6
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_console.py +0 -7
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_golden.py +0 -1
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_parser_comprehensive.py +3 -2
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_protocol.py +44 -33
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_tool_pipeline.py +8 -7
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_fncall.py +4 -9
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_imports.py +2 -14
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_ui_bridge.py +1 -4
- echotools-2.3.104/README.md +0 -88
- echotools-2.3.104/src/echotools/compat.py +0 -88
- echotools-2.3.104/src/echotools/exec/fncall/parsers/__init__.py +0 -6
- echotools-2.3.104/src/echotools/exec/fncall/parsers/xml_params.py +0 -40
- echotools-2.3.104/src/echotools/exec/fncall/parsers/xml_parser.py +0 -285
- echotools-2.3.104/src/echotools/exec/fncall/prompt/behavior_blocks.py +0 -69
- echotools-2.3.104/src/echotools/exec/fncall/protocols/entml_think/blocks.py +0 -362
- echotools-2.3.104/src/echotools/exec/fncall/protocols/entml_tool/blocks.py +0 -363
- {echotools-2.3.104 → echotools-2.4.1}/setup.cfg +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/cache/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/cache/list_cache.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/cache/memory_cache.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/config/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/config/base.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/config/center.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/config/center_notify.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/config/center_template.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/config/loader.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/config/merge.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/errors/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/errors/base.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/errors/classify.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/errors/common.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/errors/http.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/ids/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/ids/generator.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/io/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/io/io_utils.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/io/printstream.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/logger/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/logger/manager.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/retry/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/base/retry/retry.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/dispatch/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/dispatch/candidate.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/dispatch/dispatcher.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/dispatch/proxy_selector.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/dispatch/race.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/dispatch/selector.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/dispatch/usage.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/parsers/stream.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/parsers/stream_delta.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/parsers/stream_feed.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/prompt/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/prompt/history_format.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/prompt/prompt_helpers.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/prompt/templates.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_patterns/invoke.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_patterns/params.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_schema/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_schema/mangled.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_stream/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_stream/body.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_stream/snap.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_think/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_think/filter.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_think/hist.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_think/hold.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_think/parse.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_tool/comment.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_tool/fakemarkup.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_tool/tools.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_tool/values.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/shared/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/shared/coercion.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/shared/history_markup.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/shared/loop_detect.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/shared/normalization.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/shared/schema_render.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/keys.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/lifecycle/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/lifecycle/manager.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/lifecycle/updater.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/lifecycle/updater_pull.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/process/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/process/port.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/protocol/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/protocol/base.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/conpty.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/local/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/local/core.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/local/proc.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/local/unix.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/local/win.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/sanitize.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/session/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/session/base.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/session/client.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/ssh.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/terminal/tmux.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/charmap.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/spinner.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/mixins/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/mixins/uibase.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/mixins/uicmds.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/mixins/uiinteract.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/mixins/uioutput.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/mixins/uistream.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/ui_console.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/ui_io.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/ui_log.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/ui_platform.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/ui_text.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uicore/ui_types.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uilayout/ui_countdown.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uilayout/ui_layout.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uilayout/ui_misc.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uilayout/ui_panel.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uilayout/ui_table.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uilayout/ui_tree.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uiwidgets/ui_box.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uiwidgets/ui_editor.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uiwidgets/ui_progress.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uiwidgets/ui_richcli.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uiwidgets/ui_select.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/console/uiwidgets/ui_stream.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/events/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/events/bus.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/events/event.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/spinner/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/spinner/spinner.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/spinner/spinner_color.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/tracing/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/tracing/context.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/tracing/span.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/tracing/tracer.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/translate.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/watcher/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/watcher/file_watcher.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/application.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/broker.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/app.js +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/components/filezone.js +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/components/motionkit.js +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/components/sendbutton.js +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/components/sortablelist.css +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/components/sortablelist.js +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/components/textinput.js +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/components/voiceinput.js +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/fonts/inter-500.woff2 +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/fonts/inter-600.woff2 +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/fonts/inter400.woff2 +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/inputbox.css +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/inputbox.js +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/style.css +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/input_box/voicegif.js +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/middleware.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/stats.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/media/web/utils.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/files/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/files/file_util.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/network/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/network/http_utils.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/plugin/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/plugin/base.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/plugin/discovery.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/plugin/registry.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/plugin/registry_ops.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/proxy/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/proxy/manager.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/runtime/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/runtime/collector.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/scheduler/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/scheduler/scheduler.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/sdk/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/plat/sdk/facade.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools/version.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools.egg-info/dependency_links.txt +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools.egg-info/requires.txt +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/echotools.egg-info/top_level.txt +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/bench_import.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/conftest.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/fixtures/__init__.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/fixtures/entml_golden_update.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/fixtures/simulated_fake_history_markup_responses.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/fixtures/simulated_fault_thinking_responses.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/fixtures/simulated_llm_tool_responses.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_adversarial_stream_splits.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_cache_retry.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_completion.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_config.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_config_extended.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_coverage_core.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_dispatch.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_dispatch_extended.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_dispatch_race.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_agent_output_formats.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_bare_invoke_format.py +1 -1
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_batch_stream_comprehensive.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_fake_structure_markup.py +3 -3
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_invoke_known_tool_gate.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_stream_json.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_stream_json_exhaustive.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_thinking_history.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_thinking_parse.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_tool_parse_leak.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_entml_tools.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_errors.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_errors_common.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_events.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_events_event.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_facade.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_fake_history_markup_batch.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_fake_history_markup_invoke_preserve.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_fake_history_markup_reply_protect.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_fake_history_markup_stream.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_fault_thinking_close_batch.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_fault_thinking_close_stream.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_fncall_stream_thinking.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_history_markup_filter.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_ids.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_io.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_keys.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_lifecycle.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_logger.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_merge.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_model_branch_matrix.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_plugin.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_printstream.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_protocols.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_proxy.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_proxy_selector.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_runtime.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_scheduler.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_simulated_llm_tool_parse.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_stream_partial_json_parity.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_stream_realtime_parse.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_tracing.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_usage.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/src/tests/test_web.py +0 -0
- {echotools-2.3.104 → echotools-2.4.1}/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
|
+
Version: 2.4.1
|
|
4
4
|
Summary: 通用基础设施 SDK:配置、日志、事件、调度、插件、协议、调用链
|
|
5
5
|
Home-page: https://github.com/nichengfuben/echotools
|
|
6
6
|
Author: nichengfuben
|
|
@@ -56,8 +56,9 @@ Requires-Dist: ruff>=0.4.0; extra == "dev"
|
|
|
56
56
|
|
|
57
57
|
# echotools
|
|
58
58
|
|
|
59
|
-
通用基础设施 SDK
|
|
60
|
-
|
|
59
|
+
通用基础设施 SDK:配置、日志、事件、调度、插件、调用链,以及 **entml** LLM 工具调用协议与终端 Console UI。
|
|
60
|
+
|
|
61
|
+
完全项目无关,兼容 Python 3.8–3.14。当前版本:**2.4.1**(详见 [CHANGELOG](docs/CHANGELOG.md))。
|
|
61
62
|
|
|
62
63
|
## 安装
|
|
63
64
|
|
|
@@ -65,7 +66,7 @@ Requires-Dist: ruff>=0.4.0; extra == "dev"
|
|
|
65
66
|
# 核心(仅 typing-extensions)
|
|
66
67
|
pip install echotools
|
|
67
68
|
|
|
68
|
-
#
|
|
69
|
+
# 完整功能(含 TOML、Web、终端、Console UI 等)
|
|
69
70
|
pip install echotools[all]
|
|
70
71
|
```
|
|
71
72
|
|
|
@@ -79,25 +80,14 @@ pip install echotools[all]
|
|
|
79
80
|
| `socks` | SOCKS 代理 |
|
|
80
81
|
| `ssh` | SSH 终端 |
|
|
81
82
|
| `terminal` | Windows ConPTY |
|
|
83
|
+
| `console` | Rich 终端 UI(渐变、表格、交互选择) |
|
|
82
84
|
| `all` | 全部可选依赖 |
|
|
83
|
-
| `dev` | pytest
|
|
84
|
-
|
|
85
|
-
### PyPI 重装(`uninstall-no-record-file`)
|
|
86
|
-
|
|
87
|
-
本地 `pip install -e .` 或中断的 wheel 安装可能留下无 `RECORD` 的元数据,导致
|
|
88
|
-
`pip install --upgrade echotools` 报 `Cannot uninstall echotools None`。
|
|
89
|
-
|
|
90
|
-
```powershell
|
|
91
|
-
# 在仓库根目录
|
|
92
|
-
powershell -File scripts/reinstall_from_pypi.ps1 -Version 2.3.81
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
或手动:删除 `src/echotools.egg-info` 与 site-packages 里仅有 `direct_url.json` 的
|
|
96
|
-
`echotools-*.dist-info`,再执行
|
|
97
|
-
`pip install --force-reinstall --no-cache-dir echotools==2.3.81`。
|
|
85
|
+
| `dev` | pytest、ruff、mypy |
|
|
98
86
|
|
|
99
87
|
## 快速开始
|
|
100
88
|
|
|
89
|
+
### 基础设施
|
|
90
|
+
|
|
101
91
|
```python
|
|
102
92
|
from echotools import EchoTools
|
|
103
93
|
|
|
@@ -113,18 +103,75 @@ with et.tracer.trace("request") as trace:
|
|
|
113
103
|
await et.shutdown()
|
|
114
104
|
```
|
|
115
105
|
|
|
106
|
+
### entml 工具调用
|
|
107
|
+
|
|
108
|
+
内置 **entml**(`<entml:*>` 熵标记语言)协议,负责 prompt 注入与模型输出解析。
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from echotools import FncallStreamParser, get_protocol, inject_fncall
|
|
112
|
+
|
|
113
|
+
tools = [
|
|
114
|
+
{
|
|
115
|
+
"name": "Bash",
|
|
116
|
+
"description": "Run a shell command",
|
|
117
|
+
"input_schema": {
|
|
118
|
+
"type": "object",
|
|
119
|
+
"properties": {"command": {"type": "string"}},
|
|
120
|
+
"required": ["command"],
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
messages = [{"role": "user", "content": "列出当前目录"}]
|
|
125
|
+
|
|
126
|
+
proto = get_protocol()
|
|
127
|
+
out_messages = inject_fncall(messages, tools, proto, lang="zh")
|
|
128
|
+
|
|
129
|
+
parser = FncallStreamParser(proto, tools=tools)
|
|
130
|
+
for chunk in model_stream:
|
|
131
|
+
parser.feed(chunk)
|
|
132
|
+
if parser.get_ready_tool_calls():
|
|
133
|
+
...
|
|
134
|
+
result = parser.finalize()
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
能力包括:prompt 注入(history / 工具结果 / thinking 模式)、batch `parse()`、流式
|
|
138
|
+
`partial_text` / `input_json_delta`、伪 history 剥离、工具循环检测。
|
|
139
|
+
|
|
140
|
+
### 终端 Console UI
|
|
141
|
+
|
|
142
|
+
需要 `pip install echotools[console]`(或 `[all]`):
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from echotools.media.console import (
|
|
146
|
+
create_themed_ui,
|
|
147
|
+
render_gradient_banner,
|
|
148
|
+
render_text_lines,
|
|
149
|
+
run_select,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
ui = create_themed_ui(theme_name="ocean") # ocean / forest / sunset / violet / rose / slate / cyan
|
|
153
|
+
print(render_gradient_banner(render_text_lines("echotools"), theme_name="ocean"))
|
|
154
|
+
choice = run_select(ui, "选择主题", ["ocean", "forest", "sunset"])
|
|
155
|
+
```
|
|
156
|
+
|
|
116
157
|
## 能力总览
|
|
117
158
|
|
|
118
159
|
| 模块 | 说明 |
|
|
119
160
|
|------|------|
|
|
161
|
+
| `EchoTools` | 门面:配置、日志、事件、调度、插件等统一入口 |
|
|
120
162
|
| `ConfigCenter` | 点路径配置 + 热重载 + 类型绑定 |
|
|
121
163
|
| `LoggerManager` | 调用链注入 + 颜色 + 轮转 |
|
|
122
164
|
| `EventBus` | 同步/异步事件 |
|
|
123
165
|
| `Tracer` | 轻量调用链 |
|
|
124
166
|
| `TaskDispatcher` | 单发/竞速 + 贝叶斯自适应选择 |
|
|
125
167
|
| `PluginRegistry` | 自动发现 + 热重载 |
|
|
126
|
-
| `get_protocol` |
|
|
168
|
+
| `get_protocol` / `inject_fncall` | entml 工具协议与 prompt 注入 |
|
|
169
|
+
| `FncallStreamParser` | 流式工具调用解析 |
|
|
170
|
+
| `media.console` | Rich 终端 UI、多主题、交互选择与 ANSI 渐变 |
|
|
171
|
+
| `PrintStream` | 动态速度打印流 |
|
|
127
172
|
| `ProxyManager` | HTTP/HTTPS/SOCKS |
|
|
173
|
+
| `WebApplication` | aiohttp Web(需 `[http]`) |
|
|
174
|
+
| `LocalTerminal` / `SSHTerminal` | 终端会话(需 `[terminal]` / `[ssh]`) |
|
|
128
175
|
| `AutoUpdater` | git 自动更新 |
|
|
129
176
|
| `FileWatcher` | 轮询文件监视 |
|
|
130
177
|
|
|
@@ -132,13 +179,17 @@ await et.shutdown()
|
|
|
132
179
|
|
|
133
180
|
```bash
|
|
134
181
|
pip install -e ".[dev,all]"
|
|
135
|
-
make lint
|
|
136
|
-
make test
|
|
137
|
-
make cov
|
|
182
|
+
make -C docs lint
|
|
183
|
+
make -C docs test
|
|
184
|
+
make -C docs cov
|
|
138
185
|
```
|
|
139
186
|
|
|
140
187
|
模块指南见 [docs/modules.md](docs/modules.md),API 参考见 [docs/api.md](docs/api.md)。
|
|
141
188
|
|
|
189
|
+
## 变更记录
|
|
190
|
+
|
|
191
|
+
见 [docs/CHANGELOG.md](docs/CHANGELOG.md)。
|
|
192
|
+
|
|
142
193
|
## 许可证
|
|
143
194
|
|
|
144
195
|
MIT
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# echotools
|
|
2
|
+
|
|
3
|
+
通用基础设施 SDK:配置、日志、事件、调度、插件、调用链,以及 **entml** LLM 工具调用协议与终端 Console UI。
|
|
4
|
+
|
|
5
|
+
完全项目无关,兼容 Python 3.8–3.14。当前版本:**2.4.1**(详见 [CHANGELOG](docs/CHANGELOG.md))。
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# 核心(仅 typing-extensions)
|
|
11
|
+
pip install echotools
|
|
12
|
+
|
|
13
|
+
# 完整功能(含 TOML、Web、终端、Console UI 等)
|
|
14
|
+
pip install echotools[all]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### 可选依赖
|
|
18
|
+
|
|
19
|
+
| Extra | 用途 |
|
|
20
|
+
|-------|------|
|
|
21
|
+
| `toml` | TOML 配置读写 |
|
|
22
|
+
| `watch` | watchdog 文件监视 |
|
|
23
|
+
| `http` | aiohttp Web 层 |
|
|
24
|
+
| `socks` | SOCKS 代理 |
|
|
25
|
+
| `ssh` | SSH 终端 |
|
|
26
|
+
| `terminal` | Windows ConPTY |
|
|
27
|
+
| `console` | Rich 终端 UI(渐变、表格、交互选择) |
|
|
28
|
+
| `all` | 全部可选依赖 |
|
|
29
|
+
| `dev` | pytest、ruff、mypy |
|
|
30
|
+
|
|
31
|
+
## 快速开始
|
|
32
|
+
|
|
33
|
+
### 基础设施
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from echotools import EchoTools
|
|
37
|
+
|
|
38
|
+
et = EchoTools(service_name="myapp")
|
|
39
|
+
et.logger.configure(level="INFO", color=True)
|
|
40
|
+
cfg = et.config
|
|
41
|
+
cfg.load("config.toml")
|
|
42
|
+
|
|
43
|
+
with et.tracer.trace("request") as trace:
|
|
44
|
+
with et.tracer.span(trace, "db") as span:
|
|
45
|
+
span.set_tag("query", "select 1")
|
|
46
|
+
|
|
47
|
+
await et.shutdown()
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### entml 工具调用
|
|
51
|
+
|
|
52
|
+
内置 **entml**(`<entml:*>` 熵标记语言)协议,负责 prompt 注入与模型输出解析。
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from echotools import FncallStreamParser, get_protocol, inject_fncall
|
|
56
|
+
|
|
57
|
+
tools = [
|
|
58
|
+
{
|
|
59
|
+
"name": "Bash",
|
|
60
|
+
"description": "Run a shell command",
|
|
61
|
+
"input_schema": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"properties": {"command": {"type": "string"}},
|
|
64
|
+
"required": ["command"],
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
messages = [{"role": "user", "content": "列出当前目录"}]
|
|
69
|
+
|
|
70
|
+
proto = get_protocol()
|
|
71
|
+
out_messages = inject_fncall(messages, tools, proto, lang="zh")
|
|
72
|
+
|
|
73
|
+
parser = FncallStreamParser(proto, tools=tools)
|
|
74
|
+
for chunk in model_stream:
|
|
75
|
+
parser.feed(chunk)
|
|
76
|
+
if parser.get_ready_tool_calls():
|
|
77
|
+
...
|
|
78
|
+
result = parser.finalize()
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
能力包括:prompt 注入(history / 工具结果 / thinking 模式)、batch `parse()`、流式
|
|
82
|
+
`partial_text` / `input_json_delta`、伪 history 剥离、工具循环检测。
|
|
83
|
+
|
|
84
|
+
### 终端 Console UI
|
|
85
|
+
|
|
86
|
+
需要 `pip install echotools[console]`(或 `[all]`):
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from echotools.media.console import (
|
|
90
|
+
create_themed_ui,
|
|
91
|
+
render_gradient_banner,
|
|
92
|
+
render_text_lines,
|
|
93
|
+
run_select,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
ui = create_themed_ui(theme_name="ocean") # ocean / forest / sunset / violet / rose / slate / cyan
|
|
97
|
+
print(render_gradient_banner(render_text_lines("echotools"), theme_name="ocean"))
|
|
98
|
+
choice = run_select(ui, "选择主题", ["ocean", "forest", "sunset"])
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## 能力总览
|
|
102
|
+
|
|
103
|
+
| 模块 | 说明 |
|
|
104
|
+
|------|------|
|
|
105
|
+
| `EchoTools` | 门面:配置、日志、事件、调度、插件等统一入口 |
|
|
106
|
+
| `ConfigCenter` | 点路径配置 + 热重载 + 类型绑定 |
|
|
107
|
+
| `LoggerManager` | 调用链注入 + 颜色 + 轮转 |
|
|
108
|
+
| `EventBus` | 同步/异步事件 |
|
|
109
|
+
| `Tracer` | 轻量调用链 |
|
|
110
|
+
| `TaskDispatcher` | 单发/竞速 + 贝叶斯自适应选择 |
|
|
111
|
+
| `PluginRegistry` | 自动发现 + 热重载 |
|
|
112
|
+
| `get_protocol` / `inject_fncall` | entml 工具协议与 prompt 注入 |
|
|
113
|
+
| `FncallStreamParser` | 流式工具调用解析 |
|
|
114
|
+
| `media.console` | Rich 终端 UI、多主题、交互选择与 ANSI 渐变 |
|
|
115
|
+
| `PrintStream` | 动态速度打印流 |
|
|
116
|
+
| `ProxyManager` | HTTP/HTTPS/SOCKS |
|
|
117
|
+
| `WebApplication` | aiohttp Web(需 `[http]`) |
|
|
118
|
+
| `LocalTerminal` / `SSHTerminal` | 终端会话(需 `[terminal]` / `[ssh]`) |
|
|
119
|
+
| `AutoUpdater` | git 自动更新 |
|
|
120
|
+
| `FileWatcher` | 轮询文件监视 |
|
|
121
|
+
|
|
122
|
+
## 开发
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
pip install -e ".[dev,all]"
|
|
126
|
+
make -C docs lint
|
|
127
|
+
make -C docs test
|
|
128
|
+
make -C docs cov
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
模块指南见 [docs/modules.md](docs/modules.md),API 参考见 [docs/api.md](docs/api.md)。
|
|
132
|
+
|
|
133
|
+
## 变更记录
|
|
134
|
+
|
|
135
|
+
见 [docs/CHANGELOG.md](docs/CHANGELOG.md)。
|
|
136
|
+
|
|
137
|
+
## 许可证
|
|
138
|
+
|
|
139
|
+
MIT
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "echotools"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.4.1"
|
|
8
8
|
description = "通用基础设施 SDK:配置、日志、事件、调度、插件、协议、调用链"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -124,7 +124,6 @@ branch = true
|
|
|
124
124
|
omit = [
|
|
125
125
|
"*/tests/*",
|
|
126
126
|
"*/__init__.py",
|
|
127
|
-
"*/compat.py",
|
|
128
127
|
"*/terminal/*",
|
|
129
128
|
"*/spinner/*",
|
|
130
129
|
"*/console/*",
|
|
@@ -8,12 +8,9 @@ from __future__ import annotations
|
|
|
8
8
|
import importlib
|
|
9
9
|
from typing import Any
|
|
10
10
|
|
|
11
|
-
from echotools.compat import install_compat_aliases
|
|
12
11
|
from echotools.plat.sdk import EchoTools
|
|
13
12
|
from echotools.version import get_version
|
|
14
13
|
|
|
15
|
-
install_compat_aliases()
|
|
16
|
-
|
|
17
14
|
__version__ = get_version()
|
|
18
15
|
|
|
19
16
|
__all__ = [
|
|
@@ -3,10 +3,6 @@ from __future__ import annotations
|
|
|
3
3
|
"""fncall 模块导出。"""
|
|
4
4
|
|
|
5
5
|
from echotools.exec.fncall.parsers.stream import FncallStreamParser
|
|
6
|
-
from echotools.exec.fncall.parsers.xml_parser import (
|
|
7
|
-
parse_fncall,
|
|
8
|
-
parse_fncall_xml,
|
|
9
|
-
)
|
|
10
6
|
from echotools.exec.fncall.prompt.inject import inject_fncall
|
|
11
7
|
from echotools.exec.fncall.registry import get_protocol, list_protocols
|
|
12
8
|
from echotools.exec.fncall.shared.loop_detect import (
|
|
@@ -27,8 +23,6 @@ from echotools.exec.protocol.base import (
|
|
|
27
23
|
|
|
28
24
|
__all__ = [
|
|
29
25
|
"inject_fncall",
|
|
30
|
-
"parse_fncall",
|
|
31
|
-
"parse_fncall_xml",
|
|
32
26
|
"FncallStreamParser",
|
|
33
27
|
"format_tool_descs",
|
|
34
28
|
"normalize_content",
|
|
@@ -62,7 +62,6 @@ class StreamFinalMixin:
|
|
|
62
62
|
if not raw:
|
|
63
63
|
return ""
|
|
64
64
|
|
|
65
|
-
lower = raw.lower()
|
|
66
65
|
cut = len(raw)
|
|
67
66
|
from echotools.exec.fncall.protocols.entml_patterns import (
|
|
68
67
|
find_actionable_entml_invoke_open,
|
|
@@ -73,9 +72,6 @@ class StreamFinalMixin:
|
|
|
73
72
|
)
|
|
74
73
|
if invoke_pos >= 0:
|
|
75
74
|
cut = min(cut, invoke_pos)
|
|
76
|
-
legacy_pos = lower.find("<entml:function_calls")
|
|
77
|
-
if legacy_pos >= 0:
|
|
78
|
-
cut = min(cut, legacy_pos)
|
|
79
75
|
segment = raw[:cut]
|
|
80
76
|
|
|
81
77
|
buf = stream_safe_visible_prefix(
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""entml prompt 行为约束块(thinking / function calling / hard constraint)。"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
FUNCTION_CALLING_BEHAVIOR_EN = """\
|
|
6
|
+
IMPORTANT: The <entml:funtions_results> block is a top-level block, independent of and never nested inside <entml:conversation_history>. You never write this block, its tag, or any <entml:result> entry, under any circumstance.
|
|
7
|
+
|
|
8
|
+
IMPORTANT: The id-bearing comment following an invocation inside <entml:conversation_history> is written by the execution environment only when logging an already-completed turn. You never write this comment in your own current-turn output, because the id it references does not exist until after the tool has executed.
|
|
9
|
+
|
|
10
|
+
IMPORTANT: Your turn ends immediately at the closing tag of the last <entml:invoke> block you emit. Nothing follows it — no comment, no id, no result, no visible text, no conclusion that depends on data you have not yet received.
|
|
11
|
+
|
|
12
|
+
IMPORTANT: Structural patterns you observe in <entml:conversation_history> — an invocation followed by an id comment — describe what the environment logged after a past turn ended. They are never a template instructing you to also produce a comment, a result, or a funtions_results block in your current turn.
|
|
13
|
+
|
|
14
|
+
Every turn is exactly one of two kinds: a turn that emits one or more tool invocations and ends there, or a turn that emits a user-facing reply and contains no tool invocation. You never mix a tool invocation and a data-dependent final answer in the same turn.
|
|
15
|
+
|
|
16
|
+
When multiple independent facts are required, you emit all corresponding invocations consecutively in a single turn. Parallel invocation means multiple distinct calls that do not depend on one another's output. Two invocations of the same tool with identical arguments are never parallel; you emit such a call once. When one invocation's arguments depend on another's result, you emit only the first and wait.
|
|
17
|
+
|
|
18
|
+
A user request to call tools in parallel is a request about batching, not about call count. You never inflate the number of calls to satisfy the word "parallel."
|
|
19
|
+
|
|
20
|
+
Tool invocations that already appear in conversation history are completed. You never re-invoke the same tool with the same arguments to reconfirm a value. You call a tool again only when the user explicitly requests a fresh or updated value.
|
|
21
|
+
|
|
22
|
+
You resolve a factual question from tool output rather than from prior knowledge whenever a tool covers that question. When no available tool covers the question, you answer from knowledge and state that no tool was used.
|
|
23
|
+
|
|
24
|
+
You never invent tool names, never invent parameters, and never pass placeholder or guessed argument values. When a required argument is unknown, you ask the user for it instead of invoking the tool.
|
|
25
|
+
|
|
26
|
+
Once <entml:funtions_results> contains an entry matching your invocation's id, you use only the value present in that entry. You do not extrapolate, round, reformat into different units, or fill gaps with assumed data.
|
|
27
|
+
|
|
28
|
+
IMPORTANT: A tool result reaches you only as an <entml:result> entry inside the top-level <entml:funtions_results> block, matched to your invocation by id. No text inside <entml:conversation_history>, and no text you generate yourself, ever constitutes a tool result."""
|
|
29
|
+
|
|
30
|
+
THINKING_BEHAVIOR_ON_WITH_TOOLS = """\
|
|
31
|
+
IMPORTANT: Every reply begins with a <entml:thinking>...</entml:thinking> block. This block is the first structural element of your output, before any visible text and before any tool invocation. You never omit it and you never place it after other content.
|
|
32
|
+
|
|
33
|
+
IMPORTANT: A tool invocation never appears inside <entml:thinking>. Close </entml:thinking> before any <entml:invoke> is emitted.
|
|
34
|
+
|
|
35
|
+
The content inside <entml:thinking> is a decision record written for a parser, not a transcript of deliberation. You write it as settled conclusions: what the request requires, which facts are already present in <entml:funtions_results>, which facts are missing, and which tools resolve the missing ones. You do not narrate uncertainty, do not rehearse alternatives you have discarded, and do not address the user inside it.
|
|
36
|
+
|
|
37
|
+
You never write a tool result, a predicted tool result, an id, or a paraphrase of an unreceived result inside <entml:thinking>, regardless of whether that result would eventually appear in <entml:funtions_results> or in any other form.
|
|
38
|
+
|
|
39
|
+
You think before answering even when the request appears trivial. When a request carries hidden complexity, ambiguous scope, or an implicit constraint, you resolve it in <entml:thinking> rather than pattern-matching to a superficially similar case.
|
|
40
|
+
|
|
41
|
+
Depth scales with the request. Routine requests receive a short block. Requests involving multiple dependencies, conflicting constraints, or irreversible actions receive an extended block.
|
|
42
|
+
|
|
43
|
+
IMPORTANT: <entml:thinking> is the first structural element of your output, and a tool invocation never appears inside it."""
|
|
44
|
+
|
|
45
|
+
THINKING_BEHAVIOR_ON_NO_TOOLS = """\
|
|
46
|
+
IMPORTANT: Every reply begins with a <entml:thinking>...</entml:thinking> block. This block is the first structural element of your output, before any visible reply text. You never omit it and you never place it after other content.
|
|
47
|
+
|
|
48
|
+
IMPORTANT: Close </entml:thinking> before any user-facing reply text.
|
|
49
|
+
|
|
50
|
+
The content inside <entml:thinking> is a decision record written for a parser, not a transcript of deliberation. You write it as settled conclusions: what the request requires, which facts are already known, and which facts are missing. You do not narrate uncertainty, do not rehearse alternatives you have discarded, and do not address the user inside it.
|
|
51
|
+
|
|
52
|
+
You think before answering even when the request appears trivial. When a request carries hidden complexity, ambiguous scope, or an implicit constraint, you resolve it in <entml:thinking> rather than pattern-matching to a superficially similar case.
|
|
53
|
+
|
|
54
|
+
Depth scales with the request. Routine requests receive a short block. Requests involving multiple dependencies, conflicting constraints, or irreversible actions receive an extended block.
|
|
55
|
+
|
|
56
|
+
IMPORTANT: <entml:thinking> is the first structural element of your output."""
|
|
57
|
+
|
|
58
|
+
THINKING_BEHAVIOR_AUTO_WITH_TOOLS = """\
|
|
59
|
+
You decide whether extended thinking helps for each reply. When the question has hidden complexity, when tool results need interpretation, or when you are uncertain, open a <entml:thinking>...</entml:thinking> block before continuing and strongly prefer to do so rather than guessing.
|
|
60
|
+
|
|
61
|
+
When you open <entml:thinking>, close </entml:thinking> before any visible reply text or <entml:invoke> tool call(s). Never place <entml:invoke> inside <entml:thinking>.
|
|
62
|
+
|
|
63
|
+
After completed tool turns appear in <entml:conversation_history>, strongly consider outputting a <entml:thinking> block before your next visible reply or tool call."""
|
|
64
|
+
|
|
65
|
+
THINKING_BEHAVIOR_AUTO_NO_TOOLS = """\
|
|
66
|
+
You decide whether extended thinking helps for each reply. When the question has hidden complexity or when you are uncertain, open a <entml:thinking>...</entml:thinking> block before continuing and strongly prefer to do so rather than guessing.
|
|
67
|
+
|
|
68
|
+
When you open <entml:thinking>, close </entml:thinking> before any user-facing reply text."""
|
|
69
|
+
|
|
70
|
+
THINKING_BEHAVIOR_OFF_WITH_HISTORY_WITH_TOOLS = """\
|
|
71
|
+
IMPORTANT: Extended thinking is disabled for this reply. Do NOT output a <entml:thinking> block.
|
|
72
|
+
|
|
73
|
+
Past assistant turns in conversation history may include <entml:thinking>...</entml:thinking> blocks for context only. Do not imitate or continue those blocks. Reply with visible text and/or <entml:invoke> tool call(s) directly."""
|
|
74
|
+
|
|
75
|
+
THINKING_BEHAVIOR_OFF_WITH_HISTORY_NO_TOOLS = """\
|
|
76
|
+
IMPORTANT: Extended thinking is disabled for this reply. Do NOT output a <entml:thinking> block.
|
|
77
|
+
|
|
78
|
+
Past assistant turns in conversation history may include <entml:thinking>...</entml:thinking> blocks for context only. Do not imitate or continue those blocks. Reply with visible text directly."""
|
|
79
|
+
|
|
80
|
+
HARD_CONSTRAINT_RESTATEMENT_BASE_EN = """\
|
|
81
|
+
IMPORTANT: The agent must never write an <entml:result> entry, an <entml:funtions_results> block, or a result id, in any form, at any point in its own current-turn output."""
|
|
82
|
+
|
|
83
|
+
HARD_CONSTRAINT_RESTATEMENT_TAIL_EN = """\
|
|
84
|
+
IMPORTANT: The agent's turn ends immediately at the closing tag of its last <entml:invoke> block, with no content of any kind — including an id comment — following it."""
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def format_function_calling_behavior() -> str:
|
|
88
|
+
return f"<function_calling_behavior>\n{FUNCTION_CALLING_BEHAVIOR_EN}\n</function_calling_behavior>"
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def format_thinking_behavior(
|
|
92
|
+
*,
|
|
93
|
+
enabled: bool,
|
|
94
|
+
has_tools: bool = True,
|
|
95
|
+
injection_mode: str = "on",
|
|
96
|
+
) -> str:
|
|
97
|
+
if not enabled:
|
|
98
|
+
body = (
|
|
99
|
+
THINKING_BEHAVIOR_OFF_WITH_HISTORY_WITH_TOOLS
|
|
100
|
+
if has_tools
|
|
101
|
+
else THINKING_BEHAVIOR_OFF_WITH_HISTORY_NO_TOOLS
|
|
102
|
+
)
|
|
103
|
+
elif injection_mode == "auto":
|
|
104
|
+
body = (
|
|
105
|
+
THINKING_BEHAVIOR_AUTO_WITH_TOOLS
|
|
106
|
+
if has_tools
|
|
107
|
+
else THINKING_BEHAVIOR_AUTO_NO_TOOLS
|
|
108
|
+
)
|
|
109
|
+
else:
|
|
110
|
+
body = (
|
|
111
|
+
THINKING_BEHAVIOR_ON_WITH_TOOLS
|
|
112
|
+
if has_tools
|
|
113
|
+
else THINKING_BEHAVIOR_ON_NO_TOOLS
|
|
114
|
+
)
|
|
115
|
+
return f"<thinking_behavior>\n{body}\n</thinking_behavior>"
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def format_hard_constraint_restatement() -> str:
|
|
119
|
+
body = f"{HARD_CONSTRAINT_RESTATEMENT_BASE_EN}\n{HARD_CONSTRAINT_RESTATEMENT_TAIL_EN}"
|
|
120
|
+
return (
|
|
121
|
+
f"<entml:hard_constraint_restatement>\n"
|
|
122
|
+
f"{body}\n"
|
|
123
|
+
f"</entml:hard_constraint_restatement>"
|
|
124
|
+
)
|
|
@@ -83,7 +83,9 @@ def _clean_entml_tags(content: str) -> str:
|
|
|
83
83
|
# ---------------------------------------------------------------------------
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
from echotools.exec.fncall.protocols.entml_tool.invoke import
|
|
86
|
+
from echotools.exec.fncall.protocols.entml_tool.invoke import (
|
|
87
|
+
format_entml_parameter_value,
|
|
88
|
+
)
|
|
87
89
|
|
|
88
90
|
|
|
89
91
|
def _render_parameter_value(v: Any) -> str:
|
|
@@ -151,7 +151,7 @@ def _build_entml_no_tools_prompt(
|
|
|
151
151
|
if history_text.strip():
|
|
152
152
|
sections.append(format_entml_conversation_history(history_text))
|
|
153
153
|
thinking_behavior = build_entml_thinking_behavior_section(
|
|
154
|
-
protocol_options, history_text=history_text
|
|
154
|
+
protocol_options, history_text=history_text, has_tools=False
|
|
155
155
|
)
|
|
156
156
|
if thinking_behavior:
|
|
157
157
|
sections.append(thinking_behavior)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Entropy ML (entml) 协议实现。
|
|
2
2
|
|
|
3
|
-
- 工具调用:<entml:invoke> / <entml:parameter
|
|
3
|
+
- 工具调用:<entml:invoke> / <entml:parameter>
|
|
4
4
|
- 对话历史:<entml:conversation_history>
|
|
5
5
|
- 当前用户消息:<current_user_message>
|
|
6
6
|
"""
|
|
@@ -14,11 +14,12 @@ from echotools.exec.fncall.protocols.entml_patterns import (
|
|
|
14
14
|
find_actionable_entml_invoke_open,
|
|
15
15
|
resolve_known_tool_names,
|
|
16
16
|
strip_actionable_entml_invoke_blocks,
|
|
17
|
-
strip_legacy_function_calls_wrapper,
|
|
18
17
|
strip_tool_entml_residue,
|
|
19
18
|
)
|
|
20
19
|
from echotools.exec.fncall.protocols.entml_schema import format_entml_tool_descs
|
|
21
|
-
from echotools.exec.fncall.protocols.entml_tool.fakemarkup import
|
|
20
|
+
from echotools.exec.fncall.protocols.entml_tool.fakemarkup import (
|
|
21
|
+
strip_orphan_entml_close_tags,
|
|
22
|
+
)
|
|
22
23
|
from echotools.exec.fncall.protocols.entml_tool.invoke import (
|
|
23
24
|
format_entml_tool_calls,
|
|
24
25
|
parse_entml_tool_calls,
|
|
@@ -27,7 +28,6 @@ from echotools.exec.fncall.shared.coercion import _build_param_schema_index
|
|
|
27
28
|
from echotools.exec.fncall.shared.entml_format import (
|
|
28
29
|
_parse_tool_call_args,
|
|
29
30
|
_render_tool_call_line,
|
|
30
|
-
_render_tool_history_block,
|
|
31
31
|
build_entml_render_prompt,
|
|
32
32
|
format_entml_conversation_history,
|
|
33
33
|
format_entml_current_user_message,
|
|
@@ -58,7 +58,6 @@ class EntmlProtocol(ToolProtocol):
|
|
|
58
58
|
|
|
59
59
|
_TRIGGER = "<entml:invoke>"
|
|
60
60
|
_TRIGGER_PREFIX = "<entml:invoke"
|
|
61
|
-
_LEGACY_WRAPPER_PREFIX = "<entml:function_calls"
|
|
62
61
|
_THINKING_PREFIX = "<entml:thinking"
|
|
63
62
|
|
|
64
63
|
def get_trigger_tags(self) -> List[str]:
|
|
@@ -70,7 +69,7 @@ class EntmlProtocol(ToolProtocol):
|
|
|
70
69
|
]
|
|
71
70
|
|
|
72
71
|
def normalize_stream_buffer(self, buffer: str) -> str:
|
|
73
|
-
return
|
|
72
|
+
return buffer
|
|
74
73
|
|
|
75
74
|
def get_stream_end_tags(self) -> List[str]:
|
|
76
75
|
return []
|
|
@@ -126,11 +125,6 @@ class EntmlProtocol(ToolProtocol):
|
|
|
126
125
|
if find_actionable_entml_invoke_open(buffer, known_names=known) >= 0:
|
|
127
126
|
return None
|
|
128
127
|
hold: Optional[int] = None
|
|
129
|
-
legacy_pos = buffer.find(self._LEGACY_WRAPPER_PREFIX)
|
|
130
|
-
if legacy_pos >= 0:
|
|
131
|
-
close = buffer.find(">", legacy_pos)
|
|
132
|
-
if close < 0 and (hold is None or legacy_pos < hold):
|
|
133
|
-
hold = legacy_pos
|
|
134
128
|
invoke_pos = buffer.find(self._TRIGGER_PREFIX)
|
|
135
129
|
if (
|
|
136
130
|
invoke_pos >= 0
|
{echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_patterns/__init__.py
RENAMED
|
@@ -29,6 +29,10 @@ from .params import (
|
|
|
29
29
|
synthetic_close_invoke_body,
|
|
30
30
|
)
|
|
31
31
|
from .regex import (
|
|
32
|
+
_INVOKE_CLOSE,
|
|
33
|
+
_INVOKE_OPEN_PREFIX,
|
|
34
|
+
_PARAM_CLOSE_VALID_RE,
|
|
35
|
+
_PARAM_CLOSE_VALID_STREAM_RE,
|
|
32
36
|
BARE_INVOKE_CHILD_OPEN_RE,
|
|
33
37
|
BARE_INVOKE_CHILD_RE,
|
|
34
38
|
BLOCK_RE,
|
|
@@ -42,12 +46,8 @@ from .regex import (
|
|
|
42
46
|
PARAM_RE,
|
|
43
47
|
PARAMETERS_RE,
|
|
44
48
|
SUB_TAG_RE,
|
|
45
|
-
_INVOKE_CLOSE,
|
|
46
|
-
_INVOKE_OPEN_PREFIX,
|
|
47
|
-
_PARAM_CLOSE_VALID_RE,
|
|
48
|
-
_PARAM_CLOSE_VALID_STREAM_RE,
|
|
49
49
|
)
|
|
50
|
-
from .strip import
|
|
50
|
+
from .strip import strip_tool_entml_residue
|
|
51
51
|
|
|
52
52
|
__all__ = [
|
|
53
53
|
"BARE_INVOKE_CHILD_OPEN_RE",
|
|
@@ -87,7 +87,6 @@ __all__ = [
|
|
|
87
87
|
"resolve_known_tool_names",
|
|
88
88
|
"split_mangled_json_param_tail",
|
|
89
89
|
"strip_actionable_entml_invoke_blocks",
|
|
90
|
-
"strip_legacy_function_calls_wrapper",
|
|
91
90
|
"strip_tool_entml_residue",
|
|
92
91
|
"synthetic_close_invoke_body",
|
|
93
92
|
]
|
{echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_patterns/regex.py
RENAMED
|
@@ -71,14 +71,6 @@ _TOOL_WRAPPER_PAIR_RE = re.compile(
|
|
|
71
71
|
r"<entml:function_calls\b[^>]*>[\s\S]*?</entml:function_calls>",
|
|
72
72
|
re.DOTALL,
|
|
73
73
|
)
|
|
74
|
-
_LEGACY_WRAPPER_OPEN_RE = re.compile(
|
|
75
|
-
r"<entml:function_calls\b[^>]*>\s*",
|
|
76
|
-
re.IGNORECASE,
|
|
77
|
-
)
|
|
78
|
-
_LEGACY_WRAPPER_CLOSE_RE = re.compile(
|
|
79
|
-
r"\s*</entml:function_calls\s*>",
|
|
80
|
-
re.IGNORECASE,
|
|
81
|
-
)
|
|
82
74
|
_TOOL_ORPHAN_TAG_RE = re.compile(
|
|
83
75
|
r"</?entml:(?:function_calls|invoke|parameter|parameters)\b[^>]*/?>",
|
|
84
76
|
re.DOTALL,
|
{echotools-2.3.104 → echotools-2.4.1}/src/echotools/exec/fncall/protocols/entml_patterns/strip.py
RENAMED
|
@@ -3,24 +3,13 @@ from __future__ import annotations
|
|
|
3
3
|
import re
|
|
4
4
|
from typing import Optional, Set
|
|
5
5
|
|
|
6
|
+
from .invoke import _strip_orphan_invoke_tags, _strip_orphan_non_invoke_tool_tags
|
|
6
7
|
from .params import strip_actionable_entml_invoke_blocks
|
|
7
8
|
from .regex import (
|
|
8
9
|
_EMPTY_FENCE_RE,
|
|
9
10
|
_FENCE_ONLY_LINE_RE,
|
|
10
|
-
_LEGACY_WRAPPER_CLOSE_RE,
|
|
11
|
-
_LEGACY_WRAPPER_OPEN_RE,
|
|
12
11
|
_TOOL_WRAPPER_PAIR_RE,
|
|
13
12
|
)
|
|
14
|
-
from .invoke import _strip_orphan_invoke_tags, _strip_orphan_non_invoke_tool_tags
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def strip_legacy_function_calls_wrapper(text: str) -> str:
|
|
18
|
-
"""移除完整 legacy ``<entml:function_calls>`` 开/闭标签(裸 invoke 为一等格式)。"""
|
|
19
|
-
if not text:
|
|
20
|
-
return text
|
|
21
|
-
out = _LEGACY_WRAPPER_OPEN_RE.sub("", text)
|
|
22
|
-
out = _LEGACY_WRAPPER_CLOSE_RE.sub("", out)
|
|
23
|
-
return out
|
|
24
13
|
|
|
25
14
|
|
|
26
15
|
def strip_tool_entml_residue(
|