Coverage for src/local_deep_research/web/warning_checks/hardware.py: 100%
29 statements
« prev ^ index » next coverage.py v7.15.1, created at 2026-07-19 23:35 +0000
« prev ^ index » next coverage.py v7.15.1, created at 2026-07-19 23:35 +0000
1"""Pure hardware/settings-based warning checks.
3These functions have zero dependencies on Flask or SQLAlchemy —
4they take primitive values and return warning dicts (or None).
5"""
7from typing import Optional
9LOCAL_PROVIDERS = frozenset({"ollama", "llamacpp", "lmstudio"})
12def check_high_context(
13 provider: str, local_context: int, dismissed: bool
14) -> Optional[dict]:
15 """Return a high_context warning dict if context exceeds 8192 for a local provider."""
16 if provider not in LOCAL_PROVIDERS:
17 return None
18 if local_context <= 8192:
19 return None
20 if dismissed:
21 return None
23 return {
24 "type": "high_context",
25 "icon": "⚠️",
26 "title": "High Context Warning",
27 "message": (
28 f"Context size ({local_context:,} tokens) requires sufficient VRAM. "
29 f"This is recommended for the langgraph-agent strategy. "
30 f"If you experience slowdowns, reduce context size in settings "
31 f"and switch to the source-based strategy instead. "
32 f"Tip: check the metrics page in each research history entry "
33 f"to monitor actual token usage and VRAM consumption."
34 ),
35 "dismissKey": "app.warnings.dismiss_high_context",
36 "actionUrl": "/metrics/context-overflow",
37 "actionLabel": "View context metrics",
38 }
41def check_model_mismatch(
42 provider: str, model: str, local_context: int, dismissed: bool
43) -> Optional[dict]:
44 """Return a model_mismatch warning dict for large models with high context."""
45 if not model:
46 return None
47 if provider not in LOCAL_PROVIDERS:
48 return None
49 if "70b" not in model.lower():
50 return None
51 if local_context <= 8192:
52 return None
53 if dismissed:
54 return None
56 return {
57 "type": "model_mismatch",
58 "icon": "🧠",
59 "title": "Model & Context Warning",
60 "message": (
61 f"Large model ({model}) with high context ({local_context:,}) "
62 f"may exceed VRAM. Consider reducing context size or upgrading "
63 f"GPU memory."
64 ),
65 "dismissKey": "app.warnings.dismiss_model_mismatch",
66 # Shares the high_context destination on purpose: this warning fires on
67 # large-model + high-context together, and the actionable lever is
68 # reducing context size. The "Token Usage & Context Analytics" page is
69 # where the user sees actual token/context usage to make that call —
70 # there is no separate GPU/VRAM analytics page.
71 "actionUrl": "/metrics/context-overflow",
72 "actionLabel": "View context metrics",
73 }
76def check_legacy_server_config(dismissed: bool) -> Optional[dict]:
77 """Return a warning only if server_config.json has non-default values."""
78 from ..server_config import has_legacy_customizations
80 if dismissed:
81 return None
82 if not has_legacy_customizations():
83 return None
84 return {
85 "type": "legacy_server_config",
86 "icon": "ℹ️",
87 "title": "server_config.json Detected",
88 "message": (
89 "A server_config.json file was found with non-default settings. "
90 "Environment variables are the preferred configuration method. "
91 "See the documentation for migration details."
92 ),
93 "dismissKey": "app.warnings.dismiss_legacy_config",
94 }