Skip to content

feat: Unified Plugin System & Memory Plugin PoC#998

Open
3clyp50 wants to merge 16 commits intoagent0ai:developmentfrom
3clyp50:pluginsystem
Open

feat: Unified Plugin System & Memory Plugin PoC#998
3clyp50 wants to merge 16 commits intoagent0ai:developmentfrom
3clyp50:pluginsystem

Conversation

@3clyp50
Copy link
Contributor

@3clyp50 3clyp50 commented Feb 7, 2026

  • Convention-over-configuration: runtime capability discovery relies on directory layout.

  • Direct imports: plugin code uses standard Python imports.

  • Full backend decoupling: memory APIs, tools, and extensions now live in plugins/memory/; core interacts through conventions and extension calls.

  • Python extension convention update: plugin lifecycle extensions are under extensions/python/<point>/ (not extensions/backend/).

  • WebUI extension system: frontend switched from plugins.js/meta-target injection to x-extension breakpoints resolved by webui/js/extensions.js.

  • WebUI extension API: /api/load_webui_extensions provides filtered extension assets by extension point.

  • Alpine placement directives baseline: x-move-* directives in initFw.js are documented as the standard baseline for HTML UI extensions together with root x-data.

  • Plugin UI split:

    • Hook contributions: plugins/<id>/extensions/webui/<extension_point>/...
    • Full plugin pages/components: plugins/<id>/webui/...

@frdel commits

3918133cbf316296b312cd4cbed9592c4261cb95 - "plugins - frontend PoC"

  • python/api/load_webui_extensions.py and webui/js/extensions.js alignment.
  • Added first x-extension insertion points in core UI.
  • Established plugin-owned WebUI assets under plugins/<id>/webui/... and hook assets under plugins/<id>/extensions/webui/....

3bfdf91637b8b5053c2441f24a785ac82283a676 - "Support webui JS/HTML extensions and plugin paths"

  • Consolidated extension loading in webui/js/extensions.js.
  • Added JS hook execution in message rendering flow (set_messages_before_loop, set_messages_after_loop).
  • Added file filtering support to /api/load_webui_extensions and plugin helper scanning.
  • Standardized lifecycle extension path at extensions/python/....

39a81d0d5d145de4299fb69e7e1adbabbeb96f33 - "Refactor memory imports; add Alpine move directives"

  • Added Alpine move directives (x-move-*) in webui/js/initFw.js for precise plugin placement.
  • Moved memory quick-action extension from sidebar-quick-actions-main-2 to sidebar-quick-actions-main-start.
  • Updated quick-actions breakpoints and cleaned obsolete insertion IDs.
  • Refactored memory imports/tools for cleaner plugin-local imports.

Architectural Decisions & Divergences

Python vs WebUI Extension Split

Decision: separate extension concerns into:

  • extensions/python/<point>/... for lifecycle/backend hooks
  • extensions/webui/<point>/... for frontend hook contributions
    Rationale: clear runtime boundaries and simpler scanning logic per environment.

Frontend Breakpoints (x-extension)

Decision: core UI defines explicit insertion breakpoints, plugins contribute HTML/JS by extension point.
Status: implemented and functional. Documentation sets a stricter baseline for HTML contributions (x-data + required explicit x-move-*).

Remaining: Core-to-Plugin Decoupling

Memory-related settings fields and memory settings tab still exist in core configuration/UI. Plugin-specific settings?

@3clyp50 3clyp50 force-pushed the pluginsystem branch 5 times, most recently from 05960f0 to c70a234 Compare February 11, 2026 01:08
@3clyp50
Copy link
Contributor Author

3clyp50 commented Feb 11, 2026

Updated and rebased to v0.9.8

Priority: project plugins > usr plugins > core plugins
"""
# Project-specific plugins
projects = files.find_existing_paths_by_pattern("usr/projects/*/.a0proj/plugins")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment out for now, we can add project/agent plugins later

name: str
path: Path
manifest_path: Path
provides: Dict[str, Any] = field(default_factory=dict) # capability map
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this

paths: List[str] = []

for plugin in list_plugins():
cap_config = plugin.provides.get(cap_type)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove

return str(Path(module_path).parent)


def get_plugin_paths(cap_type: str, *subpaths: str) -> List[str]:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only leave subpaths

if not cap_config:
continue

# Normalize to list for uniform processing
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code is too complex, it should simply find existing paths under plugin roots:

get_plugin_paths("extensions")
returns:
/plugins/plugin1/extensions
/usr/plugins/plugin2/extensions
etc...

We just need to do is files.find_existing_paths_by_pattern with plugin roots.

@@ -1,215 +1,8 @@
import asyncio
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This extension should no longer exist in the core, it should only exist in the plugin.

@@ -1,198 +1,8 @@
import asyncio
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This extension should no longer exist in the core, it should only exist in the plugin.

@@ -1,201 +1,8 @@
import asyncio
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This extension should no longer exist in the core, it should only exist in the plugin.

@@ -1,13 +1,8 @@
from python.helpers.extension import Extension
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This extension should no longer exist in the core, it should only exist in the plugin.

@@ -1,7 +1,10 @@
from datetime import datetime
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep behaviour prompt ouside of memory plugin, it's not related to memory except for the file placement.
We will make behaviour adjustment a standalone plugin as it has a tool, extension, prompt and a file.

3clyp50 and others added 3 commits February 14, 2026 17:05
plugin manifest update
add memory plugin PoC files
offload memory prompts
cleanup imports
extract memory UI
fix paths
plugin docs
update agent plugin refs

rm plugin system spec

restore subagents.py
@3clyp50

This comment was marked as outdated.

frdel and others added 6 commits February 16, 2026 20:01
Add full support for loading web UI extensions from plugins: - Frontend: new extensions loader (js/extensions.js) that loads and caches JS and HTML extensions, calls JS hooks, imports HTML as <x-component> tags, normalizes paths, and replaces the old plugins.js auto-inject logic. - Messages: make setMessages async, introduce extension hooks (set_messages_before_loop / after_loop) and integrate JS extension calls; adjust Scroller usage accordingly. - Components: fix x-component path handling in several templates and components import logic. - Backend: add filters to /api/load_webui_extensions and pass them to plugin helper; update helpers to look for plugin extensions under extensions/python instead of backend. - Plugins helper: extend get_webui_extensions to accept file glob filters, dedupe matches, return relative paths, and improve error logging. - Project config: include plugins and usr/plugins JS files in jsconfig.json. - Add a small test extension file and move several plugin extension files from backend/ to python/ directories. - Minor: reset error_retries earlier in agent message loop to avoid stale retry counts.

These changes enable a flexible plugin extension system for both JS and HTML assets, improve caching and path normalization, and wire up backend APIs and helpers to support the new structure.
Cleanup and refactor memory plugin imports to use plugins.memory.helpers.memory directly (remove sys.path hacks) and adjust related tools (memory_load, memory_save, memory_delete, memory_forget). Move the memory quick-action entry to a new start extension file and update quick-actions HTML to remove obsolete extension points and rename the dropdown end id. Update JS extension caller to forward multiple arguments (rest params) and add several Alpine directives (move-to-start, move-to-end, move-to, move-before, move-after) plus selector helpers to support dynamic element repositioning. Also removed an unused python/__init__.py and minor whitespace/comment cleanups.
Worth discussing: in memory-entry.html I had issues with x-move-to usage. The visual aspect is different than moving the element after the same target with x-move-after.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants