Agent DocsDeveloper documentation
Builder Guide

Skills & Code Execution

Create skill scripts with 7-layer sandbox security

Skills & Code Execution

Skills are reusable code scripts that agents can execute in a secure sandbox. They extend agent capabilities beyond what LLM inference alone can provide — data analysis, file processing, API calls, calculations, and more.

Overview

The platform provides a 7-layer security pipeline for code execution:

  1. Cedar Policy Check — is this agent allowed to execute code?
  2. Code Pre-Scan — static analysis for dangerous patterns (eval, exec, network calls)
  3. Container Isolation — execution runs in an ephemeral Kubernetes pod
  4. Seccomp Profile — syscall filtering blocks dangerous operations
  5. Network Policy — outbound network access is blocked by default
  6. Output Secret Scan — scan stdout/stderr for leaked credentials
  7. Behavioral Monitoring — detect anomalous execution patterns

Creating a Skill

In Agent Studio

  1. Navigate to Studio > Skills
  2. Click Create Skill
  3. Fill in the skill metadata:
FieldDescription
NameDescriptive name (e.g., "CSV Analyzer")
DescriptionWhat the skill does — shown to the LLM for tool selection
Languagepython, javascript, typescript, or bash
TimeoutMax execution time (default: 30s, max: 120s)
Input SchemaJSON Schema defining expected inputs
Output SchemaJSON Schema defining expected outputs
  1. Write the skill script in the Monaco editor
  2. Test with sample inputs
  3. Assign to agents

Skill Script Structure

Skills receive input as a JSON object and must produce output on stdout:

Python Example:

import json
import sys

# Input is passed as JSON on stdin
input_data = json.loads(sys.stdin.read())

# Your logic here
query = input_data.get("query", "")
data = input_data.get("data", [])

# Process...
result = {"answer": f"Processed {len(data)} rows for: {query}"}

# Output must be JSON on stdout
print(json.dumps(result))

JavaScript Example:

const input = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));

const result = {
  answer: `Processed ${input.data?.length || 0} items`,
  timestamp: new Date().toISOString()
};

console.log(JSON.stringify(result));

Input Schema

Define what your skill expects using JSON Schema:

{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "The analysis question to answer"
    },
    "data": {
      "type": "array",
      "description": "Array of data rows to analyze",
      "items": { "type": "object" }
    },
    "format": {
      "type": "string",
      "enum": ["summary", "detailed", "chart"],
      "description": "Output format preference"
    }
  },
  "required": ["query"]
}

The LLM uses this schema to understand how to call your skill and what parameters to provide.

Safe Libraries

The Python sandbox includes a curated set of pre-installed libraries:

Data Analysis

  • pandas — DataFrames and data manipulation
  • numpy — Numerical computing
  • scipy — Scientific computing and statistics

Visualization

  • matplotlib — Charts and plots (saves to file, returned as base64)

Text Processing

  • re (built-in) — Regular expressions
  • json (built-in) — JSON parsing
  • csv (built-in) — CSV reading/writing
  • textwrap (built-in) — Text formatting

Date/Time

  • datetime (built-in) — Date and time manipulation
  • calendar (built-in) — Calendar operations

Math

  • math (built-in) — Mathematical functions
  • statistics (built-in) — Statistical functions
  • decimal (built-in) — Precise decimal arithmetic

Utilities

  • collections (built-in) — Specialized container types
  • itertools (built-in) — Iterator building blocks
  • functools (built-in) — Higher-order functions
  • hashlib (built-in) — Secure hashing
  • base64 (built-in) — Base64 encoding/decoding
  • urllib.parse (built-in) — URL parsing (no network access)

Not Available (Blocked by Security)

  • requests, urllib3, httpx — No outbound HTTP
  • subprocess, os.system — No shell execution
  • socket — No raw network access
  • ctypes, cffi — No native code execution
  • pickle — Blocked due to deserialization risks

Assigning Skills to Agents

Skills are linked to agents through the agent designer:

  1. Open your agent in Studio > Agents > [Agent]
  2. Go to the Skills tab
  3. Click Assign Skill and select from available skills
  4. The skill appears as an MCP tool that the LLM can invoke

Note: The agent must be saved before skills can be assigned (skills are linked records in the database).

Skill Visibility

Skills have visibility settings similar to agents:

  • Public — available to all agents in the tenant
  • Restricted — only available to specific agents
  • Private — only available to the creating builder's agents

Error Handling

In Your Script

Always handle errors gracefully and return structured error information:

import json, sys

try:
    input_data = json.loads(sys.stdin.read())
    # ... your logic ...
    result = {"status": "success", "data": processed_data}
except json.JSONDecodeError:
    result = {"status": "error", "message": "Invalid input JSON"}
except Exception as e:
    result = {"status": "error", "message": str(e)}

print(json.dumps(result))
sys.exit(0)  # Always exit cleanly — non-zero triggers sandbox alert

Platform Error Handling

The platform handles these failure modes:

  • Timeout — script killed after timeout seconds, returns timeout error
  • Memory limit — container OOM-killed, returns resource error
  • Security violation — blocked by pre-scan or seccomp, returns security error
  • Output too large — stdout truncated at 1MB

Testing Skills

In the Skill Editor

Use the Test panel in the skill editor:

  1. Enter sample input JSON
  2. Click Run
  3. View stdout, stderr, exit code, and execution time
  4. Iterate on the script

In the Playground

Test skills through an agent in the Playground:

  1. Select an agent with the skill assigned
  2. Ask the agent to perform a task that requires the skill
  3. Observe the tool call in the trace view
  4. Verify the skill output is correctly interpreted by the LLM

Best Practices

  1. Keep skills focused — one skill per task, not mega-scripts
  2. Validate inputs early — check for required fields before processing
  3. Return structured data — JSON output that the LLM can parse
  4. Handle edge cases — empty data, missing fields, invalid formats
  5. Log to stderr — use print(..., file=sys.stderr) for debugging (visible in traces)
  6. Respect timeouts — process data in chunks for large datasets
  7. Use type hints — helps both you and the LLM understand the contract

Next Steps