updating and refining plugin system refactor
This commit is contained in:
@@ -22,10 +22,10 @@ from SYS.config import (
|
||||
from SYS.database import db
|
||||
from SYS.logger import log, debug
|
||||
from SYS.plugin_config import (
|
||||
build_default_provider_config,
|
||||
build_default_plugin_config,
|
||||
build_default_store_config,
|
||||
build_default_tool_config,
|
||||
get_configurable_provider_types,
|
||||
get_configurable_plugin_types,
|
||||
get_configurable_store_types,
|
||||
get_configurable_tool_types,
|
||||
get_global_schema,
|
||||
@@ -161,7 +161,7 @@ class ConfigModal(ModalScreen):
|
||||
# Load config from the workspace root (parent of SYS)
|
||||
self.config_data = load_config()
|
||||
self.current_category = "globals"
|
||||
self.editing_item_type = None # 'store' or 'provider'
|
||||
self.editing_item_type = None # 'store' or 'plugin'
|
||||
self.editing_item_name = None
|
||||
self._button_id_map = {}
|
||||
self._provider_button_map: Dict[str, tuple[str, str]] = {}
|
||||
@@ -598,14 +598,14 @@ class ConfigModal(ModalScreen):
|
||||
row.mount(Button("Paste", id=f"paste-{inp_id}", classes="paste-btn"))
|
||||
idx += 1
|
||||
|
||||
if item_type == "provider" and isinstance(item_name, str):
|
||||
provider = self._instantiate_provider_for_editor(item_name, self.config_data)
|
||||
if item_type == "plugin" and isinstance(item_name, str):
|
||||
provider = self._instantiate_plugin_for_editor(item_name, self.config_data)
|
||||
if provider is not None:
|
||||
provider_actions = provider.config_actions() or []
|
||||
if provider_actions:
|
||||
container.mount(Rule())
|
||||
container.mount(Label(f"{provider.label} helpers", classes="config-label"))
|
||||
helper_text = str(provider.config_helper_text() or "Use these helpers to validate provider settings.").strip()
|
||||
helper_text = str(provider.config_helper_text() or "Use these helpers to validate plugin settings.").strip()
|
||||
status = Static(helper_text, id="provider-status")
|
||||
container.mount(status)
|
||||
self._provider_status = status
|
||||
@@ -626,7 +626,7 @@ class ConfigModal(ModalScreen):
|
||||
)
|
||||
|
||||
if (
|
||||
item_type == "provider"
|
||||
item_type == "plugin"
|
||||
and isinstance(item_name, str)
|
||||
and item_name.strip().lower() == "matrix"
|
||||
):
|
||||
@@ -870,12 +870,12 @@ class ConfigModal(ModalScreen):
|
||||
self.refresh_view()
|
||||
elif bid in self._provider_button_map:
|
||||
provider_name, action_id = self._provider_button_map[bid]
|
||||
self._request_provider_action(provider_name, action_id)
|
||||
self._request_plugin_action(provider_name, action_id)
|
||||
elif bid == "add-store-btn":
|
||||
options = get_configurable_store_types()
|
||||
self.app.push_screen(SelectionModal("Select Store Type", options), callback=self.on_store_type_selected)
|
||||
elif bid == "add-provider-btn":
|
||||
options = get_configurable_provider_types()
|
||||
options = get_configurable_plugin_types()
|
||||
self.app.push_screen(SelectionModal("Select Plugin Type", options), callback=self.on_provider_type_selected)
|
||||
elif bid == "add-tool-btn":
|
||||
options = get_configurable_tool_types() or ["ytdlp"]
|
||||
@@ -971,46 +971,46 @@ class ConfigModal(ModalScreen):
|
||||
else:
|
||||
self.notify("Clipboard not supported in this terminal", severity="warning")
|
||||
|
||||
def _instantiate_provider_for_editor(self, provider_name: str, config_data: Optional[Dict[str, Any]] = None) -> Optional[Any]:
|
||||
def _instantiate_plugin_for_editor(self, provider_name: str, config_data: Optional[Dict[str, Any]] = None) -> Optional[Any]:
|
||||
try:
|
||||
provider_class = get_plugin_class(provider_name)
|
||||
plugin_class = get_plugin_class(provider_name)
|
||||
except Exception:
|
||||
provider_class = None
|
||||
if provider_class is None:
|
||||
plugin_class = None
|
||||
if plugin_class is None:
|
||||
return None
|
||||
try:
|
||||
return provider_class(config_data or self.config_data)
|
||||
return plugin_class(config_data or self.config_data)
|
||||
except Exception:
|
||||
logger.exception("Failed to instantiate provider '%s' for config helper", provider_name)
|
||||
logger.exception("Failed to instantiate plugin '%s' for config helper", provider_name)
|
||||
return None
|
||||
|
||||
def _request_provider_action(self, provider_name: str, action_id: str) -> None:
|
||||
def _request_plugin_action(self, provider_name: str, action_id: str) -> None:
|
||||
if self._provider_action_running:
|
||||
return
|
||||
self._synchronize_inputs_to_config()
|
||||
self._provider_action_running = True
|
||||
if self._provider_status is not None:
|
||||
self._provider_status.update(f"Running {action_id.replace('_', ' ')}…")
|
||||
self._provider_action_background(provider_name, action_id, deepcopy(self.config_data))
|
||||
self._plugin_action_background(provider_name, action_id, deepcopy(self.config_data))
|
||||
|
||||
@work(thread=True)
|
||||
def _provider_action_background(self, provider_name: str, action_id: str, config_snapshot: Dict[str, Any]) -> None:
|
||||
def _plugin_action_background(self, provider_name: str, action_id: str, config_snapshot: Dict[str, Any]) -> None:
|
||||
try:
|
||||
provider = self._instantiate_provider_for_editor(provider_name, config_snapshot)
|
||||
provider = self._instantiate_plugin_for_editor(provider_name, config_snapshot)
|
||||
if provider is None:
|
||||
raise RuntimeError(f"Provider '{provider_name}' is unavailable")
|
||||
raise RuntimeError(f"Plugin '{provider_name}' is unavailable")
|
||||
result = provider.run_config_action(action_id)
|
||||
if not isinstance(result, dict):
|
||||
result = {"ok": False, "message": f"Provider '{provider_name}' returned an invalid config action result."}
|
||||
result = {"ok": False, "message": f"Plugin '{provider_name}' returned an invalid config action result."}
|
||||
except Exception as exc:
|
||||
result = {"ok": False, "message": str(exc) or f"Provider action '{action_id}' failed."}
|
||||
result = {"ok": False, "message": str(exc) or f"Plugin action '{action_id}' failed."}
|
||||
|
||||
try:
|
||||
self.app.call_from_thread(self._provider_action_complete, provider_name, action_id, result)
|
||||
self.app.call_from_thread(self._plugin_action_complete, provider_name, action_id, result)
|
||||
except Exception:
|
||||
self._provider_action_complete(provider_name, action_id, result)
|
||||
self._plugin_action_complete(provider_name, action_id, result)
|
||||
|
||||
def _provider_action_complete(self, provider_name: str, action_id: str, result: Dict[str, Any]) -> None:
|
||||
def _plugin_action_complete(self, provider_name: str, action_id: str, result: Dict[str, Any]) -> None:
|
||||
self._provider_action_running = False
|
||||
ok = bool(result.get("ok"))
|
||||
message = str(result.get("message") or f"Provider action '{action_id}' finished.")
|
||||
@@ -1075,11 +1075,11 @@ class ConfigModal(ModalScreen):
|
||||
if "provider" not in self.config_data:
|
||||
self.config_data["provider"] = {}
|
||||
|
||||
# For providers, they are usually top-level entries in 'provider' dict
|
||||
# Plugins are configured under the top-level 'provider' dict for now.
|
||||
if ptype not in self.config_data["provider"]:
|
||||
self.config_data["provider"][ptype] = build_default_provider_config(ptype)
|
||||
self.config_data["provider"][ptype] = build_default_plugin_config(ptype)
|
||||
|
||||
self.editing_item_type = "provider"
|
||||
self.editing_item_type = "plugin"
|
||||
self.editing_item_name = ptype
|
||||
self.refresh_view()
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import asyncio
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
from SYS.config import load_config, resolve_output_dir
|
||||
from SYS.result_table import Table
|
||||
from ProviderCore.registry import get_search_plugin
|
||||
from ProviderCore.registry import get_plugin_with_capability
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -174,7 +174,7 @@ class SearchModal(ModalScreen):
|
||||
self.current_worker.log_step(f"Connecting to {source}...")
|
||||
|
||||
try:
|
||||
provider = get_search_plugin(source)
|
||||
provider = get_plugin_with_capability(source, "search")
|
||||
if not provider:
|
||||
logger.error(f"[search-modal] Provider not available: {source}")
|
||||
if self.current_worker:
|
||||
@@ -380,7 +380,7 @@ class SearchModal(ModalScreen):
|
||||
config = load_config()
|
||||
output_dir = resolve_output_dir(config)
|
||||
|
||||
provider = get_search_plugin("openlibrary", config=config)
|
||||
provider = get_plugin_with_capability("openlibrary", "search", config=config)
|
||||
if not provider:
|
||||
logger.error("[search-modal] Provider not available: openlibrary")
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user