Conversation
Two fixes: 1. _lazy_registry_static.py: update JLCSearchTool and DigiKeyTool mappings to their new location (tooluniverse.circuit.*) after the circuit tools were moved to the sub-package. 2. tool_registry.py: call _auto_import_subpackages() even when the static registry is loaded. Previously it returned early, so installed sub-packages (e.g. tooluniverse[circuit]) were never imported and their _list_config_registry entries were never populated.
Add _discover_entry_point_plugins() that finds installed packages in the tooluniverse.plugins entry point group, imports their .py tool files so @register_tool decorators fire, and loads their JSON configs into _list_config_registry. Call it in both code paths of build_lazy_registry() (static registry and AST discovery), so external plugins are always loaded at startup regardless of the lazy registry strategy used. Remove stale _lazy_registry_static.py entries for DigiKeyTool and JLCSearchTool (now auto-loaded via the circuit plugin entry point). This enables a simple, flat plugin package structure that mirrors the local ~/.tooluniverse/ workspace layout — making it trivial for users to create tool packages and share them on GitHub.
Add _discovered_plugin_names set and per-plugin guard so that calling _discover_entry_point_plugins() more than once (e.g. in tests or if build_lazy_registry() is invoked directly) does not append duplicate configs to _list_config_registry.
_discover_entry_point_plugins() was only called from build_lazy_registry() (the lazy path). The eager path in auto_discover_tools(lazy=False) never called it, so plugin tools were silently missing when: - TOOLUNIVERSE_LAZY_LOADING=false env var is set - force_full_discovery() is called explicitly - get_tool_class_lazy() fallback triggers pkgutil.iter_modules() only finds modules in the tooluniverse.* namespace, so entry-point plugin packages (tooluniverse_circuit, etc.) are invisible to it. Add an explicit _discover_entry_point_plugins() call at the end of the eager discovery loop, before setting _discovery_completed=True. The idempotency guard in _discover_entry_point_plugins() (added in previous commit) ensures this is safe: if plugins were already loaded via the lazy path first (e.g. frozen-env fallback), the second call is a no-op.
space.yaml is the standard "identity file" for any tool pack, whether it lives in ~/.tooluniverse/ or inside an installed plugin package. The system now reads it automatically in both places: - _read_space_yaml(): new helper that reads space.yaml from a directory, logs the pack name/description at INFO, and warns about missing required_env variables (e.g. DIGIKEY_CLIENT_ID not set). - _discover_entry_point_plugins(): calls _read_space_yaml() for each plugin directory before importing tool files. - _get_user_tool_files(): calls _read_space_yaml() for each workspace root directory before scanning for .py/.json files. tools.include_tool_types in space.yaml is intentionally NOT applied automatically — it remains a user-facing filter used only when explicitly loading a space via load_space() / --load.
- Default workspace is now ./.tooluniverse (local mode) instead of dual-scan - Add use_global=True to use ~/.tooluniverse as workspace default - Workspace space.yaml auto-applied at startup when no explicit space= given - When --load is used, workspace space.yaml acts as base config; loaded yaml deep-merges on top (override wins for same keys) - Add --global CLI flag to all 3 parsers (run_http_server, run_stdio_server, run_smcp_server); propagated through SMCP to ToolUniverse - Update test: _workspace_dir is no longer None by default - Fix test state pollution: add type field to registered test tool configs
- Remove circuit tools from main package (digikey_tool.py, jlcsearch_tool.py, data/digikey_tools.json, data/jlcsearch_tools.json) — moved to tooluniverse-circuit - Space system: SpaceLoader.resolve_to_local_dir(), get_tool_files_from_dir(), _deep_merge(), _resolve_extends(); validator schema additions (sources, workspace, package fields) - Plugin entry point discovery via tooluniverse.plugins group - Add BVBRC, CoL, EOL, FlyBase, HumanMine, LNCipedia, LOTUS, MSigDB, Pfam, PubChemTox, SASBDB, ZFIN, miRBase tools - Update tool metadata and space validator - Update tests for space loader, validator, and toolspace integration
# Conflicts: # src/tooluniverse/_lazy_registry_static.py # src/tooluniverse/default_config.py # src/tooluniverse/tools/.tool_metadata.json # src/tooluniverse/tools/BVBRC_search_taxonomy.py # src/tooluniverse/tools/BioTools_get_tool.py # src/tooluniverse/tools/IdentifiersOrg_resolve.py # src/tooluniverse/tools/SASBDB_get_scattering_profile.py # src/tooluniverse/tools/__init__.py
- Replace 11 example YAML files with single life-science.yaml covering all life science and general-purpose tool categories - Add default_space.yaml with sensible defaults - Consolidate workspace + space docs into toolspace.rst; update index.rst - Fix validator bug: run schema validation before fill_defaults() so missing required fields (name) are caught instead of silently injected - Remove version from required fields (optional, defaults to "1.0.0") - Fix _resolve_workspace(): raise clear ValueError when path is an existing file instead of crashing with bare FileExistsError - Add tests/test_robustness.py with 62 adversarial tests covering bad YAML, wrong workspace structure, bad API calls, and contradictory configs - Add tests/test_workspace_and_space.py for workspace and space loading - Update tool metadata, UniProt_get_proteome, OpenMeteo_get_air_quality
Revert .tool_metadata.json, OpenMeteo_get_air_quality.py, UniProt_get_proteome.py, and __init__.py to their origin/main content, undoing unintended changes introduced during the merge.
…ls() - _load_auto_discovered_configs(): skip configs already present in all_tools so repeated load_tools() calls don't accumulate duplicates - load_tools(): clear all_tools/all_tool_dict/tool_category_dicts at the start of a full reload (include_tools=None) so calling it multiple times is safe and efficient - refresh_tools(): implement as a clean reload (was a no-op TODO stub); picks up new JSON/Python tool files added to workspace since startup; add docstring noting that built-in package tools still need a restart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.