Skip to content

Conversation

@shanechen-solace
Copy link
Contributor

@shanechen-solace shanechen-solace commented Jan 28, 2026

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_BYTES constant 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?

  • Manual testing: Manually added files of different sizes to projects to test the upload limit behavior.
  • Integration tests: Added a comprehensive test suite covering limit enforcement, valid uploads, ZIP imports, edge cases, and verification that only user-uploaded files count toward the limit.
  • Known limitations: Some test scenarios involving file deletion and replacement cannot be fully validated with the mock artifact service used in tests, but work correctly in production with a real artifact service.

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.

@github-actions
Copy link

github-actions bot commented Jan 28, 2026

WhiteSource Policy Violation Summary

✅︎ No Blocking Whitesource Policy Violations found in solaceai/solace-agent-mesh-ui-pr-910!

@shanechen-solace shanechen-solace changed the title fix(DATAGO-122175): Add total file upload limit fix(DATAGO-122883): Add total file upload limit for projects Jan 28, 2026
Copy link
Contributor

Copilot AI left a 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_BYTES constant 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.

Copy link
Contributor

Copilot AI left a 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.

Comment on lines 466 to 470
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
)
Copy link

Copilot AI Jan 29, 2026

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.

Copilot uses AI. Check for mistakes.
@shanechen-solace shanechen-solace marked this pull request as ready for review January 29, 2026 00:41
Copy link
Collaborator

@lgh-solace lgh-solace left a 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?

return size_bytes / (1024 * 1024)


def sanitize_log_input(value: str) -> str:
Copy link
Collaborator

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:
Copy link
Collaborator

@lgh-solace lgh-solace Jan 30, 2026

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?

Copy link
Contributor

@JKaram JKaram left a 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.

Comment on lines 60 to 72
// 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 };
Copy link
Contributor

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);
Copy link
Contributor

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.

@shanechen-solace shanechen-solace marked this pull request as draft February 3, 2026 15:54
@sonarqube-solacecloud
Copy link

Quality Gate failed Quality Gate failed

Failed conditions
B Security Rating on New Code (required ≥ A)

See analysis details on SonarQube

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE SonarQube for IDE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants