Skip to content
Closed
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ repos:
- --config-file=pyproject.toml
- --install-types
- --non-interactive
exclude: ^test
exclude: ^test/

- repo: https://github.com/pre-commit/mirrors-eslint
rev: 'v9.39.1'
Expand All @@ -125,11 +125,11 @@ repos:
# hooks:
# - id: python-safety-dependencies-check

# - repo: https://github.com/asottile/pyupgrade
# rev: v3.19.0
# hooks:
# - id: pyupgrade
# args: [--py313-plus]
- repo: https://github.com/asottile/pyupgrade
rev: v3.19.0
hooks:
- id: pyupgrade
args: [--py313-plus]

# - repo: https://github.com/bridgecrewio/checkov
# rev: '3.2.327'
Expand Down
99 changes: 96 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
createTypeScriptEnvironment installTypeScriptRequirements \
deploy destroy \
clean cleanTypeScript cleanPython cleanCfn cleanMisc \
help dockerCheck dockerLogin listStacks modelCheck buildNpmModules
help dockerCheck dockerLogin listStacks modelCheck buildNpmModules \
test test-coverage test-lambda test-mcp-workbench test-sdk test-rest-api test-sdk-integ test-integ test-rag-integ test-metadata-integ \
lock-poetry validate-deps

#################################################################################
# GLOBALS #
Expand Down Expand Up @@ -138,6 +140,7 @@ installPythonRequirements:
CC=/usr/bin/gcc10-gcc CXX=/usr/bin/gcc10-g++ pip3 install pip --upgrade
CC=/usr/bin/gcc10-gcc CXX=/usr/bin/gcc10-g++ pip3 install --prefer-binary -r requirements-dev.txt
CC=/usr/bin/gcc10-gcc CXX=/usr/bin/gcc10-g++ pip3 install -e lisa-sdk
CC=/usr/bin/gcc10-gcc CXX=/usr/bin/gcc10-g++ pip3 install -e lib/serve/mcp-workbench

## Set up TypeScript interpreter environment
createTypeScriptEnvironment:
Expand Down Expand Up @@ -366,14 +369,104 @@ help:
}' \
| more $(shell test $(shell uname) = Darwin && echo '--no-init --raw-control-chars')

## Run Python tests with coverage report
## Run all Python unit tests (non-integration) with coverage report
test-coverage:
pytest --verbose \
@echo "Running lambda tests with coverage..."
@pytest test/lambda --verbose \
--cov lambda \
--cov-report term-missing \
--cov-report html:build/coverage \
--cov-report xml:build/coverage/coverage.xml \
--cov-fail-under 83
@echo ""
@echo "Running MCP Workbench tests with coverage..."
@pytest test/mcp-workbench --verbose \
--cov lib/serve/mcp-workbench/src \
--cov-report term-missing \
--cov-report html:build/coverage-mcp \
--cov-report xml:build/coverage-mcp/coverage.xml \
--cov-append \
--cov-fail-under 83
@echo ""
@echo "Running SDK tests with coverage..."
@pytest test/sdk --verbose \
--cov lisa-sdk/lisapy \
--cov-report term-missing \
--cov-report html:build/coverage-sdk \
--cov-report xml:build/coverage-sdk/coverage.xml \
--cov-append \
--cov-fail-under 80
@echo ""
@echo "Running REST API tests with coverage..."
@pytest test/rest-api --verbose \
--cov lib/serve/rest-api/src \
--cov-config lib/serve/rest-api/.coveragerc \
--cov-report term-missing \
--cov-report html:build/coverage-rest-api \
--cov-report xml:build/coverage-rest-api/coverage.xml \
--cov-append \
--cov-fail-under 80


## Run all Python unit tests (non-integration) without coverage
test:
@echo "Running lambda tests..."
@pytest test/lambda --verbose
@echo ""
@echo "Running MCP Workbench tests..."
@pytest test/mcp-workbench --verbose
@echo ""
@echo "Running SDK tests..."
@pytest test/sdk --verbose
@echo ""
@echo "Running REST API tests..."
@pytest test/rest-api --verbose

## Run lambda tests only
test-lambda:
pytest test/lambda --verbose

## Run MCP Workbench tests only
test-mcp-workbench:
pytest test/mcp-workbench --verbose

## Run LISA SDK unit tests only
test-sdk:
pytest test/sdk --verbose

## Run REST API unit tests only
test-rest-api:
pytest test/rest-api --verbose

## Run LISA SDK integration tests (requires deployed LISA environment)
test-sdk-integ:
@echo "Running LISA SDK integration tests..."
@echo "Note: These tests require a deployed LISA environment with:"
@echo " - --api or --url argument for API endpoint"
@echo " - --region, --deployment, --profile arguments"
@echo " - AWS credentials configured"
@echo ""
@echo "Example: pytest test/integration/sdk --api https://your-api.com --region us-west-2"
@echo ""
pytest test/integration/sdk --verbose

## Run integration tests (Python-based)
test-integ:
pytest test/python --verbose

## Run RAG integration tests (requires deployed LISA environment)
test-rag-integ:
@echo "Running RAG integration tests..."
@echo "Note: These tests require a deployed LISA environment with:"
@echo " - LISA_API_URL environment variable set"
@echo " - LISA_DEPLOYMENT_NAME environment variable set"
@echo " - AWS credentials configured"
@echo ""
pytest test/integration --verbose

## Run repository metadata preservation integration tests
test-metadata-integ:
pytest test/integration/test_repository_update_metadata_preservation.py --verbose

## Regenerate all Poetry lock files
lock-poetry:
Expand Down
Binary file removed assets/LisaArchitecture.png
Binary file not shown.
Binary file removed assets/LisaChat.png
Binary file not shown.
Binary file removed assets/LisaModelManagement.png
Binary file not shown.
Binary file removed assets/LisaServe.png
Binary file not shown.
6 changes: 3 additions & 3 deletions bin/build-images
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ build_all_images() {
build_image "Dockerfile" "lisa-rest-api" "$LISA_VERSION" "./lib/serve/rest-api" \
"NODE_ENV=production" \
"LITELLM_CONFIG=\"db_key: sk-a8814208-0388-480c-9fc7-fea59607ca38\"" \
"BASE_IMAGE=python:3.13-slim"
"BASE_IMAGE=public.ecr.aws/docker/library/python:3.13-slim"

# lisa-batch-ingestion
RAG_DIR="./lib/rag/ingestion/ingestion-image"
Expand All @@ -130,7 +130,7 @@ build_all_images() {
MCP_DIR="./lib/serve/mcp-workbench"
build_image "Dockerfile" "lisa-mcp-workbench" "$LISA_VERSION" "$MCP_DIR" \
"NODE_ENV=production" \
"BASE_IMAGE=python:3.13-slim"
"BASE_IMAGE=public.ecr.aws/docker/library/python:3.13-slim"
else
echo "deployMcpWorkbench is disabled, skipping lisa-mcp-workbench build"
echo ""
Expand All @@ -151,7 +151,7 @@ build_all_images() {
# lisa-vllm
build_image "Dockerfile" "lisa-vllm" "latest" "./lib/serve/ecs-model/vllm" \
"NODE_ENV=production" \
"BASE_IMAGE=vllm/vllm-openai:latest" \
"BASE_IMAGE=public.ecr.aws/deep-learning-containers/vllm:0.13-gpu-py312" \
"MOUNTS3_DEB_URL=https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.deb"

echo "All images built successfully!"
Expand Down
1 change: 1 addition & 0 deletions cypress/src/e2e/fixtures/test-document.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
In the quiet town of Maplewood, there lived a cat named Whiskers. 𝒲hiskers, unlike other cats, had a penchant for adventure. One sunny afternoon, while exploring the attic, he stumbled upon an old, dusty book. 𝒞urious, he pawed at the cover until it opened to a page detailing a hidden treasure in the nearby forest. 𝒲hiskers, with his adventurous spirit, decided to embark on a quest. Armed with nothing but his curiosity, he ventured into the woods, guided by the book's cryptic clues. As the sun set, he found himself at the edge of a shimmering lake, where the treasure was said to be hidden. To his surprise, the lake reflected not gold, but the beauty of the world around him. 𝒲hiskers realized that sometimes, the greatest treasure is the journey itself. 𝒞ontent with his discovery, he returned home, ready for his next adventure.
3 changes: 2 additions & 1 deletion cypress/src/e2e/specs/bedrock-model-workflow.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import { runBedrockModelWorkflowTests } from '../../shared/specs/bedrock-model-w

describe('Bedrock Model Workflow (E2E)', () => {
before(() => {
cy.clearAllSessionStorage();
// Clear Cypress session cache to allow fresh login
Cypress.session.clearAllSavedSessions();
});

beforeEach(() => {
Expand Down
51 changes: 46 additions & 5 deletions cypress/src/e2e/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Cypress.Commands.add('loginAs', (role = 'user') => {
.click({ force: true });
});

// Wait for redirect back to app
// Wait for redirect back to app and allow configuration to load
cy.wait(2000);
});
});
Expand All @@ -155,16 +155,57 @@ Cypress.Commands.add('loginAs', (role = 'user') => {
expect(hasOidcToken).to.equal(true);
});
},
cacheAcrossSpecs: true,
cacheAcrossSpecs: false,
}
);

// After session restore/setup, Cypress clears the page
// We must visit again and wait for APIs
// After session restore/setup, Cypress clears the page which may have cancelled
// in-flight API requests. Selectively clear API cache reducers to ensure cancelled
// requests don't pollute the cache, while preserving user preferences.
cy.window().then((win) => {
const persistedState = win.localStorage.getItem('persist:lisa');
if (persistedState) {
try {
const state = JSON.parse(persistedState);
// Clear only API cache reducers that may have stale/cancelled data
// Preserve: user, userPreferences, notification, modal, breadcrumbGroup
const apiReducersToReset = [
'models', // modelManagementApi.reducerPath
'configuration', // configurationApi.reducerPath
'sessions', // sessionApi.reducerPath
'rag', // ragApi.reducerPath
'promptTemplates', // promptTemplateApi.reducerPath
'mcpServers', // mcpServerApi.reducerPath
'mcpTools', // mcpToolsApi.reducerPath
'apiTokens', // apiTokenApi.reducerPath
'userPreferences', // userPreferencesApi.reducerPath
];
apiReducersToReset.forEach((key) => {
if (state[key]) {
delete state[key];
}
});
win.localStorage.setItem('persist:lisa', JSON.stringify(state));
} catch {
// If parsing fails, remove the entire persisted state
win.localStorage.removeItem('persist:lisa');
}
}
});

// Set up intercepts BEFORE visiting so they catch all requests
// cy.session() clears all intercepts, so we must set them up fresh here
setupApiIntercepts();

// Visit the app - intercepts are now ready to catch requests
cy.visit(BASE_URL);

// Wait for app to be ready using DOM-based assertions
waitForAppReady();
waitForCriticalApis();

// Now wait for the critical configuration API to complete
// This ensures the app has loaded its configuration before tests proceed
// waitForCriticalApis();

log.snapshot('after');
log.end();
Expand Down
Loading
Loading