-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Experimental Plugin System #3998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: Deluan <deluan@navidrome.org>
Introduced a plugin manager that scans the plugins folder for subdirectories containing plugin.wasm files and auto-registers them as agents using the directory name as the unique agent name. Updated the configuration to support plugins with enabled/folder options, and ensured the plugin manager is started as a concurrent task during server startup. The wasmAgent now returns the plugin directory name for AgentName, ensuring each plugin agent is uniquely identifiable. This enables dynamic plugin discovery and integration with the agents orchestrator.
Added a Ginkgo v2 suite bootstrap (plugins_suite_test.go) for the plugins package and a test (manager_test.go) to verify that plugins in the testdata folder are auto-registered and can be loaded as agents. The test uses a mock DataStore and asserts that the agent is registered and its AgentName matches the plugin directory. Updated go.mod and go.sum for wazero dependency required by plugin WASM support.
… running suite; add real-plugin Ginkgo tests. Add BeforeSuite to plugins suite to build plugins/testdata/agent/plugin.wasm using Go WASI build command, matching README instructions. Remove plugin.wasm before build to guarantee a clean build. Add full real-plugin Ginkgo/Gomega tests for wasmAgent, covering all methods and error cases. Fix manager_test.go to use pointer to Manager. This ensures plugin tests are always run against a freshly compiled WASM binary, increasing reliability and reproducibility. Signed-off-by: Deluan <deluan@navidrome.org>
…plugins Signed-off-by: Deluan <deluan@navidrome.org>
…source management Signed-off-by: Deluan <deluan@navidrome.org>
…tions Signed-off-by: Deluan <deluan@navidrome.org>
…SM plugins Also add a sample Wikimedia plugin Signed-off-by: Deluan <deluan@navidrome.org>
Signed-off-by: Deluan <deluan@navidrome.org>
Standardized error creation using 'errors.New' where formatting was not needed. Introduced a constant for HTTP request timeouts. Removed commented-out log statement. Improved code comments for clarity and accuracy.
…nses Introduced a single SPARQLResult struct to represent all possible SPARQL response fields (sitelink, wiki, comment, img). Added a parseSPARQLResult helper to unmarshal and check for empty results, simplifying all fetch functions and improving type safety and maintainability.
Signed-off-by: Deluan <deluan@navidrome.org>
Implemented background WASM plugin compilation with concurrency limits, proper closure capture, and global compilation cache to avoid data races. Added debug and warning logs for plugin compilation results, including elapsed time. Ensured plugin registration is correct and all tests pass.
Changed agent instantiation to be fully lazy. The Agents struct now stores agent names in order and only instantiates each agent on first use, caching the result. This preserves agent call order, improves server startup time, and ensures thread safety. Updated all agent methods and tests to use the new pattern. No changes to agent registration or interface. All tests pass.
Introduced runtime.AddCleanup to guarantee that the Close method of WASM plugin instances is called, even if they are garbage collected from the sync.Pool. Modified the sync.Pool.New function in manager.go to register a cleanup function for each loaded instance that implements Close. Updated agent.go to handle the pooledInstance wrapper containing the instance and its cleanup handle. Ensured cleanup.Stop() is called before explicitly closing an instance (on error or agent shutdown) to prevent double closing. This fixes a potential resource leak where instances could be GC'd from the pool without proper cleanup.
Refactored plugins/manager.go and plugins/agent.go to improve readability and reduce function length. Extracted pool initialization logic into newPluginPool and background compilation/agent factory logic into precompilePlugin/createAgentFactory in manager.go. Extracted pool retrieval/validation and cleanup function creation into getValidPooledInstance/createPoolCleanupFunc in agent.go. Signed-off-by: Deluan <deluan@navidrome.org>
Signed-off-by: Deluan <deluan@navidrome.org>
…quests Signed-off-by: Deluan <deluan@navidrome.org>
Signed-off-by: Deluan <deluan@navidrome.org>
…etAlbumInfo and GetAlbumImages methods Signed-off-by: Deluan <deluan@navidrome.org>
…ng wasmBasePlugin Signed-off-by: Deluan <deluan@navidrome.org>
…aService in plugin manager Signed-off-by: Deluan <deluan@navidrome.org>
…recompilation support Signed-off-by: Deluan <deluan@navidrome.org>
…r improved service handling Signed-off-by: Deluan <deluan@navidrome.org>
Signed-off-by: Deluan <deluan@navidrome.org>
…tency Signed-off-by: Deluan <deluan@navidrome.org>
…ent factory creation Signed-off-by: Deluan <deluan@navidrome.org>
Signed-off-by: Deluan <deluan@navidrome.org>
… synchronization Signed-off-by: Deluan <deluan@navidrome.org>
…ervice Signed-off-by: Deluan <deluan@navidrome.org>
… each service Signed-off-by: Deluan <deluan@navidrome.org>
Signed-off-by: Deluan <deluan@navidrome.org>
…che parameter Signed-off-by: Deluan <deluan@navidrome.org>
…c configuration Signed-off-by: Deluan <deluan@navidrome.org>
…creation speed Signed-off-by: Deluan <deluan@navidrome.org>
…r clarity Signed-off-by: Deluan <deluan@navidrome.org>
…r reporting Signed-off-by: Deluan <deluan@navidrome.org>
…e plugin Signed-off-by: Deluan <deluan@navidrome.org>
…improvements Signed-off-by: Deluan <deluan@navidrome.org>
/gemini review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a substantial and well-designed plugin system. The architecture leverages WASM for security and uses Protocol Buffers for communication, which is a solid approach. The new CLI commands for plugin management are comprehensive. Core components like agents and scrobblers have been thoughtfully refactored to support these plugin extensions.
The permission system is a highlight, enforcing security by default and requiring explicit declarations from plugins. The documentation in plugins/README.md
is excellent and will be invaluable for developers looking to create plugins.
I've identified a few areas for minor improvement, primarily concerning error handling in the CLI and ensuring clarity in certain plugin interaction patterns. The critical fix in log/redactrus.go
is a good catch.
Overall, this is a strong foundation for extending Navidrome's capabilities.
…tion handling Signed-off-by: Deluan <deluan@navidrome.org>
…rformance Signed-off-by: Deluan <deluan@navidrome.org>
Signed-off-by: Deluan <deluan@navidrome.org>
…o avoid flakiness Signed-off-by: Deluan <deluan@navidrome.org>
…ed error handling Signed-off-by: Deluan <deluan@navidrome.org>
Signed-off-by: Deluan <deluan@navidrome.org>
Signed-off-by: Deluan <deluan@navidrome.org>
…settings Signed-off-by: Deluan <deluan@navidrome.org>
…igurable TTL Signed-off-by: Deluan <deluan@navidrome.org>
@deluan This sounds very interesting, thank you! Is it possible with the plugin functionalities of 0.57.0 to create a plugin that ingests the user and album rating tags from the files into the navidrome db? Until now I've added this functionality to my build in a hacky way but this could be a much better way to implement it. |
You can already do that, by using Custom tags These tags can then be used in Smart Playlists |
I assume custom tags would not be able to show up in the UI as star ratings though, or am I misunderstanding them? |
They can only be used in smart playlists and be shown in the "Raw Tags" tab in the Album/Song Get Info dialog. If you want to map the rating tag to the Navidrome's 5-star rating, then yes, a plugin would be the way to go. |
🧩 Experimental Plugin System for Navidrome
This PR introduces an experimental WebAssembly-based plugin system that allows extending Navidrome's functionality without modifying the core codebase.
Key Features
Plugin Management
Configuration
Example Plugins Included
Security
Status
Documentation
https://github.com/navidrome/navidrome/blob/master/plugins/README.md
Currently this system enables custom metadata sources, and specialized scrobblers, but the functionality will be expanded in future versions.