Competencies API

Install, activate, and manage competencies.

Endpoints

MethodPathDescription
GET/competenciesList all competencies
GET/competencies/activeList active instances
POST/competencies/installInstall a competency
GET/competencies/{id}Get competency details
POST/competencies/{id}/equipEquip to an agent
POST/competencies/{id}/unequipUnequip from an agent
GET/agents/{id}/competenciesList equipped competencies (ordered)
PUT/agents/{id}/competencies/orderReorder equipped competencies
GET/competencies/schedule-healthCheck schedule drift
POST/agents/{agent_id}/competencies/{cid}/reset-scheduleReset schedule to manifest default
GET/competencies/{id}/validate-depsValidate dependencies
GET/competencies/{id}/depsGet dependency status
POST/competencies/{id}/deps/installInstall missing deps
POST/competencies/{id}/activateActivate
POST/competencies/{id}/deactivateDeactivate
POST/competencies/{id}/pausePause
POST/competencies/{id}/resumeResume
GET/competencies/{id}/configGet settings
PUT/competencies/{id}/configUpdate 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

FieldTypeRequiredDescription
agent_idstring (UUID)YesTarget agent
schedule_overridestringNoCustom cron expression (overrides manifest default)
positionintegerNoPosition 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

FieldTypeRequiredDescription
orderarray of stringsYesCompetency 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"
  }
}