fix(telegram): track sessions for plugin runs (#107)

This commit is contained in:
banteg
2026-01-12 23:12:24 +04:00
committed by GitHub
parent 88591216f9
commit 85ecbc2b96
3 changed files with 129 additions and 2 deletions
+11 -2
View File
@@ -1433,6 +1433,7 @@ class _TelegramCommandExecutor(CommandExecutor):
runtime: TransportRuntime, runtime: TransportRuntime,
running_tasks: RunningTasks, running_tasks: RunningTasks,
scheduler: ThreadScheduler, scheduler: ThreadScheduler,
on_thread_known: Callable[[ResumeToken, anyio.Event], Awaitable[None]] | None,
chat_id: int, chat_id: int,
user_msg_id: int, user_msg_id: int,
thread_id: int | None, thread_id: int | None,
@@ -1443,6 +1444,7 @@ class _TelegramCommandExecutor(CommandExecutor):
self._runtime = runtime self._runtime = runtime
self._running_tasks = running_tasks self._running_tasks = running_tasks
self._scheduler = scheduler self._scheduler = scheduler
self._on_thread_known = on_thread_known
self._chat_id = chat_id self._chat_id = chat_id
self._user_msg_id = user_msg_id self._user_msg_id = user_msg_id
self._thread_id = thread_id self._thread_id = thread_id
@@ -1502,6 +1504,11 @@ class _TelegramCommandExecutor(CommandExecutor):
engine_override=request.engine, engine_override=request.engine,
context=request.context, context=request.context,
) )
on_thread_known = (
self._scheduler.note_thread_known
if self._on_thread_known is None
else self._on_thread_known
)
if mode == "capture": if mode == "capture":
capture = _CaptureTransport() capture = _CaptureTransport()
exec_cfg = ExecBridgeConfig( exec_cfg = ExecBridgeConfig(
@@ -1519,7 +1526,7 @@ class _TelegramCommandExecutor(CommandExecutor):
resume_token=None, resume_token=None,
context=request.context, context=request.context,
reply_ref=self._reply_ref, reply_ref=self._reply_ref,
on_thread_known=None, on_thread_known=on_thread_known,
engine_override=engine, engine_override=engine,
thread_id=self._thread_id, thread_id=self._thread_id,
show_resume_line=effective_show_resume_line, show_resume_line=effective_show_resume_line,
@@ -1535,7 +1542,7 @@ class _TelegramCommandExecutor(CommandExecutor):
resume_token=None, resume_token=None,
context=request.context, context=request.context,
reply_ref=self._reply_ref, reply_ref=self._reply_ref,
on_thread_known=self._scheduler.note_thread_known, on_thread_known=on_thread_known,
engine_override=engine, engine_override=engine,
thread_id=self._thread_id, thread_id=self._thread_id,
show_resume_line=effective_show_resume_line, show_resume_line=effective_show_resume_line,
@@ -1572,6 +1579,7 @@ async def _dispatch_command(
args_text: str, args_text: str,
running_tasks: RunningTasks, running_tasks: RunningTasks,
scheduler: ThreadScheduler, scheduler: ThreadScheduler,
on_thread_known: Callable[[ResumeToken, anyio.Event], Awaitable[None]] | None,
stateful_mode: bool, stateful_mode: bool,
) -> None: ) -> None:
allowlist = cfg.runtime.allowlist allowlist = cfg.runtime.allowlist
@@ -1591,6 +1599,7 @@ async def _dispatch_command(
runtime=cfg.runtime, runtime=cfg.runtime,
running_tasks=running_tasks, running_tasks=running_tasks,
scheduler=scheduler, scheduler=scheduler,
on_thread_known=on_thread_known,
chat_id=chat_id, chat_id=chat_id,
user_msg_id=user_msg_id, user_msg_id=user_msg_id,
thread_id=msg.thread_id, thread_id=msg.thread_id,
+5
View File
@@ -858,6 +858,11 @@ async def run_main_loop(
args_text, args_text,
running_tasks, running_tasks,
scheduler, scheduler,
wrap_on_thread_known(
scheduler.note_thread_known,
topic_key,
chat_session_key,
),
stateful_mode, stateful_mode,
) )
continue continue
+113
View File
@@ -1761,6 +1761,119 @@ async def test_run_main_loop_prompt_upload_auto_resumes_chat_sessions(
) )
@pytest.mark.anyio
async def test_run_main_loop_command_updates_chat_session_resume(
tmp_path: Path,
monkeypatch,
) -> None:
class _Command:
id = "run_cmd"
description = "run command"
async def handle(self, ctx):
await ctx.executor.run_one(commands.RunRequest(prompt="hello"))
return commands.CommandResult(text="done")
entrypoints = [
FakeEntryPoint(
"run_cmd",
"takopi.commands.run_cmd:BACKEND",
plugins.COMMAND_GROUP,
loader=_Command,
)
]
install_entrypoints(monkeypatch, entrypoints)
resume_value = "resume-123"
state_path = tmp_path / "takopi.toml"
transport = _FakeTransport()
bot = _FakeBot()
runner = ScriptRunner(
[Return(answer="ok")],
engine=CODEX_ENGINE,
resume_value=resume_value,
)
exec_cfg = ExecBridgeConfig(
transport=transport,
presenter=MarkdownPresenter(),
final_notify=True,
)
runtime = TransportRuntime(
router=_make_router(runner),
projects=_empty_projects(),
config_path=state_path,
)
cfg = TelegramBridgeConfig(
bot=bot,
runtime=runtime,
chat_id=123,
startup_msg="",
exec_cfg=exec_cfg,
session_mode="chat",
show_resume_line=False,
)
async def poller(_cfg: TelegramBridgeConfig):
yield TelegramIncomingMessage(
transport="telegram",
chat_id=123,
message_id=1,
text="/run_cmd",
reply_to_message_id=None,
reply_to_text=None,
sender_id=123,
chat_type="private",
)
await run_main_loop(cfg, poller)
store = ChatSessionStore(resolve_sessions_path(state_path))
stored = await store.get_session_resume(123, None, CODEX_ENGINE)
assert stored == ResumeToken(engine=CODEX_ENGINE, value=resume_value)
transport2 = _FakeTransport()
runner2 = ScriptRunner([Return(answer="ok")], engine=CODEX_ENGINE)
exec_cfg2 = ExecBridgeConfig(
transport=transport2,
presenter=MarkdownPresenter(),
final_notify=True,
)
runtime2 = TransportRuntime(
router=_make_router(runner2),
projects=_empty_projects(),
config_path=state_path,
)
cfg2 = TelegramBridgeConfig(
bot=bot,
runtime=runtime2,
chat_id=123,
startup_msg="",
exec_cfg=exec_cfg2,
session_mode="chat",
show_resume_line=False,
)
async def poller2(_cfg: TelegramBridgeConfig):
yield TelegramIncomingMessage(
transport="telegram",
chat_id=123,
message_id=2,
text="followup",
reply_to_message_id=None,
reply_to_text=None,
sender_id=123,
chat_type="private",
)
await run_main_loop(cfg2, poller2)
assert runner2.calls[0][1] == ResumeToken(
engine=CODEX_ENGINE,
value=resume_value,
)
@pytest.mark.anyio @pytest.mark.anyio
async def test_run_main_loop_hides_resume_line_when_disabled( async def test_run_main_loop_hides_resume_line_when_disabled(
tmp_path: Path, tmp_path: Path,