Skip to main content

Hugpy Harness

hugpy-harness has two roles:

  1. A terminal client. It provides a full-screen TUI (hugpy-harness) and a plain chat REPL (hugpy-chat) for a standalone Hugpy wrapper or a Hugpy fleet core such as https://dev.hugpy.ai. It talks HTTP only. It needs no background service, engine, worker enrollment or toolserver.
  2. The agent-loop core library. Since 0.1.7, hugpy-agent is built on this package. Its loop, gateway, adapter, journal, policy, memory and tool registry are the harness modules, and hugpy-agent adds its fleet extras through hooks. The harness never imports hugpy-agent.

The full reference, covering hooks, chat-loop behavior and the agent layer, is in docs/agent-and-harness.md.

Status (2026-10-18)

where version
this source (pyproject.toml) 0.1.10, prepared for release
installed on ae (deb, /opt/hugpy-harness/venv) 0.1.9 with local source fixes
PyPI 0.1.9; the 0.1.10 endpoint/TUI changes are not published yet

Install

From the apt repo, on any Debian or Ubuntu box:

curl -fsSL https://dev.hugpy.ai/apt/setup.sh | sudo bash
sudo apt install hugpy-harness            # hugpy-wrapper is Recommended, not required
sudo apt install --no-install-recommends hugpy-harness   # client only (remote wrapper/fleet)

From locally built debs, without an apt repo:

bash packaging/debian/build.sh            # -> build/debian/: harness .deb, wrapper .deb if built, install.sh
cd build/debian
./install.sh                              # missing local wrapper: prompt [Y/n]
./install.sh --yes                        # default yes, no prompts
./install.sh --without-wrapper            # harness only (remote wrapper or fleet)
./install.sh --dry-run                    # show the APT plan only

From source with pip:

pip install ../hugpy_tools .              # needs hugpy-tools>=0.2.7

How the deb is put together:

  • The deb (Architecture all) carries the harness wheel and the hugpy-tools wheel in /usr/share/hugpy-harness/. The postinst installs both offline into /opt/hugpy-harness/venv.
  • /usr/bin/hugpy-harness and /usr/bin/hugpy-chat exec that venv.
  • Recommends: hugpy-wrapper (>= 0.1.62). The wrapper keeps its own runtime and service, and neither package embeds the other.
  • apt remove hugpy-harness leaves chat history, the wrapper, models and hugpy-agent untouched. A purge removes only this package's runtime.

Connect

If you do not pass --base or a connection --config, the CLI reads the local wrapper endpoint and a fleet or core endpoint from the user config directory (XDG_CONFIG_HOME/hugpy) and /etc/hugpy. It checks the wrapper's /health identity against the core's online worker list. A matching worker URL selects the core, so model choice and resource monitoring cover the fleet. An absent or unreachable core leaves the standalone wrapper selected. If no wrapper is installed, a configured fleet or core endpoint is selected directly.

HUGPY_WRAPPER_URL and HUGPY_FLEET_URL explicitly select their respective endpoints. --base and --config override detection. A user-level fleet setting also selects that fleet directly. View or change it with:

hugpy-harness endpoint
hugpy-harness endpoint set-fleet https://dev.hugpy.ai
hugpy-harness endpoint clear-fleet

The setting is stored in ~/.config/hugpy/fleet.endpoint.json (or under XDG_CONFIG_HOME). The URL may be a fleet core or its HTTPS proxy.

If nothing is found, the CLI tells you to pass --base URL or set HUGPY_FLEET_URL.

Key. The CLI sends HUGPY_WRAPPER_API_KEY to a wrapper and HUGPY_FLEET_API_KEY to a core. The fleet key is a hugpy-core keys create --name <box> --scope use key, and you need it only from outside the LAN once the core requires keys for outside callers. That core key policy is being set up. As of 2026-10-15, the fleet's /v1 answered without a key.

URLs. A bare host gets https://, and {base}/v1 is probed first.

--config FILE reads a JSON connection file that may hold only base and model (both strings). The option's help text says the file comes from fitevict setup, but the installed wrapper CLI (0.1.122) has no setup command, so write the file yourself.

To connect a remote box to the fleet:

hugpy-harness endpoint set-fleet https://dev.hugpy.ai
hugpy-chat --list-models
hugpy-harness --model <id from the list>

With 0.1.7, which is what apt serves until 0.1.8 is published, pass --base https://dev.hugpy.ai instead. 0.1.7 does not read the fleet endpoint files or HUGPY_FLEET_API_KEY.

Launch

hugpy-harness                                   # full-screen TUI (same as `launch` / `tui`)
hugpy-harness launch --workspace /path/to/project --model MODEL_ID
hugpy-harness --base http://HOST:PORT --workspace /path/to/project
hugpy-harness chat --model MODEL_ID             # plain REPL (= hugpy-chat)
hugpy-chat --message "one question" --model MODEL_ID   # one turn, exit code 0 on success

TUI options: --config, --base, --workspace, --model, --session, --policy {ask,readonly,auto} (default ask), --optional-tools and --list-models. The model defaults to HUGPY_WRAPPER_MODEL.

hugpy-chat options: the same as the TUI, plus --tools-mode {prompted,constrained,native,auto}, --max-steps (12), --max-tokens (1024), --message and --resume RUN_ID.

In the TUI:

  • /model opens the model picker. Every picker filters as you type.
  • /resources toggles telemetry, and /resources full opens the compute monitor.
  • In the monitor, e or Delete evicts a model through the wrapper's operator action. A fleet core has no eviction route, so there the TUI says so instead of failing.
  • The display shows fleet resource snapshots per worker, including stale or offline state.

Sessions are journaled in <workspace>/.hugpy_wrapper/chat/journal.db. Reopen a session with the same --workspace and /session, or use hugpy-chat --resume RUN_ID. Conversations stay in the same workspace journal when you change endpoints.

Chat behavior

Chat runs the agent loop in conversation mode:

  • A plain-text reply is a complete answer. Tools are optional.
  • Each user message gets its own step budget.
  • An empty reply or an engine error ends the turn with that error. The loop never demands a tool call.
  • <tool_call> and <tool_response> markup never shows up as reply text.
  • A final_answer call that has no answer gets one repair prompt.

Model tools

The harness imports the standalone hugpy_tools catalog, so file, search, text, data, hash, time and web tools work in both the TUI and plain chat. Without optional tools, a loop has 36 tools, including fs_read, fs_write, fs_glob, shell, ask_operator and final_answer.

  • Tools execute on the harness machine, jailed to --workspace, even when the model runs on a remote wrapper or fleet.
  • Writes, network access and host operations go through --policy.
  • --optional-tools adds document, media, rendering, image, desktop and VM tools. Their backends load only when called; install the matching hugpy-tools extras, for example pip install 'hugpy-tools[images,files,render]'. Rendering also needs Playwright Chromium.
  • Generated images and screenshots go to .hugpy_wrapper/tool-artifacts in the workspace.

Using the core as a library

from hugpy_harness.config import Config
from hugpy_harness.loop import AgentLoop

loop = AgentLoop(Config(base="http://127.0.0.1:52017", model="MODEL", workspace="."),
                 extra_tool_providers=[my_provider])     # provider(ctx) -> [ToolSpec]
print(loop.run("task"))

The hooks are:

hook purpose
AgentLoop(rag_factory=, comms_factory=, catalog_provider=, extra_tool_providers=) constructor hooks
AgentLoop.turn_ctx(run_id) spans one drive
Gateway.request_ctx(chat_url, key) per-request headers and cancel
Config.state_dir and config.state_path() per-workspace state; default .hugpy_wrapper/chat
the hugpy_harness.tools entry-point group each entry is a provider(ctx) -> [ToolSpec]
imports.constants.SERVICE_NAME the harness's name (declared, not yet read anywhere)
the imports/ layer constants, functions, classes, init_imports

Details and caveats are in docs/agent-and-harness.md.

Development

python -m pytest -q tests          # 20 tests, offline
bash packaging/debian/build.sh     # runs plain `python3`; BUILD_PYTHON is not read (pure-Python wheels)

Build, release and test conventions for the whole tree are in docs/development.md.

Changes

0.1.8 (2026-10-15; installed on ae, not yet in the apt pool)

  • Fleet connection. Endpoint resolution falls back to HUGPY_FLEET_URL, then ~/.config/hugpy/fleet.endpoint.json, then /etc/hugpy/fleet.endpoint.json. The key falls back to HUGPY_FLEET_API_KEY. When no endpoint is found, the error now names --base and HUGPY_FLEET_URL.
  • Evicting a model on a fleet core (no /v1/operator/actions) reports "this endpoint has no eviction" instead of a raw HTTP error.

0.1.7 (2026-10-15; apt, bundled in hugpy-agent 0.1.118)

  • The harness became the core library for hugpy-agent. 0.1.7 added rag_factory, comms_factory, catalog_provider and extra_tool_providers on AgentLoop, the turn_ctx method, Gateway.request_ctx, Config.state_dir and state_path(), the hugpy_harness.tools entry-point group, and the imports/ layer, which includes SERVICE_NAME.

0.1.6 (2026-10-14; PyPI)

  • The right-hand resources pane shows one box per loaded model, and e or Delete unloads a model.
  • The sessions pane lists the loaded models each session used.
  • A model is strictly per session.
  • Tool markup (<tool_call> and <tool_response>) is gated out of reply text.

0.1.5 (2026-10-14)

  • Pickers search as you type.
  • /resources full is the compute panel in the terminal, with eviction.
  • A local model's reply is no longer shown twice.

Local Harness controls:

  • /models offers an engine filter; /models gguf, /models transformers, or /models all selects it directly. Each model shows its size and engine/runner.
  • /settings chooses the inference endpoint: Fleet or a specific wrapper. /observe selects resource telemetry independently of inference routing.
  • /rename NAME names a session. /pin keeps it near the top of the session list. The session retains its model, endpoint and controls across restarts.
  • /session-settings shows controls; append max_tokens 1024, temperature 0.2, no_think false, or alloc_mode auto|gpu-only|ram-only|max-gpu|max-ram to set one. Current controls also appear in the sidebar.
  • /clear removes this session's transcript and model context. /clear-model keeps the transcript and resets only model context.
  • Model reasoning is retained in a collapsed thinking card after the reply; Enter/Space/click expands it. The activity line follows the transcript and reports observed load stages; estimates without evidence remain unknown.

Local agents receive the actual registered toolset in their init prompt. When Core is available they get fleet_list_models, fleet_list_workers and fleet_call_model (chat, embeddings, image generation). The shared toolserver client exposes toolserver_list_categories, toolserver_list_tools and toolserver_call_tool through Core's /ts/* relay. Core uses its existing management access gate for this relay; inference-only keys do not grant toolserver operator access. Toolserver calls retain target-specific policy checks and the shared privileged-tool allowlist. HUGPY_AGENT_TOOLSERVER=0 disables the bridge. The shared MCP catalog gives frontier clients the same explicit toolserver names and argument fields; older call names remain accepted as compatibility aliases.

User-defined persistent sessions

See Named sessions for arbitrary names, persistent model destinations, stable routes and delegation shared with Agent.

Metadata

Release files for hugpy-harness 0.1.15

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hugpy-harness 0.1.15
File Size Uploaded Provenance
hugpy_harness-0.1.15.tar.gz 185.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for hugpy-harness 0.1.15
File Interpreter ABI Platform
hugpy_harness-0.1.15-py3-none-any.whl Python 3 none any Details

Total release size: 378.4 kB

Release files / hugpy_harness-0.1.15.tar.gz

Download URL hugpy_harness-0.1.15.tar.gz
Size 185.0 kB
Tags Source
SHA-256 checksum
How to use checksums
d82d428f1ff755b8edb474ce0f21027f8e490b8171d3cc4e170730f9ba480730
BLAKE2b-256 checksum
How to use checksums
52a9a8f134785dc1509c41a172da5f0e5bb7a1229e7163238e674881890819e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / hugpy_harness-0.1.15-py3-none-any.whl

Download URL hugpy_harness-0.1.15-py3-none-any.whl
Size 193.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c5f4b5a669295819dfef288a55635f337a477d2892a0f32a292c9d66ffdaabdc
BLAKE2b-256 checksum
How to use checksums
a34ae69854d9c0c13d2be2b42f501c07b59df9da2631f134624826a93a2647c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for hugpy-harness 0.1.15

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page