Skip to content

Agents and runtimes

Define agents, choose a runtime, attach tools and manage conversation turns.

Choose your client · Reliability · All public exports

Agent dataclass

Agent(
    name: str,
    instructions: str = "",
    model: str | Model | None = None,
    provider: str | None = None,
    tools: Sequence[Tool | Callable[..., Any]] = (),
    profile_options: dict[str, Any] = dict(),
    session_options: dict[str, Any] = dict(),
    *,
    config: dict[str, Any] = dict(),
    max_turns: int | None = None,
    toolsets: Sequence[str] | None = None,
)

Declarative profile configuration; does no I/O until attached to an instance.

name instance-attribute

name: str

instructions class-attribute instance-attribute

instructions: str = ''

model class-attribute instance-attribute

model: str | Model | None = None

provider class-attribute instance-attribute

provider: str | None = None

tools class-attribute instance-attribute

tools: Sequence[Tool | Callable[..., Any]] = ()

profile_options class-attribute instance-attribute

profile_options: dict[str, Any] = field(
    default_factory=dict
)

session_options class-attribute instance-attribute

session_options: dict[str, Any] = field(
    default_factory=dict
)

config class-attribute instance-attribute

config: dict[str, Any] = field(
    default_factory=dict, kw_only=True
)

max_turns class-attribute instance-attribute

max_turns: int | None = field(default=None, kw_only=True)

toolsets class-attribute instance-attribute

toolsets: Sequence[str] | None = field(
    default=None, kw_only=True
)

profile

profile() -> dict[str, Any]

BoundAgent

BoundAgent(
    instance: Instance, config: Agent, profile_id: str
)

Bases: ProfileResource

session_id instance-attribute

session_id: str | None = None

session property

session: SessionResource

The active session, including turns, actions and the event stream.

rpc async

rpc(method: str, **params: Any) -> Any

Escape hatch to any native Hermes gateway method.

new_session async

new_session(*, title: str | None = None) -> str

open_session async

open_session(session_id: str) -> SessionResource

Select an existing conversation after checking its instance/profile ownership.

add_tools async

add_tools(
    tools: Sequence[Tool | Callable[..., Any]],
) -> BindingResource

Attach another Python tool bundle to this profile and refresh its live sessions.

remove_tools async

remove_tools(binding_id: str) -> None

Remove this profile's binding; revoke owned callbacks when no binding still uses them.

start async

start(
    prompt: str | list[ContentPart],
    *,
    mode: Literal["enqueue", "steer"] | Unset = UNSET,
    tool_binding_ids: list[str] | Unset = UNSET,
    metadata: dict[str, Any] | Unset = UNSET,
    idempotency_key: str | Unset = UNSET,
) -> TurnResource

Submit without waiting; the handle supports get/wait/stop/steer/approve.

Consume agent.session.events() separately for the session's SSE stream. Tool bindings must already exist; support is determined by the server.

run async

run(
    prompt: str | list[ContentPart],
    *,
    timeout: float = 300,
    tool_binding_ids: list[str] | Unset = UNSET,
    metadata: dict[str, Any] | Unset = UNSET,
    idempotency_key: str | Unset = UNSET,
) -> RunResult

Wait for completion or a pending approval, not just the submit ACK.

Docker dataclass

Docker(
    image: str = "nousresearch/hermes-agent:latest",
    cpu: str = "1",
    memory: str = "2Gi",
    environment: dict[str, str] = dict(),
    options: dict[str, Any] = dict(),
)

image class-attribute instance-attribute

image: str = 'nousresearch/hermes-agent:latest'

cpu class-attribute instance-attribute

cpu: str = '1'

memory class-attribute instance-attribute

memory: str = '2Gi'

environment class-attribute instance-attribute

environment: dict[str, str] = field(
    default_factory=dict, repr=False
)

options class-attribute instance-attribute

options: dict[str, Any] = field(default_factory=dict)

to_dict

to_dict() -> dict[str, Any]

External dataclass

External(
    endpoint: str,
    authorization: dict[str, str] = (
        lambda: {"scheme": "none"}
    )(),
    options: dict[str, Any] = dict(),
)

endpoint instance-attribute

endpoint: str

authorization class-attribute instance-attribute

authorization: dict[str, str] = field(
    default_factory=lambda: {"scheme": "none"}, repr=False
)

options class-attribute instance-attribute

options: dict[str, Any] = field(default_factory=dict)

to_dict

to_dict() -> dict[str, Any]

Hermes

Hermes(
    sdk: AsyncEdithHermes,
    *,
    runtime: Runtime | None = None,
    owner: dict[str, str] | None = None,
    tool_host: ToolHost | None = None,
)

Bases: RootResource

High-level orchestration; .sdk preserves every existing low-level namespace.

owner instance-attribute

owner = owner or {
    "tenantId": "local",
    "subjectId": "local-user",
}

cloud property

cloud: Any

Unpinned provider extension API; no official typed cloud contract is available.

remote classmethod

remote(
    base_url: str,
    *,
    token: str | None = None,
    runtime: Runtime | None = None,
    owner: dict[str, str] | None = None,
    tool_host: ToolHost | None = None,
    timeout: float = 30,
    max_retries: int = 2,
) -> Hermes

Connect to a control plane. No runtime/auth/storage service is implicitly installed.

aclose async

aclose() -> None

Close client connections; does not delete remote instances or stop an external ToolHost.

local async classmethod

local(
    *,
    runtime: Runtime | None = None,
    state: str = ".edith-hermes/state.db",
    cleanup: bool = True,
    tools_host: str | None = None,
    settings: Any = None,
) -> AsyncIterator[Hermes]

Local Docker/process control plane; optional SQLite state, no PostgreSQL/OIDC/KMS.

cleanup=True deletes instances created in this context. Set False for persistent instances; their Python callback tools are only reachable while this context lives. Kubernetes control planes should run in-cluster (use Hermes(existing_sdk,...)).

open_instance async

open_instance(instance_id: str) -> Instance

Attach handles to an existing SDK-managed instance; never takes cleanup ownership.

create_instance async

create_instance(
    name: str,
    *,
    agents: Sequence[Agent] = (),
    timeout: float = 300,
    runtime: Runtime | None = None,
    owner: dict[str, str] | None = None,
    options: dict[str, Any] | None = None,
) -> Instance

Instance

Instance(hermes: Hermes, instance_id: str)

Bases: InstanceResource

agents instance-attribute

agents: dict[str, BoundAgent] = {}

agent

agent(name: str) -> BoundAgent

add_agent async

add_agent(
    config: Agent, *, profile_id: str | None = None
) -> BoundAgent

delete async

delete(
    *, retain_data: bool | Unset = UNSET
) -> InstanceOperation

restart async

restart() -> None

Kubernetes dataclass

Kubernetes(
    image: str,
    namespace: str = "hermes-runtimes",
    cpu: str = "1",
    memory: str = "2Gi",
    options: dict[str, Any] = dict(),
)

image instance-attribute

image: str

namespace class-attribute instance-attribute

namespace: str = 'hermes-runtimes'

cpu class-attribute instance-attribute

cpu: str = '1'

memory class-attribute instance-attribute

memory: str = '2Gi'

options class-attribute instance-attribute

options: dict[str, Any] = field(default_factory=dict)

to_dict

to_dict() -> dict[str, Any]

Model dataclass

Model(
    id: str,
    provider: str,
    base_url: str | None = None,
    api_key: str | None = None,
)

id instance-attribute

id: str

provider instance-attribute

provider: str

base_url class-attribute instance-attribute

base_url: str | None = None

api_key class-attribute instance-attribute

api_key: str | None = field(default=None, repr=False)

Process dataclass

Process(
    executable: str = "hermes",
    options: dict[str, Any] = dict(),
)

executable class-attribute instance-attribute

executable: str = 'hermes'

options class-attribute instance-attribute

options: dict[str, Any] = field(default_factory=dict)

to_dict

to_dict() -> dict[str, Any]

RunResult dataclass

RunResult(
    text: str,
    status: str,
    session_id: str,
    turn_id: str,
    raw: dict[str, Any],
)

text instance-attribute

text: str

status instance-attribute

status: str

session_id instance-attribute

session_id: str

turn_id instance-attribute

turn_id: str

raw class-attribute instance-attribute

raw: dict[str, Any] = field(repr=False)

Runtime

Bases: Protocol

Implement this protocol to supply another runtime configuration.

to_dict

to_dict() -> dict[str, Any]

Tool dataclass

Tool(
    function: Callable[..., Any],
    name: str,
    description: str,
    arguments: type[BaseModel],
)

function class-attribute instance-attribute

function: Callable[..., Any] = field(repr=False)

name instance-attribute

name: str

description instance-attribute

description: str

arguments class-attribute instance-attribute

arguments: type[BaseModel] = field(repr=False)

from_function classmethod

from_function(function: Callable[..., Any]) -> Tool

definition

definition() -> dict[str, Any]

invoke async

invoke(arguments: dict[str, Any]) -> Any

ToolHost

ToolHost(base_url: str)

Expose only capability-authenticated callbacks/MCP, not anonymous control-plane routes.

base_url instance-attribute

base_url = base_url.rstrip('/')

tools instance-attribute

tools: dict[str, dict[str, Tool]] = {}

app instance-attribute

app = FastAPI()

register

register(tools: Sequence[Tool]) -> str

unregister

unregister(callback_url: str) -> None

Revoke a callback capability, e.g. after removing its tool binding.

tool

tool(function: Callable[..., Any]) -> Tool

Expose an annotated Python function to Hermes; generates its JSON schema.