#venvstacks

1 messages · Page 1 of 1 (latest)

tepid lava
#

Even if that proposed solution ends up not working out, though, there are ways of working around the limitation.

tepid lava
tepid lava
#

If anyone is experimenting with this, it's worth being aware of the (undocumented) constraint that postinstall scripts in 0.1.x. have to be executed using the underlying base runtime, or they won't work properly: https://github.com/lmstudio-ai/venvstacks/issues/66

Rather than documenting that, I'm instead working on eliminating the restriction.

GitHub

While working on #24/#64, I found a problem where the postinstall scripts will do the wrong thing if executed with something other than the expected base runtime environment (pyvenv.cfg gets popula...

#

The fix for that has been merged to main, but I'll only publish 0.2.0 after I've finished the automatic layer versioning feature that picked up that those test cases were broken.

tepid lava
misty fiber
#

Just a question - if I wanted to use venvstacks in my own application, with the current functionality, I'd have to write my own venvstacks.toml manually?

tepid lava
#

Kind of, in that there's no venvstacks init command to generate a skeleton. However, grabbing a copy of https://github.com/lmstudio-ai/venvstacks/blob/main/tests/minimal_project/venvstacks.toml or https://github.com/lmstudio-ai/venvstacks/blob/main/tests/sample_project/venvstacks.toml and editing it to suit the specific use case is a better workaround than starting with a blank file.

GitHub

Virtual environment stacks for Python. Contribute to lmstudio-ai/venvstacks development by creating an account on GitHub.

GitHub

Virtual environment stacks for Python. Contribute to lmstudio-ai/venvstacks development by creating an account on GitHub.

misty fiber
#

And just to be sure, something like cli.py in the sample_project is the main python logic I intending to get running, right?

#

or the x_imports are just applications too?

#

OH I see, the difference is between the deps, got it!

tepid lava
#

Yeah, there are two things that can differ between the application layers:

  • which dependencies to install
  • the launch module code

In the sample project, both of those things are different (since it's aiming to be a decent exercise of the full end-to-end capability)

#

Actually running the launch modules is with the deployed env's Python -m switch, but the docs for locating that in a platform independent way aren't really there yet.

misty fiber
#

Bare w/ me because I am pretty new to build systems revolving python in general - let's say if I have my application published with venvstacks and I get the .tar.gz files. How would I run the python code, for example, my golang code?

tepid lava
#
  1. Unpack all 3 layers in the same location on the target system (so the directories end up next to each other). For each one, run the post-installation script after unpacking.
  2. Once everything is unpacked, run the application layer's launch module using the -m switch for the Python executable in that environment.
misty fiber
#

I shall try this and get back to you!

tepid lava
#

The longer version of the required steps:

  1. Read the layer config from {env_path}share/venv/metadata/venvstacks_layer.json
  2. Resolve base_python from the layer config relative to the environment folder
  3. Use that resolved path to run {base_python_path} {env_path}/postinstall.py
  4. Read launch_module from the layer config
  5. Resolve python from the layer config relative to the environment folder
  6. Use that resolved path to run {python_path} -m {launch_module} (potentially with CLI arguments, depending on the use case)

The rest of the fields in the layer config are for the post-installation script to worry about - the embedding application won't need to care.

misty fiber
#

would my launch module be present in site_packages?

tepid lava
#

Yeah, they get copied there by the layer build process.

#

So naming conflicts with dependencies are something to watch out for.

misty fiber
#

And I only need to run the launch_module for the application layer?

tepid lava
#

That's right. The build process will complain if you try to define them for other layers.

misty fiber
#

Pretty sure I did something wrong, I am going to retry this

tepid lava
misty fiber
#

Let me list down the steps I did

  1. Extract these 3 files
  2. Go in each folder starting from cpython and run ./bin/python -m postinstall
  3. Run the launch module in the app-scipy folder by going inside the lib folder and running ../../../bin/python -m scipy_import

I am trying to do it in my terminal manually

#

(i'd assumed the /bin/python have symlinks so they all end up using the same binary)

#

Gives me no module name 'scipy'

tepid lava
#

You shouldn't need to change directory. Something more like (adjust exact layer versions as needed):

$ cpython-3.11/bin/python cpython-3.11/postinstall.py
$ cpython-3.11/bin/python framework-scipy@1/postinstall.py
$ cpython-3.11/bin/python app-scipy@1/postinstall.py
$ app-scipy@1/bin/python -m scipy_import

Using the layered envs before they're configured properly mostly works on non-Windows systems (as you say, they're just symlinks), but the above avoids making that assumption.

One potential trap is that the unpack needs to not include the tarball's own name - the relative paths between environments won't work if that extra layer is present (I doubt that is the case for you though, since the postinstall executions would fail for that scenario).

#

A useful diagnostic is to run app-scipy@1/bin/python -m site to get the layer Python to dump where it is looking for files.

misty fiber
tepid lava
#

Yes, that's the "adjust exact layer versions as needed" part. Those layers have autonumbering turned on, so they may come out different based on whether someone has just grabbed the venvstacks.toml file from the test suite, or has grabbed the full requirements folder as well (the environment locks used for the layer autonumbering are stored alongside the locked dependency files)

misty fiber
#

It worked!

#

Thank you so much for bearing with me with this

tepid lava
#

Hey, I'm excited to see someone outside LMStudio actively trying it out 🙂

misty fiber
#

I just rebuilt everything with the @1 instead of @2 and I think that solved the problem?

tepid lava
#

We published it because we thought other people would find it useful, but there's nothing like actually getting real feedback to validate that 🙂

misty fiber
tepid lava
#

If you still have the original tarballs, I'd be interested in their venvstacks_layer.json files.

#

In particular, if the app layer config file was referencing the wrong version of the framework layer, that could explain what you were seeing.

misty fiber
#

Oh yes! That is exactly the issue (this is the older .json)

  "base_python": "../cpython-3.11/bin/python",
  "dynlib_dirs": [],
  "py_version": "3.11.10",
  "pylib_dirs": [
    "../framework-scipy@1/lib/python3.11/site-packages",
    "../cpython-3.11/lib/python3.11/site-packages"
  ],
  "python": "bin/python",
  "site_dir": "lib/python3.11/site-packages"
}
#

any reason why this happened? or was it something i did which broke it?

tepid lava
#

Certainly the easiest way to get into that situation is to update the framework layer without rebuilding the application layer. The fact you lose transparent framework layer updates is the biggest downside of turning on the layer versioning (and is the main reason the layer versioning is opt-in rather than opt-out)

#

It's not impossible for there to be bugs around relocking-and-rebuilding in the same step, though - the test suite necessarily separates the failing test run that updates the locked requirements from the subsequent successful test run using those updated expectations.

tepid lava
#

Hmm, Neil might have a stronger argument than I thought he did for ditching the implicit lock support.

#

(when we added the separate lock and publish subcommands, he wondered if we should keep the "all-in-one" aspects of the build subcommand)

#

We will need to consider that further if anyone else starts running into similar "framework was built as version X, but built app layer still declared a dependency on version X-1" problems.

misty fiber
#

I still have no idea how I ended up with the 2nd layer version - I had just used the commands from the homepage of the documentation. Trying to rerun them again in different combinations still hasn't reproduced another layer version for me, which is very interesting (or lock version I think after reading the github issue)

tepid lava
#

If you got a double version bump when starting from a bare venvstacks.toml file (with no parallel requirements folder) that would definitely be interesting, since that scenario isn't covered in the test suite (the full sample project test is always running against the previously checked in version, and the minimal project doesn't have layer versioning enabled).

... that's a pretty good argument to add layer versioning to the minimal project tests.

misty fiber
#

Ah I see. Tomorrow I'll try to build a stack from scratch for my app, let's see how'd that go

tepid lava
misty fiber
#

Finally getting my own venvstack for my application

simple question - why do we need to redefine the requirements in the application layer if we are already giving it the framework?

name = "sklearn-import"
launch_module = "launch_modules/sklearn_import.py"
frameworks = ["sklearn"]
requirements = [
    "scikit-learn",
]
platforms = ["linux_x86_64"]
misty fiber
tepid lava
#

The requirements redefinition is because an app may only depend on a subset of what the framework layer provides. Having it default to depending on the same things the framework depends on would be a reasonable bit of syntactic sugar, though.

tepid lava
#

I'm currently pondering this design problem for venvstacks: https://github.com/lmstudio-ai/venvstacks/issues/2

The current "constraints" locking model works by locking from the bottom up (runtimes, then frameworks, then applications), and using the lower layer requirements.txt files as constraints when locking the upper layers. This can lead to locking failures in upper layers if they impose an upper bound that the lower layers aren't otherwise aware of. The upper bounds (once known) can be added to the lower layer definitions, but then there is no straightforward way to determine if they're still needed (other than removing them and seeing if the stack still locks).

It shouldn't be that hard to build a "comprehensive" locking mode atop uv's workspace mechanism that bundles a runtime layer and all the framework and application layers that depend on it into a single mutually compatible lock file that all the layers then use as their constraints file. The downside of comprehensive locking is that it loses the ability to incrementally relock parts of the dependency tree without risking inconsistencies.

The question is then whether it would be feasible to make a hybrid mode that used the differences between the locked versions for those two approaches to determine a set of "inferred upper bounds" for the runtime and framework layers, which would then allow incremental relocking the same way the currently locking model does, without having to manually infer the transitive upper bounds.

GitHub

The initial venvstacks locking mode operates by way of constraint files: when an upper layer depends on lower layers, the pinned requirements of the lower layers are used as constraints when compil...

tepid lava
tepid lava
#

With inspiration from @inner rover , the local wheel test case in https://github.com/lmstudio-ai/venvstacks/pull/122 is now looking promising (it uses stable ABI wheels built on the Python version running the test suite to populate a pair of virtual environment stacks that specifically run on Python 3.11).

(adding this test case is a preparatory step towards making the "split layers" case work on platforms other than Windows)

tepid lava
#

Hmm, I'm annoyingly getting a "failed to find ninja" error in the Windows builds, while the dynamic-library builds don't seem to be hitting a problem with that.

tepid lava
tepid lava
tepid lava
#

ninja, Windows, GitHub Actions

tepid lava
#

Success! Local wheel test has been merged to main, which means next week I can get started on removing the Windows qualifier from the split framework layer test case 🙂

tepid lava
#

Ugh, something somewhere is being clever, and it is making writing this test case difficult:

/tmp/tmpbqiwe6lm/_export🦎/framework-only-consumer/lib/python3.11/site-packages/dynlib_consumer.abi3.so
        linux-vdso.so.1 (0x00007ffcbf1ee000)
        libcheckdynlib.so => /tmp/tmp5_0p7lwp/build_venv/lib/python3.12/site-packages/dynlib_publisher/libcheckdynlib.so (0x00007f2220141000)

I don't know how the dynamic linker is finding the built-in-a-subprocess shared library inside the build venv, but it is.

#

I guess I don't really need to figure it out - I can just destroy the build venv after the wheels are built, so the built dynlib simply isn't there anymore (there's a separate folder that stores the locally built wheels for the test case)

#

Hah, and in complaining about it, I realised this is happening because the consumer lib has an absolute RPATH in it instead of a relative one. So once I delete the build venv copy, even the version of the test case that isn't split across multiple framework layers will fail.

#

Huzzah:

subprocess.CalledProcessError: Command '['/tmp/tmprb9f7asg/_export🦎/app-via-combined-layer/bin/python', '-X', 'utf8', '-Im', 'dynlib_import']' returned non-zero exit status 1
tepid lava
#

That's more like it:

framework-both-wheels
        linux-vdso.so.1 (0x00007fff441dc000)
        libcheckdynlib.so => /tmp/tmpl2y5512o/_export🦎/framework-both-wheels/lib/python3.11/site-packages/dynlib_publisher/libcheckdynlib.so (0x00007f0d0bc13000)
framework-only-consumer
        linux-vdso.so.1 (0x00007ffdfc1a6000)
        libcheckdynlib.so => not found
#

Now the test case fails as expected, I can finally get started on the actual task (making it pass)

tepid lava
#

Despite the excess of red crosses in CI, the draft PR at https://github.com/lmstudio-ai/venvstacks/pull/124 actually goes a long way towards finally proving the concept behind allowing shared object loading across layers.

It just also shows that I was right in the issue description in that a library exclusion mechanism would be needed to resolve naming conflicts.

tepid lava
#

Gah, poring over a generated shell script trying to figure out why it wasn't running properly in dash & zsh, only to eventually realise one of the commands had a &> /dev/null in it (bashism for 1> /dev/null 2>&1)

#

(Fedora never switched away from bash, so my local build was entirely fine, but CI failed on both Ubuntu and macOS)

#

sigh dash strikes again. Its exec builtin doesn't provide -a, so using /bin/sh as the wrapper script shebang fails on Ubuntu.

tepid lava
#

I guess forcing bash on Linux and zsh on macOS is strictly more accurate than using /bin/sh anyway, since I do genuinely need the exec -a feature.

tepid lava
#

Still some follow up work to be completed (release notes, docs updates, improving a couple of details), but 0.4.0 (once it is released) will support loading shared objects from other layers on both Linux (via bash) and macOS (via zsh). (This already works on Windows assuming os.add_dll_directory is called appropriately)

tepid lava
tepid lava
#

Considering the comment I made here: #off-topic message

I'd been assuming it didn't make sense to publish a venvstacks-consumer client library/utility in Python, but I'm starting to wonder if that's a valid assumption.

Even an app written in Python may have valid reasons for wanting to embed a separate dedicated runtime for executing user or plugin code, and a Python reference implementation can still serve as a useful illustrative example for apps written in other languages.

dark sorrel
#

Personally I'd encourage you to explore that. I feel like in general, building on top of your own "client library" leads to better internal architecture. And e.g. in the case of Pip there would be less misuse if people had had an explicit package-installation API to begin with, even if it's unclear to the maintainers what the use case is.

tepid lava
#

And I have at least the beginnings of that side, since the test suite needed them. Even if folks don't use it in their production deployments, they may find it useful for checking their stack builds actually worked.

tepid lava
tepid lava
tepid lava
#

Feature idea I plan to add to the issue tracker (prompted by #off-topic message): virtual layer archives.

When building layers in this mode,
instead of including the installed wheels in the layer archives, pip will be included in the runtime layers, the lock files will be included in each layer, and the post install scripts will install from the lock files using the PyPI index configuration specified at build time

tepid lava
#

Updating the declared CI dependencies to resolve a dependabot complaint about a h11 CVE revealed some rather significant gaps in the test coverage around handling changes to layer dependency declarations that aren't accompanied by a layer name change or lock reset: https://github.com/lmstudio-ai/venvstacks/issues/149

GitHub

The PR at #148 should have been a simple update to address a dependabot complaint about h11 CVE-2025-43859. Surprisingly, updating the UV_EXCLUDE_NEWER setting in the expected output config file di...

#

No new release for that yet (still needs release notes and additional test suite updates), so in the meantime, available workarounds are:

  • use --reset-lock to do full layer lock resets when the inputs change
  • use explicit layer versioning in the layer names (since the name changes effectively serve as layer lock resets)
tepid lava
#

New release has been published: https://github.com/lmstudio-ai/venvstacks/releases/tag/0.5.0

It's mostly assorted layer lock invalidation fixes, but a few other notable changes:

  • with the improved layer lock invalidation, launch module changes in application layers will also bump the layer version when using implicit layer versioning
  • resolving symlink conflicts should require fewer build iterations now, as the initial exception will report all of the ambiguities in the layer rather than just the first one encountered
GitHub

➡️  PyPI page: venvstacks 0.5.0.
Changed

Layer locks are now invalidated for launch module changes. This also means that implicit versioning will update the layer version (resolves #89).
The excep...

reef drift
#

Awesome stuff, will try it out this evening and see if I can package my code with it, wish me luck 🤞

tepid lava
#

With the benefit of hindsight, 0.5.0 really could have done with a beta cycle.

#

(assorted poor interactions with in-place upgrades of existing projects, as well as with the lock reset feature)

timid pumice
#

on the other hand, it's zerover, it's fine to break things!

#

😄

tepid lava
tepid lava
#

0.6.0 feature release has been published: https://github.com/lmstudio-ai/venvstacks/releases/tag/0.6.0

  • Most notable changes are the additions of support_modules and preferring hardlinks in local export when the export destination is on the same filesystem as the build tree
  • There are also assorted adjustments to the way lock updates are handled for existing trees
GitHub

➡️  PyPI page: venvstacks 0.6.0.
Added

A new optional field, support_modules, has been added to application layer specifications. This field allows application layers to embed copies of common un...

tepid lava
tepid lava
tepid lava
#

0.7.0 feature release has been published: https://github.com/lmstudio-ai/venvstacks/releases/tag/0.7.0

Primary changes are the console output improvements noted above, but keeping RECORD files around means that projects that expect to be able to access their own file listing metadata at runtime now work correctly when deployed with venvstacks.

GitHub

➡️  PyPI page: venvstacks 0.7.0.
Added

show subcommand to display layer definitions (added in #159).
--show option on subcommands (other than show) to display the selected layers and operations b...

tepid lava
#

I'm kinda regretting picking venvstacks.toml as the default stacks file name now, as it means I can't use it as the tool config file name.

I guess I could take the approach of:

  • if there's a [config] table in the stacks file, that gets used as the tool config
  • otherwise, look for venvstacks-config.toml adjacent to the stacks file

That way, to share the same config across multiple stacks files, put it in a separate venvstacks-config.toml file. At some point in the future I could potentially define an inherit-config option to inherit settings from other config files, but I'd leave that out of the initial iteration.

cinder nebula
# tepid lava I'm kinda regretting picking `venvstacks.toml` as the default stacks file name n...

I always thought the point of pyproject.toml was to act as a consolidation point for requirements and metadata around a Python project. While PEP 621 is mainly framed in terms of build backends, maybe it’s worth pushing the conversation further.
towards making it a general home for project-related configuration too.

Honestly, I’m getting a bit fatigued by the proliferation of tool-specific TOML files — ruff.toml, uv.toml, ty.toml, and now potentially venvstacks.toml/venvstacks-config.toml. It feels like we’re moving in the opposite direction of consolidation. I’d much prefer if all this project-related config lived in one place, with pyproject.toml being the obvious candidate for that “single source of truth.”

That said, I get why you want to keep a clean separation between “stacks definition” and “tool config” — it probably simplifies the mental model. But maybe the long-term solution should be encouraging projects (or the PyPA specs) to evolve pyproject.toml to explicitly support general-purpose tool configuration, rather than everyone inventing yet another *.toml.

tepid lava
#

Environment stack definitions aren't really Python projects in their own right (launch modules notwithstanding), so I never seriously considered using pyproject.toml. Too many of the standard metadata fields simply don't apply.

Most of the other tools do accept their config via the pyproject.toml [tool] table these days, but also accept dedicated config files for both backwards compatibility and for cases where there is no pyproject.toml

cinder nebula
#

fair enough, thanks

vocal badger
reef hill
tepid lava
#

0.8.0 is going to be a substantial release that invalidates all existing layer lock files by switching from requirements.txt to pylock.toml (the layer package summaries will still use the flat requirement format, though)

There's a large set of improvements coming alongside that inconvenience, though:

  • cross-platform locking (no more per-platform layer locks)
  • support for custom index configuration (include per-layer prioritisation of named indexes)
  • support for package source overrides (primarily so different layers may pull torch from different indexes)
  • accepting most other uv settings via the tool.uv table in venvstacks.toml (or via an adjacent venvstacks.uv.toml file)
  • using uv pip install instead of pip install for the layer build step (needed to make the above changes actually work)

Independently of the uv related changes:

  • pbs-installer has been improved to always prefer the stripped CPython runtimes (no venvstacks update needed, just an update of its pinned dependencies)
  • much of the traceback spam when subprocess invocations fail has been eliminated
tepid lava
#

@alpine charm Are you aware of any compatibility issues with pdm and pip 25.3? I just got a super weird CI error in venvstacks trying to update the CI lock to the latest version of everything. Example stack trace (every platform did something similar in CI, but I couldn't reproduce the problem locally on Fedora):

ERRORS:
add pip failed:
Traceback (most recent call last):
  File 
"/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/pdm/instal
lers/synchronizers.py", line 191, in synchronize
    handlers(key, status.progress)
... snip a bunch of traceback lines ...
  File 
"/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/pdm/enviro
nments/base.py", line 85, in _build_session
    from pdm.models.session import PDMPyPIClient
  File 
"/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/pdm/models
/session.py", line 14, in <module>
    from pdm.models.serializers import MsgPackSerializer
  File 
"/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/pdm/models
/serializers.py", line 8, in <module>
    from hishel._serializers import Metadata
ModuleNotFoundError: No module named 'hishel._serializers'
tepid lava
# tepid lava <@532467288566136832> Are you aware of any compatibility issues with `pdm` and `...

The preceding PDM install looked like it finished without any problems (and hishel was installed):

Installing collected packages: distlib, urllib3, typing-extensions, truststore, tomlkit, socksio, sniffio, shellingham, resolvelib, python-dotenv, pyproject-hooks, pygments, platformdirs, pbs-installer, packaging, msgpack, mdurl, installer, idna, h11, filelock, charset-normalizer, certifi, blinker, virtualenv, requests, markdown-it-py, httpcore, hishel, findpython, dep-logic, anyio, rich, id, httpx, unearth, pdm

Successfully installed anyio-4.11.0 blinker-1.9.0 certifi-2025.10.5 charset-normalizer-3.4.4 dep-logic-0.5.2 distlib-0.4.0 filelock-3.20.0 findpython-0.7.0 h11-0.16.0 hishel-1.1.2 httpcore-1.0.9 httpx-0.28.1 id-1.5.0 idna-3.11 installer-0.7.0 markdown-it-py-4.0.0 mdurl-0.1.2 msgpack-1.1.2 packaging-25.0 pbs-installer-2025.8.27 pdm-2.25.9 platformdirs-4.5.0 pygments-2.19.2 pyproject-hooks-1.2.0 python-dotenv-1.2.1 requests-2.32.5 resolvelib-1.2.1 rich-14.2.0 shellingham-1.5.4 sniffio-1.3.1 socksio-1.0.0 tomlkit-0.13.3 truststore-0.10.4 typing-extensions-4.15.0 unearth-0.18.1 urllib3-2.5.0 virtualenv-20.35.4
#

pdm failure on CI lock update

tepid lava
tepid lava
#

@gaunt glacier I wrote up your layer template idea at https://github.com/lmstudio-ai/venvstacks/issues/328

After writing it up, I think it completely supercedes the old idea of figuring out a way to define matrix builds. I won't close the previous issue yet, but I'm certainly leaning that way.

GitHub

(This is a potential alternative approach to resolving #179 that can be handled via relatively simple dict manipulation when reading the stack specifications, rather than the complex additions that...

tepid lava
#

Some highlights:

  • Cross-platform layer locks
  • uv configuration (including custom indexes with per-layer override options)
  • deriving layer lock times from uv's exclude-newer setting
  • layer target platforms are inferred from the layers they depend on
  • respecting MACOSX_DEPLOYMENT_TARGET
  • following uv's baseline target for portable Linux environments
tepid lava
#

That's a lot of layer lock file noise removed by the fixes, though (mostly from dropping the wheel listings for wheels imported from lower layers):

tepid lava
#

After finding that some of the example stacks didn't actually build after the --python-platform changes, I added a linux_target field (similar to macosx_target), so layer builds can target newer versions of glibc than 2.28: https://github.com/lmstudio-ai/venvstacks/pull/341

tepid lava
#

The actual 0.8.0 final release is currently expected to happen after the resolution of https://github.com/lmstudio-ai/venvstacks/issues/326 lands (it turns out the new cross-platform locking makes it unfortunately easy to generate a lock file that seems to be cross-platform, but is actually missing wheels for some of the intended target platforms. The new changes add a post-lock check that fails if the lock file doesn't include a wheel for all of the expected platforms, without incurring all the environment marker noise in the lock file and package summaries that comes with requesting uv's native target environment enforcement.

GitHub

Due to the way uv is invoked, it's possible for a layer lock to be generated with wheels for some expected platforms being missing (and due to the problems encountered in #306 that aspect of th...

gaunt glacier
#

Issue 326

tepid lava
#

This mostly affects @gaunt glacier (who already knows), but in the interests of transparency: I've left LM Studio for a role with Westpac here in Australia, so while I'll still be here to assist with any usage questions folks may have, I'm not actively developing venvstacks myself any more (Neil and other folks at LM Studio will be taking that over).

gaunt glacier
#

Was great collaborating with you @tepid lava , and wish you the best at the new role!

#

Not sure how clear it is to the community here, but for a year now LM Studio has been using venvstacks in production for all of our python functionality, including Apple's MLX and Openai's harmony. Alyssa has done a fantastic job of taking this project from zero to one. Thank you Alyssa!

tepid lava
#

@gaunt glacier I've been thinking a bit more about potential ways to get https://github.com/lmstudio-ai/venvstacks/blob/main/.github/workflows/prepare-release.yml to actually work properly (instead of creating the GH release without triggering the push to PyPI). The cleanest idea I've come up with would be to:

tepid lava
tepid lava