Skip to main content
Harnest owns the environment and compiled application used by every test lane. Authored tests exercise the selected ADK or LangGraph target without importing Harnest or manually loading build artifacts.

Work visually in Harnest Studio

Use Harnest Studio to create and edit agents. Its run and test workflow provides local previews and access to the checks described below.

Unit tests

Run the default offline lane:
Harnest compiles the project, then collects tests/unit/test_*.py. Unit tests should not call models, MCP servers, or other networks. This is a convention, not an OS sandbox.

Smoke tests

Live runtime checks belong in tests/smoke/test_*.py and run only when selected:
The unit lane runs first. Smoke tests add a FastAPI client and a smoke fixture. Use SmokeClient.respond for one JSON response or SmokeClient.stream to collect ordered SSE events. Smoke tests may spend time or money and use real credentials. Run them deliberately.

Evaluations

Run eval assets after the Python tests:
Both frameworks use ADK evaluation assets. Save the complete EvalRunResult with --eval-output FILE, including when using --no-output.

Build evaluations

Choose metrics, author eval sets and simulations, configure services, and inspect complete results.

Compile an artifact

Compile validated source into a standalone runtime directory:
Compiled directories are reproducible output. Do not edit or commit them.

Conditional dependencies

Harnest resolves the selected environment before importing the agent or its Harnest Extensions. Production runtime, development, and eval use independent locks so compiled deployment artifacts do not inherit development-only packages.

Select compilation dependencies

Add harnest-compile.yaml beside your agent’s config.yaml to select optional dependency groups:
harnest-compile.yaml
Define the selected extra in the agent’s configured pyproject.toml. Package versions stay in ordinary Python metadata:
pyproject.toml
Here, compilation selects crm; analytics is included only if another dependency requires it. These declarations affect compile and runtime build --agent, not development commands. Compilation retains complete selected packages and their transitive dependencies. Use separate extras for optional integrations; Harnest does not trim packages based on observed imports.

Project files and compiled content

Compilation includes Python, project configuration, dependencies, instructions, eval declarations, and complete installed skills, extensions, and plugins. Secrets, generated state, and virtual environments are excluded. Teammate documentation and company authoring configuration stay in the project. Development commands still use the authored tree. harnest-compile.yaml accepts only version and extras. A resources field is rejected, including an empty list. There is no general file-inclusion setting. Harnest does not infer arbitrary file reads from Python code. Use agent templates for model-facing instructions and skills; copying a team guide into a project does not make it model-facing. Selected optional dependencies use a separate harnest-compile.lock, synchronized into the same agent environment as the runtime profile. Switching between compile and runtime profiles replaces the installed dependency set; it does not create another environment. Refresh it with harnest env sync AGENT_DIR --profile compile. Native runtime packs retain their own resolution constrained by production locks. Project packs can generate and migrate these declarations through their existing file and YAML operations. Pack authoring and migration tools stay in the authoring environment unless you explicitly declare them as runtime dependencies.

Inspect a build report

Build reports list selected dependencies, retained files, inclusion reasons, and sizes. Runtime reports add package versions, owners, and declared requirements; inactive markers remain metadata. logicalBytes counts retained file bytes; uniqueObjectBytes counts distinct objects in that runtime. Neither includes filesystem overhead or measures savings across other packs. Package sizes can overlap. Shared runtimes resolve the combined selected requirements of all listed agents. Identical files continue sharing the existing content-addressed store and launch cache. Changing selected requirements requires rebuilding runtime coverage; changing included agent content only requires recompiling the agent.

Build native executables

Build executables for the deployment OS and architecture on a compatible baseline. The destination needs no Harnest or Python installation, but still needs your external services and credentials. Choose how to ship the dependencies: On Windows, build on a Windows host and use an output filename ending in .exe. For example, in PowerShell:
Runtime packs target the build host; a Linux or macOS pack cannot be attached to a Windows executable. Packaged Python console tools remain usable after moving the deployment directory. --runtime validates and references the pack. It does not copy dependencies into the agent executable unless you also pass --embed-runtime. Ordinary compile without these options still produces the existing Python artifact directory.

Share dependencies across agents

Run these commands from the directory containing your agent folders:
A shared pack resolves all agents’ dependencies together using current production locks as constraints. Sync stale locks first. Agents must use the same Python version; incompatible dependencies require separate packs. Builds may download dependencies; launchers do not. Release CLIs include the launcher. Contributor builds require Go and can select a local wheel with runtime build --wheel FILE. Keep build output outside the agent source, or under its .harnest/ directory. Runtime output directories must be new: builds do not overwrite existing packs. When dependencies change, build a new pack and recompile the agents that should use it.

Attach a runtime when launching

Place launcher options before serve or run. Relative paths resolve from the working directory. Set HARNEST_AGENT_RUNTIME instead of passing --runtime to every invocation. The launcher verifies the exact runtime digest and platform before loading agent code; a different pack is rejected even if it has a similar name. The run command requires spec.interfaces.cli: true when the agent is compiled. It accepts a positional message or reads stdin when the message is omitted. Pass run --help or serve --help for command options. Provide credentials through the deployment environment. Authored spec.environment values act as defaults; explicitly supplied environment variables take precedence. Use --server-config FILE before the command to replace the packaged server settings for one process. Keep durable state and deployment configuration outside the executable and runtime cache.

Deduplicate dependency storage

Identical dependency files share storage across packs and the launch cache. Agents still run in separate processes. By default, runtime builds use .harnest-runtime-objects beside the output directory. Use runtime build --store DIRECTORY to share one build store across other output locations. Packs contain their own object links and remain usable after the build store is removed; copy the complete runtime pack when deploying it. Hardlink-aware copying preserves sharing between multiple packs. Ordinary copies may duplicate their on-disk bytes until the launch cache deduplicates them. Set HARNEST_AGENT_CACHE to override the user cache directory. Reused files are verified. Keep packs, object storage, and cache on one hardlink-capable filesystem for maximum sharing (one NTFS volume on Windows); otherwise Harnest copies files. Embedding the same runtime into several executables necessarily repeats those bytes in the executable files. Use attached runtimes when distribution size matters. Embedded executables also materialize dependencies in the shared launch cache.

CI

A minimal offline CI sequence is:
Add smoke or eval lanes only when CI has the required services and credentials. For Harnest source changes, follow Development standards.