Metadata-Version: 2.4
Name: red-loom
Version: 0.2.1
Summary: Local-model agent loop for Ollama, LM Studio, Hugging Face, MLX, and OpenAI-compatible servers.
Author: Red Standard contributors
License-Expression: MIT
Project-URL: Homepage, https://github.com/watLr/Agent_Loop_Engine
Project-URL: Documentation, https://github.com/watLr/Agent_Loop_Engine/blob/main/docs/red-standard/loom/guide.md
Project-URL: Issues, https://github.com/watLr/Agent_Loop_Engine/issues
Project-URL: Source, https://github.com/watLr/Agent_Loop_Engine
Keywords: agent,cli,local-models,llm,ollama
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: huggingface
Requires-Dist: transformers>=4.44; extra == "huggingface"
Requires-Dist: torch; extra == "huggingface"
Provides-Extra: mlx
Requires-Dist: mlx-lm>=0.18; extra == "mlx"
Provides-Extra: workflow
Requires-Dist: jsonschema>=4; extra == "workflow"
Provides-Extra: server
Requires-Dist: websockets>=12; extra == "server"
Requires-Dist: jsonschema>=4; extra == "server"
Requires-Dist: watchdog>=4; extra == "server"
Provides-Extra: dev
Requires-Dist: build>=1; extra == "dev"
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: websockets>=12; extra == "dev"
Requires-Dist: jsonschema>=4; extra == "dev"
Requires-Dist: watchdog>=4; extra == "dev"
Dynamic: license-file

# Loom

Loom is the Red Standard engine: an independent local-model agent harness plus
the WebSocket engine server behind the Atelier shell. (It was carved from the
earlier "Codex Loop" project on 2026-06-17: package `codex_loop` → `loom`,
runtime dir `.codex-loop/` → `.loom/`.)

Supported model providers:

- Ollama (streaming)
- LM Studio, vLLM, or any OpenAI-compatible local server (streaming)
- Hugging Face Transformers (streaming)
- MLX on macOS (streaming)

This implementation is a Python library, a CLI, and the production engine. It
provides:

- A reusable `AgentSession` loop
- Provider adapters with a shared interface
- A model-friendly JSON tool-call protocol for local models without native tool calling
- Safe file and shell tools scoped to a workspace root (26 built-ins)
- Shell classification for PowerShell/Bash-style commands
- Simple and model-assisted context compaction
- Durable memory (backed by the Red Thread graph), persistent tasks, MCP config, plugin registry, subagents, and a patch workflow
- The RSAPI WebSocket engine server the Tauri shell connects to
- A streaming interactive CLI and one-shot mode

## Package Layout

`loom/` is split into two layers plus the serving surfaces:

- `loom/harness/` — the agent loop itself: `agent.py`, types, storage,
  compaction, providers, prompts, the tool protocol, patcher, file-state
  tracking, and verification.
- `loom/capabilities/` — what the loop can be given: memory, tasks, skills,
  the MCP client, permissions, model profiles, and the Red Thread graph.
- `loom/tools/` — the 26 built-in tools.
- `loom/server/` — the RSAPI WebSocket engine server (see below).
- `loom/mcp_server/` — a zero-dependency JSON-RPC 2.0 stdio MCP server
  (console script `loom-mcp`) exposing the Red Thread graph to CLI agents.

Some top-level compatibility modules still re-alias selected capability and
vocabulary paths. Gen 2 removed the old `agent`, `verification`, and `providers`
shims; import those directly from `loom.harness.*`.

## Engine Server (RSAPI)

The production surface is the WebSocket engine server:

```bash
python -m loom.server --workspace .
# or, installed: loom-engine --workspace .
```

It is a lean `websockets` server exposing:

- `GET /health` — unauthenticated liveness, served from the WS handshake hook
  (no separate HTTP server).
- `ws://127.0.0.1:<port>/rsapi` — the contract socket, bearer-token
  authenticated (`Authorization: Bearer <token>` or `?token=`), loopback-only.

Frames follow the JSON-Schema contract in `contracts/` (a copy is bundled at
`loom/server/contract_schema.json`; `SCHEMA_REVISION = 45` lives in
`loom/server/envelope.py`). On boot the server writes the token 0600 to
`<workspace>/.loom/engine.json` — it is never printed to stdout — and announces
readiness with a token-stripped `listening` JSON line.

For Atelier, `engine/packaging/build_sidecar.py` builds a PyInstaller `--onedir`
bundle (`engine/dist/loom-engine/`) that the shell supervises. Heavy providers
(torch, mlx) are deliberately excluded from the sidecar venv. This is separate
from the publishable Python distribution below.

## Install the standalone CLI

The distribution is named `red-loom`; the product, import, and command
remain Loom / `loom`. Install it into an isolated environment with pipx:

```bash
pipx install red-loom
# From a source checkout before the registry release:
pipx install ./engine
```

The base install is the dependency-free terminal harness. Optional surfaces are
explicit:

```bash
pipx install 'red-loom[workflow]'  # JSON-schema workflow steps
pipx install 'red-loom[server]'    # RSAPI engine server
pipx install 'red-loom[huggingface]'
pipx install 'red-loom[mlx]'
```

Set a text model once, then launch the interactive client:

```bash
loom config set provider ollama
loom config set model qcwind/qwen3-8b-instruct-Q4-K-M:latest
loom
```

With no saved model, an interactive TTY lists installed Ollama text models and
requires an explicit choice. It never guesses a model or selects the vision-only
Moondream route. A noninteractive process fails with the exact config command to
run instead of hanging.

`~/.loom/cli.json` stores only non-secret defaults: provider, model, base URL,
permission, effort, temperature, token/turn bounds, native-tools override, and
compaction strategy. It is written atomically with owner-only permissions. API
keys stay in provider environment variables or the OS keychain; credential fields
and credential-bearing URLs are refused.

## Use the CLI

Running `loom` starts the interactive client. Model output streams as it arrives.
A trailing `\` continues composition on the next line. Text entered during a turn
steers its next safe model boundary; `/cancel` cooperatively stops it; other slash
commands wait until the turn ends. The same reader owns approvals and structured
questions, so the terminal never has two consumers racing over stdin.

Core commands:

```text
/model [provider:model]     /provider [name]
/permission [mode]          /effort [default|low|medium|high]
/compact                    /stats  /cost
/rewind [epoch]             /fork [epoch]
/clear                      /workspace [path]
/memory [query]             /mcp  /tools
/sessions                   /resume <session-id>
/cancel                     /exit
```

`/rewind` restores checkpointed files and appends a logical conversation snapshot
to the audit transcript, so the truncation survives a later resume. `/fork`
branches conversation only; it does not branch workspace files.

An explicit prompt still runs once and exits:

From this folder:

```bash
loom --provider ollama --model qwen2.5-coder:7b "Inspect the current directory"
```

For LM Studio, start the local server and use:

```bash
loom --provider lmstudio --model local-model "Say hello"
```

For vLLM or another OpenAI-compatible endpoint:

```bash
loom --provider openai-compatible --base-url http://localhost:8000/v1 --model Qwen/Qwen2.5-Coder-7B-Instruct "List available tools"
```

`--repl` remains accepted as a compatibility alias for interactive mode.

Sessions are persisted by default in `.loom/sessions`:

```bash
loom --workspace . --list-sessions
loom --provider lmstudio --model local-model --session 20260424-120000-abcd1234 "Continue"
```

Use `--no-persist` for throwaway runs.

Use `--json` for NDJSON events suitable for GUIs or controllers:

```bash
loom --provider lmstudio --model qwen2.5-coder-7b --json --no-persist "Say hello"
```

OpenAI-compatible local servers default to the portable text tool protocol
instead of native function schemas to fit smaller local context windows. Add
`--native-tools` only for servers/models that handle native tools reliably.

Use `--tools` to expose only a focused tool set for smaller local models:

```bash
python -m loom.cli --provider lmstudio --model google/gemma-4-e4b --tools list_dir --json "List this directory with the tool"
```

Use `--verify` to run explicit verification commands before final output:

```bash
python -m loom.cli --provider lmstudio --model google/gemma-4-e4b --verify "python scripts/dev.py test" "Make a small change"
```

Use `--permission ask` for approval-gated writes and non-read-only shell
commands. Add `--yes` for non-interactive auto-approval in trusted test runs.
The edit tool also tracks file snapshots: if a file changes after `read_file`,
`replace_in_file` requires another read before editing.

Use `--compaction-strategy model` to summarize long histories with the selected
model. The default `simple` strategy remains deterministic and offline.

## Management Commands

The CLI also exposes non-model commands for agent state:

```bash
python -m loom.cli memory list --workspace .
python -m loom.cli memory add --workspace . --type project --text "Use Gemma E4B for live smokes." --why "It passed tool tests." --how-to-apply "Prefer it for local agent checks."
python -m loom.cli mcp list --workspace .
python -m loom.cli plugin list --workspace .
python -m loom.cli task list --workspace .
python -m loom.cli patch preview --workspace . --changes-file patch.json
python -m loom.cli models profile list --workspace .
python -m loom.cli serve --workspace . --port 8765
```

Memory is stored as Markdown nodes under `<workspace>/.redthread/nodes/` (the
Red Thread graph); a legacy `.loom/memory.jsonl` is imported once, losslessly,
on first use and renamed `.imported`.

`serve` starts the **legacy** stdlib HTTP/SSE server
(`loom/server/legacy_http.py`), kept only for this CLI command and a
regression test. New integrations should use the RSAPI WebSocket server above.

## Skills

Local skills are discovered from `skills/`, `.loom/skills/`, installed
skill packs under `.loom/skill-packs/`, and any `--skill-root` path.
Each skill is a folder containing `SKILL.md`.

```bash
python -m loom.cli --workspace . --list-skills
python -m loom.cli --workspace . --search-skills bigquery
python -m loom.cli --workspace . --install-skill-pack google/skills
```

Installed skill packs are indexed only; they are not executed or trusted
automatically. Review licenses and contents before using third-party packs.

## Development Harness

The project includes a local harness for build checks, tests, provider health,
machine specs, and a no-model smoke test:

```bash
python scripts/dev.py specs
python scripts/dev.py health
python scripts/dev.py check
python scripts/dev.py live-models
```

`check` runs syntax checks, imports, unit tests, an in-process agent-loop smoke
test, and non-failing health probes for Ollama and LM Studio.
`live-models` runs timeout-bounded LM Studio model tests against direct
completion and agent tool loops, then records capability data in
`.loom/model-profiles.json`.

## Tool Protocol

Models can call tools by emitting JSON in a fenced block or `<tool_call>` tag:

```json
{"tool": "read_file", "arguments": {"path": "README.md"}}
```

Multiple calls are supported:

```json
{"tool_calls": [{"tool": "list_dir", "arguments": {"path": "."}}]}
```

Tool results are appended to the conversation and the loop continues until the assistant returns a normal final answer.

## Roadmap

Loom's roadmap lives with the rest of Red Standard planning:

- `docs/red-standard/ROADMAP.md` — the project-wide roadmap.
- `docs/red-standard/loom/next-steps.md` — Loom-specific next steps.
