shellsim 0.1.21__tar.gz → 0.1.25__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {shellsim-0.1.21 → shellsim-0.1.25}/Cargo.lock +1 -1
- {shellsim-0.1.21 → shellsim-0.1.25}/Cargo.toml +1 -1
- {shellsim-0.1.21 → shellsim-0.1.25}/PKG-INFO +14 -1
- {shellsim-0.1.21 → shellsim-0.1.25}/README.md +11 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/pyproject.toml +4 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/python/native/Cargo.lock +3 -2
- {shellsim-0.1.21 → shellsim-0.1.25}/python/native/Cargo.toml +2 -1
- {shellsim-0.1.21 → shellsim-0.1.25}/python/native/src/lib.rs +261 -2
- {shellsim-0.1.21 → shellsim-0.1.25}/python/shellsim/__init__.py +15 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/python/shellsim/_api.py +277 -1
- {shellsim-0.1.21 → shellsim-0.1.25}/python/shellsim/_cli.py +68 -1
- shellsim-0.1.25/python/shellsim/display_host.py +205 -0
- shellsim-0.1.25/python/shellsim/package.py +620 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/net.rs +7 -6
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/wasm.rs +6 -10
- {shellsim-0.1.21 → shellsim-0.1.25}/src/display.rs +7 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/exec.rs +2 -1
- {shellsim-0.1.21 → shellsim-0.1.25}/src/harness.rs +351 -12
- {shellsim-0.1.21 → shellsim-0.1.25}/src/harness_manager.rs +2 -2
- {shellsim-0.1.21 → shellsim-0.1.25}/src/main.rs +18 -7
- {shellsim-0.1.21 → shellsim-0.1.25}/src/net.rs +248 -5
- {shellsim-0.1.21 → shellsim-0.1.25}/src/netcmd.rs +50 -22
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program.rs +1 -1
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/http.rs +52 -41
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/asyncio.rs +3 -2
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/linalg.rs +3 -3
- shellsim-0.1.25/src/python/stdlib/source/numpy/linalg.py +706 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/host.rs +13 -2
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/native_runtime.rs +2 -2
- {shellsim-0.1.21 → shellsim-0.1.25}/src/scheduler.rs +2 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/syscalls.rs +7 -5
- {shellsim-0.1.21 → shellsim-0.1.25}/src/vfs.rs +22 -0
- shellsim-0.1.21/src/python/stdlib/source/numpy/linalg.py +0 -301
- {shellsim-0.1.21 → shellsim-0.1.25}/LICENSE +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/python/shellsim/__main__.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/python/shellsim/py.typed +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/python/shellsim/python.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/rust-toolchain.toml +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/arith.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/bin/shellsim-python.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/clock.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/archives.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/arcmd.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/awk/ast.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/awk/eval.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/awk/lexer.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/awk/parser.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/awk.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/bc.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/builtins.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/dd.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/diff.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/echo.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/expr.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/find.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/format.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/fs.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/apply.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/commit.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/compare.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/config.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/conflict.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/diff.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/ignore.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/import.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/log.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/merge.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/mod.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/plumbing.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/rebase.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/refs.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/repo.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/stash.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/switch.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/git/worktree.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/grep.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/hashing.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/makecmd.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/mod.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/options.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/patch.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/pkg.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/printf.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/proc.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/regex_compat.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/rgcmd.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/sed.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/sort.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/streams.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/system.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/tarcmd.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/text.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/unavailable.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/util.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/xargs.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/commands/zipcmd.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/corpus.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/descriptors.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/expand.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/hashes.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/host_ingest.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/interp.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/jqcmd.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/lib.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/mcp.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/process.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/profile.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program/cat.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program/env.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program/find.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program/head.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program/make.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program/nice.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program/nohup.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program/sleep.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program/tee.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program/timeout.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/program/xargs.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/pseudo_fs.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/ast.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/bytecode.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/compiler.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/complex.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/cpython_names.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/exception_types.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/filesystem.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/float_text.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/hash.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/heap.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/lexer.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/mapping.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/mod.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/native.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/number.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/object_model.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/parser.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/process.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/protocol.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/slice.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/source.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/argparse.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/base64.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/bisect.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/collections.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/core.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/dataclasses.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/enum.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/frozen.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/functools.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/hashlib.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/heapq.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/http.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/importlib.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/introspect.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/itertools.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/json.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/mapping_views.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/math.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/mod.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/args.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/array.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/construct.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/convert.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/dtype.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/dtype_object.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/element.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/errstate.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/format.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/index.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/io.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/layout.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/linalg/dense.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/math.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/mod.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/ndarray.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/ops.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/products.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/random/bitgen.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/random/discrete.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/random/gamma.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/random/integers.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/random/normal.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/random/sequence.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/random.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/reduce.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/scalar.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/select.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/shape/broadcast.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/shape/diagonal.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/shape/join.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/shape/repeat.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/shape.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/sort/bincount.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/sort/search.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/sort.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/ufunc/masked.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/ufunc.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/numpy/underflow.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/operator.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/os.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/pytest.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/re.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/scipy/mod.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/scipy/special/erf.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/scipy/special/gamma.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/scipy/special/ibeta.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/scipy/special/igam.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/scipy/special/meter.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/scipy/special/mod.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/scipy/special/zeta.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/abc.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/asyncio.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/base64.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/cmath.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/codecs.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/collections.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/contextlib.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/copy.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/csv.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/datetime.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/fractions.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/functools.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/glob.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/hashlib.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/http.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/http_client.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/importlib.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/inspect.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/io.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/json.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/keyword.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/logging.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/__init__.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/_creation.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/_errors.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/_io.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/_math.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/_printing.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/_products.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/_sets.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/_shapes.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/_stats.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/exceptions.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/fft.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/random.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/numpy/testing.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/operator.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/os.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/pathlib.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/pytest.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/random.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/__init__.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/integrate.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/interpolate.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/linalg.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/optimize.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/spatial/__init__.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/spatial/distance.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/special.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/stats/__init__.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/stats/_describe.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/stats/_distributions.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/scipy/stats/_tests.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/shutil.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/signal.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/statistics.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/struct.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/subprocess.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/tempfile.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/textwrap.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/urllib.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/urllib_error.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/urllib_request.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/uuid.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/warnings.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/zipfile.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/source/zlib.py +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/string.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/struct.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/subprocess.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/sys.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/time.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/typing.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/unittest.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/vfs.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/warnings.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/stdlib/zlib.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/string.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/token.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/unicode/tables.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/unicode.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/calls.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/dispatch.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/equality.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/format.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/hashing.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/iteration.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/mappings.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/namespace.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/objects.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/operations.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm/summation.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/python/vm.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/realtime.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/resources.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/sandbox.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/scenario.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/shell.rs +0 -0
- {shellsim-0.1.21 → shellsim-0.1.25}/src/telemetry.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shellsim
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.25
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Operating System :: MacOS :: MacOS X
|
|
6
6
|
Classifier: Operating System :: Microsoft :: Windows
|
|
@@ -10,6 +10,8 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
|
10
10
|
Classifier: Programming Language :: Rust
|
|
11
11
|
Classifier: Topic :: Software Development :: Testing
|
|
12
12
|
Classifier: Typing :: Typed
|
|
13
|
+
Requires-Dist: shellsim-c-toolchain==0.1.25 ; extra == 'c'
|
|
14
|
+
Provides-Extra: c
|
|
13
15
|
License-File: LICENSE
|
|
14
16
|
Summary: In-process BusyBox-like environment for RL rollouts and agent tests
|
|
15
17
|
Keywords: agents,containers,reinforcement-learning,sandbox,simulation,testing
|
|
@@ -84,6 +86,10 @@ shellsim -c 'printf "b\na\n" | sort'
|
|
|
84
86
|
shellsim --root ./project -c 'python3.14 test.py'
|
|
85
87
|
```
|
|
86
88
|
|
|
89
|
+
Install `shellsim[c]` instead when a `.shl` package needs the separately distributed C-to-Wasm
|
|
90
|
+
toolchain. The core wheel does not contain TinyCC or the WASI sysroot. See
|
|
91
|
+
[the C toolchain contract](docs/shl-packages.md#optional-c-toolchain).
|
|
92
|
+
|
|
87
93
|
`--root` copies the selected host tree into a disposable `/work` snapshot. With no `-c` and a
|
|
88
94
|
terminal attached, `shellsim` starts a persistent interactive session.
|
|
89
95
|
|
|
@@ -206,6 +212,13 @@ as a stdio MCP server. `shellsim replay scenario.ndjson` reruns checked action t
|
|
|
206
212
|
`shellsim corpus manifest.json` runs frozen shell and Python workloads under a versioned stock
|
|
207
213
|
environment and emits a classified JSON report. See [compatibility testing](docs/compatibility-testing.md).
|
|
208
214
|
|
|
215
|
+
`shellsim serve --host-tools` grants a virtual guest-to-host tool route at construction. The
|
|
216
|
+
trusted runner receives typed calls in `poll_action` and completes them with `respond_tool_call`;
|
|
217
|
+
ordinary sessions have no such route. See [`.shl` package design](docs/shl-packages.md).
|
|
218
|
+
|
|
219
|
+
Python hosts can instead use `shellsim.Container(tools={"name": handler})` to register handlers
|
|
220
|
+
at construction and call `container.run(...)` without a CLI subprocess or manual polling.
|
|
221
|
+
|
|
209
222
|
```sh
|
|
210
223
|
printf '%s\n' \
|
|
211
224
|
'{"id":1,"op":"execute","source":"printf hello > result"}' \
|
|
@@ -61,6 +61,10 @@ shellsim -c 'printf "b\na\n" | sort'
|
|
|
61
61
|
shellsim --root ./project -c 'python3.14 test.py'
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
Install `shellsim[c]` instead when a `.shl` package needs the separately distributed C-to-Wasm
|
|
65
|
+
toolchain. The core wheel does not contain TinyCC or the WASI sysroot. See
|
|
66
|
+
[the C toolchain contract](docs/shl-packages.md#optional-c-toolchain).
|
|
67
|
+
|
|
64
68
|
`--root` copies the selected host tree into a disposable `/work` snapshot. With no `-c` and a
|
|
65
69
|
terminal attached, `shellsim` starts a persistent interactive session.
|
|
66
70
|
|
|
@@ -183,6 +187,13 @@ as a stdio MCP server. `shellsim replay scenario.ndjson` reruns checked action t
|
|
|
183
187
|
`shellsim corpus manifest.json` runs frozen shell and Python workloads under a versioned stock
|
|
184
188
|
environment and emits a classified JSON report. See [compatibility testing](docs/compatibility-testing.md).
|
|
185
189
|
|
|
190
|
+
`shellsim serve --host-tools` grants a virtual guest-to-host tool route at construction. The
|
|
191
|
+
trusted runner receives typed calls in `poll_action` and completes them with `respond_tool_call`;
|
|
192
|
+
ordinary sessions have no such route. See [`.shl` package design](docs/shl-packages.md).
|
|
193
|
+
|
|
194
|
+
Python hosts can instead use `shellsim.Container(tools={"name": handler})` to register handlers
|
|
195
|
+
at construction and call `container.run(...)` without a CLI subprocess or manual polling.
|
|
196
|
+
|
|
186
197
|
```sh
|
|
187
198
|
printf '%s\n' \
|
|
188
199
|
'{"id":1,"op":"execute","source":"printf hello > result"}' \
|
|
@@ -24,6 +24,9 @@ classifiers = [
|
|
|
24
24
|
]
|
|
25
25
|
keywords = ["agents", "containers", "reinforcement-learning", "sandbox", "simulation", "testing"]
|
|
26
26
|
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
c = ["shellsim-c-toolchain==0.1.25"]
|
|
29
|
+
|
|
27
30
|
[project.urls]
|
|
28
31
|
Homepage = "https://github.com/rjpower/shellsim"
|
|
29
32
|
Issues = "https://github.com/rjpower/shellsim/issues"
|
|
@@ -52,6 +55,7 @@ include = [
|
|
|
52
55
|
"infra/*.py",
|
|
53
56
|
"infra/**/*.py",
|
|
54
57
|
"python/**/*.py",
|
|
58
|
+
"toolchain/**/*.py",
|
|
55
59
|
"tests/python/test_*.py",
|
|
56
60
|
"tests/python_package/**/*.py",
|
|
57
61
|
"tests/tooling/**/*.py",
|
|
@@ -925,7 +925,7 @@ dependencies = [
|
|
|
925
925
|
|
|
926
926
|
[[package]]
|
|
927
927
|
name = "shellsim"
|
|
928
|
-
version = "0.1.
|
|
928
|
+
version = "0.1.25"
|
|
929
929
|
dependencies = [
|
|
930
930
|
"base64",
|
|
931
931
|
"crc32fast",
|
|
@@ -949,8 +949,9 @@ dependencies = [
|
|
|
949
949
|
|
|
950
950
|
[[package]]
|
|
951
951
|
name = "shellsim-python-bindings"
|
|
952
|
-
version = "0.1.
|
|
952
|
+
version = "0.1.25"
|
|
953
953
|
dependencies = [
|
|
954
|
+
"base64",
|
|
954
955
|
"pyo3",
|
|
955
956
|
"serde",
|
|
956
957
|
"serde_json",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[package]
|
|
4
4
|
name = "shellsim-python-bindings"
|
|
5
|
-
version = "0.1.
|
|
5
|
+
version = "0.1.25"
|
|
6
6
|
edition = "2021"
|
|
7
7
|
description = "Python bindings for shellsim"
|
|
8
8
|
license = "Apache-2.0"
|
|
@@ -14,6 +14,7 @@ name = "shellsim_native"
|
|
|
14
14
|
crate-type = ["cdylib"]
|
|
15
15
|
|
|
16
16
|
[dependencies]
|
|
17
|
+
base64 = "0.22"
|
|
17
18
|
pyo3 = { version = "0.28", features = ["abi3-py39", "extension-module"] }
|
|
18
19
|
serde = { version = "1", features = ["derive"] }
|
|
19
20
|
serde_json = "1"
|
|
@@ -12,15 +12,21 @@ use std::path::Path;
|
|
|
12
12
|
use std::sync::Mutex;
|
|
13
13
|
use std::thread;
|
|
14
14
|
|
|
15
|
+
use base64::engine::general_purpose::STANDARD;
|
|
16
|
+
use base64::Engine;
|
|
15
17
|
use pyo3::create_exception;
|
|
16
18
|
use pyo3::exceptions::PyException;
|
|
17
19
|
use pyo3::prelude::*;
|
|
18
20
|
use pyo3::types::PyBytes;
|
|
19
21
|
use serde::Serialize;
|
|
22
|
+
use shellsim::display::KeyEvent;
|
|
23
|
+
use shellsim::harness::{HarnessOperation, HarnessRequest, HarnessSession};
|
|
20
24
|
use shellsim::net::NetworkRequest;
|
|
25
|
+
use shellsim::realtime::ClockMode;
|
|
21
26
|
use shellsim::{CommandTrust, InvocationEvent, Limits, RunOutcome};
|
|
22
27
|
|
|
23
28
|
const ACTION_STACK_BYTES: usize = 8 * 1024 * 1024;
|
|
29
|
+
type PythonFrame = (u64, u32, u32, Py<PyBytes>);
|
|
24
30
|
|
|
25
31
|
create_exception!(
|
|
26
32
|
shellsim._native,
|
|
@@ -67,6 +73,253 @@ struct NativeEnvironment {
|
|
|
67
73
|
environment: Mutex<shellsim::Environment>,
|
|
68
74
|
}
|
|
69
75
|
|
|
76
|
+
/// In-process host control for a machine granted the virtual tool endpoint.
|
|
77
|
+
#[pyclass(module = "shellsim._native")]
|
|
78
|
+
struct NativeContainer {
|
|
79
|
+
session: Mutex<HarnessSession>,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#[pymethods]
|
|
83
|
+
impl NativeContainer {
|
|
84
|
+
#[new]
|
|
85
|
+
fn new(cpu: u64, memory: u64, disk: u64, output: u64, real_time: bool) -> Self {
|
|
86
|
+
Self {
|
|
87
|
+
session: Mutex::new(HarnessSession::with_clock_and_host_tools(
|
|
88
|
+
Limits {
|
|
89
|
+
cpu,
|
|
90
|
+
memory,
|
|
91
|
+
disk,
|
|
92
|
+
output,
|
|
93
|
+
},
|
|
94
|
+
if real_time {
|
|
95
|
+
ClockMode::RealTime
|
|
96
|
+
} else {
|
|
97
|
+
ClockMode::Virtual
|
|
98
|
+
},
|
|
99
|
+
)),
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
fn write_file(&self, py: Python<'_>, path: String, data: Vec<u8>, mode: u32) -> PyResult<()> {
|
|
104
|
+
let path = container_vfs_path(&path).map_err(SimulationError::new_err)?;
|
|
105
|
+
if mode > 0o7777 {
|
|
106
|
+
return Err(SimulationError::new_err("invalid file mode"));
|
|
107
|
+
}
|
|
108
|
+
py.detach(|| {
|
|
109
|
+
let mut session = self
|
|
110
|
+
.session
|
|
111
|
+
.lock()
|
|
112
|
+
.map_err(|_| "shellsim container lock is poisoned".to_string())?;
|
|
113
|
+
on_worker(&mut session, move |session| {
|
|
114
|
+
session.environment.sync_vfs_time();
|
|
115
|
+
session
|
|
116
|
+
.environment
|
|
117
|
+
.vfs
|
|
118
|
+
.put_file(&path, data, mode)
|
|
119
|
+
.map_err(|error| error.to_string())
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
.map_err(SimulationError::new_err)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
fn read_file(&self, py: Python<'_>, path: String) -> PyResult<Py<PyBytes>> {
|
|
126
|
+
let path = container_vfs_path(&path).map_err(SimulationError::new_err)?;
|
|
127
|
+
let bytes = py
|
|
128
|
+
.detach(|| {
|
|
129
|
+
let mut session = self
|
|
130
|
+
.session
|
|
131
|
+
.lock()
|
|
132
|
+
.map_err(|_| "shellsim container lock is poisoned".to_string())?;
|
|
133
|
+
on_worker(&mut session, move |session| {
|
|
134
|
+
session
|
|
135
|
+
.environment
|
|
136
|
+
.vfs
|
|
137
|
+
.read("/", &path)
|
|
138
|
+
.map_err(|error| error.to_string())
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
.map_err(SimulationError::new_err)?;
|
|
142
|
+
Ok(PyBytes::new(py, &bytes).unbind())
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
fn mkdir(&self, py: Python<'_>, path: String, mode: u32) -> PyResult<()> {
|
|
146
|
+
let path = container_vfs_path(&path).map_err(SimulationError::new_err)?;
|
|
147
|
+
if mode > 0o7777 {
|
|
148
|
+
return Err(SimulationError::new_err("invalid directory mode"));
|
|
149
|
+
}
|
|
150
|
+
py.detach(|| {
|
|
151
|
+
let mut session = self
|
|
152
|
+
.session
|
|
153
|
+
.lock()
|
|
154
|
+
.map_err(|_| "shellsim container lock is poisoned".to_string())?;
|
|
155
|
+
on_worker(&mut session, move |session| {
|
|
156
|
+
session.environment.sync_vfs_time();
|
|
157
|
+
session
|
|
158
|
+
.environment
|
|
159
|
+
.vfs
|
|
160
|
+
.put_dir(&path, mode)
|
|
161
|
+
.map_err(|error| error.to_string())
|
|
162
|
+
})
|
|
163
|
+
})
|
|
164
|
+
.map_err(SimulationError::new_err)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
fn snapshot_workspace(&self, py: Python<'_>) -> PyResult<String> {
|
|
168
|
+
py.detach(|| {
|
|
169
|
+
let mut session = self
|
|
170
|
+
.session
|
|
171
|
+
.lock()
|
|
172
|
+
.map_err(|_| "shellsim container lock is poisoned".to_string())?;
|
|
173
|
+
on_worker(&mut session, |session| {
|
|
174
|
+
let entries = session.snapshot_workspace()?;
|
|
175
|
+
serde_json::to_string(&entries).map_err(|error| error.to_string())
|
|
176
|
+
})
|
|
177
|
+
})
|
|
178
|
+
.map_err(SimulationError::new_err)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
fn start_execute(&self, py: Python<'_>, source: String, stdin: Vec<u8>) -> PyResult<String> {
|
|
182
|
+
self.apply(
|
|
183
|
+
py,
|
|
184
|
+
HarnessOperation::StartExecute {
|
|
185
|
+
source,
|
|
186
|
+
stdin_base64: STANDARD.encode(stdin),
|
|
187
|
+
stdin_closed: true,
|
|
188
|
+
},
|
|
189
|
+
)
|
|
190
|
+
.and_then(serialize_result)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
fn poll_action(&self, py: Python<'_>, action_id: u64) -> PyResult<String> {
|
|
194
|
+
self.apply(
|
|
195
|
+
py,
|
|
196
|
+
HarnessOperation::PollAction {
|
|
197
|
+
action_id,
|
|
198
|
+
work_quanta: 100_000,
|
|
199
|
+
advance_time: true,
|
|
200
|
+
},
|
|
201
|
+
)
|
|
202
|
+
.and_then(serialize_result)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
fn respond_tool_call(
|
|
206
|
+
&self,
|
|
207
|
+
py: Python<'_>,
|
|
208
|
+
request_id: u64,
|
|
209
|
+
result_json: Option<String>,
|
|
210
|
+
error: Option<String>,
|
|
211
|
+
) -> PyResult<()> {
|
|
212
|
+
let result = result_json
|
|
213
|
+
.map(|json| serde_json::from_str(&json))
|
|
214
|
+
.transpose()
|
|
215
|
+
.map_err(|error| SimulationError::new_err(error.to_string()))?;
|
|
216
|
+
self.apply(
|
|
217
|
+
py,
|
|
218
|
+
HarnessOperation::RespondToolCall {
|
|
219
|
+
request_id,
|
|
220
|
+
result,
|
|
221
|
+
error,
|
|
222
|
+
},
|
|
223
|
+
)?;
|
|
224
|
+
Ok(())
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
fn read_action_output(&self, py: Python<'_>, action_id: u64) -> PyResult<String> {
|
|
228
|
+
self.apply(py, HarnessOperation::ReadActionOutput { action_id })
|
|
229
|
+
.and_then(serialize_result)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
fn cancel_action(&self, py: Python<'_>, action_id: u64) -> PyResult<()> {
|
|
233
|
+
self.apply(py, HarnessOperation::CancelAction { action_id })?;
|
|
234
|
+
Ok(())
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
fn drop_action(&self, py: Python<'_>, action_id: u64) -> PyResult<()> {
|
|
238
|
+
self.apply(py, HarnessOperation::DropAction { action_id })?;
|
|
239
|
+
Ok(())
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
fn display_frame(&self, py: Python<'_>, action_id: u64) -> PyResult<Option<PythonFrame>> {
|
|
243
|
+
let frame = py
|
|
244
|
+
.detach(|| {
|
|
245
|
+
let mut session = self
|
|
246
|
+
.session
|
|
247
|
+
.lock()
|
|
248
|
+
.map_err(|_| "shellsim container lock is poisoned".to_string())?;
|
|
249
|
+
on_worker(&mut session, |session| session.display_frame(action_id))
|
|
250
|
+
})
|
|
251
|
+
.map_err(SimulationError::new_err)?;
|
|
252
|
+
Ok(frame.map(|(generation, frame)| {
|
|
253
|
+
(
|
|
254
|
+
generation,
|
|
255
|
+
frame.width,
|
|
256
|
+
frame.height,
|
|
257
|
+
PyBytes::new(py, &frame.pixels).unbind(),
|
|
258
|
+
)
|
|
259
|
+
}))
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
fn inject_key(&self, py: Python<'_>, action_id: u64, code: u32, pressed: bool) -> PyResult<()> {
|
|
263
|
+
py.detach(|| {
|
|
264
|
+
let mut session = self
|
|
265
|
+
.session
|
|
266
|
+
.lock()
|
|
267
|
+
.map_err(|_| "shellsim container lock is poisoned".to_string())?;
|
|
268
|
+
on_worker(&mut session, |session| {
|
|
269
|
+
session.inject_action_key(action_id, KeyEvent { code, pressed })
|
|
270
|
+
})
|
|
271
|
+
})
|
|
272
|
+
.map_err(SimulationError::new_err)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
fn clock_mode(&self) -> PyResult<&'static str> {
|
|
276
|
+
let session = self
|
|
277
|
+
.session
|
|
278
|
+
.lock()
|
|
279
|
+
.map_err(|_| SimulationError::new_err("shellsim container lock is poisoned"))?;
|
|
280
|
+
Ok(match session.environment.clock_mode() {
|
|
281
|
+
ClockMode::Virtual => "virtual",
|
|
282
|
+
ClockMode::RealTime => "real_time",
|
|
283
|
+
})
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
impl NativeContainer {
|
|
288
|
+
fn apply(&self, py: Python<'_>, operation: HarnessOperation) -> PyResult<serde_json::Value> {
|
|
289
|
+
py.detach(|| {
|
|
290
|
+
let mut session = self
|
|
291
|
+
.session
|
|
292
|
+
.lock()
|
|
293
|
+
.map_err(|_| "shellsim container lock is poisoned".to_string())?;
|
|
294
|
+
on_worker(&mut session, move |session| {
|
|
295
|
+
let response = session.handle(HarnessRequest {
|
|
296
|
+
id: None,
|
|
297
|
+
session_id: None,
|
|
298
|
+
operation,
|
|
299
|
+
});
|
|
300
|
+
if !response.ok {
|
|
301
|
+
return Err(response
|
|
302
|
+
.error
|
|
303
|
+
.unwrap_or_else(|| "container operation failed".into()));
|
|
304
|
+
}
|
|
305
|
+
serde_json::to_value(response.result).map_err(|error| error.to_string())
|
|
306
|
+
})
|
|
307
|
+
})
|
|
308
|
+
.map_err(SimulationError::new_err)
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
fn container_vfs_path(path: &str) -> Result<String, String> {
|
|
313
|
+
if path.contains('\0') {
|
|
314
|
+
return Err("container path contains NUL".to_string());
|
|
315
|
+
}
|
|
316
|
+
Ok(shellsim::vfs::resolve_against("/work", path))
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
fn serialize_result(result: serde_json::Value) -> PyResult<String> {
|
|
320
|
+
serde_json::to_string(&result).map_err(|error| SimulationError::new_err(error.to_string()))
|
|
321
|
+
}
|
|
322
|
+
|
|
70
323
|
#[pymethods]
|
|
71
324
|
impl NativeEnvironment {
|
|
72
325
|
#[new]
|
|
@@ -380,11 +633,16 @@ fn invocation_names(events: &[InvocationEvent], trust: CommandTrust) -> Vec<Stri
|
|
|
380
633
|
}
|
|
381
634
|
|
|
382
635
|
/// Run an environment operation with a predictable native stack and contain all Rust unwinds.
|
|
383
|
-
fn on_worker<T, F>(
|
|
636
|
+
fn on_worker<State, T, F>(
|
|
637
|
+
guard: &mut std::sync::MutexGuard<'_, State>,
|
|
638
|
+
operation: F,
|
|
639
|
+
) -> Result<T, String>
|
|
384
640
|
where
|
|
641
|
+
State: Send,
|
|
385
642
|
T: Send,
|
|
386
|
-
F: FnOnce(&mut
|
|
643
|
+
F: FnOnce(&mut State) -> Result<T, String> + Send,
|
|
387
644
|
{
|
|
645
|
+
let environment = &mut **guard;
|
|
388
646
|
thread::scope(|scope| {
|
|
389
647
|
let worker = thread::Builder::new()
|
|
390
648
|
.name("shellsim-python".to_string())
|
|
@@ -416,6 +674,7 @@ fn panic_suffix(payload: &(dyn Any + Send)) -> String {
|
|
|
416
674
|
#[pymodule]
|
|
417
675
|
fn _native(module: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
418
676
|
module.add_class::<NativeEnvironment>()?;
|
|
677
|
+
module.add_class::<NativeContainer>()?;
|
|
419
678
|
module.add("SimulationError", module.py().get_type::<SimulationError>())?;
|
|
420
679
|
Ok(())
|
|
421
680
|
}
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
from . import python as python
|
|
4
4
|
from ._api import (
|
|
5
|
+
Action,
|
|
6
|
+
ActionPoll,
|
|
5
7
|
CommandUsage,
|
|
8
|
+
Container,
|
|
9
|
+
DisplayFrame,
|
|
6
10
|
Environment,
|
|
7
11
|
HttpRequest,
|
|
8
12
|
HttpResponse,
|
|
@@ -12,21 +16,32 @@ from ._api import (
|
|
|
12
16
|
RunResult,
|
|
13
17
|
ShellSession,
|
|
14
18
|
SimulationError,
|
|
19
|
+
ToolError,
|
|
15
20
|
Usage,
|
|
16
21
|
run,
|
|
17
22
|
)
|
|
23
|
+
from .display_host import DisplayHost
|
|
24
|
+
from .package import Package, PackageSpec
|
|
18
25
|
|
|
19
26
|
__all__ = [
|
|
27
|
+
"Action",
|
|
28
|
+
"ActionPoll",
|
|
20
29
|
"CommandUsage",
|
|
30
|
+
"Container",
|
|
31
|
+
"DisplayFrame",
|
|
32
|
+
"DisplayHost",
|
|
21
33
|
"Environment",
|
|
22
34
|
"HttpRequest",
|
|
23
35
|
"HttpResponse",
|
|
24
36
|
"Invocation",
|
|
25
37
|
"Limits",
|
|
26
38
|
"MountResult",
|
|
39
|
+
"Package",
|
|
40
|
+
"PackageSpec",
|
|
27
41
|
"RunResult",
|
|
28
42
|
"ShellSession",
|
|
29
43
|
"SimulationError",
|
|
44
|
+
"ToolError",
|
|
30
45
|
"Usage",
|
|
31
46
|
"run",
|
|
32
47
|
"python",
|