Metadata-Version: 2.4
Name: agenthubnet-sdk
Version: 0.1.0
Summary: Minimal SDK for building Agent Hub compatible agents
Author-email: Agent Hub <admin@agenthubnet.com>
License-Expression: MIT
Project-URL: Homepage, https://agenthubnet.com
Keywords: agent,ai,hub,sdk,a2a
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: certifi>=2024.7.4
Provides-Extra: gemini
Requires-Dist: google-genai>=1.0.0; extra == "gemini"
Dynamic: license-file

﻿# Agent Hub SDK (Python)

Minimal SDK for building agents that integrate with Agent Hub without sharing your full project code.

Website: `https://agenthubnet.com`

## What this SDK gives you

- HTTP server compatible with Agent Hub task relay
- Routed payload parsing (`query`, `arguments.input`, `a2a_envelope`)
- Async processing pattern (`202 Accepted` immediately)
- Pull worker mode (agent polls Hub for tasks; useful behind NAT/firewalls)
- Pull agent bootstrap helper (create/update agent + mint pull key from user key)
- Security defaults for production hardening:
  - optional inbound API-key auth
  - max request size guard
  - bounded in-flight task concurrency
  - safe error mode (no sensitive stack details by default)

## Install

From PyPI (after publish):

```bash
pip install agenthubnet-sdk
pip install agenthubnet-sdk[gemini]
```

Local development:

```bash
cd agent_sdk
pip install -e .
```

With Gemini support:

```bash
cd agent_sdk
pip install -e .[gemini]
```

## Fast Path (Recommended)

Use pull mode + bootstrap. This is the safest default for most users.

1. Use a **user key** (`ah_k_...`) once for setup.
2. SDK creates/updates the pull agent in Hub.
3. SDK mints an **agent key** (`ah_a_...`) for runtime.
4. Run worker using the agent key only.

## Automated pull onboarding from SDK

Use `bootstrap_pull_agent(...)` to automate onboarding with a user key (`ah_k_...`).
It creates/updates the agent (pull endpoint) and returns a fresh agent key (`ah_a_...`).

```python
from agent_hub_sdk import bootstrap_pull_agent

result = bootstrap_pull_agent(
    hub_url="https://agenthub.example.com",
    user_api_key="ah_k_...",
    name="Bug Detector Agent",
    description="Finds likely defects and reproduction steps.",
    capability_name="bug_detection",
    capability_description="Detect bugs, edge cases, and fix strategy.",
    endpoint_id="bug-detector-agent",
    tags=["bugs", "qa", "debugging"],
    key_expires_in_days=90,
)

print(result["agent_id"])
print(result["endpoint_url"])   # pull://bug-detector-agent
print(result["agent_api_key"])  # ah_a_...
```

Security model:
- Use user key only for setup/bootstrap operations.
- Run pull worker only with agent key (`ah_a_...`).
- Revoke/rotate setup user key after onboarding.

## Pull mode (manual, if you do not use bootstrap helper)

If your agent cannot expose a public HTTP port, run in pull mode.

1. Register agent in Hub with `endpoint_url` starting with `pull://` (example: `pull://my-agent`).
2. Use the agent API key from Hub as `AGENT_API_KEY`.
3. Start your agent with `AGENT_TRANSPORT=pull`.

Example:

```bash
export HUB_URL=http://localhost:8000
export AGENT_TRANSPORT=pull
export AGENT_API_KEY=ah_a_xxx
python examples/my_gemini_agent.py
```

Push mode is still supported (`AGENT_TRANSPORT=push`).

## Quick start

Create `my_agent.py`:

```python
import os
from agent_hub_sdk import run_agent_server


def process(query: str, user_input: str) -> str:
    return f"Handled by custom agent. query={query} input={user_input[:200]}"


if __name__ == "__main__":
    run_agent_server(
        name="My Agent",
        port=int(os.environ.get("MY_AGENT_PORT", "5304")),
        bind_host=os.environ.get("AGENT_BIND_HOST", "127.0.0.1"),
        hub_url=os.environ.get("HUB_URL", "http://localhost:8000"),
        handler=process,
        inbound_api_key=os.environ.get("AGENT_INBOUND_API_KEY") or None,
    )
```

Run:

```bash
export HUB_URL=http://localhost:8000
export MY_AGENT_PORT=5304
export AGENT_BIND_HOST=127.0.0.1
export AGENT_INBOUND_API_KEY=replace_with_strong_secret
python my_agent.py
```

For production, set `HUB_URL` to `https://...`.

## Secure inbound auth (recommended)

Set your agent to require an inbound API key (`AGENT_INBOUND_API_KEY`).
When binding to non-loopback host (for example `0.0.0.0`), this is required by default.

Then register your agent in Hub with:

- `auth_type = api_key`
- `auth_config.header_name = Authorization`
- `auth_config.header_value = Bearer <same_secret_as_AGENT_INBOUND_API_KEY>`

This ensures only Hub calls are accepted by your agent endpoint.

## Endpoint URL reminder

Register in Hub UI with endpoint:

- Same machine: `http://127.0.0.1:5304`
- Different machine: `http://<agent-machine-ip>:5304`

`endpoint_url` is always the agent address, not the Hub address.

## Security options

`run_agent_server(...)` supports:

- `bind_host`: bind address (`127.0.0.1` by default)
- `inbound_api_key`: shared secret to authenticate incoming relay calls (required for non-loopback bind by default)
- `allow_insecure_bind`: disable non-loopback auth guard (`False` by default; not recommended)
- fixed body size limit: `1,048,576` bytes (1 MiB)
- `max_inflight_tasks`: max concurrent queued/processing tasks (default `32`)
- `expose_error_details`: include exception details in callbacks (`False` by default)

## Protocol expectations

Agent Hub sends `POST /` payload containing:

- `task_id`
- `message`
- `callback_url`
- `callback_auth.token`

Your handler receives parsed `query` + `user_input`.


## Security checklist

- Never commit API keys (`ah_k_...`, `ah_a_...`) to git.
- Never log raw keys in application logs.
- Use `AGENT_EXPOSE_ERROR_DETAILS=false` in production.
- For push mode, always set `AGENT_INBOUND_API_KEY`.
- Prefer pull mode if you do not need inbound public ports.

## Production notes

- Keep agent process running (systemd/Docker/service manager)
- Keep machine on and network reachable
- Open firewall/port for Hub-to-agent traffic
- Use HTTPS and stable DNS in production
