Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,4 @@ installer/*.dbc
# Keep example.dbc
!installer/example.dbc

installer/slackbot/logs/*
17 changes: 16 additions & 1 deletion installer/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,19 @@ SCAN_INTERVAL_SECONDS=3600
VITE_API_BASE_URL=http://localhost:8000
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173

# End Data Downloader configuration
# End Data Downloader configuration

# ------------------------------------------------------------
# AI Code Generation (Sandbox) configuration
# ------------------------------------------------------------
# Cohere API key for AI-powered code generation
COHERE_API_KEY=your-cohere-api-key-here

# Cohere model to use (default: command-r-plus)
COHERE_MODEL=command-r-plus

# Maximum number of retries when generated code fails (default: 2)
MAX_RETRIES=2

# InfluxDB database name for telemetry queries (default: telemetry)
INFLUXDB_DATABASE=telemetry
35 changes: 34 additions & 1 deletion installer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ All secrets and tokens are defined in `.env`. The defaults provided in `.env.exa
| `SLACK_WEBHOOK_URL` | Incoming webhook for notifications (optional) | empty |
| `SLACK_DEFAULT_CHANNEL` | Default Slack channel ID for outbound messages | `C0123456789` |
| `FILE_UPLOADER_WEBHOOK_URL` | Webhook invoked after uploads complete | inherits `SLACK_WEBHOOK_URL` |
| `COHERE_API_KEY` | Cohere API key for AI-powered code generation | empty |
| `COHERE_MODEL` | Cohere model to use | `command-a-03-2025` |
| `MAX_RETRIES` | Maximum retries for failed code execution | `2` |
| `INFLUXDB_DATABASE` | Database name for telemetry queries | `telemetry` |
| `DEBUG` | Enables verbose logging for selected services | `0` |

> **Security reminder:** Replace every default value when deploying outside of a local development environment. Generate secure tokens with `python3 -c "import secrets; print(secrets.token_urlsafe(32))"`.
Expand All @@ -69,10 +73,12 @@ All secrets and tokens are defined in `.env`. The defaults provided in `.env.exa
| `data-downloader` | `3000` | Periodically downloads CAN CSV archives from the DAQ server. Visual SQL query builder included. |
| `telegraf` | n/a | Collects CAN metrics produced by the importer and forwards them to InfluxDB. |
| `grafana` | `8087` | Visualises telemetry with pre-provisioned dashboards. |
| `slackbot` | n/a | Socket-mode Slack bot for notifications and automation (optional). |
| `slackbot` | n/a | Socket-mode Slack bot for notifications and automation (optional). Integrates with code-generator for AI queries. |
| `lap-detector` | `8050` | Dash-based lap analysis web application. |
| `startup-data-loader` | n/a | Seeds InfluxDB with sample CAN frames on first boot. |
| `file-uploader` | `8084` | Web UI for uploading CAN CSV archives and streaming them into InfluxDB. |
| `sandbox` | n/a | Custom Python execution environment with internet access for running AI-generated code and InfluxDB queries. |
| `code-generator` | `3030` (internal) | AI-powered code generation service using Cohere. Generates Python code from natural language. |

## Data and DBC files

Expand All @@ -89,6 +95,33 @@ All secrets and tokens are defined in `.env`. The defaults provided in `.env.exa
- **Service fails to connect to InfluxDB** – Confirm the token in `.env` matches `influxdb3-admin-token.json`. Regenerate the volumes with `docker compose down -v` if you rotate credentials.
- **Re-import sample data** – Remove the `telegraf-data` volume and rerun the stack.
- **Slack services are optional** – Leave Slack variables empty or set `ENABLE_SLACK=false` to skip starting the bot during development.
- **AI code generation not working** – Ensure `COHERE_API_KEY` is set in `.env`. Check logs with `docker compose logs code-generator`.
- **Sandbox execution fails** – Verify sandbox container is running with `docker ps | grep sandbox`. Check logs with `docker compose logs sandbox`.

## AI-Powered Code Generation

The stack includes an AI-powered code generation service that allows natural language queries via Slack:

**Usage:**
```
!agent plot battery voltage over the last hour
!agent show me motor temperature correlation with RPM
!agent analyze inverter efficiency
```

**Features:**
- Automatic code generation from natural language using Cohere AI
- Self-correcting retry mechanism (up to 2 retries on failure)
- Secure sandboxed execution environment
- Auto-generation of plots and visualizations
- Direct InfluxDB access for telemetry queries

**Setup:**
1. Add `COHERE_API_KEY` to your `.env` file
2. Optional: Configure `COHERE_MODEL` and `MAX_RETRIES`
3. Services start automatically with the stack

See `sandbox/README.md` for detailed documentation.

## Next steps

Expand Down
52 changes: 51 additions & 1 deletion installer/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,24 +108,29 @@ services:
SLACK_APP_TOKEN: ${SLACK_APP_TOKEN:-}
SLACK_WEBHOOK_URL: ${SLACK_WEBHOOK_URL:-}
SLACK_DEFAULT_CHANNEL: ${SLACK_DEFAULT_CHANNEL:-C0123456789}
ENABLE_SLACK: ${ENABLE_SLACK:-false}
INFLUXDB_ADMIN_TOKEN: "${INFLUXDB_ADMIN_TOKEN:-apiv3_dev-influxdb-admin-token}"
INFLUXDB_URL: "${INFLUXDB_URL:-http://influxdb3:8181}"
CODE_GENERATOR_URL: "http://code-generator:3030"
volumes:
- ./slackbot:/app
working_dir: /app
command: >
sh -c '
if [ "$ENABLE_SLACK" = "true" ]; then
echo "Slackbot enabled, starting...";
python slack_bot.py;
python -u slack_bot.py;
else
echo "Slackbot disabled (ENABLE_SLACK=$ENABLE_SLACK). Exiting.";
sleep 5;
exit 0;
fi
'
depends_on:
- code-generator
networks:
- datalink
- default

lap-detector:
build: ./lap-detector
Expand Down Expand Up @@ -246,3 +251,48 @@ services:
depends_on:
data-downloader-api:
condition: service_started

# Custom sandbox execution container (with internet access for InfluxDB queries)
sandbox:
build:
context: ./sandbox
dockerfile: Dockerfile.sandbox
container_name: sandbox
restart: unless-stopped
environment:
SANDBOX_PORT: 8080
SANDBOX_TIMEOUT: 30
SANDBOX_MAX_FILE_MB: 5
SANDBOX_MAX_FILES: 10
INFLUXDB_URL: ${INFLUXDB_URL:-http://influxdb3:8181}
INFLUXDB_ADMIN_TOKEN: ${INFLUXDB_ADMIN_TOKEN}
INFLUXDB_DATABASE: ${INFLUXDB_DATABASE:-telemetry}
depends_on:
- influxdb3
networks:
- datalink

# Code generator - Cohere integration for AI-powered code generation
code-generator:
build:
context: ./sandbox
dockerfile: Dockerfile
container_name: code-generator
restart: unless-stopped
environment:
COHERE_API_KEY: ${COHERE_API_KEY}
COHERE_MODEL: ${COHERE_MODEL:-command-r-plus}
SANDBOX_URL: "http://sandbox:8080"
MAX_RETRIES: ${MAX_RETRIES:-2}
CODE_GEN_PORT: 3030
INFLUXDB_URL: ${INFLUXDB_URL:-http://influxdb3:8181}
INFLUXDB_ADMIN_TOKEN: ${INFLUXDB_ADMIN_TOKEN}
INFLUXDB_DATABASE: ${INFLUXDB_DATABASE:-telemetry}
depends_on:
- sandbox
- influxdb3
volumes:
- ./sandbox/generated:/app/generated
- ./sandbox/prompt-guide.txt:/app/prompt-guide.txt
networks:
- datalink
16 changes: 16 additions & 0 deletions installer/sandbox/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
generated/
generated_sandbox_code.py
*.pyc
__pycache__/
.env
*.png
*.jpg
*.jpeg
*.gif
*.svg
*.pdf
*.csv
output.*

# Custom prompt engineering (use prompt-guide.txt.example as template)
prompt-guide.txt
20 changes: 20 additions & 0 deletions installer/sandbox/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM python:3.12-slim

WORKDIR /app

# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY code_generator.py .
COPY prompt-guide.txt .

# Create directory for generated code
RUN mkdir -p /app/generated

# Expose port
EXPOSE 3030

# Run the service
CMD ["python", "code_generator.py"]
51 changes: 51 additions & 0 deletions installer/sandbox/Dockerfile.sandbox
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
FROM python:3.11-slim

ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1

WORKDIR /app

# System deps for scientific Python + Chromium (ARM64 compatible)
# Chromium is for Kaleido image export (used by Plotly, 3D plot rendering.)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
chromium \
chromium-sandbox \
libx11-6 \
libxext6 \
libxrender1 \
libxtst6 \
libxss1 \
libnss3 \
libatk1.0-0 \
libatk-bridge2.0-0 \
libcups2 \
libdrm2 \
libxcomposite1 \
libxdamage1 \
libxrandr2 \
libgbm1 \
libasound2 \
fonts-liberation \
&& rm -rf /var/lib/apt/lists/*

COPY requirements-docker.txt /tmp/requirements-docker.txt
RUN pip install --upgrade pip \
&& pip install --no-cache-dir -r /tmp/requirements-docker.txt \
&& rm -rf /root/.cache/pip

# Tell Kaleido where Chromium lives
ENV CHROME_PATH=/usr/bin/chromium

# Verify
RUN python3 - <<EOF
import plotly.express as px
fig = px.line(x=[1,2,3], y=[1,4,9])
fig.write_image("test.png")
print("PNG export OK")
EOF

COPY . /app

EXPOSE 8080
CMD ["python3", "sandbox_server.py"]
Loading