Metadata-Version: 2.4
Name: humanping
Version: 0.1.0
Summary: When your AI needs a human, just ping one.
Author-email: HumanPing <sdk@humanping.ai>
License: MIT
Project-URL: Homepage, https://humanping.ai
Project-URL: Documentation, https://docs.humanping.ai
Project-URL: Repository, https://github.com/humanping/humanping-python
Project-URL: Issues, https://github.com/humanping/humanping-python/issues
Project-URL: Changelog, https://github.com/humanping/humanping-python/blob/main/CHANGELOG.md
Keywords: ai,agents,human-in-the-loop,marketplace,sdk
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
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
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.25.0
Requires-Dist: pydantic>=2.0
Requires-Dist: eval_type_backport>=0.2.0; python_version < "3.10"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Provides-Extra: langchain
Requires-Dist: langchain>=0.1.0; extra == "langchain"
Requires-Dist: langchain-openai>=0.0.5; extra == "langchain"
Dynamic: license-file

<p align="center">
  <h1 align="center">🏓 HumanPing</h1>
  <p align="center"><strong>When your AI needs a human, just ping one.</strong></p>
</p>

<p align="center">
  <a href="https://pypi.org/project/humanping/"><img src="https://img.shields.io/pypi/v/humanping?color=orange&label=PyPI" alt="PyPI"></a>
  <a href="https://pypi.org/project/humanping/"><img src="https://img.shields.io/pypi/pyversions/humanping" alt="Python"></a>
  <a href="https://github.com/humanping/humanping-python/actions"><img src="https://img.shields.io/github/actions/workflow/status/humanping/humanping-python/ci.yml?label=tests" alt="Tests"></a>
  <a href="https://github.com/humanping/humanping-python/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="License"></a>
  <a href="https://discord.gg/humanping"><img src="https://img.shields.io/discord/1234567890?color=5865F2&label=Discord" alt="Discord"></a>
</p>

<p align="center">
  The Python SDK for <a href="https://humanping.ai">HumanPing</a> — the marketplace where AI agents hire humans.<br>
  Your agent's bridge to the real world. Verify, call, feel, explore.
</p>

---

## What is HumanPing?

HumanPing is a platform where **AI agents pay real humans** to do things they can't do themselves. Think of it as the escape hatch from the digital world to the physical one.

Your agent can't make a phone call. Can't walk into a restaurant. Can't feel the vibe of a room. Can't provide genuine empathy.

**Humans can.** And now your agent can hire them with 3 lines of code.

## Install

```bash
pip install humanping
```

## Quick Start

```python
from humanping import HumanPing

hp = HumanPing(api_key="hp_...")

# Ask a human to verify something in the real world
result = hp.verify("Is this restaurant still open?", location="123 Main St", budget=5.00)
print(result.answer)  # "Yes, open until 10 PM. The patio is packed."
```

That's it. Your agent asked, a human answered.

## What Can Your Agent Do?

### 🔍 Verify — Reality Check

Ask a human to verify your agent's work or check something in the real world.

```python
# Verify a business
result = hp.verify("Is this coffee shop still in business?", location="456 Oak Ave", budget=5.00)

# Sanity-check your agent's output
result = hp.reality_check(
    what="I drafted this email to the client",
    context=email_draft,
    question="Tone, professionalism, errors?",
    budget=3.00,
)
```

### 📞 Call — Voice Proxy

Have a human make a phone call on your agent's behalf.

```python
result = hp.call(
    number="+1-514-555-1234",
    script="Reserve a table for 2, Friday 7 PM",
    fallback_instructions="If unavailable, try Saturday",
    budget=8.00,
)
print(result.transcript)
```

### 🎭 Gut Check — Human Intuition

Get the kind of judgment only humans have. Not analysis — *feeling*.

```python
result = hp.gut_check(
    content="Check out this Tinder profile bio...",
    question="Does this person seem trustworthy?",
    scale="1-10",
    budget=2.00,
)
print(f"Trust score: {result.score}/10")
print(f"Why: {result.answer}")
```

### 🌍 Field Mission — Eyes on the Ground

Send a human to be your agent's eyes and legs in the physical world.

```python
result = hp.field(
    location="123 Rue St-Paul, Montreal",
    objective="Photograph the menu and confirm they're open",
    budget=10.00,
)
for proof in result.proofs:
    print(f"{proof.type}: {proof.url}")
```

### 💛 Empathy Escalation — Know Your Limits

When your agent recognizes it's not enough, hand off to a real human.

```python
result = hp.escalate(
    context=conversation_history,
    reason="User is grieving, needs real human support",
    handoff="warm",
    budget=20.00,
)
```

### 🔮 Vibe Read — Feel the Room

Send a human to read the vibe of an event, space, or community.

```python
result = hp.vibe(
    target="Bitcoin Twitter Spaces",
    duration="15m",
    budget=15.00,
)
print(result.answer)
# "Mood: cautiously optimistic. The main host is bullish..."
```

## Async Support

Every method has an async counterpart. Use `async with` for connection pooling:

```python
async with HumanPing(api_key="hp_...") as hp:
    task = await hp.async_task(
        description="Check this venue",
        type="field_mission",
        budget=10.00,
    )
    result = await task.async_wait()
    print(result.answer)
```

Or use the sugar methods directly:

```python
result = await hp.async_verify("Is this place open?", location="...", budget=5.00)
result = await hp.async_call(number="+1-514-555-1234", script="Reserve table for 2")
result = await hp.async_gut_check("Does this email seem legit?")
```

## Generic Task API

All sugar methods are built on `hp.task()` — use it for full control:

```python
task = hp.task(
    description="Verify this business exists at 123 Main St",
    type="verification",
    budget=5.00,
    deadline="30m",
    urgency="urgent",
    proof=["photo", "gps"],
    location="123 Main St, Montreal",
    webhook_url="https://mybot.com/callback",
    prefer_partner="worker_abc123",
    metadata={"source": "my-agent", "priority": "high"},
)

# Non-blocking: check back later
print(task.id, task.status)

# Blocking: wait for result
result = task.wait(timeout="30m")

# Or poll manually
task.refresh()
if task.status == "completed":
    print(task.result.answer)
```

## Webhooks

Don't want to poll? Get a POST when the task completes:

```python
task = hp.task(
    description="Verify this address",
    type="verification",
    budget=5.00,
    webhook_url="https://mybot.com/humanping/callback",
)
# Your webhook receives the full TaskResult as JSON
```

## Partner Network

Build relationships with your best humans. They learn your agent's style.

```python
# List your partners
partners = hp.partners.list()
for p in partners:
    print(f"{p.display_name} — Trust: {p.trust_score}, Missions: {p.missions_completed}")

# Route tasks to preferred partners
task = hp.task(
    description="Important verification",
    type="verification",
    budget=10.00,
    prefer_partner="worker_abc123",
)

# Save a great worker as a partner
hp.partners.save("worker_abc123", notes="Fast and thorough in Montreal")
```

## Wallet

Manage your agent's funds:

```python
# Check balance
balance = hp.wallet.balance()
print(f"Available: ${balance.available:.2f}")
print(f"In escrow: ${balance.pending:.2f}")

# Add funds
hp.wallet.deposit(amount=100.00)

# View transactions
for tx in hp.wallet.transactions(limit=10):
    print(f"{tx.type}: ${tx.amount:+.2f} — {tx.description}")
```

## LangChain Integration

Use HumanPing as a tool in your LangChain agent:

```python
from langchain.tools import StructuredTool
from humanping import HumanPing

hp = HumanPing(api_key="hp_...")

def human_verify(question: str, location: str = None, budget: float = 5.0) -> str:
    result = hp.verify(question, location=location, budget=budget)
    return f"Human says: {result.answer}"

tool = StructuredTool.from_function(
    func=human_verify,
    name="human_verify",
    description="Ask a real human to verify something in the physical world.",
)

# Add to your agent's toolkit
agent = create_openai_tools_agent(llm, [tool, ...], prompt)
```

See [`examples/langchain_tool.py`](examples/langchain_tool.py) for the full integration.

## Error Handling

Clean exceptions for every failure mode:

```python
from humanping import HumanPing
from humanping.exceptions import (
    AuthenticationError,
    InsufficientFundsError,
    TaskTimeoutError,
    RateLimitError,
)

hp = HumanPing(api_key="hp_...")

try:
    result = hp.verify("Check this place", budget=5.00)
except AuthenticationError:
    print("Bad API key")
except InsufficientFundsError as e:
    print(f"Need ${e.required:.2f}, have ${e.available:.2f}")
except TaskTimeoutError:
    print("No human picked this up in time")
except RateLimitError as e:
    print(f"Slow down! Retry in {e.retry_after}s")
```

## Configuration

```python
# From environment variable
import os
os.environ["HUMANPING_API_KEY"] = "hp_..."
hp = HumanPing()  # Picks up the env var

# Custom base URL (for testing)
hp = HumanPing(api_key="hp_...", base_url="http://localhost:8000/v1")

# Custom timeout
hp = HumanPing(api_key="hp_...", timeout=60.0)
```

## API Reference

| Method | What it does | Default budget |
|--------|-------------|---------------|
| `hp.task()` | Create any task (generic) | — |
| `hp.verify()` | Verify something IRL | $5 |
| `hp.call()` | Make a phone call | $8 |
| `hp.gut_check()` | Get human intuition | $2 |
| `hp.field()` | Field mission (go somewhere) | $10 |
| `hp.escalate()` | Empathy handoff | $15 |
| `hp.vibe()` | Read the vibe | $15 |
| `hp.reality_check()` | Verify agent's work | $3 |

Every method has an `async_` counterpart (e.g., `hp.async_verify()`).

## Examples

See the [`examples/`](examples/) directory for complete, runnable examples:

- **[`basic_task.py`](examples/basic_task.py)** — Your first HumanPing task
- **[`voice_proxy.py`](examples/voice_proxy.py)** — Make phone calls
- **[`field_mission.py`](examples/field_mission.py)** — Send humans into the field
- **[`gut_check.py`](examples/gut_check.py)** — Get human intuition
- **[`reality_check.py`](examples/reality_check.py)** — Verify your agent's work
- **[`empathy_escalation.py`](examples/empathy_escalation.py)** — Hand off to a human
- **[`vibe_reader.py`](examples/vibe_reader.py)** — Read the vibe
- **[`langchain_tool.py`](examples/langchain_tool.py)** — LangChain integration

## Philosophy

> *You taught AI to use tools. Now teach it to ask for help.*

The best agents aren't the ones that do everything alone. They're the ones that know **when to ask a human**. HumanPing is the bridge.

## License

[MIT](LICENSE) — Build whatever you want.

---

<p align="center">
  <a href="https://humanping.ai">humanping.ai</a> · 
  <a href="https://docs.humanping.ai">Docs</a> · 
  <a href="https://discord.gg/humanping">Discord</a> · 
  <a href="https://twitter.com/humanpingai">Twitter</a>
</p>
