mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-07-15 12:58:04 +00:00
Rescue plain UI open-panel tool text
This commit is contained in:
@@ -256,6 +256,17 @@ _RAW_WEB_JSON_TOOL_RE = re.compile(
|
|||||||
)
|
)
|
||||||
_RAW_WEB_JSON_ALLOWED_KEYS = {"query", "queries", "time_filter", "freshness", "max_pages"}
|
_RAW_WEB_JSON_ALLOWED_KEYS = {"query", "queries", "time_filter", "freshness", "max_pages"}
|
||||||
|
|
||||||
|
# Narrow rescue for models that ignore native tool calling and print the UI
|
||||||
|
# command as plain text. Keep this intentionally tiny: open-panel is a harmless
|
||||||
|
# frontend event, while broad plain-text parsing of shell/doc/email tools would
|
||||||
|
# be unsafe.
|
||||||
|
_PLAIN_UI_OPEN_PANEL_RE = re.compile(
|
||||||
|
r"(?im)^\s*(?:`{1,3})?\s*ui_control\s+open_panel\s+"
|
||||||
|
r"(documents?|library|gallery|images?|email|inbox|mail|sessions?|chats?|history|"
|
||||||
|
r"notes?|brain|memor(?:y|ies)|skills?|settings|preferences|cookbook|models?)"
|
||||||
|
r"\s*(?:`{1,3})?\s*$"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Parsing functions
|
# Parsing functions
|
||||||
@@ -1018,6 +1029,14 @@ def parse_tool_blocks(text: str, skip_fenced: bool = False) -> List[ToolBlock]:
|
|||||||
if raw_web_json:
|
if raw_web_json:
|
||||||
blocks.append(raw_web_json[0])
|
blocks.append(raw_web_json[0])
|
||||||
|
|
||||||
|
# Pattern 7: plain `ui_control open_panel notes` line. This commonly comes
|
||||||
|
# from weaker native-tool models after reading the tool docs but failing to
|
||||||
|
# emit the actual structured call.
|
||||||
|
if not blocks:
|
||||||
|
m = _PLAIN_UI_OPEN_PANEL_RE.search(text)
|
||||||
|
if m:
|
||||||
|
blocks.append(ToolBlock("ui_control", f"open_panel {m.group(1).lower()}"))
|
||||||
|
|
||||||
return blocks
|
return blocks
|
||||||
|
|
||||||
|
|
||||||
@@ -1051,6 +1070,7 @@ def strip_tool_blocks(text: str, skip_fenced: bool = False) -> str:
|
|||||||
if raw_web_json:
|
if raw_web_json:
|
||||||
_, (start, end) = raw_web_json
|
_, (start, end) = raw_web_json
|
||||||
cleaned = cleaned[:start] + cleaned[end:]
|
cleaned = cleaned[:start] + cleaned[end:]
|
||||||
|
cleaned = _PLAIN_UI_OPEN_PANEL_RE.sub("", cleaned)
|
||||||
# Strip bare <invoke> blocks not wrapped in <tool_call>
|
# Strip bare <invoke> blocks not wrapped in <tool_call>
|
||||||
cleaned = _strip_bare_invoke_markup(cleaned)
|
cleaned = _strip_bare_invoke_markup(cleaned)
|
||||||
cleaned = re.sub(r'\n{3,}', '\n\n', cleaned)
|
cleaned = re.sub(r'\n{3,}', '\n\n', cleaned)
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import src.agent_tools # noqa: F401 (break agent_tools<->tool_parsing import cycle)
|
||||||
|
from src.tool_parsing import parse_tool_blocks, strip_tool_blocks
|
||||||
|
|
||||||
|
|
||||||
|
def test_plain_ui_control_open_panel_is_rescued_even_when_fences_skipped():
|
||||||
|
blocks = parse_tool_blocks("ui_control open_panel notes", skip_fenced=True)
|
||||||
|
|
||||||
|
assert len(blocks) == 1
|
||||||
|
assert blocks[0].tool_type == "ui_control"
|
||||||
|
assert blocks[0].content == "open_panel notes"
|
||||||
|
|
||||||
|
|
||||||
|
def test_plain_ui_control_open_panel_rescues_backticked_line():
|
||||||
|
blocks = parse_tool_blocks("``ui_control open_panel cookbook```", skip_fenced=True)
|
||||||
|
|
||||||
|
assert len(blocks) == 1
|
||||||
|
assert blocks[0].tool_type == "ui_control"
|
||||||
|
assert blocks[0].content == "open_panel cookbook"
|
||||||
|
|
||||||
|
|
||||||
|
def test_plain_ui_control_open_panel_strips_executed_line_only():
|
||||||
|
text = "I'll open it now.\nui_control open_panel notes"
|
||||||
|
|
||||||
|
assert strip_tool_blocks(text, skip_fenced=True) == "I'll open it now."
|
||||||
|
|
||||||
|
|
||||||
|
def test_plain_ui_control_rescue_does_not_run_other_commands():
|
||||||
|
assert parse_tool_blocks("ui_control switch_model gemma4:31b", skip_fenced=True) == []
|
||||||
|
assert parse_tool_blocks("bash ls", skip_fenced=True) == []
|
||||||
Reference in New Issue
Block a user