Merge pull request #13 from google/playground-submit
Create Artemis container for playground
This commit is contained in:
5 files changed
+287
No files matched your search
@@ -0,0 +1,15 @@
|
|||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.env
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
.pytest_cache/
|
||||||
|
.coverage
|
||||||
|
htmlcov/
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.egg-info/
|
||||||
|
playground/
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# Copyright 2026 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install system dependencies, Android toolchain (adb), OpenCV runtime, FFmpeg, and curl
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
build-essential \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
adb \
|
||||||
|
ffmpeg \
|
||||||
|
libgl1 \
|
||||||
|
libglib2.0-0 \
|
||||||
|
ca-certificates \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Copy core Artemis package structure and configuration from repository root
|
||||||
|
COPY artemis/ /app/artemis/
|
||||||
|
COPY apps/ /app/apps/
|
||||||
|
COPY mcp_server/ /app/mcp_server/
|
||||||
|
COPY config/ /app/config/
|
||||||
|
COPY pyproject.toml setup.py README.md LICENSE /app/
|
||||||
|
|
||||||
|
# Install dependencies and artemis in editable mode
|
||||||
|
RUN pip install --no-cache-dir -e /app
|
||||||
|
|
||||||
|
# Copy custom container entrypoint script
|
||||||
|
COPY playground/artemis_container/docker-entrypoint.sh /app/docker-entrypoint.sh
|
||||||
|
RUN chmod +x /app/docker-entrypoint.sh
|
||||||
|
|
||||||
|
# Environment Configuration
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
ENV PYTHONPATH=/app
|
||||||
|
ENV ARTEMIS_APP_DIR=/app
|
||||||
|
ENV PORT=8080
|
||||||
|
|
||||||
|
# Expose internal Artemis Admin Console and Stream port
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Health check to ensure Artemis Admin Console is alive
|
||||||
|
HEALTHCHECK --interval=15s --timeout=3s --start-period=10s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:8080/api/system/health || curl -f http://localhost:8080/ || exit 1
|
||||||
|
|
||||||
|
ENTRYPOINT ["/app/docker-entrypoint.sh"]
|
||||||
|
CMD ["uvicorn", "apps.admin_console.server:app", "--host", "0.0.0.0", "--port", "8080"]
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
# 🤖 Artemis Session Container
|
||||||
|
|
||||||
|
Dedicated, session-isolated container image for running the Artemis Autonomous AI Agent on Google Cloud **Container-Optimized OS (COS)**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Architecture & Lifecycle
|
||||||
|
|
||||||
|
When a user initiates a session via the [Backend Manager](../backend_manager/README.md), the backend dynamically spawns an instance of this container named `artemis-session-<session_id>` on the shared `artemis-net` bridge network.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔑 Key Features
|
||||||
|
|
||||||
|
1. **Automated ADB Bridging**:
|
||||||
|
- The container entrypoint automatically connects to the target Cuttlefish instance with automatic retry handling.
|
||||||
|
|
||||||
|
2. **Multimodal Perception & Toolchain**:
|
||||||
|
- Packaged with Android Platform Tools, ffmpeg, OpenCV libraries, and Python.
|
||||||
|
|
||||||
|
3. **Real-time Event Streaming**:
|
||||||
|
- Hosts the Artemis Admin Console server exposing SSE and WebSocket endpoints for live streaming agent reasoning, thought steps, and action execution directly to the frontend.
|
||||||
|
|
||||||
|
4. **Dynamic Selector & Coordinate Fallback Engine**:
|
||||||
|
- Drives real-time automated navigation on the connected Cuttlefish emulator using Artemis's multimodal reasoning pipeline.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Directory Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
playground/artemis_container/
|
||||||
|
├── Dockerfile # Python 3.12 slim with adb, ffmpeg, OpenCV, and Artemis
|
||||||
|
├── docker-entrypoint.sh # Automated ADB connection loop & service startup
|
||||||
|
├── docker-compose.yml # Compose spec for testing standalone session
|
||||||
|
├── .dockerignore
|
||||||
|
└── README.md # Documentation & operational guide
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Building & Running
|
||||||
|
|
||||||
|
### 1. Build the Artemis Container Image
|
||||||
|
From the repository root:
|
||||||
|
```bash
|
||||||
|
docker build -f playground/artemis_container/Dockerfile -t artemis:latest .
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Run Standalone with Docker CLI
|
||||||
|
```bash
|
||||||
|
# Ensure bridge network exists
|
||||||
|
docker network create artemis-net || true
|
||||||
|
|
||||||
|
# Run Artemis session container targeting Cuttlefish on port 6520
|
||||||
|
docker run -d \
|
||||||
|
--name artemis-session-sample \
|
||||||
|
--network artemis-net \
|
||||||
|
--add-host host.docker.internal:host-gateway \
|
||||||
|
-e SESSION_ID=sample-123 \
|
||||||
|
-e ADB_DEVICE_SERIAL=host.docker.internal:6520 \
|
||||||
|
-e GEMINI_API_KEY="your-gemini-key" \
|
||||||
|
-p 8080:8080 \
|
||||||
|
artemis:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Run with Docker Compose (Test Setup)
|
||||||
|
```bash
|
||||||
|
cd playground/artemis_container
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Verification & Health Check
|
||||||
|
|
||||||
|
1. **Verify ADB Connection inside Container**:
|
||||||
|
```bash
|
||||||
|
docker exec -it artemis-session-sample adb devices
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Verify Server Health Probe**:
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8080/api/system/health
|
||||||
|
# Returns: {"status": "ok", ...}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Verify Trace Streaming**:
|
||||||
|
```bash
|
||||||
|
curl -N http://localhost:8080/stream/events
|
||||||
|
# Real-time Server-Sent Events stream
|
||||||
|
```
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# Copyright 2026 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
artemis-session:
|
||||||
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: playground/artemis_container/Dockerfile
|
||||||
|
container_name: artemis-session-sample
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
environment:
|
||||||
|
- SESSION_ID=sample-session-123
|
||||||
|
- ADB_DEVICE_SERIAL=host.docker.internal:6520
|
||||||
|
- PORT=8080
|
||||||
|
- PYTHONUNBUFFERED=1
|
||||||
|
# Model & Perception API Keys (pass from host environment)
|
||||||
|
- GEMINI_API_KEY=${GEMINI_API_KEY}
|
||||||
|
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||||
|
networks:
|
||||||
|
- artemis-net
|
||||||
|
extra_hosts:
|
||||||
|
# Allows reaching Cuttlefish emulator running on the COS VM host network
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8080/api/system/health"]
|
||||||
|
interval: 15s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
|
networks:
|
||||||
|
artemis-net:
|
||||||
|
name: artemis-net
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2026 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "=================================================="
|
||||||
|
echo " ARTEMIS SESSION CONTAINER INITIALIZATION"
|
||||||
|
echo " Session ID : ${SESSION_ID:-standalone-dev}"
|
||||||
|
echo " ADB Target : ${ADB_DEVICE_SERIAL:-not-configured}"
|
||||||
|
echo "=================================================="
|
||||||
|
|
||||||
|
# Start ADB daemon inside container
|
||||||
|
adb start-server
|
||||||
|
|
||||||
|
# If ADB target is specified, attempt connection with retry loop
|
||||||
|
if [ -n "$ADB_DEVICE_SERIAL" ]; then
|
||||||
|
# Resolve host gateway IP if targeting host.docker.internal on Linux bridge
|
||||||
|
TARGET_SERIAL="$ADB_DEVICE_SERIAL"
|
||||||
|
if [[ "$ADB_DEVICE_SERIAL" == host.docker.internal:* ]]; then
|
||||||
|
PORT_PART="${ADB_DEVICE_SERIAL#host.docker.internal:}"
|
||||||
|
DEFAULT_GW=$(ip route show default 2>/dev/null | awk '{print $3}' | head -n1)
|
||||||
|
if [ -n "$DEFAULT_GW" ]; then
|
||||||
|
echo "[Artemis Entrypoint] Detected bridge gateway IP: ${DEFAULT_GW} for host.docker.internal"
|
||||||
|
TARGET_SERIAL="${DEFAULT_GW}:${PORT_PART}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[Artemis Entrypoint] Connecting to target Android device at ${TARGET_SERIAL}..."
|
||||||
|
|
||||||
|
MAX_RETRIES=15
|
||||||
|
RETRY_COUNT=0
|
||||||
|
CONNECTED=false
|
||||||
|
|
||||||
|
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
|
||||||
|
echo "[Artemis Entrypoint] Attempting adb connect ${TARGET_SERIAL} (Attempt $((RETRY_COUNT + 1))/${MAX_RETRIES})..."
|
||||||
|
CONNECT_OUTPUT=$(adb connect "${TARGET_SERIAL}" 2>&1 || true)
|
||||||
|
echo " -> ${CONNECT_OUTPUT}"
|
||||||
|
|
||||||
|
# Check if connected
|
||||||
|
if echo "${CONNECT_OUTPUT}" | grep -q "connected to"; then
|
||||||
|
CONNECTED=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
RETRY_COUNT=$((RETRY_COUNT + 1))
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$CONNECTED" = true ]; then
|
||||||
|
echo "[Artemis Entrypoint] ADB successfully connected to ${TARGET_SERIAL}."
|
||||||
|
else
|
||||||
|
echo "[Artemis Entrypoint] Warning: Could not establish immediate ADB connection to ${TARGET_SERIAL}. Container will continue; agent will reconnect on demand."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# List currently attached devices
|
||||||
|
echo "[Artemis Entrypoint] Active ADB Devices:"
|
||||||
|
adb devices -l
|
||||||
|
|
||||||
|
echo "[Artemis Entrypoint] Starting Artemis Admin Console & Agent Server on port ${PORT:-8080}..."
|
||||||
|
exec "$@"
|
||||||
Reference in new issue
Block a user