Competencies API
Install, activate, and manage competencies.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /competencies | List all competencies |
| GET | /competencies/active | List active instances |
| POST | /competencies/install | Install a competency |
| GET | /competencies/{id} | Get competency details |
| POST | /competencies/{id}/equip | Equip to an agent |
| POST | /competencies/{id}/unequip | Unequip from an agent |
| GET | /agents/{id}/competencies | List equipped competencies (ordered) |
| PUT | /agents/{id}/competencies/order | Reorder equipped competencies |
| GET | /competencies/schedule-health | Check schedule drift |
| POST | /agents/{agent_id}/competencies/{cid}/reset-schedule | Reset schedule to manifest default |
| GET | /competencies/{id}/validate-deps | Validate dependencies |
| GET | /competencies/{id}/deps | Get dependency status |
| POST | /competencies/{id}/deps/install | Install missing deps |
| POST | /competencies/{id}/activate | Activate |
| POST | /competencies/{id}/deactivate | Deactivate |
| POST | /competencies/{id}/pause | Pause |
| POST | /competencies/{id}/resume | Resume |
| GET | /competencies/{id}/config | Get settings |
| PUT | /competencies/{id}/config | Update settings |
GET /competencies
curl http://localhost:4200/competencies
Response (200)
{
"competencies": [
{
"id": "claims-intake",
"name": "Claims Intake",
"category": "Insurance",
"status": "Active",
"required_skills": ["document-ocr", "postgresql-connector", "email-skill"]
},
{
"id": "policy-lookup",
"name": "Policy Lookup",
"category": "Insurance",
"status": "Installed",
"required_skills": ["postgresql-connector"]
}
]
}
POST /competencies/install
Install a competency from a local directory.
curl -X POST http://localhost:4200/competencies/install \
-H "Content-Type: application/json" \
-d '{"path": "/opt/competencies/claims-intake"}'
Response (201)
{
"id": "claims-intake"
}
Error (409 — duplicate)
{
"error": {
"category": "Duplicate",
"message": "Competency 'claims-intake' is already installed",
"details": {"competency_id": "claims-intake"}
}
}
GET /competencies/{id}
curl http://localhost:4200/competencies/claims-intake
Response (200)
{
"id": "claims-intake",
"name": "Claims Intake",
"description": "First Notice of Loss processing for property and auto claims",
"category": "Insurance",
"status": "Active",
"required_skills": ["document-ocr", "postgresql-connector", "email-skill"],
"required_permissions": ["database:read", "database:write", "api:claimcenter:write"],
"integrations": ["guidewire-claimcenter", "lexisnexis-clue"],
"schedule": "0 */6 * * *",
"agent": {
"name": "claims-intake-agent",
"description": "Processes first notice of loss and initiates claims"
},
"settings": [
{"key": "auto_escalate_threshold", "label": "Auto-Escalate Severity", "value": "4"},
{"key": "require_clue_report", "label": "Require CLUE Report", "value": "true"}
]
}
POST /competencies/{id}/equip
Equip a competency to an agent. Agents may have multiple competencies equipped simultaneously with operator-controlled ordering. If the competency manifest declares a schedule field, a kernel cron job is automatically created. Use schedule_override to provide a custom cadence instead of the manifest default.
Tool collision detection is performed before equipping: if any tool provided by the new competency's skills already exists in the agent's current tool allowlist (from another equipped competency), the request is rejected with a clear error naming the conflicting tool and its source.
curl -X POST http://localhost:4200/competencies/claims-intake/equip \
-H "Content-Type: application/json" \
-d '{"agent_id": "550e8400-e29b-41d4-a716-446655440000"}'
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string (UUID) | Yes | Target agent |
schedule_override | string | No | Custom cron expression (overrides manifest default) |
position | integer | No | Position to insert at (0-indexed). If omitted, appends at end. |
Example with position
curl -X POST http://localhost:4200/competencies/regulatory-compliance/equip \
-H "Content-Type: application/json" \
-d '{
"agent_id": "550e8400-e29b-41d4-a716-446655440000",
"position": 0
}'
Response (200)
Empty body (status indicates success).
Error (400 — missing dependencies)
{
"error": {
"category": "MissingDependency",
"message": "Cannot equip: skill 'document-ocr' is not installed",
"details": {"missing_skill": "document-ocr"}
}
}
Error (409 — tool collision)
{
"error": {
"category": "InvalidState",
"message": "Tool collision: 'web_search' is already provided by competency 'client-communication'",
"details": {
"tool_name": "web_search",
"existing_competency": "client-communication",
"new_competency": "claims-intake"
}
}
}
Error (500 — schedule creation failed with explicit override)
{
"error": {
"category": "Internal",
"message": "Failed to create cron job for schedule_override: ..."
}
}
POST /competencies/{id}/unequip
Unequip a specific competency from an agent. The agent's system prompt, skills, and tool allowlist are rebuilt from the remaining equipped competencies.
curl -X POST http://localhost:4200/competencies/claims-intake/unequip \
-H "Content-Type: application/json" \
-d '{"agent_id": "550e8400-e29b-41d4-a716-446655440000"}'
Response (200)
Empty body.
GET /agents/{id}/competencies
List all competencies equipped to an agent, in position order.
curl http://localhost:4200/agents/550e8400-e29b-41d4-a716-446655440000/competencies
Response (200)
{
"competencies": ["claims-intake", "client-communication", "regulatory-compliance"]
}
PUT /agents/{id}/competencies/order
Reorder equipped competencies. The provided list must contain exactly the competency IDs currently equipped (no additions or removals). The agent's system prompt is rebuilt in the new order.
curl -X PUT http://localhost:4200/agents/550e8400-e29b-41d4-a716-446655440000/competencies/order \
-H "Content-Type: application/json" \
-d '{"order": ["regulatory-compliance", "claims-intake", "client-communication"]}'
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
order | array of strings | Yes | Competency IDs in desired order |
Response (200)
Empty body.
Error (422 — mismatched set)
{
"error": {
"category": "ValidationError",
"message": "Reorder list must contain exactly the currently equipped competencies"
}
}
GET /competencies/{id}/validate-deps
Check if all required skills are installed.
curl http://localhost:4200/competencies/claims-intake/validate-deps
Response (200)
{
"competency_id": "claims-intake",
"all_satisfied": true,
"dependencies": [
{"skill": "document-ocr", "state": "Installed", "version": "1.4.0"},
{"skill": "postgresql-connector", "state": "Installed", "version": "2.1.0"},
{"skill": "email-skill", "state": "Installed", "version": "1.3.0"}
]
}
Response (200 — missing deps)
{
"competency_id": "claims-intake",
"all_satisfied": false,
"dependencies": [
{"skill": "document-ocr", "state": "Missing"},
{"skill": "postgresql-connector", "state": "Installed", "version": "2.1.0"},
{"skill": "email-skill", "state": "Installed", "version": "1.3.0"}
]
}
GET /competencies/{id}/config
Get current settings for an active competency.
curl http://localhost:4200/competencies/claims-intake/config
Response (200)
{
"settings": {
"auto_escalate_threshold": "4",
"require_clue_report": "true"
}
}
PUT /competencies/{id}/config
Update settings.
curl -X PUT http://localhost:4200/competencies/claims-intake/config \
-H "Content-Type: application/json" \
-d '{
"settings": {
"auto_escalate_threshold": "3",
"require_clue_report": "false"
}
}'
Response (200)
{
"updated": true,
"settings": {
"auto_escalate_threshold": "3",
"require_clue_report": "false"
}
}
GET /competencies/schedule-health
Check schedule drift across all competency bindings. Reports entries where:
- A cron job ID is recorded but the job no longer exists in the kernel scheduler (
missing) - The manifest declares a schedule but no cron job was created (
not_created) - The job exists but its expression doesn't match the manifest default (
expression_mismatch)
curl http://localhost:4200/competencies/schedule-health
Response (200 — healthy)
{
"drift": []
}
Response (200 — drift detected)
{
"drift": [
{
"agent_id": "550e8400-e29b-41d4-a716-446655440000",
"competency_id": "claims-intake",
"expected_schedule": "0 */6 * * *",
"status": "missing"
},
{
"agent_id": "662f9200-a31c-42d5-b817-557766551111",
"competency_id": "fnol-notify",
"expected_schedule": "*/30 * * * *",
"actual_schedule": "0 * * * *",
"status": "expression_mismatch"
}
]
}
POST /agents/{agent_id}/competencies/{cid}/reset-schedule
Recreate a deleted or drifted cron job from the competency manifest's default schedule.
curl -X POST http://localhost:4200/agents/550e8400-e29b-41d4-a716-446655440000/competencies/claims-intake/reset-schedule
Response (200)
{
"status": "reset"
}
Error (404 — not equipped)
{
"error": {
"category": "NotFound",
"message": "Competency 'claims-intake' is not equipped to agent 550e8400..."
}
}
Error (400 — no schedule in manifest)
{
"error": {
"category": "InvalidState",
"message": "Competency 'claims-intake' does not declare a default schedule"
}
}