Metadata-Version: 2.4
Name: devops-bot-sdk
Version: 1.0.0
Summary: DevOps Bot Desktop SDK — thin client for the AgentOS Electron desktop app
Author: noumanaziz2128
License: Proprietary
Project-URL: Homepage, https://agentos.io
Project-URL: Repository, https://github.com/consultancy-outfit/devops-bot-ai
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.0
Requires-Dist: cryptography>=42
Provides-Extra: screenshot
Requires-Dist: Pillow>=10.0; extra == "screenshot"
Provides-Extra: process
Requires-Dist: psutil>=5.9; extra == "process"
Provides-Extra: all
Requires-Dist: Pillow>=10.0; extra == "all"
Requires-Dist: psutil>=5.9; extra == "all"

# AgentOS SDK

Thin Python client for the AgentOS desktop app (Electron). Wraps the backend
`/api/v1/*` endpoints. No orchestration logic — agents run server-side.

## Requirements

- Python 3.11+
- AgentOS backend running (default: `http://localhost:8000`)
- An API token from the AgentOS web app (Settings → API Tokens)

## Installation

### Basic (chat + pipeline + webhooks)
```bash
pip install agentos-sdk
```

### With screenshot collector
```bash
pip install "agentos-sdk[screenshot]"
```

### With process collector
```bash
pip install "agentos-sdk[process]"
```

### Everything
```bash
pip install "agentos-sdk[all]"
```

### From source (development)
```bash
# From the repo root
pip install -e sdk/          # installs sdk/ as editable package
# OR
pip install -e "sdk/[all]"   # with all optional extras
```

## Setup

```bash
agentos configure
# Backend URL [http://localhost:8000]: https://your-backend.example.com
# Paste your token (format: aeos_<64-char-hex>): aeos_...
# ✓ Configuration saved to ~/.agentos/config.toml
```

Replace a token:
```bash
agentos configure --rotate
```

## Quick start

```python
import asyncio
from sdk import BackendClient

async def main():
    client = BackendClient.from_config()   # reads ~/.agentos/config.toml

    # Bootstrap — load your persona + active model
    profile = await client.bootstrap()
    print(f"Logged in as tier={profile.tier}")

    # Chat (SSE stream)
    async for envelope in client.chat("my-thread", "What tasks are open?"):
        if envelope.type == "delta":
            print(envelope.data["text"], end="", flush=True)
        elif envelope.type == "done":
            break

asyncio.run(main())
```

## Run as Electron sidecar

```bash
python -m sdk.ipc.electron_bridge
```

Wire protocol (newline-delimited JSON on stdin/stdout):

```
# Electron → Python (stdin)
{"channel": "chat:send", "payload": {"thread_id": "t1", "message": "Hello"}}

# Python → Electron (stdout)
{"type": "delta",    "thread_id": "t1", "data": {"text": "Hi there"}}
{"type": "done",     "thread_id": "t1", "data": {"text": "Hi there", "usage": {...}}}
```

## Available channels

| Channel | Payload | What it does |
|---|---|---|
| `chat:send` | `{thread_id, message, role_slug?, model_id?}` | Stream chat response |
| `orchestrator:run` | `{task_input, intent?, task_id?}` | Start pipeline + poll status |
| `collectors:upload` | `{type, token, paths?, project}` | Upload local data |
| `auth:oauth_start` | `{service}` | Get OAuth URL (browser opens it) |
| `auth:oauth_complete` | `{service, code}` | Signal OAuth done |
| `onboarding:step` | `{step, input}` | Onboarding step |

## Collectors

All collector data is sent through `BackendClient.submit_webhook` — no other egress.

```python
from sdk.collectors import files, screenshot, process

# Upload a file
payload = files.build_webhook_payload(token, ["./notes.md"], project="my-project")
await client.submit_webhook("local_files", payload)

# Screenshot
payload = screenshot.build_webhook_payload(token, project="my-project")
await client.submit_webhook("local_screenshot", payload)

# Process snapshot
payload = process.build_webhook_payload(token, project="my-project")
await client.submit_webhook("local_process", payload)
```

## Size limits

| Collector | Limit |
|---|---|
| Single file | 50 MB |
| File batch | 200 MB |
| Screenshot | 10 MB (auto-recompressed) |

## Error handling

```python
from sdk import BackendUnreachable, BackendAuthFailed, BackendVersionTooOld, TokenNotConfigured

try:
    client = BackendClient.from_config()
    await client.ping()
except TokenNotConfigured:
    print("Run: agentos configure")
except BackendAuthFailed:
    print("Token expired — run: agentos configure --rotate")
except BackendVersionTooOld as e:
    print(f"Upgrade required: {e}")
except BackendUnreachable as e:
    print(f"Backend down: {e}")
```

## Versioning

The SDK is versioned independently from the backend. Every request carries
`X-SDK-Version: 1.0.0`. The backend may return HTTP 426 if the SDK is too
old to safely communicate — upgrade with `pip install --upgrade agentos-sdk`.
