Skip to content

Skills Capability Specification

Capability Identity

PropertyValue
EnumA2ECapability.SKILL
String"skill"
Plugin TypeSkillPlugin
Namespaceskill/*
Message Count5

Overview

The skills capability provides multi-step, LLM-driven agentic execution units. Unlike tools (which are stateless primitives), skills are complex workflows that may involve multiple LLM calls, tool invocations, and conditional logic. Skills are inspired by MCP/JSON-RPC 2.0 and optimized for sandboxed, multi-turn agentic loops where skills may live in Docker containers.

Key distinctions from tools:

  • Skills are multi-turn; tools are single-turn
  • Skills may stream intermediate events; tools optionally stream
  • Skills may use LLMs; tools are pure computation
  • Skills have natural language instructions for agent selection
  • Skills declare their tool and toolkit dependencies

Protocol Flow

Message Types (5)

skill/discover/req — SkillDiscoverRequest

Agent → Host. Discover available skills.

FieldTypeRequiredDefaultDescription
typestrYes"skill/discover/req"Message type identifier
idstrYesauto UUIDMessage UUID
versionstrYes"1.0"Protocol version
tsfloatYesautoUnix epoch timestamp
filter_tagslist[str]No[]Filter by tags (OR logic)
filter_categorieslist[str]No[]Filter by category

skill/discover/resp — SkillDiscoverResponse

Host → Agent. Returns all matching skill manifests.

FieldTypeRequiredDefaultDescription
typestrYes"skill/discover/resp"Message type identifier
idstrYesauto UUIDMessage UUID
versionstrYes"1.0"Protocol version
tsfloatYesautoUnix epoch timestamp
req_idstrYes""Echoes request ID
skillslist[SkillDefinition]Yes[]Available skill definitions

skill/call/req — SkillCallRequest

Agent → Host. Execute a skill.

FieldTypeRequiredDefaultDescription
typestrYes"skill/call/req"Message type identifier
idstrYesauto UUIDMessage UUID
versionstrYes"1.0"Protocol version
tsfloatYesautoUnix epoch timestamp
namestrYes""Must match SkillDefinition.name
argumentsdict[str, Any]Yes{}Input arguments validated against skill.input_schema
correlation_idstrNo""Ties to agent turn/trajectory
timeoutintNo60Per-call wall-clock limit (seconds)
streamingboolNoTrueEmit SkillEvent messages during execution
llm_overrideLLMConfigNoNoneOverride model/provider for this invocation
metadatadictNo{}Additional metadata

skill/call/resp — SkillCallResponse

Host → Agent. Final result of skill execution.

FieldTypeRequiredDefaultDescription
typestrYes"skill/call/resp"Message type identifier
idstrYesauto UUIDMessage UUID
versionstrYes"1.0"Protocol version
tsfloatYesautoUnix epoch timestamp
req_idstrYes""Echoes request ID
namestrYes""Skill that was executed
dataSkillResultNoNoneSkill execution result
errordictNoNoneTransport-level error: {code, message, retryable}
created_atfloatNoautoResult creation timestamp

skill/event — SkillEvent

Host → Agent. Zero or more streaming events during skill execution. Extends A2EEvent.

FieldTypeRequiredDefaultDescription
typestrYes"skill/event"Message type identifier
idstrYesauto UUIDMessage UUID
versionstrYes"1.0"Protocol version
tsfloatYesautoUnix epoch timestamp
kindstrYesEvent kind (see Event Kinds below)
req_idstrYes""Correlates to SkillCallRequest ID
datadictYes{}Event payload
seqintYes0Monotonic sequence number

Event kinds and their data shapes:

KindData ShapeDescription
progress{ "pct": int, "message": str }Progress update
artifact{ "name": str, "mime": str, "chunk": str, "final": bool }Incremental data chunk
log{ "level": str, "message": str }Debug log line
status{ "message": str }One-liner status update

Data Models

SkillDefinition

FieldTypeRequiredDefaultDescription
namestrYesUnique skill name
versionstrYesSkill version
descriptionstrYesHuman-readable description
triggerslist[str]YesTrigger phrases for auto-invocation
toolslist[Any]NoNoneTool dependencies
toolkitslist[Any]NoNoneToolkit dependencies
statusSkillStatusYesCreated, Blocked, Published, Archived
input_schemadictNo{}JSON Schema for input arguments
output_schemadictNo{}JSON Schema for output
instructionsstrNoNoneNatural language instructions (critical for agent selection)
file_pathstrNoNonePath to skill definition file
llm_configLLMConfigNoNoneDefault LLM configuration
argumentslist[str]No{}Default arguments
when_to_usestrYesGuidance on when the agent should use this skill
argument_hintstrYesHint for argument construction
sourcestrYesOrigin: user, system, or project
categorystrNoNoneClassification category
tagslist[str]NoNoneClassification tags
max_turnsintNoNoneMaximum agentic turns
timeout_secondsintNoNoneTimeout for skill execution
iconstrNoNoneIcon for UI
metadatadictNoNoneAdditional metadata

LLMConfig

FieldTypeRequiredDefaultDescription
provider_namestrYesLLM provider name
provider_credentialsdictYesProvider credentials/API keys
provider_configdictNoNoneProvider-specific configuration
is_defaultboolNoFalseWhether this is the default config

SkillResult

FieldTypeRequiredDefaultDescription
successboolYesWhether execution succeeded
dataAnyNoNoneResult data
summaryAnyNoNoneHuman-readable summary
truncatedboolNoFalseOutput was truncated
errorstrNoNoneError message
error_codestrNoNoneMachine-readable error code
duration_msintYesExecution time in milliseconds
eventslist[SkillEvent]No[]Collected streaming events

SkillStatus

ValueDescription
CreatedSkill is created but not yet available
BlockedSkill is blocked (missing dependencies)
PublishedSkill is available for use
ArchivedSkill is archived and unavailable

Error Codes — SkillErrorCode

CodeEnum ValueDescriptionRetryable
unknown_skillUNKNOWN_SKILLSkill name not foundNo
skill_errorSKILL_ERRORSkill execution failedYes
runtime_errorRUNTIME_ERRORGeneral runtime failureDepends

Additional ErrorCode values (protocol-level):

CodeDescription
parse_errorMessage could not be parsed
invalid_messageMessage type not recognized
schema_violationInput didn't match skill schema
timeoutSkill execution timed out
out_of_memorySandbox OOM
sandbox_crashSandbox process crashed
unauthorizedAgent not authorized for this skill
version_mismatchProtocol version mismatch

Plugin Contract — SkillPlugin

python
class SkillPlugin(A2EPlugin):
    def __init__(self, host_instance, config):
        super().setup(host_instance, config)

    @abstractmethod
    def _list_skills(self) -> list[SkillDefinition]:
        """Must return skill manifest. Override in subclass."""

    @abstractmethod
    def _execute_skill(self, name: str, arguments: dict, context: dict) -> SkillResult:
        """Execute skill logic. Override in subclass.
        context contains: emit_event, llm_override, metadata, streaming"""

    def discover(self, msg: SkillDiscoverRequest) -> list[SkillDefinition]:
        """Filter skills by tags and categories."""

    def call(self, msg: SkillCallRequest) -> SkillCallResponse:
        """Execute skill with streaming support."""

Handler dispatch:

  • SkillDiscoverRequest → calls discover(msg) with tag/category filtering
  • SkillCallRequest → calls call(msg) with streaming event aggregation

Streaming support: The call() method provides an emit_event callback in the execution context, allowing skills to stream intermediate results. Events are:

  1. Pushed to the agent via self.push(evt)
  2. Aggregated into the events field of SkillResult

Wire Examples

Discover Skills

json
{"type":"skill/discover/req","id":"sd1","version":"1.0","ts":1716123456.789,"filter_tags":["coding"],"filter_categories":[]}
json
{"type":"skill/discover/resp","id":"sd2","version":"1.0","ts":1716123456.900,"req_id":"sd1","skills":[{"name":"code_review","version":"1.0.0","description":"Review code for quality and security","triggers":["review code","code review"],"tools":null,"toolkits":null,"status":"Published","input_schema":{"type":"object","properties":{"code":{"type":"string"}},"required":["code"]},"output_schema":{},"instructions":"Review the provided code...","when_to_use":"Use when code needs quality review","argument_hint":"Provide the code to review","source":"system","category":"development","tags":["coding","review"],"max_turns":10,"timeout_seconds":120}]}

Call Skill (with streaming)

json
{"type":"skill/call/req","id":"sc1","version":"1.0","ts":1716123457.100,"name":"code_review","arguments":{"code":"def add(a, b): return a + b"},"correlation_id":"","timeout":60,"streaming":true,"llm_override":null,"metadata":{}}
json
{"type":"skill/event","id":"se1","version":"1.0","ts":1716123457.200,"kind":"progress","req_id":"sc1","data":{"pct":30,"message":"Analyzing code structure..."},"seq":0}
json
{"type":"skill/call/resp","id":"sc2","version":"1.0","ts":1716123458.500,"req_id":"sc1","name":"code_review","data":{"success":true,"data":{"issues":[]},"summary":"No issues found","duration_ms":1400},"created_at":1716123458.500}

Security Considerations

  1. Sandboxing: Skills may run in Docker containers for isolation
  2. LLM override restriction: Host may restrict llm_override to approved providers
  3. Timeout enforcement: Per-call timeout prevents runaway skill execution
  4. Credential isolation: LLM credentials in llm_override must be scoped
  5. Input schema validation: Arguments validated against input_schema before execution

A2E Protocol v1.0 — Released under the MIT License.