fix(review): apply PR #3774 review fixes

- Clear pending_user_turn after shortcut command persistence
- Guard is_allowed against None allow_from values
- Update pairing help text for two-arg revoke
- Reuse format_expiry in CLI pairing list
This commit is contained in:
chengyongru 2026-05-14 17:54:45 +08:00
parent 31746c6598
commit a729b9e87e
4 changed files with 10 additions and 9 deletions

View File

@ -1283,6 +1283,7 @@ class AgentLoop:
"assistant", result.content, _command=True "assistant", result.content, _command=True
) )
self.sessions.save(ctx.session) self.sessions.save(ctx.session)
self._clear_pending_user_turn(ctx.session)
return "shortcut" return "shortcut"
return "dispatch" return "dispatch"

View File

@ -195,11 +195,11 @@ class BaseChannel(ABC):
""" """
if isinstance(self.config, dict): if isinstance(self.config, dict):
if "allow_from" in self.config: if "allow_from" in self.config:
allow_list = self.config.get("allow_from") allow_list = self.config.get("allow_from") or []
else: else:
allow_list = self.config.get("allowFrom", []) allow_list = self.config.get("allowFrom", []) or []
else: else:
allow_list = getattr(self.config, "allow_from", []) allow_list = getattr(self.config, "allow_from", []) or []
if "*" in allow_list: if "*" in allow_list:
return True return True
if str(sender_id) in allow_list: if str(sender_id) in allow_list:

View File

@ -1631,7 +1631,7 @@ app.add_typer(pairing_app, name="pairing")
@pairing_app.command("list") @pairing_app.command("list")
def pairing_list(): def pairing_list():
"""Show pending pairing requests.""" """Show pending pairing requests."""
from nanobot.pairing import list_pending from nanobot.pairing import format_expiry, list_pending
pending = list_pending() pending = list_pending()
if not pending: if not pending:
@ -1644,11 +1644,8 @@ def pairing_list():
table.add_column("Sender ID", style="yellow") table.add_column("Sender ID", style="yellow")
table.add_column("Expires", style="green") table.add_column("Expires", style="green")
import time
for item in pending: for item in pending:
remaining = int(item.get("expires_at", 0) - time.time()) expiry = format_expiry(item.get("expires_at", 0))
expiry = f"{remaining}s" if remaining > 0 else "expired"
table.add_row( table.add_row(
item["code"], item["code"],
item["channel"], item["channel"],

View File

@ -20,6 +20,9 @@ from loguru import logger
from nanobot.config.paths import get_data_dir from nanobot.config.paths import get_data_dir
from nanobot.utils.helpers import _write_text_atomic from nanobot.utils.helpers import _write_text_atomic
# threading.Lock is used so store functions remain callable from both sync CLI
# and async channel handlers. At private-assistant scale (small JSON file,
# sub-millisecond operations) the brief block is acceptable.
_LOCK = threading.Lock() _LOCK = threading.Lock()
_ALPHABET = string.ascii_uppercase + string.digits _ALPHABET = string.ascii_uppercase + string.digits
_CODE_LENGTH = 8 # e.g. ABCD-EFGH _CODE_LENGTH = 8 # e.g. ABCD-EFGH
@ -251,5 +254,5 @@ def handle_pairing_command(channel: str, subcommand_text: str) -> str:
return ( return (
"Unknown pairing command.\n" "Unknown pairing command.\n"
"Usage: `/pairing [list|approve <code>|deny <code>|revoke <user_id>]`" "Usage: `/pairing [list|approve <code>|deny <code>|revoke <user_id>|revoke <channel> <user_id>]`"
) )