Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ecdeb1f
Implement the cortex daemon functionality and documentation
sujay-d07 Jan 5, 2026
e5000e2
Changing the daemon's working entirely
sujay-d07 Jan 7, 2026
b727408
feat: creating a main daemon setup script, adding a alert dismissal f…
sujay-d07 Jan 7, 2026
684fb35
Update README and daemon documentation; enhance CLI commands and remo…
sujay-d07 Jan 7, 2026
ed043b0
Implement LLM-powered alert analysis in cortexd. Alerts now include a…
sujay-d07 Jan 7, 2026
20a68f6
Fixing ruff and black formatting issues
sujay-d07 Jan 7, 2026
feb9323
Enhance Cortex CLI and Daemon Management
sujay-d07 Jan 9, 2026
dc1b7c7
Enhance Daemon Client and Alert Management
sujay-d07 Jan 9, 2026
8062071
Enhance Thread Safety and Documentation in Daemon Components
sujay-d07 Jan 9, 2026
2ce0dc9
Implement CPU Usage Delta Calculation and Enhance System Monitor Thre…
sujay-d07 Jan 9, 2026
3d77e00
Refactor System Monitor for Enhanced Thread Management and Atomic Int…
sujay-d07 Jan 9, 2026
7c68d1c
Implement the cortex daemon functionality and documentation
sujay-d07 Jan 5, 2026
d1a6547
Refactor LLM integration and update documentation
sujay-d07 Jan 13, 2026
87266f5
Enhance daemon setup process and improve documentation
sujay-d07 Jan 13, 2026
4451d70
Update daemon action error message in Cortex CLI
sujay-d07 Jan 13, 2026
e415f49
Enhance CI workflow with startup time and memory footprint checks
sujay-d07 Jan 13, 2026
d2e3f8a
Enhance daemon installation process in Cortex CLI and Daemon Manager
sujay-d07 Jan 13, 2026
6133231
Enhance alert metadata handling and improve end-to-end test documenta…
sujay-d07 Jan 13, 2026
3950000
Merge branch 'main' into issue-427
Anshgrover23 Jan 13, 2026
dd896d1
Merge branch 'main' into issue-427
sujay-d07 Jan 13, 2026
0c8204f
Merge branch 'main' into issue-427
Anshgrover23 Jan 13, 2026
cbb552a
Merge branch 'cortexlinux:main' into issue-427
sujay-d07 Jan 14, 2026
0b355f0
docs: update README and CLI for cortexd enhancements
sujay-d07 Jan 14, 2026
af380a0
feat: enhance daemon setup with audit logging
sujay-d07 Jan 14, 2026
dbdf43a
refactor: improve code readability in setup_daemon.py using black sta…
sujay-d07 Jan 14, 2026
33bea2d
refactor: enhance model path security check in setup_daemon.py
sujay-d07 Jan 14, 2026
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
270 changes: 259 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,30 @@ jobs:
continue-on-error: true

test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
name: Test (Python ${{ matrix.python-version }} / Ubuntu ${{ matrix.os-version }})
runs-on: ${{ matrix.os }}
needs: lint
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
include:
# Ubuntu 22.04 tests
- os: ubuntu-22.04
os-version: "22.04"
python-version: "3.10"
- os: ubuntu-22.04
os-version: "22.04"
python-version: "3.11"
- os: ubuntu-22.04
os-version: "22.04"
python-version: "3.12"
# Ubuntu 24.04 tests
- os: ubuntu-24.04
os-version: "24.04"
python-version: "3.11"
- os: ubuntu-24.04
os-version: "24.04"
python-version: "3.12"

steps:
- name: Checkout
Expand All @@ -60,9 +77,10 @@ jobs:
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}
key: ${{ runner.os }}-${{ matrix.os-version }}-pip-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-${{ matrix.python-version }}-
${{ runner.os }}-${{ matrix.os-version }}-pip-${{ matrix.python-version }}-
${{ runner.os }}-${{ matrix.os-version }}-pip-
${{ runner.os }}-pip-

- name: Install dependencies
Expand All @@ -84,14 +102,234 @@ jobs:
--ignore=tests/integration

- name: Upload coverage to Codecov
if: matrix.python-version == '3.11'
if: matrix.python-version == '3.11' && matrix.os-version == '22.04'
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
flags: unittests
name: codecov-${{ matrix.python-version }}
name: codecov-${{ matrix.python-version }}-${{ matrix.os-version }}
fail_ci_if_error: false

startup-time-check:
name: Startup Time Check (< 1s)
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Cache pip packages
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-startup-${{ hashFiles('pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-startup-
${{ runner.os }}-pip-

- name: Install dependencies
run: |
python -m pip install -U pip
pip install -e .

- name: Check startup time
env:
ANTHROPIC_API_KEY: "test-key-for-ci"
OPENAI_API_KEY: "test-key-for-ci"
run: |
python << 'EOF'
import subprocess
import time
import sys
import os

THRESHOLD_SECONDS = 1.0
NUM_RUNS = 5

print(f"Testing startup time (threshold: {THRESHOLD_SECONDS}s, runs: {NUM_RUNS})")
print("=" * 50)

times = []
for i in range(NUM_RUNS):
# Clear any Python cache effects with a fresh subprocess
start = time.perf_counter()
result = subprocess.run(
[sys.executable, '-m', 'cortex.cli', '--help'],
capture_output=True,
timeout=30,
env={**os.environ, 'PYTHONDONTWRITEBYTECODE': '1'}
)
elapsed = time.perf_counter() - start
times.append(elapsed)
status = "✓" if elapsed < THRESHOLD_SECONDS else "✗"
print(f" Run {i+1}: {elapsed:.3f}s {status}")

print("=" * 50)
avg_time = sum(times) / len(times)
min_time = min(times)
max_time = max(times)

print(f"Results:")
print(f" Minimum: {min_time:.3f}s")
print(f" Maximum: {max_time:.3f}s")
print(f" Average: {avg_time:.3f}s")
print()

# Use minimum time as the metric (best case, no I/O delays)
if min_time > THRESHOLD_SECONDS:
print(f"::error::Startup time {min_time:.3f}s exceeds {THRESHOLD_SECONDS}s threshold")
sys.exit(1)
else:
print(f"::notice::Startup time check PASSED: {min_time:.3f}s < {THRESHOLD_SECONDS}s")
EOF

memory-footprint-check:
name: Memory Footprint Check
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Cache pip packages
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-memory-${{ hashFiles('pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-memory-
${{ runner.os }}-pip-

- name: Install dependencies
run: |
python -m pip install -U pip
pip install -e .
pip install psutil

- name: Measure memory footprint
env:
ANTHROPIC_API_KEY: "test-key-for-ci"
OPENAI_API_KEY: "test-key-for-ci"
run: |
python << 'EOF'
import subprocess
import sys
import os
import json

# Memory threshold in MB - adjust as needed for your project
MEMORY_THRESHOLD_MB = 150
BASELINE_FILE = '.github/memory-baseline.json'

print(f"Testing memory footprint (threshold: {MEMORY_THRESHOLD_MB} MB)")
print("=" * 50)

# Measure memory for importing cortex module
measure_script = '''
import psutil
import os
import gc

# Force garbage collection before measurement
gc.collect()

# Get baseline memory before import
process = psutil.Process(os.getpid())
baseline_mb = process.memory_info().rss / 1024 / 1024

# Import cortex
import cortex
import cortex.cli

# Force garbage collection after import
gc.collect()

# Measure memory after import
after_import_mb = process.memory_info().rss / 1024 / 1024
import_cost_mb = after_import_mb - baseline_mb

print(f"BASELINE_MB={baseline_mb:.2f}")
print(f"AFTER_IMPORT_MB={after_import_mb:.2f}")
print(f"IMPORT_COST_MB={import_cost_mb:.2f}")
'''

result = subprocess.run(
[sys.executable, '-c', measure_script],
capture_output=True,
text=True,
timeout=60,
env={**os.environ}
)

print(result.stdout)
if result.stderr:
print(f"stderr: {result.stderr}")

# Parse results
metrics = {}
for line in result.stdout.strip().split('\n'):
if '=' in line:
key, value = line.split('=')
metrics[key] = float(value)

after_import = metrics.get('AFTER_IMPORT_MB', 0)
import_cost = metrics.get('IMPORT_COST_MB', 0)

print("=" * 50)
print(f"Results:")
print(f" Total memory after import: {after_import:.2f} MB")
print(f" Memory cost of import: {import_cost:.2f} MB")
print()

# Check for regression against baseline if it exists
baseline_memory = None
if os.path.exists(BASELINE_FILE):
try:
with open(BASELINE_FILE, 'r') as f:
baseline = json.load(f)
baseline_memory = baseline.get('import_cost_mb')
if baseline_memory:
regression = import_cost - baseline_memory
regression_pct = (regression / baseline_memory) * 100
print(f" Baseline: {baseline_memory:.2f} MB")
print(f" Regression: {regression:+.2f} MB ({regression_pct:+.1f}%)")
# Fail if regression is > 20%
if regression_pct > 20:
print(f"::warning::Memory regression of {regression_pct:.1f}% detected")
except (json.JSONDecodeError, KeyError):
pass

# Check against absolute threshold
if after_import > MEMORY_THRESHOLD_MB:
print(f"::error::Memory usage {after_import:.2f} MB exceeds {MEMORY_THRESHOLD_MB} MB threshold")
sys.exit(1)
else:
print(f"::notice::Memory check PASSED: {after_import:.2f} MB < {MEMORY_THRESHOLD_MB} MB")

# Output metrics for potential baseline update
print()
print(f"::set-output name=memory_mb::{after_import:.2f}")
print(f"::set-output name=import_cost_mb::{import_cost:.2f}")
EOF

- name: Save memory metrics artifact
uses: actions/upload-artifact@v4
with:
name: memory-metrics
path: |
memory-report.json
if-no-files-found: ignore

security:
name: Security Scan
runs-on: ubuntu-latest
Expand Down Expand Up @@ -128,9 +366,14 @@ jobs:
safety-report.json

build:
name: Build Package
runs-on: ubuntu-latest
needs: [lint, test]
name: Build Package (${{ matrix.os }})
runs-on: ${{ matrix.os }}
needs: [lint, test, startup-time-check, memory-footprint-check]
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, ubuntu-24.04]

steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -151,8 +394,13 @@ jobs:
- name: Check package
run: twine check dist/*

- name: Test package installation
run: |
pip install dist/*.whl
cortex --help

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist
name: dist-${{ matrix.os }}
path: dist/
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Enhanced contribution guidelines (CONTRIBUTING.md)
- Professional README with full documentation
- This CHANGELOG file
- Daemon LLM health status documentation (docs/DAEMON_LLM_HEALTH_STATUS.md)

### Changed
- Updated README with proper installation instructions
Expand All @@ -25,6 +26,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- For true offline operation, use `export CORTEX_PROVIDER=ollama` instead

### Fixed
- **Daemon**: LLM loaded status now correctly reports "Yes" in `cortex daemon health` when model loads successfully
- Added `set_llm_loaded()` method to SystemMonitor interface
- Main daemon calls this method after successful model load
- Implementation is generic and works with any GGUF model
- (Pending) Shell injection vulnerability in coordinator.py
- (Pending) CI/CD pipeline test directory path

Expand Down
Loading
Loading