Commit 7dd7dd6d authored by Kostas Chartsias's avatar Kostas Chartsias
Browse files

Merge branch 'feature/agent_memory' into 'set-sast-config-1'

# Conflicts:
#   .gitlab-ci.yml
parents ff2d5150 c21535e3
Loading
Loading
Loading
Loading
Loading
+114 −10
Original line number Diff line number Diff line
# You can override the included template(s) by including variable overrides
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
# Secret Detection customization: https://docs.gitlab.com/user/application_security/secret_detection/pipeline/configure
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
# Container Scanning customization: https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings
# Note that environment variables can be set in several places
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
default:
  image: python:3.12-slim
  cache:
    paths:
      - .cache/pip
  before_script:
    - pip install -r "$CI_PROJECT_DIR/mcp_module/requirements.txt"
    - pip install -r "$CI_PROJECT_DIR/ai_agent/requirements.txt"
    - pip install mypy pytest ruff import-linter
    - export PYTHONPATH="$CI_PROJECT_DIR:$PYTHONPATH"

stages:
  - type
  - architecture
  - lint
  - format
  - test
sast:
  stage: test
  - build

variables:
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
  SOURCE_DIRS: "mcp_module/ ai_agent/"
  TEST_DIRS: "tests/"

include:
  - template: Security/SAST.gitlab-ci.yml

sast:
  stage: test

type:
  stage: type
  tags:
    - docker
  script:
    - mypy $SOURCE_DIRS

architecture:
  stage: architecture
  tags:
    - docker
  script:
    - |
      if [ -f "$CI_PROJECT_DIR/.importlinter" ] || \
         [ -f "$CI_PROJECT_DIR/.importlinter.ini" ] || \
         [ -f "$CI_PROJECT_DIR/pyproject.toml" ] || \
         [ -f "$CI_PROJECT_DIR/setup.cfg" ]; then
        lint-imports
      else
        echo "No import-linter config found; skipping architecture check."
      fi

lint:
  stage: lint
  tags:
    - docker
  script:
    - ruff check $SOURCE_DIRS $TEST_DIRS

format:
  stage: format
  tags:
    - docker
  script:
    - ruff format --check $SOURCE_DIRS $TEST_DIRS

test:
  stage: test
  tags:
    - docker
  script:
    - pytest

.variables-template:
  tags:
    - shell
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
    - |
      if [ -n "$CI_COMMIT_TAG" ]; then
        export IMAGE_TAG="$CI_COMMIT_TAG"
      elif [ "$CI_COMMIT_REF_NAME" = "main" ]; then
        export IMAGE_TAG="latest"
      elif [ "$CI_COMMIT_REF_NAME" = "develop" ]; then
        export IMAGE_TAG="develop"
      else
        export IMAGE_TAG="$(echo "$CI_COMMIT_REF_NAME" | tr '/' '-')"
      fi
      echo "Using image tag: $IMAGE_TAG"

build-ai-agent:
  stage: build
  extends: .variables-template
  variables:
    IMAGE_NAME: "ai_agent"
  script:
    - echo "Building ${IMAGE_NAME} image..."
    - docker build -t "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" -f "$CI_PROJECT_DIR/$IMAGE_NAME/Dockerfile" "$CI_PROJECT_DIR/$IMAGE_NAME"
    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
  only:
    - main
    - develop
    - tags

build-mcp-module:
  stage: build
  extends: .variables-template
  variables:
    IMAGE_NAME: "mcp_module"
  script:
    - echo "Building ${IMAGE_NAME} image..."
    - docker build -t "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" -f "$CI_PROJECT_DIR/$IMAGE_NAME/Dockerfile" "$CI_PROJECT_DIR/$IMAGE_NAME"
    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
  only:
    - main
    - develop
    - tags
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ The MCP Module implements an MCP server that exposes **CAMARA-compliant APIs** v


### 2. AI Agent
AI Agent is a lightweight, modular backend built with [`Quart`](https://quart.palletsprojects.com/en/latest/) that exposes REST API endpoints for interacting with multiple AI sub-agents. 
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.

ai_agent/.dockerignore

0 → 100644
+10 −0
Original line number Diff line number Diff line
__pycache__/
*.py[cod]
*.pyo
.pytest_cache/
.venv/
.env
.idea/
.git/
*.log
+1 −1
Original line number Diff line number Diff line
@@ -18,4 +18,4 @@ RUN pip install --no-cache-dir \

COPY . /app/ai_agent

CMD ["python", "-m", "ai_agent.app"]
CMD ["sh", "-c", "uvicorn ai_agent.app:app --host ${APP_HOST:-0.0.0.0} --port ${APP_PORT:-9013}"]
+31 −5
Original line number Diff line number Diff line
# AI Agent 

This repository contains a lightweight **[`Quart`](https://quart.palletsprojects.com/en/latest/) backend server** that exposes API endpoints for interacting with different AI sub-agents. 
This repository contains a lightweight **[`FastAPI`](https://fastapi.tiangolo.com/)** backend server that exposes API endpoints for interacting with different AI sub-agents. 

---

@@ -36,6 +36,12 @@ MCP_SERVER_URL=http://127.0.0.1:8004/mcp
# --- Groq ---
GROQ_API_KEY=your_groq_api_key_here
GROQ_MODEL_NAME=qwen/qwen3-32b

# --- Optional short-term memory (Redis) ---
REDIS_URL=redis://127.0.0.1:6379/0
MEMORY_WINDOW_TURNS=6
MEMORY_TTL_SECONDS=3600
MEMORY_KEY_PREFIX=ai_agent:session
```

### Environment Variables
@@ -47,6 +53,10 @@ GROQ_MODEL_NAME=qwen/qwen3-32b
| `MCP_SERVER_URL`  | URL of the MCP server used by sub-agent |
| `GROQ_API_KEY`    | API key for Groq LLM access             |
| `GROQ_MODEL_NAME` | Groq model identifier                   |
| `REDIS_URL` | Redis DSN for short-term memory (`redis://host:6379/0`) |
| `MEMORY_WINDOW_TURNS` | Number of recent user/assistant turns to retain |
| `MEMORY_TTL_SECONDS` | Session memory TTL in seconds |
| `MEMORY_KEY_PREFIX` | Prefix for Redis session keys |

---

@@ -96,7 +106,7 @@ Follow these steps to set up and run the app locally.
Start the backend server using:

```
python app.py
python -m ai_agent.app
```

The server will start at:
@@ -138,10 +148,26 @@ To add new functionality:
Example:

```
from ai_agent.routes.my_agent import register_my_agent_routes
register_my_agent_routes(app)
from ai_agent.routes.my_agent import router as my_agent_router
app.include_router(my_agent_router)
```

---
## 🧠 Session Memory

When `REDIS_URL` is configured, both Groq endpoints support short-term memory with a sliding window.

- `POST /groq-mcp`: pass `session_id` in the JSON body.
- `GET /groq-mcp/stream`: pass `session_id` as a query parameter.

Example:

```json
{
  "session_id": "user-123-session-a",
  "query": "What did I ask you before?"
}
```

If `REDIS_URL` is missing, the API remains stateless.

---
Loading