Feature/remote pipe func bundle transport#37
Conversation
Let a run request ship a whole method bundle (.mthds + .py + structures/*.py + requirements.txt) alongside the run, as bundle_b64 (base64 zip) or a files map, so custom PipeFunc Python travels with the method. New api/bundle.py parses+guards in memory (both-forms/empty/corrupt-zip/traversal → 422, oversized bundle_b64 refused before decode + file-count/decompressed-size ceilings → 413, zip-bomb bounded read) then materializes into a temp library dir; /execute and /start wire it via _bundle_library_dirs. A bundle shipping .py is refused (403 CustomCodeRequiresSandbox) unless the deployment is sandbox-hosted, and the gate runs before any disk write. A bundle and inline mthds_contents are mutually exclusive. Swap StrEnum imports to enum (pipelex.types removed in 0.38). Requires pipelex >= 0.38 (is_pipe_func_sandbox_hosted); pin bump + OpenAPI regeneration are the release step. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The run routes import `is_pipe_func_sandbox_hosted` (and the bundle-transport symbols) from pipelex, which only exist on the 0.38 seam line. The pin was still `pipelex==0.37.0`, so the hosted image crash-looped at boot with `ImportError: cannot import name 'is_pipe_func_sandbox_hosted' from 'pipelex.config'`. Repoint pipelex to feature/remote-pipe-func HEAD (00015c5) via [tool.uv.sources], matching pipelex-worker. Regenerated uv.lock (pipelex 0.37.0 -> 0.38.0). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR adds request-carried method bundles for pipeline runs. The main changes are:
Confidence Score: 4/5One packaging issue needs to be fixed before merging for non- The core bundle parsing, route integration, sandbox gate, and tests look sound. The score reflects a contained blocking issue in dependency metadata that can make the changed imports fail outside
What T-Rex did
Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Client
participant API as /execute or /start
participant Bundle as api.bundle
participant Gate as Sandbox gate
participant Runner as ApiRunner
participant Orchestrator
Client->>API: Run request with bundle_b64 or files
API->>Bundle: parse_bundle(...)
Bundle-->>API: ParsedBundle(entries, has_python_sources)
API->>Gate: is_pipe_func_sandbox_hosted() when .py present
alt .py present and not sandbox-hosted
Gate-->>API: false
API-->>Client: 403 CustomCodeRequiresSandbox
else accepted bundle
API->>Bundle: materialize_parsed(parsed)
Bundle-->>API: temp library_dirs
API->>Runner: ApiRunner(..., library_dirs)
Runner->>Orchestrator: execute/start pipe job
Orchestrator-->>Runner: run result or dispatch ack
Runner-->>API: response model
API->>Bundle: context exit cleanup
API-->>Client: 200 execute or 202 start
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Client
participant API as /execute or /start
participant Bundle as api.bundle
participant Gate as Sandbox gate
participant Runner as ApiRunner
participant Orchestrator
Client->>API: Run request with bundle_b64 or files
API->>Bundle: parse_bundle(...)
Bundle-->>API: ParsedBundle(entries, has_python_sources)
API->>Gate: is_pipe_func_sandbox_hosted() when .py present
alt .py present and not sandbox-hosted
Gate-->>API: false
API-->>Client: 403 CustomCodeRequiresSandbox
else accepted bundle
API->>Bundle: materialize_parsed(parsed)
Bundle-->>API: temp library_dirs
API->>Runner: ApiRunner(..., library_dirs)
Runner->>Orchestrator: execute/start pipe job
Orchestrator-->>Runner: run result or dispatch ack
Runner-->>API: response model
API->>Bundle: context exit cleanup
API-->>Client: 200 execute or 202 start
end
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
pyproject.toml:18-20
**Preserve git dependency source**
`pipelex` now imports branch-only symbols (`is_pipe_func_sandbox_hosted` and the bundle seam), but the standard dependency published at lines 18-20 no longer pins that git revision. `tool.uv.sources` is only honored by `uv`; installing or building this project with other PEP 621 consumers will resolve `pipelex` from PyPI and miss the branch code, causing import or runtime failures on the changed path. Encode the git URL in the project dependency itself or keep a released version pin that contains these APIs.
Reviews (1): Last reviewed commit: "Pin pipelex to 0.38 SHA (fixes hosted bo..." | Re-trigger Greptile |
| dependencies = [ | ||
| "pipelex[mistralai,anthropic,google,google-genai,bedrock,fal]==0.37.0", | ||
| "pipelex[mistralai,anthropic,google,google-genai,bedrock,fal]", | ||
| "pipelex-tools-py>=0.1.0", |
There was a problem hiding this comment.
Preserve git dependency source
pipelex now imports branch-only symbols (is_pipe_func_sandbox_hosted and the bundle seam), but the standard dependency published at lines 18-20 no longer pins that git revision. tool.uv.sources is only honored by uv; installing or building this project with other PEP 621 consumers will resolve pipelex from PyPI and miss the branch code, causing import or runtime failures on the changed path. Encode the git URL in the project dependency itself or keep a released version pin that contains these APIs.
Artifacts
Repro: non-uv packaging and import harness
- Contains supporting evidence from the run (text/x-python; charset=utf-8).
Repro: pip resolver output and failing import traceback
- Keeps the command output available without making the summary code-heavy.
Ran code and verified through T-Rex
Prompt To Fix With AI
This is a comment left during a code review.
Path: pyproject.toml
Line: 18-20
Comment:
**Preserve git dependency source**
`pipelex` now imports branch-only symbols (`is_pipe_func_sandbox_hosted` and the bundle seam), but the standard dependency published at lines 18-20 no longer pins that git revision. `tool.uv.sources` is only honored by `uv`; installing or building this project with other PEP 621 consumers will resolve `pipelex` from PyPI and miss the branch code, causing import or runtime failures on the changed path. Encode the git URL in the project dependency itself or keep a released version pin that contains these APIs.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
All reported issues were addressed across 13 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…brary_dirs The bundle transport previously handed the engine a bare materialized directory with mthds_contents=None, so main_pipe never resolved (it is only derived from mthds_contents) and the run 500'd on "Either pipe_code or mthds_contents...". _bundle_run_source now splits a request bundle: the `.mthds` text travels as `mthds_contents` (the year-proven path — main_pipe resolves exactly as for a plain run), and only the non-`.mthds` files (custom PipeFunc `.py`, structures, requirements) are materialized into a temp library_dirs entry for source capture. Mirrors "a normal run, plus the Python." /execute and /start both use it; the custom-Python sandbox gate and both-forms guard are unchanged. Also bumps the pipelex pin to 34607e2c (config-only PipeFunc execution mode). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ath fix) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…th fix) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary by cubic
Adds method-bundle transport to
/executeand/startso callers can send a full method viabundle_b64(zip) orfiles(map). The bundle’s.mthdsnow feedsmthds_contentssomain_piperesolves, while only.py/deps are materialized to a templibrary_dirs; custom.pyis allowed only on sandbox-hosted deployments.New Features
bundle_b64(base64 zip) orfiles({relpath: text}); exactly one allowed; mutually exclusive withmthds_contents; requires at least one.mthds.MAX_BUNDLE_FILESandMAX_BUNDLE_TOTAL_KIB; bounded decompression with a pre-decode size check forbundle_b64; all guards run before any disk write..mthds->mthds_contents; other files -> templibrary_dirsforApiRunner(auto-cleaned;startonly needs it during setup). You can still setpipe_codeto pick a pipe in the bundle..pyrequire sandbox-hosted deployments; otherwise 403CustomCodeRequiresSandbox.pipelexviauvsources to the 0.38 seam (bumped SHA); docs and unit tests added.Bug Fixes
.mthdspopulatesmthds_contentssomain_piperesolves; only non-.mthdsfiles are written to disk.Written for commit 87636c1. Summary will update on new commits.