fix: resolve not-subscriptable ty diagnostics across codebase

Add TypedDicts for DEFAULT_CONFIG, CLI state dicts (_ModelPickerState,
_ApprovalState, _ClarifyState), and OPTIONAL_ENV_VARS so ty can resolve
nested dict subscripts.  Guard Optional returns before subscripting
(toolsets, cron/scheduler, delegate_tool), coerce str|None to str before
slicing (gateway/run, run_agent), split ternary for isinstance narrowing
(wecom), and suppress discord interaction.data access with ty: ignore.
This commit is contained in:
alt-glitch 2026-04-21 16:59:13 +05:30
parent 72e7c0ce34
commit fb6d37495b
9 changed files with 405 additions and 25 deletions

36
cli.py
View file

@ -28,7 +28,7 @@ import textwrap
from contextlib import contextmanager
from pathlib import Path
from datetime import datetime
from typing import List, Dict, Any, Optional
from typing import List, Dict, Any, Optional, TypedDict
logger = logging.getLogger(__name__)
@ -81,6 +81,34 @@ _project_env = Path(__file__).parent / '.env'
load_hermes_dotenv(hermes_home=_hermes_home, project_env=_project_env)
class _ModelPickerState(TypedDict, total=False):
stage: str
providers: List[Dict[str, Any]]
selected: int
current_model: str
current_provider: str
user_provs: Optional[Dict[str, Any]]
custom_provs: Optional[Dict[str, Any]]
provider_data: Dict[str, Any]
model_list: List[str]
class _ApprovalState(TypedDict, total=False):
command: str
description: str
choices: List[str]
selected: int
response_queue: "queue.Queue[str]"
show_full: bool
class _ClarifyState(TypedDict, total=False):
question: str
choices: List[str]
selected: int
response_queue: "queue.Queue[str]"
_REASONING_TAGS = (
"REASONING_SCRATCHPAD",
"think",
@ -1956,16 +1984,16 @@ class HermesCLI:
self._interrupt_queue = queue.Queue()
self._should_exit = False
self._last_ctrl_c_time = 0
self._clarify_state = None
self._clarify_state: Optional[_ClarifyState] = None
self._clarify_freetext = False
self._clarify_deadline = 0
self._sudo_state = None
self._sudo_deadline = 0
self._modal_input_snapshot = None
self._approval_state = None
self._approval_state: Optional[_ApprovalState] = None
self._approval_deadline = 0
self._approval_lock = threading.Lock()
self._model_picker_state = None
self._model_picker_state: Optional[_ModelPickerState] = None
self._secret_state = None
self._secret_deadline = 0
self._spinner_text: str = "" # thinking spinner text for TUI