Skip to content

feat: add tools for agent skills#206

Open
kyteinsky wants to merge 2 commits into
mainfrom
feat/skills
Open

feat: add tools for agent skills#206
kyteinsky wants to merge 2 commits into
mainfrom
feat/skills

Conversation

@kyteinsky

@kyteinsky kyteinsky commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

required: nextcloud/assistant#594
resolves: #170

In the admin's filesystem:

image image image image

After adding the global skills from alice's filesystem:

image image image image

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI

Signed-off-by: kyteinsky <kyteinsky@gmail.com>
Assisted-by: Github Copilot: claude-opus-4-7
Signed-off-by: kyteinsky <kyteinsky@gmail.com>
Assisted-by: Github Copilot: claude-opus-4-6
Assisted-by: Github Copilot: qwen-35b-3-6
Comment thread ex_app/lib/tools.py
# tool files during development requires a process restart, which is fine.
qualified = f'ex_app.lib.all_tools.{module_name}'
module = importlib.import_module(qualified)
spec = module.__spec__

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice one!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds “skills” support to the Context Agent by introducing tools to load/store user skills from the Assistant app, and wiring the available skills list into the agent system prompt so the model can decide when to fetch skill bodies.

Changes:

  • Switch tool-module loading to canonical package imports (intended to share module state via sys.modules).
  • Add a new Skills tool module with load_skill / store_skill and a cached list_skills_metadata.
  • Extend the agent system prompt generation to include available skills and memory-loading guidance.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
ex_app/lib/tools.py Changes dynamic tool module loading strategy to use canonical imports.
ex_app/lib/all_tools/skills.py Introduces skills endpoints integration and exposes load/store tools.
ex_app/lib/all_tools/lib/decorator.py Adds cache invalidation support to timed_memoize for per-user caches.
ex_app/lib/agent.py Injects available skills list and skill tool guidance into the system prompt.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ex_app/lib/tools.py
Comment on lines +88 to +92
# SAME module object as the one we load here. Trade-off: hot-reloading
# tool files during development requires a process restart, which is fine.
qualified = f'ex_app.lib.all_tools.{module_name}'
module = importlib.import_module(qualified)
spec = module.__spec__
Comment on lines +25 to +28
# skills are cached in the Assistant side for 24 hours backed by etags
# this cache interval is only a delay in cases where the skill is manually
# updated or added in the filesystem
SKILLS_CACHE_TTL = 5 * 60
from nc_py_api import AsyncNextcloudApp
from nc_py_api._exceptions import NextcloudExceptionNotFound

from ex_app.lib.all_tools.lib.decorator import safe_tool, timed_memoize
Comment on lines +104 to +105
@tool
async def store_skill(skill_name: str, description: str, content: str):
Comment thread ex_app/lib/agent.py
Comment on lines 152 to +154
if task['input'].get('memories', None) is not None and task['input'].get('memories', None) is not []:
system_prompt_text += "You can remember things from other conversations with the user. If relevant, take into account the following memories:\n\n" + "\n".join(task['input']['memories']) + "\n\n"
if tool_enabled("load_memory"):
Comment thread ex_app/lib/agent.py
if task['input'].get('memories', None) is not None and task['input'].get('memories', None) is not []:
system_prompt_text += "You can remember things from other conversations with the user. If relevant, take into account the following memories:\n\n" + "\n".join(task['input']['memories']) + "\n\n"
if tool_enabled("load_memory"):
system_prompt_text += "In addition to the above memories, there are also long-term memories stored on-demand from other conversations. List and load those memories if they are not present here and the user or the conversation points to something that should be rememebered.\n"
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.

Add support for skills

3 participants