mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(cli): handle unquoted multi-word session names in -c/--continue and -r/--resume
When a user runs `hermes -w -c Pokemon Agent Dev` without quoting the session name, argparse would fail with: error: argument command: invalid choice: 'Agent' This is because argparse parses `-c Pokemon` (consuming one token via nargs='?'), then sees 'Agent' and tries to match it as a subcommand. Fix: add _coalesce_session_name_args() that pre-processes sys.argv before argparse, joining consecutive non-flag, non-subcommand tokens after -c or -r into a single argument. This makes both quoted and unquoted multi-word session names work transparently. Includes 17 tests covering all edge cases: multi-word names, single-word, bare flags, flag ordering, subcommand boundaries, and passthrough.
This commit is contained in:
parent
3e352f8a0d
commit
0a628c1aef
2 changed files with 158 additions and 3 deletions
|
|
@ -1777,6 +1777,44 @@ def cmd_update(args):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
def _coalesce_session_name_args(argv: list) -> list:
|
||||
"""Join unquoted multi-word session names after -c/--continue and -r/--resume.
|
||||
|
||||
When a user types ``hermes -c Pokemon Agent Dev`` without quoting the
|
||||
session name, argparse sees three separate tokens. This function merges
|
||||
them into a single argument so argparse receives
|
||||
``['-c', 'Pokemon Agent Dev']`` instead.
|
||||
|
||||
Tokens are collected after the flag until we hit another flag (``-*``)
|
||||
or a known top-level subcommand.
|
||||
"""
|
||||
_SUBCOMMANDS = {
|
||||
"chat", "model", "gateway", "setup", "whatsapp", "login", "logout",
|
||||
"status", "cron", "doctor", "config", "pairing", "skills", "tools",
|
||||
"sessions", "insights", "version", "update", "uninstall",
|
||||
}
|
||||
_SESSION_FLAGS = {"-c", "--continue", "-r", "--resume"}
|
||||
|
||||
result = []
|
||||
i = 0
|
||||
while i < len(argv):
|
||||
token = argv[i]
|
||||
if token in _SESSION_FLAGS:
|
||||
result.append(token)
|
||||
i += 1
|
||||
# Collect subsequent non-flag, non-subcommand tokens as one name
|
||||
parts: list = []
|
||||
while i < len(argv) and not argv[i].startswith("-") and argv[i] not in _SUBCOMMANDS:
|
||||
parts.append(argv[i])
|
||||
i += 1
|
||||
if parts:
|
||||
result.append(" ".join(parts))
|
||||
else:
|
||||
result.append(token)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
"""Main entry point for hermes CLI."""
|
||||
parser = argparse.ArgumentParser(
|
||||
|
|
@ -2356,12 +2394,12 @@ For more help on a command:
|
|||
if not data:
|
||||
print(f"Session '{args.session_id}' not found.")
|
||||
return
|
||||
with open(args.output, "w") as f:
|
||||
with open(args.output, "w", encoding="utf-8") as f:
|
||||
f.write(_json.dumps(data, ensure_ascii=False) + "\n")
|
||||
print(f"Exported 1 session to {args.output}")
|
||||
else:
|
||||
sessions = db.export_all(source=args.source)
|
||||
with open(args.output, "w") as f:
|
||||
with open(args.output, "w", encoding="utf-8") as f:
|
||||
for s in sessions:
|
||||
f.write(_json.dumps(s, ensure_ascii=False) + "\n")
|
||||
print(f"Exported {len(sessions)} sessions to {args.output}")
|
||||
|
|
@ -2515,7 +2553,11 @@ For more help on a command:
|
|||
# =========================================================================
|
||||
# Parse and execute
|
||||
# =========================================================================
|
||||
args = parser.parse_args()
|
||||
# Pre-process argv so unquoted multi-word session names after -c / -r
|
||||
# are merged into a single token before argparse sees them.
|
||||
# e.g. ``hermes -c Pokemon Agent Dev`` → ``hermes -c 'Pokemon Agent Dev'``
|
||||
_processed_argv = _coalesce_session_name_args(sys.argv[1:])
|
||||
args = parser.parse_args(_processed_argv)
|
||||
|
||||
# Handle --version flag
|
||||
if args.version:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue