Skills System (Beta)¶
Skills are auto-generated tool definitions that make hosted service endpoints discoverable by AI agents. When you publish a service version, the platform generates a skill snapshot containing structured metadata for every endpoint -- allowing agents to understand what each endpoint does, what inputs it expects, and how to call it.
What is a Skill?¶
A Skill is a runtime-neutral description of a hosted service endpoint, packaged with:
- Manifest -- identity, version, tags, and human-readable title
- HTTP signature -- method, path, and path parameter schema
- Request/response schemas -- the endpoint's JSON Schema definitions
- Auth requirements -- what authentication the endpoint needs
- Execution hints -- timeout, async eligibility, rate limit tier
- Trigger hints -- instructions for when and how to activate the Skill
- Usage examples -- SDK and CLI invocation patterns
Skills bridge the gap between endpoint definitions (which are HTTP-centric) and agent tool registries (which need structured, discoverable capabilities).
Skill Generation Flow¶
Skills are generated automatically during the version publish process:
sequenceDiagram
participant User
participant API as Management API
participant Publish as Publish Service
participant Skills as Skills Service
participant Version as Version Store
User->>API: POST /versions/{id}/publish
API->>Publish: publish_version()
Publish->>Publish: Freeze endpoint_snapshot
Publish->>Skills: generate(service, version)
Skills->>Skills: Build endpoint skills
Skills->>Skills: Build service bundle
Skills->>Skills: Compute checksums
Skills-->>Publish: skill_snapshot
Publish->>Version: Store skill_snapshot
Publish-->>API: Published version
API-->>User: Version with skills
Skill Structure¶
Each endpoint produces one endpoint skill. All endpoint skills for a version are grouped into a service bundle.
Endpoint Skill¶
An individual endpoint skill contains everything an agent needs to invoke the endpoint:
{
"skill_id": "document-processor.post__analyze",
"version": "v2",
"service_id": "abc-123",
"service_slug": "document-processor",
"endpoint_key": "post__analyze",
"http": {
"method": "POST",
"path": "/analyze",
"signature": "POST /analyze",
"path_params_schema": {
"type": "object",
"properties": {},
"required": []
}
},
"request_schema": {
"type": "object",
"properties": {
"content": {"type": "string"},
"analysis_type": {"type": "string", "enum": ["summary", "entities", "sentiment"]}
},
"required": ["content"]
},
"response_schema": {
"type": "object",
"properties": {
"result": {"type": "object"},
"confidence": {"type": "number"}
}
},
"requires_scopes": [],
"auth_mode": "platform",
"execution": {
"async_eligible": true,
"timeout_seconds": 30,
"rate_limit_tier": null
},
"trigger_hints": [
"Activate for calls matching `POST /analyze`.",
"Validate request payload against request_schema before submit.",
"Prefer async submit and polling for long-running invocations."
],
"usage_examples": {
"sdk": [
"flow.services.invoke(service_id='abc-123', endpoint_key='post__analyze', payload={...})"
],
"cli": [
"flow services invoke --service abc-123 --endpoint post__analyze --method POST"
]
},
"package": {
"manifest": {
"id": "document-processor.post__analyze",
"version": "v2",
"title": "Analyze Document",
"description": "Accepts a document and returns structured analysis",
"service_id": "abc-123",
"service_slug": "document-processor",
"endpoint_key": "post__analyze",
"tags": ["document-processor", "hsl-endpoint"]
},
"instructions": "Service `document-processor` endpoint `post__analyze` handles `POST /analyze`.\nAuth mode: `platform`. Required scopes: `none`.\nAsync eligible: `yes`.",
"resources": [],
"scripts": []
},
"checksum": "a1b2c3..."
}
Service Bundle¶
The service bundle groups all endpoint skills for a version and includes shared metadata:
{
"bundle_id": "document-processor.bundle.v2",
"version": "v2",
"service_id": "abc-123",
"service_slug": "document-processor",
"service_name": "Document Processor",
"endpoint_skill_refs": [
{
"skill_id": "document-processor.post__analyze",
"version": "v2",
"endpoint_key": "post__analyze",
"checksum": "a1b2c3..."
}
],
"shared_auth_metadata": {
"auth_modes": ["platform"],
"requires_scopes": []
},
"compatibility": {
"format": "runtime-neutral-skill-bundle",
"adapters": {
"claude": {"supported": true},
"openai": {"supported": true}
}
},
"checksum": "d4e5f6..."
}
Skill Naming Convention¶
Skills use a two-part naming convention:
The endpoint_key is derived from the HTTP method and path:
| Method | Path | Endpoint Key | Skill ID |
|---|---|---|---|
POST |
/analyze |
post__analyze |
my-service.post__analyze |
GET |
/users/{user_id} |
get__users__user_id |
my-service.get__users__user_id |
PUT |
/items/{id}/status |
put__items__id__status |
my-service.put__items__id__status |
Skill Snapshots and Versioning¶
The skill snapshot is frozen alongside the endpoint snapshot when a version is published. This guarantees:
- Immutability -- the Skill definition for a given version never changes
- Reproducibility -- agents using version-pinned skills always get consistent behavior
- Integrity -- each skill carries a SHA-256 checksum for tamper detection
You can retrieve the skill snapshot for any version:
Skill Discovery by Agents¶
Agents discover available skills through the skills endpoint. The platform supports filtering and scoping so agents only see skills they are authorized to use.
Resolving Activated Skills¶
The Skills service can filter the full skill set based on the agent's context:
- Scopes -- only skills whose
requires_scopesare a subset of the agent's scopes - Endpoint key -- filter to a specific endpoint
- Async-only -- only skills with async-eligible endpoints
from app.services.hsl_skills_service import HSLSkillsService
skills_svc = HSLSkillsService()
# Get all skills the agent can use
activated = skills_svc.resolve_activated_skills(
request_context={
"scopes": ["data:read", "analytics:execute"],
"endpoint_key": None,
"async_only": False,
},
skills_payload=skill_snapshot,
)
Runtime Adaptation¶
Skills are generated in a runtime-neutral format. Before passing to a specific LLM runtime, adapt them:
adapted = skills_svc.adapt_for_runtime(
runtime="claude", # or "openai"
activated_skills=activated,
)
The adapted output includes a simplified view with name, description, instructions, and metadata -- formatted for the target runtime's tool-calling protocol.
Exposing Endpoints as Skills¶
To generate a Skill for an endpoint, set expose_as_agent_tool: true when creating or updating the endpoint:
{
"path": "/analyze",
"method": "POST",
"expose_as_agent_tool": true,
"tool_description": "Analyze a document for summaries, entities, or sentiment. Accepts text content and returns structured analysis with confidence scores."
}
Write good tool descriptions
The tool_description field is what agents see when deciding whether to use a Skill. Be specific about what the endpoint does, what input it expects, and what it returns. Avoid generic descriptions.
Endpoints with expose_as_agent_tool: false are still accessible through the Service Gateway -- they just are not included in the skill snapshot and will not be discovered by agents.
Checksums and Integrity¶
Every skill artifact includes a SHA-256 checksum computed from its canonical JSON representation. Checksums serve two purposes:
- Change detection -- quickly determine if a skill has changed between versions
- Integrity verification -- ensure the skill artifact has not been tampered with
The service bundle's endpoint_skill_refs include the checksum of each child skill, creating a hash tree that can be verified top-down.