Metadata-Version: 2.4
Name: mithai
Version: 0.12.0
Summary: AI agent framework for organizations
Project-URL: Homepage, https://last9.io
Project-URL: Repository, https://github.com/last9/mithai
Project-URL: Issues, https://github.com/last9/mithai/issues
Author: Nishant Modak
License-Expression: Apache-2.0
License-File: AUTHORS
License-File: LICENSE
Keywords: ai,chatops,devops,infrastructure,llm,slack,telegram
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.11
Requires-Dist: anthropic>=0.40.0
Requires-Dist: click>=8.1.0
Requires-Dist: jinja2>=3.1.0
Requires-Dist: prompt-toolkit>=3.0.0
Requires-Dist: pydantic>=2.0
Requires-Dist: python-dotenv>=1.2.2
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0.0
Provides-Extra: bedrock
Requires-Dist: boto3>=1.34.0; extra == 'bedrock'
Provides-Extra: dev
Requires-Dist: httpx>=0.27.0; extra == 'dev'
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'dev'
Requires-Dist: pyinstaller>=6.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=9.0.3; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Requires-Dist: starlette>=1.3.1; extra == 'dev'
Provides-Extra: mcp
Requires-Dist: mcp>=1.0.0; extra == 'mcp'
Provides-Extra: redis
Requires-Dist: redis>=5.0.0; extra == 'redis'
Provides-Extra: s3
Requires-Dist: boto3>=1.34.0; extra == 's3'
Provides-Extra: slack
Requires-Dist: anyio>=3.0; extra == 'slack'
Requires-Dist: slack-bolt>=1.18.0; extra == 'slack'
Requires-Dist: starlette>=1.3.1; extra == 'slack'
Requires-Dist: uvicorn>=0.30.0; extra == 'slack'
Provides-Extra: telegram
Requires-Dist: python-telegram-bot>=21.0; extra == 'telegram'
Provides-Extra: telemetry
Requires-Dist: last9-genai>=0.1.0; extra == 'telemetry'
Requires-Dist: opentelemetry-api>=1.20.0; extra == 'telemetry'
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0; extra == 'telemetry'
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'telemetry'
Provides-Extra: ui
Requires-Dist: httpx>=0.27.0; extra == 'ui'
Requires-Dist: starlette>=1.3.1; extra == 'ui'
Requires-Dist: uvicorn>=0.30.0; extra == 'ui'
Description-Content-Type: text/markdown

# mithai

AI agent framework for infrastructure operations.

**[Documentation →](https://docs.mithai.dev)**

mithai gives your team an AI-powered ops agent that lives in Slack, Telegram, and a terminal — simultaneously. It can query your infrastructure, take actions, and ask a human before doing anything dangerous.

## How it works

```
You (in Slack/Telegram/CLI)
     |
     v
  Adapter  -->  Engine  -->  LLM (Anthropic API or AWS Bedrock)
                  |              |
              Skills         Tool calls
           (shell, memory,    (namespaced as
            scheduling, etc.)  skill__tool)
                  |
             Human MCP
          (approve/confirm
           before risky ops)
```

**Skills** are plugins — a folder with `prompt.md` (tells the AI what the skill does) and `tools.py` (defines tools the AI can call). The AI decides which tools to use based on your message.

**Human MCP** is human-in-the-loop as a protocol. Skills declare which tools need human approval (`"human": "approve"`) or confirmation (`"human": "confirm"`). Read-only tools run automatically.

## Quick start

```bash
pip install mithai
mithai init
# Edit .env with your ANTHROPIC_API_KEY
mithai chat
```

Or from source:

```bash
git clone https://github.com/last9/mithai.git
cd mithai
pip install -e ".[dev]"
mithai init
mithai chat
```

To use AWS Bedrock instead of the Anthropic API, install the `bedrock` extra and configure your AWS credentials — see [LLM providers](#llm-providers) below:

```bash
pip install 'mithai[bedrock]'
```

Telemetry is optional. Install `mithai[telemetry]` only when you want
OpenTelemetry export and Last9 GenAI span enrichment; the core package runs
without those dependencies.

## Creating a skill

```bash
mithai skill create my_skill
```

This creates `skills/my_skill/` with two files:

**`prompt.md`** — what the AI knows about your skill:
```markdown
You can check the health of HTTP endpoints.
Report status codes and response times.
```

**`tools.py`** — what the AI can do:
```python
import json

TOOLS = [
    {
        "name": "check_url",
        "description": "Check if a URL is reachable",
        "input_schema": {
            "type": "object",
            "properties": {
                "url": {"type": "string", "description": "URL to check"},
            },
            "required": ["url"],
        },
        # Add "human": "approve" for risky operations
    },
]

def handle(name: str, input: dict, ctx: dict) -> str:
    if name == "check_url":
        # Your implementation here
        return json.dumps({"status": 200, "healthy": True})
    return json.dumps({"error": f"Unknown tool: {name}"})
```

That's it. Drop the folder in `skills/`, restart mithai, and the AI can use it.

## Built-in skills

| Skill | What it does | Human MCP |
|-------|-------------|-----------|
| `http_checker` | Check URL health, status codes, response times | auto |
| `shell` | Run allowlisted shell commands | dynamic |
| `memory` | Persistent memory across conversations (MEMORY.md) | auto |
| `sessions` | Inspect past conversation sessions per channel | auto |
| `scheduling` | Create recurring cron-based tasks via Slack | confirm |
| `kubernetes` | Inspect pods, deployments, events, logs, and resource descriptions | auto |

## Human MCP

Tools declare their human-in-the-loop requirement:

```python
TOOLS = [
    {"name": "get_pods", ...},                          # auto-execute
    {"name": "restart", ..., "human": "approve"},       # click approve/deny
    {"name": "delete_ns", ..., "human": "confirm"},     # type confirmation
]
```

Override in `config.yaml`:
```yaml
human:
  timeout_seconds: 300
  overrides:
    shell__run_command: confirm    # escalate
    kubernetes__get_pods: null     # keep read-only pod listing auto-executed
```

## Scheduling

The scheduling skill lets the agent create recurring tasks. A cron job posts a Slack message mentioning the bot — the bot processes it like any other @mention.

Two backends:

| Backend | Config | Storage |
|---------|--------|---------|
| `crontab` (default) | No config needed | Local crontab |
| `agent_cloud_platform` | URL + token | Central platform, survives restarts |

```yaml
skills:
  config:
    scheduling:
      backend: agent_cloud_platform
      scheduling_backend_url: https://your-platform/api
      scheduling_backend_token: ${SCHEDULING_BACKEND_TOKEN}
```

## Configuration

```yaml
# config.yaml
bot:
  name: mithai
  system_prompt: |
    You are an ops assistant. Be concise.

adapter:
  # Run one adapter:
  type: slack

  # Or run multiple adapters simultaneously:
  # types:
  #   - slack
  #   - telegram

  slack:
    bot_token: ${SLACK_BOT_TOKEN}
    app_token: ${SLACK_APP_TOKEN}
  telegram:
    bot_token: ${TELEGRAM_BOT_TOKEN}
    allowed_chat_ids:
      - ${TELEGRAM_CHAT_ID}

llm:
  provider: anthropic
  model: claude-sonnet-4-6
  anthropic:
    api_key: ${ANTHROPIC_API_KEY}

skills:
  paths:
    - ./skills
  config:
    shell:
      allowed_commands: ["df -h", "free -h", "uptime"]
    scheduling:
      backend: crontab  # or agent_cloud_platform
```

When using `types`, each adapter runs in its own thread sharing the same engine and skills. Human MCP approvals route back through whichever platform the message came from.

### LLM providers

mithai supports two LLM providers. Select via `llm.provider` in `config.yaml`.

**Anthropic (default)** — direct Claude API access via the `anthropic` Python SDK:

```yaml
llm:
  provider: anthropic
  model: claude-sonnet-4-6
  anthropic:
    api_key: ${ANTHROPIC_API_KEY}
```

**AWS Bedrock** — unified Converse API across model families (Anthropic / Llama / Cohere / Mistral on Bedrock). Requires `pip install 'mithai[bedrock]'`:

```yaml
llm:
  provider: bedrock
  model: anthropic.claude-sonnet-4-20250514-v1:0   # Bedrock model ID
  bedrock:
    access_key_id: ${AWS_ACCESS_KEY_ID}
    secret_access_key: ${AWS_SECRET_ACCESS_KEY}
    region: ${AWS_REGION}
```

The IAM principal needs `bedrock:InvokeModel` for each model the agent will use. For full provider details, model IDs, and troubleshooting see the [Configuration › LLM](docs/configuration.md#llm) and [Troubleshooting](docs/troubleshooting.md) docs.

## Onboarding

When the bot is added to a Slack channel — or on startup for channels in `allowed_channels` — it runs an onboarding flow: learning who's in the channel, what it's used for, and introducing itself.

Enable it in `config.yaml`:

```yaml
onboarding:
  enabled: true
```

**What it does:**

1. Reads its existing memory (`MEMORY.md`) to recall what it already knows about the org from other channels
2. Fetches the full channel member roster via `slack_get_members`
3. Reads recent channel history via `slack_get_history`
4. Merges any new facts into `MEMORY.md` — updating or correcting existing entries rather than duplicating them
5. Posts a short intro message to the channel

On startup, channels listed in `allowed_channels` that haven't been onboarded yet are onboarded automatically (one per thread, concurrently).

**Customising the onboarding prompt:**

Drop an `onboarding.md` file in your project root (alongside `config.yaml`). The engine loads it instead of the built-in prompt. Two placeholders are available:

```markdown
You just joined #{channel_name} (ID: {channel_id}).

This team uses a monorepo. Start by reading memory, fetching the member
roster, and scanning the last 50 messages. Then update MEMORY.md and
write a one-paragraph intro. No bullet points, no emojis.
```

Literal `{` and `}` in the template (e.g. JSON examples) are safe — only `{channel_id}` and `{channel_name}` are substituted.

**Memory model:**

mithai serves one organisation across multiple Slack channels. Knowledge is shared — facts learned in `#infra` are available in `#backend`. `MEMORY.md` is the single source of truth. The onboarding flow reads before writing and merges rather than appends, so joining a new channel enriches the shared knowledge without duplicating it.

## CLI

```
mithai init                    # scaffold project
mithai run                     # start all configured adapters
mithai run --adapter slack     # start only one adapter
mithai chat                    # CLI REPL for development
mithai skill create <name>     # create a new skill
mithai skill list              # list loaded skills
mithai skill validate          # validate all skills
mithai agent create <id>       # scaffold a new agent (multi-agent mode)
mithai agent list              # list configured agents
mithai agent info <id>         # show agent details
mithai agent validate          # validate all agent configs
```

### Multi-agent scaffolding

`mithai agent create` generates the directory structure and config for a new agent:

```bash
mithai agent create devops --name "DevOps Agent" --skills shell,memory,http_checker
```

This creates `agents/devops/` with `memory/`, `.env.example`, and `system_prompt.md`, and appends the agent config block to `config.yaml`.

To customize the onboarding flow for all agents, drop an `onboarding.md` in the project root (see [Onboarding](#onboarding)).

## License

Apache 2.0
