Skip to content

fix(daytona): bulk upload, config bridge, silent disk cap (#7362)#7447

Closed
alt-glitch wants to merge 5 commits into
mainfrom
fix/daytona-bulk-upload-config-bridge-7362
Closed

fix(daytona): bulk upload, config bridge, silent disk cap (#7362)#7447
alt-glitch wants to merge 5 commits into
mainfrom
fix/daytona-bulk-upload-config-bridge-7362

Conversation

@alt-glitch

Copy link
Copy Markdown
Collaborator

Fixes #7362 — three issues with the Daytona backend.

Changes

1. Bulk file upload (perf)

  • Add optional bulk_upload_fn callback to FileSyncManager
  • When provided, all changed files upload in one call instead of per-file HTTP POSTs
  • DaytonaEnvironment wires this to sandbox.fs.upload_files() (single multipart POST)
  • ~580 files: ~5 min → <2s on init
  • Parent directories pre-created in one mkdir -p call
  • Backwards compatible: SSH/Modal continue using per-file upload_fn

2. Config-to-env bridge (config)

  • Add container_cpu, container_memory, container_disk, container_persistent to _config_to_env_sync dict in config.py
  • hermes config set terminal.container_memory 8192 now correctly writes TERMINAL_CONTAINER_MEMORY=8192 to .env

3. Disk cap visibility (logging)

  • Replace warnings.warn() with logger.warning() for disk cap message
  • warnings.warn() is suppressed in agent/gateway mode; logger.warning() always visible

Tests

  • 3 new unit tests for bulk upload: invocation, fallback, rollback
  • All 15 file_sync tests pass

FileSyncManager now accepts an optional bulk_upload_fn callback.
When provided, all changed files are uploaded in one call instead
of iterating one-by-one with individual HTTP POSTs.

DaytonaEnvironment wires this to sandbox.fs.upload_files() which
batches everything into a single multipart POST — ~580 files goes
from ~5 min to <2s on init.

Parent directories are pre-created in one mkdir -p call.

Fixes #7362 (item 1).
Add terminal.container_cpu, container_memory, container_disk, and
container_persistent to the _config_to_env_sync dict so that
`hermes config set terminal.container_memory 8192` correctly
writes TERMINAL_CONTAINER_MEMORY=8192 to ~/.hermes/.env.

Previously these YAML keys had no effect because terminal_tool.py
reads only env vars and the bridge was missing these mappings.

Fixes #7362 (item 2).
warnings.warn() is suppressed/invisible when running as a gateway
or agent. Switch to logger.warning() so the disk cap message
actually appears in logs.

Fixes #7362 (item 3).
Cover the three key behaviors:
- bulk_upload_fn is called instead of per-file upload_fn
- Fallback to upload_fn when bulk_upload_fn is None
- Rollback on bulk upload failure retries all files
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: exec() or eval() usage

Dynamic code execution can hide malicious behavior, especially when combined with base64 or network fetches.

Matches (first 20):

3200:+            self._sandbox.process.exec(mkdir_cmd)

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

@alt-glitch

Copy link
Copy Markdown
Collaborator Author

@BugBot review

@cursor

cursor Bot commented Apr 10, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches remote file-sync behavior and Daytona sandbox initialization; mistakes could prevent credentials/skills from syncing or change resource-limit configuration, but changes are additive and covered by new unit tests.

Overview
Improves Daytona startup performance and reliability by adding optional bulk-upload support to FileSyncManager and wiring Daytona to upload all changed files in one sandbox.fs.upload_files() call (with a single pre-mkdir -p for parent dirs), while keeping per-file uploads as the fallback.

Fixes terminal config/env bridging by syncing terminal.container_cpu, terminal.container_memory, terminal.container_disk, and terminal.container_persistent from config.yaml into corresponding TERMINAL_CONTAINER_* entries in .env when set via hermes config set.

Makes disk-cap messages visible in gateway/agent mode by switching Daytona’s disk limit notice from warnings.warn() to logger.warning(), and adds unit tests covering bulk upload invocation, fallback behavior, and rollback on bulk-upload failure.

Reviewed by Cursor Bugbot for commit c724aa8. Configure here.

Comment thread tools/environments/daytona.py Outdated
@alt-glitch

Copy link
Copy Markdown
Collaborator Author

Benchmark Results

Tested against live Daytona sandbox with 581 files (skills, credentials, caches):

Branch Method Time
main Sequential (upload_file × 581) 803.54s (13.4 min)
fix/daytona-bulk-upload-config-bridge-7362 Bulk (upload_files × 1) 4.28s

188× faster. The file_sync: bulk-uploaded 581 file(s) debug line confirms the bulk path is hit.

Bulk upload log
00:38:11 INFO  bench: Files to sync: 581
00:38:12 INFO  bench: Creating Daytona sandbox...
00:38:13 INFO  bench: Sandbox created in 1.32s
00:38:14 INFO  bench: Bulk upload available: True
00:38:14 INFO  bench: === Starting file sync benchmark ===
00:38:14 DEBUG file_sync: uploading 581 file(s)
00:38:18 DEBUG file_sync: bulk-uploaded 581 file(s)
00:38:18 INFO  bench: === File sync completed in 4.28s (581 files, bulk=True) ===

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: exec() or eval() usage

Dynamic code execution can hide malicious behavior, especially when combined with base64 or network fetches.

Matches (first 20):

3192:+            self._sandbox.process.exec(mkdir_cmd)

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

@alt-glitch

Copy link
Copy Markdown
Collaborator Author

@BugBot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit c724aa8. Configure here.

@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #7538. Your commits were cherry-picked onto current main with authorship preserved in git log. Thanks for the contribution @alt-glitch — the bulk upload optimization is a big win for Daytona users.

@teknium1 teknium1 closed this Apr 11, 2026
kshitijk4poor added a commit to kshitijk4poor/hermes-agent that referenced this pull request Apr 11, 2026
Wire bulk_upload_fn into SSH and Modal backends, matching the
pattern established for Daytona in NousResearch#7447.

SSH: stages files in a temp directory mirroring the remote path
layout, then pipes tar cf | ssh tar xf in a single TCP stream.
Eliminates per-file scp round-trips.

Modal: builds an in-memory gzipped tar archive, base64-encodes it,
and decodes+extracts in one exec call. Eliminates per-file
base64|exec overhead.

Both backends pre-create all unique parent directories in a single
call before the bulk transfer.

Closes NousResearch#7465
Closes NousResearch#7467
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.

Daytona backend: bulk upload, config bridge, silent disk cap

3 participants