Conversation
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
There was a problem hiding this comment.
Pull request overview
This PR introduces first-class Skills support: a backend skills service + REST API, React UI pages to manage skills and Git-synced skill repositories, and agent-level integration to expose skills via dynamic prompts and an in-process MCP session.
Changes:
- Add a skills service (
services/skills) that manages a state-dir-backed skills store and exposes an in-process MCP session + dynamic prompt. - Add Web UI skills management (list/search/create/edit/import/export, resources, git repo management) and wire new API endpoints.
- Extend agent/pool configuration to support per-agent “Enable Skills”, injecting the skills prompt and MCP tools when enabled.
Reviewed changes
Copilot reviewed 20 out of 21 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
webui/skills_handlers.go |
Adds the Skills + Git repo REST API handlers used by the React UI. |
webui/routes.go |
Registers the new Skills and Git repo API routes. |
webui/react-ui/src/utils/config.js |
Adds endpoint definitions for skills and git repos. |
webui/react-ui/src/utils/api.js |
Adds skillsApi client wrapper for the new endpoints. |
webui/react-ui/src/router.jsx |
Adds routes for Skills list and Skill editor pages. |
webui/react-ui/src/pages/Skills.jsx |
Implements the Skills management page and Git repo UI. |
webui/react-ui/src/pages/SkillEdit.jsx |
Implements create/edit form for a skill. |
webui/react-ui/src/App.jsx |
Adds “Skills” to the sidebar navigation. |
webui/options.go |
Allows wiring a SkillsService into the webui App config. |
services/skills/service.go |
Implements skills dir manager caching + shared in-process MCP session creation. |
services/skills/prompt.go |
Implements a dynamic prompt block that renders available skills as XML. |
core/state/pool.go |
Adds optional skills provider integration to inject prompt/MCP session when enabled. |
core/state/config.go |
Adds enable_skills to agent config + metadata for the UI. |
core/agent/options.go |
Adds WithMCPSession option for attaching pre-connected MCP sessions. |
core/agent/mcp.go |
Registers extra MCP sessions’ tools; avoids closing shared sessions. |
main.go |
Instantiates the skills service and passes it into pool + webui. |
README.md |
Documents built-in Skills and how to use/mount them. |
docker-compose.yaml |
Notes optional host mount for /pool/skills. |
Dockerfile.webui |
Updates Go builder image version used for building the webui binary. |
go.mod / go.sum |
Bumps/introduces dependencies (skillserver, MCP sdk, go-x libs, etc.). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| frontmatter := fmt.Sprintf("---\nname: %s\ndescription: %s\n", req.Name, req.Description) | ||
| if req.License != "" { | ||
| frontmatter += fmt.Sprintf("license: %s\n", req.License) | ||
| } | ||
| if req.Compatibility != "" { | ||
| frontmatter += fmt.Sprintf("compatibility: %s\n", req.Compatibility) | ||
| } |
There was a problem hiding this comment.
Frontmatter is constructed via string formatting with unescaped user input (name/description/license/compatibility/metadata). Newlines, colons, quotes, etc. can produce invalid YAML (or unintended structure), breaking skill parsing. Consider using a YAML encoder and/or quoting/sanitizing values.
core/agent/mcp.go
Outdated
| func (a *Agent) closeMCPServers() { | ||
| for _, s := range a.mcpSessions { | ||
| s.Close() | ||
| // Do not close shared sessions (e.g. in-process skills MCP) so other agents can keep using them | ||
| isExtra := false | ||
| for _, e := range a.options.extraMCPSessions { |
There was a problem hiding this comment.
closeMCPServers closes sessions but never clears a.mcpSessions. Since initMCPActions appends new sessions each time, the slice can grow unbounded and may repeatedly attempt to close old sessions (and duplicate extra sessions). Consider resetting a.mcpSessions after closing (while preserving shared sessions if needed).
services/skills/service.go
Outdated
| defer s.mu.Unlock() | ||
| s.manager = nil | ||
| s.mcpSrv = nil | ||
| s.session = nil |
There was a problem hiding this comment.
InvalidateManager drops references to the cached MCP session/server but doesn’t close the existing session (and may leave the in-process server goroutine running). This can leak resources and keep using stale managers; consider explicitly closing the prior session and stopping the server before nil’ing them out.
| defer s.mu.Unlock() | |
| s.manager = nil | |
| s.mcpSrv = nil | |
| s.session = nil | |
| // Capture current resources and clear cached references under lock | |
| oldManager := s.manager | |
| oldSrv := s.mcpSrv | |
| oldSession := s.session | |
| s.manager = nil | |
| s.mcpSrv = nil | |
| s.session = nil | |
| s.mu.Unlock() | |
| // Close session if it supports Close | |
| if oldSession != nil { | |
| if closer, ok := any(oldSession).(interface{ Close() error }); ok { | |
| _ = closer.Close() | |
| } | |
| } | |
| // Stop/close server if it supports Close | |
| if oldSrv != nil { | |
| if closer, ok := any(oldSrv).(interface{ Close() error }); ok { | |
| _ = closer.Close() | |
| } | |
| } | |
| // Close manager if it supports Close | |
| if oldManager != nil { | |
| if closer, ok := any(oldManager).(interface{ Close() error }); ok { | |
| _ = closer.Close() | |
| } | |
| } |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
a4fa485 to
3174b84
Compare
This pull request introduces built-in Skills management to LocalAGI, enabling agents to use reusable skills that can be managed, imported, exported, and synced via git from the Web UI. The changes add support for skills as a first-class feature, update documentation and configuration, and allow agents to receive skills context and tools when enabled. Additionally, the Go version is updated to 1.26, and several dependencies are upgraded.
Skills Management Integration
SkillsProviderinterface and integrated skills prompt and MCP session injection into agent startup logic incore/state/pool.go, allowing agents to use skills when enabled. [1] [2] [3] [4] [5] [6] [7]enable_skills(checkbox),skills_prompt(textarea), and corresponding metadata incore/state/config.go. [1] [2] [3]MCP Session Handling
WithMCPSessionoption and integrated them in agent initialization and cleanup logic. [1] [2] [3] [4]Dependency and Platform Updates
github.com/modelcontextprotocol/go-sdkto v1.2.0 and other indirect dependencies for skills and git integration. [1] [2] [3] [4] [5]