rakyll/ate-env

An environment service with built in tools for Agent Substrate

★ 4Forks 0GoGitHub ↗Compare

README

Agent Substrate Environment

A lightweight agentic environment service for Agent Substrate. It exposes an API that lets an agent runtime run tools — file operations and shell commands — inside session-tenant sandboxed actors.

Each session maps to a sandboxed actor in Agent Substrate. The service manages the actor's lifecycle (create → resume → suspend) via the Agent Substrate control API, and executes incoming tool calls in-process against the local environment. It returns tool call responses.

Overview

%%{init: {"flowchart": {"diagramPadding": 80}}}%%
flowchart LR
    runtime["Agent Runtime"]
    env["Agent Substrate Environment"]
    substrate["Agent Substrate Control API"]
    actor["Actor (sandbox)"]

    runtime -->|resume, suspend, execute| env
    env -->|actor lifecycle operations| substrate
    env -->|tool call operations| actor
    substrate -.->  actor
    actor --> available_skills["available skills"] --> skill
    actor --> filesystem
    actor --> bash
Loading

Configuration

Configuration is loaded from config.yaml in the working directory. If the file is missing, built-in defaults are used. Any field left empty falls back to its default.

# Address/port for this HTTP service to listen on
listen: ":7777"

# Predefined environments mapping client-facing names to Agent Substrate templates.
environments:
  - name: "my-env"
    template: "default-env-template"
    atespace: "default"
    skills_dir: "/skills"
    allowed_tools:
      - "bash"
      - "read_file"
      - "write_file"
      - "list_dir"
      - "list_skills"
      - "activate_skill"
Field Default Description
listen :7777 Bind address.
environments my-env -> default-env-template List of predefined client-facing environment configuration (template, atespace, skills_dir, allowed tools).
ate.ateapi ateapi.ate-system.svc.cluster.local:443 Agent Substrate Control API endpoint.

Usage

Your cluster must already have Agent Substrate installed.

# Build, push, and deploy. Set GOOGLE_PROJECT_ID to push to gcr.io/$GOOGLE_PROJECT_ID,
# or set ATE_ENV_IMAGE_REPO directly for any other registry.
GOOGLE_PROJECT_ID=my-project ./manifests/install.sh --deploy-ate-env

# Reach the service locally (optional)
kubectl port-forward -n ate-env deploy/ate-env 7777:7777

# Tear it down
./manifests/install.sh --delete-ate-env

Environment variables the script honors:

Variable Description
GOOGLE_PROJECT_ID Sets ATE_ENV_IMAGE_REPO=gcr.io/$GOOGLE_PROJECT_ID.
ATE_ENV_IMAGE_REPO Registry to push the image to (required unless GOOGLE_PROJECT_ID or ATE_ENV_IMAGE is set).
ATE_ENV_IMAGE Use a prebuilt digest-pinned image instead of building one.
ATE_ENV_WAIT_TIMEOUT Rollout wait timeout (default 5m).
KUBECTL_CONTEXT kubectl context to deploy to (defaults to the current context).

API

Applications are responsible for session resumption and suspension. A typical application makes calls in the following fashion:

  1. Resume session
  2. Tool call
  3. Tool call
  4. Tool call
  5. Suspend session

Session Resumption

POST /v1/environments/{env}/sessions/{session_id}/resume

Create (if needed) and resume the actor for the session in {env}.

Response: { "status": "ok" }

Session Suspension

POST /v1/environments/{env}/sessions/{session_id}/suspend

Suspend the session's actor.

Response: { "status": "ok" }

Tool Call

POST /v1/environments/{env}/sessions/{session_id}

Execute a tool call in the session's actor. Only tools configured/enabled for {env} can be executed. The tool call is inlined into the request body alongside env_variables. Setting "auto_resume": true automatically creates/resumes the session actor prior to executing the tool call, and automatically suspends it at the end of the tool call.

{
  "auto_resume": true,
  "env_variables": [
    { "name": "MY_SECRET", "value": "c3ebfdfdk12345..." }
  ],
  "call_id": "call_1",
  "type": "function_call",
  "function": {
    "name": "bash",
    "arguments": "{\"command\": \"echo hi && ls\"}"
  }
}

Response: the tool output:

{
  "type": "function_call_output",
  "name": "bash",
  "call_id": "call_1",
  "output": "hi\n..."
}

Supported tools

All tool calls run in-process in this binary. The bash tool executes the command locally with sh -c via os/exec. File operation tools (read_file, write_file, list_dir) use the Go standard library directly — they never shell out.

Tool Arguments Behavior
bash command Runs the command locally with sh -c (os/exec); per-call env vars are merged in.
read_file path Reads and returns the file contents (os.ReadFile). Only text files are supported.
write_file path, content Creates parent dirs (os.MkdirAll) and writes the content (os.WriteFile). Only text files are supported.
list_dir path Lists the directory (os.ReadDir), ls -la style.
list_skills — Lists the available agentic skills with their descriptions.
activate_skill name Returns the skill's full SKILL.md instructions and its bundled files.

Agentic skills

The service supports Agent Skills out of the box. A skill is a subdirectory of skills_dir containing a SKILL.md file — YAML frontmatter (name, description) followed by markdown instructions — plus any bundled files the instructions reference:

/skills/
└── pdf-processing/
    ├── SKILL.md
    └── extract.sh

Skills follow progressive disclosure: list_skills returns only each skill's name and description so the agent can pick one cheaply, and activate_skill loads the chosen skill's full instructions along with the paths of its bundled files, which the agent can then read_file or execute with bash. Both tools must be listed in an environment's allowed_tools to be callable.

Example

Explicit lifecycle management:

export SESSION_ID=123e4567-e89b-12d3-a456-426614174000

# 1. Resume the session
curl -sX POST localhost:7777/v1/environments/my-env/sessions/$SESSION_ID/resume

# 2. Run a tool call with env vars
curl -sX POST localhost:7777/v1/environments/my-env/sessions/$SESSION_ID \
  -H 'Content-Type: application/json' \
  -d '{"env_variables":[{"name":"MY_SECRET","value":"c3ebfdfdk12345..."}],"call_id":"c1","type":"function_call","function":{"name":"bash","arguments":"{\"command\":\"uname -a\"}"}}'

# 3. Suspend when done
curl -sX POST localhost:7777/v1/environments/my-env/sessions/$SESSION_ID/suspend

Or using auto_resume:

# Execute tool call with auto_resume enabled (creates/resumes actor automatically)
curl -sX POST localhost:7777/v1/environments/my-env/sessions/$SESSION_ID \
  -H 'Content-Type: application/json' \
  -d '{"auto_resume":true,"call_id":"c1","type":"function_call","function":{"name":"bash","arguments":"{\"command\":\"uname -a\"}"}}'

License

Apache 2.0.

Contributors

rakyll

Issues