Describe the bug
Passing a local source directory as a target copies it into the sandbox via the
SDK's per-file LocalDir materialization (session.start() → LocalDir.apply()).
Each file costs several docker exec round-trips (a mkdir for the parent plus
a write() that itself stages via mkdir + stream + move). On a real repository
that is thousands of files, those round-trips serialize against a non-thread-safe
docker-py client and the scan appears to hang on "loading" for minutes before
the agent can start. On larger trees it can surface as an ExecTransportError.
This is dominated by file count, not byte size — even a well-under-1 GB repo
with many small files is affected.
To Reproduce
- Point Strix at a local directory with a few thousand files
(e.g. any medium Node/Python repo with node_modules or a populated .git):
strix --target ./some-medium-repo
- Watch the run sit on "loading" while the source is copied in file-by-file.
- The larger the file count, the longer the stall (roughly linear); very large
trees can raise ExecTransportError.
Expected behavior
The source tree should land in the container quickly (near-constant time w.r.t.
file count) so the agent can start promptly.
System Information:
- OS: Ubuntu 22.04 (Docker backend)
- Strix Version or Commit: current
main
- Python Version: 3.12
- LLM Used: n/a (independent of model)
Additional context
Rough local measurement of just the copy/import step against a strix-sandbox
container, synthetic tree of small files:
| files |
per-file LocalDir |
single tar put_archive |
| 100 |
~69.8 s |
~0.23 s |
The --mount option (#577) sidesteps this by bind-mounting read-only, but that
doesn't help when the agent needs a writable copy (or needs .git inside the
box). Proposed fix: import each source tree with a single container.put_archive()
(one tar) instead of the per-file exec loop. Happy to open a PR — I have the
change and tests ready.
Describe the bug
Passing a local source directory as a target copies it into the sandbox via the
SDK's per-file
LocalDirmaterialization (session.start()→LocalDir.apply()).Each file costs several
docker execround-trips (amkdirfor the parent plusa
write()that itself stages via mkdir + stream + move). On a real repositorythat is thousands of files, those round-trips serialize against a non-thread-safe
docker-pyclient and the scan appears to hang on "loading" for minutes beforethe agent can start. On larger trees it can surface as an
ExecTransportError.This is dominated by file count, not byte size — even a well-under-1 GB repo
with many small files is affected.
To Reproduce
(e.g. any medium Node/Python repo with
node_modulesor a populated.git):strix --target ./some-medium-repotrees can raise
ExecTransportError.Expected behavior
The source tree should land in the container quickly (near-constant time w.r.t.
file count) so the agent can start promptly.
System Information:
mainAdditional context
Rough local measurement of just the copy/import step against a
strix-sandboxcontainer, synthetic tree of small files:
LocalDirput_archiveThe
--mountoption (#577) sidesteps this by bind-mounting read-only, but thatdoesn't help when the agent needs a writable copy (or needs
.gitinside thebox). Proposed fix: import each source tree with a single
container.put_archive()(one tar) instead of the per-file exec loop. Happy to open a PR — I have the
change and tests ready.