echotools 2.3.30__tar.gz → 2.3.31__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.30 → echotools-2.3.31}/PKG-INFO +1 -1
- {echotools-2.3.30 → echotools-2.3.31}/pyproject.toml +1 -1
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/prompt/history_format.py +11 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/prompt/inject.py +5 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/prompt/templates.py +9 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/protocols/entml.py +7 -1
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools.egg-info/PKG-INFO +1 -1
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_entml_protocol.py +43 -0
- {echotools-2.3.30 → echotools-2.3.31}/README.md +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/docs/README.md +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/setup.cfg +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/cache/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/cache/list_cache.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/cache/memory_cache.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/config/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/config/base.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/config/center.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/config/center_notify.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/config/center_template.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/config/loader.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/config/merge.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/errors/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/errors/base.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/errors/classify.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/errors/common.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/errors/http.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/ids/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/ids/generator.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/io/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/io/io_utils.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/io/printstream.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/logger/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/logger/manager.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/retry/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/base/retry/retry.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/compat.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/dispatch/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/dispatch/candidate.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/dispatch/dispatcher.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/dispatch/proxy_selector.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/dispatch/race.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/dispatch/selector.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/dispatch/usage.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/parsers/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/parsers/stream.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/parsers/xml_params.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/parsers/xml_parser.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/prompt/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/prompt/history.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/prompt/prompt_helpers.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/protocols/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/protocols/entml_invoke.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/protocols/entml_patterns.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/protocols/entml_thinking.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/protocols/entml_thinking_history.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/protocols/entml_thinking_parse.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/protocols/entml_tools.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/protocols/entml_values.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/registry.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/shared/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/shared/coercion.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/shared/loop_detect.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/shared/normalization.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/shared/schema_render.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/shared/xml_helpers.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/keys.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/lifecycle/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/lifecycle/manager.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/lifecycle/updater.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/lifecycle/updater_pull.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/process/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/process/port.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/protocol/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/protocol/base.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/conpty.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/local/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/local/core.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/local/proc.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/local/unix.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/local/win.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/sanitize.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/session/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/session/base.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/session/client.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/ssh.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/terminal/tmux.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/console/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/console/charmap.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/console/spinner.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/console/ui.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/events/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/events/bus.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/events/event.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/spinner/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/spinner/spinner.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/spinner/spinner_color.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/tracing/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/tracing/context.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/tracing/span.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/tracing/tracer.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/translate.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/watcher/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/watcher/file_watcher.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/application.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/broker.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/app.js +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/filezone.js +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/motionkit.js +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/sendbutton.js +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/sortablelist.css +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/sortablelist.js +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/textinput.js +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/voiceinput.js +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/fonts/inter-500.woff2 +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/fonts/inter-600.woff2 +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/fonts/inter400.woff2 +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/fonts/tailwind.css +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/inputbox.css +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/inputbox.js +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/style.css +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/voicegif.js +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/middleware.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/stats.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/utils.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/files/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/files/file_util.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/network/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/network/http_utils.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/plugin/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/plugin/base.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/plugin/discovery.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/plugin/registry.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/plugin/registry_ops.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/proxy/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/proxy/manager.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/runtime/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/runtime/collector.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/scheduler/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/scheduler/scheduler.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/sdk/__init__.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/plat/sdk/facade.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools/version.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools.egg-info/SOURCES.txt +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools.egg-info/dependency_links.txt +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools.egg-info/requires.txt +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/echotools.egg-info/top_level.txt +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/bench_import.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/conftest.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_cache_retry.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_completion.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_config.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_config_extended.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_console.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_coverage_core.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_dispatch.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_dispatch_extended.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_dispatch_race.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_entml_thinking_history.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_entml_thinking_parse.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_entml_tools.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_errors.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_errors_common.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_events.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_events_event.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_facade.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_fncall.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_ids.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_imports.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_io.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_keys.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_lifecycle.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_logger.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_merge.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_plugin.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_printstream.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_protocols.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_proxy.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_proxy_selector.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_runtime.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_scheduler.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_tracing.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_usage.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_web.py +0 -0
- {echotools-2.3.30 → echotools-2.3.31}/src/tests/test_web_broker.py +0 -0
|
@@ -15,6 +15,17 @@ from .prompt_helpers import (
|
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
|
|
18
|
+
def history_contains_tool_calls(messages: List[Dict[str, Any]]) -> bool:
|
|
19
|
+
"""历史消息中是否包含 assistant tool_calls 或 tool 结果。"""
|
|
20
|
+
for m in messages:
|
|
21
|
+
role = m.get("role") or "user"
|
|
22
|
+
if role == "assistant" and m.get("tool_calls"):
|
|
23
|
+
return True
|
|
24
|
+
if role == "tool":
|
|
25
|
+
return True
|
|
26
|
+
return False
|
|
27
|
+
|
|
28
|
+
|
|
18
29
|
def _format_conversation_history(
|
|
19
30
|
messages: List[Dict[str, Any]],
|
|
20
31
|
protocol: Optional[Any] = None,
|
|
@@ -12,6 +12,7 @@ from echotools.exec.fncall.prompt.history import (
|
|
|
12
12
|
)
|
|
13
13
|
from echotools.exec.fncall.prompt.history_format import (
|
|
14
14
|
_format_conversation_history,
|
|
15
|
+
history_contains_tool_calls,
|
|
15
16
|
)
|
|
16
17
|
from echotools.exec.fncall.prompt.prompt_helpers import (
|
|
17
18
|
build_no_tools_prompt,
|
|
@@ -61,6 +62,7 @@ def build_tools_prompt(
|
|
|
61
62
|
current_user_message: str,
|
|
62
63
|
loop_detection_threshold: int,
|
|
63
64
|
protocol_options: Optional[Dict[str, Any]] = None,
|
|
65
|
+
history_has_tool_calls: bool = False,
|
|
64
66
|
) -> str:
|
|
65
67
|
loop_warning = ""
|
|
66
68
|
if loop_detection_threshold > 0:
|
|
@@ -77,6 +79,8 @@ def build_tools_prompt(
|
|
|
77
79
|
if protocol_options is not None and protocol.id == "entml"
|
|
78
80
|
else {}
|
|
79
81
|
)
|
|
82
|
+
if protocol.id == "entml":
|
|
83
|
+
extra["history_has_tool_calls"] = history_has_tool_calls
|
|
80
84
|
return protocol.render_prompt(
|
|
81
85
|
tool_descs=tool_descs,
|
|
82
86
|
lang=lang,
|
|
@@ -133,6 +137,7 @@ def inject_fncall(
|
|
|
133
137
|
prompt = build_tools_prompt(
|
|
134
138
|
protocol, tools, normalized, lang, user_system_prompt,
|
|
135
139
|
history_text, current_user_message, loop_detection_threshold, protocol_options,
|
|
140
|
+
history_has_tool_calls=history_contains_tool_calls(history_messages),
|
|
136
141
|
)
|
|
137
142
|
if dump_prompt:
|
|
138
143
|
_maybe_dump_prompt(prompt, dump_dir)
|
|
@@ -118,6 +118,15 @@ _HISTORY_CLARIFY_EN = (
|
|
|
118
118
|
"The user's latest message follows below."
|
|
119
119
|
)
|
|
120
120
|
|
|
121
|
+
_HISTORY_TOOL_INVOKE_REMINDER_EN = (
|
|
122
|
+
"Reminder — tool notation in the conversation history above: prior tool "
|
|
123
|
+
"calls appear as compact pseudocode (e.g. `[function_name(arg=\"value\")]` "
|
|
124
|
+
"and optional `→ Result:` / `→ Error:` lines). That transcript is for "
|
|
125
|
+
"context only; it is not parsed and must not be copied. To invoke a tool "
|
|
126
|
+
"in your reply, output a valid `<entml:invoke>` block exactly as specified "
|
|
127
|
+
"in the tool instructions at the top of this prompt."
|
|
128
|
+
)
|
|
129
|
+
|
|
121
130
|
_HISTORY_CLARIFY_ZH = (
|
|
122
131
|
"以下是已完成的交互记录。"
|
|
123
132
|
"此处展示的所有工具调用及其结果均已执行完毕,请勿重复调用。"
|
|
@@ -10,7 +10,10 @@ from __future__ import annotations
|
|
|
10
10
|
import json as _json
|
|
11
11
|
from typing import Any, Dict, List, Optional, Tuple
|
|
12
12
|
|
|
13
|
-
from echotools.exec.fncall.prompt.templates import
|
|
13
|
+
from echotools.exec.fncall.prompt.templates import (
|
|
14
|
+
_HISTORY_CLARIFY_EN,
|
|
15
|
+
_HISTORY_TOOL_INVOKE_REMINDER_EN,
|
|
16
|
+
)
|
|
14
17
|
from echotools.exec.fncall.protocols.entml_invoke import (
|
|
15
18
|
format_entml_tool_calls,
|
|
16
19
|
parse_entml_tool_calls,
|
|
@@ -117,6 +120,7 @@ class EntmlProtocol(ToolProtocol):
|
|
|
117
120
|
loop_warning: str = "",
|
|
118
121
|
current_user_message: str = "",
|
|
119
122
|
protocol_options: Optional[Dict[str, Any]] = None,
|
|
123
|
+
history_has_tool_calls: bool = False,
|
|
120
124
|
) -> str:
|
|
121
125
|
if tool_descs:
|
|
122
126
|
sections: List[str] = [
|
|
@@ -138,6 +142,8 @@ class EntmlProtocol(ToolProtocol):
|
|
|
138
142
|
sections.append(
|
|
139
143
|
format_entml_conversation_history(history_text, _HISTORY_CLARIFY_EN)
|
|
140
144
|
)
|
|
145
|
+
if tool_descs and history_has_tool_calls:
|
|
146
|
+
sections.append(_HISTORY_TOOL_INVOKE_REMINDER_EN)
|
|
141
147
|
|
|
142
148
|
if loop_warning:
|
|
143
149
|
sections.append(f"<loop_warning>\n{loop_warning}\n</loop_warning>")
|
|
@@ -207,6 +207,49 @@ def test_entml_history_clarify_always_english() -> None:
|
|
|
207
207
|
content = inject_fncall(msgs, tools, proto, lang="zh")[0]["content"]
|
|
208
208
|
assert "The following is a transcript of completed interactions." in content
|
|
209
209
|
assert "以下是已完成的交互记录" not in content
|
|
210
|
+
assert "Reminder — tool notation in the conversation history above" not in content
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def test_entml_history_tool_invoke_reminder_when_tools_in_history() -> None:
|
|
214
|
+
proto = get_protocol("entml")
|
|
215
|
+
tools = [
|
|
216
|
+
{
|
|
217
|
+
"type": "function",
|
|
218
|
+
"function": {
|
|
219
|
+
"name": "search",
|
|
220
|
+
"description": "Search",
|
|
221
|
+
"parameters": {
|
|
222
|
+
"type": "object",
|
|
223
|
+
"properties": {"query": {"type": "string"}},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
msgs = [
|
|
229
|
+
{"role": "user", "content": "find docs"},
|
|
230
|
+
{
|
|
231
|
+
"role": "assistant",
|
|
232
|
+
"content": "",
|
|
233
|
+
"tool_calls": [{
|
|
234
|
+
"id": "call_1",
|
|
235
|
+
"type": "function",
|
|
236
|
+
"function": {
|
|
237
|
+
"name": "search",
|
|
238
|
+
"arguments": json.dumps({"query": "docs"}),
|
|
239
|
+
},
|
|
240
|
+
}],
|
|
241
|
+
},
|
|
242
|
+
{"role": "tool", "tool_call_id": "call_1", "content": "found 3"},
|
|
243
|
+
{"role": "user", "content": "summarize"},
|
|
244
|
+
]
|
|
245
|
+
content = inject_fncall(msgs, tools, proto)[0]["content"]
|
|
246
|
+
assert "[search(query=\"docs\")]" in content
|
|
247
|
+
assert "Reminder — tool notation in the conversation history above" in content
|
|
248
|
+
assert "output a valid `<entml:invoke>` block" in content
|
|
249
|
+
hist_idx = content.index("<entml:conversation_history>")
|
|
250
|
+
reminder_idx = content.index("Reminder — tool notation")
|
|
251
|
+
user_idx = content.index("<current_user_message>")
|
|
252
|
+
assert hist_idx < reminder_idx < user_idx
|
|
210
253
|
|
|
211
254
|
|
|
212
255
|
@pytest.mark.parametrize(
|
|
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.30 → echotools-2.3.31}/src/echotools/exec/fncall/protocols/entml_thinking_history.py
RENAMED
|
File without changes
|
{echotools-2.3.30 → echotools-2.3.31}/src/echotools/exec/fncall/protocols/entml_thinking_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
|
|
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.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/filezone.js
RENAMED
|
File without changes
|
{echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/motionkit.js
RENAMED
|
File without changes
|
{echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/sendbutton.js
RENAMED
|
File without changes
|
{echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/sortablelist.css
RENAMED
|
File without changes
|
{echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/sortablelist.js
RENAMED
|
File without changes
|
{echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/textinput.js
RENAMED
|
File without changes
|
{echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/components/voiceinput.js
RENAMED
|
File without changes
|
{echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/fonts/inter-500.woff2
RENAMED
|
File without changes
|
{echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/fonts/inter-600.woff2
RENAMED
|
File without changes
|
{echotools-2.3.30 → echotools-2.3.31}/src/echotools/media/web/input_box/fonts/inter400.woff2
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
|
|
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
|