Skip to main content

Typed async client for the Hermes Agent API Server

Project description

Hermes Agent API Client

Hermes Agent API Client is a typed async Python client for authenticated capability discovery and streaming Chat Completions from the Hermes Agent API Server. The package requires Python 3.13 or later.

Installation

Install the package from PyPI:

uv add hermes-agent-api-client

Usage

HermesAgentApiClient is a single-use async context manager. Without an injected HTTP client, it creates and closes its own httpx.AsyncClient:

from hermes_agent_api_client import HermesAgentApiClient, TerminalEvent


async def ask_hermes(request: dict[str, object]) -> None:
    async with HermesAgentApiClient(
        "https://hermes.example",
        "bearer-key",
    ) as client:
        capabilities = await client.probe_capabilities()
        assert capabilities.chat_completions_streaming

        async for event in client.stream_chat_events(request):
            if isinstance(event, TerminalEvent):
                print(event.outcome)

The default verify=None uses httpx's verified TLS default. An owned client may instead receive verify=False or an ssl.SSLContext. Disabling certificate verification weakens transport security and should be limited to controlled environments.

To share a caller-managed client, inject it explicitly:

import httpx

from hermes_agent_api_client import HermesAgentApiClient


async def probe_with_shared_transport() -> None:
    async with httpx.AsyncClient(verify=True) as http_client:
        async with HermesAgentApiClient(
            "https://hermes.example",
            "bearer-key",
            http_client=http_client,
        ) as client:
            await client.probe_capabilities()

The caller owns an injected client, so exiting HermesAgentApiClient does not close it. TLS verification must be configured on the injected client; passing both http_client and a non-None verify value is rejected.

Capability discovery can distinguish a non-Hermes endpoint from a Hermes Agent that lacks required Chat Completions support using package-root imports only:

from hermes_agent_api_client import (
    HermesAgentApiClient,
    HermesCapabilityError,
    HermesIdentityError,
)


async def discover_hermes(base_url: str, bearer_key: str) -> str:
    try:
        async with HermesAgentApiClient(base_url, bearer_key) as client:
            capabilities = await client.probe_capabilities()
    except HermesIdentityError:
        return "not a Hermes Agent endpoint"
    except HermesCapabilityError:
        return "Hermes Agent lacks Chat Completions support"
    return capabilities.model

Supported contract

The package supports only these Hermes operations:

  • GET /v1/capabilities through probe_capabilities().
  • Streaming POST /v1/chat/completions through stream_chat_events().

The exact OpenAI-compatible request document remains a caller-owned mapping; the client does not define additional request-model semantics.

A successful capability probe returns an immutable HermesCapabilities value with this supported shape:

  • object: exactly hermes.api_server.capabilities.
  • platform: exactly hermes-agent.
  • model: the advertised API/profile name.
  • auth_type: exactly bearer.
  • auth_required: the literal boolean True.
  • chat_completions: the literal boolean True.
  • chat_completions_streaming: the literal boolean True.

At the immutable upstream compatibility target, model is resolved in order from an explicit API-server model override, a non-default active profile, or the hermes-agent fallback. The client preserves the advertised string exactly: it does not trim, normalize, replace, or truncate leading, trailing, or internal whitespace. Strict validation requires an actual string containing 1 through 255 Unicode code points and at least one non-whitespace code point; empty, whitespace-only, non-string, and over-limit values are rejected.

The stream yields immutable AssistantDeltaEvent, ToolProgressEvent, UsageEvent, KeepaliveEvent, and TerminalEvent values. Terminal outcomes are success, length, or upstream_error.

Public failures derive from HermesContractError and expose only safe category, status_code, and retryable metadata. HermesIdentityError and HermesCapabilityError both inherit HermesProtocolError, so existing callers that catch HermesProtocolError or HermesContractError continue to catch them. Both subclasses have protocol category, no status code, and retryable=False, with no additional instance state.

Capability-probe classification is staged and deterministic:

Wire condition Public exception
Top-level document is not a mapping HermesProtocolError
Missing or non-exact object discriminator HermesIdentityError
Missing or non-exact platform discriminator HermesIdentityError
Valid identity, but features is missing or not a mapping HermesCapabilityError
Valid identity, but features.chat_completions is missing, false, or not the literal boolean True HermesCapabilityError
Invalid or missing model HermesProtocolError
Invalid or missing bearer authentication contract HermesProtocolError
Missing, false, or invalid chat_completions_streaming HermesProtocolError
Malformed JSON, oversized body, or another unrelated schema failure HermesProtocolError
Existing authentication HTTP status HermesAuthenticationError
Existing non-authentication HTTP status HermesHttpStatusError
Existing request, timeout, read, or cleanup transport failure HermesTransportError

Identity failures take precedence over required-feature failures. Capability failures are classified only after both identity discriminators are valid, and all remaining wire failures use the generic HermesProtocolError fallback. Authentication HTTP status, other HTTP status, and transport failures remain HermesAuthenticationError, HermesHttpStatusError, and HermesTransportError, respectively. Callers should not expect upstream response bodies, bearer credentials, request payloads, URLs, or raw validation details in public error text.

Compatibility targets the immutable Hermes Agent tag v2026.7.7.2 at commit 9de9c25f620ff7f1ce0fd5457d596052d5159596. Evidence is derived from a capability fixture captured from that tagged handler and local protocol/transport tests; it is not evidence from a live Hermes server or a moving upstream branch.

Security: Hermes API access exposes the configured agent toolset. Protect the bearer key, restrict network access, and grant the Hermes agent only the tools appropriate for the calling application.

Development

Install the exact locked development environment and the commit hook:

uv sync --locked --all-groups
prek install

prek runs the complete quality gate automatically before every Git commit and blocks the commit when any check fails.

License

Licensed under the Universal Permissive License 1.0 (UPL-1.0). See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hermes_agent_api_client-0.3.0.tar.gz (55.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hermes_agent_api_client-0.3.0-py3-none-any.whl (22.7 kB view details)

Uploaded Python 3

File details

Details for the file hermes_agent_api_client-0.3.0.tar.gz.

File metadata

  • Download URL: hermes_agent_api_client-0.3.0.tar.gz
  • Upload date:
  • Size: 55.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for hermes_agent_api_client-0.3.0.tar.gz
Algorithm Hash digest
SHA256 8a68c4432830e94c5018491db50ea68dd7eb4d33b0f52553c6d3a68fd7600f65
MD5 c25d3aa7a9504c40b81f5fc925a72271
BLAKE2b-256 3306c09097ea91ab5726754a70fa3fbd32fd6669d61d234f745e386f81c8cae8

See more details on using hashes here.

Provenance

The following attestation bundles were made for hermes_agent_api_client-0.3.0.tar.gz:

Publisher: release.yml on Djelibeybi/hermes-agent-api-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hermes_agent_api_client-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for hermes_agent_api_client-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cb0c7a46a1697e4d34bc034fdda7b48d5c978c572ebd57013a40e8cee1ccf111
MD5 2114cd512236d699cd2a3ae57e87c94f
BLAKE2b-256 e46131b5aaf061f7a180cee2ea092b399d9cc766186649d6b4a36d9aecd8e699

See more details on using hashes here.

Provenance

The following attestation bundles were made for hermes_agent_api_client-0.3.0-py3-none-any.whl:

Publisher: release.yml on Djelibeybi/hermes-agent-api-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page