Add lightweight subprocess interpreter - #5
Merged
Conversation
Amp-Thread-ID: https://ampcode.com/threads/T-019fcce1-bc8b-753e-886f-9b77c0ccb376 Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Interpreter benchmarkWall-clock milliseconds are shown as p50 / p95; memory is guest-process RSS where available.
TTI covers construction through the first completed execution. Raw samples, p95 values, host process-tree RSS, and environment metadata are in the uploaded |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
InProcessInterpreterSubprocessInterpreterbacked by one persistent CPython workerSUBMIT, recoverable errors, execution timeout termination, and child-local stdout captureThis intentionally excludes the much larger
IsolationSpecframework from #1. A subprocess provides memory, stdout, and lifecycle separation, but it is not an OS security sandbox: generated code retains the host user's filesystem, environment, credentials, process, and network authority.Builds on merged PR #3, which removed the experimental
bind()API and updated the execution-instructions work.Size
The execution implementation is 350 lines:
SubprocessInterpreter: 206 linesThe in-process implementation remains approximately 100 lines. They are separate public classes because their value boundaries, failure behavior, and operational contracts differ materially.
Measured overhead
Focused Linux/Python 3.11 run with 5 cold sessions and 100 warm executions; values are median / p95:
The persistent worker therefore adds about 25 ms once, while warm scalar execution remains below 0.2 ms p95 and host callbacks below 0.4 ms p95. Large JSON transfer is the material boundary cost.
Real DSPy validation
A real-LM Flex flow passed with the subprocess interpreter:
The exact run returned integer
42with one real LM call.A small real-LM GEPA optimization also passed with
SubprocessInterpreter: it producedLOCAL INTERPRETER, successfully evaluated through Flex, and the compiled Flex retainedSubprocessInterpreteras its interpreter factory.Verification
uv run pytest -q— 44 passed, 1 expected xfailuv run ruff check src tests scripts— passeduv build— wheel and sdist built; wheel contains both interpreter modules and the workergit diff --check— clean42, one LM callLOCAL INTERPRETER, subprocess factory preserved