Metadata-Version: 2.4
Name: marona
Version: 0.6.2
Summary: Provider-neutral AI runtime and MCP/Skill gateway for Hub connections, managed responses, and external agents.
Author: Blessing Nyuwani
License-Expression: MIT
Project-URL: Homepage, https://www.marona.ai
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 Python SDK

Provider-neutral AI runtime and MCP/Skill gateway for Marona Hub connections,
managed responses, and bring-your-own-agent integrations.

```bash
pip install marona
```

## 1. Marona Hub

Connect Apps and governed Skills as one neutral MCP tool collection.

```python
from marona import Marona

marona = Marona(api_key="YOUR_MARONA_API_KEY")

connection = marona.hub.connect(
    apps=["sda-books"],
    skills=["download-book"],
)

tools = connection.list_tools()
result = connection.call_tool(
    "skill__download_book",
    {"request": "Download Steps to Christ"},
)
```

`MCPConnection` is not tied to OpenAI, LangGraph, CrewAI, or another model
vendor. It exposes:

```python
connection.list_tools()
connection.call_tool(name, arguments)
connection.server_url
connection.server_urls
connection.warnings
connection.session
```

An unresolved App or Skill name does not discard valid tools. Check
`connection.warnings` for its `code`, `selector_type`, `slug`, and corrective
message. Authentication, permission, billing, and configured-server failures
remain blocking errors.

Marona Hub owns discovery, identity, permissions, App and Skill resolution,
approvals, governed execution, and online, offline, or hybrid availability.

Use the asynchronous methods inside an event loop:

```python
connection = await marona.hub.connect_async(
    apps=["sda-books"],
    skills=["download-book"],
)
tools = await connection.list_tools_async()
result = await connection.call_tool_async(
    "skill__download_book",
    {"request": "Download Steps to Christ"},
)
```

## 2. Marona Runtime

Use `responses.create(...)` when Marona should manage model reasoning, tool
selection, permission and approval checks, execution, and the final response.

```python
from marona import Marona

marona = Marona(api_key="YOUR_MARONA_API_KEY")

tools = marona.hub.connect(
    apps=["sda-books"],
    skills=["download-book"],
)

response = marona.responses.create(
    model="gpt-5.6",
    tools=tools,
    input="Download Steps to Christ",
)

print(response.output_text)
```

The same request supports managed, direct-provider, private, and local models:

```python
model="gpt-5.6"                    # Marona-managed model
model="openai/gpt-5.6"
model="anthropic/claude-sonnet"
model="google/gemini"
model="ollama/qwen3"
model="litellm/local-qwen"
model="local/qwen"
```

Register only custom providers or downloaded in-process models:

```python
marona.models.register(
    name="office/company-assistant",
    endpoint="https://models.office.example/v1",
    model="company-assistant-v2",
    api_key="YOUR_PROVIDER_KEY",
)

marona.models.register(
    name="local/qwen",
    executor=qwen_executor,
    context_window=8192,
    max_output_tokens=512,
)
```

For asynchronous applications, call `await marona.responses.create_async(...)`.

### Images And Documents

```python
response = marona.responses.create(
    model="openai/gpt-5.6",
    input=[
        {
            "role": "user",
            "content": [
                {"type": "input_text", "text": "Summarize this document and image."},
                {"type": "input_image", "image_url": "https://example.com/image.jpg"},
                {
                    "type": "input_file",
                    "filename": "report.pdf",
                    "file_data": "data:application/pdf;base64,...",
                    "detail": "high",
                },
            ],
        }
    ],
)
```

## 3. Bring Your Own Agent

The external framework owns its Agent, reasoning, and orchestration. Marona
supplies neutral MCP tools and retains authorization, approvals, and execution.

### OpenAI Agents SDK Example

```python
from marona import Marona
from agents import Agent, Runner

marona = Marona(api_key="YOUR_MARONA_API_KEY")
connection = marona.hub.connect(
    apps=["sda-books"],
    skills=["download-book"],
)

# Adapt only at the framework boundary. Marona itself remains vendor-neutral.
framework_tools = your_openai_agents_mcp_adapter(connection)

agent = Agent(
    name="Book Assistant",
    model="gpt-5.6",
    instructions="Help users find and download books.",
    tools=framework_tools,
)

result = Runner.run_sync(agent, "Download Steps to Christ")
print(result.final_output)
```

`your_openai_agents_mcp_adapter(...)` represents the OpenAI-specific adapter at
the framework boundary; it is not part of Marona's vendor-neutral core API.

An MCP-compatible framework can map its standard tool-list and tool-call hooks
directly to `connection.list_tools()` and `connection.call_tool(...)`. Marona
does not claim that one Python tool object automatically satisfies every agent
framework's proprietary interface.

## Execution Modes

Set mode when creating Marona:

```python
marona = Marona(
    api_key="YOUR_MARONA_API_KEY",
    mode="hybrid",
)
```

- `online`: network models and online MCP targets are allowed.
- `hybrid`: local/private execution may fall back to online execution.
- `offline`: only installed local Apps, Skills, data, and local models run.

Changing `model` never changes App, Skill, permission, approval, or MCP rules.
