Commit 8398a83f authored by Dimitrios Gogos's avatar Dimitrios Gogos
Browse files

Merge branch 'develop' into 'main'

Release 2.0.0: AI² with per-user auth, more OEG tools, chat memory and Helm chart

See merge request !9
parents 3cc859b1 79fbcea8
Loading
Loading
Loading
Loading
Loading
+14 −1
Changes for README.md: 14 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -19,9 +19,22 @@ The MCP Module implements an MCP server that exposes **CAMARA-compliant APIs** v
AI Agent is a lightweight, modular backend built with **[`FastAPI`](https://fastapi.tiangolo.com/)** that exposes REST API endpoints for interacting with multiple AI sub-agents. 

It is designed to be easily extensible with support for different LLMs and OpenOP MCP servers.
It keeps a short per-session chat memory in Redis when `REDIS_URL` is set.

---
## Authentication

Every request carries the user's Keycloak access token (`Authorization: Bearer …`). The agent
passes it to the MCP server, which sends it to OEG, so the user's own roles decide what AI2 may
do. `AUTH_ENABLED=false` turns this off for platforms deployed without login.

## Repository layout

| Path | Contents |
|---|---|
| [`mcp_module/`](mcp_module/README.md) | MCP server |
| [`ai_agent/`](ai_agent/README.md) | AI Agent |
| [`deployment/docker/`](deployment/docker/README.md) | Docker Compose for both modules and Redis |
| [`deployment/helm/`](deployment/helm/README.md) | Helm chart, the same one the platform chart deploys |
| `tests/` | Unit tests for both modules (`pytest`) |

---
+8 −5
Changes for ai_agent/README.md: 8 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -12,8 +12,11 @@ ai_agent/
├── routes/                # API route definitions
│   ├── groq.py             # Groq-related endpoints
│   └── debug.py            # Debug / health endpoints
├── .env                   # Environment variables
├── prompts/               # System prompts for the agent and its memory
├── memory.py              # Redis session memory
├── security.py            # Bearer token check
├── app.py                 # Application entry point
├── Dockerfile
├── requirements.txt       # Python dependencies
```

@@ -67,8 +70,8 @@ MEMORY_KEY_PREFIX=ai_agent:session
### 1. Clone the Repository

```
git clone <your-repo-url>
cd ai_agent
git clone https://labs.etsi.org/rep/oop/code/ai2.git
cd ai2
```

### 2. Create a Virtual Environment (Recommended)
@@ -82,7 +85,7 @@ venv\Scripts\activate # Windows
### 3. Install Dependencies

```
pip install -r requirements.txt
pip install -r ai_agent/requirements.txt
```

### 4. Configure Environment Variables
@@ -104,7 +107,7 @@ docker build -t ai_agent .

Follow these steps to set up and run the app locally.

Start the backend server using:
Start the backend server from the repository root using:

```
python -m ai_agent.app
+4 −0
Changes for deployment/docker/README.md: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -13,6 +13,9 @@ OEG_SERVICE_URL=http://your-oeg-api-url
GROQ_MODEL_NAME=qwen/qwen3.8-27b
```

Optional, with the defaults the compose file uses: `REDIS_URL` (`redis://redis:6379/0`),
`MEMORY_WINDOW_TURNS` (`10`) and `MEMORY_TTL_SECONDS` (`3600`) for the agent's session memory.

## Run
Start services
```
@@ -31,5 +34,6 @@ This allows you to interact with APIs and MCP servers individually, without atta
|-----------|-----------|
| mcp       | 8004      |
| ai-agent  | 9013      |
| redis     | 6385      |

---
 No newline at end of file
+22 −56
Changes for deployment/helm/README.md: 22 added lines, 56 removed lines.
Original line number Diff line number Diff line
# AI2 Helm Chart

Deploys the AI2 stack — MCP server and AI Agent — into a Kubernetes cluster.
`ai2/` is the same chart the platform deploys as a subchart of `oop-platform-chart` in the helm
repository; change it there and copy it here. See [ai2/README.md](ai2/README.md) for its values.

## Components

| Component  | Description                                              | Default Port |
|------------|----------------------------------------------------------|-------------|
| mcp        | MCP server exposing CAMARA-compliant tools via FastMCP   | 8004        |
| ai-agent   | Quart backend accepting natural language prompts via Groq | 9013        |

The ai-agent waits for the MCP server to be healthy before starting (via initContainer).
It deploys the MCP server, the AI Agent and a Redis for the agent's session memory. The ai-agent
waits for the MCP server to be healthy before starting (via initContainer).

## Prerequisites

@@ -20,27 +15,24 @@ The ai-agent waits for the MCP server to be healthy before starting (via initCon

## Install

Fetch the Bitnami Redis dependency before installing:

```bash
helm dependency update ./deployment/helm/ai2
```

```bash
helm install ai2test ./helm/ai2 \
helm install ai2test ./deployment/helm/ai2 \
  --namespace ai2test \
  --create-namespace \
  --set secrets.groqApiKey=<your-groq-api-key> \
  --set config.mcp.oegServiceUrl=http://<oeg-host>
  --set mcp.oegUrl=http://<oeg-host>
```

Without the umbrella chart there is no Keycloak; add `--set global.auth.enabled=false` to call
AI2 without a token.

## Upgrade

```bash
helm upgrade ai2test ./helm/ai2 \
helm upgrade ai2test ./deployment/helm/ai2 \
  --namespace ai2test \
  --set secrets.groqApiKey=<your-groq-api-key> \
  --set config.mcp.oegServiceUrl=http://<new-oeg-host>
  --reuse-values \
  --set mcp.oegUrl=http://<new-oeg-host>
```

## Uninstall
@@ -49,59 +41,33 @@ helm upgrade ai2test ./helm/ai2 \
helm uninstall ai2test --namespace ai2test
```

## Key Values

| Value                           | Description                      | Default                  |
|---------------------------------|----------------------------------|--------------------------|
| `secrets.groqApiKey`            | Groq API key (required)          | `""`                     |
| `config.mcp.oegServiceUrl`      | Base URL of the OEG service      | `http://oeg`   |
| `config.aiAgent.groqModelName`  | Groq model identifier            | `qwen/qwen3.8-27b`         |
| `service.mcp.type`              | Kubernetes service type for MCP  | `NodePort`               |
| `service.mcp.nodePort`          | NodePort for MCP                 | `32004`                  |
| `service.aiAgent.nodePort`      | NodePort for ai-agent            | `32013`                  |
| `redis.enabled`                 | Deploy Redis for agent memory    | `true`                   |
| `redis.master.service.ports.redis` | Bitnami Redis service port     | `6379`                   |
| `redis.memory.database`         | Redis database index for AI memory | `0`                    |
| `config.aiAgent.memoryWindowTurns` | Recent turns retained in memory | `10`                    |
| `config.aiAgent.memoryTtlSeconds` | Session memory TTL in seconds   | `3600`                  |
| `config.aiAgent.memoryKeyPrefix` | Redis key prefix                 | `ai_agent:session`       |
| `images.mcp.tag`                | MCP image tag                    | `latest`                 |
| `images.aiAgent.tag`            | AI Agent image tag               | `latest`                 |

## Local Development (kind)

Build and load images locally instead of pulling from the registry:

```bash
docker build -t <your_mcp_dev_image>:latest ../../mcp_module
docker build -t <your_ai_agent_dev_image>:latest ../../ai_agent
docker build -t <your_mcp_dev_image>:latest mcp_module
docker build -t <your_ai_agent_dev_image>:latest ai_agent

kind load docker-image <your_mcp_dev_image>:latest --name <your-cluster>
kind load docker-image <your_ai_agent_dev_image>:latest --name <your-cluster>
```

Then install with `pullPolicy: IfNotPresent` to use the local images:
Then install with those images, exposed on NodePorts:

```bash
helm install ai2 ./helm/ai2 \
helm install ai2 ./deployment/helm/ai2 \
  --namespace ai2test \
  --create-namespace \
  --set secrets.groqApiKey=<your-groq-api-key> \
  --set config.mcp.oegServiceUrl=http://<oeg-host> \
  --set images.mcp.pullPolicy=IfNotPresent \
  --set images.aiAgent.pullPolicy=IfNotPresent
  --set mcp.oegUrl=http://<oeg-host> \
  --set global.auth.enabled=false \
  --set mcp.image.repository=<your_mcp_dev_image>,mcp.image.tag=latest \
  --set aiAgent.image.repository=<your_ai_agent_dev_image>,aiAgent.image.tag=latest \
  --set mcp.service.type=NodePort,mcp.service.nodePort=32004 \
  --set aiAgent.service.type=NodePort,aiAgent.service.nodePort=32013
```

## Redis Memory

Redis is deployed through the Bitnami Redis Helm chart dependency as an in-cluster service and is used by the AI agent for optional short-term session memory. The generated agent value is:

```bash
REDIS_URL=redis://<redis-service>:6379/0
```

This mirrors the Docker Compose Redis container port `6379`; the chart disables Redis auth and persistence by default to match the local cache/session-store behavior. The Compose host mapping `6385:6379` is not represented as a Kubernetes NodePort because Kubernetes NodePorts must normally be in the cluster NodePort range, commonly `30000-32767`.

## Test the Deployment

```bash

deployment/helm/ai2/Chart.lock

deleted100644 → 0
+0 −6
Changes for deployment/helm/ai2/Chart.lock: 0 added lines, 6 removed lines.
Original line number Diff line number Diff line
dependencies:
- name: redis
  repository: oci://registry-1.docker.io/bitnamicharts
  version: 25.5.3
digest: sha256:b680f268339ce6899da9e632b2839d21e8391886211d57f7bcc735c73ffa6e1c
generated: "2026-06-04T11:48:21.792172108+03:00"
Loading