Skip to content

feat: add context agent skills endpoints and admin settings#594

Open
kyteinsky wants to merge 3 commits into
mainfrom
feat/context-agent-skills
Open

feat: add context agent skills endpoints and admin settings#594
kyteinsky wants to merge 3 commits into
mainfrom
feat/context-agent-skills

Conversation

@kyteinsky

@kyteinsky kyteinsky commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

related: nextcloud/context_agent#206

The folder selection dialog lists the current admin's files. Once selected, the path and the user id are stored. This screenshot is when the admin user was logged in and the folder was set from alice's filesystem.

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-sonnet-4-6
Signed-off-by: kyteinsky <kyteinsky@gmail.com>
Assisted-by: Github Copilot: claude-opus-4-7
Signed-off-by: kyteinsky <kyteinsky@gmail.com>

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

This PR introduces “agent skills” management to the Assistant app: users can store and retrieve skills as folder-based SKILL.md files, and admins can optionally configure a global skills folder that becomes available to all users (in addition to personal skills).

Changes:

  • Added an admin UI section to configure/clear a global agent skills folder (stored as admin uid + path).
  • Introduced a backend AgentSkillsService plus an OCS API controller to list/load/store user skills (with YAML frontmatter parsing).
  • Updated routing, OpenAPI spec, and PHP dependencies (adds symfony/yaml) to support the new API.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/components/AdminSettings.vue Adds “Global Agent Skills” admin UI with folder picker and persistence calls.
lib/Settings/Admin.php Extends admin initial-state to expose context-agent availability + global skills config to the UI.
lib/Service/AgentSkillsService.php New service to resolve skills folders, parse YAML frontmatter, cache metadata, and read/write SKILL.md.
lib/Controller/ConfigController.php Adds endpoint to set/clear the global skills folder configuration.
lib/Controller/AgentSkillsApiController.php New OCS controller exposing list/load/store skills endpoints.
appinfo/routes.php Registers new admin-config route and new OCS /skills endpoints.
openapi.json Documents the new /skills endpoints and schemas.
composer.json Adds symfony/yaml dependency required for frontmatter parsing.
composer.lock Locks new Symfony YAML-related packages.

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

Comment on lines +134 to +137
} catch (\Exception|Throwable $e) {
$this->logger->error('Failed to store the skill', ['exception' => $e]);
return new DataResponse(['error' => 'Failed to store the skill'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
Comment on lines +331 to +341
$node = $userFolder->get($path);
// todo
$folder = $node;
$this->logger->warning('global folder etag', ['etag' => $folder->getEtag(), 'fileId' => $folder->getId(), 'path' => $folder->getPath()]);
// todo

if (!$node instanceof Folder) {
$this->logger->warning('Global skills path is not a folder: ' . $path . ' (admin: ' . $adminUid . ')');
return null;
}
return $node;
Comment on lines +63 to +69
} catch (NotFoundException|NotPermittedException $e) {
$this->logger->debug('Skills folder not found', ['exception' => $e]);
return new DataResponse(['error' => 'Skills folder not found'], Http::STATUS_NOT_FOUND);
} catch (\Exception|Throwable $e) {
$this->logger->error('Failed to list skills', ['exception' => $e]);
return new DataResponse(['error' => 'Failed to list skills'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
Comment on lines +96 to +103
} catch (NotFoundException|NotPermittedException $e) {
$this->logger->debug('Skill not found', ['exception' => $e]);
return new DataResponse(['error' => 'Skill not found'], Http::STATUS_NOT_FOUND);
} catch (\Exception|Throwable $e) {
$this->logger->error('Failed to load the skill', ['exception' => $e]);
return new DataResponse(['error' => 'Failed to load the skill'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
}
Comment on lines +26 to +30
class AgentSkillsService {

public const GLOBAL_SKILLS_ADMIN_UID_KEY = 'global_skills_admin_uid';
public const GLOBAL_SKILLS_PATH_KEY = 'global_skills_path';

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