Metadata-Version: 2.4
Name: mindpy
Version: 0.2.5
Summary: A Python AI framework for controlling Minecraft bots
Project-URL: Homepage, https://github.com/AnujaGajaweera/MindPy
Project-URL: Documentation, https://mindpy.readthedocs.io
Project-URL: Repository, https://github.com/AnujaGajaweera/MindPy
Project-URL: Issues, https://github.com/AnujaGajaweera/MindPy/issues
Author: MindPy Contributors
License: MIT
License-File: LICENSE
Keywords: ai,automation,bot,minecraft,mineflayer,pycraft
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.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Games/Entertainment
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Requires-Dist: aiohttp>=3.9.0
Requires-Dist: cryptography>=42.0.0
Requires-Dist: loguru>=0.7.2
Requires-Dist: numpy>=1.26.0
Requires-Dist: orjson>=3.9.0
Requires-Dist: pydantic-settings>=2.1.0
Requires-Dist: pydantic>=2.5.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: pyyaml>=6.0.1
Requires-Dist: rich>=13.7.0
Requires-Dist: toml>=0.10.2
Requires-Dist: typer>=0.9.0
Requires-Dist: typing-extensions>=4.9.0
Requires-Dist: websockets>=12.0
Provides-Extra: all
Requires-Dist: anthropic>=0.8.0; extra == 'all'
Requires-Dist: black>=23.12.0; extra == 'all'
Requires-Dist: coverage>=7.3.0; extra == 'all'
Requires-Dist: fastapi>=0.109.0; extra == 'all'
Requires-Dist: google-generativeai>=0.3.0; extra == 'all'
Requires-Dist: mkdocs-material>=9.5.0; extra == 'all'
Requires-Dist: mkdocs>=1.5.0; extra == 'all'
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'all'
Requires-Dist: mypy>=1.8.0; extra == 'all'
Requires-Dist: openai>=1.6.0; extra == 'all'
Requires-Dist: pre-commit>=3.6.0; extra == 'all'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'all'
Requires-Dist: pytest-cov>=4.1.0; extra == 'all'
Requires-Dist: pytest>=7.4.0; extra == 'all'
Requires-Dist: ruff>=0.1.0; extra == 'all'
Requires-Dist: uvicorn>=0.27.0; extra == 'all'
Provides-Extra: api
Requires-Dist: fastapi>=0.109.0; extra == 'api'
Requires-Dist: uvicorn>=0.27.0; extra == 'api'
Provides-Extra: dev
Requires-Dist: black>=23.12.0; extra == 'dev'
Requires-Dist: coverage>=7.3.0; extra == 'dev'
Requires-Dist: mypy>=1.8.0; extra == 'dev'
Requires-Dist: pre-commit>=3.6.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest>=7.4.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
Requires-Dist: mkdocs>=1.5.0; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'docs'
Provides-Extra: llm
Requires-Dist: anthropic>=0.8.0; extra == 'llm'
Requires-Dist: google-generativeai>=0.3.0; extra == 'llm'
Requires-Dist: openai>=1.6.0; extra == 'llm'
Description-Content-Type: text/markdown

<div align="center">

# MindPy

**A Python-first, asyncio-native framework for building intelligent Minecraft bots.**

[![CI](https://github.com/CybersharpX/MindPy/actions/workflows/ci.yml/badge.svg)](https://github.com/CybersharpX/MindPy/actions)
[![PyPI](https://img.shields.io/pypi/v/mindpy)](https://pypi.org/project/mindpy/)
[![Python](https://img.shields.io/pypi/pyversions/mindpy)](https://pypi.org/project/mindpy/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

</div>

---

MindPy lets you write Python bots for Minecraft servers — from a simple greeter to a full autonomous AI agent — using a clean, event-driven API with zero external Minecraft dependencies.

```python
import asyncio
from mindpy import Bot, EventTypes, Event

async def main():
    async with Bot("mc.example.com", username="Scout") as bot:

        @bot.on(EventTypes.BOT_SPAWNED)
        async def on_spawn(event: Event) -> None:
            await bot.chat("Hello, world!")

        @bot.on(EventTypes.CHAT_MESSAGE)
        async def on_chat(event: Event) -> None:
            raw = event.data["raw"]
            if "come here" in raw:
                await bot.chat("On my way!")

        await bot.run()

asyncio.run(main())
```

---

## Features

| Category | Capabilities |
|---|---|
| **Protocol** | Asyncio-native MC Java Edition 1.8 → 1.21+, no external dependency |
| **Auth** | Offline mode + Microsoft OAuth2 (Device Code Flow) online mode |
| **World** | numpy `uint16` chunk storage, 3-D spatial entity index |
| **Navigation** | A* pathfinding (Chebyshev heuristic), waypoints, path smoothing |
| **AI** | OpenAI / Anthropic / Gemini / Ollama LLM providers, tool calling, reflection |
| **Memory** | Working, short-term, long-term, conversation, world, player, task, knowledge-base |
| **Tasks** | Interruptible, suspendable, serializable, cancelable task system |
| **Goals** | Hierarchical goal decomposition |
| **Events** | Priority-sorted publish/subscribe with wildcard patterns & `SubscriptionToken` |
| **Plugins** | Auto-discovery, dependency resolution, lifecycle hooks |
| **Config** | YAML / JSON / TOML / env-var config with sentinel-safe fallbacks |
| **CI** | ruff, mypy, pytest on Ubuntu + Windows, PyPI trusted publishing |

---

## Installation

**Requires Python ≥ 3.12**

```bash
pip install mindpy
```

**With LLM support:**
```bash
pip install "mindpy[llm]"      # OpenAI, Anthropic, Gemini
```

**Development install:**
```bash
git clone https://github.com/CybersharpX/MindPy.git
cd MindPy
pip install -e ".[dev,llm]"
pre-commit install
```

---

## Quick Start

### Offline mode (cracked server)

```python
import asyncio
from mindpy import Bot, EventTypes, Event

async def main():
    bot = Bot(host="localhost", port=25565, username="MyBot")

    @bot.on(EventTypes.BOT_CONNECTED)
    async def ready(event: Event) -> None:
        await bot.chat("MindPy is online!")

    async with bot:
        await bot.run()

asyncio.run(main())
```

### Online mode (Microsoft account)

```python
import asyncio
from mindpy import Bot
from mindpy.protocol.auth import MicrosoftAuth

async def main():
    # Authenticate once — paste the URL into your browser
    async with MicrosoftAuth() as auth:
        profile = await auth.device_flow_auth()

    async with Bot("mc.example.com", auth_profile=profile, online_mode=True) as bot:
        await bot.run()

asyncio.run(main())
```

### Choosing a protocol version

```python
from mindpy import Bot
from mindpy.protocol.codec import ProtocolRegistry

# List all explicitly supported versions
print(ProtocolRegistry.supported_versions())
# [47, 340, 754, 762, 765, 769]

# 47  = Minecraft 1.8
# 340 = Minecraft 1.12.2
# 754 = Minecraft 1.16.5
# 762 = Minecraft 1.19.4
# 765 = Minecraft 1.20.4
# 769 = Minecraft 1.21+   (also used as fallback for 1.21.x patches)

bot = Bot("localhost", protocol_version=769)  # explicitly use 1.21
```

---

## Event System

Every in-game event flows through the `EventBus`:

```python
from mindpy import Bot, Event, EventTypes
from mindpy.events import handler          # class-level decorator
from mindpy.events.event import EventPriority

bot = Bot("localhost")

# --- Option 1: fluent bot.on() decorator ---
@bot.on(EventTypes.CHAT_MESSAGE, priority=EventPriority.HIGH)
async def on_chat(event: Event) -> None:
    print(event.data["raw"])

# --- Option 2: wildcard subscription ---
@bot.on("bot.*")
async def on_any_bot_event(event: Event) -> None:
    print(f"[bot] {event.event_type}")

# --- Option 3: SubscriptionToken (cancel later) ---
token = bot.event_bus.subscribe("player.joined", on_chat)
# ... later:
token.cancel()

# --- Option 4: wait for a single event ---
event = await bot.event_bus.wait_for(EventTypes.BOT_SPAWNED, timeout=30.0)
```

**Built-in event types** (`mindpy.events.event.EventTypes`):

| Event | Trigger |
|---|---|
| `bot.connected` | TCP connection + login succeeded |
| `bot.disconnected` | Graceful or forced disconnect |
| `bot.spawned` | JoinGame packet received |
| `bot.died` | Health reached 0 |
| `bot.health_changed` | UpdateHealth packet |
| `bot.position_changed` | Server-forced teleport |
| `bot.reconnecting` | Reconnect attempt starting |
| `bot.error` | Unhandled connection error |
| `chat.message` | Any chat packet received |
| `chunk.loaded` / `chunk.unloaded` | World chunk events |
| `entity.*` | Entity spawn/despawn/move/damage |
| `task.*` / `goal.*` | Task and goal lifecycle |
| `plugin.*` | Plugin load/unload |

---

## Bot API Reference

### `Bot.__init__`

```python
Bot(
    host: str = "localhost",
    port: int = 25565,
    username: str = "MindPyBot",
    auth_profile: AuthProfile | None = None,
    protocol_version: int = 765,       # 1.20.4 default
    online_mode: bool = False,
    view_distance: int = 10,
    config: Config | None = None,
)
```

### Core methods

| Method | Description |
|---|---|
| `await bot.connect()` | TCP connect + full login sequence |
| `await bot.disconnect()` | Graceful disconnect, publishes event |
| `await bot.reconnect()` | Exponential-backoff retry loop |
| `await bot.run()` | Block until disconnected |
| `await bot.chat(msg)` | Send chat message (truncated to 256 chars) |
| `await bot.say(msg)` | Alias for `chat()` |
| `await bot.move_to(x, y, z)` | Send position update packet |
| `bot.is_connected()` | `True` if in PLAY state |
| `bot.get_position()` | `(x, y, z)` tuple |
| `bot.get_health()` | Current health (0.0–20.0) |
| `bot.get_hunger()` | Current food level (0–20) |

### `BotState` fields

```python
bot.state.connected       # bool
bot.state.health          # float (0.0–20.0)
bot.state.hunger          # int (0–20)
bot.state.saturation      # float
bot.state.x, .y, .z       # float – world position
bot.state.yaw, .pitch     # float – look direction
bot.state.entity_id       # int – server-assigned entity ID
bot.state.game_mode       # int – 0=survival 1=creative 2=adventure 3=spectator
bot.state.dimension       # str – e.g. "minecraft:overworld"
bot.state.position        # property → (x, y, z)
```

---

## Protocol Layer

`mindpy.protocol` is a standalone asyncio-native Minecraft protocol implementation — no any other external MC protocol library needed.

```python
from mindpy.protocol import MinecraftConnection, ProtocolRegistry, ConnectionState
from mindpy.protocol.login import LoginOrchestrator

# Low-level usage (normally you just use Bot)
conn = MinecraftConnection("localhost", 25565, protocol_version=765, registry=...)
await conn.connect()

orchestrator = LoginOrchestrator(conn, username="Bot")
await orchestrator.login()    # transitions conn to PLAY state

# Register per-packet handlers
from mindpy.protocol.versions.v765 import KeepAliveClientboundPacket

@conn.on_packet(KeepAliveClientboundPacket)
async def handle_ka(packet):
    ...
```

---

## AI Integration

```python
import asyncio
from mindpy import Bot, EventTypes, Event
from mindpy.llm import LLMManager
from mindpy.ai import AIAgent, AgentContext

async def main():
    # Setup LLM
    llm = LLMManager()
    llm.setup_openai(api_key="sk-...", model="gpt-4o")

    agent = AIAgent(llm, system_prompt="You are a Minecraft helper bot.")

    bot = Bot("localhost")

    @bot.on(EventTypes.CHAT_MESSAGE)
    async def on_chat(event: Event) -> None:
        raw = event.data.get("raw", "")
        ctx = AgentContext(position=bot.state.position, health=bot.state.health)
        reply = await agent.decide(ctx, user_message=raw)
        await bot.chat(reply[:256])

    async with bot:
        await bot.run()

asyncio.run(main())
```

---

## Testing

```bash
# Run all tests
pytest

# Run only protocol tests
pytest tests/test_protocol.py -v

# Run with coverage
pytest --cov=mindpy --cov-report=term-missing
```

---

## Documentation

| Doc | Link |
|---|---|
| Getting Started | [docs/getting-started.md](docs/getting-started.md) |
| Architecture | [docs/architecture.md](docs/architecture.md) |
| API Reference | [docs/api.md](docs/api.md) |
| Plugin Development | [docs/plugin-development.md](docs/plugin-development.md) |
| Protocol Guide | [docs/protocol.md](docs/protocol.md) |
| Examples | [examples/](examples/) |

---

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). PRs are welcome!

```bash
git clone https://github.com/CybersharpX/MindPy.git
cd MindPy
pip install -e ".[dev]"
pre-commit install
pytest
```

---

## License

MIT — see [LICENSE](LICENSE).

---

> MindPy is inspired by [Mineflayer](https://github.com/prismarinejs/mineflayer) but is a ground-up Python reimplementation with a native asyncio protocol layer, numpy world storage, and first-class AI/LLM integration.
