-
Notifications
You must be signed in to change notification settings - Fork 92
fix(DATAGO-122883): Add total file upload limit for projects #910
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(DATAGO-122883): Add total file upload limit for projects #910
Conversation
WhiteSource Policy Violation Summary✅︎ No Blocking Whitesource Policy Violations found in solaceai/solace-agent-mesh-ui-pr-910! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds a total file upload size limit for projects to prevent unbounded storage usage. The implementation enforces a 100MB total project limit (with 50MB per-file limit) in production, while tests use 3MB/1MB limits respectively.
Changes:
- Added
DEFAULT_MAX_TOTAL_UPLOAD_SIZE_BYTESconstant and validation logic to check cumulative user-uploaded file sizes - LLM-generated artifacts are excluded from the limit (filtered by
source="project") - Frontend and backend both validate the total upload limit before accepting new files
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/integration/apis/persistence/projects/test_projects_upload_limits.py | Comprehensive test suite covering limit enforcement, ZIP imports, edge cases, and verification that only user-uploaded files count toward limits |
| tests/integration/apis/conftest.py | Added test configuration override for 3MB total project size limit |
| src/solace_agent_mesh/gateway/http_sse/services/project_service.py | Core validation logic for total upload size limits, including helper function and limit checks in project creation and artifact upload |
| src/solace_agent_mesh/gateway/http_sse/routers/config.py | Exposed maxTotalUploadSizeBytes to frontend via config endpoint |
| src/solace_agent_mesh/gateway/constants.py | New constants file defining all upload size limit defaults |
| src/solace_agent_mesh/gateway/base/app.py | Added configuration parameter for total upload size limit and migrated to use centralized constants |
| client/webui/frontend/src/lib/utils/file-validation.ts | Added validateTotalUploadSize function for frontend validation |
| client/webui/frontend/src/lib/contexts/ConfigContext.ts | Added maxTotalUploadSizeBytes to config context type |
| client/webui/frontend/src/lib/components/projects/KnowledgeSection.tsx | Integrated total upload size validation in file upload flow |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
tests/integration/apis/persistence/projects/test_projects_upload_limits.py
Outdated
Show resolved
Hide resolved
src/solace_agent_mesh/gateway/http_sse/services/project_service.py
Outdated
Show resolved
Hide resolved
src/solace_agent_mesh/gateway/http_sse/services/project_service.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| existing_artifacts = await self.get_project_artifacts(db, project_id, user_id) | ||
| current_project_size = sum( | ||
| artifact.size for artifact in existing_artifacts | ||
| if artifact.source == "project" and artifact.size is not None # Only count user-uploaded files | ||
| ) |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling get_project_artifacts on every file upload may be inefficient for projects with many artifacts. Consider caching the artifact list or implementing a more efficient size tracking mechanism (e.g., storing total size as project metadata) to avoid repeated database queries and artifact service calls.
lgh-solace
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks clean and has some nice additions, but perhaps goes too far on the BE? Thoughts?
client/webui/frontend/src/lib/components/projects/KnowledgeSection.tsx
Outdated
Show resolved
Hide resolved
| return size_bytes / (1024 * 1024) | ||
|
|
||
|
|
||
| def sanitize_log_input(value: str) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel this function is currently unnecessary? We are logging user_id and project_id, but those aren't user controlled, they're just IDs and UUIDs.
| """ | ||
|
|
||
|
|
||
| def bytes_to_mb(size_bytes: int) -> float: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one could be useful - but not sure it's useful enough to add to the shared helper since its only one line... 🤔
Edit: Maybe we could keep it in project_service.py?
JKaram
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good.
Just be mindful of the comments the AI leaves. Some of them are very redundant.
client/webui/frontend/src/lib/components/projects/KnowledgeSection.tsx
Outdated
Show resolved
Hide resolved
| // 1. Validate individual file sizes | ||
| const fileSizeResult = validateFileSizes(files, { maxSizeBytes: maxUploadSizeBytes }); | ||
| if (!fileSizeResult.valid) { | ||
| return fileSizeResult; | ||
| } | ||
|
|
||
| // 2. Validate total upload limit | ||
| const totalUploadSizeResult = validateTotalUploadSize(currentProjectSize, files, maxTotalUploadSizeBytes); | ||
| if (!totalUploadSizeResult.valid) { | ||
| return { valid: false, error: totalUploadSizeResult.error }; | ||
| } | ||
|
|
||
| return { valid: true }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove the unnecessary comments. // 1. Validate individual file sizes ...
| */ | ||
| export function validateTotalUploadSize(currentProjectSizeBytes: number, newFiles: FileList | File[], maxTotalUploadSizeBytes?: number): TotalUploadSizeValidationResult { | ||
| const fileArray = Array.from(newFiles); | ||
| const newSize = fileArray.reduce((sum, file) => sum + file.size, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be a good place for the util I mentioned above. We might even have one already.
…d-limit Signed-off-by: Shane Chen <shane.chen@solace.com>
|




What is the purpose of this change?
Add a limit to the total size of files that can be uploaded to a project to prevent unbounded storage usage across users.
How was this change implemented?
Added
DEFAULT_MAX_TOTAL_UPLOAD_SIZE_BYTESconstant and validation logic in project_service.py that checks the cumulative size of user-uploaded files before accepting new uploads, rejecting requests with a 400 error when the total would exceed the limit.Key Design Decisions
For now, the limit per-file has been set to 50mb and the total upload limit is 100mb.
The total project size limit is the primary constraint rather than enforcing strict per-file limits, providing flexibility for users to manage their file sizes as needed within the overall quota. LLM-generated artifacts are intentionally excluded from the limit (filtered by
source="project") to ensure that AI-generated content doesn't consume a user's upload quota, only their manually uploaded files count.How was this change tested?
Demos
SLACK: https://solacedotcom.slack.com/archives/C09TE7FNFAR/p1770050818570359?thread_ts=1769705717.347159&cid=C09TE7FNFAR
Screen.Recording.2026-01-30.at.4.51.46.PM.mov
Is there anything the reviewers should focus on/be aware of?
The test suite is about half of this PR.