wip fixing regressions, removing hardcoded paths
This commit is contained in:
@@ -32,10 +32,6 @@ from src import conductor_tech_lead
|
|||||||
from src import multi_agent_conductor
|
from src import multi_agent_conductor
|
||||||
from src import theme
|
from src import theme
|
||||||
|
|
||||||
def save_config(config: dict[str, Any]) -> None:
|
|
||||||
with open(models.CONFIG_PATH, "wb") as f:
|
|
||||||
tomli_w.dump(config, f)
|
|
||||||
|
|
||||||
def hide_tk_root() -> Tk:
|
def hide_tk_root() -> Tk:
|
||||||
root = Tk()
|
root = Tk()
|
||||||
root.withdraw()
|
root.withdraw()
|
||||||
@@ -1298,7 +1294,7 @@ class AppController:
|
|||||||
self._flush_to_project()
|
self._flush_to_project()
|
||||||
self._save_active_project()
|
self._save_active_project()
|
||||||
self._flush_to_config()
|
self._flush_to_config()
|
||||||
save_config(self.config)
|
models.save_config(self.config)
|
||||||
self._set_status("config saved")
|
self._set_status("config saved")
|
||||||
|
|
||||||
def _cb_disc_create(self) -> None:
|
def _cb_disc_create(self) -> None:
|
||||||
@@ -1696,7 +1692,7 @@ class AppController:
|
|||||||
self._flush_to_project()
|
self._flush_to_project()
|
||||||
self._save_active_project()
|
self._save_active_project()
|
||||||
self._flush_to_config()
|
self._flush_to_config()
|
||||||
save_config(self.config)
|
models.save_config(self.config)
|
||||||
track_id = self.active_track.id if self.active_track else None
|
track_id = self.active_track.id if self.active_track else None
|
||||||
flat = project_manager.flat_config(self.project, self.active_discussion, track_id=track_id)
|
flat = project_manager.flat_config(self.project, self.active_discussion, track_id=track_id)
|
||||||
full_md, path, file_items = aggregate.run(flat)
|
full_md, path, file_items = aggregate.run(flat)
|
||||||
@@ -1720,8 +1716,9 @@ class AppController:
|
|||||||
sys.stderr.write(f"[DEBUG] History summary length: {len(history)}\n")
|
sys.stderr.write(f"[DEBUG] History summary length: {len(history)}\n")
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
proj = project_manager.load_project(self.active_project_path)
|
proj = project_manager.load_project(self.active_project_path)
|
||||||
flat = project_manager.flat_config(proj)
|
flat = project_manager.flat_config(self.project)
|
||||||
file_items = aggregate.build_file_items(Path("."), flat.get("files", {}).get("paths", []))
|
file_items = aggregate.build_file_items(Path(self.ui_files_base_dir), flat.get("files", {}).get("paths", []))
|
||||||
|
|
||||||
_t1_baseline = len(ai_client.get_comms_log())
|
_t1_baseline = len(ai_client.get_comms_log())
|
||||||
tracks = orchestrator_pm.generate_tracks(self.ui_epic_input, flat, file_items, history_summary=history)
|
tracks = orchestrator_pm.generate_tracks(self.ui_epic_input, flat, file_items, history_summary=history)
|
||||||
_t1_new = ai_client.get_comms_log()[_t1_baseline:]
|
_t1_new = ai_client.get_comms_log()[_t1_baseline:]
|
||||||
|
|||||||
14
src/gui_2.py
14
src/gui_2.py
@@ -28,10 +28,6 @@ from imgui_bundle import imgui, hello_imgui, immapp, imgui_node_editor as ed
|
|||||||
PROVIDERS: list[str] = ["gemini", "anthropic", "gemini_cli", "deepseek"]
|
PROVIDERS: list[str] = ["gemini", "anthropic", "gemini_cli", "deepseek"]
|
||||||
COMMS_CLAMP_CHARS: int = 300
|
COMMS_CLAMP_CHARS: int = 300
|
||||||
|
|
||||||
def save_config(config: dict[str, Any]) -> None:
|
|
||||||
with open(models.CONFIG_PATH, "wb") as f:
|
|
||||||
tomli_w.dump(config, f)
|
|
||||||
|
|
||||||
def hide_tk_root() -> Tk:
|
def hide_tk_root() -> Tk:
|
||||||
root = Tk()
|
root = Tk()
|
||||||
root.withdraw()
|
root.withdraw()
|
||||||
@@ -208,7 +204,7 @@ class App:
|
|||||||
self._flush_to_project()
|
self._flush_to_project()
|
||||||
self._save_active_project()
|
self._save_active_project()
|
||||||
self._flush_to_config()
|
self._flush_to_config()
|
||||||
save_config(self.config)
|
models.save_config(self.config)
|
||||||
self.ai_status = "config saved"
|
self.ai_status = "config saved"
|
||||||
if imgui.menu_item("Reset Session", "", False)[0]:
|
if imgui.menu_item("Reset Session", "", False)[0]:
|
||||||
ai_client.reset_session()
|
ai_client.reset_session()
|
||||||
@@ -248,7 +244,7 @@ class App:
|
|||||||
self._flush_to_project()
|
self._flush_to_project()
|
||||||
self._save_active_project()
|
self._save_active_project()
|
||||||
self._flush_to_config()
|
self._flush_to_config()
|
||||||
save_config(self.config)
|
models.save_config(self.config)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass # silent — don't disrupt the GUI loop
|
pass # silent — don't disrupt the GUI loop
|
||||||
# Sync pending comms
|
# Sync pending comms
|
||||||
@@ -721,7 +717,7 @@ class App:
|
|||||||
self._flush_to_project()
|
self._flush_to_project()
|
||||||
self._save_active_project()
|
self._save_active_project()
|
||||||
self._flush_to_config()
|
self._flush_to_config()
|
||||||
save_config(self.config)
|
models.save_config(self.config)
|
||||||
self.ai_status = "config saved"
|
self.ai_status = "config saved"
|
||||||
ch, self.ui_word_wrap = imgui.checkbox("Word-Wrap (Read-only panels)", self.ui_word_wrap)
|
ch, self.ui_word_wrap = imgui.checkbox("Word-Wrap (Read-only panels)", self.ui_word_wrap)
|
||||||
ch, self.ui_summary_only = imgui.checkbox("Summary Only (send file structure, not full content)", self.ui_summary_only)
|
ch, self.ui_summary_only = imgui.checkbox("Summary Only (send file structure, not full content)", self.ui_summary_only)
|
||||||
@@ -1019,7 +1015,7 @@ class App:
|
|||||||
self._flush_to_project()
|
self._flush_to_project()
|
||||||
self._save_active_project()
|
self._save_active_project()
|
||||||
self._flush_to_config()
|
self._flush_to_config()
|
||||||
save_config(self.config)
|
models.save_config(self.config)
|
||||||
self.ai_status = "discussion saved"
|
self.ai_status = "discussion saved"
|
||||||
ch, self.ui_auto_add_history = imgui.checkbox("Auto-add message & response to history", self.ui_auto_add_history)
|
ch, self.ui_auto_add_history = imgui.checkbox("Auto-add message & response to history", self.ui_auto_add_history)
|
||||||
# Truncation controls
|
# Truncation controls
|
||||||
@@ -1994,7 +1990,7 @@ class App:
|
|||||||
imgui.same_line()
|
imgui.same_line()
|
||||||
if imgui.button("Apply Font (Requires Restart)"):
|
if imgui.button("Apply Font (Requires Restart)"):
|
||||||
self._flush_to_config()
|
self._flush_to_config()
|
||||||
save_config(self.config)
|
models.save_config(self.config)
|
||||||
self.ai_status = "Font settings saved. Restart required."
|
self.ai_status = "Font settings saved. Restart required."
|
||||||
imgui.separator()
|
imgui.separator()
|
||||||
imgui.text("UI Scale (DPI)")
|
imgui.text("UI Scale (DPI)")
|
||||||
|
|||||||
@@ -105,14 +105,24 @@ def _is_allowed(path: Path) -> bool:
|
|||||||
|
|
||||||
CRITICAL: Blacklisted files (history) are NEVER allowed.
|
CRITICAL: Blacklisted files (history) are NEVER allowed.
|
||||||
"""
|
"""
|
||||||
# Blacklist check
|
from src.paths import get_config_path
|
||||||
name = path.name.lower()
|
from src.ai_client import get_credentials_path
|
||||||
if name in ("history.toml", "config.toml", "credentials.toml") or name.endswith("_history.toml"):
|
|
||||||
return False
|
|
||||||
try:
|
try:
|
||||||
rp = path.resolve(strict=True)
|
rp = path.resolve(strict=True)
|
||||||
except (OSError, ValueError):
|
except (OSError, ValueError):
|
||||||
rp = path.resolve()
|
rp = path.resolve()
|
||||||
|
|
||||||
|
# Blacklist check by resolved path
|
||||||
|
if rp == get_config_path().resolve():
|
||||||
|
return False
|
||||||
|
if rp == get_credentials_path().resolve():
|
||||||
|
return False
|
||||||
|
|
||||||
|
name = path.name.lower()
|
||||||
|
if name == "history.toml" or name.endswith("_history.toml"):
|
||||||
|
return False
|
||||||
|
|
||||||
if rp in _allowed_paths:
|
if rp in _allowed_paths:
|
||||||
return True
|
return True
|
||||||
# Allow current working directory and subpaths by default if no base_dirs
|
# Allow current working directory and subpaths by default if no base_dirs
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import tomllib
|
import tomllib
|
||||||
import os
|
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import List, Optional, Dict, Any, Union
|
from typing import List, Optional, Dict, Any, Union
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from src.paths import get_config_path
|
||||||
|
|
||||||
CONFIG_PATH = Path(os.environ.get("SLOP_CONFIG", "config.toml"))
|
CONFIG_PATH = get_config_path()
|
||||||
|
|
||||||
def load_config() -> dict[str, Any]:
|
def load_config() -> dict[str, Any]:
|
||||||
with open(CONFIG_PATH, "rb") as f:
|
with open(CONFIG_PATH, "rb") as f:
|
||||||
return tomllib.load(f)
|
return tomllib.load(f)
|
||||||
|
|
||||||
|
def save_config(config: dict[str, Any]) -> None:
|
||||||
|
import tomli_w
|
||||||
|
with open(CONFIG_PATH, "wb") as f:
|
||||||
|
tomli_w.dump(config, f)
|
||||||
|
|
||||||
# Global constants for agent tools
|
# Global constants for agent tools
|
||||||
AGENT_TOOL_NAMES = [
|
AGENT_TOOL_NAMES = [
|
||||||
"read_file",
|
"read_file",
|
||||||
@@ -32,29 +37,6 @@ AGENT_TOOL_NAMES = [
|
|||||||
"py_get_hierarchy"
|
"py_get_hierarchy"
|
||||||
]
|
]
|
||||||
|
|
||||||
def parse_history_entries(history_strings: list[str], roles: list[str]) -> list[dict[str, Any]]:
|
|
||||||
"""Parse stored history strings back to disc entry dicts."""
|
|
||||||
import re
|
|
||||||
entries = []
|
|
||||||
for raw in history_strings:
|
|
||||||
ts = ""
|
|
||||||
rest = raw
|
|
||||||
if rest.startswith("@"):
|
|
||||||
nl = rest.find("\n")
|
|
||||||
if nl != -1:
|
|
||||||
ts = rest[1:nl]
|
|
||||||
rest = rest[nl + 1:]
|
|
||||||
known = roles or ["User", "AI"]
|
|
||||||
role_pat = re.compile(r"^(" + "|".join(re.escape(r) for r in known) + r"):", re.IGNORECASE)
|
|
||||||
match = role_pat.match(rest)
|
|
||||||
role = match.group(1) if match else "User"
|
|
||||||
if match:
|
|
||||||
content = rest[match.end():].strip()
|
|
||||||
else:
|
|
||||||
content = rest
|
|
||||||
entries.append({"role": role, "content": content, "collapsed": False, "ts": ts})
|
|
||||||
return entries
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Ticket:
|
class Ticket:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -113,7 +113,12 @@ def generate_tracks(user_request: str, project_config: dict[str, Any], file_item
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Quick CLI test
|
# Quick CLI test
|
||||||
import project_manager
|
import project_manager
|
||||||
proj = project_manager.load_project("manual_slop.toml")
|
from src import aggregate
|
||||||
|
test_project = Path("manual_slop.toml")
|
||||||
|
if not test_project.exists():
|
||||||
|
print(f"Error: {test_project} not found for testing.")
|
||||||
|
else:
|
||||||
|
proj = project_manager.load_project(str(test_project))
|
||||||
flat = project_manager.flat_config(proj)
|
flat = project_manager.flat_config(proj)
|
||||||
file_items = aggregate.build_file_items(Path("."), flat.get("files", {}).get("paths", []))
|
file_items = aggregate.build_file_items(Path("."), flat.get("files", {}).get("paths", []))
|
||||||
print("Testing Tier 1 Track Generation...")
|
print("Testing Tier 1 Track Generation...")
|
||||||
|
|||||||
Reference in New Issue
Block a user