DEV Community

Arun Raghunath
Arun Raghunath

Posted on

Closing the execution gap, Part 2: Dependency management

This is Part 2 of Closing the execution gap — a series on building jhansi.io, a cloud sandbox for AI-generated code.


The first question I got after shipping persistent sandboxes was predictable:

"Great — but do I still have to pip install everything myself?"

Yes. You did. That was embarrassing.

If the pitch is "run AI-generated code with zero friction," making users manage deps manually is a contradiction. For regulated teams it's worse: every new package is a supply-chain review. Friction kills adoption.

So v0.3 fixes it.


The problem with dependencies in sandboxes

Every sandbox starts as a clean container. Upload main.py, hit run, and you get:

ModuleNotFoundError: No module named 'requests'
Enter fullscreen mode Exit fullscreen mode

The naive fix is to install at exec time. But downloading from PyPI on every run is slow, expensive, and brittle. pandas + numpy is a 40s cold start. Run that 100 times and your AI agent burns budget before it does anything useful.

The right fix: install once, persist forever.


Install once, persist forever

jhansi.io gives every sandbox a persistent workspace — a folder that survives across runs. In v0.3, dependencies live there too.

  • First exec: we detect deps, install to /sandbox/deps, run your code.
  • Second exec: deps are already there. Cold start drops dramatically. This matters for AI agents. Humans tolerate a 30s install. Agents that try 5 approaches to solve a task can't. Workspace-scoped cache means failed attempt #1 pays the install tax. Attempts #2–5 run instantly.

First exec — install + run

$ curl -X POST .../sandboxes/sb_abc123/exec -d '{"filename": "main.py"}'
{
"output": "Installing requests==2.31.0...\n200\n"
}

Second exec — just run

$ curl -X POST .../sandboxes/sb_abc123/exec -d '{"filename": "main.py"}'
{
"output": "200\n"
}

That's the difference between "AI is too slow" and "AI is faster than a junior dev."


Manifest first, auto-detect as fallback

How do we know what to install? Both approaches, in the right order.

If you provide a manifest, we trust you. You know your deps better than any static analyser. If you don't, we fall back to auto-detection.

Priority for Python:

  1. pyproject.tomlpip install
  2. requirements.txtpip install -r
  3. Neither → pipreqs scan pipreqs isn't just import requestsrequests. It knows import cv2 means opencv-python, import sklearn means scikit-learn. You don't have to remember.

Using a manifest isn't just faster — it's auditable. Auditors can diff your pinned deps between runs. Auto-detect is for prototyping. More on auditability in Part 5.


Four languages, four strategies

AI doesn't just write Python. jhansi.io handles the four languages LLMs generate most:

Language Manifest detected Install command No manifest fallback
Python pyproject.toml, requirements.txt pip install --target /sandbox/deps pipreqs auto-detect
Node package.json npm install Run as-is
Go go.mod go mod download go mod init + go mod tidy
Java pom.xml, build.gradle Maven or Gradle Direct javac compile

Each language keeps its own idioms. We don't impose a universal abstraction. Workspace-scoping means one sandbox's torch==2.1.0 can't poison another's torch==1.13. No dependency hell across AI runs.


The trust boundary

One decision worth documenting: we don't vet what gets installed.

Egress is restricted to official registries — PyPI, npm, Maven Central, proxy.golang.org — and nothing else. No arbitrary domains. What you install from those registries is your responsibility.

The contract is simple:

jhansi.io guarantees isolation. You own your code.

This is the same model as AWS Lambda or Cloud Run. We contain the blast radius. We don't audit your imports.

SBOM per exec — a full list of every package installed, with versions and licenses — is on the roadmap. Today we contain. Tomorrow we curate.


What's next

Two things didn't make v0.3:

  • Streaming output — dep installs can take 30s. Right now you wait. Soon you'll see output live and know exactly why torch is taking forever.
  • Missing import detection — if your manifest forgets a package, you get an ImportError today. We should surface the unlisted import in the response. Coming soon. Next in the series: Isolation — you can pip install safely now. But can you stop that package from exfiltrating your AWS credentials? What "hard-sandboxed" actually means, why Docker isn't enough, and the attacks most sandboxes miss.

jhansi.io is open source (Apache 2.0) at github.com/jhansi-io. Follow the series on Dev.to, LinkedIn, and X.

Top comments (0)