"""RelationalAI-Cortex Integration

Deploy Snowflake Cortex AI agents powered by RelationalAI semantic models for Snowflake Intelligence.

## Quickstart

```python
from snowflake import snowpark

from relationalai.semantics import Model
from relationalai.config import create_config, SnowflakeConnection
from relationalai.agent.cortex import CortexAgentManager, DeploymentConfig, discover_imports, ToolRegistry

# Create session using role for deployment
session: snowpark.Session = create_config().get_session(SnowflakeConnection)

# Configure manager
manager = CortexAgentManager(
    session=session,
    config=DeploymentConfig(
        agent_name="MY_ASSISTANT",  # Unique name for the agent
        database="MY_DB",           # Snowflake database for deployment (sprocs & agent)
        schema="MY_SCHEMA",         # Snowflake schema for deployment (sprocs & agent)
        warehouse="COMPUTE_WH"))    # Warehouse for RAI tool execution (SI users need USAGE)

# Your model definition function
def initialize(m: Model):
    # Define your entities, relationships, and computed properties
    ...

# Initialize RAI Tools
def init_tools(model: Model):
    initialize(model)  # Initialize RAI Model with your semantics
    return ToolRegistry().add(
        model=model,   # Expose model through tools
        description="...")


# Deploy
manager.deploy(
    init_tools=init_tools,       # Initialize RAI Tools
    imports=discover_imports())  # Specify local python modules to package into sproc

print(manager.status())
```

After deployment, you can find the Cortex Agent in the Snowflake UI under **AI & ML > Agents**. The UI allows you to chat with the agent, preview or add it to Snowflake Intelligence, and view traces of conversations the agent participates in.

For programmatic access (testing, automation):

```python
chat = manager.chat()
response = chat.send("What can I ask about?")
print(response.full_text())
```

Conversations through the programmatic interface are persisted and available through the Monitoring tab for the agent in the Snowflake UI.

## How It Works

The RelationalAI-Cortex integration
1) operationalizes your RAI Model into Snowflake stored procedures
2) configures a Cortex Agent with these tools, and instructions on how to explore your semantic models and answer questions about your data.

| Tool | Purpose |
|------|---------|
| `RAI_DISCOVER_MODELS` | Discover available models and their key concepts |
| `RAI_VERBALIZE_MODEL` | Get detailed model structure and relationships |
| `RAI_EXPLAIN_CONCEPT` | Understand business rules for specific concepts |
| `RAI_QUERY_MODEL` | Execute pre-defined queries (PREVIEW) |

### RBAC: Caller's Rights

All stored procedures are created with **CALLER'S RIGHTS** — they execute under the SI user's Snowflake role, not the deployer's role. This means:

- **Data access is governed by the caller's role.** Users only see data their role can `SELECT`.
- **No privilege escalation.** The agent never operates with more permissions than the person using it.

This makes Snowflake's existing RBAC the single source of truth for data governance across all agent interactions.

## Snowflake Privileges

Two roles are involved:
1) **deployer/admin** who creates the Cortex Agent
2) **SI users** who interact with it through the Snowflake Intelligence UI (or, programmatic users of the Cortex Agent)

Both require the `rai_developer` role.

### `rai_developer` Role

The `rai_developer` role is created during RAI Native App installation. It grants access to RAI and includes the following privileges by default:

| Privilege | Purpose |
|-----------|---------|
| `USAGE` on `S3_RAI_INTERNAL_BUCKET_EGRESS_INTEGRATION` | External access for RAI stored procedures |
| `USAGE` on `PYPI_ACCESS_INTEGRATION` | Access to Python packages during sproc execution |

These are necessary to execute the Snowflake stored procedures.

### Deployer / Admin

| Privilege | Purpose |
|-----------|---------|
| `CREATE STAGE` on target schema | Store sproc dependencies (if `manage_stage=True`) |
| `CREATE PROCEDURE` on target schema | Register RAI tool sprocs |
| `CREATE AGENT` on target schema | Register the Cortex agent |
| `database role snowflake.cortex_user` | Access Cortex services |
| `rai_developer` role | Access RAI (see above) |
| `USAGE` on database and schema | Access the deployment target |

### SI Users

Because sprocs use CALLER'S RIGHTS, SI users need privileges on the resources the agent accesses at runtime:

| Privilege | Purpose |
|-----------|---------|
| `USAGE` on warehouse | Execute sprocs (warehouse from `DeploymentConfig`, or session default) |
| `database role snowflake.cortex_user` | Access Cortex services |
| `rai_developer` role | Access RAI (see above) |
| `USAGE` on database and schema | Access the data |
| `SELECT` on tables | Read data accessed by the model |
| `EXECUTE` on stored procedures | Invoke RAI tools |

### Example Role Definitions

```sql
-- Deployer role
create role my_deployer_role;
grant create stage on schema my_db.my_schema to role my_deployer_role;
grant create procedure on schema my_db.my_schema to role my_deployer_role;
grant create agent on schema my_db.my_schema to role my_deployer_role;
grant database role snowflake.cortex_user to role my_deployer_role;
grant role rai_developer to role my_deployer_role;
grant usage on database my_db to role my_deployer_role;
grant usage on schema my_db.my_schema to role my_deployer_role;

-- SI user role
create role my_si_user_role;
grant usage on warehouse compute_wh to role my_si_user_role;
grant database role snowflake.cortex_user to role my_si_user_role;
grant role rai_developer to role my_si_user_role;
grant usage on database my_db to role my_si_user_role;
grant usage on schema my_db.my_schema to role my_si_user_role;
grant select on all tables in schema my_db.my_schema to role my_si_user_role;
grant execute on all procedures in schema my_db.my_schema to role my_si_user_role;
```
"""

# Unified interface (recommended for most use cases)
from .cortex_agent_manager import CortexAgentManager
from .deployment_config import DeploymentConfig, DeploymentStatus

# Low-level APIs (for advanced use cases)
from .cortex_tool_resources import CortexToolResources, ToolResourceStatus
from .tool import MaturityLevel
from .api.agent import CortexAgentApi, APIResponseError
from .api.thread import CortexThreadApi

# Chat interface
from .chat import CortexAgentChat, ToolCall, ToolResult, ContentItem, ChatResponse

# Tools
from .tool import ToolRegistry, DefaultTool, Tool, Capability

# Verbalizers
from .verbalize import Verbalizer, ModelVerbalizer, SourceCodeVerbalizer

# Queries
from .queries import Queries, QueryCatalog

# Snowflake utilities
from .api.client import http_client

# Import discovery
from .discover_imports import discover_imports


__include_in_docs__ = True

__all__ = [
    # Unified interface
    "CortexAgentManager",
    "DeploymentConfig",
    "DeploymentStatus",
    # Low-level APIs
    "CortexToolResources",
    "ToolResourceStatus",
    "MaturityLevel",
    "CortexAgentApi",
    "CortexThreadApi",
    "APIResponseError",
    # Chat
    "CortexAgentChat",
    "ToolCall",
    "ToolResult",
    "ContentItem",
    "ChatResponse",
    # Tools
    "Tool",
    "ToolRegistry",
    "DefaultTool",
    "Capability",
    # Verbalizers
    "Verbalizer",
    "ModelVerbalizer",
    "SourceCodeVerbalizer",
    # Queries
    "Queries",
    "QueryCatalog",
    # Snowflake utilities
    "http_client",
    # Utilities
    "discover_imports",
]
