Hugpy Harness
hugpy-harness has two roles:
- 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 ashttps://dev.hugpy.ai. It talks HTTP only. It needs no background service, engine, worker enrollment or toolserver. - 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 thehugpy-toolswheel in/usr/share/hugpy-harness/. The postinst installs both offline into/opt/hugpy-harness/venv. /usr/bin/hugpy-harnessand/usr/bin/hugpy-chatexec 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-harnessleaves 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:
/modelopens the model picker. Every picker filters as you type./resourcestoggles telemetry, and/resources fullopens the compute monitor.- In the monitor,
eor 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_answercall 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-toolsadds document, media, rendering, image, desktop and VM tools. Their backends load only when called; install the matchinghugpy-toolsextras, for examplepip install 'hugpy-tools[images,files,render]'. Rendering also needs Playwright Chromium.- Generated images and screenshots go to
.hugpy_wrapper/tool-artifactsin 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 toHUGPY_FLEET_API_KEY. When no endpoint is found, the error now names--baseandHUGPY_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_providerandextra_tool_providersonAgentLoop, theturn_ctxmethod,Gateway.request_ctx,Config.state_dirandstate_path(), thehugpy_harness.toolsentry-point group, and theimports/layer, which includesSERVICE_NAME.
0.1.6 (2026-10-14; PyPI)
- The right-hand resources pane shows one box per loaded model, and
eor 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 fullis the compute panel in the terminal, with eviction.- A local model's reply is no longer shown twice.
Local Harness controls:
/modelsoffers an engine filter;/models gguf,/models transformers, or/models allselects it directly. Each model shows its size and engine/runner./settingschooses the inference endpoint: Fleet or a specific wrapper./observeselects resource telemetry independently of inference routing./rename NAMEnames a session./pinkeeps it near the top of the session list. The session retains its model, endpoint and controls across restarts./session-settingsshows controls; appendmax_tokens 1024,temperature 0.2,no_think false, oralloc_mode auto|gpu-only|ram-only|max-gpu|max-ramto set one. Current controls also appear in the sidebar./clearremoves this session's transcript and model context./clear-modelkeeps 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_models, fleet_workers and fleet_call (chat, embeddings, image generation). The shared toolserver client exposes ts_categories, ts_list and ts_call 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. Frontier agent providers and initialization are unchanged.
Metadata
Release files for hugpy-harness 0.1.12
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| hugpy_harness-0.1.12.tar.gz | 180.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hugpy_harness-0.1.12-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 369.4 kB
Release files / hugpy_harness-0.1.12.tar.gz
| Download URL | hugpy_harness-0.1.12.tar.gz |
|---|---|
| Size | 180.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2fc8c8b86843a920a2ab8e7d88d21d872ee8c81cbe37081c3306b7ed9daf569d
|
|
BLAKE2b-256 checksum How to use checksums |
a91cbb28f2ef772dd3fbc255b823c07366648847475f2e28eab50800b9969528
|
| 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.12-py3-none-any.whl
| Download URL | hugpy_harness-0.1.12-py3-none-any.whl |
|---|---|
| Size | 189.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5231821668244908e75f7db7f67ef27cc02eaedc36bc02f56fd1a9b4e92e3ebf
|
|
BLAKE2b-256 checksum How to use checksums |
e5941f3fdddbe1abb27ac1b35c08ecc1dc3c6dd564b3ecac9360fbb98dfde685
|
| 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.12
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.