From 4200d94161dd4a12b893bfa42d77677a8edba9d3 Mon Sep 17 00:00:00 2001 From: Greyson Lalonde Date: Thu, 5 Mar 2026 19:32:17 -0500 Subject: [PATCH] feat: add skill lifecycle events --- lib/crewai/src/crewai/events/__init__.py | 14 +++++ .../src/crewai/events/types/skill_events.py | 60 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 lib/crewai/src/crewai/events/types/skill_events.py diff --git a/lib/crewai/src/crewai/events/__init__.py b/lib/crewai/src/crewai/events/__init__.py index a6f213a54..e18893fc6 100644 --- a/lib/crewai/src/crewai/events/__init__.py +++ b/lib/crewai/src/crewai/events/__init__.py @@ -87,6 +87,14 @@ from crewai.events.types.reasoning_events import ( AgentReasoningStartedEvent, ReasoningEvent, ) +from crewai.events.types.skill_events import ( + SkillActivatedEvent, + SkillDiscoveryCompletedEvent, + SkillDiscoveryStartedEvent, + SkillEvent, + SkillLoadFailedEvent, + SkillLoadedEvent, +) from crewai.events.types.task_events import ( TaskCompletedEvent, TaskEvaluationEvent, @@ -184,6 +192,12 @@ __all__ = [ "MethodExecutionFinishedEvent", "MethodExecutionStartedEvent", "ReasoningEvent", + "SkillActivatedEvent", + "SkillDiscoveryCompletedEvent", + "SkillDiscoveryStartedEvent", + "SkillEvent", + "SkillLoadFailedEvent", + "SkillLoadedEvent", "TaskCompletedEvent", "TaskEvaluationEvent", "TaskFailedEvent", diff --git a/lib/crewai/src/crewai/events/types/skill_events.py b/lib/crewai/src/crewai/events/types/skill_events.py new file mode 100644 index 000000000..3e763d162 --- /dev/null +++ b/lib/crewai/src/crewai/events/types/skill_events.py @@ -0,0 +1,60 @@ +"""Skill lifecycle events for the Agent Skills standard. + +Events emitted during skill discovery, loading, and activation. +""" + +from __future__ import annotations + +from typing import Any + +from crewai.events.base_events import BaseEvent + + +class SkillEvent(BaseEvent): + """Base event for skill operations.""" + + skill_name: str = "" + skill_path: str | None = None + from_agent: Any | None = None + from_task: Any | None = None + + def __init__(self, **data: Any) -> None: + super().__init__(**data) + self._set_agent_params(data) + self._set_task_params(data) + + +class SkillDiscoveryStartedEvent(SkillEvent): + """Event emitted when skill discovery begins.""" + + type: str = "skill_discovery_started" + search_path: str + + +class SkillDiscoveryCompletedEvent(SkillEvent): + """Event emitted when skill discovery completes.""" + + type: str = "skill_discovery_completed" + skills_found: int + skill_names: list[str] + + +class SkillLoadedEvent(SkillEvent): + """Event emitted when a skill is loaded at metadata level.""" + + type: str = "skill_loaded" + disclosure_level: int = 1 + + +class SkillActivatedEvent(SkillEvent): + """Event emitted when a skill is activated (promoted to instructions level).""" + + type: str = "skill_activated" + disclosure_level: int = 2 + + +class SkillLoadFailedEvent(SkillEvent): + """Event emitted when skill loading fails.""" + + type: str = "skill_load_failed" + error: str