Skip to content

feat: support pre-uploading files to a session before it starts#1282

Open
ambient-code[bot] wants to merge 3 commits intomainfrom
feat/pre-upload-files
Open

feat: support pre-uploading files to a session before it starts#1282
ambient-code[bot] wants to merge 3 commits intomainfrom
feat/pre-upload-files

Conversation

@ambient-code
Copy link
Copy Markdown
Contributor

@ambient-code ambient-code bot commented Apr 10, 2026

Summary

  • Add backend S3 storage client and pre-upload API endpoints (PUT/GET/DELETE /file-uploads/) that write files directly to MinIO/S3, bypassing the runner
  • Frontend upload route automatically falls back to pre-upload when session is not running (409 response)
  • Add file attachment UI to the Create Session dialog — users can attach files that are uploaded to S3 right after session creation
  • Init container (hydrate.sh) already downloads from the same S3 path, so pre-uploaded files are automatically seeded into the workspace

Closes #1280

Test plan

  • Verify backend compiles: cd components/backend && go build ./...
  • Run storage unit tests: cd components/backend && go test ./storage/ -v
  • Run handler unit tests: cd components/backend && go test -run TestFileUpload ./handlers/ -v
  • Run frontend build: cd components/frontend && npm run build
  • Run frontend tests: cd components/frontend && npx vitest run create-session-dialog-files
  • Run existing upload modal tests: cd components/frontend && npx vitest run upload-file-modal
  • E2E: Create a session with files attached, verify files appear in /workspace/file-uploads/ after pod starts
  • E2E: Upload files to a stopped session via the workspace upload modal, verify they're stored in S3

🤖 Ambient Session

Enable users to attach files during session creation that are uploaded
directly to S3/MinIO storage. The session's init container (hydrate.sh)
already downloads from this S3 path, so pre-uploaded files are
automatically seeded into the workspace when the pod initializes.

Backend changes:
- Add `storage` package with MinIO/S3 client (upload, list, delete)
- Add pre-upload endpoints: PUT/GET/DELETE file-uploads for sessions
- S3 config loaded from env vars (S3_ENDPOINT, S3_BUCKET, AWS creds)
- RBAC-checked, path-sanitized, works regardless of session pod state

Frontend changes:
- Add file attachment section to CreateSessionDialog
- Upload route falls back to pre-upload endpoint on 409 (not running)
- Files uploaded after session creation, before navigation

Closes #1280

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ambient-code ambient-code bot added the ambient-code:managed PR managed by AI automation label Apr 10, 2026
@ambient-code
Copy link
Copy Markdown
Contributor Author

ambient-code bot commented Apr 10, 2026

Implementation Notes

Architecture

This PR leverages the existing S3 state-sync architecture. The init container (hydrate.sh) already downloads file-uploads/ from s3://{bucket}/{namespace}/{sessionName}/file-uploads/. By writing files to this same S3 path before the pod starts, they are naturally seeded into the workspace during initialization.

New Backend Endpoints

  • PUT /projects/:name/agentic-sessions/:sessionName/file-uploads/*path — Upload file to S3
  • GET /projects/:name/agentic-sessions/:sessionName/file-uploads — List pre-uploaded files
  • DELETE /projects/:name/agentic-sessions/:sessionName/file-uploads/*path — Delete pre-uploaded file

All endpoints perform RBAC checks and path sanitization. The session CR must exist but the pod does not need to be running.

Frontend Flow

  1. Create Session dialog: Users can attach files before creating the session. After session creation, files are uploaded to S3 via the new pre-upload endpoint.
  2. Existing upload modal: When uploading to a non-running session (409 from workspace endpoint), the route automatically falls back to the pre-upload S3 endpoint.

Configuration

The backend reads S3 config from environment variables: S3_ENDPOINT, S3_BUCKET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY. If not configured, pre-upload endpoints return 503 (graceful degradation).

🤖 Session

- Downgrade minio-go from v7.0.100 (requires Go 1.25) to v7.0.82
  which is compatible with the Go 1.24.6 used in the Dockerfile
- Restore `toolchain go1.24.7` directive in go.mod
- Fix gofmt formatting in storage/s3_test.go

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jeremyeder
Copy link
Copy Markdown
Contributor

@ambient-code

@jeremyeder jeremyeder enabled auto-merge (squash) April 10, 2026 18:37
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

⚠️ SDD Preflight — Managed Paths Modified

This PR modifies files in SDD-managed component(s). These components are migrating to Spec-Driven Development.

File Component Mode
components/frontend/src/components/create-session-dialog.tsx runner warn

No action required — these components are in warn mode. Consider using the component's agent workflow for future changes.

📖 Specs: Runner Spec · Runner Constitution

@github-actions
Copy link
Copy Markdown
Contributor

Pull Reviews

🚨 Concerning — Adds pre-upload file functionality allowing files to be staged in S3 before session startup, with frontend fallback handling, backend routing, S3 storage operations, and test coverage.

https://pub-510dcf6312d143b68159aa24908df5dc.r2.dev/videos/ci-ambient-code-platform-1282-1775846715016.mp4

Callouts

  • critical (security): The fileUploadS3Key function constructs S3 paths using user-provided session names without validation. Malicious session names with path traversal characters (e.g., '../') could result in files being stored at unintended S3 locations. While individual file paths are validated with pathutil.IsPathWithinBase, the session name itself is not sanitized.
  • warning (security): The payload size is not validated before uploading to S3. A malicious user could upload extremely large files, causing storage exhaustion or DoS. Consider implementing maximum file size limits and total quota per session.
  • warning (testing): The file_uploads_test.go file only tests utility functions. Critical path logic including RBAC checks, S3 operations, and error handling is untested. Integration tests or mocked S3 tests are needed.
  • warning (performance): The PreUploadFile handler reads the entire request body into memory with io.ReadAll before uploading to S3. For large files, this could consume excessive memory. Consider streaming directly to S3.
  • info (complexity): Each of the three file operation handlers duplicates RBAC check logic, project/session parameter extraction, and error handling. Consider extracting these into middleware or helper functions to reduce duplication.
  • critical (security): S3 credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) are read directly from environment variables without validation. If these are exposed in logs or error messages, it could leak credentials. Consider masking in logs and validating credential format.
  • warning (breaking-change): New endpoints are added to routes but corresponding handler functions (handlers.ListPreUploadedFiles, handlers.PreUploadFile, handlers.DeletePreUploadedFile) are not shown in the diff. If these handlers don't exist or have breaking signatures, the backend will fail to compile.
  • warning (complexity): The pre-upload fallback uses HTTP 409 Conflict to signal session unavailable. This creates implicit contract between frontend and backend. If handlers don't return 409 in expected scenarios, fallback won't trigger. Consider explicit status code documentation.
  • warning (performance): S3Client.ListObjects uses recursive listing without pagination limits. For buckets with many files under a prefix, this could load all objects into memory. Consider adding MaxKeys parameter or pagination support.
  • info (testing): S3 tests only cover LoadS3ConfigFromEnv, not actual S3 operations (PutObject, ListObjects, DeleteObject, ObjectExists). Consider adding integration tests or mocked operation tests.
  • info (testing): CreateSessionDialog file tests use complex mocking setup. The removeButtons filter logic is fragile and relies on specific class names and structure. Consider using data-testid attributes for more reliable selectors.
  • warning (performance): Sequential file uploads in a for-loop after session creation could be slow with multiple files. No concurrent upload requests and no progress tracking per file, only overall completion state.
  • warning (testing): New file upload logic added to onSuccess callback with no tests visible in this diff. The async upload flow with error handling needs test coverage for success/failure scenarios.
  • info (security): Files are uploaded directly to S3 via the API endpoint. Ensure the backend endpoint validates file types, scans for malware, and enforces per-user/session storage quotas. File type validation is not performed on the frontend.
  • info (complexity): Error handling for partial upload failures silently continues and shows a generic toast. Users won't know which specific files failed if some uploads succeed and others fail.
File-by-file breakdown
  • components/backend/handlers/file_uploads.go (high): Implements three HTTP endpoint handlers for pre-uploading files to S3 before a session starts, including upload, list, and delete operations with full RBAC authorization checks.
  • components/backend/main.go (high): Initializes the S3 storage client at application startup and makes it available to the file upload handlers.
  • components/backend/go.mod (medium): Adds new dependency declarations for MinIO S3 client and supporting libraries required for S3 file storage operations.
  • components/backend/handlers/file_uploads_test.go (low): Provides unit tests for the S3 key generation utility functions used in file upload operations.
  • components/backend/go.sum (low): Records cryptographic checksums for all dependencies to ensure reproducible builds.
  • components/backend/storage/s3.go (high): Provides S3-compatible object storage operations for pre-uploading files before session startup
  • components/frontend/src/app/api/projects/[name]/agentic-sessions/[sessionName]/workspace/upload/route.ts (high): Adds fallback pre-upload mechanism when session pod is not running, with direct S3 upload capability
  • components/backend/routes.go (high): Registers three new HTTP endpoints for file pre-upload management before session startup
  • components/backend/storage/s3_test.go (medium): Unit tests for S3 configuration loading from environment variables
  • components/frontend/src/components/tests/create-session-dialog-files.test.tsx (medium): Tests file attachment functionality in the create session dialog
  • components/frontend/src/components/create-session-dialog.tsx (high): Add file pre-upload functionality to the create session dialog, allowing users to attach files before session creation and have them automatically uploaded to the session workspace on success.

Generated by pull-reviews — automated video reviews for PRs

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

Labels

ambient-code:managed PR managed by AI automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support pre-uploading files to a session before it starts

1 participant