fix(legacy): silence ruff + mypy errors surfaced by litellm 1.83 bump

Three modules touched in Phase 0 surfaced latent issues:

  - llm/llm.py:_extract_thinking — choices[0].message can be None or a
    TextChoices variant without thinking_blocks under the new stubs.
    Narrow via getattr+Any; restructure return through the else block
    so try/except/else is ruff-clean (TRY300).
  - llm/__init__.py:litellm._logging._disable_debugging is now untyped;
    suppress with explicit type:ignore.
  - tools/notes/notes_actions.py:append_note_content — drop dead-code
    isinstance check (delta is typed str at the boundary), and cast the
    update_note return through a typed local in the try/else flow.

Plus per-file PLC0415 ignore for two modules whose lazy imports exist
to break the circular dependency on strix.telemetry. Pre-commit
auto-formatter strips inline #noqa comments, so the suppress lives in
pyproject.toml until the dep graph is refactored.

No behavior change. 165/165 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
0xallam
2026-04-24 23:50:20 -07:00
parent d9748a44db
commit 3652b449d1
4 changed files with 19 additions and 13 deletions
+4
View File
@@ -243,6 +243,10 @@ ignore = [
]
[tool.ruff.lint.per-file-ignores]
# Pre-existing lazy imports inside functions (avoid circular dependency
# with strix.telemetry). Keep until the dependency graph is refactored.
"strix/llm/llm.py" = ["PLC0415"]
"strix/tools/notes/notes_actions.py" = ["PLC0415"]
"tests/**/*.py" = [
"S106", # Possible hardcoded password
"S108", # Possible insecure usage of temporary file/directory
+1 -1
View File
@@ -13,7 +13,7 @@ __all__ = [
"LLMRequestFailedError",
]
litellm._logging._disable_debugging()
litellm._logging._disable_debugging() # type: ignore[no-untyped-call]
logging.getLogger("asyncio").setLevel(logging.CRITICAL)
logging.getLogger("asyncio").propagate = False
warnings.filterwarnings("ignore", category=RuntimeWarning, module="asyncio")
+7 -4
View File
@@ -275,14 +275,17 @@ class LLM:
def _extract_thinking(self, chunks: list[Any]) -> list[dict[str, Any]] | None:
if not chunks or not self._supports_reasoning():
return None
blocks: list[dict[str, Any]] | None = None
try:
resp = stream_chunk_builder(chunks)
if resp.choices and hasattr(resp.choices[0].message, "thinking_blocks"):
blocks: list[dict[str, Any]] = resp.choices[0].message.thinking_blocks
return blocks
choices: Any = getattr(resp, "choices", None)
if choices:
message: Any = getattr(choices[0], "message", None)
if message is not None and hasattr(message, "thinking_blocks"):
blocks = message.thinking_blocks
except Exception: # noqa: BLE001, S110 # nosec B110
pass
return None
return blocks
def _update_usage_stats(self, response: Any) -> None:
try:
+7 -8
View File
@@ -231,9 +231,7 @@ def _to_note_listing_entry(
entry["content"] = content
elif content:
if len(content) > _DEFAULT_CONTENT_PREVIEW_CHARS:
entry["content_preview"] = (
f"{content[:_DEFAULT_CONTENT_PREVIEW_CHARS].rstrip()}..."
)
entry["content_preview"] = f"{content[:_DEFAULT_CONTENT_PREVIEW_CHARS].rstrip()}..."
else:
entry["content_preview"] = content
@@ -375,16 +373,17 @@ def append_note_content(note_id: str, delta: str) -> dict[str, Any]:
if note_id not in _notes_storage:
return {"success": False, "error": f"Note with ID '{note_id}' not found"}
if not isinstance(delta, str):
return {"success": False, "error": "Delta must be a string"}
note = _notes_storage[note_id]
existing_content = str(note.get("content") or "")
updated_content = f"{existing_content.rstrip()}{delta}"
return update_note(note_id=note_id, content=updated_content)
result: dict[str, Any] = update_note(
note_id=note_id,
content=updated_content,
)
except (ValueError, TypeError) as e:
return {"success": False, "error": f"Failed to append note content: {e}"}
else:
return result
@register_tool(sandbox_execution=False)