Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
2fc6871
Auto-merge main back to develop post release
estohlmann Aug 23, 2025
0f42f2d
Removed session ID from prompt input #371
dustins Aug 25, 2025
bbc965f
Updating MCP to allow for a test server button and fixed post create/…
estohlmann Aug 25, 2025
7267aa9
General UI Enhancements
jmharold Aug 25, 2025
c5ef436
Adding ability to define a default embedding model when creating/upda…
estohlmann Aug 25, 2025
8e694ea
Trim vector store IAM permissions
estohlmann Aug 25, 2025
bf89b95
Time based session grouping
estohlmann Aug 26, 2025
8bf4ce8
Updating Dependencies
bedanley Aug 26, 2025
1e0c448
Fixing document chunk processing
estohlmann Aug 27, 2025
c2302b2
Revert "Fixing document chunk processing"
estohlmann Aug 27, 2025
abc1218
Fixing document chunk processing
estohlmann Aug 27, 2025
b08182b
Add container override config for batch ingestion
bedanley Aug 27, 2025
e24d2b7
Add Document Library Pagination
estohlmann Aug 28, 2025
05a7fbe
Add Model Usage UI Components
bedanley Aug 28, 2025
4b95528
Organize ingestion code
bedanley Aug 29, 2025
930e4ad
Fix imports
bedanley Aug 30, 2025
78a9eec
fixing tests and adding code coverage
bedanley Aug 30, 2025
58c0885
fixing tests and adding code coverage
bedanley Aug 30, 2025
2bf5cc2
Merge branch 'develop' into bug/batch-ingestion-container-config
bedanley Aug 30, 2025
45f3180
Add auth test
bedanley Aug 31, 2025
2e67aab
Add code coverage
bedanley Aug 31, 2025
830effe
Add code coverage
bedanley Aug 31, 2025
4f337d5
Create python dir for bundling rag
bedanley Sep 2, 2025
8541118
Fix unit test imports
bedanley Sep 3, 2025
7de0943
update git ignore
estohlmann Sep 3, 2025
24b2424
Merge branch 'develop' into bug/batch-ingestion-container-config
estohlmann Sep 3, 2025
e4817c8
Merge pull request #381 from awslabs/bug/batch-ingestion-container-co…
bedanley Sep 4, 2025
f0cadfa
Add TIKTOKEN_CACHE to RAG layer
bedanley Sep 4, 2025
a8c3d7e
Merge pull request #382 from awslabs/bug/tiktoken_cache
bedanley Sep 4, 2025
3c017b8
Bug/set max batch jobs (#386)
bedanley Sep 8, 2025
fd625d7
Bug/default model config update (#387)
bedanley Sep 8, 2025
af52e55
self hosted base models
bedanley Sep 8, 2025
2a7f81a
UI Enhancements
jmharold Sep 8, 2025
b610cc9
Updating version for release v5.2.0
estohlmann Sep 9, 2025
78763be
Merge branch 'main' into release/v5.2.0
estohlmann Sep 9, 2025
9410a5f
Changelog and misc quick fixes
estohlmann Sep 9, 2025
bf2a3cd
Fixing chart rendering
estohlmann Sep 9, 2025
8df62e4
remove da bombs
estohlmann Sep 9, 2025
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
2 changes: 0 additions & 2 deletions .github/workflows/code.end-to-end-test.nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ jobs:
cache: 'npm'
- name: Install base dependencies
run: npm ci
- name: Install Cypress deps
run: npm ci --prefix cypress
- name: Run Cypress E2E Suite
env:
TEST_ACCOUNT_PASSWORD: ${{ secrets.TEST_ACCOUNT_PASSWORD }}
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ lib/rag/ingestion/ingestion-image/build
.DS_Store
*.iml
*.code-workspace
.cursor
memory-bank/

# Coverage Statistic Folders
coverage
Expand Down
19 changes: 10 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ repos:
files: config.yaml

- repo: https://github.com/PyCQA/bandit
rev: '1.7.5'
rev: '1.7.10'
hooks:
- id: bandit
args: [--recursive, -c=pyproject.toml]
additional_dependencies: ['bandit[toml]']
additional_dependencies: ['bandit[toml]', 'pbr']

- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
rev: v1.5.0
hooks:
- id: detect-secrets
exclude: (?x)^(
.*.ipynb|config.yaml|.*.md|.*test.*.py
)$

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
rev: v5.0.0
hooks:
- id: check-json
- id: check-yaml
Expand All @@ -41,15 +41,15 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
rev: v2.3.0
hooks:
- id: codespell
entry: codespell
args: ['--skip=*.git*,*cdk.out*,*venv*,*mypy_cache*,*package-lock*,*node_modules*,*dist/*,*poetry.lock*,*coverage*,*models/*,*htmlcov*,*TIKTOKEN_CACHE/*', "-L=xdescribe"]
pass_filenames: false

- repo: https://github.com/pycqa/isort
rev: 5.12.0
rev: 5.13.2
hooks:
- id: isort
name: isort (python)
Expand All @@ -59,13 +59,14 @@ repos:
hooks:
- id: black

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: 'v0.1.3'
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.8.4'
hooks:
- id: ruff
args:
- --exit-non-zero-on-fix
- --per-file-ignores=test/**/*.py:E402
exclude: \.ipynb$

- repo: https://github.com/pycqa/flake8
rev: '7.1.1'
Expand All @@ -85,7 +86,7 @@ repos:


- repo: https://github.com/pre-commit/mirrors-mypy
rev: 'v1.6.1'
rev: 'v1.13.0'
hooks:
- id: mypy
verbose: true
Expand Down
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,46 @@
# v5.2.0
## Key Features
### Model Context Protocol (MCP) Enhancements
- **Connection Validation**: Real-time connection testing with detailed feedback on server connectivity during connection creation/edit
- **Enhanced Debugging**: Improved error handling and connection status reporting for MCP servers

### Session Management Improvements
- **Time-Based Session Grouping**: Sessions are now automatically organized into time-based groups based on updated date (Last Day, Last 7 Days, Last Month, Last 3 Months, Older)
- **Session ID Removal**: Removed session ID from prompt input for cleaner user interface

### RAG (Retrieval-Augmented Generation) Improvements
#### Document Processing
- **Document Chunk Processing Fixes**: Resolved issues with document chunk processing and ingestion
- **Document Library Pagination**: Added pagination support for the Document Library to handle large numbers of documents efficiently

#### Vector Store Configuration
- **Default Embedding Model Support**: Added ability to define a default embedding model when creating or updating vector stores
- **IAM Permissions Optimization**: Trimmed vector store IAM permissions to follow the principle of least privilege
- **Container Configuration**: Added container override configuration for batch ingestion processes

#### Batch Ingestion
- **Container Configuration**: Added support for container override configuration in batch ingestion jobs
- **Max Batch Jobs Setting**: Implemented dynamic maximum batch jobs limit
- **Ingestion Rules Updates**: Automatic updates to ingestion rules when Lambda functions are updated

### Model Management Improvements
- **Base Container Configuration**: Added support for using prebuilt model containers, instead of building during model deployment

### UI/UX Enhancements
- **General UI Improvements**: Various user interface enhancements to improve usability
- **Updated Default System Prompt**: Updated LISAs default system prompt to take advantage of new rendering capabilities. Pairing this prompt with new UI components supports the display of:
- Inline-Code
- Mathematic equations using LaTex syntax
- Mermaid Diagrams. These diagrams can also be copied and downloaded as images

## Acknowledgements
* @bedanley
* @estohlmann
* @dustins
* @jmharold

**Full Changelog**: https://github.com/awslabs/LISA/compare/v5.1.0...v5.2.0

# v5.1.0
## Key Features
### Model Management Enhancements
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.1.0
5.2.0
3 changes: 2 additions & 1 deletion lambda/mcp_server/lambda_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@

import boto3
from boto3.dynamodb.conditions import Attr, Key
from utilities.common_functions import api_wrapper, get_item, get_username, is_admin, retry_config
from utilities.auth import get_username, is_admin
from utilities.common_functions import api_wrapper, get_item, retry_config

from .models import McpServerModel, McpServerStatus

Expand Down
4 changes: 3 additions & 1 deletion lambda/models/domain_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,9 @@ class RagDocument(BaseModel):
def __init__(self, **data: Any) -> None:
super().__init__(**data)
self.pk = self.createPartitionKey(self.repository_id, self.collection_id)
self.chunks = len(self.subdocs)
# Only calculate chunks if not explicitly provided in data (for new documents)
if "chunks" not in data:
self.chunks = len(self.subdocs)

@staticmethod
def createPartitionKey(repository_id: str, collection_id: str) -> str:
Expand Down
3 changes: 2 additions & 1 deletion lambda/models/lambda_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from mangum import Mangum
from utilities.common_functions import get_groups, is_admin, retry_config
from utilities.auth import is_admin
from utilities.common_functions import get_groups, retry_config
from utilities.fastapi_middleware.aws_api_gateway_middleware import AWSAPIGatewayMiddleware

from .domain_objects import (
Expand Down
91 changes: 83 additions & 8 deletions lambda/models/state_machine/create_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,49 @@ def handle_start_copy_docker_image(event: Dict[str, Any], context: Any) -> Dict[
image_path = get_container_path(request.inferenceContainer)
output_dict["containerConfig"]["image"]["path"] = image_path

# Check if image type is ECR - skip building docker image if it already exists
if request.containerConfig and request.containerConfig.image.type == "ecr":
logger.info(f"ECR image detected for model {event.get('modelId')}, verifying image accessibility")
# Verify the ECR image is accessible
try:
# Extract repository name and tag from the base image
base_image = request.containerConfig.image.baseImage
if ":" in base_image:
repository_name, image_tag = base_image.rsplit(":", 1)
else:
repository_name = base_image
image_tag = "latest"

# Remove registry URL if present to get just the repository name
if "/" in repository_name:
repository_name = repository_name.split("/")[-1]

# Verify image exists in ECR
ecrClient.describe_images(repositoryName=repository_name, imageIds=[{"imageTag": image_tag}])

logger.info(f"ECR image {base_image} verified successfully")
output_dict["image_info"] = {
"image_tag": image_tag,
"image_uri": repository_name,
"image_type": "ecr",
"remaining_polls": 0,
"image_status": "prebuilt",
}
return output_dict

except ecrClient.exceptions.ImageNotFoundException:
error_msg = f"ECR image {base_image} not found. Please ensure the image exists and is accessible."
logger.error(error_msg)
raise Exception(error_msg)
except ecrClient.exceptions.RepositoryNotFoundException:
error_msg = (
f"ECR repository {repository_name} not found. Please ensure the repository exists and is accessible."
)
logger.error(error_msg)
raise Exception(error_msg)

# For non-ECR images, proceed with the normal docker image building process
logger.info(f"Invoking image build for model {event.get('modelId')}")
response = lambdaClient.invoke(
FunctionName=os.environ["DOCKER_IMAGE_BUILDER_FN_ARN"],
Payload=json.dumps(
Expand All @@ -130,6 +173,7 @@ def handle_start_copy_docker_image(event: Dict[str, Any], context: Any) -> Dict[
payload = response["Payload"].read()
output_dict["image_info"] = json.loads(payload)
output_dict["image_info"]["remaining_polls"] = 30
output_dict["image_info"]["image_status"] = "building"
return output_dict


Expand All @@ -138,14 +182,22 @@ def handle_poll_docker_image_available(event: Dict[str, Any], context: Any) -> D
output_dict = deepcopy(event)

try:
# Use the appropriate repository name based on image type
repository_name = (
event["image_info"]["image_uri"]
if event["image_info"].get("image_type") == "ecr"
else os.environ["ECR_REPOSITORY_NAME"]
)
ecrClient.describe_images(
repositoryName=os.environ["ECR_REPOSITORY_NAME"], imageIds=[{"imageTag": event["image_info"]["image_tag"]}]
repositoryName=repository_name, imageIds=[{"imageTag": event["image_info"]["image_tag"]}]
)
except ecrClient.exceptions.ImageNotFoundException:
output_dict["continue_polling_docker"] = True
output_dict["image_info"]["remaining_polls"] -= 1
if output_dict["image_info"]["remaining_polls"] <= 0:
ec2Client.terminate_instances(InstanceIds=[event["image_info"]["instance_id"]])
# Only terminate EC2 instance if one exists (not for pre-existing ECR images)
if "instance_id" in event["image_info"]:
ec2Client.terminate_instances(InstanceIds=[event["image_info"]["instance_id"]])
raise MaxPollsExceededException(
json.dumps(
{
Expand All @@ -157,7 +209,9 @@ def handle_poll_docker_image_available(event: Dict[str, Any], context: Any) -> D
return output_dict

output_dict["continue_polling_docker"] = False
ec2Client.terminate_instances(InstanceIds=[event["image_info"]["instance_id"]])
# Only terminate EC2 instance if one exists (not for pre-existing ECR images)
if "instance_id" in event["image_info"]:
ec2Client.terminate_instances(InstanceIds=[event["image_info"]["instance_id"]])
return output_dict


Expand All @@ -178,11 +232,32 @@ def camelize_object(o): # type: ignore[no-untyped-def]

prepared_event = camelize_object(event)
prepared_event["containerConfig"]["environment"] = event["containerConfig"]["environment"]
prepared_event["containerConfig"]["image"] = {
"repositoryArn": os.environ["ECR_REPOSITORY_ARN"],
"tag": event["image_info"]["image_tag"],
"type": "ecr",
}

# Handle ECR images differently - use the existing ECR image instead of the built one
if event["image_info"].get("image_type") == "ecr":
# For pre-existing ECR images, construct the ARN using the image repository
account_id = os.environ.get("AWS_ACCOUNT_ID", "")
if not account_id:
# Try to get account ID from the existing ECR repository ARN
ecr_repo_arn = os.environ.get("ECR_REPOSITORY_ARN", "")
if ecr_repo_arn:
account_id = ecr_repo_arn.split(":")[4]

repository_arn = (
f"arn:aws:ecr:{os.environ['AWS_REGION']}:{account_id}:repository/{event['image_info']['image_uri']}"
)
prepared_event["containerConfig"]["image"] = {
"repositoryArn": repository_arn,
"tag": event["image_info"]["image_tag"],
"type": "ecr",
}
else:
# For built images, use the default ECR repository
prepared_event["containerConfig"]["image"] = {
"repositoryArn": os.environ["ECR_REPOSITORY_ARN"],
"tag": event["image_info"]["image_tag"],
"type": "ecr",
}

response = lambdaClient.invoke(
FunctionName=os.environ["ECS_MODEL_DEPLOYER_FN_ARN"],
Expand Down
3 changes: 2 additions & 1 deletion lambda/prompt_templates/lambda_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@

import boto3
from boto3.dynamodb.conditions import Attr, Key
from utilities.common_functions import api_wrapper, get_groups, get_item, get_username, is_admin, retry_config
from utilities.auth import get_username, is_admin
from utilities.common_functions import api_wrapper, get_groups, get_item, retry_config

from .models import PromptTemplateModel

Expand Down
Loading
Loading