style: auto ruff format
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
.PHONY: check
|
.PHONY: check
|
||||||
|
|
||||||
check:
|
check:
|
||||||
|
uv run ruff format
|
||||||
uv run ruff check .
|
uv run ruff check .
|
||||||
uv run ty check .
|
uv run ty check .
|
||||||
uv run pytest
|
uv run pytest
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ class ConfigError(RuntimeError):
|
|||||||
|
|
||||||
|
|
||||||
_EXAMPLE_CONFIG = (
|
_EXAMPLE_CONFIG = (
|
||||||
'bot_token = "123456789:ABCdefGHIjklMNOpqrsTUVwxyz"\n'
|
'bot_token = "123456789:ABCdefGHIjklMNOpqrsTUVwxyz"\nchat_id = 123456789\n'
|
||||||
"chat_id = 123456789\n"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -29,10 +28,7 @@ def _display_path(path: Path) -> str:
|
|||||||
def _missing_config_message(primary: Path, alternate: Path | None = None) -> str:
|
def _missing_config_message(primary: Path, alternate: Path | None = None) -> str:
|
||||||
example = "Example config:\n```\n" + _EXAMPLE_CONFIG + "```\n"
|
example = "Example config:\n```\n" + _EXAMPLE_CONFIG + "```\n"
|
||||||
if alternate is None:
|
if alternate is None:
|
||||||
return (
|
return f"Missing config file `{_display_path(primary)}`.\n{example}"
|
||||||
f"Missing config file `{_display_path(primary)}`.\n"
|
|
||||||
f"{example}"
|
|
||||||
)
|
|
||||||
return (
|
return (
|
||||||
"Missing takopi config.\n"
|
"Missing takopi config.\n"
|
||||||
"Create one of these files:\n"
|
"Create one of these files:\n"
|
||||||
|
|||||||
@@ -41,9 +41,7 @@ def extract_session_id(text: str | None) -> str | None:
|
|||||||
return found
|
return found
|
||||||
|
|
||||||
|
|
||||||
def resolve_resume_session(
|
def resolve_resume_session(text: str | None, reply_text: str | None) -> str | None:
|
||||||
text: str | None, reply_text: str | None
|
|
||||||
) -> str | None:
|
|
||||||
return extract_session_id(text) or extract_session_id(reply_text)
|
return extract_session_id(text) or extract_session_id(reply_text)
|
||||||
|
|
||||||
|
|
||||||
@@ -124,9 +122,7 @@ def truncate_for_telegram(text: str, limit: int) -> str:
|
|||||||
return (head + sep + tail)[:limit]
|
return (head + sep + tail)[:limit]
|
||||||
|
|
||||||
|
|
||||||
def prepare_telegram(
|
def prepare_telegram(md: str, *, limit: int) -> tuple[str, list[dict[str, Any]] | None]:
|
||||||
md: str, *, limit: int
|
|
||||||
) -> tuple[str, list[dict[str, Any]] | None]:
|
|
||||||
rendered, entities = render_markdown(md)
|
rendered, entities = render_markdown(md)
|
||||||
if len(rendered) > limit:
|
if len(rendered) > limit:
|
||||||
rendered = truncate_for_telegram(rendered, limit)
|
rendered = truncate_for_telegram(rendered, limit)
|
||||||
@@ -655,9 +651,7 @@ async def _run_main_loop(cfg: BridgeConfig) -> None:
|
|||||||
r = msg.get("reply_to_message") or {}
|
r = msg.get("reply_to_message") or {}
|
||||||
resume_session = resolve_resume_session(text, r.get("text"))
|
resume_session = resolve_resume_session(text, r.get("text"))
|
||||||
|
|
||||||
await queue.put(
|
await queue.put((msg["chat"]["id"], user_msg_id, text, resume_session))
|
||||||
(msg["chat"]["id"], user_msg_id, text, resume_session)
|
|
||||||
)
|
|
||||||
finally:
|
finally:
|
||||||
await cfg.bot.close()
|
await cfg.bot.close()
|
||||||
|
|
||||||
|
|||||||
@@ -130,15 +130,27 @@ def format_event(
|
|||||||
exit_part = ""
|
exit_part = ""
|
||||||
else:
|
else:
|
||||||
status = STATUS_FAIL if exit_code is not None else STATUS_DONE
|
status = STATUS_FAIL if exit_code is not None else STATUS_DONE
|
||||||
exit_part = f" (exit {exit_code})" if exit_code is not None else ""
|
exit_part = (
|
||||||
|
f" (exit {exit_code})" if exit_code is not None else ""
|
||||||
|
)
|
||||||
line = prefix + f"{status} {command}{exit_part}"
|
line = prefix + f"{status} {command}{exit_part}"
|
||||||
return last_item, [line], line, prefix
|
return last_item, [line], line, prefix
|
||||||
case ("mcp_tool_call", "item.started"):
|
case ("mcp_tool_call", "item.started"):
|
||||||
name = ".".join(part for part in (item["server"], item["tool"]) if part) or "tool"
|
name = (
|
||||||
|
".".join(
|
||||||
|
part for part in (item["server"], item["tool"]) if part
|
||||||
|
)
|
||||||
|
or "tool"
|
||||||
|
)
|
||||||
line = prefix + f"{STATUS_RUNNING} tool: {name}"
|
line = prefix + f"{STATUS_RUNNING} tool: {name}"
|
||||||
return last_item, [line], line, prefix
|
return last_item, [line], line, prefix
|
||||||
case ("mcp_tool_call", "item.completed"):
|
case ("mcp_tool_call", "item.completed"):
|
||||||
name = ".".join(part for part in (item["server"], item["tool"]) if part) or "tool"
|
name = (
|
||||||
|
".".join(
|
||||||
|
part for part in (item["server"], item["tool"]) if part
|
||||||
|
)
|
||||||
|
or "tool"
|
||||||
|
)
|
||||||
line = prefix + f"{STATUS_DONE} tool: {name}"
|
line = prefix + f"{STATUS_DONE} tool: {name}"
|
||||||
return last_item, [line], line, prefix
|
return last_item, [line], line, prefix
|
||||||
case ("web_search", "item.completed"):
|
case ("web_search", "item.completed"):
|
||||||
@@ -146,12 +158,20 @@ def format_event(
|
|||||||
line = prefix + f"{STATUS_DONE} searched: {query}"
|
line = prefix + f"{STATUS_DONE} searched: {query}"
|
||||||
return last_item, [line], line, prefix
|
return last_item, [line], line, prefix
|
||||||
case ("file_change", "item.completed"):
|
case ("file_change", "item.completed"):
|
||||||
paths = [change["path"] for change in item["changes"] if change.get("path")]
|
paths = [
|
||||||
|
change["path"]
|
||||||
|
for change in item["changes"]
|
||||||
|
if change.get("path")
|
||||||
|
]
|
||||||
if not paths:
|
if not paths:
|
||||||
total = len(item["changes"])
|
total = len(item["changes"])
|
||||||
desc = "updated files" if total == 0 else f"updated {total} files"
|
desc = (
|
||||||
|
"updated files" if total == 0 else f"updated {total} files"
|
||||||
|
)
|
||||||
elif len(paths) <= 3:
|
elif len(paths) <= 3:
|
||||||
desc = "updated " + ", ".join(f"`{_shorten_path(p, MAX_PATH_LEN)}`" for p in paths)
|
desc = "updated " + ", ".join(
|
||||||
|
f"`{_shorten_path(p, MAX_PATH_LEN)}`" for p in paths
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
desc = f"updated {len(paths)} files"
|
desc = f"updated {len(paths)} files"
|
||||||
line = prefix + f"{STATUS_DONE} {desc}"
|
line = prefix + f"{STATUS_DONE} {desc}"
|
||||||
@@ -200,7 +220,11 @@ class ExecProgressRenderer:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# Replace the preceding "running" line for the same item on completion.
|
# Replace the preceding "running" line for the same item on completion.
|
||||||
if event["type"] == "item.completed" and progress_prefix and self.recent_actions:
|
if (
|
||||||
|
event["type"] == "item.completed"
|
||||||
|
and progress_prefix
|
||||||
|
and self.recent_actions
|
||||||
|
):
|
||||||
last = self.recent_actions[-1]
|
last = self.recent_actions[-1]
|
||||||
if last.startswith(progress_prefix + f"{STATUS_RUNNING} "):
|
if last.startswith(progress_prefix + f"{STATUS_RUNNING} "):
|
||||||
self.recent_actions.pop()
|
self.recent_actions.pop()
|
||||||
|
|||||||
@@ -2,4 +2,3 @@ import sys
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
||||||
|
|
||||||
|
|||||||
@@ -41,9 +41,7 @@ def test_resolve_resume_session_prefers_message_text() -> None:
|
|||||||
uuid_reply = "019b66fc-64c2-7a71-81cd-081c504cfeb2"
|
uuid_reply = "019b66fc-64c2-7a71-81cd-081c504cfeb2"
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
resolve_resume_session(
|
resolve_resume_session(f"resume: `{uuid_message}`", f"resume: `{uuid_reply}`")
|
||||||
f"resume: `{uuid_message}`", f"resume: `{uuid_reply}`"
|
|
||||||
)
|
|
||||||
== uuid_message
|
== uuid_message
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -51,7 +49,10 @@ def test_resolve_resume_session_prefers_message_text() -> None:
|
|||||||
def test_resolve_resume_session_uses_reply_when_missing() -> None:
|
def test_resolve_resume_session_uses_reply_when_missing() -> None:
|
||||||
uuid_reply = "019b66fc-64c2-7a71-81cd-081c504cfeb2"
|
uuid_reply = "019b66fc-64c2-7a71-81cd-081c504cfeb2"
|
||||||
|
|
||||||
assert resolve_resume_session("no resume here", f"resume: `{uuid_reply}`") == uuid_reply
|
assert (
|
||||||
|
resolve_resume_session("no resume here", f"resume: `{uuid_reply}`")
|
||||||
|
== uuid_reply
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_truncate_for_telegram_preserves_resume_line() -> None:
|
def test_truncate_for_telegram_preserves_resume_line() -> None:
|
||||||
@@ -143,7 +144,11 @@ class _FakeRunner:
|
|||||||
self._saw_agent_message = saw_agent_message
|
self._saw_agent_message = saw_agent_message
|
||||||
|
|
||||||
async def run_serialized(self, *_args, **_kwargs) -> tuple[str, str, bool]:
|
async def run_serialized(self, *_args, **_kwargs) -> tuple[str, str, bool]:
|
||||||
return ("019b66fc-64c2-7a71-81cd-081c504cfeb2", self._answer, self._saw_agent_message)
|
return (
|
||||||
|
"019b66fc-64c2-7a71-81cd-081c504cfeb2",
|
||||||
|
self._answer,
|
||||||
|
self._saw_agent_message,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class _FakeClock:
|
class _FakeClock:
|
||||||
|
|||||||
@@ -81,7 +81,10 @@ def test_render_event_cli_all_formats_fixture() -> None:
|
|||||||
assert any(line.startswith("stream error:") for line in out)
|
assert any(line.startswith("stream error:") for line in out)
|
||||||
assert any(line.startswith("4. ▸ `pytest -q`") for line in out)
|
assert any(line.startswith("4. ▸ `pytest -q`") for line in out)
|
||||||
assert any("✗ `pytest -q` (exit 1)" in line for line in out)
|
assert any("✗ `pytest -q` (exit 1)" in line for line in out)
|
||||||
assert any("searched: python jsonlines parser handle unknown fields" in line for line in out)
|
assert any(
|
||||||
|
"searched: python jsonlines parser handle unknown fields" in line
|
||||||
|
for line in out
|
||||||
|
)
|
||||||
assert any("tool: github.search_issues" in line for line in out)
|
assert any("tool: github.search_issues" in line for line in out)
|
||||||
assert any("updated `src/compute_answer.py`" in line for line in out)
|
assert any("updated `src/compute_answer.py`" in line for line in out)
|
||||||
assert any(
|
assert any(
|
||||||
|
|||||||
@@ -16,7 +16,5 @@ def test_render_markdown_code_fence_language_is_string() -> None:
|
|||||||
|
|
||||||
assert text == "print('x')\n\n"
|
assert text == "print('x')\n\n"
|
||||||
assert entities is not None
|
assert entities is not None
|
||||||
assert any(
|
assert any(e.get("type") == "pre" and e.get("language") == "py" for e in entities)
|
||||||
e.get("type") == "pre" and e.get("language") == "py" for e in entities
|
|
||||||
)
|
|
||||||
assert any(e.get("type") == "code" for e in entities)
|
assert any(e.get("type") == "code" for e in entities)
|
||||||
|
|||||||
Reference in New Issue
Block a user