diff --git a/.slop_cache/summary_cache.json b/.slop_cache/summary_cache.json index 953de1f..7bd2cea 100644 --- a/.slop_cache/summary_cache.json +++ b/.slop_cache/summary_cache.json @@ -94,5 +94,13 @@ "C:\\Users\\Ed\\AppData\\Local\\Temp\\pytest-of-Ed\\pytest-847\\test_force_full0\\other.txt": { "hash": "04d61c0832f9cbc2a210334352425d2519890a0a5945da96ccc5bd9ff101c4d3", "summary": "This document is a plain text file containing ten lines of content, with the first eight lines previewed. Its purpose appears to be simply to hold and present this sequential text.\n\n**Outline:**\n**TXT** \u2014 10 lines\npreview:\n```\nline1\nline2\nline3\nline4\nline5\nline6\nline7\nline8\n```" + }, + "C:\\Users\\Ed\\AppData\\Local\\Temp\\pytest-of-Ed\\pytest-848\\test_auto_aggregate_skip0\\file1.txt": { + "hash": "d0b425e00e15a0d36b9b361f02bab63563aed6cb4665083905386c55d5b679fa", + "summary": "This document contains a single line of text, \"content1\". Its purpose and key takeaways are limited to this singular piece of content.\n\n**Outline:**\n**TXT** \u2014 1 lines\npreview:\n```\ncontent1\n```" + }, + "C:\\Users\\Ed\\AppData\\Local\\Temp\\pytest-of-Ed\\pytest-848\\test_force_full0\\other.txt": { + "hash": "04d61c0832f9cbc2a210334352425d2519890a0a5945da96ccc5bd9ff101c4d3", + "summary": "This document is a simple text file containing ten lines of content, with the first eight lines previewed. Its purpose appears to be for basic data storage or as a placeholder.\n\n**Outline:**\n**TXT** \u2014 10 lines\npreview:\n```\nline1\nline2\nline3\nline4\nline5\nline6\nline7\nline8\n```" } } \ No newline at end of file diff --git a/conductor/tracks/data_oriented_optimization_20260312/entropy_audit_report.md b/conductor/tracks/data_oriented_optimization_20260312/entropy_audit_report.md new file mode 100644 index 0000000..3ef9410 --- /dev/null +++ b/conductor/tracks/data_oriented_optimization_20260312/entropy_audit_report.md @@ -0,0 +1,73 @@ +# Entropy Audit Report: src/ + +**Files Analyzed:** 48 +**Total Lines:** 22,222 +**Issues Found:** 1050 + +## Summary by Severity + +- **High:** 12 +- **Medium:** 1 +- **Low:** 1037 + +## Summary by Category + +- **long_function:** 12 +- **magic_number:** 928 +- **tech_debt:** 109 +- **too_many_params:** 1 + +## High Severity Issues + +### src\ai_client.py +- **Line 940:** Function `_send_gemini` is 229 lines (>200) + - Detail: `Lines 940-1169` + +### src\ai_client.py +- **Line 1660:** Function `_send_deepseek` is 251 lines (>200) + - Detail: `Lines 1660-1911` + +### src\ai_client.py +- **Line 1913:** Function `_send_minimax` is 216 lines (>200) + - Detail: `Lines 1913-2129` + +### src\api_hooks.py +- **Line 88:** Function `do_GET` is 205 lines (>200) + - Detail: `Lines 88-293` + +### src\api_hooks.py +- **Line 295:** Function `do_POST` is 350 lines (>200) + - Detail: `Lines 295-645` + +### src\app_controller.py +- **Line 137:** Function `__init__` is 332 lines (>200) + - Detail: `Lines 137-469` + +### src\app_controller.py +- **Line 716:** Function `_process_pending_gui_tasks` is 264 lines (>200) + - Detail: `Lines 716-980` + +### src\app_controller.py +- **Line 1924:** Function `create_api` is 234 lines (>200) + - Detail: `Lines 1924-2158` + +### src\gui_2.py +- **Line 750:** Function `_gui_func` is 580 lines (>200) + - Detail: `Lines 750-1330` + +### src\gui_2.py +- **Line 2730:** Function `_render_discussion_panel` is 376 lines (>200) + - Detail: `Lines 2730-3106` + +### src\gui_2.py +- **Line 4059:** Function `_render_mma_dashboard` is 420 lines (>200) + - Detail: `Lines 4059-4479` + +### src\multi_agent_conductor.py +- **Line 403:** Function `run_worker_lifecycle` is 210 lines (>200) + - Detail: `Lines 403-613` + + +## Medium Severity Issues + +- **Line 2236** (src\ai_client.py): Function `send` has 12 parameters \ No newline at end of file diff --git a/conductor/tracks/data_oriented_optimization_20260312/entropy_findings.md b/conductor/tracks/data_oriented_optimization_20260312/entropy_findings.md index 962b448..3ce2c21 100644 --- a/conductor/tracks/data_oriented_optimization_20260312/entropy_findings.md +++ b/conductor/tracks/data_oriented_optimization_20260312/entropy_findings.md @@ -1,68 +1,69 @@ # Entropy Audit Findings: Data-Oriented Python Optimization Pass -## Phase 5 Status: In Progress +## Phase 5 Status: In Progress - Focused Audit Complete -## Issues Found and Fixed +**Approach:** Muratori-style - focused on actual issues, not style. "The less Python the better" means: +- Duplicate logic (same thing done in multiple places) = BAD +- Long functions that are linear and single-purpose = OK +- Nested imports in hot paths = BAD (performance) +- Mutable default arguments = BAD (bugs) -### 1. Duplicate Line Bug in `app_controller.py` -**Location:** `rag_emb_provider.setter` (around line 541) -**Issue:** Two identical lines in setter: -```python -if self.rag_engine: self.rag_engine = rag_engine.RAGEngine(self.rag_config, self.active_project_root) -if self.rag_engine: self.rag_engine = rag_engine.RAGEngine(self.rag_config, self.active_project_root) -``` -**Fix:** Removed duplicate line. -**Status:** FIXED (commit f6feab9) +## Already Fixed This Session -### 2. FALSE POSITIVE: Python Property Definitions -**Location:** `app_controller.py`, `gui_2.py` -**Issue:** Audit script flagged `@property` getter/setter pairs as "duplicate definitions" -**Explanation:** These are correct Python property patterns (getter + setter), not bugs -**Status:** NOT AN ISSUE - False positive from audit script +### ✓ GUI Indentation Bug causing crash (commit f6feab9) +The `_render_mma_dashboard` had code incorrectly indented inside an `if` block. -## Issues Identified (Not Fixed - Require Design Decisions) +### ✓ Duplicate Line Bug in `rag_emb_provider.setter` (commit f6feab9) +`app_controller.py` had two identical lines. -### 3. Duplicate Blocking/Unblocking Logic -**Location:** `gui_2.py` vs `dag_engine.py` +### ✓ Nested Imports in Hot Paths (commit 54afbb9) -**gui_2.py has:** -- `_cb_block_ticket()` - manual transitive blocking with while loop -- `_cb_unblock_ticket()` - manual transitive unblocking with while loop -- `_reorder_ticket()` - manual dependency validation +**`multi_agent_conductor.py`:** +- Removed `import sys` from inside `run()` - was unused +- `from src.personas import PersonaManager` and `from src import paths` were already available at module level -**dag_engine.py has:** -- `cascade_blocks()` - transitive blocking propagation -- `topological_sort()` - dependency ordering +**`gui_2.py`:** +- Removed `import traceback` from inside `_gui_func` exception handler +- `import uvicorn` in `run()` remains lazy-loaded for `--headless` mode only -**Issue:** Both do similar transitive closure operations on tickets, but on different data structures: -- gui_2.py: `List[Dict[str, Any]]` (active_tickets) -- dag_engine.py: `List[Ticket]` (Ticket objects from models.py) +**`app_controller.py`:** +- Added `import traceback` and `import inspect` at module level +- Removed 3 nested `import traceback` from `_process_pending_gui_tasks`, `_handle_request_event`, `_do_generate` -**Impact:** Potential state inconsistency if GUI state and DAG engine state diverge -**Recommendation:** Refactor gui_2.py to call controller/engine methods rather than duplicating logic +## Actual Issues Found (Design - Require Architecture Changes) -### 4. Two Parallel Ticket Representations -**Locations:** -- `app_controller.py`: `self.active_tickets: List[Dict[str, Any]]` (dictionaries) -- `dag_engine.py`: `self.tickets: List[Ticket]` (dataclass instances) +### 1. Parallel Ticket Representations +**Severity:** HIGH - Maintenance burden -**Issue:** Ticket data is converted between dict and Ticket object forms. The `_load_active_tickets` method (line 3184) does: -```python -self.active_tickets = [asdict(t) if not isinstance(t, dict) else t for t in self.active_track.tickets] -``` +`active_tickets` (Dict-based) is accessed/modified in THREE files: +- `api_hooks.py` - API endpoint handling +- `app_controller.py` - Main controller state +- `gui_2.py` - UI state -**Recommendation:** Consider unifying to a single representation, or ensure clear ownership of state management. +While `dag_engine.py` uses `List[Ticket]` objects. This creates state sync burden. + +### 2. Duplicate Blocking Logic +**Severity:** MEDIUM - Potential state inconsistency + +| Component | Has Blocking Logic? | +|-----------|-------------------| +| gui_2.py | Yes: `_cb_block_ticket`, `_cb_unblock_ticket` | +| dag_engine.py | Yes: `cascade_blocks` | + +If GUI manually blocks tickets without going through DAG, state can diverge. ## Issues Not Addressed (Lower Priority) -### 5. Widespread Mixed Indentation -Many files contain 4-space indentation blocks within predominantly 1-space indented code. This is a style inconsistency but not a functional bug. +### Widespread Mixed Indentation +Many files have 4-space blocks within 1-space files. Style inconsistency only. -### 6. Import Consolidation -Multiple files have similar import patterns. Could benefit from a central `src/__init__.py` with commonly used imports, but this is cosmetic. +### Pattern Usage Across Files +These patterns appear in multiple files (by design - not duplicates): +- `calculate_track_progress`: gui_2.py, project_manager.py +- `topological_sort`: app_controller.py, conductor_tech_lead.py, dag_engine.py +- `push_mma_state`: app_controller.py, gui_2.py ## Summary -- **Fixed:** 1 bug (duplicate line in rag_emb_provider setter) -- **False Positives:** Property definitions flagged incorrectly by audit -- **Design Issues:** 2 (duplicate blocking logic, parallel ticket representations) -- **Cosmetic:** Mixed indentation, import patterns \ No newline at end of file +- **Fixed:** Nested imports in hot paths (performance), 2 bugs +- **Design Issues:** 2 (parallel ticket state, duplicate blocking logic) - require architectural changes +- **Cosmetic:** Mixed indentation - intentional for readability in some places diff --git a/scripts/comprehensive_entropy_audit.py b/scripts/comprehensive_entropy_audit.py new file mode 100644 index 0000000..aa76f1c --- /dev/null +++ b/scripts/comprehensive_entropy_audit.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python3 +""" +Comprehensive Entropy Audit Script for Manual Slop src/ +Checks for: +1. Duplicate function definitions +2. Duplicate class definitions +3. Very long functions (>200 lines) +4. Nested imports within functions +5. Inconsistent patterns (TODO, FIXME comments) +6. Cyclomatic complexity indicators (nested conditionals) +7. Dead code indicators (unused variables, commented out code) +""" + +import os +import re +import ast +from pathlib import Path +from dataclasses import dataclass, field +from typing import List, Dict, Set, Optional + +@dataclass +class EntropyIssue: + file: str + line: int + severity: str # 'high', 'medium', 'low' + category: str + description: str + detail: str = "" + +@dataclass +class FileAnalysis: + path: str + size_kb: float + issues: List[EntropyIssue] = field(default_factory=list) + stats: Dict = field(default_factory=dict) + +class EntropyAuditor: + def __init__(self, src_dir: str = "src"): + self.src_dir = Path(src_dir) + self.issues: List[EntropyIssue] = [] + self.files_analyzed = 0 + self.total_lines = 0 + + def analyze_file(self, filepath: Path) -> FileAnalysis: + with open(filepath, encoding='utf-8', errors='ignore') as f: + content = f.read() + + lines = content.split('\n') + self.total_lines += len(lines) + + analysis = FileAnalysis( + path=str(filepath), + size_kb=filepath.stat().st_size / 1024 + ) + + # 1. Check for nested imports + self._check_nested_imports(filepath, content) + + # 2. Check for very long functions + self._check_long_functions(filepath, content) + + # 3. Check for TODO/FIXME + self._check_todos(filepath, content) + + # 4. Check for nested depth (complexity) + self._check_nesting_depth(filepath, lines) + + # 5. Check for duplicate code patterns + self._check_duplicate_patterns(filepath, lines) + + # 6. Check for magic numbers + self._check_magic_numbers(filepath, lines) + + return analysis + + def _check_nested_imports(self, filepath: Path, content: str) -> None: + """Check for imports inside function bodies.""" + tree = ast.parse(content, filename=str(filepath)) + for node in ast.walk(tree): + if isinstance(node, ast.FunctionDef): + for child in ast.walk(node): + if isinstance(child, (ast.Import, ast.ImportFrom)): + # Check if it's not at module level + if not any(isinstance(p, (ast.Import, ast.ImportFrom)) for p in tree.body): + line = child.lineno or 0 + self.issues.append(EntropyIssue( + file=str(filepath), + line=line, + severity='medium', + category='nested_import', + description=f'Nested import in function `{node.name}`', + detail=ast.unparse(child)[:100] + )) + + def _check_long_functions(self, filepath: Path, content: str) -> None: + """Check for functions with >200 lines or >10 parameters.""" + tree = ast.parse(content, filename=str(filepath)) + for node in ast.walk(tree): + if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): + if node.end_lineno and node.lineno: + length = node.end_lineno - node.lineno + if length > 200: + self.issues.append(EntropyIssue( + file=str(filepath), + line=node.lineno, + severity='high', + category='long_function', + description=f'Function `{node.name}` is {length} lines (>{200})', + detail=f'Lines {node.lineno}-{node.end_lineno}' + )) + if len(node.args.args) > 10: + self.issues.append(EntropyIssue( + file=str(filepath), + line=node.lineno, + severity='medium', + category='too_many_params', + description=f'Function `{node.name}` has {len(node.args.args)} parameters', + detail=str(node.args.args[:5]) + '...' + )) + + def _check_todos(self, filepath: Path, content: str) -> None: + """Check for TODO/FIXME/BUG comments.""" + for i, line in enumerate(content.split('\n'), 1): + if re.search(r'(TODO|FIXME|BUG|HACK|XXX)', line, re.IGNORECASE): + self.issues.append(EntropyIssue( + file=str(filepath), + line=i, + severity='low', + category='tech_debt', + description=line.strip()[:80], + detail=f'Technical debt marker' + )) + + def _check_nesting_depth(self, filepath: Path, lines: List[str]) -> None: + """Check for deeply nested code blocks.""" + for i, line in enumerate(lines, 1): + if line and not line.strip().startswith('#'): + # Count leading spaces + stripped = line.lstrip() + indent = len(line) - len(stripped) + if indent > 20: # More than ~10 levels deep + self.issues.append(EntropyIssue( + file=str(filepath), + line=i, + severity='medium', + category='deep_nesting', + description=f'Line has {indent} spaces of indentation', + detail=line.strip()[:60] + )) + + def _check_duplicate_patterns(self, filepath: Path, lines: List[str]) -> None: + """Check for consecutive duplicate non-blank lines.""" + prev_line = None + dup_start = None + for i, line in enumerate(lines, 1): + stripped = line.strip() + if stripped and not stripped.startswith('#') and stripped == prev_line: + if dup_start is None: + dup_start = i - 1 + else: + if dup_start and i - dup_start > 2: + self.issues.append(EntropyIssue( + file=str(filepath), + line=dup_start, + severity='high', + category='duplicate_lines', + description=f'{i - dup_start} consecutive duplicate lines starting at {dup_start}', + detail=lines[dup_start-1].strip()[:60] if dup_start <= len(lines) else '' + )) + dup_start = None + prev_line = stripped + + def _check_magic_numbers(self, filepath: Path, lines: List[str]) -> None: + """Check for magic numbers (unnamed constants).""" + magic_pattern = re.compile(r'(? None: + """Run audit on all Python files in src/.""" + py_files = list(self.src_dir.glob("*.py")) + print(f"Auditing {len(py_files)} Python files in {self.src_dir}...") + + for filepath in sorted(py_files): + if filepath.name == "__init__.py": + continue + try: + self.analyze_file(filepath) + self.files_analyzed += 1 + except Exception as e: + print(f"Error analyzing {filepath}: {e}") + + def generate_report(self) -> str: + """Generate a markdown report of findings.""" + by_severity = {'high': [], 'medium': [], 'low': []} + by_category = {} + + for issue in self.issues: + by_severity[issue.severity].append(issue) + if issue.category not in by_category: + by_category[issue.category] = [] + by_category[issue.category].append(issue) + + report = [ + "# Entropy Audit Report: src/", + "", + f"**Files Analyzed:** {self.files_analyzed}", + f"**Total Lines:** {self.total_lines:,}", + f"**Issues Found:** {len(self.issues)}", + "", + "## Summary by Severity", + "", + f"- **High:** {len(by_severity['high'])}", + f"- **Medium:** {len(by_severity['medium'])}", + f"- **Low:** {len(by_severity['low'])}", + "", + "## Summary by Category", + "" + ] + + for cat, issues in sorted(by_category.items()): + report.append(f"- **{cat}:** {len(issues)}") + + report.extend(["", "## High Severity Issues", ""]) + for issue in sorted(by_severity['high'], key=lambda x: (x.file, x.line)): + report.append(f"### {issue.file}") + report.append(f"- **Line {issue.line}:** {issue.description}") + if issue.detail: + report.append(f" - Detail: `{issue.detail[:80]}`") + report.append("") + + report.extend(["", "## Medium Severity Issues", ""]) + for issue in sorted(by_severity['medium'], key=lambda x: (x.file, x.line))[:50]: + report.append(f"- **Line {issue.line}** ({issue.file}): {issue.description}") + + if len(by_severity['medium']) > 50: + report.append(f"\n_... and {len(by_severity['medium']) - 50} more medium issues_") + + return "\n".join(report) + + +def main(): + auditor = EntropyAuditor("src") + auditor.run_audit() + report = auditor.generate_report() + print(report) + + # Also write to file + report_path = "conductor/tracks/data_oriented_optimization_20260312/entropy_audit_report.md" + with open(report_path, 'w') as f: + f.write(report) + print(f"\nReport written to {report_path}") + + +if __name__ == "__main__": + main() diff --git a/scripts/focused_entropy_audit.py b/scripts/focused_entropy_audit.py new file mode 100644 index 0000000..37b44db --- /dev/null +++ b/scripts/focused_entropy_audit.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +""" +Focused Entropy Audit for Manual Slop - Muratori Style +Focuses on ACTUAL issues, not style: +1. Duplicate logic (same thing done in multiple places) +2. State inconsistencies (parallel representations) +3. Logic errors / bugs +4. Performance concerns +""" + +import os +import re +import ast +from pathlib import Path +from collections import defaultdict +from typing import List, Dict, Set, Tuple, Optional + +def find_duplicate_logic_files(): + """Find files with similar patterns that might indicate duplicate logic.""" + patterns = { + 'calculate_track_progress': [], + 'cascade_blocks': [], + 'topological_sort': [], + 'push_mma_state': [], + 'active_tickets': [], + } + + for f in Path('src').glob('*.py'): + content = f.read_text(encoding='utf-8', errors='ignore') + for pattern in patterns: + if re.search(pattern, content): + patterns[pattern].append(f.name) + + return patterns + +def check_ticket_state_management(): + """Check for state management issues in ticket handling.""" + issues = [] + + # Check if there are parallel ticket representations + gui_2_content = Path('src/gui_2.py').read_text(encoding='utf-8', errors='ignore') + app_ctrl_content = Path('src/app_controller.py').read_text(encoding='utf-8', errors='ignore') + dag_content = Path('src/dag_engine.py').read_text(encoding='utf-8', errors='ignore') + + # gui_2 uses dict-based tickets + if 'active_tickets' in gui_2_content: + if 'ticket["status"]' in gui_2_content or "t['status']" in gui_2_content: + issues.append(("gui_2.py", "Dict-based ticket access pattern found")) + + # Check for blocking logic duplication + gui_blocking = len(re.findall(r'_cb_block_ticket|_cb_unblock_ticket', gui_2_content)) + dag_blocking = len(re.findall(r'cascade_blocks', dag_content)) + + if gui_blocking > 0 and dag_blocking > 0: + issues.append(("architecture", "GUI has manual block/unblock that could conflict with DAG cascade_blocks")) + + return issues + +def check_import_issues(): + """Check for actual import problems - nested imports causing runtime issues.""" + issues = [] + + for f in Path('src').glob('*.py'): + try: + content = f.read_text(encoding='utf-8', errors='ignore') + tree = ast.parse(content, filename=str(f)) + + for node in ast.walk(tree): + if isinstance(node, ast.FunctionDef): + for child in ast.walk(node): + if isinstance(child, (ast.Import, ast.ImportFrom)): + line = child.lineno or 0 + # Check if this import is inside a HOT PATH function + if node.name in ['_process_pending_gui_tasks', '_gui_func', 'run', 'tick']: + issues.append((f.name, f"Nested import `{ast.unparse(child).strip()[:50]}` in hot path `{node.name}` line {line}")) + except: + pass + + return issues + +def check_potential_bugs(): + """Check for potential bugs - undefined variables, etc.""" + bugs = [] + + # Check for == None vs is None patterns + for f in Path('src').glob('*.py'): + content = f.read_text(encoding='utf-8', errors='ignore') + lines = content.split('\n') + + for i, line in enumerate(lines, 1): + # Skip comments + if line.strip().startswith('#'): + continue + + # Check for mutable default arguments (common bug) + if re.search(r'def\s+\w+\([^)]*=\s*\[\s*\]', line): + bugs.append((f.name, i, "Mutable default argument", line.strip()[:60])) + if re.search(r'def\s+\w+\([^)]*=\s*\{\s*\}', line): + bugs.append((f.name, i, "Mutable default argument", line.strip()[:60])) + + return bugs + +def check_actual_duplicates(): + """Check for ACTUAL duplicate code - same logic copied.""" + duplicates = [] + seen_snippets = defaultdict(list) + + # Look for duplicate patterns (3+ lines identical) + for f in sorted(Path('src').glob('*.py')): + try: + content = f.read_text(encoding='utf-8', errors='ignore') + lines = content.split('\n') + + # Normalize and check consecutive duplicate lines + prev_normalized = None + dup_start = None + + for i, line in enumerate(lines, 1): + if line.strip().startswith('#'): + prev_normalized = None + dup_start = None + continue + + normalized = line.strip() + if not normalized: + prev_normalized = None + dup_start = None + continue + + if normalized == prev_normalized: + if dup_start is None: + dup_start = i - 1 + else: + if dup_start and i - dup_start >= 3: + # Found 3+ consecutive duplicate lines + duplicates.append((f.name, dup_start, i - 1, lines[dup_start-1].strip()[:60])) + dup_start = None + prev_normalized = normalized + except: + pass + + return duplicates + +def main(): + print("=" * 70) + print("FOCUSED ENTROPY AUDIT - Muratori Style") + print("=" * 70) + print() + + print("1. TICKET STATE MANAGEMENT ISSUES") + print("-" * 40) + issues = check_ticket_state_management() + if issues: + for issue in issues: + print(f" [{issue[0]}] {issue[1]}") + else: + print(" None found") + print() + + print("2. NESTED IMPORTS IN HOT PATH FUNCTIONS") + print("-" * 40) + issues = check_import_issues() + if issues: + for fname, msg in issues[:10]: + print(f" [{fname}] {msg}") + else: + print(" None found") + print() + + print("3. POTENTIAL BUGS (mutable defaults, etc)") + print("-" * 40) + issues = check_potential_bugs() + if issues: + for fname, line, bugtype, code in issues[:10]: + print(f" [{fname}:{line}] {bugtype}: {code}") + else: + print(" None found") + print() + + print("4. ACTUAL DUPLICATE CODE (3+ consecutive lines)") + print("-" * 40) + duplicates = check_actual_duplicates() + if duplicates: + for fname, start, end, code in duplicates[:10]: + print(f" [{fname}:{start}-{end}] {code}") + else: + print(" None found") + print() + + print("5. PATTERN USAGE ACROSS FILES") + print("-" * 40) + patterns = find_duplicate_logic_files() + for pattern, files in patterns.items(): + if len(files) > 1: + print(f" {pattern}: {files}") + print() + +if __name__ == "__main__": + main() diff --git a/src/app_controller.py b/src/app_controller.py index d4c903d..a149713 100644 --- a/src/app_controller.py +++ b/src/app_controller.py @@ -2,8 +2,10 @@ import threading import time import copy import sys +import traceback import os import re +import inspect from typing import Any, List, Dict, Optional, Callable from pathlib import Path from src import workspace_manager @@ -865,7 +867,6 @@ class AppController: elif item == "btn_mma_load_track": self._cb_load_track(str(user_data or "")) elif item in self._clickable_actions: - import inspect func = self._clickable_actions[item] try: sig = inspect.signature(func) @@ -974,7 +975,6 @@ class AppController: self.mma_streams[stream_id] = "" self.mma_streams[stream_id] += f"[BEAD UPDATE] {bead_id} -> status: {status}\n" except Exception as e: - import traceback sys.stderr.write(f"[DEBUG] Error executing GUI task: {e}\n{traceback.format_exc()}\n") sys.stderr.flush() print(f"Error executing GUI task: {e}") @@ -1642,7 +1642,6 @@ class AppController: sys.stderr.flush() self.event_queue.put("response", {"text": e.ui_message(), "status": "error", "role": "Vendor API"}) except Exception as e: - import traceback sys.stderr.write(f"[DEBUG] _handle_request_event ERROR: {e}\n{traceback.format_exc()}\n") sys.stderr.flush() self.event_queue.put("response", {"text": f"ERROR: {e}", "status": "error", "role": "System"}) @@ -2642,7 +2641,6 @@ class AppController: sys.stderr.write("[DEBUG] Enqueued user_request event\n") sys.stderr.flush() except Exception as e: - import traceback sys.stderr.write(f"[DEBUG] _do_generate ERROR: {e}\n{traceback.format_exc()}\n") sys.stderr.flush() self._set_status(f"generate error: {e}") diff --git a/src/gui_2.py b/src/gui_2.py index a3bd6f2..e4451d9 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -35,6 +35,7 @@ from src import thinking_parser import re import difflib import subprocess +import traceback if sys.platform == "win32": import win32gui import win32con @@ -1319,7 +1320,6 @@ class App: imgui.end_popup() except Exception as e: print(f"ERROR in _gui_func: {e}") - import traceback traceback.print_exc() if pushed_prior_tint: diff --git a/src/multi_agent_conductor.py b/src/multi_agent_conductor.py index 672cee7..c68ed76 100644 --- a/src/multi_agent_conductor.py +++ b/src/multi_agent_conductor.py @@ -218,7 +218,6 @@ class ConductorEngine: md_content: The full markdown context (history + files) for AI workers. max_ticks: Optional limit on number of iterations (for testing). """ - import sys tick_count = 0 while True: if self._pause_event.is_set(): @@ -282,10 +281,7 @@ class ConductorEngine: else: # Check if ticket has a persona with preferred_models if ticket.persona_id: - # Try to load preferred_models from persona try: - from src.personas import PersonaManager - from src import paths pm = PersonaManager(Path(paths.get_project_personas_path(Path.cwd())) if paths.get_project_personas_path(Path.cwd()).exists() else None) personas = pm.load_all() if ticket.persona_id in personas: