fix(exec_render): rename header item to step
This commit is contained in:
@@ -32,7 +32,7 @@ def format_header(elapsed_s: float, item: int | None, label: str) -> str:
|
|||||||
elapsed = format_elapsed(elapsed_s)
|
elapsed = format_elapsed(elapsed_s)
|
||||||
parts = [label, elapsed]
|
parts = [label, elapsed]
|
||||||
if item is not None:
|
if item is not None:
|
||||||
parts.append(f"item {item}")
|
parts.append(f"step {item}")
|
||||||
return HEADER_SEP.join(parts)
|
return HEADER_SEP.join(parts)
|
||||||
|
|
||||||
|
|
||||||
@@ -68,6 +68,7 @@ def format_event(
|
|||||||
last_item: int | None,
|
last_item: int | None,
|
||||||
*,
|
*,
|
||||||
command_width: int | None = None,
|
command_width: int | None = None,
|
||||||
|
escape_markdown: bool = False,
|
||||||
) -> tuple[int | None, list[str], str | None, str | None]:
|
) -> tuple[int | None, list[str], str | None, str | None]:
|
||||||
"""
|
"""
|
||||||
Returns (new_last_item, cli_lines, progress_line, progress_prefix).
|
Returns (new_last_item, cli_lines, progress_line, progress_prefix).
|
||||||
@@ -92,6 +93,9 @@ def format_event(
|
|||||||
item_num = extract_numeric_id(item["id"], last_item)
|
item_num = extract_numeric_id(item["id"], last_item)
|
||||||
last_item = item_num if item_num is not None else last_item
|
last_item = item_num if item_num is not None else last_item
|
||||||
prefix = f"{item_num}. "
|
prefix = f"{item_num}. "
|
||||||
|
if escape_markdown and item_num is not None:
|
||||||
|
# Avoid ordered-list parsing which renumbers items in MarkdownIt/CommonMark.
|
||||||
|
prefix = f"{item_num}\\." + " "
|
||||||
|
|
||||||
match (item["type"], etype):
|
match (item["type"], etype):
|
||||||
case ("agent_message", "item.completed"):
|
case ("agent_message", "item.completed"):
|
||||||
@@ -160,7 +164,9 @@ def format_event(
|
|||||||
def render_event_cli(
|
def render_event_cli(
|
||||||
event: dict[str, Any], last_item: int | None = None
|
event: dict[str, Any], last_item: int | None = None
|
||||||
) -> tuple[int | None, list[str]]:
|
) -> tuple[int | None, list[str]]:
|
||||||
last_item, cli_lines, _, _ = format_event(event, last_item, command_width=None)
|
last_item, cli_lines, _, _ = format_event(
|
||||||
|
event, last_item, command_width=None, escape_markdown=False
|
||||||
|
)
|
||||||
return last_item, cli_lines
|
return last_item, cli_lines
|
||||||
|
|
||||||
|
|
||||||
@@ -180,7 +186,10 @@ class ExecProgressRenderer:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
self.last_item, _, progress_line, progress_prefix = format_event(
|
self.last_item, _, progress_line, progress_prefix = format_event(
|
||||||
event, self.last_item, command_width=self.command_width
|
event,
|
||||||
|
self.last_item,
|
||||||
|
command_width=self.command_width,
|
||||||
|
escape_markdown=True,
|
||||||
)
|
)
|
||||||
if progress_line is None:
|
if progress_line is None:
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import json
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from takopi.exec_render import ExecProgressRenderer, render_event_cli
|
from takopi.exec_render import ExecProgressRenderer, render_event_cli
|
||||||
|
from takopi.rendering import render_markdown
|
||||||
|
|
||||||
|
|
||||||
def _loads(lines: str) -> list[dict]:
|
def _loads(lines: str) -> list[dict]:
|
||||||
@@ -67,11 +68,11 @@ def test_progress_renderer_renders_progress_and_final() -> None:
|
|||||||
r.note_event(evt)
|
r.note_event(evt)
|
||||||
|
|
||||||
progress = r.render_progress(3.0)
|
progress = r.render_progress(3.0)
|
||||||
assert progress.startswith("working · 3s · item 3")
|
assert progress.startswith("working · 3s · step 3")
|
||||||
assert "1. ✓ `bash -lc ls`" in progress
|
assert "1\\. ✓ `bash -lc ls`" in progress
|
||||||
|
|
||||||
final = r.render_final(3.0, "answer", status="done")
|
final = r.render_final(3.0, "answer", status="done")
|
||||||
assert final.startswith("done · 3s · item 3")
|
assert final.startswith("done · 3s · step 3")
|
||||||
assert "running:" not in final
|
assert "running:" not in final
|
||||||
assert "ran:" not in final
|
assert "ran:" not in final
|
||||||
assert final.endswith("answer")
|
assert final.endswith("answer")
|
||||||
@@ -97,6 +98,33 @@ def test_progress_renderer_clamps_actions_and_ignores_unknown() -> None:
|
|||||||
assert r.note_event(evt) is True
|
assert r.note_event(evt) is True
|
||||||
|
|
||||||
assert len(r.recent_actions) == 3
|
assert len(r.recent_actions) == 3
|
||||||
assert r.recent_actions[0].startswith("3. ")
|
assert r.recent_actions[0].startswith("3\\. ")
|
||||||
assert r.recent_actions[-1].startswith("5. ")
|
assert r.recent_actions[-1].startswith("5\\. ")
|
||||||
assert r.note_event({"type": "mystery"}) is False
|
assert r.note_event({"type": "mystery"}) is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_progress_renderer_preserves_item_ids_in_telegram_text() -> None:
|
||||||
|
r = ExecProgressRenderer(max_actions=5, command_width=None)
|
||||||
|
for i in (30, 31, 32):
|
||||||
|
r.note_event(
|
||||||
|
{
|
||||||
|
"type": "item.completed",
|
||||||
|
"item": {
|
||||||
|
"id": f"item_{i}",
|
||||||
|
"type": "command_execution",
|
||||||
|
"command": f"echo {i}",
|
||||||
|
"exit_code": 0,
|
||||||
|
"status": "completed",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
md = r.render_progress(0.0)
|
||||||
|
assert "30\\." in md
|
||||||
|
assert "31\\." in md
|
||||||
|
assert "32\\." in md
|
||||||
|
|
||||||
|
text, _ = render_markdown(md)
|
||||||
|
assert "30. ✓ echo 30" in text
|
||||||
|
assert "31. ✓ echo 31" in text
|
||||||
|
assert "32. ✓ echo 32" in text
|
||||||
|
|||||||
Reference in New Issue
Block a user