This commit is contained in:
2026-01-31 19:00:04 -08:00
parent dcf16e0cc4
commit 6513a3ad04
25 changed files with 617 additions and 397 deletions

View File

@@ -17,6 +17,8 @@ from Store.registry import _discover_store_classes, _required_keys_for
from ProviderCore.registry import list_providers
from TUI.modalscreen.matrix_room_picker import MatrixRoomPicker
from TUI.modalscreen.selection_modal import SelectionModal
import logging
logger = logging.getLogger(__name__)
class ConfigModal(ModalScreen):
"""A modal for editing the configuration."""
@@ -187,22 +189,23 @@ class ConfigModal(ModalScreen):
try:
self.query_one("#add-tool-btn", Button).display = False
except Exception:
pass
logger.exception("Failed to hide add-tool button in ConfigModal.on_mount")
# Update DB path and last-saved on mount
try:
self.query_one("#config-db-path", Static).update(self._db_path)
except Exception:
pass
logger.exception("Failed to update config DB path display in ConfigModal.on_mount")
try:
mtime = None
try:
mtime = db.db_path.stat().st_mtime
mtime = __import__('datetime').datetime.utcfromtimestamp(mtime).isoformat() + "Z"
except Exception:
logger.exception("Failed to stat DB path for last-saved time")
mtime = None
self.query_one("#config-last-save", Static).update(f"Last saved: {mtime or '(unknown)'}")
except Exception:
pass
logger.exception("Failed to update last-saved display in ConfigModal.on_mount")
self.refresh_view()
def refresh_view(self) -> None:
@@ -236,7 +239,7 @@ class ConfigModal(ModalScreen):
self.query_one("#back-btn", Button).display = (self.editing_item_name is not None)
self.query_one("#save-btn", Button).display = (self.editing_item_name is not None or self.current_category == "globals")
except Exception:
pass
logger.exception("Failed to update visibility of config modal action buttons")
render_id = self._render_id
@@ -445,7 +448,7 @@ class ConfigModal(ModalScreen):
if k:
provider_schema_map[k.upper()] = field_def
except Exception:
pass
logger.exception("Failed to retrieve provider config_schema")
# Fetch Tool schema
if item_type == "tool":
try:
@@ -457,7 +460,7 @@ class ConfigModal(ModalScreen):
if k:
provider_schema_map[k.upper()] = field_def
except Exception:
pass
logger.exception("Failed to retrieve tool config_schema")
# Use columns for better layout of inputs with paste buttons
container.mount(Label("Edit Settings"))
@@ -629,7 +632,7 @@ class ConfigModal(ModalScreen):
row.mount(Button("Paste", id=f"paste-{inp_id}", classes="paste-btn"))
idx += 1
except Exception:
pass
logger.exception("Failed to build required config inputs for provider/tool")
if (
item_type == "provider"
@@ -700,15 +703,16 @@ class ConfigModal(ModalScreen):
seen_ids.add(rid)
deduped.append(r)
except Exception:
logger.exception("Failed to process a matrix room entry while deduplicating")
continue
if self._matrix_inline_list is not None and deduped:
try:
self._render_matrix_rooms_inline(deduped)
except Exception:
pass
logger.exception("Failed to render matrix inline rooms")
except Exception:
pass
logger.exception("Failed to fetch or process matrix rooms for inline rendering")
except Exception:
self._matrix_inline_checkbox_map = {}
self._matrix_inline_list = None
@@ -785,7 +789,7 @@ class ConfigModal(ModalScreen):
try:
self.config_data = reload_config()
except Exception:
pass
logger.exception("Failed to reload config after save conflict")
self._editor_snapshot = None
self.editing_item_name = None
self.editing_item_type = None
@@ -807,7 +811,7 @@ class ConfigModal(ModalScreen):
try:
self.config_data = reload_config()
except Exception:
pass
logger.exception("Failed to reload config after durable save")
if saved == 0:
msg = f"Configuration saved (no rows changed) to {db.db_path.name}"
@@ -816,7 +820,7 @@ class ConfigModal(ModalScreen):
try:
self.notify(msg, timeout=6)
except Exception:
pass
logger.exception("Failed to show notification message in ConfigModal")
# Return to the main list view within the current category
self.editing_item_name = None
@@ -828,7 +832,7 @@ class ConfigModal(ModalScreen):
try:
log(f"Durable save failed: {exc}")
except Exception:
pass
logger.exception("Failed to call log() for durable save error")
elif bid in self._button_id_map:
action, itype, name = self._button_id_map[bid]
if action == "edit":
@@ -870,7 +874,7 @@ class ConfigModal(ModalScreen):
if cls.config_schema():
options.append(stype)
except Exception:
pass
logger.exception("Failed to inspect store class config_schema for '%s'", stype)
self.app.push_screen(SelectionModal("Select Store Type", options), callback=self.on_store_type_selected)
elif bid == "add-provider-btn":
provider_names = list(list_providers().keys())
@@ -883,7 +887,7 @@ class ConfigModal(ModalScreen):
if pcls.config_schema():
options.append(ptype)
except Exception:
pass
logger.exception("Failed to inspect provider class config_schema for '%s'", ptype)
self.app.push_screen(SelectionModal("Select Provider Type", options), callback=self.on_provider_type_selected)
elif bid == "add-tool-btn":
# Discover tool modules that advertise a config_schema()
@@ -918,22 +922,22 @@ class ConfigModal(ModalScreen):
cb = self.query_one(f"#{checkbox_id}", Checkbox)
cb.value = True
except Exception:
pass
logger.exception("Failed to set matrix inline checkbox to True for '%s'", checkbox_id)
try:
self.query_one("#matrix-inline-save", Button).disabled = False
except Exception:
pass
logger.exception("Failed to enable matrix inline save button")
elif bid == "matrix-inline-clear":
for checkbox_id in list(self._matrix_inline_checkbox_map.keys()):
try:
cb = self.query_one(f"#{checkbox_id}", Checkbox)
cb.value = False
except Exception:
pass
logger.exception("Failed to set matrix inline checkbox to False for '%s'", checkbox_id)
try:
self.query_one("#matrix-inline-save", Button).disabled = True
except Exception:
pass
logger.exception("Failed to disable matrix inline save button")
elif bid == "matrix-inline-save":
selected: List[str] = []
for checkbox_id, room_id in self._matrix_inline_checkbox_map.items():
@@ -942,7 +946,7 @@ class ConfigModal(ModalScreen):
if cb.value and room_id:
selected.append(room_id)
except Exception:
pass
logger.exception("Failed to read matrix inline checkbox '%s'", checkbox_id)
if not selected:
if self._matrix_status:
self._matrix_status.update("No default rooms were saved.")
@@ -963,7 +967,7 @@ class ConfigModal(ModalScreen):
try:
self.query_one("#matrix-inline-save", Button).disabled = True
except Exception:
pass
logger.exception("Failed to disable matrix inline save button")
self.refresh_view()
@@ -1096,7 +1100,7 @@ class ConfigModal(ModalScreen):
if key:
new_config[key] = field_def.get("default", "")
except Exception:
pass
logger.exception("Failed to load config_schema for tool '%s'", tname)
self.config_data["tool"][tname] = new_config
self.editing_item_type = "tool"
@@ -1247,7 +1251,7 @@ class ConfigModal(ModalScreen):
self._matrix_status.update("Matrix test skipped: please set both 'homeserver' and 'access_token' before testing.")
return
except Exception:
pass
logger.exception("Failed to check matrix configuration before testing")
if self._matrix_status:
self._matrix_status.update("Saving configuration before testing…")
@@ -1280,7 +1284,7 @@ class ConfigModal(ModalScreen):
try:
debug(f"[matrix] Test connection failed: {exc}\n{tb}")
except Exception:
pass
logger.exception("Failed to debug matrix test failure")
msg = str(exc) or "Matrix test failed"
m_lower = msg.lower()
@@ -1328,7 +1332,7 @@ class ConfigModal(ModalScreen):
if isinstance(parsed, (list, tuple, dict)):
return self._normalize_cached_raw(parsed if isinstance(parsed, (list, tuple)) else [parsed])
except Exception:
pass
logger.exception("Failed to parse cached_rooms JSON for provider matrix")
# Try Python literal eval (accepts single quotes, repr-style lists)
try:
@@ -1338,7 +1342,7 @@ class ConfigModal(ModalScreen):
if isinstance(parsed, (list, tuple, dict)):
return self._normalize_cached_raw(parsed if isinstance(parsed, (list, tuple)) else [parsed])
except Exception:
pass
logger.exception("Failed to parse cached_rooms as Python literal for provider matrix")
# Try to extract dict-like pairs for room_id/name when the string looks like
# a Python repr or partial dict fragment (e.g., "'room_id': '!r1', 'name': 'Room'"
@@ -1362,11 +1366,11 @@ class ConfigModal(ModalScreen):
if ids:
return [{"room_id": rid, "name": ""} for rid in ids]
except Exception:
pass
logger.exception("Failed to extract cached_rooms pairs or ids for provider matrix")
return []
except Exception:
pass
logger.exception("Failed to parse cached_rooms for provider matrix")
return []
def _normalize_cached_raw(self, parsed: List[Any]) -> List[Dict[str, Any]]:
@@ -1383,6 +1387,7 @@ class ConfigModal(ModalScreen):
if s:
out.append({"room_id": s, "name": ""})
except Exception:
logger.exception("Failed to normalize cached_rooms entry: %r", it)
continue
return out
@@ -1406,7 +1411,7 @@ class ConfigModal(ModalScreen):
self._matrix_status.update("Load skipped: please set both 'homeserver' and 'access_token' before loading rooms.")
return
except Exception:
pass
logger.exception("Failed to check matrix configuration before load")
if self._matrix_status:
self._matrix_status.update("Saving configuration before loading rooms…")
@@ -1437,7 +1442,7 @@ class ConfigModal(ModalScreen):
try:
debug(f"[matrix] Load rooms failed: {exc}\n{tb}")
except Exception:
pass
logger.exception("Failed to debug matrix load failure")
msg = str(exc) or "Matrix load failed"
if "auth" in msg.lower():
msg = msg + ". Please verify your access token and try again."
@@ -1453,14 +1458,14 @@ class ConfigModal(ModalScreen):
try:
self.notify(full_msg, severity="error", timeout=8)
except Exception:
pass
logger.exception("Failed to show Matrix load failure notification")
return
# Populate inline list
try:
self._render_matrix_rooms_inline(rooms)
except Exception:
pass
logger.exception("Failed to render inline matrix rooms")
# Persist cached rooms so they are available on next editor open
try:
@@ -1474,15 +1479,15 @@ class ConfigModal(ModalScreen):
try:
save_config(self.config_data)
except Exception:
pass
logger.exception("Failed to persist cached matrix rooms via save_config() fallback")
if self._matrix_status:
self._matrix_status.update(f"Loaded and cached {len(rooms)} room(s).")
try:
self.notify(f"Loaded {len(rooms)} rooms and cached the results", timeout=5)
except Exception:
pass
logger.exception("Failed to notify loaded-and-cached message for Matrix rooms")
except Exception:
pass
logger.exception("Failed to cache Matrix rooms after load")
def _open_matrix_room_picker(
self,
@@ -1522,15 +1527,15 @@ class ConfigModal(ModalScreen):
try:
save_config(self.config_data)
except Exception:
pass
logger.exception("Failed to persist cached matrix rooms via save_config() fallback")
if self._matrix_status:
self._matrix_status.update(f"Loaded {len(rooms)} rooms (cached)")
try:
self.notify(f"Loaded {len(rooms)} rooms and cached the results", timeout=5)
except Exception:
pass
logger.exception("Failed to notify loaded-and-cached message for Matrix rooms")
except Exception:
pass
logger.exception("Failed to cache Matrix rooms when inline view unavailable")
return
# Clear current entries
@@ -1549,7 +1554,7 @@ class ConfigModal(ModalScreen):
save_btn = self.query_one("#matrix-inline-save", Button)
save_btn.disabled = True
except Exception:
pass
logger.exception("Failed to disable matrix inline save button when no rooms returned")
return
any_selected = False
@@ -1597,7 +1602,7 @@ class ConfigModal(ModalScreen):
save_btn = self.query_one("#matrix-inline-save", Button)
save_btn.disabled = not any_selected
except Exception:
pass
logger.exception("Failed to set matrix inline save button disabled state")
def _resolve_matrix_rooms_by_ids(self, ids: Iterable[str]) -> List[Dict[str, Any]]:
"""
@@ -1628,7 +1633,7 @@ class ConfigModal(ModalScreen):
try:
debug(f"[config] failed to resolve matrix room names: {exc}")
except Exception:
pass
logger.exception("Failed to debug matrix name resolution")
return []
def on_matrix_rooms_selected(self, result: Any = None) -> None:
@@ -1683,7 +1688,7 @@ class ConfigModal(ModalScreen):
try:
self.query_one("#matrix-inline-save", Button).disabled = not any_selected
except Exception:
pass
logger.exception("Failed to update matrix inline save button")
def on_input_changed(self, event: Input.Changed) -> None:
if event.input.id:
@@ -1722,11 +1727,11 @@ class ConfigModal(ModalScreen):
try:
self.query_one("#config-db-path", Static).update(self._db_path)
except Exception:
pass
logger.exception("Failed to update config db path label")
try:
self.query_one("#config-last-save", Static).update("Last saved: (saving...)")
except Exception:
pass
logger.exception("Failed to update config last-save label")
log(f"ConfigModal scheduled save (changed={changed})")
return changed
@@ -1775,7 +1780,7 @@ class ConfigModal(ModalScreen):
try:
self.config_data = reload_config()
except Exception:
pass
logger.exception("Failed to reload config after save completion")
# Update last-saved label with file timestamp for visibility
db_mtime = None
@@ -1794,19 +1799,19 @@ class ConfigModal(ModalScreen):
try:
self.query_one("#config-last-save", Static).update(label_text)
except Exception:
pass
logger.exception("Failed to update last-save label with timestamp")
except Exception:
pass
logger.exception("Failed to compute last-save label text")
try:
self.refresh_view()
except Exception:
pass
logger.exception("Failed to refresh config editor view after save completion")
try:
self.notify(f"Configuration saved ({changed} change(s)) to {db.db_path.name}", timeout=5)
except Exception:
pass
logger.exception("Failed to show configuration saved notification")
else:
# No TUI available; log instead of updating UI
log(f"Configuration saved ({changed} change(s)) to {db.db_path.name}")
@@ -1818,17 +1823,17 @@ class ConfigModal(ModalScreen):
try:
self.notify(f"Save failed: {error}", severity="error", timeout=10)
except Exception:
pass
logger.exception("Failed to show save failed notification")
try:
self.config_data = reload_config()
except Exception:
pass
logger.exception("Failed to reload config after save failure")
try:
self.refresh_view()
except Exception:
pass
logger.exception("Failed to refresh view after save failure")
else:
log(f"Save failed: {error}")
@@ -1867,7 +1872,7 @@ class ConfigModal(ModalScreen):
if rk not in required_keys:
required_keys.append(rk)
except Exception:
pass
logger.exception("Failed to inspect provider class '%s' for required keys", item_name)
section = self.config_data.get("provider", {}).get(item_name, {})
elif item_type == "tool":
try:
@@ -1880,7 +1885,7 @@ class ConfigModal(ModalScreen):
if k and k not in required_keys:
required_keys.append(k)
except Exception:
pass
logger.exception("Failed to inspect tool module 'tool.%s' for required keys", item_name)
section = self.config_data.get("tool", {}).get(item_name, {})
# Check required keys

View File

@@ -630,7 +630,7 @@ class DownloadModal(ModalScreen):
f"Download failed: {error_reason}",
)
except Exception:
pass
logger.exception("Failed to finish worker during download failure handling")
# Also append detailed error info to worker stdout for visibility
if worker:
@@ -799,7 +799,7 @@ class DownloadModal(ModalScreen):
f"Download error: {str(e)}",
)
except Exception:
pass
logger.exception("Failed to finish worker during download error handling")
self.app.call_from_thread(self._hide_progress)
self.app.call_from_thread(self.dismiss)
return
@@ -1091,7 +1091,7 @@ class DownloadModal(ModalScreen):
try:
worker.finish("error", f"Download failed: {str(e)}")
except Exception:
pass
logger.exception("Failed to finish worker on download submit error")
self.app.call_from_thread(self._hide_progress)
self.app.call_from_thread(
self.app.notify,

View File

@@ -8,6 +8,8 @@ from textual.screen import ModalScreen
from textual.widgets import Static, Button, Checkbox, ListView, ListItem
from textual import work
from rich.text import Text
import logging
logger = logging.getLogger(__name__)
class MatrixRoomPicker(ModalScreen[List[str]]):
@@ -121,7 +123,7 @@ class MatrixRoomPicker(ModalScreen[List[str]]):
# Stop propagation so parent handlers (ConfigModal) don't react.
event.stop()
except Exception:
pass
logger.exception("Failed to stop ListView.Selected event propagation")
def _set_status(self, text: str) -> None:
if self._status_widget:
@@ -137,6 +139,7 @@ class MatrixRoomPicker(ModalScreen[List[str]]):
any_selected = True
break
except Exception:
logger.exception("Error querying checkbox in MatrixRoomPicker; skipping")
continue
if self._save_button:
self._save_button.disabled = not any_selected
@@ -214,7 +217,7 @@ class MatrixRoomPicker(ModalScreen[List[str]]):
cb = self.query_one(f"#{checkbox_id}", Checkbox)
cb.value = True
except Exception:
pass
logger.exception("Failed to set checkbox value in MatrixRoomPicker")
if self._save_button:
self._save_button.disabled = False
elif event.button.id == "matrix-room-clear":
@@ -223,7 +226,7 @@ class MatrixRoomPicker(ModalScreen[List[str]]):
cb = self.query_one(f"#{checkbox_id}", Checkbox)
cb.value = False
except Exception:
pass
logger.exception("Failed to set checkbox value to False in MatrixRoomPicker")
if self._save_button:
self._save_button.disabled = True
elif event.button.id == "matrix-room-save":
@@ -234,5 +237,5 @@ class MatrixRoomPicker(ModalScreen[List[str]]):
if cb.value and room_id:
selected.append(room_id)
except Exception:
pass
logger.exception("Failed to read checkbox state for '%s' while saving MatrixRoomPicker selection", checkbox_id)
self.dismiss(selected)

View File

@@ -501,7 +501,7 @@ class WorkersModal(ModalScreen):
try:
self.stdout_display.cursor_location = (len(combined_text) - 1, 0)
except Exception:
pass
logger.exception("Failed to set stdout_display cursor location")
logger.info("[workers-modal] Updated stdout display successfully")
except Exception as e:
logger.error(

View File

@@ -10,6 +10,7 @@ import contextlib
import io
import shlex
import sys
import traceback
from pathlib import Path
from dataclasses import dataclass, field
from typing import Any, Callable, Dict, List, Optional, Sequence
@@ -25,8 +26,9 @@ from SYS import pipeline as ctx
from CLI import ConfigLoader
from SYS.pipeline import PipelineExecutor
from SYS.worker import WorkerManagerRegistry
from SYS.logger import set_debug
from SYS.logger import set_debug, debug
from SYS.rich_display import capture_rich_output
import traceback
from SYS.result_table import Table
@@ -120,7 +122,7 @@ class PipelineRunner:
result.stderr = syntax_error.message
return result
except Exception:
pass
debug(traceback.format_exc())
try:
tokens = shlex.split(normalized)
@@ -137,11 +139,12 @@ class PipelineRunner:
try:
set_debug(bool(config.get("debug", False)))
except Exception:
pass
debug(traceback.format_exc())
try:
self._worker_manager = WorkerManagerRegistry.ensure(config)
except Exception:
debug(traceback.format_exc())
self._worker_manager = None
ctx.reset()
@@ -153,7 +156,7 @@ class PipelineRunner:
seeds = [seeds]
ctx.set_last_result_items_only(list(seeds))
except Exception:
pass
debug(traceback.format_exc())
stdout_buffer = io.StringIO()
stderr_buffer = io.StringIO()
@@ -173,7 +176,7 @@ class PipelineRunner:
try:
ctx.clear_current_command_text()
except Exception:
pass
debug(traceback.format_exc())
result.stdout = stdout_buffer.getvalue()
result.stderr = stderr_buffer.getvalue()
@@ -268,7 +271,7 @@ class PipelineRunner:
items_copy = items.copy() if isinstance(items, list) else list(items) if items else []
out.append((t, items_copy, subj))
except Exception:
pass
debug(traceback.format_exc())
return out
snap["result_table_history"] = _copy_history(state.result_table_history)
@@ -306,7 +309,7 @@ class PipelineRunner:
out.append((t, items_copy, subj))
setattr(state, key, out)
except Exception:
pass
debug(traceback.format_exc())
try:
if "live_progress" in snapshot: