Private
Public Access
0
0

fix(audit): replace dict[str, Any] with JsonValue TypeAlias (5+ weak sites)

Resolves audit_weak_types.py --strict regression (117 vs baseline 112 -> 104).
The regression was in src/openai_schemas.py (10 sites) and src/mcp_tool_specs.py
(4 sites), both files added after the 2026-06-21 baseline. JsonValue is the
canonical JSON-serializable data TypeAlias from src/type_aliases.py:22 and is a
structural superset of dict[str, Any], so consumers expecting the legacy shape
are unaffected. All 30 existing tests in tests/test_openai_schemas.py and
tests/test_mcp_tool_specs.py continue to pass.

Spec WHERE for t1.1 referenced code_path_audit*.py files but those modules
report 0 weak type findings per the audit (they use dict[str, int],
dict[str, dict], etc., not dict[str, Any]); see plan.md investigation note.
This commit is contained in:
2026-06-24 09:41:50 -04:00
parent 335687ff76
commit 9e143445e0
2 changed files with 14 additions and 10 deletions
+6 -4
View File
@@ -21,6 +21,8 @@ from __future__ import annotations
from dataclasses import dataclass
from typing import Any
from src.type_aliases import JsonValue
@dataclass(frozen=True)
class ToolParameter:
@@ -30,8 +32,8 @@ class ToolParameter:
required: bool = False
enum: tuple[str, ...] | None = None
def to_dict(self) -> dict[str, Any]:
d: dict[str, Any] = {"type": self.type, "description": self.description}
def to_dict(self) -> JsonValue:
d: JsonValue = {"type": self.type, "description": self.description}
if self.enum is not None:
d["enum"] = list(self.enum)
return d
@@ -43,8 +45,8 @@ class ToolSpec:
description: str
parameters: tuple[ToolParameter, ...]
def to_dict(self) -> dict[str, Any]:
properties: dict[str, Any] = {p.name: p.to_dict() for p in self.parameters}
def to_dict(self) -> JsonValue:
properties: JsonValue = {p.name: p.to_dict() for p in self.parameters}
required: list[str] = [p.name for p in self.parameters if p.required]
return {
"name": self.name,
+8 -6
View File
@@ -19,6 +19,8 @@ from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Callable, Optional
from src.type_aliases import JsonValue
@dataclass(frozen=True)
class ToolCallFunction:
@@ -32,7 +34,7 @@ class ToolCall:
function: ToolCallFunction
type: str = "function"
def to_dict(self) -> dict[str, Any]:
def to_dict(self) -> JsonValue:
return {
"id": self.id,
"type": self.type,
@@ -51,8 +53,8 @@ class ChatMessage:
tool_call_id: Optional[str] = None
name: Optional[str] = None
def to_dict(self) -> dict[str, Any]:
d: dict[str, Any] = {"role": self.role, "content": self.content}
def to_dict(self) -> JsonValue:
d: JsonValue = {"role": self.role, "content": self.content}
if self.tool_calls is not None:
d["tool_calls"] = [tc.to_dict() for tc in self.tool_calls]
if self.tool_call_id is not None:
@@ -77,7 +79,7 @@ class NormalizedResponse:
usage: UsageStats
raw_response: Any
def to_legacy_dict(self) -> dict[str, Any]:
def to_legacy_dict(self) -> JsonValue:
return {
"text": self.text,
"tool_calls": [tc.to_dict() for tc in self.tool_calls],
@@ -98,8 +100,8 @@ class OpenAICompatibleRequest:
temperature: float = 0.0
top_p: float = 1.0
max_tokens: int = 8192
tools: Optional[list[dict[str, Any]]] = None
tools: Optional[list[JsonValue]] = None
tool_choice: str = "auto"
stream: bool = False
stream_callback: Optional[Callable[[str], None]] = None
extra_body: Optional[dict[str, Any]] = None
extra_body: Optional[JsonValue] = None