Metadata-Version: 2.4
Name: marona
Version: 0.1.4
Summary: Official Python client SDK for Marona-compatible AI runtimes and Hub integrations.
Author: Blessing Nyuwani
License-Expression: MIT
Project-URL: Homepage, https://www.marona.ai
Project-URL: Repository, https://github.com/BlessingNyuwani/edge-node-service
Project-URL: Documentation, https://hub.marona.ai
Keywords: marona,sdk,mcp,agents,ai,runtime
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
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
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx<1.0,>=0.28
Provides-Extra: dev
Requires-Dist: pytest<9.0,>=8.0; extra == "dev"
Requires-Dist: build<2.0,>=1.2; extra == "dev"
Requires-Dist: twine<7.0,>=6.0; extra == "dev"
Dynamic: license-file

# marona

Official Python client for Marona-compatible AI runtimes and Marona Hub.

Use `marona` when you are building an application, bot, device, or agent
interface that needs to:

- send messages to a Marona-compatible runtime
- discover available apps
- connect approved Hub apps to your own agent framework
- manage user permissions and service connections
- receive inbound events
- create realtime voice or vision sessions

## Install

```bash
pip install marona
```

## 1. Create A Client

Marona Cloud:

```python
from marona import Marona

marona = Marona(
    base_url="https://edge.marona.ai",
    api_key="mrn_live_...",
)
```

Self-hosted runtime:

```python
from marona import Marona

marona = Marona(
    base_url="https://runtime.example.com",
    api_key="mrn_live_...",
)
```

## 2. Send A Runtime Message

```python
import asyncio

from marona import Marona


async def main() -> None:
    marona = Marona(api_key="mrn_live_...")
    response = await marona.message(
        "Create a PowerPoint about AI introduction",
        interface="api",
        conversation_id="demo",
    )

    print(response.reply)
    for artifact in response.artifacts:
        print(artifact.get("filename"), artifact.get("url"))


asyncio.run(main())
```

## 3. Connect Hub Apps To Your Own Agent

Every Hub app has a unique app ID, also called a slug. Examples:

- `weather-mcp`
- `knowledge-mcp`
- `company-crm-mcp`

Use `hub.connect(...)` when your own agent framework will execute the model and
you only need approved app connections from Marona Hub.

```python
import asyncio

from marona import Marona


async def main() -> None:
    marona = Marona(api_key="mrn_live_...")
    servers = await marona.hub.connect(
        ["weather-mcp", "knowledge-mcp"],
        adapter="openai_mcp",
    )
    print(servers)


asyncio.run(main())
```

For frameworks that need tool descriptors instead of MCP server configs:

```python
tools = await marona.hub.connect(
    ["weather-mcp"],
    adapter="tools",
)
```

## 4. List Available Apps

```python
apps = await marona.list_apps(limit=20, search="slides")

for app in apps.apps:
    print(app["slug"], app["name"])
```

## 5. Pair A User Interface

Pairing lets a web, mobile, desktop, wearable, or other interface attach to the
same user identity.

```python
pairing = await marona.start_pairing(
    interface="web",
    device_name="My web app",
)

print(pairing.display_code)
print(pairing.whatsapp_url)
```

After the user sends the pairing code from WhatsApp, poll for completion:

```python
status = await marona.pairing_status(pairing.pairing_id)

if status.identity:
    identity_token = status.identity.access_token
```

Use the identity token on future requests:

```python
response = await marona.message(
    "What is on my calendar today?",
    identity_token=identity_token,
)
```

## 6. Connect A User Service Account

Some apps need a user connection, such as Google Calendar, Gmail, or Google
Slides.

```python
connection = await marona.connect_app(
    "slides",
    provider="google",
    identity_token=identity_token,
    return_url="https://example.com/connected",
)

print(connection.authorization_url)
```

Open `authorization_url` in a browser so the user can authorize the provider.

## 7. Send Files

```python
from marona import RuntimeAttachment

attachment = RuntimeAttachment.from_bytes(
    b"hello",
    filename="note.txt",
    mime_type="text/plain",
    kind="document",
)

response = await marona.message(
    "Summarize this file",
    attachments=[attachment],
    identity_token=identity_token,
)
```

## 8. Edge Runtime Activation

Device runtimes can activate and sync against Marona Hub with the same package:

```python
from marona import EdgeHubClient

edge = EdgeHubClient(hub_url="https://hub.marona.ai")
activation = await edge.start_activation(
    device_name="Office runtime",
    device_public_key="...",
)
```

## Package Names

- Python client: `marona`, import `marona`
- Dart client: `marona`, import `package:marona/marona.dart`
- TypeScript client: `marona`, import `Marona` from `"marona"`
- Developer SDK for building apps: `marona-sdk`, import `marona_sdk`

## Release

Build and verify:

```bash
rm -rf dist build marona.egg-info
python3 -m build
python3 -m twine check dist/*
```

Upload with the project-scoped PyPI token:

```bash
TWINE_USERNAME=__token__ TWINE_PASSWORD='PROJECT_SCOPED_TOKEN' python3 -m twine upload dist/*
```
