Expose connector skill activation

Add a protected skills_activate endpoint and context-aware skills_list support so connector clients can activate skills in live chats. Advertise the capability through the connector API.
This commit is contained in:
Alessandro 2026-05-22 17:03:04 +02:00
parent 5464ead7ce
commit 770b53e292
3 changed files with 58 additions and 1 deletions

View file

@ -35,6 +35,7 @@ _OPTIONAL_FEATURES: dict[str, tuple[str, ...]] = {
"agent_profile_set": ("api.agent_profile_set",),
"agents_list": ("helpers.subagents",),
"skills_list": ("helpers.skills", "helpers.files", "helpers.projects", "helpers.runtime"),
"skills_activate": ("helpers.skills", "helpers.persist_chat"),
"skills_delete": ("helpers.skills", "helpers.files", "helpers.projects", "helpers.runtime"),
"model_presets": ("plugins._model_config.helpers.model_config",),
"model_switcher": ("plugins._model_config.helpers.model_config",),

View file

@ -0,0 +1,49 @@
"""POST /api/plugins/_a0_connector/v1/skills_activate."""
from __future__ import annotations
import json
from typing import Any
from helpers.api import Request, Response
import plugins._a0_connector.api.v1.base as connector_base
def _json_error(message: str, status: int) -> Response:
return Response(
response=json.dumps({"ok": False, "error": message}),
status=status,
mimetype="application/json",
)
class SkillsActivate(connector_base.ProtectedConnectorApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
from agent import AgentContext
from helpers import skills
from helpers.persist_chat import save_tmp_chat
context_id = str(input.get("context_id", "") or "").strip()
if not context_id:
return _json_error("context_id is required", 400)
context = AgentContext.get(context_id)
if context is None:
return _json_error("Context not found", 404)
entries = skills.normalize_active_skills([input.get("skill")])
if not entries:
return _json_error("skill is required", 400)
skill_entry: dict[str, Any] = dict(entries[0])
try:
active_skills = skills.activate_chat_skill(context.get_agent(), skill_entry)
save_tmp_chat(context)
except ValueError as exc:
return _json_error(str(exc), 400)
return {
"ok": True,
"context_id": context.id,
"skill": skill_entry,
"active_skills": active_skills,
}

View file

@ -7,10 +7,17 @@ import plugins._a0_connector.api.v1.base as connector_base
class SkillsList(connector_base.ProtectedConnectorApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
from agent import AgentContext
from helpers import files, projects, skills
context_id = str(input.get("context_id", "") or "").strip()
project_name = str(input.get("project_name", "")).strip() or None
skill_list = skills.list_skill_catalog(project_name=project_name or "")
context = AgentContext.get(context_id) if context_id else None
agent = context.get_agent() if context else None
if context is not None and not project_name:
project_name = projects.get_context_project_name(context) or None
skill_list = skills.list_skill_catalog(project_name=project_name or "", agent=agent)
agent_profile = str(input.get("agent_profile", "")).strip() or None
if agent_profile: