Create hermes-agent.py with the code below, or save it directly from your editor.
# /// script# requires-python = ">=3.12"# dependencies = [# "bindu @ git+https://github.com/GetBindu/Bindu.git",# "hermes-agent @ git+https://github.com/NousResearch/hermes-agent.git",# ]# ///"""Hermes-Agent via Bindu.Runs hermes-agent's ``AIAgent`` — a full tool-using coding/research agent —as a bindufied A2A microservice. DID identity, OAuth2-ready HTTP on :3773,optional FRP tunnel, x402 payments.This example is self-contained: it does not depend on any add-on module.Only the two packages listed below need to be installed.Setup (Python 3.12+): cp .env.example .env && $EDITOR .env # set OPENROUTER_API_KEYRun (one command — uv reads the PEP 723 header and installs deps on demand): uv run hermes-agent.pyOr, for a persistent install: uv pip install bindu \\ "hermes-agent @ git+https://github.com/NousResearch/hermes-agent.git" python hermes-agent.pyTiers (`HERMES_TIER` env var) control which Hermes toolsets are exposed: read — web search + web extract only (default, safe for tunnels) sandbox — adds filesystem read/write and execute_code full — everything (terminal, browser, MCP). Localhost only.Note: `full` tier exposes terminal + code execution. Never combine it witha public tunnel."""from __future__ import annotationsimport osfrom typing import Anyfrom bindu.penguin.bindufy import bindufyfrom run_agent import AIAgent# Toolset tiers. `None` means no restriction (full tier)._TIERS: dict[str, list[str] | None] = { "read": ["web"], "sandbox": ["web", "file", "moa"], "full": None,}_agent: AIAgent | None = Nonedef _get_agent() -> AIAgent: """Lazily create one shared AIAgent per process. Keeping a single long-lived agent preserves Anthropic prompt caching across Bindu calls — Bindu replays the full history every request, but we only feed the *new* user message into the agent's growing message list. """ global _agent if _agent is None: tier = os.getenv("HERMES_TIER", "read") _agent = AIAgent( model=os.getenv("HERMES_MODEL", "anthropic/claude-3.5-haiku"), max_iterations=30, enabled_toolsets=_TIERS.get(tier, _TIERS["read"]), quiet_mode=True, platform="bindu", save_trajectories=False, skip_memory=True, persist_session=False, ) return _agentdef _last_user_text(messages: list[dict[str, Any]]) -> str: """Extract the newest user message's text, tolerating the A2A parts shape.""" for m in reversed(messages): if m.get("role") != "user": continue content = m.get("content", "") if isinstance(content, str): return content if isinstance(content, list): return "\n".join( p.get("text", "") for p in content if isinstance(p, dict) and p.get("kind") == "text" ) return ""def handler(messages: list[dict[str, Any]]) -> str: """Bindu handler contract: (messages) -> string.""" text = _last_user_text(messages) if not text.strip(): return "Empty message." return _get_agent().chat(text)config = { "author": os.getenv("HERMES_AUTHOR", "you@example.com"), "name": os.getenv("HERMES_NAME", "hermes"), "description": "Hermes agent (tool-using) exposed as a Bindu A2A microservice", "deployment": { "url": os.getenv("HERMES_URL", "http://localhost:3773"), "expose": True, "cors_origins": ["http://localhost:5173"] }, "skills": ["skills/hermes-agent-skill"],}if __name__ == "__main__": bindufy(config, handler)
# Clone the Bindu repositorygit clone https://github.com/GetBindu/Bindu# Navigate to frontend directorycd frontend# Install dependenciesnpm install# Start frontend development servernpm run dev