some organization pass, still need to review a bunch

This commit is contained in:
ed
2026-06-06 00:21:36 -04:00
parent f8b0a1243d
commit 053f5d867a
18 changed files with 658 additions and 706 deletions
+1 -1
View File
@@ -4170,7 +4170,7 @@ def render_operations_hub(app: App) -> None:
with imscope.tab_item("Vendor State") as (exp, _):
if exp: render_vendor_state(app)
def render_vendor_state(app: App) -> None:
def render_vendor_state(app: App) -> None: # TODO(Ed): Shouldn't this just be a part of usage analytics? We can show all used vendors at once...
"""Render the Operations Hub > Vendor State panel.
[C: src/vendor_state.py:get_vendor_state]
"""
-2
View File
@@ -35,7 +35,6 @@ def parse_ts(s: str) -> Optional[datetime.datetime]:
def entry_to_str(entry: dict[str, Any]) -> str:
"""
Serialise a disc entry dict -> stored string.
[C: tests/test_thinking_persistence.py:test_entry_to_str_with_thinking]
"""
@@ -62,7 +61,6 @@ def format_discussion(entries: list[dict[str, Any]]) -> str:
def str_to_entry(raw: str, roles: list[str]) -> dict[str, Any]:
"""
Parse a stored string back to a disc entry dict.
[C: tests/test_thinking_persistence.py:test_str_to_entry_with_thinking]
"""
+17 -19
View File
@@ -6,9 +6,13 @@ import sys
from typing import List, Dict, Any, Optional
from src import ai_client
from src import models
from src import mcp_client
from src.file_cache import ASTParser
_SENTENCE_TRANSFORMERS = None
_GOOGLE_GENAI = None
_CHROMADB = None
@@ -74,15 +78,14 @@ class GeminiEmbeddingProvider(BaseEmbeddingProvider):
if google_module is None:
raise ImportError("google-genai is not installed")
genai_pkg, types = google_module
from src import ai_client
ai_client._ensure_gemini_client()
client = ai_client._gemini_client
if not client:
raise ValueError("Gemini client not initialized")
res = client.models.embed_content(
model=self.model_name,
contents=texts,
config=types.EmbedContentConfig(task_type="RETRIEVAL_DOCUMENT")
model = self.model_name,
contents = texts,
config = types.EmbedContentConfig(task_type="RETRIEVAL_DOCUMENT")
)
return [e.values for e in res.embeddings]
@@ -94,8 +97,7 @@ class RAGEngine:
self.collection = None
self.embedding_provider = None
if not self.config.enabled:
return
if not self.config.enabled: return
self._init_embedding_provider()
self._init_vector_store()
@@ -143,10 +145,10 @@ class RAGEngine:
return
embeddings = self.embedding_provider.embed(texts)
self.collection.upsert(
ids=ids,
embeddings=embeddings,
documents=texts,
metadatas=metadatas
ids = ids,
embeddings = embeddings,
documents = texts,
metadatas = metadatas
)
def _chunk_text(self, content: str) -> List[str]:
@@ -168,7 +170,6 @@ class RAGEngine:
def _chunk_code(self, content: str, file_path: str) -> List[str]:
"""AST-aware chunking for Python code."""
try:
from src.file_cache import ASTParser
parser = ASTParser("python")
tree = parser.parse(content)
chunks = []
@@ -246,17 +247,14 @@ class RAGEngine:
"""
[C: tests/mock_concurrent_mma.py:main, tests/test_rag_engine.py:test_rag_engine_chroma]
"""
if not self.config.enabled:
return []
if self.config.vector_store.provider == 'mcp':
return self._search_mcp(query, top_k)
if self.collection == "mock":
return []
if not self.config.enabled: return []
if self.config.vector_store.provider == 'mcp': return self._search_mcp(query, top_k)
if self.collection == "mock": return []
query_embedding = self.embedding_provider.embed([query])[0]
results = self.collection.query(
query_embeddings=[query_embedding],
n_results=top_k
query_embeddings = [query_embedding],
n_results = top_k
)
ret = []
-1
View File
@@ -90,7 +90,6 @@ def open_session(label: Optional[str] = None) -> None:
def close_session() -> None:
"""
Flush and close all log files. Called on clean exit.
[C: tests/test_app_controller_offloading.py:tmp_session_dir, tests/test_logging_e2e.py:e2e_setup, tests/test_logging_e2e.py:test_logging_e2e, tests/test_session_logger_optimization.py:temp_session_setup, tests/test_session_logger_reset.py:temp_logs, tests/test_session_logging.py:temp_logs]
"""
+1 -4
View File
@@ -8,8 +8,7 @@ def draw_soft_shadow(draw_list: imgui.ImDrawList, p_min: imgui.ImVec2, p_max: im
"""
r, g, b, a = color.x, color.y, color.z, color.w
steps = int(shadow_size)
if steps <= 0:
return
if steps <= 0: return
alpha_step = a / steps
@@ -17,12 +16,10 @@ def draw_soft_shadow(draw_list: imgui.ImDrawList, p_min: imgui.ImVec2, p_max: im
current_alpha = a - (i * alpha_step)
# Apply an easing function (e.g., cubic) for a smoother shadow falloff
current_alpha = current_alpha * (1.0 - (i / steps)**2)
if current_alpha <= 0.01:
continue
expand = float(i)
c_min = imgui.ImVec2(p_min.x - expand, p_min.y - expand)
c_max = imgui.ImVec2(p_max.x + expand, p_max.y + expand)
+3 -3
View File
@@ -70,9 +70,9 @@ def run_powershell(script: str, base_dir: str, qa_callback: Optional[Callable[[s
try:
process = subprocess.Popen(
[exe, "-NoProfile", "-NonInteractive", "-Command", full_script],
stdin=subprocess.DEVNULL,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True,
cwd=base_dir, env=_build_subprocess_env(),
stdin = subprocess.DEVNULL,
stdout = subprocess.PIPE, stderr=subprocess.PIPE, text=True,
cwd = base_dir, env=_build_subprocess_env(),
)
stdout, stderr = process.communicate(timeout=TIMEOUT_SECONDS)
parts: list[str] = []
+6 -22
View File
@@ -1,16 +1,5 @@
# summarize.py
"""
Note(Gemini):
Local heuristic summariser. Doesn't use any AI or network.
Uses Python's AST to reliably pull out classes, methods, and functions.
Regex is used for TOML and Markdown.
The rationale here is simple: giving the AI the *structure* of a codebase is 90%
as good as giving it the full source, but costs 1% of the tokens.
If it needs the full source of a file after reading the summary, it can just call read_file.
"""
# summarize.py
"""
Local symbolic summariser — no AI calls, no network.
For each file, extracts structural information:
@@ -28,6 +17,8 @@ import re
from pathlib import Path
from typing import Callable, Any
from src import ai_client
from src.summary_cache import SummaryCache, get_file_hash
@@ -73,16 +64,13 @@ def _summarise_python(path: Path, content: str) -> str:
n.name for n in ast.iter_child_nodes(node)
if isinstance(n, (ast.FunctionDef, ast.AsyncFunctionDef))
]
if methods:
parts.append(f"class {node.name}: {', '.join(methods)}")
else:
parts.append(f"class {node.name}")
if methods: parts.append(f"class {node.name}: {', '.join(methods)}")
else: parts.append(f"class {node.name}")
top_fns = [
node.name for node in ast.iter_child_nodes(tree)
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef))
]
if top_fns:
parts.append(f"functions: {', '.join(top_fns)}")
if top_fns: parts.append(f"functions: {', '.join(top_fns)}")
return "\n".join(parts)
def _summarise_toml(path: Path, content: str) -> str:
@@ -168,16 +156,13 @@ _SUMMARISERS: dict[str, Callable[[Path, str], str]] = {
def summarise_file(path: Path, content: str) -> str:
"""
Return a compact markdown summary string for a single file.
`content` is the already-read file text (or an error string).
[C: tests/test_subagent_summarization.py:test_summarise_file_integration]
"""
content_hash = get_file_hash(content)
cached = _summary_cache.get_summary(str(path), content_hash)
if cached:
return cached
if cached: return cached
suffix = path.suffix.lower() if hasattr(path, "suffix") else ""
fn = _SUMMARISERS.get(suffix, _summarise_generic)
try:
@@ -185,7 +170,6 @@ def summarise_file(path: Path, content: str) -> str:
# Smart AI Summarization
is_code = suffix in [".py", ".ps1", ".js", ".ts", ".cpp", ".c", ".h", ".cs", ".go", ".rs", ".lua"]
try:
from src import ai_client
smart_summary = ai_client.run_subagent_summarization(
file_path=str(path),
content=content[:10000],
-7
View File
@@ -7,7 +7,6 @@ from typing import Optional, Dict
def get_file_hash(content: str) -> str:
"""
Returns SHA256 hash of the content.
[C: tests/test_summary_cache.py:test_get_file_hash, tests/test_summary_cache.py:test_summary_cache]
"""
@@ -15,8 +14,6 @@ def get_file_hash(content: str) -> str:
class SummaryCache:
"""
A hash-based cache for file summaries to avoid redundant processing.
Invalidates when content hash changes.
"""
@@ -32,7 +29,6 @@ class SummaryCache:
def load(self) -> None:
"""
Loads cache from disk.
[C: src/tool_presets.py:ToolPresetManager._read_raw, src/workspace_manager.py:WorkspaceManager._load_file, tests/test_gui_phase3.py:test_create_track, tests/test_history_management.py:test_save_separation, tests/test_session_logging.py:test_open_session_creates_subdir_and_registry]
"""
@@ -54,7 +50,6 @@ class SummaryCache:
def get_summary(self, file_path: str, content_hash: str) -> Optional[str]:
"""
Returns cached summary if hash matches, otherwise None.
[C: tests/test_summary_cache.py:test_summary_cache, tests/test_summary_cache.py:test_summary_cache_lru]
"""
@@ -68,7 +63,6 @@ class SummaryCache:
def set_summary(self, file_path: str, content_hash: str, summary: str) -> None:
"""
Stores summary in cache and saves to disk.
[C: tests/test_summary_cache.py:test_summary_cache, tests/test_summary_cache.py:test_summary_cache_lru]
"""
@@ -87,7 +81,6 @@ class SummaryCache:
def clear(self) -> None:
"""
Clears the cache both in-memory and on disk.
[C: tests/conftest.py:reset_ai_client]
"""
+1 -2
View File
@@ -14,7 +14,7 @@ from contextlib import nullcontext
from imgui_bundle import imgui, hello_imgui
from typing import Any, Optional
import src.theme_nerv
from src import theme_nerv
from src import imgui_scopes as imscope
from src.theme_nerv import DATA_GREEN
@@ -213,7 +213,6 @@ def apply(palette_name: str) -> None:
global _current_palette
_current_palette = palette_name
if palette_name == 'NERV':
from src import theme_nerv
theme_nerv.apply_nerv()
apply_syntax_palette(get_syntax_palette_for_theme(palette_name))
return
+18 -18
View File
@@ -124,12 +124,12 @@ class ThemeFile:
def with_scope(self, scope: str) -> ThemeFile:
return ThemeFile(
name=self.name,
palette=self.palette,
syntax_palette=self.syntax_palette,
source_path=self.source_path,
scope=scope,
description=self.description,
name = self.name,
palette = self.palette,
syntax_palette = self.syntax_palette,
source_path = self.source_path,
scope = scope,
description = self.description,
)
def to_dict(self) -> dict[str, Any]:
@@ -152,12 +152,12 @@ class ThemeFile:
f"must be one of {VALID_SYNTAX_PALETTES}"
)
return cls(
name=name,
palette=ThemePalette.from_dict(data["colors"]),
syntax_palette=syntax_palette,
source_path=source_path,
scope=scope,
description=str(data.get("description", "")),
name = name,
palette = ThemePalette.from_dict(data["colors"]),
syntax_palette = syntax_palette,
source_path = source_path,
scope = scope,
description = str(data.get("description", "")),
)
@@ -204,14 +204,14 @@ def load_themes_from_toml(path: Path, scope: str) -> dict[str, ThemeFile]:
except Exception as e:
print(f"warning: failed to parse {path}: {e}", file=sys.stderr)
return out
if not isinstance(data, dict):
return out
if not isinstance(data, dict): return out
themes_sec = data.get("themes", {})
if not isinstance(themes_sec, dict):
return out
if not isinstance(themes_sec, dict): return out
for name, theme_data in themes_sec.items():
if not isinstance(theme_data, dict):
continue
if not isinstance(theme_data, dict): continue
try:
theme = ThemeFile.from_dict(name, theme_data, source_path=path, scope=scope)
except ValueError as e:
-1
View File
@@ -64,7 +64,6 @@ NERV_PALETTE = {
def apply_nerv() -> None:
"""
Apply NERV theme with hard edges and specific palette.
[C: tests/test_theme_nerv.py:test_apply_nerv_sets_rounding_and_colors]
"""
+1 -3
View File
@@ -13,8 +13,7 @@ class CRTFilter:
"""
[C: tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
"""
if not self.enabled:
return
if not self.enabled: return
draw_list = imgui.get_foreground_draw_list()
# 1. Enhanced Scanlines (Horizontal)
@@ -40,7 +39,6 @@ class CRTFilter:
# Exponential alpha for smoother falloff
alpha = (i / v_steps) ** 3.0 * 0.25
v_color = imgui.get_color_u32((0.0, 0.0, 0.0, alpha))
# Inset and rounding grow to simulate tube curvature
inset = (v_steps - i) * 4.5
rounding = 60.0 + (v_steps - i) * 8.0
+1 -6
View File
@@ -7,8 +7,6 @@ from src.models import ThinkingSegment
def parse_thinking_trace(text: str) -> Tuple[List[ThinkingSegment], str]:
"""
Parses thinking segments from text and returns (segments, response_content).
Support extraction of thinking traces from <thinking>...</thinking>, <thought>...</thought>,
and blocks prefixed with Thinking:.
@@ -18,7 +16,6 @@ def parse_thinking_trace(text: str) -> Tuple[List[ThinkingSegment], str]:
# 1. Extract <thinking> and <thought> tags
current_text = text
# Combined pattern for tags
tag_pattern = re.compile(r'<(thinking|thought)>(.*?)</\1>', re.DOTALL | re.IGNORECASE)
@@ -46,8 +43,7 @@ def parse_thinking_trace(text: str) -> Tuple[List[ThinkingSegment], str]:
def replace_func(match):
content = match.group(1).strip()
if content:
found_segments.append(ThinkingSegment(content=content, marker="Thinking:"))
if content: found_segments.append(ThinkingSegment(content=content, marker="Thinking:"))
return "\n\n"
res = thinking_colon_pattern.sub(replace_func, txt)
@@ -55,5 +51,4 @@ def parse_thinking_trace(text: str) -> Tuple[List[ThinkingSegment], str]:
colon_segments, final_remaining = extract_colon_blocks(remaining)
segments.extend(colon_segments)
return segments, final_remaining.strip()
+6 -12
View File
@@ -51,19 +51,13 @@ class ToolBiasEngine:
for cat_tools in preset.categories.values():
for t in cat_tools:
if not isinstance(t, Tool): continue
if t.weight >= 5:
preferred.append(f"{t.name} [HIGH PRIORITY]")
elif t.weight == 4:
preferred.append(f"{t.name} [PREFERRED]")
elif t.weight == 2:
low_priority.append(f"{t.name} [NOT RECOMMENDED]")
elif t.weight <= 1:
low_priority.append(f"{t.name} [LOW PRIORITY]")
if t.weight >= 5: preferred.append(f"{t.name} [HIGH PRIORITY]")
elif t.weight == 4: preferred.append(f"{t.name} [PREFERRED]")
elif t.weight == 2: low_priority.append(f"{t.name} [NOT RECOMMENDED]")
elif t.weight <= 1: low_priority.append(f"{t.name} [LOW PRIORITY]")
if preferred:
lines.append(f"Preferred tools: {', '.join(preferred)}.")
if low_priority:
lines.append(f"Low-priority tools: {', '.join(low_priority)}.")
if preferred: lines.append(f"Preferred tools: {', '.join(preferred)}.")
if low_priority: lines.append(f"Low-priority tools: {', '.join(low_priority)}.")
if global_bias.category_multipliers:
lines.append("Category focus multipliers:")
-1
View File
@@ -62,7 +62,6 @@ class ToolPresetManager:
def load_all(self) -> Dict[str, ToolPreset]:
"""
Backward compatibility for load_all().
[C: tests/test_persona_manager.py:test_delete_persona, tests/test_persona_manager.py:test_load_all_merged, tests/test_persona_manager.py:test_save_persona, tests/test_preset_manager.py:test_delete_preset, tests/test_preset_manager.py:test_load_all_merged, tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project]
"""
+28 -28
View File
@@ -18,11 +18,11 @@ def get_vendor_state(app) -> list[VendorMetric]:
"""
out: list[VendorMetric] = []
out.append(VendorMetric(
key="provider_model",
label="Provider / Model",
value=f"{app.current_provider} / {app.current_model}",
state="info",
tooltip="The vendor and model that will handle the next request."
key = "provider_model",
label = "Provider / Model",
value = f"{app.current_provider} / {app.current_model}",
state = "info",
tooltip = "The vendor and model that will handle the next request."
))
ctrl = getattr(app, "controller", None)
tt = getattr(ctrl, "token_tracker", None) if ctrl else None
@@ -30,16 +30,16 @@ def get_vendor_state(app) -> list[VendorMetric]:
pct = 100.0 * getattr(tt, "used", 0) / tt.limit
state = "warn" if pct > 75 else "ok"
out.append(VendorMetric(
key="context_window",
label="Context Window",
value=f"{tt.used:,} / {tt.limit:,} ({pct:.0f}%)",
state=state,
tooltip="Used vs total context window for the current session."
key = "context_window",
label = "Context Window",
value = f"{tt.used:,} / {tt.limit:,} ({pct:.0f}%)",
state = state,
tooltip = "Used vs total context window for the current session."
))
else:
out.append(VendorMetric(
key="context_window", label="Context Window", value="", state="info",
tooltip="No token tracker attached for the current provider."
key = "context_window", label="Context Window", value="", state="info",
tooltip = "No token tracker attached for the current provider."
))
if tt is not None:
hits = getattr(tt, "cache_hits", 0)
@@ -47,35 +47,35 @@ def get_vendor_state(app) -> list[VendorMetric]:
total = hits + miss
rate = (100.0 * hits / total) if total else 0.0
out.append(VendorMetric(
key="cache", label="Cache Hit Rate",
value=f"{rate:.0f}% ({hits:,}/{total:,})",
state="ok" if rate > 50 else "info",
tooltip="Server-side prompt cache hit rate for the current session."
key = "cache", label="Cache Hit Rate",
value = f"{rate:.0f}% ({hits:,}/{total:,})",
state = "ok" if rate > 50 else "info",
tooltip = "Server-side prompt cache hit rate for the current session."
))
else:
out.append(VendorMetric(
key="cache", label="Cache Hit Rate", value="", state="info",
tooltip="No token tracker attached for the current provider."
key = "cache", label="Cache Hit Rate", value="", state="info",
tooltip = "No token tracker attached for the current provider."
))
quota = (getattr(ctrl, "vendor_quota", {}) or {}) if ctrl else {}
pct_left = quota.get("remaining_pct")
if pct_left is None:
out.append(VendorMetric(
key="quota", label="Vendor Quota", value="", state="info",
tooltip="Vendor did not report quota for the current billing period."
key = "quota", label="Vendor Quota", value="", state="info",
tooltip = "Vendor did not report quota for the current billing period."
))
else:
out.append(VendorMetric(
key="quota", label="Vendor Quota",
value=f"{pct_left}% remaining",
state="ok" if pct_left > 25 else "warn",
tooltip="Approximate quota remaining for the current billing period."
key = "quota", label="Vendor Quota",
value = f"{pct_left}% remaining",
state = "ok" if pct_left > 25 else "warn",
tooltip = "Approximate quota remaining for the current billing period."
))
err = getattr(ctrl, "last_error", None) if ctrl else None
out.append(VendorMetric(
key="last_error", label="Last Error",
value=err.get("class", "none") if err else "none",
state="error" if err else "ok",
tooltip=err.get("message", "No error since session start.") if err else "No error since session start."
key = "last_error", label="Last Error",
value = err.get("class", "none") if err else "none",
state = "error" if err else "ok",
tooltip = err.get("message", "No error since session start.") if err else "No error since session start."
))
return out
-1
View File
@@ -29,7 +29,6 @@ class WorkspaceManager:
def load_all_profiles(self) -> Dict[str, WorkspaceProfile]:
"""
Merges global and project profiles into a single dictionary.
[C: tests/test_workspace_manager.py:test_delete_profile, tests/test_workspace_manager.py:test_load_all_profiles_merged, tests/test_workspace_manager.py:test_save_profile_global_and_project]
"""