loom

Implementation of Loom as a Python library & CLI (+ lightweight tree-nav TUI). Intuitive for use/learning by humans + coding/tool-use agents; features rich sampler-param modulation, automatic base model emulation for instruct models, and more.


Intro

the following draft was written at the late peak of the bulk of work done on the project (as of yet).

external: Gist · Oct 2024

I am currently working on an implementation of Loom as a Python library and CLI + TUI.

I. what is Loom (broadly)?

not to be confused with the screen recording app, the first loom implementation was written by Janus in 2021 to manage GPT-3 completions.

a number of Loom clients exist today; a few are ~actively maintained. most, but not all of them are designed for operation with base models, which I'll discuss briefly in this post, plus (likely) in more detail in a future post.

context

early GPT models (pre-davinci) were released on the OpenAI API with no fine-tuning; they were completion engines, not answer machines[^1]. For a span of time, deriving useful outputs from a language model was a bit of an art form.

[^1]: chat models are, and have always been, so much more than just answer machines, but most people use and relate to them in this way.

at this point in time, every language model was what's now known by some[^2] as a base model. I'm not currently aware of how the term "base model" was coined (or who coined it), but I presume that it emerged post-InstructGPT, to distinguish pretrained models from fine-tuned ones.

[^2]: The term "base model" became overloaded rather quickly, largely via a process that was accelerated by the release of Llama + Alpaca/Vicuna, kicking off the era of OSS fine-tuning. Today, most platforms that offer fine-tuning as a service refer to the (generally chat model being fine-tuned as the "base model." When I or other Loom appreciators use the term "base model," we're typically referring to these base models.

me «» LLMs

leading up to ChatGPT’s release in 2022, a wave of people came onto the scene via DALL•E 2 and Stable Diffusion — I myself was first exposed to GPT-3 outputs via Reddit, where it was not especially uncommon for switched-on enthusiasts to recommend it as an accessible (OpenAI provided ~$10 of API credits to anyone who signed up) method to generate prompts for image models via the OpenAI playground, typically with text-davinci-002.

The concept of generating text was pretty foreign to me at the time, and my impression from my first few interactions was that it felt almost too good to be true. It was, but it also wasn't. Language models were (are) amazing[^3].

[^3]: I quickly found myself hooked on GPT-3 soon after I was granted access to Codex (code-davinci-002), when I realized that I could (with much effort) use it to produce functioning shell scripts that I couldn't without it.

notable loom implementations

each incarnation of Loom was built for a different context & purpose, and has features accordingly unique to it.

pyloom
see Loom: interface to the multiverse.

Somewhat embarrassingly, I’m not especially familiar with this first-ever implementation of Loom — in fact, I’ve not used it to this day (I will, soon..). I do know that it stores and visualizes logprobs, and it seems built to handle very large trees well.

loom (Latitude)
see Loom - the infinite wishes it had an interface (via Janus’ GPT Wrangling).

bonsai (Conjecture)
see Cyborgism#Becoming_a_Cyborg.

loomsidian
Loomsidian implements Loom as an Obsidian extension. It's also the most-used Loom client today, for good reason. Loom and Obsidian synergize really well together for reasons that I will at some point go into at length (I believe I have a recorded a number of lengthy voice memos on this topic).

if you use Obsidian every day (and even if you don't), I recommend setting up Loomsidian and learning to operate it (feel free to contact me for help/tips). the opportunity cost of not doing this is not measurable, but it may be high for you, so consider trying it out!

there are some issues to keep in mind (I suspect Celeste would likely be open to funding to address them):

  • to avoid losing data, you need a fairly strong mental model of how Loomsidian manages its document tree. I may write and/or record a video with thoughts on this, but in short, never edit the text for a node that has children unless you want to affect all of its children, because they will inherit that change when loomsidian concatenates them with the node you've changed.
  • the extension won't run on mobile/tablet
  • sync can be finicky, and trees can get deleted. export any tree you aren't comfortable losing

clooi

Back when the original Bing model (”Sydney”) was still around, Janus modded an abandoned Node TUI into a pretty functional Loom, presumably because Microsoft’s Bing/Copilot UI has no editing/branching[^4] whatsoever. Thus, the Bingleton Command Loom Interface was born. it saw quite a lot of Twitter exposure following Claude 3’s release (after which Janus quickly added Anthropic support).

equipped with the BCLI, Janus and other cyborg(ist)s covered a lot of ground in terms of explored Claude-space.

[^4]: more providers (e.g., Perplexity, Poe, Raycast… nearly every company that serves LLMs in a web UI) should implement not just editing (not especially uncommon, though not ubiquitous (which it should be)), but persisting of every edit state, branch, and [regen’d] response. I realize this adds overhead, but I would like to advocate for it regardless; I think it’s worth it and would never daily-drive an interface that didn’t have this feature (clearly I am an outlier..).

Honorable mentions (loom implementations that I haven't used, or have briefly and recommend checking out, but don't use regularly):

  • flux
    • it seems to me that many who have had little-to-no janus/Loom exposure are somewhat familiar (likely downstream of its announcement tweet) with this React application which supports branching chat model inference. at the time of its launch, it was the only interface that I knew of (other than ChatGPT, notably) with this important[^2] feature.
    • I myself was excited to give it a try when it launched, excited/hoping to loom-pill my coworkers, but after using it a few times I found the UX to be somewhat lacking. the application is unmaintained; I think it was a strong proof of concept, but not too much more.
  • miniloom: implemented by John David Pressman and Katherine Crowson as a component of MiniHF, their "inference, human preference data collection, and fine-tuning tool for local language models."
  • multiloom: single-file loom client
  • anansi: React-based Loom client with tree visualization and logprobs support
  • nanoloom: a small Python package which also implements loom; I haven't run it yet (but should soon). You should follow tel-0s on Twitter and look through their site.

I relate to Loom today as a concept rather than as a singular piece of software. it’s a verb ("looming," "weaving"), a paradigm; it's a mental framework one can apply to software/data, logic/language.

Using a loom-complete LLM interface vs. not is like using a pre-tabs browser vs. not; interfacing with an LLM via a (base model) loom feels something like lucid dreaming.

I have thought about this sort of thing for many hours. I obviously recommend that you try one (or many) out yourself if you have any interest in understanding and/or leveraging LLMs — in interacting with them at all, really.

II. what is loom (the Python package)?

context

from forming an interest → obsession with Janus’s body of work (and that which it implies + points to) to the moment I actually tried Loom took me, somewhat surprisingly, around 10 months. This was largely because I was caught up with a startup for most of that time, but also because setting up and understanding a loom client, along with developing a(ny) proficiency for handling base models, was (and is currently still) fairly challenging[^4].

[^4]: I think it’s actually fairly easy to grok base models (mostly as a matter of exposure to the right material/thought-scaffolding; my non-technical girlfriend understands them very well), but also far too easy to build a slightly-off understanding that feels “right enough.”

Thanks to ampdot's code-davinci-002 proxy and a committment/resolution to loom every day in the last months of 2023, I was able to build up a modest number of hours spent in Loomsidian before OpenAI cut off the then-already-restricted code-davinci-002 access without much warning.

I built some habits, and also wants, over those weeks I spent looming daily. Without cd2 access, I turned to Python, and started grinding away on a few projects for the first half of 2024. Having achieved a decent level of (LLM-augmented) proficiency, I decided to implement a Loom CLI after having the right conversations my girlfriend and a couple of friends, focusing on key features from Loomsidian/clooi and on ones they (and other Loom interfaces) lacked.

Some of those core features:

  • storing text nodes in a tree structure
    • providing affordances for manipulating the nodes in that tree structure
  • cleanly representing the state of the tree / the selected node in the terminal
    • supporting "raw output" to stdout for immediate compatibility with other programs (shell + GUIs)
  • a few others; a feature of particular importance to me at the time (which is today only partially implemented) was the ability to load content from external sources[^5].

[^5]: Every day, I curate text/media (which, when not textual, can be represented as text, or used outright) from the internet that I want to use in Loom. I've found ways to optimize this process over time (I started doing this mostly with Readwise, but today use Are.na and a personal Discord server) from one end, but on the other (sitting down in front of a loom client), ingesting these is still a fairly taxing manual process. It certainly doesn't need to be, though; I'll have more (possibly quite a lot) to share on this soon.

architecture

Keep in mind that this project is still in an early stage; it will continue to evolve over the rest of this year, and probably well into 2025.

loom operates around a document model. A document is a tree of nodes, each of which is an arbitrary string of text with associated metadata. Documents can have any number of root nodes, and are serialized to portable JSON files; I typically work in new ones for ~5 sessions or so before moving on to another.

Base models have first-class support (inverting the typical "chat > base" pattern dominant in the broader AI tooling space as of this year), but some basic affordances exist for working with chat models as well — both as standard chat models and as base-model-simulators. Future updates will include better support for chat models; I suspect we have a lot to gain from loom-complete chat inference, especially given powerful (G)UIs.

Motivation

writing with nvim/zed + loom

I felt in 2023 a rather deep need/aspiration to increase the frequency of my base model interactions from ~biweekly to [perhaps many times] daily; I had for a while longed for a true CLI that would allow me to do so from the comfort of my terminal.

I'd previously enjoyed experimenting with Janus's chat-only TUI loom (initially written to facilitate branching interactions with Bing), but it lacked support for raw text completion, and (not unlike Claude Code today) was not operable via native shell commands.

Design

The initial implementation was built with mixtral-8x22b, llama-3-8b and llama-3-70b as supported base models via Together AI (which no longer does any serverless base model hosting today, sadly).

The majority of my base model usage to date had been via celeste's Loomsidian, which maintains a tree of document states (represented in the Obsidian sidebar), and provides the user a set of key-bindable Obsidian actions to interface with that tree. One of its core interactions is ctrl-space (or similar) to invoke a model to generate completion(s) from the cursor position, appending each result to the tree of document states.

The core interactions/workflow for loom largely mirror Loomsidian's, but are terminal-native — as I write this I realize that it's a sort of "multi-state document editor/manager" first, and "base model loom" second. Commands include: